Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ccf70ddc authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull KVM fixes from Paolo Bonzini:
 "(Relatively) a lot of reverts, mostly.

  Bugs have trickled in for a new feature in 4.2 (MTRR support in
  guests) so I'm reverting it all; let's not make this -rc period busier
  for KVM than it's been so far.  This covers the four reverts from me.

  The fifth patch is being reverted because Radim found a bug in the
  implementation of stable scheduler clock, *but* also managed to
  implement the feature entirely without hypervisor support.  So instead
  of fixing the hypervisor side we can remove it completely; 4.4 will
  get the new implementation"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  Use WARN_ON_ONCE for missing X86_FEATURE_NRIPS
  Update KVM homepage Url
  Revert "KVM: SVM: use NPT page attributes"
  Revert "KVM: svm: handle KVM_X86_QUIRK_CD_NW_CLEARED in svm_get_mt_mask"
  Revert "KVM: SVM: Sync g_pat with guest-written PAT value"
  Revert "KVM: x86: apply guest MTRR virtualization on host reserved pages"
  Revert "KVM: x86: zero kvmclock_offset when vcpu0 initializes kvmclock system MSR"
parents 46c8217c d2922422
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -5957,7 +5957,7 @@ F: virt/kvm/
KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V
KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V
M:	Joerg Roedel <joro@8bytes.org>
M:	Joerg Roedel <joro@8bytes.org>
L:	kvm@vger.kernel.org
L:	kvm@vger.kernel.org
W:	http://kvm.qumranet.com
W:	http://www.linux-kvm.org/
S:	Maintained
S:	Maintained
F:	arch/x86/include/asm/svm.h
F:	arch/x86/include/asm/svm.h
F:	arch/x86/kvm/svm.c
F:	arch/x86/kvm/svm.c
@@ -5965,7 +5965,7 @@ F: arch/x86/kvm/svm.c
KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC
KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC
M:	Alexander Graf <agraf@suse.com>
M:	Alexander Graf <agraf@suse.com>
L:	kvm-ppc@vger.kernel.org
L:	kvm-ppc@vger.kernel.org
W:	http://kvm.qumranet.com
W:	http://www.linux-kvm.org/
T:	git git://github.com/agraf/linux-2.6.git
T:	git git://github.com/agraf/linux-2.6.git
S:	Supported
S:	Supported
F:	arch/powerpc/include/asm/kvm*
F:	arch/powerpc/include/asm/kvm*
+1 −0
Original line number Original line Diff line number Diff line
@@ -41,6 +41,7 @@ struct pvclock_wall_clock {


#define PVCLOCK_TSC_STABLE_BIT	(1 << 0)
#define PVCLOCK_TSC_STABLE_BIT	(1 << 0)
#define PVCLOCK_GUEST_STOPPED	(1 << 1)
#define PVCLOCK_GUEST_STOPPED	(1 << 1)
/* PVCLOCK_COUNTS_FROM_ZERO broke ABI and can't be used anymore. */
#define PVCLOCK_COUNTS_FROM_ZERO (1 << 2)
#define PVCLOCK_COUNTS_FROM_ZERO (1 << 2)
#endif /* __ASSEMBLY__ */
#endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_PVCLOCK_ABI_H */
#endif /* _ASM_X86_PVCLOCK_ABI_H */
+13 −112
Original line number Original line Diff line number Diff line
@@ -514,7 +514,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
	struct vcpu_svm *svm = to_svm(vcpu);
	struct vcpu_svm *svm = to_svm(vcpu);


	if (svm->vmcb->control.next_rip != 0) {
	if (svm->vmcb->control.next_rip != 0) {
		WARN_ON(!static_cpu_has(X86_FEATURE_NRIPS));
		WARN_ON_ONCE(!static_cpu_has(X86_FEATURE_NRIPS));
		svm->next_rip = svm->vmcb->control.next_rip;
		svm->next_rip = svm->vmcb->control.next_rip;
	}
	}


@@ -866,64 +866,6 @@ static void svm_disable_lbrv(struct vcpu_svm *svm)
	set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 0, 0);
	set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 0, 0);
}
}


#define MTRR_TYPE_UC_MINUS	7
#define MTRR2PROTVAL_INVALID 0xff

static u8 mtrr2protval[8];

static u8 fallback_mtrr_type(int mtrr)
{
	/*
	 * WT and WP aren't always available in the host PAT.  Treat
	 * them as UC and UC- respectively.  Everything else should be
	 * there.
	 */
	switch (mtrr)
	{
	case MTRR_TYPE_WRTHROUGH:
		return MTRR_TYPE_UNCACHABLE;
	case MTRR_TYPE_WRPROT:
		return MTRR_TYPE_UC_MINUS;
	default:
		BUG();
	}
}

static void build_mtrr2protval(void)
{
	int i;
	u64 pat;

	for (i = 0; i < 8; i++)
		mtrr2protval[i] = MTRR2PROTVAL_INVALID;

	/* Ignore the invalid MTRR types.  */
	mtrr2protval[2] = 0;
	mtrr2protval[3] = 0;

	/*
	 * Use host PAT value to figure out the mapping from guest MTRR
	 * values to nested page table PAT/PCD/PWT values.  We do not
	 * want to change the host PAT value every time we enter the
	 * guest.
	 */
	rdmsrl(MSR_IA32_CR_PAT, pat);
	for (i = 0; i < 8; i++) {
		u8 mtrr = pat >> (8 * i);

		if (mtrr2protval[mtrr] == MTRR2PROTVAL_INVALID)
			mtrr2protval[mtrr] = __cm_idx2pte(i);
	}

	for (i = 0; i < 8; i++) {
		if (mtrr2protval[i] == MTRR2PROTVAL_INVALID) {
			u8 fallback = fallback_mtrr_type(i);
			mtrr2protval[i] = mtrr2protval[fallback];
			BUG_ON(mtrr2protval[i] == MTRR2PROTVAL_INVALID);
		}
	}
}

static __init int svm_hardware_setup(void)
static __init int svm_hardware_setup(void)
{
{
	int cpu;
	int cpu;
@@ -990,7 +932,6 @@ static __init int svm_hardware_setup(void)
	} else
	} else
		kvm_disable_tdp();
		kvm_disable_tdp();


	build_mtrr2protval();
	return 0;
	return 0;


err:
err:
@@ -1145,43 +1086,6 @@ static u64 svm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
	return target_tsc - tsc;
	return target_tsc - tsc;
}
}


static void svm_set_guest_pat(struct vcpu_svm *svm, u64 *g_pat)
{
	struct kvm_vcpu *vcpu = &svm->vcpu;

	/* Unlike Intel, AMD takes the guest's CR0.CD into account.
	 *
	 * AMD does not have IPAT.  To emulate it for the case of guests
	 * with no assigned devices, just set everything to WB.  If guests
	 * have assigned devices, however, we cannot force WB for RAM
	 * pages only, so use the guest PAT directly.
	 */
	if (!kvm_arch_has_assigned_device(vcpu->kvm))
		*g_pat = 0x0606060606060606;
	else
		*g_pat = vcpu->arch.pat;
}

static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
{
	u8 mtrr;

	/*
	 * 1. MMIO: trust guest MTRR, so same as item 3.
	 * 2. No passthrough: always map as WB, and force guest PAT to WB as well
	 * 3. Passthrough: can't guarantee the result, try to trust guest.
	 */
	if (!is_mmio && !kvm_arch_has_assigned_device(vcpu->kvm))
		return 0;

	if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED) &&
	    kvm_read_cr0(vcpu) & X86_CR0_CD)
		return _PAGE_NOCACHE;

	mtrr = kvm_mtrr_get_guest_memory_type(vcpu, gfn);
	return mtrr2protval[mtrr];
}

static void init_vmcb(struct vcpu_svm *svm, bool init_event)
static void init_vmcb(struct vcpu_svm *svm, bool init_event)
{
{
	struct vmcb_control_area *control = &svm->vmcb->control;
	struct vmcb_control_area *control = &svm->vmcb->control;
@@ -1278,7 +1182,6 @@ static void init_vmcb(struct vcpu_svm *svm, bool init_event)
		clr_cr_intercept(svm, INTERCEPT_CR3_READ);
		clr_cr_intercept(svm, INTERCEPT_CR3_READ);
		clr_cr_intercept(svm, INTERCEPT_CR3_WRITE);
		clr_cr_intercept(svm, INTERCEPT_CR3_WRITE);
		save->g_pat = svm->vcpu.arch.pat;
		save->g_pat = svm->vcpu.arch.pat;
		svm_set_guest_pat(svm, &save->g_pat);
		save->cr3 = 0;
		save->cr3 = 0;
		save->cr4 = 0;
		save->cr4 = 0;
	}
	}
@@ -1673,10 +1576,13 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)


	if (!vcpu->fpu_active)
	if (!vcpu->fpu_active)
		cr0 |= X86_CR0_TS;
		cr0 |= X86_CR0_TS;

	/*
	/* These are emulated via page tables.  */
	 * re-enable caching here because the QEMU bios
	 * does not do it - this results in some delay at
	 * reboot
	 */
	if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
		cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
		cr0 &= ~(X86_CR0_CD | X86_CR0_NW);

	svm->vmcb->save.cr0 = cr0;
	svm->vmcb->save.cr0 = cr0;
	mark_dirty(svm->vmcb, VMCB_CR);
	mark_dirty(svm->vmcb, VMCB_CR);
	update_cr0_intercept(svm);
	update_cr0_intercept(svm);
@@ -3351,16 +3257,6 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
	case MSR_VM_IGNNE:
	case MSR_VM_IGNNE:
		vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
		vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
		break;
		break;
	case MSR_IA32_CR_PAT:
		if (npt_enabled) {
			if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
				return 1;
			vcpu->arch.pat = data;
			svm_set_guest_pat(svm, &svm->vmcb->save.g_pat);
			mark_dirty(svm->vmcb, VMCB_NPT);
			break;
		}
		/* fall through */
	default:
	default:
		return kvm_set_msr_common(vcpu, msr);
		return kvm_set_msr_common(vcpu, msr);
	}
	}
@@ -4195,6 +4091,11 @@ static bool svm_has_high_real_mode_segbase(void)
	return true;
	return true;
}
}


static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
{
	return 0;
}

static void svm_cpuid_update(struct kvm_vcpu *vcpu)
static void svm_cpuid_update(struct kvm_vcpu *vcpu)
{
{
}
}
+8 −3
Original line number Original line Diff line number Diff line
@@ -8617,17 +8617,22 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
	u64 ipat = 0;
	u64 ipat = 0;


	/* For VT-d and EPT combination
	/* For VT-d and EPT combination
	 * 1. MMIO: guest may want to apply WC, trust it.
	 * 1. MMIO: always map as UC
	 * 2. EPT with VT-d:
	 * 2. EPT with VT-d:
	 *   a. VT-d without snooping control feature: can't guarantee the
	 *   a. VT-d without snooping control feature: can't guarantee the
	 *	result, try to trust guest.  So the same as item 1.
	 *	result, try to trust guest.
	 *   b. VT-d with snooping control feature: snooping control feature of
	 *   b. VT-d with snooping control feature: snooping control feature of
	 *	VT-d engine can guarantee the cache correctness. Just set it
	 *	VT-d engine can guarantee the cache correctness. Just set it
	 *	to WB to keep consistent with host. So the same as item 3.
	 *	to WB to keep consistent with host. So the same as item 3.
	 * 3. EPT without VT-d: always map as WB and set IPAT=1 to keep
	 * 3. EPT without VT-d: always map as WB and set IPAT=1 to keep
	 *    consistent with host MTRR
	 *    consistent with host MTRR
	 */
	 */
	if (!is_mmio && !kvm_arch_has_noncoherent_dma(vcpu->kvm)) {
	if (is_mmio) {
		cache = MTRR_TYPE_UNCACHABLE;
		goto exit;
	}

	if (!kvm_arch_has_noncoherent_dma(vcpu->kvm)) {
		ipat = VMX_EPT_IPAT_BIT;
		ipat = VMX_EPT_IPAT_BIT;
		cache = MTRR_TYPE_WRBACK;
		cache = MTRR_TYPE_WRBACK;
		goto exit;
		goto exit;
+0 −4
Original line number Original line Diff line number Diff line
@@ -1708,8 +1708,6 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
		vcpu->pvclock_set_guest_stopped_request = false;
		vcpu->pvclock_set_guest_stopped_request = false;
	}
	}


	pvclock_flags |= PVCLOCK_COUNTS_FROM_ZERO;

	/* If the host uses TSC clocksource, then it is stable */
	/* If the host uses TSC clocksource, then it is stable */
	if (use_master_clock)
	if (use_master_clock)
		pvclock_flags |= PVCLOCK_TSC_STABLE_BIT;
		pvclock_flags |= PVCLOCK_TSC_STABLE_BIT;
@@ -2007,8 +2005,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
					&vcpu->requests);
					&vcpu->requests);


			ka->boot_vcpu_runs_old_kvmclock = tmp;
			ka->boot_vcpu_runs_old_kvmclock = tmp;

			ka->kvmclock_offset = -get_kernel_ns();
		}
		}


		vcpu->arch.time = data;
		vcpu->arch.time = data;