Commit f5396f2d authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge branch 'kvm-5.16-fixes' into kvm-master

* Fix misuse of gfn-to-pfn cache when recording guest steal time / preempted status

* Fix selftests on APICv machines

* Fix sparse warnings

* Fix detection of KVM features in CPUID

* Cleanups for bogus writes to MSR_KVM_PV_EOI_EN

* Fixes and cleanups for MSR bitmap handling

* Cleanups for INVPCID

* Make x86 KVM_SOFT_MAX_VCPUS consistent with other architectures
parents 1f058331 da1bfd52
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@
#define __KVM_HAVE_ARCH_VCPU_DEBUGFS

#define KVM_MAX_VCPUS 1024
#define KVM_SOFT_MAX_VCPUS 710

/*
 * In x86, the VCPU ID corresponds to the APIC ID, and APIC IDs
@@ -725,6 +724,7 @@ struct kvm_vcpu_arch {

	int cpuid_nent;
	struct kvm_cpuid_entry2 *cpuid_entries;
	u32 kvm_cpuid_base;

	u64 reserved_gpa_bits;
	int maxphyaddr;
@@ -748,7 +748,7 @@ struct kvm_vcpu_arch {
		u8 preempted;
		u64 msr_val;
		u64 last_steal;
		struct gfn_to_pfn_cache cache;
		struct gfn_to_hva_cache cache;
	} st;

	u64 l1_tsc_offset;
@@ -1034,6 +1034,7 @@ struct kvm_x86_msr_filter {
#define APICV_INHIBIT_REASON_IRQWIN     3
#define APICV_INHIBIT_REASON_PIT_REINJ  4
#define APICV_INHIBIT_REASON_X2APIC	5
#define APICV_INHIBIT_REASON_BLOCKIRQ	6

struct kvm_arch {
	unsigned long n_used_mmu_pages;
+4 −1
Original line number Diff line number Diff line
@@ -806,11 +806,14 @@ static inline u32 amd_get_nodes_per_socket(void) { return 0; }
static inline u32 amd_get_highest_perf(void)		{ return 0; }
#endif

#define for_each_possible_hypervisor_cpuid_base(function) \
	for (function = 0x40000000; function < 0x40010000; function += 0x100)

static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
{
	uint32_t base, eax, signature[3];

	for (base = 0x40000000; base < 0x40010000; base += 0x100) {
	for_each_possible_hypervisor_cpuid_base(base) {
		cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);

		if (!memcmp(sig, signature, 12) &&
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 * should be used to determine that a VM is running under KVM.
 */
#define KVM_CPUID_SIGNATURE	0x40000000
#define KVM_SIGNATURE "KVMKVMKVM\0\0\0"

/* This CPUID returns two feature bitmaps in eax, edx. Before enabling
 * a particular paravirtualization, the appropriate feature bit should
+1 −1
Original line number Diff line number Diff line
@@ -809,7 +809,7 @@ static noinline uint32_t __kvm_cpuid_base(void)
		return 0;	/* So we don't blow up on old processors */

	if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
		return hypervisor_cpuid_base("KVMKVMKVM\0\0\0", 0);
		return hypervisor_cpuid_base(KVM_SIGNATURE, 0);

	return 0;
}
+64 −29
Original line number Diff line number Diff line
@@ -99,11 +99,45 @@ static int kvm_check_cpuid(struct kvm_cpuid_entry2 *entries, int nent)
	return 0;
}

void kvm_update_pv_runtime(struct kvm_vcpu *vcpu)
static void kvm_update_kvm_cpuid_base(struct kvm_vcpu *vcpu)
{
	struct kvm_cpuid_entry2 *best;
	u32 function;
	struct kvm_cpuid_entry2 *entry;

	vcpu->arch.kvm_cpuid_base = 0;

	for_each_possible_hypervisor_cpuid_base(function) {
		entry = kvm_find_cpuid_entry(vcpu, function, 0);

		if (entry) {
			u32 signature[3];

			signature[0] = entry->ebx;
			signature[1] = entry->ecx;
			signature[2] = entry->edx;

	best = kvm_find_cpuid_entry(vcpu, KVM_CPUID_FEATURES, 0);
			BUILD_BUG_ON(sizeof(signature) > sizeof(KVM_SIGNATURE));
			if (!memcmp(signature, KVM_SIGNATURE, sizeof(signature))) {
				vcpu->arch.kvm_cpuid_base = function;
				break;
			}
		}
	}
}

struct kvm_cpuid_entry2 *kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu)
{
	u32 base = vcpu->arch.kvm_cpuid_base;

	if (!base)
		return NULL;

	return kvm_find_cpuid_entry(vcpu, base | KVM_CPUID_FEATURES, 0);
}

void kvm_update_pv_runtime(struct kvm_vcpu *vcpu)
{
	struct kvm_cpuid_entry2 *best = kvm_find_kvm_cpuid_features(vcpu);

	/*
	 * save the feature bitmap to avoid cpuid lookup for every PV
@@ -142,7 +176,7 @@ 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);

	best = kvm_find_cpuid_entry(vcpu, KVM_CPUID_FEATURES, 0);
	best = kvm_find_kvm_cpuid_features(vcpu);
	if (kvm_hlt_in_guest(vcpu->kvm) && best &&
		(best->eax & (1 << KVM_FEATURE_PV_UNHALT)))
		best->eax &= ~(1 << KVM_FEATURE_PV_UNHALT);
@@ -239,6 +273,26 @@ u64 kvm_vcpu_reserved_gpa_bits_raw(struct kvm_vcpu *vcpu)
	return rsvd_bits(cpuid_maxphyaddr(vcpu), 63);
}

static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,
                        int nent)
{
    int r;

    r = kvm_check_cpuid(e2, nent);
    if (r)
        return r;

    kvfree(vcpu->arch.cpuid_entries);
    vcpu->arch.cpuid_entries = e2;
    vcpu->arch.cpuid_nent = nent;

    kvm_update_kvm_cpuid_base(vcpu);
    kvm_update_cpuid_runtime(vcpu);
    kvm_vcpu_after_set_cpuid(vcpu);

    return 0;
}

/* when an old userspace process fills a new kernel module */
int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
			     struct kvm_cpuid *cpuid,
@@ -275,18 +329,9 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
		e2[i].padding[2] = 0;
	}

	r = kvm_check_cpuid(e2, cpuid->nent);
	if (r) {
	r = kvm_set_cpuid(vcpu, e2, cpuid->nent);
	if (r)
		kvfree(e2);
		goto out_free_cpuid;
	}

	kvfree(vcpu->arch.cpuid_entries);
	vcpu->arch.cpuid_entries = e2;
	vcpu->arch.cpuid_nent = cpuid->nent;

	kvm_update_cpuid_runtime(vcpu);
	kvm_vcpu_after_set_cpuid(vcpu);

out_free_cpuid:
	kvfree(e);
@@ -310,20 +355,11 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
			return PTR_ERR(e2);
	}

	r = kvm_check_cpuid(e2, cpuid->nent);
	if (r) {
	r = kvm_set_cpuid(vcpu, e2, cpuid->nent);
	if (r)
		kvfree(e2);
		return r;
	}

	kvfree(vcpu->arch.cpuid_entries);
	vcpu->arch.cpuid_entries = e2;
	vcpu->arch.cpuid_nent = cpuid->nent;

	kvm_update_cpuid_runtime(vcpu);
	kvm_vcpu_after_set_cpuid(vcpu);

	return 0;
	return r;
}

int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
@@ -871,8 +907,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
		}
		break;
	case KVM_CPUID_SIGNATURE: {
		static const char signature[12] = "KVMKVMKVM\0\0";
		const u32 *sigptr = (const u32 *)signature;
		const u32 *sigptr = (const u32 *)KVM_SIGNATURE;
		entry->eax = KVM_CPUID_FEATURES;
		entry->ebx = sigptr[0];
		entry->ecx = sigptr[1];
Loading