1 IMPLEMENTATION [ia32 || amd64]:
4 #include "std_macros.h"
7 PRIVATE inline NEEDS["gdt.h"]
9 Task::invoke_arch(L4_msg_tag &tag, Utcb *utcb)
11 switch (utcb->values[0])
17 Utcb_values_per_ldt_entry
18 = Cpu::Ldt_entry_size / sizeof(utcb->values[0]),
20 if (EXPECT_FALSE(tag.words() < 3
21 || tag.words() % Utcb_values_per_ldt_entry))
23 tag = commit_result(-L4_err::EInval);
27 unsigned entry_number = utcb->values[1];
28 unsigned size = (tag.words() - 2) * sizeof(utcb->values[0]);
30 // Allocate the memory if not yet done
34 if (entry_number * Cpu::Ldt_entry_size + size > Config::PAGE_SIZE)
36 WARN("set_ldt: LDT size exceeds one page, not supported.");
37 tag = commit_result(-L4_err::EInval);
41 _ldt.size(size + Cpu::Ldt_entry_size * entry_number);
43 Address desc_addr = reinterpret_cast<Address>(&utcb->values[2]);
46 = reinterpret_cast<Gdt_entry *>(_ldt.addr()) + entry_number;
48 while (size >= Cpu::Ldt_entry_size)
50 desc = *reinterpret_cast<Gdt_entry const *>(desc_addr);
53 WARN("set_ldt: Bad descriptor.");
54 tag = commit_result(-L4_err::EInval);
59 size -= Cpu::Ldt_entry_size;
60 desc_addr += Cpu::Ldt_entry_size;
64 if (this == current()->space())
65 Cpu::cpus.cpu(current_cpu()).enable_ldt(_ldt.addr(), _ldt.size());
67 tag = commit_result(0);