Fixes for 3.12-rc5. Two old PPC bugs and one new (3.12-rc2) x86 bug.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.14 (GNU/Linux)
 
 iQIcBAABAgAGBQJSVndRAAoJEBvWZb6bTYby/SIP/26s8gh/TkTa6eYVXAOIq2PE
 0T2rCN2KYT/huDuoH5SJ1dMUweWwmwaXsZVD8iNVuvbZSIUcC7j6hlPg+IIl7uD4
 EEKFPsCehCumleCsoeyYu14YPFApp8CTbx2nXre2fT3z82bEdFbdAF8i0nwCWsBF
 7yvQYMl/qDhWotNFnn9D9i3VaiJwn4BrQxWsGkSssOr1+YRD7o718qErmqwliECv
 m25QQCr+kX7O5Le9kaQ0LsMMzUWnR63VHsBArXsLP+bKozC2AgyTCku3QVYGk3K3
 uYeen0wbErhZB2JDZq4NUYVltvF0gNoOWwgfRGuOm4ZRfP5g1Paeu1xDDs3TYXkG
 9/fkeJRsFpPm+o783IhZaTwTh8EOIcpSyrAq/mC9fCRYf0u50aKOexjV+Sj0Lsya
 jC9MkGYB6sT3q+XmYKntVqmkemjgr6ku1TLMS7zouR0g8IsnJ9oEKzxE/0PXgIr0
 IkOD6rceSmG8KR5r57GYO1zdCyfaPgKAgAzeifBHnCaWQiX/Id9rO1nk9mzMIa70
 xQw7LcUC0rzN6t+zS236wrfCzDAh/trZep+WTU+98WC4fqxyo8vlPNhEu/In56jw
 mhNTb3UCsPyzUEXDdkeZN/Hy4RZ/WbMAeuh8ZcQzn+grK8h5Rura07B4zKluhjvx
 DLAjE/JmEzfBuhpoXsZn
 =O6an
 -----END PGP SIGNATURE-----

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fixes from Paolo Bonzini:
 "Fixes for 3.12-rc5: two old PPC bugs and one new (3.12-rc2) x86 bug"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  kvm: ppc: booke: check range page invalidation progress on page setup
  KVM: PPC: Book3S HV: Fix typo in saving DSCR
  KVM: nVMX: fix shadow on EPT
This commit is contained in:
Linus Torvalds 2013-10-10 11:33:48 -07:00
commit 8273548c54
3 changed files with 30 additions and 14 deletions

View File

@ -1066,7 +1066,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
mfspr r8, SPRN_DSCR mfspr r8, SPRN_DSCR
ld r7, HSTATE_DSCR(r13) ld r7, HSTATE_DSCR(r13)
std r8, VCPU_DSCR(r7) std r8, VCPU_DSCR(r9)
mtspr SPRN_DSCR, r7 mtspr SPRN_DSCR, r7
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)

View File

@ -332,6 +332,13 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
unsigned long hva; unsigned long hva;
int pfnmap = 0; int pfnmap = 0;
int tsize = BOOK3E_PAGESZ_4K; int tsize = BOOK3E_PAGESZ_4K;
int ret = 0;
unsigned long mmu_seq;
struct kvm *kvm = vcpu_e500->vcpu.kvm;
/* used to check for invalidations in progress */
mmu_seq = kvm->mmu_notifier_seq;
smp_rmb();
/* /*
* Translate guest physical to true physical, acquiring * Translate guest physical to true physical, acquiring
@ -449,6 +456,12 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
gvaddr &= ~((tsize_pages << PAGE_SHIFT) - 1); gvaddr &= ~((tsize_pages << PAGE_SHIFT) - 1);
} }
spin_lock(&kvm->mmu_lock);
if (mmu_notifier_retry(kvm, mmu_seq)) {
ret = -EAGAIN;
goto out;
}
kvmppc_e500_ref_setup(ref, gtlbe, pfn); kvmppc_e500_ref_setup(ref, gtlbe, pfn);
kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize,
@ -457,10 +470,13 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
/* Clear i-cache for new pages */ /* Clear i-cache for new pages */
kvmppc_mmu_flush_icache(pfn); kvmppc_mmu_flush_icache(pfn);
out:
spin_unlock(&kvm->mmu_lock);
/* Drop refcount on page, so that mmu notifiers can clear it */ /* Drop refcount on page, so that mmu notifiers can clear it */
kvm_release_pfn_clean(pfn); kvm_release_pfn_clean(pfn);
return 0; return ret;
} }
/* XXX only map the one-one case, for now use TLB0 */ /* XXX only map the one-one case, for now use TLB0 */

View File

@ -3255,25 +3255,29 @@ static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
static void ept_load_pdptrs(struct kvm_vcpu *vcpu) static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
{ {
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
if (!test_bit(VCPU_EXREG_PDPTR, if (!test_bit(VCPU_EXREG_PDPTR,
(unsigned long *)&vcpu->arch.regs_dirty)) (unsigned long *)&vcpu->arch.regs_dirty))
return; return;
if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
vmcs_write64(GUEST_PDPTR0, vcpu->arch.mmu.pdptrs[0]); vmcs_write64(GUEST_PDPTR0, mmu->pdptrs[0]);
vmcs_write64(GUEST_PDPTR1, vcpu->arch.mmu.pdptrs[1]); vmcs_write64(GUEST_PDPTR1, mmu->pdptrs[1]);
vmcs_write64(GUEST_PDPTR2, vcpu->arch.mmu.pdptrs[2]); vmcs_write64(GUEST_PDPTR2, mmu->pdptrs[2]);
vmcs_write64(GUEST_PDPTR3, vcpu->arch.mmu.pdptrs[3]); vmcs_write64(GUEST_PDPTR3, mmu->pdptrs[3]);
} }
} }
static void ept_save_pdptrs(struct kvm_vcpu *vcpu) static void ept_save_pdptrs(struct kvm_vcpu *vcpu)
{ {
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
vcpu->arch.mmu.pdptrs[0] = vmcs_read64(GUEST_PDPTR0); mmu->pdptrs[0] = vmcs_read64(GUEST_PDPTR0);
vcpu->arch.mmu.pdptrs[1] = vmcs_read64(GUEST_PDPTR1); mmu->pdptrs[1] = vmcs_read64(GUEST_PDPTR1);
vcpu->arch.mmu.pdptrs[2] = vmcs_read64(GUEST_PDPTR2); mmu->pdptrs[2] = vmcs_read64(GUEST_PDPTR2);
vcpu->arch.mmu.pdptrs[3] = vmcs_read64(GUEST_PDPTR3); mmu->pdptrs[3] = vmcs_read64(GUEST_PDPTR3);
} }
__set_bit(VCPU_EXREG_PDPTR, __set_bit(VCPU_EXREG_PDPTR,
@ -7777,10 +7781,6 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
vmcs_write64(GUEST_PDPTR1, vmcs12->guest_pdptr1); vmcs_write64(GUEST_PDPTR1, vmcs12->guest_pdptr1);
vmcs_write64(GUEST_PDPTR2, vmcs12->guest_pdptr2); vmcs_write64(GUEST_PDPTR2, vmcs12->guest_pdptr2);
vmcs_write64(GUEST_PDPTR3, vmcs12->guest_pdptr3); vmcs_write64(GUEST_PDPTR3, vmcs12->guest_pdptr3);
__clear_bit(VCPU_EXREG_PDPTR,
(unsigned long *)&vcpu->arch.regs_avail);
__clear_bit(VCPU_EXREG_PDPTR,
(unsigned long *)&vcpu->arch.regs_dirty);
} }
kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->guest_rsp); kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->guest_rsp);