On Fri, Jan 31, 2020 at 10:31:44AM +0100, Ard Biesheuvel wrote: > Playing around with this a bit more, I think we should go with > > if (IS_ENABLED(CONFIG_X86_32)) { > static const struct desc_struct desc[] __aligned(8) = { > [GDT_ENTRY_BOOT_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff), > [GDT_ENTRY_BOOT_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff), > }; > > native_load_gdt(&(struct desc_ptr){ sizeof(desc) - 1, > (unsigned long)desc }); > } > This is the way I originally did it (except I loaded the GDT with the relocated address of desc in case efi_relocate_kernel got called). It booted on a test, but I grew concerned because this GDT will be somewhere in the middle of the decompression buffer and get overwritten either during the copy to the end of the buffer or during decompression. If anything tries to reload segment registers it will blow up. Looking at the code though it doesn't look like anything will -- the segments are loaded at the beginning of startup_32, and then it looks like nothing should touch them until we get to the startup code of the decompressed kernel, which sets up its own boot GDT first. So this might be ok if the x86 maintainers agree.