Commit 4d9a6775 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-x86-misc-6.15' of https://github.com/kvm-x86/linux into HEAD

KVM x86 misc changes for 6.15:

 - Fix a bug in PIC emulation that caused KVM to emit a spurious KVM_REQ_EVENT.

 - Add a helper to consolidate handling of mp_state transitions, and use it to
   clear pv_unhalted whenever a vCPU is made RUNNABLE.

 - Defer runtime CPUID updates until KVM emulates a CPUID instruction, to
   coalesce updates when multiple pieces of vCPU state are changing, e.g. as
   part of a nested transition.

 - Fix a variety of nested emulation bugs, and add VMX support for synthesizing
   nested VM-Exit on interception (instead of injecting #UD into L2).

 - Drop "support" for PV Async #PF with proctected guests without SEND_ALWAYS,
   as KVM can't get the current CPL.

 - Misc cleanups
parents 4286a3ec e6c8728a
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -881,6 +881,7 @@ struct kvm_vcpu_arch {

	int cpuid_nent;
	struct kvm_cpuid_entry2 *cpuid_entries;
	bool cpuid_dynamic_bits_dirty;
	bool is_amd_compatible;

	/*
@@ -998,8 +999,8 @@ struct kvm_vcpu_arch {
		u64 msr_int_val; /* MSR_KVM_ASYNC_PF_INT */
		u16 vec;
		u32 id;
		bool send_user_only;
		u32 host_apf_flags;
		bool send_always;
		bool delivery_as_pf_vmexit;
		bool pageready_pending;
	} apf;
@@ -1355,8 +1356,6 @@ struct kvm_arch {

	u64 shadow_mmio_value;

	struct iommu_domain *iommu_domain;
	bool iommu_noncoherent;
#define __KVM_HAVE_ARCH_NONCOHERENT_DMA
	atomic_t noncoherent_dma_count;
#define __KVM_HAVE_ARCH_ASSIGNED_DEVICE
@@ -2166,8 +2165,8 @@ int kvm_emulate_rdpmc(struct kvm_vcpu *vcpu);
void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned long payload);
void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr);
void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr,
			   bool has_error_code, u32 error_code);
void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
void kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu,
				    struct x86_exception *fault);
+28 −26
Original line number Diff line number Diff line
@@ -58,25 +58,24 @@ void __init kvm_init_xstate_sizes(void)

u32 xstate_required_size(u64 xstate_bv, bool compacted)
{
	int feature_bit = 0;
	u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
	int i;

	xstate_bv &= XFEATURE_MASK_EXTEND;
	while (xstate_bv) {
		if (xstate_bv & 0x1) {
			struct cpuid_xstate_sizes *xs = &xstate_sizes[feature_bit];
	for (i = XFEATURE_YMM; i < ARRAY_SIZE(xstate_sizes) && xstate_bv; i++) {
		struct cpuid_xstate_sizes *xs = &xstate_sizes[i];
		u32 offset;

		if (!(xstate_bv & BIT_ULL(i)))
			continue;

		/* ECX[1]: 64B alignment in compacted form */
		if (compacted)
			offset = (xs->ecx & 0x2) ? ALIGN(ret, 64) : ret;
		else
			offset = xs->ebx;
		ret = max(ret, offset + xs->eax);
		}

		xstate_bv >>= 1;
		feature_bit++;
		xstate_bv &= ~BIT_ULL(i);
	}

	return ret;
@@ -196,6 +195,7 @@ static int kvm_check_cpuid(struct kvm_vcpu *vcpu)
}

static u32 kvm_apply_cpuid_pv_features_quirk(struct kvm_vcpu *vcpu);
static void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu);

/* Check whether the supplied CPUID data is equal to what is already set for the vCPU. */
static int kvm_cpuid_check_equal(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,
@@ -300,10 +300,12 @@ static __always_inline void kvm_update_feature_runtime(struct kvm_vcpu *vcpu,
	guest_cpu_cap_change(vcpu, x86_feature, has_feature);
}

void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
static void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
{
	struct kvm_cpuid_entry2 *best;

	vcpu->arch.cpuid_dynamic_bits_dirty = false;

	best = kvm_find_cpuid_entry(vcpu, 1);
	if (best) {
		kvm_update_feature_runtime(vcpu, best, X86_FEATURE_OSXSAVE,
@@ -333,7 +335,6 @@ void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
		     cpuid_entry_has(best, X86_FEATURE_XSAVEC)))
		best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
}
EXPORT_SYMBOL_GPL(kvm_update_cpuid_runtime);

static bool kvm_cpuid_has_hyperv(struct kvm_vcpu *vcpu)
{
@@ -646,6 +647,9 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
	if (cpuid->nent < vcpu->arch.cpuid_nent)
		return -E2BIG;

	if (vcpu->arch.cpuid_dynamic_bits_dirty)
		kvm_update_cpuid_runtime(vcpu);

	if (copy_to_user(entries, vcpu->arch.cpuid_entries,
			 vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
		return -EFAULT;
@@ -1704,7 +1708,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
			phys_as = entry->eax & 0xff;
			g_phys_as = phys_as;
			if (kvm_mmu_get_max_tdp_level() < 5)
				g_phys_as = min(g_phys_as, 48);
				g_phys_as = min(g_phys_as, 48U);
		}

		entry->eax = phys_as | (virt_as << 8) | (g_phys_as << 16);
@@ -1769,13 +1773,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)

		cpuid_entry_override(entry, CPUID_8000_0022_EAX);

		if (kvm_cpu_cap_has(X86_FEATURE_PERFMON_V2))
		ebx.split.num_core_pmc = kvm_pmu_cap.num_counters_gp;
		else if (kvm_cpu_cap_has(X86_FEATURE_PERFCTR_CORE))
			ebx.split.num_core_pmc = AMD64_NUM_COUNTERS_CORE;
		else
			ebx.split.num_core_pmc = AMD64_NUM_COUNTERS;

		entry->ebx = ebx.full;
		break;
	}
@@ -1985,6 +1983,9 @@ bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
	struct kvm_cpuid_entry2 *entry;
	bool exact, used_max_basic = false;

	if (vcpu->arch.cpuid_dynamic_bits_dirty)
		kvm_update_cpuid_runtime(vcpu);

	entry = kvm_find_cpuid_entry_index(vcpu, function, index);
	exact = !!entry;

@@ -2000,7 +2001,8 @@ bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
		*edx = entry->edx;
		if (function == 7 && index == 0) {
			u64 data;
		        if (!__kvm_get_msr(vcpu, MSR_IA32_TSX_CTRL, &data, true) &&
			if ((*ebx & (feature_bit(RTM) | feature_bit(HLE))) &&
			    !__kvm_get_msr(vcpu, MSR_IA32_TSX_CTRL, &data, true) &&
			    (data & TSX_CTRL_CPUID_CLEAR))
				*ebx &= ~(feature_bit(RTM) | feature_bit(HLE));
		} else if (function == 0x80000007) {
+8 −1
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@ extern u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
void kvm_set_cpu_caps(void);

void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu);
void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu);
struct kvm_cpuid_entry2 *kvm_find_cpuid_entry_index(struct kvm_vcpu *vcpu,
						    u32 function, u32 index);
struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
@@ -232,6 +231,14 @@ static __always_inline bool guest_cpu_cap_has(struct kvm_vcpu *vcpu,
{
	unsigned int x86_leaf = __feature_leaf(x86_feature);

	/*
	 * Except for MWAIT, querying dynamic feature bits is disallowed, so
	 * that KVM can defer runtime updates until the next CPUID emulation.
	 */
	BUILD_BUG_ON(x86_feature == X86_FEATURE_APIC ||
		     x86_feature == X86_FEATURE_OSXSAVE ||
		     x86_feature == X86_FEATURE_OSPKE);

	return vcpu->arch.cpu_caps[x86_leaf] & __feature_bit(x86_feature);
}

+4 −1
Original line number Diff line number Diff line
@@ -477,8 +477,11 @@ static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt,
		.dst_val    = ctxt->dst.val64,
		.src_bytes  = ctxt->src.bytes,
		.dst_bytes  = ctxt->dst.bytes,
		.src_type   = ctxt->src.type,
		.dst_type   = ctxt->dst.type,
		.ad_bytes   = ctxt->ad_bytes,
		.next_rip   = ctxt->eip,
		.rip	    = ctxt->eip,
		.next_rip   = ctxt->_eip,
	};

	return ctxt->ops->intercept(ctxt, &info, stage);
+1 −1
Original line number Diff line number Diff line
@@ -567,7 +567,7 @@ static void pic_irq_request(struct kvm *kvm, int level)
{
	struct kvm_pic *s = kvm->arch.vpic;

	if (!s->output)
	if (!s->output && level)
		s->wakeup_needed = true;
	s->output = level;
}
Loading