1 IMPLEMENTATION [ia32 || amd64]:
4 #include "std_macros.h"
13 PRIVATE inline NEEDS["gdt.h"]
15 Task::invoke_arch(L4_msg_tag &tag, Utcb *utcb)
17 switch (utcb->values[0])
23 Utcb_values_per_ldt_entry
24 = Cpu::Ldt_entry_size / sizeof(utcb->values[0]),
26 if (EXPECT_FALSE(tag.words() < 3
27 || tag.words() % Utcb_values_per_ldt_entry))
29 tag = commit_result(-L4_err::EInval);
33 unsigned entry_number = utcb->values[1];
34 unsigned size = (tag.words() - 2) * sizeof(utcb->values[0]);
36 // Allocate the memory if not yet done
40 if (entry_number * Cpu::Ldt_entry_size + size > Config::PAGE_SIZE)
42 WARN("set_ldt: LDT size exceeds one page, not supported.");
43 tag = commit_result(-L4_err::EInval);
47 _ldt.size(size + Cpu::Ldt_entry_size * entry_number);
49 Address desc_addr = reinterpret_cast<Address>(&utcb->values[2]);
52 = reinterpret_cast<Gdt_entry *>(_ldt.addr()) + entry_number;
54 while (size >= Cpu::Ldt_entry_size)
56 desc = *reinterpret_cast<Gdt_entry const *>(desc_addr);
59 WARN("set_ldt: Bad descriptor.");
60 tag = commit_result(-L4_err::EInval);
65 size -= Cpu::Ldt_entry_size;
66 desc_addr += Cpu::Ldt_entry_size;
70 if (this == current()->space())
71 Cpu::cpus.cpu(current_cpu()).enable_ldt(_ldt.addr(), _ldt.size());
73 tag = commit_result(0);