DEFINE_PER_CPU_PAGE_ALIGNED(structgdt_page, gdt_page) = { .gdt = {
/*
* Weneed valid kernel segments for data and code in long mode too
* IRETwill check the segment types kkeil2000/10/28
* Alsosysret mandates a special GDT layout
*
* TLSdescriptors are currently at a different place compared to i386.
*Hopefully nobody expects them at a fixed place (Wine?)
*/
[GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
[GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff),
[GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff),
[GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),
[GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),
} };
#defineGDT_ENTRY_INIT(flags, base, limit) { { { \
.a = ((limit) & 0xffff) | (((base) &0xffff) << 16), \
.b = (((base) & 0xff0000) >> 16) |(((flags) & 0xf0ff) << 8) | \
((limit) & 0xf0000) | ((base) &0xff000000), \
} } }
structgdt_page {
struct desc_struct gdt[GDT_ENTRIES];
}__attribute__((aligned(PAGE_SIZE)));
#defineGDT_ENTRIES 16
staticinline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
{
return per_cpu(gdt_page, cpu).gdt;
}
staticunsigned long get_segment_base(unsigned int segment)
{
struct desc_struct *desc;
int idx = segment >> 3;
if ((segment & SEGMENT_TI_MASK) ==SEGMENT_LDT) {
if (idx > LDT_ENTRIES)
return 0;
if (idx >current->active_mm->context.size)
return 0;
desc = current->active_mm->context.ldt;
} else {
if (idx > GDT_ENTRIES)
return 0;
desc = __this_cpu_ptr(&gdt_page.gdt[0]);
}
return get_desc_base(desc + idx);
}
'Core BSP 분석 > 리눅스 커널 핵심 분석' 카테고리의 다른 글
Debug config (0) | 2023.05.06 |
---|---|
CONFIG_DETECT_HUNG_TASK (0) | 2023.05.06 |
process state (0) | 2023.05.06 |
cmm: thread dump (0) | 2023.05.05 |
x86 stack dump(1) (0) | 2023.05.05 |