On Mon, May 25, 2009 at 11:47:24AM +0300, Avi Kivity wrote: > The processor is documented to reload the PDPTRs while in PAE mode if any > of the CR4 bits PSE, PGE, or PAE change. Linux relies on this > behaviour when zapping the low mappings of PAE kernels during boot. > > The code already handled changes to CR4.PAE; augment it to also notice changes > to PSE and PGE. > > This triggered while booting an F11 PAE kernel; the futex initialization code > runs before any CR3 reloads and writes to a NULL pointer; the futex subsystem > ended up uninitialized, killing PI futexes and pulseaudio which uses them. One comment regarding set_cr0. Section 8.1 of the TLB doc says: * The processor does not maintain a PDP cache as described in Section 4. The processor always caches information from the four page-directory-pointer-table entries. These entries are not cached at the time of address translation. Instead, they are always cached as part of the execution of the following instructions: * A MOV to CR0 that modifies CR0.PG and that occurs with IA32_EFER.LMA = 0 and CR4.PAE = 1. However kvm_set_cr0 only caches the PDPTRs if CR0.PG changed from 0->1. Can't see a problem there though. Also, the checks in kvm_arch_vcpu_ioctl_set_sregs should probably be unified with kvm_set_crX, to avoid future mistakes. Otherwise, ACK. > > Signed-off-by: Avi Kivity <avi@xxxxxxxxxx> > --- > arch/x86/kvm/x86.c | 6 +++++- > 1 files changed, 5 insertions(+), 1 deletions(-) > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 8b5d1e5..6d44dd5 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -341,6 +341,9 @@ EXPORT_SYMBOL_GPL(kvm_lmsw); > > void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) > { > + unsigned long old_cr4 = vcpu->arch.cr4; > + unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE; > + > if (cr4 & CR4_RESERVED_BITS) { > printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n"); > kvm_inject_gp(vcpu, 0); > @@ -354,7 +357,8 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) > kvm_inject_gp(vcpu, 0); > return; > } > - } else if (is_paging(vcpu) && !is_pae(vcpu) && (cr4 & X86_CR4_PAE) > + } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE) > + && ((cr4 ^ old_cr4) & pdptr_bits) > && !load_pdptrs(vcpu, vcpu->arch.cr3)) { > printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n"); > kvm_inject_gp(vcpu, 0); > -- > 1.6.0.6 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html