[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] x86: re-enable NX if disabled
On 04/12/15 16:31, Jan Beulich wrote: > I noticed Linux 4.4 doing this universally now, and I think it's a good > idea to override such anti-security BIOS settings (we certainly have no > compatibility problem due to NX being enabled). I had a plan to do the same, so definitely +1. > > Secondary changes: > - no need to check supported extended CPUID level for leaves 80000000 > and 80000001 (required on x86-64) > - no need to update c->cpuid_level in early_init_intel() (done anyway > in generic_identify()) > - alignment of trampoline data items > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > > --- a/xen/arch/x86/boot/trampoline.S > +++ b/xen/arch/x86/boot/trampoline.S > @@ -32,9 +32,13 @@ GLOBAL(trampoline_realmode_entry) > lmsw %ax # CR0.PE = 1 (enter protected mode) > ljmpl $BOOT_CS32,$bootsym_rel(trampoline_protmode_entry,6) > > + .balign 8 > + .word 0 > idt_48: .word 0, 0, 0 # base = limit = 0 > + .word 0 > gdt_48: .word 6*8-1 > .long bootsym_rel(trampoline_gdt,4) > + > trampoline_gdt: > /* 0x0000: unused */ > .quad 0x0000000000000000 > @@ -56,6 +60,9 @@ trampoline_gdt: > .long trampoline_gdt + BOOT_PSEUDORM_DS + 2 - . > .popsection > > +GLOBAL(trampoline_misc_enable_off) > + .quad 0 > + For clarity, I would name this trampoline_misc_enable_mask and invert its representation to make the asm easier. > GLOBAL(cpuid_ext_features) > .long 0 > > @@ -84,6 +91,21 @@ trampoline_protmode_entry: > add bootsym_rel(trampoline_xen_phys_start,4,%eax) > mov %eax,%cr3 > > + /* Adjust IA32_MISC_ENABLE if needed. */ Possibly worth stating that this is to allow us to enable NX before attempting to use pagetables with NX set. > + mov bootsym_rel(trampoline_misc_enable_off,4,%esi) > + mov bootsym_rel(trampoline_misc_enable_off+4,4,%edi) > + mov %esi,%eax > + or %edi,%eax > + jz 1f > + mov $MSR_IA32_MISC_ENABLE,%ecx > + rdmsr > + not %esi > + not %edi > + and %esi,%eax > + and %edi,%edx > + wrmsr > +1: > + > /* Set up EFER (Extended Feature Enable Register). */ > mov bootsym_rel(cpuid_ext_features,4,%edi) > movl $MSR_EFER,%ecx > --- a/xen/arch/x86/cpu/common.c > +++ b/xen/arch/x86/cpu/common.c > @@ -256,15 +256,15 @@ static void __cpuinit generic_identify(s > > /* AMD-defined flags: level 0x80000001 */ > c->extended_cpuid_level = cpuid_eax(0x80000000); > - if ( (c->extended_cpuid_level & 0xffff0000) == 0x80000000 ) { > - if ( c->extended_cpuid_level >= 0x80000001 ) > - cpuid(0x80000001, &tmp, &tmp, > - > &c->x86_capability[cpufeat_word(X86_FEATURE_LAHF_LM)], > - > &c->x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)]); > + cpuid(0x80000001, &tmp, &tmp, > + &c->x86_capability[cpufeat_word(X86_FEATURE_LAHF_LM)], > + &c->x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)]); > + if (c == &boot_cpu_data) > + bootsym(cpuid_ext_features) = > + c->x86_capability[cpufeat_word(X86_FEATURE_NX)]; > > - if ( c->extended_cpuid_level >= 0x80000004 ) > - get_model_name(c); /* Default name */ > - } > + if (c->extended_cpuid_level >= 0x80000004) > + get_model_name(c); /* Default name */ > > /* Intel-defined flags: level 0x00000007 */ > if ( c->cpuid_level >= 0x00000007 ) > --- a/xen/arch/x86/cpu/intel.c > +++ b/xen/arch/x86/cpu/intel.c > @@ -162,19 +162,29 @@ static void __devinit early_init_intel(s > if (c->x86 == 15 && c->x86_cache_alignment == 64) > c->x86_cache_alignment = 128; > > - /* Unmask CPUID levels if masked: */ > + /* Unmask CPUID levels and NX if masked: */ > if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) { > - u64 misc_enable; > + u64 misc_enable, disable; > > rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable); > > - if (misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID) { > - misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; > - wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); > - c->cpuid_level = cpuid_eax(0); > - if (opt_cpu_info || c == &boot_cpu_data) > - printk(KERN_INFO "revised cpuid level: %d\n", > - c->cpuid_level); > + disable = misc_enable & (MSR_IA32_MISC_ENABLE_LIMIT_CPUID | > + MSR_IA32_MISC_ENABLE_XD_DISABLE); > + if (disable) { > + wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable & ~disable); > + bootsym(trampoline_misc_enable_off) |= disable; > + } > + > + if (disable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID) > + printk(KERN_INFO "revised cpuid level: %d\n", > + cpuid_eax(0)); > + if (disable & MSR_IA32_MISC_ENABLE_XD_DISABLE) { > + u64 efer; > + > + rdmsrl(MSR_EFER, efer); > + wrmsrl(MSR_EFER, efer | EFER_NX); {read,write}_efer(), which also update this_cpu(efer). > + printk(KERN_INFO > + "re-enabled NX (Execute Disable) protection\n"); > } Because of the asm adjustment of $MSR_IA32_MISC_ENABLE, this code will only ever run on the BSP. As such, it would better live somewhere like early_cpu_detect() (or a brand new early_cpu_workaround()), making it __init. With that, the adjustment of bootsym(cpuid_ext_features) can move as well. (As part of feature levelling, I had considered changing it to a boolean indicating whether NX should be used, but that is definitely a separate piece of cleanup.) ~Andrew _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |