kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement
@ 2021-01-26 13:48 Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 01/15] selftests: kvm: Move kvm_get_supported_hv_cpuid() to common code Vitaly Kuznetsov
                   ` (15 more replies)
  0 siblings, 16 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

Changes since v1 [Sean]:
- Add a few cleanup patches ("Rename vcpu_to_hv_vcpu() to to_hv_vcpu()",
  "Rename vcpu_to_synic()/synic_to_vcpu()", ...)
- Drop unused kvm_hv_vapic_assist_page_enabled()
- Stop shadowing global 'current_vcpu' variable in kvm_hv_flush_tlb()/
  kvm_hv_send_ipi()

Original description:

Hyper-V emulation is enabled in KVM unconditionally even for Linux guests.
This is bad at least from security standpoint as it is an extra attack
surface. Ideally, there should be a per-VM capability explicitly enabled by
VMM but currently it is not the case and we can't mandate one without
breaking backwards compatibility. We can, however, check guest visible CPUIDs
and only enable Hyper-V emulation when "Hv#1" interface was exposed in
HYPERV_CPUID_INTERFACE.

Also (and while on it) per-vcpu Hyper-V context ('struct kvm_vcpu_hv') is
currently part of 'struct kvm_vcpu_arch' and thus allocated unconditionally
for each vCPU. The context, however, quite big and accounts for more than
1/4 of 'struct kvm_vcpu_arch' (e.g. 2912/9512 bytes). Switch to allocating
it dynamically. This may come handy if we ever decide to raise KVM_MAX_VCPUS
(and rumor has it some downstream distributions already have more than '288')

Vitaly Kuznetsov (15):
  selftests: kvm: Move kvm_get_supported_hv_cpuid() to common code
  selftests: kvm: Properly set Hyper-V CPUIDs in evmcs_test
  KVM: x86: hyper-v: Drop unused kvm_hv_vapic_assist_page_enabled()
  KVM: x86: hyper-v: Rename vcpu_to_hv_vcpu() to to_hv_vcpu()
  KVM: x86: hyper-v: Rename vcpu_to_synic()/synic_to_vcpu()
  KVM: x86: hyper-v: Rename vcpu_to_stimer()/stimer_to_vcpu()
  KVM: x86: hyper-v: Rename vcpu_to_hv_syndbg() to to_hv_syndbg()
  KVM: x86: hyper-v: Introduce to_kvm_hv() helper
  KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable
  KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct
    kvm_vcpu_hv'
  KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context
  KVM: x86: hyper-v: Allocate 'struct kvm_vcpu_hv' dynamically
  KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional
  KVM: x86: hyper-v: Allocate Hyper-V context lazily
  KVM: x86: hyper-v: Drop hv_vcpu_to_vcpu() helper

 arch/x86/include/asm/kvm_host.h               |   4 +-
 arch/x86/kvm/cpuid.c                          |   2 +
 arch/x86/kvm/hyperv.c                         | 301 +++++++++++-------
 arch/x86/kvm/hyperv.h                         |  54 ++--
 arch/x86/kvm/lapic.c                          |   5 +-
 arch/x86/kvm/lapic.h                          |   7 +-
 arch/x86/kvm/vmx/vmx.c                        |   9 +-
 arch/x86/kvm/x86.c                            |  19 +-
 .../selftests/kvm/include/x86_64/processor.h  |   3 +
 .../selftests/kvm/lib/x86_64/processor.c      |  33 ++
 .../testing/selftests/kvm/x86_64/evmcs_test.c |  39 ++-
 .../selftests/kvm/x86_64/hyperv_cpuid.c       |  31 +-
 12 files changed, 314 insertions(+), 193 deletions(-)

-- 
2.29.2


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 01/15] selftests: kvm: Move kvm_get_supported_hv_cpuid() to common code
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 02/15] selftests: kvm: Properly set Hyper-V CPUIDs in evmcs_test Vitaly Kuznetsov
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

kvm_get_supported_hv_cpuid() may come handy in all Hyper-V related tests.
Split it off hyperv_cpuid test, create system-wide and vcpu versions.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 .../selftests/kvm/include/x86_64/processor.h  |  3 ++
 .../selftests/kvm/lib/x86_64/processor.c      | 33 +++++++++++++++++++
 .../selftests/kvm/x86_64/hyperv_cpuid.c       | 31 ++---------------
 3 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h
index 90cd5984751b..53c634a462f2 100644
--- a/tools/testing/selftests/kvm/include/x86_64/processor.h
+++ b/tools/testing/selftests/kvm/include/x86_64/processor.h
@@ -391,6 +391,9 @@ bool set_cpuid(struct kvm_cpuid2 *cpuid, struct kvm_cpuid_entry2 *ent);
 uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2,
 		       uint64_t a3);
 
+struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void);
+struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vm *vm, uint32_t vcpuid);
+
 /*
  * Basic CPU control in CR0
  */
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
index 95e1a757c629..efb540c90732 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
@@ -1224,3 +1224,36 @@ uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2,
 		     : "b"(a0), "c"(a1), "d"(a2), "S"(a3));
 	return r;
 }
+
+struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void)
+{
+	static struct kvm_cpuid2 *cpuid;
+	int ret;
+	int kvm_fd;
+
+	if (cpuid)
+		return cpuid;
+
+	cpuid = allocate_kvm_cpuid2();
+	kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
+	if (kvm_fd < 0)
+		exit(KSFT_SKIP);
+
+	ret = ioctl(kvm_fd, KVM_GET_SUPPORTED_HV_CPUID, cpuid);
+	TEST_ASSERT(ret == 0, "KVM_GET_SUPPORTED_HV_CPUID failed %d %d\n",
+		    ret, errno);
+
+	close(kvm_fd);
+	return cpuid;
+}
+
+struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vm *vm, uint32_t vcpuid)
+{
+	static struct kvm_cpuid2 *cpuid;
+
+	cpuid = allocate_kvm_cpuid2();
+
+	vcpu_ioctl(vm, vcpuid, KVM_GET_SUPPORTED_HV_CPUID, cpuid);
+
+	return cpuid;
+}
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c b/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c
index 88a595b7fbdd..7e2d2d17d2ed 100644
--- a/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c
+++ b/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c
@@ -125,30 +125,6 @@ void test_hv_cpuid_e2big(struct kvm_vm *vm, bool system)
 		    " it should have: %d %d", system ? "KVM" : "vCPU", ret, errno);
 }
 
-
-struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(struct kvm_vm *vm, bool system)
-{
-	int nent = 20; /* should be enough */
-	static struct kvm_cpuid2 *cpuid;
-
-	cpuid = malloc(sizeof(*cpuid) + nent * sizeof(struct kvm_cpuid_entry2));
-
-	if (!cpuid) {
-		perror("malloc");
-		abort();
-	}
-
-	cpuid->nent = nent;
-
-	if (!system)
-		vcpu_ioctl(vm, VCPU_ID, KVM_GET_SUPPORTED_HV_CPUID, cpuid);
-	else
-		kvm_ioctl(vm, KVM_GET_SUPPORTED_HV_CPUID, cpuid);
-
-	return cpuid;
-}
-
-
 int main(int argc, char *argv[])
 {
 	struct kvm_vm *vm;
@@ -167,7 +143,7 @@ int main(int argc, char *argv[])
 	/* Test vCPU ioctl version */
 	test_hv_cpuid_e2big(vm, false);
 
-	hv_cpuid_entries = kvm_get_supported_hv_cpuid(vm, false);
+	hv_cpuid_entries = vcpu_get_supported_hv_cpuid(vm, VCPU_ID);
 	test_hv_cpuid(hv_cpuid_entries, false);
 	free(hv_cpuid_entries);
 
@@ -177,7 +153,7 @@ int main(int argc, char *argv[])
 		goto do_sys;
 	}
 	vcpu_enable_evmcs(vm, VCPU_ID);
-	hv_cpuid_entries = kvm_get_supported_hv_cpuid(vm, false);
+	hv_cpuid_entries = vcpu_get_supported_hv_cpuid(vm, VCPU_ID);
 	test_hv_cpuid(hv_cpuid_entries, true);
 	free(hv_cpuid_entries);
 
@@ -190,9 +166,8 @@ int main(int argc, char *argv[])
 
 	test_hv_cpuid_e2big(vm, true);
 
-	hv_cpuid_entries = kvm_get_supported_hv_cpuid(vm, true);
+	hv_cpuid_entries = kvm_get_supported_hv_cpuid();
 	test_hv_cpuid(hv_cpuid_entries, nested_vmx_supported());
-	free(hv_cpuid_entries);
 
 out:
 	kvm_vm_free(vm);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 02/15] selftests: kvm: Properly set Hyper-V CPUIDs in evmcs_test
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 01/15] selftests: kvm: Move kvm_get_supported_hv_cpuid() to common code Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 03/15] KVM: x86: hyper-v: Drop unused kvm_hv_vapic_assist_page_enabled() Vitaly Kuznetsov
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

Generally, when Hyper-V emulation is enabled, VMM is supposed to set
Hyper-V CPUID identifications so the guest knows that Hyper-V features
are available. evmcs_test doesn't currently do that but so far Hyper-V
emulation in KVM was enabled unconditionally. As we are about to change
that, proper Hyper-V CPUID identification should be set in selftests as
well.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 .../testing/selftests/kvm/x86_64/evmcs_test.c | 39 ++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/x86_64/evmcs_test.c b/tools/testing/selftests/kvm/x86_64/evmcs_test.c
index 37b8a78f6b74..39a3cb2bd103 100644
--- a/tools/testing/selftests/kvm/x86_64/evmcs_test.c
+++ b/tools/testing/selftests/kvm/x86_64/evmcs_test.c
@@ -78,6 +78,42 @@ void guest_code(struct vmx_pages *vmx_pages)
 	GUEST_ASSERT(vmlaunch());
 }
 
+struct kvm_cpuid2 *guest_get_cpuid(void)
+{
+	static struct kvm_cpuid2 *cpuid_full;
+	struct kvm_cpuid2 *cpuid_sys, *cpuid_hv;
+	int i, nent = 0;
+
+	if (cpuid_full)
+		return cpuid_full;
+
+	cpuid_sys = kvm_get_supported_cpuid();
+	cpuid_hv = kvm_get_supported_hv_cpuid();
+
+	cpuid_full = malloc(sizeof(*cpuid_full) +
+			    (cpuid_sys->nent + cpuid_hv->nent) *
+			    sizeof(struct kvm_cpuid_entry2));
+	if (!cpuid_full) {
+		perror("malloc");
+		abort();
+	}
+
+	/* Need to skip KVM CPUID leaves 0x400000xx */
+	for (i = 0; i < cpuid_sys->nent; i++) {
+		if (cpuid_sys->entries[i].function >= 0x40000000 &&
+		    cpuid_sys->entries[i].function < 0x40000100)
+			continue;
+		cpuid_full->entries[nent] = cpuid_sys->entries[i];
+		nent++;
+	}
+
+	memcpy(&cpuid_full->entries[nent], cpuid_hv->entries,
+	       cpuid_hv->nent * sizeof(struct kvm_cpuid_entry2));
+	cpuid_full->nent = nent + cpuid_hv->nent;
+
+	return cpuid_full;
+}
+
 int main(int argc, char *argv[])
 {
 	vm_vaddr_t vmx_pages_gva = 0;
@@ -99,6 +135,7 @@ int main(int argc, char *argv[])
 		exit(KSFT_SKIP);
 	}
 
+	vcpu_set_cpuid(vm, VCPU_ID, guest_get_cpuid());
 	vcpu_enable_evmcs(vm, VCPU_ID);
 
 	run = vcpu_state(vm, VCPU_ID);
@@ -142,7 +179,7 @@ int main(int argc, char *argv[])
 		/* Restore state in a new VM.  */
 		kvm_vm_restart(vm, O_RDWR);
 		vm_vcpu_add(vm, VCPU_ID);
-		vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid());
+		vcpu_set_cpuid(vm, VCPU_ID, guest_get_cpuid());
 		vcpu_enable_evmcs(vm, VCPU_ID);
 		vcpu_load_state(vm, VCPU_ID, state);
 		run = vcpu_state(vm, VCPU_ID);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 03/15] KVM: x86: hyper-v: Drop unused kvm_hv_vapic_assist_page_enabled()
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 01/15] selftests: kvm: Move kvm_get_supported_hv_cpuid() to common code Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 02/15] selftests: kvm: Properly set Hyper-V CPUIDs in evmcs_test Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 04/15] KVM: x86: hyper-v: Rename vcpu_to_hv_vcpu() to to_hv_vcpu() Vitaly Kuznetsov
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

kvm_hv_vapic_assist_page_enabled() seems to be unused since its
introduction in commit 10388a07164c1 ("KVM: Add HYPER-V apic access MSRs"),
drop it.

Reported-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/lapic.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 4fb86e3a9dd3..4de7579e206c 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -125,11 +125,6 @@ int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
 int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data);
 int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
 
-static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
-{
-	return vcpu->arch.hyperv.hv_vapic & HV_X64_MSR_VP_ASSIST_PAGE_ENABLE;
-}
-
 int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data, unsigned long len);
 void kvm_lapic_init(void);
 void kvm_lapic_exit(void);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 04/15] KVM: x86: hyper-v: Rename vcpu_to_hv_vcpu() to to_hv_vcpu()
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (2 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 03/15] KVM: x86: hyper-v: Drop unused kvm_hv_vapic_assist_page_enabled() Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 05/15] KVM: x86: hyper-v: Rename vcpu_to_synic()/synic_to_vcpu() Vitaly Kuznetsov
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

vcpu_to_hv_vcpu()'s argument is almost always 'vcpu' so there's
no need to have an additional prefix. Also, this makes the code
more consistent with vmx/svm where to_vmx()/to_svm() are being
used.

No functional change intended.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 24 ++++++++++++------------
 arch/x86/kvm/hyperv.h |  4 ++--
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 922c69dcca4d..1a3bac5de897 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -141,10 +141,10 @@ static struct kvm_vcpu *get_vcpu_by_vpidx(struct kvm *kvm, u32 vpidx)
 		return NULL;
 
 	vcpu = kvm_get_vcpu(kvm, vpidx);
-	if (vcpu && vcpu_to_hv_vcpu(vcpu)->vp_index == vpidx)
+	if (vcpu && to_hv_vcpu(vcpu)->vp_index == vpidx)
 		return vcpu;
 	kvm_for_each_vcpu(i, vcpu, kvm)
-		if (vcpu_to_hv_vcpu(vcpu)->vp_index == vpidx)
+		if (to_hv_vcpu(vcpu)->vp_index == vpidx)
 			return vcpu;
 	return NULL;
 }
@@ -165,7 +165,7 @@ static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
 {
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
-	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 	struct kvm_vcpu_hv_stimer *stimer;
 	int gsi, idx;
 
@@ -316,7 +316,7 @@ static int syndbg_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 		return 1;
 
 	trace_kvm_hv_syndbg_set_msr(vcpu->vcpu_id,
-				    vcpu_to_hv_vcpu(vcpu)->vp_index, msr, data);
+				    to_hv_vcpu(vcpu)->vp_index, msr, data);
 	switch (msr) {
 	case HV_X64_MSR_SYNDBG_CONTROL:
 		syndbg->control.control = data;
@@ -378,7 +378,7 @@ static int syndbg_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host)
 	}
 
 	trace_kvm_hv_syndbg_get_msr(vcpu->vcpu_id,
-				    vcpu_to_hv_vcpu(vcpu)->vp_index, msr,
+				    to_hv_vcpu(vcpu)->vp_index, msr,
 				    *pdata);
 
 	return 0;
@@ -537,7 +537,7 @@ static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,
 	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
 
 	set_bit(stimer->index,
-		vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+		to_hv_vcpu(vcpu)->stimer_pending_bitmap);
 	kvm_make_request(KVM_REQ_HV_STIMER, vcpu);
 	if (vcpu_kick)
 		kvm_vcpu_kick(vcpu);
@@ -552,7 +552,7 @@ static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer)
 
 	hrtimer_cancel(&stimer->timer);
 	clear_bit(stimer->index,
-		  vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap);
+		  to_hv_vcpu(vcpu)->stimer_pending_bitmap);
 	stimer->msg_pending = false;
 	stimer->exp_time = 0;
 }
@@ -801,7 +801,7 @@ static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
 
 void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 	struct kvm_vcpu_hv_stimer *stimer;
 	u64 time_now, exp_time;
 	int i;
@@ -831,7 +831,7 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
 
 void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
@@ -882,7 +882,7 @@ static void stimer_init(struct kvm_vcpu_hv_stimer *stimer, int timer_index)
 
 void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 	int i;
 
 	synic_init(&hv_vcpu->synic);
@@ -894,7 +894,7 @@ void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
 
 void kvm_hv_vcpu_postcreate(struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu_hv *hv_vcpu = vcpu_to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
 	hv_vcpu->vp_index = kvm_vcpu_get_idx(vcpu);
 }
@@ -1483,7 +1483,7 @@ static __always_inline unsigned long *sparse_set_to_vcpu_mask(
 
 	bitmap_zero(vcpu_bitmap, KVM_MAX_VCPUS);
 	kvm_for_each_vcpu(i, vcpu, kvm) {
-		if (test_bit(vcpu_to_hv_vcpu(vcpu)->vp_index,
+		if (test_bit(to_hv_vcpu(vcpu)->vp_index,
 			     (unsigned long *)vp_bitmap))
 			__set_bit(i, vcpu_bitmap);
 	}
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 6d7def2b0aad..f5e0d3d1d54a 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -50,7 +50,7 @@
 /* Hyper-V HV_X64_MSR_SYNDBG_OPTIONS bits */
 #define HV_X64_SYNDBG_OPTION_USE_HCALLS		BIT(2)
 
-static inline struct kvm_vcpu_hv *vcpu_to_hv_vcpu(struct kvm_vcpu *vcpu)
+static inline struct kvm_vcpu_hv *to_hv_vcpu(struct kvm_vcpu *vcpu)
 {
 	return &vcpu->arch.hyperv;
 }
@@ -100,7 +100,7 @@ bool kvm_hv_get_assist_page(struct kvm_vcpu *vcpu,
 static inline struct kvm_vcpu_hv_stimer *vcpu_to_stimer(struct kvm_vcpu *vcpu,
 							int timer_index)
 {
-	return &vcpu_to_hv_vcpu(vcpu)->stimer[timer_index];
+	return &to_hv_vcpu(vcpu)->stimer[timer_index];
 }
 
 static inline struct kvm_vcpu *stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stimer)
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 05/15] KVM: x86: hyper-v: Rename vcpu_to_synic()/synic_to_vcpu()
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (3 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 04/15] KVM: x86: hyper-v: Rename vcpu_to_hv_vcpu() to to_hv_vcpu() Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 06/15] KVM: x86: hyper-v: Rename vcpu_to_stimer()/stimer_to_vcpu() Vitaly Kuznetsov
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

vcpu_to_synic()'s argument is almost always 'vcpu' so there's no need to
have an additional prefix. Also, as this is used outside of hyper-v
emulation code, add '_hv_' part to make it clear what this s. This makes
the naming more consistent with to_hv_vcpu().

Rename synic_to_vcpu() to hv_synic_to_vcpu() for consistency.

No functional change intended.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 30 +++++++++++++++---------------
 arch/x86/kvm/hyperv.h |  4 ++--
 arch/x86/kvm/lapic.c  |  4 ++--
 arch/x86/kvm/x86.c    |  2 +-
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 1a3bac5de897..5679dca610a5 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -128,7 +128,7 @@ static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint,
 	synic_update_vector(synic, vector);
 
 	/* Load SynIC vectors into EOI exit bitmap */
-	kvm_make_request(KVM_REQ_SCAN_IOAPIC, synic_to_vcpu(synic));
+	kvm_make_request(KVM_REQ_SCAN_IOAPIC, hv_synic_to_vcpu(synic));
 	return 0;
 }
 
@@ -157,14 +157,14 @@ static struct kvm_vcpu_hv_synic *synic_get(struct kvm *kvm, u32 vpidx)
 	vcpu = get_vcpu_by_vpidx(kvm, vpidx);
 	if (!vcpu)
 		return NULL;
-	synic = vcpu_to_synic(vcpu);
+	synic = to_hv_synic(vcpu);
 	return (synic->active) ? synic : NULL;
 }
 
 static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
 {
 	struct kvm *kvm = vcpu->kvm;
-	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
+	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
 	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 	struct kvm_vcpu_hv_stimer *stimer;
 	int gsi, idx;
@@ -189,7 +189,7 @@ static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
 
 static void synic_exit(struct kvm_vcpu_hv_synic *synic, u32 msr)
 {
-	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic);
 	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
 
 	hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNIC;
@@ -204,7 +204,7 @@ static void synic_exit(struct kvm_vcpu_hv_synic *synic, u32 msr)
 static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
 			 u32 msr, u64 data, bool host)
 {
-	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic);
 	int ret;
 
 	if (!synic->active && !host)
@@ -421,7 +421,7 @@ static int synic_get_msr(struct kvm_vcpu_hv_synic *synic, u32 msr, u64 *pdata,
 
 static int synic_set_irq(struct kvm_vcpu_hv_synic *synic, u32 sint)
 {
-	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic);
 	struct kvm_lapic_irq irq;
 	int ret, vector;
 
@@ -457,7 +457,7 @@ int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vpidx, u32 sint)
 
 void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector)
 {
-	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
+	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
 	int i;
 
 	trace_kvm_hv_synic_send_eoi(vcpu->vcpu_id, vector);
@@ -634,7 +634,7 @@ static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
 	union hv_stimer_config new_config = {.as_uint64 = config},
 		old_config = {.as_uint64 = stimer->config.as_uint64};
 	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
-	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
+	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
 
 	if (!synic->active && !host)
 		return 1;
@@ -658,7 +658,7 @@ static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
 			    bool host)
 {
 	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
-	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
+	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
 
 	if (!synic->active && !host)
 		return 1;
@@ -694,7 +694,7 @@ static int stimer_get_count(struct kvm_vcpu_hv_stimer *stimer, u64 *pcount)
 static int synic_deliver_msg(struct kvm_vcpu_hv_synic *synic, u32 sint,
 			     struct hv_message *src_msg, bool no_retry)
 {
-	struct kvm_vcpu *vcpu = synic_to_vcpu(synic);
+	struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic);
 	int msg_off = offsetof(struct hv_message_page, sint_message[sint]);
 	gfn_t msg_page_gfn;
 	struct hv_message_header hv_hdr;
@@ -763,7 +763,7 @@ static int stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
 
 	payload->expiration_time = stimer->exp_time;
 	payload->delivery_time = get_time_ref_counter(vcpu->kvm);
-	return synic_deliver_msg(vcpu_to_synic(vcpu),
+	return synic_deliver_msg(to_hv_synic(vcpu),
 				 stimer->config.sintx, msg,
 				 no_retry);
 }
@@ -901,7 +901,7 @@ void kvm_hv_vcpu_postcreate(struct kvm_vcpu *vcpu)
 
 int kvm_hv_activate_synic(struct kvm_vcpu *vcpu, bool dont_zero_synic_pages)
 {
-	struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
+	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
 
 	/*
 	 * Hyper-V SynIC auto EOI SINT's are
@@ -1291,7 +1291,7 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 	case HV_X64_MSR_SIMP:
 	case HV_X64_MSR_EOM:
 	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
-		return synic_set_msr(vcpu_to_synic(vcpu), msr, data, host);
+		return synic_set_msr(to_hv_synic(vcpu), msr, data, host);
 	case HV_X64_MSR_STIMER0_CONFIG:
 	case HV_X64_MSR_STIMER1_CONFIG:
 	case HV_X64_MSR_STIMER2_CONFIG:
@@ -1403,7 +1403,7 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 	case HV_X64_MSR_SIMP:
 	case HV_X64_MSR_EOM:
 	case HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15:
-		return synic_get_msr(vcpu_to_synic(vcpu), msr, pdata, host);
+		return synic_get_msr(to_hv_synic(vcpu), msr, pdata, host);
 	case HV_X64_MSR_STIMER0_CONFIG:
 	case HV_X64_MSR_STIMER1_CONFIG:
 	case HV_X64_MSR_STIMER2_CONFIG:
@@ -1793,7 +1793,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 		fallthrough;	/* maybe userspace knows this conn_id */
 	case HVCALL_POST_MESSAGE:
 		/* don't bother userspace if it has no way to handle it */
-		if (unlikely(rep || !vcpu_to_synic(vcpu)->active)) {
+		if (unlikely(rep || !to_hv_synic(vcpu)->active)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
 			break;
 		}
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index f5e0d3d1d54a..d47b3f045a25 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -63,12 +63,12 @@ static inline struct kvm_vcpu *hv_vcpu_to_vcpu(struct kvm_vcpu_hv *hv_vcpu)
 	return container_of(arch, struct kvm_vcpu, arch);
 }
 
-static inline struct kvm_vcpu_hv_synic *vcpu_to_synic(struct kvm_vcpu *vcpu)
+static inline struct kvm_vcpu_hv_synic *to_hv_synic(struct kvm_vcpu *vcpu)
 {
 	return &vcpu->arch.hyperv.synic;
 }
 
-static inline struct kvm_vcpu *synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
+static inline struct kvm_vcpu *hv_synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
 {
 	return hv_vcpu_to_vcpu(container_of(synic, struct kvm_vcpu_hv, synic));
 }
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 43cceadd073e..53bdea2d5a81 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1245,7 +1245,7 @@ static int apic_set_eoi(struct kvm_lapic *apic)
 	apic_clear_isr(vector, apic);
 	apic_update_ppr(apic);
 
-	if (test_bit(vector, vcpu_to_synic(apic->vcpu)->vec_bitmap))
+	if (test_bit(vector, to_hv_synic(apic->vcpu)->vec_bitmap))
 		kvm_hv_synic_send_eoi(apic->vcpu, vector);
 
 	kvm_ioapic_send_eoi(apic, vector);
@@ -2512,7 +2512,7 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
 	 */
 
 	apic_clear_irr(vector, apic);
-	if (test_bit(vector, vcpu_to_synic(vcpu)->auto_eoi_bitmap)) {
+	if (test_bit(vector, to_hv_synic(vcpu)->auto_eoi_bitmap)) {
 		/*
 		 * For auto-EOI interrupts, there might be another pending
 		 * interrupt above PPR, so check whether to raise another
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9a8969a6dd06..0bf0672d4811 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8741,7 +8741,7 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
 		return;
 
 	bitmap_or((ulong *)eoi_exit_bitmap, vcpu->arch.ioapic_handled_vectors,
-		  vcpu_to_synic(vcpu)->vec_bitmap, 256);
+		  to_hv_synic(vcpu)->vec_bitmap, 256);
 	kvm_x86_ops.load_eoi_exitmap(vcpu, eoi_exit_bitmap);
 }
 
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 06/15] KVM: x86: hyper-v: Rename vcpu_to_stimer()/stimer_to_vcpu()
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (4 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 05/15] KVM: x86: hyper-v: Rename vcpu_to_synic()/synic_to_vcpu() Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 07/15] KVM: x86: hyper-v: Rename vcpu_to_hv_syndbg() to to_hv_syndbg() Vitaly Kuznetsov
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

vcpu_to_stimers()'s argument is almost always 'vcpu' so there's no need to
have an additional prefix. Also, this makes the naming more consistent with
to_hv_vcpu()/to_hv_synic().

Rename stimer_to_vcpu() to hv_stimer_to_vcpu() for consitency.

No functional change intended.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 36 ++++++++++++++++++------------------
 arch/x86/kvm/hyperv.h |  6 +++---
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 5679dca610a5..840628a21282 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -534,7 +534,7 @@ static u64 get_time_ref_counter(struct kvm *kvm)
 static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,
 				bool vcpu_kick)
 {
-	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
 
 	set_bit(stimer->index,
 		to_hv_vcpu(vcpu)->stimer_pending_bitmap);
@@ -545,9 +545,9 @@ static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,
 
 static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer)
 {
-	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
 
-	trace_kvm_hv_stimer_cleanup(stimer_to_vcpu(stimer)->vcpu_id,
+	trace_kvm_hv_stimer_cleanup(hv_stimer_to_vcpu(stimer)->vcpu_id,
 				    stimer->index);
 
 	hrtimer_cancel(&stimer->timer);
@@ -562,7 +562,7 @@ static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer)
 	struct kvm_vcpu_hv_stimer *stimer;
 
 	stimer = container_of(timer, struct kvm_vcpu_hv_stimer, timer);
-	trace_kvm_hv_stimer_callback(stimer_to_vcpu(stimer)->vcpu_id,
+	trace_kvm_hv_stimer_callback(hv_stimer_to_vcpu(stimer)->vcpu_id,
 				     stimer->index);
 	stimer_mark_pending(stimer, true);
 
@@ -579,7 +579,7 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 	u64 time_now;
 	ktime_t ktime_now;
 
-	time_now = get_time_ref_counter(stimer_to_vcpu(stimer)->kvm);
+	time_now = get_time_ref_counter(hv_stimer_to_vcpu(stimer)->kvm);
 	ktime_now = ktime_get();
 
 	if (stimer->config.periodic) {
@@ -596,7 +596,7 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 			stimer->exp_time = time_now + stimer->count;
 
 		trace_kvm_hv_stimer_start_periodic(
-					stimer_to_vcpu(stimer)->vcpu_id,
+					hv_stimer_to_vcpu(stimer)->vcpu_id,
 					stimer->index,
 					time_now, stimer->exp_time);
 
@@ -618,7 +618,7 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
 		return 0;
 	}
 
-	trace_kvm_hv_stimer_start_one_shot(stimer_to_vcpu(stimer)->vcpu_id,
+	trace_kvm_hv_stimer_start_one_shot(hv_stimer_to_vcpu(stimer)->vcpu_id,
 					   stimer->index,
 					   time_now, stimer->count);
 
@@ -633,13 +633,13 @@ static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
 {
 	union hv_stimer_config new_config = {.as_uint64 = config},
 		old_config = {.as_uint64 = stimer->config.as_uint64};
-	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
 	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
 
 	if (!synic->active && !host)
 		return 1;
 
-	trace_kvm_hv_stimer_set_config(stimer_to_vcpu(stimer)->vcpu_id,
+	trace_kvm_hv_stimer_set_config(hv_stimer_to_vcpu(stimer)->vcpu_id,
 				       stimer->index, config, host);
 
 	stimer_cleanup(stimer);
@@ -657,13 +657,13 @@ static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
 static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
 			    bool host)
 {
-	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
 	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
 
 	if (!synic->active && !host)
 		return 1;
 
-	trace_kvm_hv_stimer_set_count(stimer_to_vcpu(stimer)->vcpu_id,
+	trace_kvm_hv_stimer_set_count(hv_stimer_to_vcpu(stimer)->vcpu_id,
 				      stimer->index, count, host);
 
 	stimer_cleanup(stimer);
@@ -750,7 +750,7 @@ static int synic_deliver_msg(struct kvm_vcpu_hv_synic *synic, u32 sint,
 
 static int stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
 {
-	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
 	struct hv_message *msg = &stimer->msg;
 	struct hv_timer_message_payload *payload =
 			(struct hv_timer_message_payload *)&msg->u.payload;
@@ -770,7 +770,7 @@ static int stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer)
 
 static int stimer_notify_direct(struct kvm_vcpu_hv_stimer *stimer)
 {
-	struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
+	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
 	struct kvm_lapic_irq irq = {
 		.delivery_mode = APIC_DM_FIXED,
 		.vector = stimer->config.apic_vector
@@ -790,7 +790,7 @@ static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer)
 		r = stimer_send_msg(stimer);
 	else
 		r = stimer_notify_direct(stimer);
-	trace_kvm_hv_stimer_expiration(stimer_to_vcpu(stimer)->vcpu_id,
+	trace_kvm_hv_stimer_expiration(hv_stimer_to_vcpu(stimer)->vcpu_id,
 				       stimer->index, direct, r);
 	if (!r) {
 		stimer->msg_pending = false;
@@ -1298,7 +1298,7 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 	case HV_X64_MSR_STIMER3_CONFIG: {
 		int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
 
-		return stimer_set_config(vcpu_to_stimer(vcpu, timer_index),
+		return stimer_set_config(to_hv_stimer(vcpu, timer_index),
 					 data, host);
 	}
 	case HV_X64_MSR_STIMER0_COUNT:
@@ -1307,7 +1307,7 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 	case HV_X64_MSR_STIMER3_COUNT: {
 		int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
 
-		return stimer_set_count(vcpu_to_stimer(vcpu, timer_index),
+		return stimer_set_count(to_hv_stimer(vcpu, timer_index),
 					data, host);
 	}
 	case HV_X64_MSR_TSC_FREQUENCY:
@@ -1410,7 +1410,7 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 	case HV_X64_MSR_STIMER3_CONFIG: {
 		int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
 
-		return stimer_get_config(vcpu_to_stimer(vcpu, timer_index),
+		return stimer_get_config(to_hv_stimer(vcpu, timer_index),
 					 pdata);
 	}
 	case HV_X64_MSR_STIMER0_COUNT:
@@ -1419,7 +1419,7 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 	case HV_X64_MSR_STIMER3_COUNT: {
 		int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
 
-		return stimer_get_count(vcpu_to_stimer(vcpu, timer_index),
+		return stimer_get_count(to_hv_stimer(vcpu, timer_index),
 					pdata);
 	}
 	case HV_X64_MSR_TSC_FREQUENCY:
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index d47b3f045a25..48fcabacd339 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -97,13 +97,13 @@ bool kvm_hv_assist_page_enabled(struct kvm_vcpu *vcpu);
 bool kvm_hv_get_assist_page(struct kvm_vcpu *vcpu,
 			    struct hv_vp_assist_page *assist_page);
 
-static inline struct kvm_vcpu_hv_stimer *vcpu_to_stimer(struct kvm_vcpu *vcpu,
-							int timer_index)
+static inline struct kvm_vcpu_hv_stimer *to_hv_stimer(struct kvm_vcpu *vcpu,
+						      int timer_index)
 {
 	return &to_hv_vcpu(vcpu)->stimer[timer_index];
 }
 
-static inline struct kvm_vcpu *stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stimer)
+static inline struct kvm_vcpu *hv_stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stimer)
 {
 	struct kvm_vcpu_hv *hv_vcpu;
 
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 07/15] KVM: x86: hyper-v: Rename vcpu_to_hv_syndbg() to to_hv_syndbg()
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (5 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 06/15] KVM: x86: hyper-v: Rename vcpu_to_stimer()/stimer_to_vcpu() Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 08/15] KVM: x86: hyper-v: Introduce to_kvm_hv() helper Vitaly Kuznetsov
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

vcpu_to_hv_syndbg()'s argument is  always 'vcpu' so there's no need to have
an additional prefix. Also, this makes the code more consistent with
vmx/svm where to_vmx()/to_svm() are being used.

No functional change intended.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 8 ++++----
 arch/x86/kvm/hyperv.h | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 840628a21282..83748e016b4d 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -293,7 +293,7 @@ static int kvm_hv_syndbg_complete_userspace(struct kvm_vcpu *vcpu)
 
 static void syndbg_exit(struct kvm_vcpu *vcpu, u32 msr)
 {
-	struct kvm_hv_syndbg *syndbg = vcpu_to_hv_syndbg(vcpu);
+	struct kvm_hv_syndbg *syndbg = to_hv_syndbg(vcpu);
 	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
 
 	hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNDBG;
@@ -310,7 +310,7 @@ static void syndbg_exit(struct kvm_vcpu *vcpu, u32 msr)
 
 static int syndbg_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 {
-	struct kvm_hv_syndbg *syndbg = vcpu_to_hv_syndbg(vcpu);
+	struct kvm_hv_syndbg *syndbg = to_hv_syndbg(vcpu);
 
 	if (!kvm_hv_is_syndbg_enabled(vcpu) && !host)
 		return 1;
@@ -349,7 +349,7 @@ static int syndbg_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 
 static int syndbg_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host)
 {
-	struct kvm_hv_syndbg *syndbg = vcpu_to_hv_syndbg(vcpu);
+	struct kvm_hv_syndbg *syndbg = to_hv_syndbg(vcpu);
 
 	if (!kvm_hv_is_syndbg_enabled(vcpu) && !host)
 		return 1;
@@ -1855,7 +1855,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 		}
 		fallthrough;
 	case HVCALL_RESET_DEBUG_SESSION: {
-		struct kvm_hv_syndbg *syndbg = vcpu_to_hv_syndbg(vcpu);
+		struct kvm_hv_syndbg *syndbg = to_hv_syndbg(vcpu);
 
 		if (!kvm_hv_is_syndbg_enabled(vcpu)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_CODE;
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 48fcabacd339..220849cc12e5 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -73,7 +73,7 @@ static inline struct kvm_vcpu *hv_synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
 	return hv_vcpu_to_vcpu(container_of(synic, struct kvm_vcpu_hv, synic));
 }
 
-static inline struct kvm_hv_syndbg *vcpu_to_hv_syndbg(struct kvm_vcpu *vcpu)
+static inline struct kvm_hv_syndbg *to_hv_syndbg(struct kvm_vcpu *vcpu)
 {
 	return &vcpu->kvm->arch.hyperv.hv_syndbg;
 }
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 08/15] KVM: x86: hyper-v: Introduce to_kvm_hv() helper
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (6 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 07/15] KVM: x86: hyper-v: Rename vcpu_to_hv_syndbg() to to_hv_syndbg() Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 09/15] KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable Vitaly Kuznetsov
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

Spelling '&kvm->arch.hyperv' correctly is hard. Also, this makes the code
more consistent with vmx/svm where to_kvm_vmx()/to_kvm_svm() are already
being used.

Opportunistically change kvm_hv_msr_{get,set}_crash_{data,ctl}() and
kvm_hv_msr_set_crash_data() to take 'kvm' instead of 'vcpu' as these
MSRs are partition wide.

No functional change intended.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c  | 107 +++++++++++++++++++++--------------------
 arch/x86/kvm/hyperv.h  |   5 ++
 arch/x86/kvm/vmx/vmx.c |   3 +-
 arch/x86/kvm/x86.c     |   2 +-
 4 files changed, 64 insertions(+), 53 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 83748e016b4d..d60f60ac53f1 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -282,8 +282,7 @@ static bool kvm_hv_is_syndbg_enabled(struct kvm_vcpu *vcpu)
 
 static int kvm_hv_syndbg_complete_userspace(struct kvm_vcpu *vcpu)
 {
-	struct kvm *kvm = vcpu->kvm;
-	struct kvm_hv *hv = &kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(vcpu->kvm);
 
 	if (vcpu->run->hyperv.u.syndbg.msr == HV_X64_MSR_SYNDBG_CONTROL)
 		hv->hv_syndbg.control.status =
@@ -514,7 +513,7 @@ static void synic_init(struct kvm_vcpu_hv_synic *synic)
 
 static u64 get_time_ref_counter(struct kvm *kvm)
 {
-	struct kvm_hv *hv = &kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 	struct kvm_vcpu *vcpu;
 	u64 tsc;
 
@@ -939,10 +938,9 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
 	return r;
 }
 
-static int kvm_hv_msr_get_crash_data(struct kvm_vcpu *vcpu,
-				     u32 index, u64 *pdata)
+static int kvm_hv_msr_get_crash_data(struct kvm *kvm, u32 index, u64 *pdata)
 {
-	struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 	size_t size = ARRAY_SIZE(hv->hv_crash_param);
 
 	if (WARN_ON_ONCE(index >= size))
@@ -952,41 +950,26 @@ static int kvm_hv_msr_get_crash_data(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
-static int kvm_hv_msr_get_crash_ctl(struct kvm_vcpu *vcpu, u64 *pdata)
+static int kvm_hv_msr_get_crash_ctl(struct kvm *kvm, u64 *pdata)
 {
-	struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 
 	*pdata = hv->hv_crash_ctl;
 	return 0;
 }
 
-static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host)
+static int kvm_hv_msr_set_crash_ctl(struct kvm *kvm, u64 data)
 {
-	struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
-
-	if (host)
-		hv->hv_crash_ctl = data & HV_CRASH_CTL_CRASH_NOTIFY;
-
-	if (!host && (data & HV_CRASH_CTL_CRASH_NOTIFY)) {
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 
-		vcpu_debug(vcpu, "hv crash (0x%llx 0x%llx 0x%llx 0x%llx 0x%llx)\n",
-			  hv->hv_crash_param[0],
-			  hv->hv_crash_param[1],
-			  hv->hv_crash_param[2],
-			  hv->hv_crash_param[3],
-			  hv->hv_crash_param[4]);
-
-		/* Send notification about crash to user space */
-		kvm_make_request(KVM_REQ_HV_CRASH, vcpu);
-	}
+	hv->hv_crash_ctl = data & HV_CRASH_CTL_CRASH_NOTIFY;
 
 	return 0;
 }
 
-static int kvm_hv_msr_set_crash_data(struct kvm_vcpu *vcpu,
-				     u32 index, u64 data)
+static int kvm_hv_msr_set_crash_data(struct kvm *kvm, u32 index, u64 data)
 {
-	struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 	size_t size = ARRAY_SIZE(hv->hv_crash_param);
 
 	if (WARN_ON_ONCE(index >= size))
@@ -1068,7 +1051,7 @@ static bool compute_tsc_page_parameters(struct pvclock_vcpu_time_info *hv_clock,
 void kvm_hv_setup_tsc_page(struct kvm *kvm,
 			   struct pvclock_vcpu_time_info *hv_clock)
 {
-	struct kvm_hv *hv = &kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 	u32 tsc_seq;
 	u64 gfn;
 
@@ -1078,7 +1061,7 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm,
 	if (!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE))
 		return;
 
-	mutex_lock(&kvm->arch.hyperv.hv_lock);
+	mutex_lock(&hv->hv_lock);
 	if (!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE))
 		goto out_unlock;
 
@@ -1122,14 +1105,14 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm,
 	kvm_write_guest(kvm, gfn_to_gpa(gfn),
 			&hv->tsc_ref, sizeof(hv->tsc_ref.tsc_sequence));
 out_unlock:
-	mutex_unlock(&kvm->arch.hyperv.hv_lock);
+	mutex_unlock(&hv->hv_lock);
 }
 
 static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
 			     bool host)
 {
 	struct kvm *kvm = vcpu->kvm;
-	struct kvm_hv *hv = &kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 
 	switch (msr) {
 	case HV_X64_MSR_GUEST_OS_ID:
@@ -1168,11 +1151,25 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
 			kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu);
 		break;
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
-		return kvm_hv_msr_set_crash_data(vcpu,
+		return kvm_hv_msr_set_crash_data(kvm,
 						 msr - HV_X64_MSR_CRASH_P0,
 						 data);
 	case HV_X64_MSR_CRASH_CTL:
-		return kvm_hv_msr_set_crash_ctl(vcpu, data, host);
+		if (host)
+			return kvm_hv_msr_set_crash_ctl(kvm, data);
+
+		if (data & HV_CRASH_CTL_CRASH_NOTIFY) {
+			vcpu_debug(vcpu, "hv crash (0x%llx 0x%llx 0x%llx 0x%llx 0x%llx)\n",
+				   hv->hv_crash_param[0],
+				   hv->hv_crash_param[1],
+				   hv->hv_crash_param[2],
+				   hv->hv_crash_param[3],
+				   hv->hv_crash_param[4]);
+
+			/* Send notification about crash to user space */
+			kvm_make_request(KVM_REQ_HV_CRASH, vcpu);
+		}
+		break;
 	case HV_X64_MSR_RESET:
 		if (data == 1) {
 			vcpu_debug(vcpu, "hyper-v reset requested\n");
@@ -1220,7 +1217,7 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 
 	switch (msr) {
 	case HV_X64_MSR_VP_INDEX: {
-		struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+		struct kvm_hv *hv = to_kvm_hv(vcpu->kvm);
 		int vcpu_idx = kvm_vcpu_get_idx(vcpu);
 		u32 new_vp_index = (u32)data;
 
@@ -1330,7 +1327,7 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 {
 	u64 data = 0;
 	struct kvm *kvm = vcpu->kvm;
-	struct kvm_hv *hv = &kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 
 	switch (msr) {
 	case HV_X64_MSR_GUEST_OS_ID:
@@ -1346,11 +1343,11 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 		data = hv->hv_tsc_page;
 		break;
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
-		return kvm_hv_msr_get_crash_data(vcpu,
+		return kvm_hv_msr_get_crash_data(kvm,
 						 msr - HV_X64_MSR_CRASH_P0,
 						 pdata);
 	case HV_X64_MSR_CRASH_CTL:
-		return kvm_hv_msr_get_crash_ctl(vcpu, pdata);
+		return kvm_hv_msr_get_crash_ctl(kvm, pdata);
 	case HV_X64_MSR_RESET:
 		data = 0;
 		break;
@@ -1438,12 +1435,14 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 
 int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 {
+	struct kvm_hv *hv = to_kvm_hv(vcpu->kvm);
+
 	if (kvm_hv_msr_partition_wide(msr)) {
 		int r;
 
-		mutex_lock(&vcpu->kvm->arch.hyperv.hv_lock);
+		mutex_lock(&hv->hv_lock);
 		r = kvm_hv_set_msr_pw(vcpu, msr, data, host);
-		mutex_unlock(&vcpu->kvm->arch.hyperv.hv_lock);
+		mutex_unlock(&hv->hv_lock);
 		return r;
 	} else
 		return kvm_hv_set_msr(vcpu, msr, data, host);
@@ -1451,12 +1450,14 @@ int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 
 int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host)
 {
+	struct kvm_hv *hv = to_kvm_hv(vcpu->kvm);
+
 	if (kvm_hv_msr_partition_wide(msr)) {
 		int r;
 
-		mutex_lock(&vcpu->kvm->arch.hyperv.hv_lock);
+		mutex_lock(&hv->hv_lock);
 		r = kvm_hv_get_msr_pw(vcpu, msr, pdata, host);
-		mutex_unlock(&vcpu->kvm->arch.hyperv.hv_lock);
+		mutex_unlock(&hv->hv_lock);
 		return r;
 	} else
 		return kvm_hv_get_msr(vcpu, msr, pdata, host);
@@ -1466,7 +1467,7 @@ static __always_inline unsigned long *sparse_set_to_vcpu_mask(
 	struct kvm *kvm, u64 *sparse_banks, u64 valid_bank_mask,
 	u64 *vp_bitmap, unsigned long *vcpu_bitmap)
 {
-	struct kvm_hv *hv = &kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 	struct kvm_vcpu *vcpu;
 	int i, bank, sbank = 0;
 
@@ -1668,7 +1669,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *current_vcpu, u64 ingpa, u64 outgpa,
 
 bool kvm_hv_hypercall_enabled(struct kvm *kvm)
 {
-	return READ_ONCE(kvm->arch.hyperv.hv_guest_os_id) != 0;
+	return to_kvm_hv(kvm)->hv_guest_os_id != 0;
 }
 
 static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
@@ -1698,6 +1699,7 @@ static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
 
 static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param)
 {
+	struct kvm_hv *hv = to_kvm_hv(vcpu->kvm);
 	struct eventfd_ctx *eventfd;
 
 	if (unlikely(!fast)) {
@@ -1726,7 +1728,7 @@ static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param)
 
 	/* the eventfd is protected by vcpu->kvm->srcu, but conn_to_evt isn't */
 	rcu_read_lock();
-	eventfd = idr_find(&vcpu->kvm->arch.hyperv.conn_to_evt, param);
+	eventfd = idr_find(&hv->conn_to_evt, param);
 	rcu_read_unlock();
 	if (!eventfd)
 		return HV_STATUS_INVALID_PORT_ID;
@@ -1885,23 +1887,26 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 
 void kvm_hv_init_vm(struct kvm *kvm)
 {
-	mutex_init(&kvm->arch.hyperv.hv_lock);
-	idr_init(&kvm->arch.hyperv.conn_to_evt);
+	struct kvm_hv *hv = to_kvm_hv(kvm);
+
+	mutex_init(&hv->hv_lock);
+	idr_init(&hv->conn_to_evt);
 }
 
 void kvm_hv_destroy_vm(struct kvm *kvm)
 {
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 	struct eventfd_ctx *eventfd;
 	int i;
 
-	idr_for_each_entry(&kvm->arch.hyperv.conn_to_evt, eventfd, i)
+	idr_for_each_entry(&hv->conn_to_evt, eventfd, i)
 		eventfd_ctx_put(eventfd);
-	idr_destroy(&kvm->arch.hyperv.conn_to_evt);
+	idr_destroy(&hv->conn_to_evt);
 }
 
 static int kvm_hv_eventfd_assign(struct kvm *kvm, u32 conn_id, int fd)
 {
-	struct kvm_hv *hv = &kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 	struct eventfd_ctx *eventfd;
 	int ret;
 
@@ -1925,7 +1930,7 @@ static int kvm_hv_eventfd_assign(struct kvm *kvm, u32 conn_id, int fd)
 
 static int kvm_hv_eventfd_deassign(struct kvm *kvm, u32 conn_id)
 {
-	struct kvm_hv *hv = &kvm->arch.hyperv;
+	struct kvm_hv *hv = to_kvm_hv(kvm);
 	struct eventfd_ctx *eventfd;
 
 	mutex_lock(&hv->hv_lock);
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 220849cc12e5..fdb321ba9c3f 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -50,6 +50,11 @@
 /* Hyper-V HV_X64_MSR_SYNDBG_OPTIONS bits */
 #define HV_X64_SYNDBG_OPTION_USE_HCALLS		BIT(2)
 
+static inline struct kvm_hv *to_kvm_hv(struct kvm *kvm)
+{
+	return &kvm->arch.hyperv;
+}
+
 static inline struct kvm_vcpu_hv *to_hv_vcpu(struct kvm_vcpu *vcpu)
 {
 	return &vcpu->arch.hyperv;
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 2af05d3b0590..9db84508aa0b 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -50,6 +50,7 @@
 #include "capabilities.h"
 #include "cpuid.h"
 #include "evmcs.h"
+#include "hyperv.h"
 #include "irq.h"
 #include "kvm_cache_regs.h"
 #include "lapic.h"
@@ -552,7 +553,7 @@ static int hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu)
 {
 	struct hv_enlightened_vmcs *evmcs;
 	struct hv_partition_assist_pg **p_hv_pa_pg =
-			&vcpu->kvm->arch.hyperv.hv_pa_pg;
+			&to_kvm_hv(vcpu->kvm)->hv_pa_pg;
 	/*
 	 * Synthetic VM-Exit is not enabled in current code and so All
 	 * evmcs in singe VM shares same assist page.
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0bf0672d4811..868d2bf8fb95 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -10356,7 +10356,7 @@ void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu)
 
 void kvm_arch_free_vm(struct kvm *kvm)
 {
-	kfree(kvm->arch.hyperv.hv_pa_pg);
+	kfree(to_kvm_hv(kvm)->hv_pa_pg);
 	vfree(kvm);
 }
 
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 09/15] KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (7 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 08/15] KVM: x86: hyper-v: Introduce to_kvm_hv() helper Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 10/15] KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct kvm_vcpu_hv' Vitaly Kuznetsov
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

'current_vcpu' variable in KVM is a per-cpu pointer to the currently
scheduled vcpu. kvm_hv_flush_tlb()/kvm_hv_send_ipi() functions used
to have local 'vcpu' variable to iterate over vCPUs but it's gone
now and there's no need to use anything but the standard 'vcpu' as
an argument.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index d60f60ac53f1..9a52a07fab81 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1491,11 +1491,10 @@ static __always_inline unsigned long *sparse_set_to_vcpu_mask(
 	return vcpu_bitmap;
 }
 
-static u64 kvm_hv_flush_tlb(struct kvm_vcpu *current_vcpu, u64 ingpa,
-			    u16 rep_cnt, bool ex)
+static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, u64 ingpa, u16 rep_cnt, bool ex)
 {
-	struct kvm *kvm = current_vcpu->kvm;
-	struct kvm_vcpu_hv *hv_vcpu = &current_vcpu->arch.hyperv;
+	struct kvm *kvm = vcpu->kvm;
+	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
 	struct hv_tlb_flush_ex flush_ex;
 	struct hv_tlb_flush flush;
 	u64 vp_bitmap[KVM_HV_MAX_SPARSE_VCPU_SET_BITS];
@@ -1593,10 +1592,10 @@ static void kvm_send_ipi_to_many(struct kvm *kvm, u32 vector,
 	}
 }
 
-static u64 kvm_hv_send_ipi(struct kvm_vcpu *current_vcpu, u64 ingpa, u64 outgpa,
+static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, u64 ingpa, u64 outgpa,
 			   bool ex, bool fast)
 {
-	struct kvm *kvm = current_vcpu->kvm;
+	struct kvm *kvm = vcpu->kvm;
 	struct hv_send_ipi_ex send_ipi_ex;
 	struct hv_send_ipi send_ipi;
 	u64 vp_bitmap[KVM_HV_MAX_SPARSE_VCPU_SET_BITS];
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 10/15] KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct kvm_vcpu_hv'
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (8 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 09/15] KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-02-08 23:06   ` Maxim Levitsky
  2021-01-26 13:48 ` [PATCH v2 11/15] KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context Vitaly Kuznetsov
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

As a preparation to allocating Hyper-V context dynamically, make it clear
who's the user of the said context.

No functional change intended.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c  | 14 ++++++++------
 arch/x86/kvm/hyperv.h  |  4 +++-
 arch/x86/kvm/lapic.h   |  2 ++
 arch/x86/kvm/vmx/vmx.c |  8 +++++---
 arch/x86/kvm/x86.c     |  4 +++-
 5 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 9a52a07fab81..18e00fb46b15 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -190,7 +190,7 @@ static void kvm_hv_notify_acked_sint(struct kvm_vcpu *vcpu, u32 sint)
 static void synic_exit(struct kvm_vcpu_hv_synic *synic, u32 msr)
 {
 	struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic);
-	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
 	hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNIC;
 	hv_vcpu->exit.u.synic.msr = msr;
@@ -293,7 +293,7 @@ static int kvm_hv_syndbg_complete_userspace(struct kvm_vcpu *vcpu)
 static void syndbg_exit(struct kvm_vcpu *vcpu, u32 msr)
 {
 	struct kvm_hv_syndbg *syndbg = to_hv_syndbg(vcpu);
-	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
 	hv_vcpu->exit.type = KVM_EXIT_HYPERV_SYNDBG;
 	hv_vcpu->exit.u.syndbg.msr = msr;
@@ -839,7 +839,9 @@ void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu)
 
 bool kvm_hv_assist_page_enabled(struct kvm_vcpu *vcpu)
 {
-	if (!(vcpu->arch.hyperv.hv_vapic & HV_X64_MSR_VP_ASSIST_PAGE_ENABLE))
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+
+	if (!(hv_vcpu->hv_vapic & HV_X64_MSR_VP_ASSIST_PAGE_ENABLE))
 		return false;
 	return vcpu->arch.pv_eoi.msr_val & KVM_MSR_ENABLED;
 }
@@ -1213,7 +1215,7 @@ static u64 current_task_runtime_100ns(void)
 
 static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 {
-	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
 	switch (msr) {
 	case HV_X64_MSR_VP_INDEX: {
@@ -1376,7 +1378,7 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 			  bool host)
 {
 	u64 data = 0;
-	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
 	switch (msr) {
 	case HV_X64_MSR_VP_INDEX:
@@ -1494,7 +1496,7 @@ static __always_inline unsigned long *sparse_set_to_vcpu_mask(
 static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, u64 ingpa, u16 rep_cnt, bool ex)
 {
 	struct kvm *kvm = vcpu->kvm;
-	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(current_vcpu);
 	struct hv_tlb_flush_ex flush_ex;
 	struct hv_tlb_flush flush;
 	u64 vp_bitmap[KVM_HV_MAX_SPARSE_VCPU_SET_BITS];
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index fdb321ba9c3f..be1e3f5d1df6 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -119,7 +119,9 @@ static inline struct kvm_vcpu *hv_stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stim
 
 static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu)
 {
-	return !bitmap_empty(vcpu->arch.hyperv.stimer_pending_bitmap,
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+
+	return !bitmap_empty(hv_vcpu->stimer_pending_bitmap,
 			     HV_SYNIC_STIMER_COUNT);
 }
 
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 4de7579e206c..4ad2fbbd962a 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -6,6 +6,8 @@
 
 #include <linux/kvm_host.h>
 
+#include "hyperv.h"
+
 #define KVM_APIC_INIT		0
 #define KVM_APIC_SIPI		1
 #define KVM_APIC_LVT_NUM	6
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 9db84508aa0b..443878dd775c 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6733,12 +6733,14 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
 	x86_spec_ctrl_restore_host(vmx->spec_ctrl, 0);
 
 	/* All fields are clean at this point */
-	if (static_branch_unlikely(&enable_evmcs))
+	if (static_branch_unlikely(&enable_evmcs)) {
+		struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+
 		current_evmcs->hv_clean_fields |=
 			HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL;
 
-	if (static_branch_unlikely(&enable_evmcs))
-		current_evmcs->hv_vp_id = vcpu->arch.hyperv.vp_index;
+		current_evmcs->hv_vp_id = hv_vcpu->vp_index;
+	}
 
 	/* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */
 	if (vmx->host_debugctlmsr)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 868d2bf8fb95..4c2b1f4260c6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8894,8 +8894,10 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 			goto out;
 		}
 		if (kvm_check_request(KVM_REQ_HV_EXIT, vcpu)) {
+			struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+
 			vcpu->run->exit_reason = KVM_EXIT_HYPERV;
-			vcpu->run->hyperv = vcpu->arch.hyperv.exit;
+			vcpu->run->hyperv = hv_vcpu->exit;
 			r = 0;
 			goto out;
 		}
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 11/15] KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (9 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 10/15] KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct kvm_vcpu_hv' Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-28 14:19   ` Paolo Bonzini
  2021-01-26 13:48 ` [PATCH v2 12/15] KVM: x86: hyper-v: Allocate 'struct kvm_vcpu_hv' dynamically Vitaly Kuznetsov
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

Currently, Hyper-V context is part of 'struct kvm_vcpu_arch' and is always
available. As a preparation to allocating it dynamically, check that it is
not NULL at call sites which can normally proceed without it i.e. the
behavior is identical to the situation when Hyper-V emulation is not being
used by the guest.

When Hyper-V context for a particular vCPU is not allocated, we may still
need to get 'vp_index' from there. E.g. in a hypothetical situation when
Hyper-V emulation was enabled on one CPU and wasn't on another, Hyper-V
style send-IPI hypercall may still be used. Luckily, vp_index is always
initialized to kvm_vcpu_get_idx() and can only be changed when Hyper-V
context is present. Introduce vcpu_to_hv_vpindex() helper for
simplification.

No functional change intended.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c  | 17 ++++++++++-------
 arch/x86/kvm/hyperv.h  | 10 ++++++++++
 arch/x86/kvm/lapic.c   |  5 +++--
 arch/x86/kvm/vmx/vmx.c |  4 +---
 arch/x86/kvm/x86.c     |  7 +++++--
 5 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 18e00fb46b15..2823473c84a2 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -141,10 +141,10 @@ static struct kvm_vcpu *get_vcpu_by_vpidx(struct kvm *kvm, u32 vpidx)
 		return NULL;
 
 	vcpu = kvm_get_vcpu(kvm, vpidx);
-	if (vcpu && to_hv_vcpu(vcpu)->vp_index == vpidx)
+	if (vcpu && to_hv_vpindex(vcpu) == vpidx)
 		return vcpu;
 	kvm_for_each_vcpu(i, vcpu, kvm)
-		if (to_hv_vcpu(vcpu)->vp_index == vpidx)
+		if (to_hv_vpindex(vcpu) == vpidx)
 			return vcpu;
 	return NULL;
 }
@@ -376,9 +376,7 @@ static int syndbg_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host)
 		break;
 	}
 
-	trace_kvm_hv_syndbg_get_msr(vcpu->vcpu_id,
-				    to_hv_vcpu(vcpu)->vp_index, msr,
-				    *pdata);
+	trace_kvm_hv_syndbg_get_msr(vcpu->vcpu_id, to_hv_vpindex(vcpu), msr, *pdata);
 
 	return 0;
 }
@@ -805,6 +803,9 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
 	u64 time_now, exp_time;
 	int i;
 
+	if (!hv_vcpu)
+		return;
+
 	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
 		if (test_and_clear_bit(i, hv_vcpu->stimer_pending_bitmap)) {
 			stimer = &hv_vcpu->stimer[i];
@@ -841,6 +842,9 @@ bool kvm_hv_assist_page_enabled(struct kvm_vcpu *vcpu)
 {
 	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
+	if (!hv_vcpu)
+		return false;
+
 	if (!(hv_vcpu->hv_vapic & HV_X64_MSR_VP_ASSIST_PAGE_ENABLE))
 		return false;
 	return vcpu->arch.pv_eoi.msr_val & KVM_MSR_ENABLED;
@@ -1486,8 +1490,7 @@ static __always_inline unsigned long *sparse_set_to_vcpu_mask(
 
 	bitmap_zero(vcpu_bitmap, KVM_MAX_VCPUS);
 	kvm_for_each_vcpu(i, vcpu, kvm) {
-		if (test_bit(to_hv_vcpu(vcpu)->vp_index,
-			     (unsigned long *)vp_bitmap))
+		if (test_bit(to_hv_vpindex(vcpu), (unsigned long *)vp_bitmap))
 			__set_bit(i, vcpu_bitmap);
 	}
 	return vcpu_bitmap;
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index be1e3f5d1df6..2258bcc34ada 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -83,6 +83,13 @@ static inline struct kvm_hv_syndbg *to_hv_syndbg(struct kvm_vcpu *vcpu)
 	return &vcpu->kvm->arch.hyperv.hv_syndbg;
 }
 
+static inline u32 to_hv_vpindex(struct kvm_vcpu *vcpu)
+{
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+
+	return hv_vcpu ? hv_vcpu->vp_index : kvm_vcpu_get_idx(vcpu);
+}
+
 int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
 int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host);
 
@@ -121,6 +128,9 @@ static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu)
 {
 	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
+	if (!hv_vcpu)
+		return false;
+
 	return !bitmap_empty(hv_vcpu->stimer_pending_bitmap,
 			     HV_SYNIC_STIMER_COUNT);
 }
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 53bdea2d5a81..843ce1bc3e1a 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1245,7 +1245,8 @@ static int apic_set_eoi(struct kvm_lapic *apic)
 	apic_clear_isr(vector, apic);
 	apic_update_ppr(apic);
 
-	if (test_bit(vector, to_hv_synic(apic->vcpu)->vec_bitmap))
+	if (to_hv_vcpu(apic->vcpu) &&
+	    test_bit(vector, to_hv_synic(apic->vcpu)->vec_bitmap))
 		kvm_hv_synic_send_eoi(apic->vcpu, vector);
 
 	kvm_ioapic_send_eoi(apic, vector);
@@ -2512,7 +2513,7 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
 	 */
 
 	apic_clear_irr(vector, apic);
-	if (test_bit(vector, to_hv_synic(vcpu)->auto_eoi_bitmap)) {
+	if (to_hv_vcpu(vcpu) && test_bit(vector, to_hv_synic(vcpu)->auto_eoi_bitmap)) {
 		/*
 		 * For auto-EOI interrupts, there might be another pending
 		 * interrupt above PPR, so check whether to raise another
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 443878dd775c..6c72331d6bdf 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6734,12 +6734,10 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
 
 	/* All fields are clean at this point */
 	if (static_branch_unlikely(&enable_evmcs)) {
-		struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
-
 		current_evmcs->hv_clean_fields |=
 			HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL;
 
-		current_evmcs->hv_vp_id = hv_vcpu->vp_index;
+		current_evmcs->hv_vp_id = to_hv_vpindex(vcpu);
 	}
 
 	/* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4c2b1f4260c6..0d5d36134093 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8740,8 +8740,11 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
 	if (!kvm_apic_hw_enabled(vcpu->arch.apic))
 		return;
 
-	bitmap_or((ulong *)eoi_exit_bitmap, vcpu->arch.ioapic_handled_vectors,
-		  to_hv_synic(vcpu)->vec_bitmap, 256);
+	if (to_hv_vcpu(vcpu))
+		bitmap_or((ulong *)eoi_exit_bitmap,
+			  vcpu->arch.ioapic_handled_vectors,
+			  to_hv_synic(vcpu)->vec_bitmap, 256);
+
 	kvm_x86_ops.load_eoi_exitmap(vcpu, eoi_exit_bitmap);
 }
 
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 12/15] KVM: x86: hyper-v: Allocate 'struct kvm_vcpu_hv' dynamically
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (10 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 11/15] KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 13/15] KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional Vitaly Kuznetsov
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

Hyper-V context is only needed for guests which use Hyper-V emulation in
KVM (e.g. Windows/Hyper-V guests). 'struct kvm_vcpu_hv' is, however, quite
big, it accounts for more than 1/4 of the total 'struct kvm_vcpu_arch'
which is also quite big already. This all looks like a waste.

Allocate 'struct kvm_vcpu_hv' dynamically. This patch does not bring any
(intentional) functional change as we still allocate the context
unconditionally but it paves the way to doing that only when needed.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/include/asm/kvm_host.h |  3 ++-
 arch/x86/kvm/hyperv.c           | 16 ++++++++++++++--
 arch/x86/kvm/hyperv.h           | 13 ++++++-------
 arch/x86/kvm/x86.c              |  7 +++++--
 4 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 3d6616f6f6ef..a1dda14bdf4b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -510,6 +510,7 @@ struct kvm_vcpu_hv_synic {
 
 /* Hyper-V per vcpu emulation context */
 struct kvm_vcpu_hv {
+	struct kvm_vcpu *vcpu;
 	u32 vp_index;
 	u64 hv_vapic;
 	s64 runtime_offset;
@@ -717,7 +718,7 @@ struct kvm_vcpu_arch {
 	/* used for guest single stepping over the given code position */
 	unsigned long singlestep_rip;
 
-	struct kvm_vcpu_hv hyperv;
+	struct kvm_vcpu_hv *hyperv;
 
 	cpumask_var_t wbinvd_dirty_mask;
 
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 2823473c84a2..8fcd1dfed998 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -836,6 +836,9 @@ void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu)
 
 	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
 		stimer_cleanup(&hv_vcpu->stimer[i]);
+
+	kfree(hv_vcpu);
+	vcpu->arch.hyperv = NULL;
 }
 
 bool kvm_hv_assist_page_enabled(struct kvm_vcpu *vcpu)
@@ -885,16 +888,25 @@ static void stimer_init(struct kvm_vcpu_hv_stimer *stimer, int timer_index)
 	stimer_prepare_msg(stimer);
 }
 
-void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
+int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv *hv_vcpu;
 	int i;
 
+	hv_vcpu = kzalloc(sizeof(struct kvm_vcpu_hv), GFP_KERNEL_ACCOUNT);
+	if (!hv_vcpu)
+		return -ENOMEM;
+
+	vcpu->arch.hyperv = hv_vcpu;
+	hv_vcpu->vcpu = vcpu;
+
 	synic_init(&hv_vcpu->synic);
 
 	bitmap_zero(hv_vcpu->stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
 	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
 		stimer_init(&hv_vcpu->stimer[i], i);
+
+	return 0;
 }
 
 void kvm_hv_vcpu_postcreate(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 2258bcc34ada..51d0d61a515c 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -57,20 +57,19 @@ static inline struct kvm_hv *to_kvm_hv(struct kvm *kvm)
 
 static inline struct kvm_vcpu_hv *to_hv_vcpu(struct kvm_vcpu *vcpu)
 {
-	return &vcpu->arch.hyperv;
+	return vcpu->arch.hyperv;
 }
 
 static inline struct kvm_vcpu *hv_vcpu_to_vcpu(struct kvm_vcpu_hv *hv_vcpu)
 {
-	struct kvm_vcpu_arch *arch;
-
-	arch = container_of(hv_vcpu, struct kvm_vcpu_arch, hyperv);
-	return container_of(arch, struct kvm_vcpu, arch);
+	return hv_vcpu->vcpu;
 }
 
 static inline struct kvm_vcpu_hv_synic *to_hv_synic(struct kvm_vcpu *vcpu)
 {
-	return &vcpu->arch.hyperv.synic;
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+
+	return &hv_vcpu->synic;
 }
 
 static inline struct kvm_vcpu *hv_synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
@@ -101,7 +100,7 @@ int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
 void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
 int kvm_hv_activate_synic(struct kvm_vcpu *vcpu, bool dont_zero_synic_pages);
 
-void kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
+int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
 void kvm_hv_vcpu_postcreate(struct kvm_vcpu *vcpu);
 void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0d5d36134093..e612bde18e99 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -10007,11 +10007,12 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 	vcpu->arch.pending_external_vector = -1;
 	vcpu->arch.preempted_in_kernel = false;
 
-	kvm_hv_vcpu_init(vcpu);
+	if (kvm_hv_vcpu_init(vcpu))
+		goto free_guest_fpu;
 
 	r = kvm_x86_ops.vcpu_create(vcpu);
 	if (r)
-		goto free_guest_fpu;
+		goto free_hv_vcpu;
 
 	vcpu->arch.arch_capabilities = kvm_get_arch_capabilities();
 	vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
@@ -10022,6 +10023,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 	vcpu_put(vcpu);
 	return 0;
 
+free_hv_vcpu:
+	kvm_hv_vcpu_uninit(vcpu);
 free_guest_fpu:
 	kvm_free_guest_fpu(vcpu);
 free_user_fpu:
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 13/15] KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (11 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 12/15] KVM: x86: hyper-v: Allocate 'struct kvm_vcpu_hv' dynamically Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 14/15] KVM: x86: hyper-v: Allocate Hyper-V context lazily Vitaly Kuznetsov
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

Hyper-V emulation is enabled in KVM unconditionally. This is bad at least
from security standpoint as it is an extra attack surface. Ideally, there
should be a per-VM capability explicitly enabled by VMM but currently it
is not the case and we can't mandate one without breaking backwards
compatibility. We can, however, check guest visible CPUIDs and only enable
Hyper-V emulation when "Hv#1" interface was exposed in
HYPERV_CPUID_INTERFACE.

Note, VMMs are free to act in any sequence they like, e.g. they can try
to set MSRs first and CPUIDs later so we still need to allow the host
to read/write Hyper-V specific MSRs unconditionally.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/cpuid.c            |  2 ++
 arch/x86/kvm/hyperv.c           | 27 +++++++++++++++++++++++----
 arch/x86/kvm/hyperv.h           |  3 ++-
 arch/x86/kvm/x86.c              |  2 +-
 5 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a1dda14bdf4b..e8de3420922f 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -718,6 +718,7 @@ struct kvm_vcpu_arch {
 	/* used for guest single stepping over the given code position */
 	unsigned long singlestep_rip;
 
+	bool hyperv_enabled;
 	struct kvm_vcpu_hv *hyperv;
 
 	cpumask_var_t wbinvd_dirty_mask;
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 13036cf0b912..3768491ee67d 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -181,6 +181,8 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 
 	vcpu->arch.cr3_lm_rsvd_bits = rsvd_bits(cpuid_maxphyaddr(vcpu), 63);
 
+	kvm_hv_set_cpuid(vcpu);
+
 	/* Invoke the vendor callback only after the above state is updated. */
 	kvm_x86_ops.vcpu_after_set_cpuid(vcpu);
 }
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 8fcd1dfed998..ce7dab132d04 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -36,6 +36,9 @@
 #include "trace.h"
 #include "irq.h"
 
+/* "Hv#1" signature */
+#define HYPERV_CPUID_SIGNATURE_EAX 0x31237648
+
 #define KVM_HV_MAX_SPARSE_VCPU_SET_BITS DIV_ROUND_UP(KVM_MAX_VCPUS, 64)
 
 static void stimer_mark_pending(struct kvm_vcpu_hv_stimer *stimer,
@@ -1455,6 +1458,9 @@ int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 {
 	struct kvm_hv *hv = to_kvm_hv(vcpu->kvm);
 
+	if (!host && !vcpu->arch.hyperv_enabled)
+		return 1;
+
 	if (kvm_hv_msr_partition_wide(msr)) {
 		int r;
 
@@ -1470,6 +1476,9 @@ int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host)
 {
 	struct kvm_hv *hv = to_kvm_hv(vcpu->kvm);
 
+	if (!host && !vcpu->arch.hyperv_enabled)
+		return 1;
+
 	if (kvm_hv_msr_partition_wide(msr)) {
 		int r;
 
@@ -1683,9 +1692,20 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, u64 ingpa, u64 outgpa,
 	return HV_STATUS_SUCCESS;
 }
 
-bool kvm_hv_hypercall_enabled(struct kvm *kvm)
+void kvm_hv_set_cpuid(struct kvm_vcpu *vcpu)
+{
+	struct kvm_cpuid_entry2 *entry;
+
+	entry = kvm_find_cpuid_entry(vcpu, HYPERV_CPUID_INTERFACE, 0);
+	if (entry && entry->eax == HYPERV_CPUID_SIGNATURE_EAX)
+		vcpu->arch.hyperv_enabled = true;
+	else
+		vcpu->arch.hyperv_enabled = false;
+}
+
+bool kvm_hv_hypercall_enabled(struct kvm_vcpu *vcpu)
 {
-	return to_kvm_hv(kvm)->hv_guest_os_id != 0;
+	return vcpu->arch.hyperv_enabled && to_kvm_hv(vcpu->kvm)->hv_guest_os_id;
 }
 
 static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
@@ -2018,8 +2038,7 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
 			break;
 
 		case HYPERV_CPUID_INTERFACE:
-			memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12);
-			ent->eax = signature[0];
+			ent->eax = HYPERV_CPUID_SIGNATURE_EAX;
 			break;
 
 		case HYPERV_CPUID_VERSION:
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 51d0d61a515c..2d50c8df9355 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -92,7 +92,7 @@ static inline u32 to_hv_vpindex(struct kvm_vcpu *vcpu)
 int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
 int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host);
 
-bool kvm_hv_hypercall_enabled(struct kvm *kvm);
+bool kvm_hv_hypercall_enabled(struct kvm_vcpu *vcpu);
 int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
 
 void kvm_hv_irq_routing_update(struct kvm *kvm);
@@ -141,6 +141,7 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm,
 
 void kvm_hv_init_vm(struct kvm *kvm);
 void kvm_hv_destroy_vm(struct kvm *kvm);
+void kvm_hv_set_cpuid(struct kvm_vcpu *vcpu);
 int kvm_vm_ioctl_hv_eventfd(struct kvm *kvm, struct kvm_hyperv_eventfd *args);
 int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
 		     struct kvm_cpuid_entry2 __user *entries);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e612bde18e99..e97f4eeed897 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8101,7 +8101,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 	unsigned long nr, a0, a1, a2, a3, ret;
 	int op_64_bit;
 
-	if (kvm_hv_hypercall_enabled(vcpu->kvm))
+	if (kvm_hv_hypercall_enabled(vcpu))
 		return kvm_hv_hypercall(vcpu);
 
 	nr = kvm_rax_read(vcpu);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 14/15] KVM: x86: hyper-v: Allocate Hyper-V context lazily
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (12 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 13/15] KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-26 13:48 ` [PATCH v2 15/15] KVM: x86: hyper-v: Drop hv_vcpu_to_vcpu() helper Vitaly Kuznetsov
  2021-01-28 14:25 ` [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Paolo Bonzini
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

Hyper-V context is only needed for guests which use Hyper-V emulation in
KVM (e.g. Windows/Hyper-V guests) so we don't actually need to allocate
it in kvm_arch_vcpu_create(), we can postpone the action until Hyper-V
specific MSRs are accessed or SynIC is enabled.

Once allocated, let's keep the context alive for the lifetime of the vCPU
as an attempt to free it would require additional synchronization with
other vCPUs and normally it is not supposed to happen.

Note, Hyper-V style hypercall enablement is done by writing to
HV_X64_MSR_GUEST_OS_ID so we don't need to worry about allocating Hyper-V
context from kvm_hv_hypercall().

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 33 +++++++++++++++++++++++++--------
 arch/x86/kvm/hyperv.h |  2 --
 arch/x86/kvm/x86.c    |  9 +--------
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index ce7dab132d04..a6785176e0e7 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -837,6 +837,9 @@ void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu)
 	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 	int i;
 
+	if (!hv_vcpu)
+		return;
+
 	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
 		stimer_cleanup(&hv_vcpu->stimer[i]);
 
@@ -891,7 +894,7 @@ static void stimer_init(struct kvm_vcpu_hv_stimer *stimer, int timer_index)
 	stimer_prepare_msg(stimer);
 }
 
-int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
+static int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
 {
 	struct kvm_vcpu_hv *hv_vcpu;
 	int i;
@@ -909,19 +912,23 @@ int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
 	for (i = 0; i < ARRAY_SIZE(hv_vcpu->stimer); i++)
 		stimer_init(&hv_vcpu->stimer[i], i);
 
+	hv_vcpu->vp_index = kvm_vcpu_get_idx(vcpu);
+
 	return 0;
 }
 
-void kvm_hv_vcpu_postcreate(struct kvm_vcpu *vcpu)
+int kvm_hv_activate_synic(struct kvm_vcpu *vcpu, bool dont_zero_synic_pages)
 {
-	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+	struct kvm_vcpu_hv_synic *synic;
+	int r;
 
-	hv_vcpu->vp_index = kvm_vcpu_get_idx(vcpu);
-}
+	if (!to_hv_vcpu(vcpu)) {
+		r = kvm_hv_vcpu_init(vcpu);
+		if (r)
+			return r;
+	}
 
-int kvm_hv_activate_synic(struct kvm_vcpu *vcpu, bool dont_zero_synic_pages)
-{
-	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
+	synic = to_hv_synic(vcpu);
 
 	/*
 	 * Hyper-V SynIC auto EOI SINT's are
@@ -1461,6 +1468,11 @@ int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 	if (!host && !vcpu->arch.hyperv_enabled)
 		return 1;
 
+	if (!to_hv_vcpu(vcpu)) {
+		if (kvm_hv_vcpu_init(vcpu))
+			return 1;
+	}
+
 	if (kvm_hv_msr_partition_wide(msr)) {
 		int r;
 
@@ -1479,6 +1491,11 @@ int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host)
 	if (!host && !vcpu->arch.hyperv_enabled)
 		return 1;
 
+	if (!to_hv_vcpu(vcpu)) {
+		if (kvm_hv_vcpu_init(vcpu))
+			return 1;
+	}
+
 	if (kvm_hv_msr_partition_wide(msr)) {
 		int r;
 
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 2d50c8df9355..a0926125495a 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -100,8 +100,6 @@ int kvm_hv_synic_set_irq(struct kvm *kvm, u32 vcpu_id, u32 sint);
 void kvm_hv_synic_send_eoi(struct kvm_vcpu *vcpu, int vector);
 int kvm_hv_activate_synic(struct kvm_vcpu *vcpu, bool dont_zero_synic_pages);
 
-int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu);
-void kvm_hv_vcpu_postcreate(struct kvm_vcpu *vcpu);
 void kvm_hv_vcpu_uninit(struct kvm_vcpu *vcpu);
 
 bool kvm_hv_assist_page_enabled(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e97f4eeed897..4c3e47b8a5c5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -10007,12 +10007,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 	vcpu->arch.pending_external_vector = -1;
 	vcpu->arch.preempted_in_kernel = false;
 
-	if (kvm_hv_vcpu_init(vcpu))
-		goto free_guest_fpu;
-
 	r = kvm_x86_ops.vcpu_create(vcpu);
 	if (r)
-		goto free_hv_vcpu;
+		goto free_guest_fpu;
 
 	vcpu->arch.arch_capabilities = kvm_get_arch_capabilities();
 	vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
@@ -10023,8 +10020,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 	vcpu_put(vcpu);
 	return 0;
 
-free_hv_vcpu:
-	kvm_hv_vcpu_uninit(vcpu);
 free_guest_fpu:
 	kvm_free_guest_fpu(vcpu);
 free_user_fpu:
@@ -10048,8 +10043,6 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 {
 	struct kvm *kvm = vcpu->kvm;
 
-	kvm_hv_vcpu_postcreate(vcpu);
-
 	if (mutex_lock_killable(&vcpu->mutex))
 		return;
 	vcpu_load(vcpu);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 15/15] KVM: x86: hyper-v: Drop hv_vcpu_to_vcpu() helper
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (13 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 14/15] KVM: x86: hyper-v: Allocate Hyper-V context lazily Vitaly Kuznetsov
@ 2021-01-26 13:48 ` Vitaly Kuznetsov
  2021-01-28 14:25 ` [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Paolo Bonzini
  15 siblings, 0 replies; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-26 13:48 UTC (permalink / raw)
  To: kvm, Paolo Bonzini; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

hv_vcpu_to_vcpu() helper is only used by other helpers and
is not very complex, we can drop it without much regret.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.h | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index a0926125495a..1ec3b9a0b644 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -60,11 +60,6 @@ static inline struct kvm_vcpu_hv *to_hv_vcpu(struct kvm_vcpu *vcpu)
 	return vcpu->arch.hyperv;
 }
 
-static inline struct kvm_vcpu *hv_vcpu_to_vcpu(struct kvm_vcpu_hv *hv_vcpu)
-{
-	return hv_vcpu->vcpu;
-}
-
 static inline struct kvm_vcpu_hv_synic *to_hv_synic(struct kvm_vcpu *vcpu)
 {
 	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
@@ -74,7 +69,9 @@ static inline struct kvm_vcpu_hv_synic *to_hv_synic(struct kvm_vcpu *vcpu)
 
 static inline struct kvm_vcpu *hv_synic_to_vcpu(struct kvm_vcpu_hv_synic *synic)
 {
-	return hv_vcpu_to_vcpu(container_of(synic, struct kvm_vcpu_hv, synic));
+	struct kvm_vcpu_hv *hv_vcpu = container_of(synic, struct kvm_vcpu_hv, synic);
+
+	return hv_vcpu->vcpu;
 }
 
 static inline struct kvm_hv_syndbg *to_hv_syndbg(struct kvm_vcpu *vcpu)
@@ -118,7 +115,7 @@ static inline struct kvm_vcpu *hv_stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stim
 
 	hv_vcpu = container_of(stimer - stimer->index, struct kvm_vcpu_hv,
 			       stimer[0]);
-	return hv_vcpu_to_vcpu(hv_vcpu);
+	return hv_vcpu->vcpu;
 }
 
 static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu)
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 11/15] KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context
  2021-01-26 13:48 ` [PATCH v2 11/15] KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context Vitaly Kuznetsov
@ 2021-01-28 14:19   ` Paolo Bonzini
  2021-01-28 15:21     ` Vitaly Kuznetsov
  0 siblings, 1 reply; 25+ messages in thread
From: Paolo Bonzini @ 2021-01-28 14:19 UTC (permalink / raw)
  To: Vitaly Kuznetsov, kvm; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

On 26/01/21 14:48, Vitaly Kuznetsov wrote:
> 
> +static inline u32 to_hv_vpindex(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
> +
> +	return hv_vcpu ? hv_vcpu->vp_index : kvm_vcpu_get_idx(vcpu);
> +}
> +

I'd rather restrict to_* names for pointer conversions. 
kvm_hv_get_vpindex is a better choice here.

Paolo


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement
  2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
                   ` (14 preceding siblings ...)
  2021-01-26 13:48 ` [PATCH v2 15/15] KVM: x86: hyper-v: Drop hv_vcpu_to_vcpu() helper Vitaly Kuznetsov
@ 2021-01-28 14:25 ` Paolo Bonzini
  2021-02-08 14:18   ` Vitaly Kuznetsov
  15 siblings, 1 reply; 25+ messages in thread
From: Paolo Bonzini @ 2021-01-28 14:25 UTC (permalink / raw)
  To: Vitaly Kuznetsov, kvm; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

On 26/01/21 14:48, Vitaly Kuznetsov wrote:
> Changes since v1 [Sean]:
> - Add a few cleanup patches ("Rename vcpu_to_hv_vcpu() to to_hv_vcpu()",
>    "Rename vcpu_to_synic()/synic_to_vcpu()", ...)
> - Drop unused kvm_hv_vapic_assist_page_enabled()
> - Stop shadowing global 'current_vcpu' variable in kvm_hv_flush_tlb()/
>    kvm_hv_send_ipi()
> 
> Original description:
> 
> Hyper-V emulation is enabled in KVM unconditionally even for Linux guests.
> This is bad at least from security standpoint as it is an extra attack
> surface. Ideally, there should be a per-VM capability explicitly enabled by
> VMM but currently it is not the case and we can't mandate one without
> breaking backwards compatibility. We can, however, check guest visible CPUIDs
> and only enable Hyper-V emulation when "Hv#1" interface was exposed in
> HYPERV_CPUID_INTERFACE.
> 
> Also (and while on it) per-vcpu Hyper-V context ('struct kvm_vcpu_hv') is
> currently part of 'struct kvm_vcpu_arch' and thus allocated unconditionally
> for each vCPU. The context, however, quite big and accounts for more than
> 1/4 of 'struct kvm_vcpu_arch' (e.g. 2912/9512 bytes). Switch to allocating
> it dynamically. This may come handy if we ever decide to raise KVM_MAX_VCPUS
> (and rumor has it some downstream distributions already have more than '288')
> 
> Vitaly Kuznetsov (15):
>    selftests: kvm: Move kvm_get_supported_hv_cpuid() to common code
>    selftests: kvm: Properly set Hyper-V CPUIDs in evmcs_test
>    KVM: x86: hyper-v: Drop unused kvm_hv_vapic_assist_page_enabled()
>    KVM: x86: hyper-v: Rename vcpu_to_hv_vcpu() to to_hv_vcpu()
>    KVM: x86: hyper-v: Rename vcpu_to_synic()/synic_to_vcpu()
>    KVM: x86: hyper-v: Rename vcpu_to_stimer()/stimer_to_vcpu()
>    KVM: x86: hyper-v: Rename vcpu_to_hv_syndbg() to to_hv_syndbg()
>    KVM: x86: hyper-v: Introduce to_kvm_hv() helper
>    KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable
>    KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct
>      kvm_vcpu_hv'
>    KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context
>    KVM: x86: hyper-v: Allocate 'struct kvm_vcpu_hv' dynamically
>    KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional
>    KVM: x86: hyper-v: Allocate Hyper-V context lazily
>    KVM: x86: hyper-v: Drop hv_vcpu_to_vcpu() helper
> 
>   arch/x86/include/asm/kvm_host.h               |   4 +-
>   arch/x86/kvm/cpuid.c                          |   2 +
>   arch/x86/kvm/hyperv.c                         | 301 +++++++++++-------
>   arch/x86/kvm/hyperv.h                         |  54 ++--
>   arch/x86/kvm/lapic.c                          |   5 +-
>   arch/x86/kvm/lapic.h                          |   7 +-
>   arch/x86/kvm/vmx/vmx.c                        |   9 +-
>   arch/x86/kvm/x86.c                            |  19 +-
>   .../selftests/kvm/include/x86_64/processor.h  |   3 +
>   .../selftests/kvm/lib/x86_64/processor.c      |  33 ++
>   .../testing/selftests/kvm/x86_64/evmcs_test.c |  39 ++-
>   .../selftests/kvm/x86_64/hyperv_cpuid.c       |  31 +-
>   12 files changed, 314 insertions(+), 193 deletions(-)
> 

Queued, thanks.

Paolo


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 11/15] KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context
  2021-01-28 14:19   ` Paolo Bonzini
@ 2021-01-28 15:21     ` Vitaly Kuznetsov
  2021-01-28 16:58       ` Paolo Bonzini
  0 siblings, 1 reply; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-01-28 15:21 UTC (permalink / raw)
  To: Paolo Bonzini, kvm; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

Paolo Bonzini <pbonzini@redhat.com> writes:

> On 26/01/21 14:48, Vitaly Kuznetsov wrote:
>> 
>> +static inline u32 to_hv_vpindex(struct kvm_vcpu *vcpu)
>> +{
>> +	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
>> +
>> +	return hv_vcpu ? hv_vcpu->vp_index : kvm_vcpu_get_idx(vcpu);
>> +}
>> +
>
> I'd rather restrict to_* names for pointer conversions. 
> kvm_hv_get_vpindex is a better choice here.

No objections, feel free to rename. Alternatively, I can send a
follow-up patch.

-- 
Vitaly


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 11/15] KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context
  2021-01-28 15:21     ` Vitaly Kuznetsov
@ 2021-01-28 16:58       ` Paolo Bonzini
  0 siblings, 0 replies; 25+ messages in thread
From: Paolo Bonzini @ 2021-01-28 16:58 UTC (permalink / raw)
  To: Vitaly Kuznetsov, kvm; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

On 28/01/21 16:21, Vitaly Kuznetsov wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:
> 
>> On 26/01/21 14:48, Vitaly Kuznetsov wrote:
>>>
>>> +static inline u32 to_hv_vpindex(struct kvm_vcpu *vcpu)
>>> +{
>>> +	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
>>> +
>>> +	return hv_vcpu ? hv_vcpu->vp_index : kvm_vcpu_get_idx(vcpu);
>>> +}
>>> +
>>
>> I'd rather restrict to_* names for pointer conversions.
>> kvm_hv_get_vpindex is a better choice here.
> 
> No objections, feel free to rename. Alternatively, I can send a
> follow-up patch.

Ok, will do.

Paolo


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement
  2021-01-28 14:25 ` [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Paolo Bonzini
@ 2021-02-08 14:18   ` Vitaly Kuznetsov
  2021-02-08 15:02     ` Paolo Bonzini
  0 siblings, 1 reply; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-02-08 14:18 UTC (permalink / raw)
  To: Paolo Bonzini, kvm; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

Paolo Bonzini <pbonzini@redhat.com> writes:

> On 26/01/21 14:48, Vitaly Kuznetsov wrote:
>> Changes since v1 [Sean]:
>> - Add a few cleanup patches ("Rename vcpu_to_hv_vcpu() to to_hv_vcpu()",
>>    "Rename vcpu_to_synic()/synic_to_vcpu()", ...)
>> - Drop unused kvm_hv_vapic_assist_page_enabled()
>> - Stop shadowing global 'current_vcpu' variable in kvm_hv_flush_tlb()/
>>    kvm_hv_send_ipi()
>> 
>> Original description:
>> 
>> Hyper-V emulation is enabled in KVM unconditionally even for Linux guests.
>> This is bad at least from security standpoint as it is an extra attack
>> surface. Ideally, there should be a per-VM capability explicitly enabled by
>> VMM but currently it is not the case and we can't mandate one without
>> breaking backwards compatibility. We can, however, check guest visible CPUIDs
>> and only enable Hyper-V emulation when "Hv#1" interface was exposed in
>> HYPERV_CPUID_INTERFACE.
>> 
>> Also (and while on it) per-vcpu Hyper-V context ('struct kvm_vcpu_hv') is
>> currently part of 'struct kvm_vcpu_arch' and thus allocated unconditionally
>> for each vCPU. The context, however, quite big and accounts for more than
>> 1/4 of 'struct kvm_vcpu_arch' (e.g. 2912/9512 bytes). Switch to allocating
>> it dynamically. This may come handy if we ever decide to raise KVM_MAX_VCPUS
>> (and rumor has it some downstream distributions already have more than '288')
>> 
>> Vitaly Kuznetsov (15):
>>    selftests: kvm: Move kvm_get_supported_hv_cpuid() to common code
>>    selftests: kvm: Properly set Hyper-V CPUIDs in evmcs_test
>>    KVM: x86: hyper-v: Drop unused kvm_hv_vapic_assist_page_enabled()
>>    KVM: x86: hyper-v: Rename vcpu_to_hv_vcpu() to to_hv_vcpu()
>>    KVM: x86: hyper-v: Rename vcpu_to_synic()/synic_to_vcpu()
>>    KVM: x86: hyper-v: Rename vcpu_to_stimer()/stimer_to_vcpu()
>>    KVM: x86: hyper-v: Rename vcpu_to_hv_syndbg() to to_hv_syndbg()
>>    KVM: x86: hyper-v: Introduce to_kvm_hv() helper
>>    KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable
>>    KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct
>>      kvm_vcpu_hv'
>>    KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context
>>    KVM: x86: hyper-v: Allocate 'struct kvm_vcpu_hv' dynamically
>>    KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional
>>    KVM: x86: hyper-v: Allocate Hyper-V context lazily
>>    KVM: x86: hyper-v: Drop hv_vcpu_to_vcpu() helper
>> 
...
>> 
>
> Queued, thanks.

I was expecting it to appear in kvm/queue but it didn't happen so just
wanted to double-check what happened to these patches. Thanks!

-- 
Vitaly


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement
  2021-02-08 14:18   ` Vitaly Kuznetsov
@ 2021-02-08 15:02     ` Paolo Bonzini
  0 siblings, 0 replies; 25+ messages in thread
From: Paolo Bonzini @ 2021-02-08 15:02 UTC (permalink / raw)
  To: Vitaly Kuznetsov, kvm; +Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

On 08/02/21 15:18, Vitaly Kuznetsov wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:
> 
>> On 26/01/21 14:48, Vitaly Kuznetsov wrote:
>>> Changes since v1 [Sean]:
>>> - Add a few cleanup patches ("Rename vcpu_to_hv_vcpu() to to_hv_vcpu()",
>>>     "Rename vcpu_to_synic()/synic_to_vcpu()", ...)
>>> - Drop unused kvm_hv_vapic_assist_page_enabled()
>>> - Stop shadowing global 'current_vcpu' variable in kvm_hv_flush_tlb()/
>>>     kvm_hv_send_ipi()
>>>
>>> Original description:
>>>
>>> Hyper-V emulation is enabled in KVM unconditionally even for Linux guests.
>>> This is bad at least from security standpoint as it is an extra attack
>>> surface. Ideally, there should be a per-VM capability explicitly enabled by
>>> VMM but currently it is not the case and we can't mandate one without
>>> breaking backwards compatibility. We can, however, check guest visible CPUIDs
>>> and only enable Hyper-V emulation when "Hv#1" interface was exposed in
>>> HYPERV_CPUID_INTERFACE.
>>>
>>> Also (and while on it) per-vcpu Hyper-V context ('struct kvm_vcpu_hv') is
>>> currently part of 'struct kvm_vcpu_arch' and thus allocated unconditionally
>>> for each vCPU. The context, however, quite big and accounts for more than
>>> 1/4 of 'struct kvm_vcpu_arch' (e.g. 2912/9512 bytes). Switch to allocating
>>> it dynamically. This may come handy if we ever decide to raise KVM_MAX_VCPUS
>>> (and rumor has it some downstream distributions already have more than '288')
>>>
>>> Vitaly Kuznetsov (15):
>>>     selftests: kvm: Move kvm_get_supported_hv_cpuid() to common code
>>>     selftests: kvm: Properly set Hyper-V CPUIDs in evmcs_test
>>>     KVM: x86: hyper-v: Drop unused kvm_hv_vapic_assist_page_enabled()
>>>     KVM: x86: hyper-v: Rename vcpu_to_hv_vcpu() to to_hv_vcpu()
>>>     KVM: x86: hyper-v: Rename vcpu_to_synic()/synic_to_vcpu()
>>>     KVM: x86: hyper-v: Rename vcpu_to_stimer()/stimer_to_vcpu()
>>>     KVM: x86: hyper-v: Rename vcpu_to_hv_syndbg() to to_hv_syndbg()
>>>     KVM: x86: hyper-v: Introduce to_kvm_hv() helper
>>>     KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable
>>>     KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct
>>>       kvm_vcpu_hv'
>>>     KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context
>>>     KVM: x86: hyper-v: Allocate 'struct kvm_vcpu_hv' dynamically
>>>     KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional
>>>     KVM: x86: hyper-v: Allocate Hyper-V context lazily
>>>     KVM: x86: hyper-v: Drop hv_vcpu_to_vcpu() helper
>>>
> ...
>>>
>>
>> Queued, thanks.
> 
> I was expecting it to appear in kvm/queue but it didn't happen so just
> wanted to double-check what happened to these patches. Thanks!

Added them back now (they conflicted with the Xen patches), thanks.

Paolo


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 10/15] KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct kvm_vcpu_hv'
  2021-01-26 13:48 ` [PATCH v2 10/15] KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct kvm_vcpu_hv' Vitaly Kuznetsov
@ 2021-02-08 23:06   ` Maxim Levitsky
  2021-02-09  8:38     ` Vitaly Kuznetsov
  0 siblings, 1 reply; 25+ messages in thread
From: Maxim Levitsky @ 2021-02-08 23:06 UTC (permalink / raw)
  To: Vitaly Kuznetsov, kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson

On Tue, 2021-01-26 at 14:48 +0100, Vitaly Kuznetsov wrote:


...
> _vcpu_mask(
>  static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, u64 ingpa, u16 rep_cnt, bool ex)
>  {
>  	struct kvm *kvm = vcpu->kvm;
> -	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
> +	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(current_vcpu);
You probably mean vcpu here instead of current_vcpu. Today I smoke tested the kvm/nested-svm branch,
and had this fail on me while testing windows guests.


Other than that HyperV seems to work and even survive nested migration (I had one
windows reboot but I suspect windows update did it.)
I'll leave my test overnight (now with updates disabled) to see if it is stable.

Best regards,
	Maxim Levitsky


>  	struct hv_tlb_flush_ex flush_ex;
>  	struct hv_tlb_flush flush;
>  	u64 vp_bitmap[KVM_HV_MAX_SPARSE_VCPU_SET_BITS];
> diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
> index fdb321ba9c3f..be1e3f5d1df6 100644
> --- a/arch/x86/kvm/hyperv.h
> +++ b/arch/x86/kvm/hyperv.h
> @@ -119,7 +119,9 @@ static inline struct kvm_vcpu *hv_stimer_to_vcpu(struct kvm_vcpu_hv_stimer *stim
>  
>  static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu)
>  {
> -	return !bitmap_empty(vcpu->arch.hyperv.stimer_pending_bitmap,
> +	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
> +
> +	return !bitmap_empty(hv_vcpu->stimer_pending_bitmap,
>  			     HV_SYNIC_STIMER_COUNT);
>  }
>  
> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
> index 4de7579e206c..4ad2fbbd962a 100644
> --- a/arch/x86/kvm/lapic.h
> +++ b/arch/x86/kvm/lapic.h
> @@ -6,6 +6,8 @@
>  
>  #include <linux/kvm_host.h>
>  
> +#include "hyperv.h"
> +
>  #define KVM_APIC_INIT		0
>  #define KVM_APIC_SIPI		1
>  #define KVM_APIC_LVT_NUM	6
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 9db84508aa0b..443878dd775c 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -6733,12 +6733,14 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
>  	x86_spec_ctrl_restore_host(vmx->spec_ctrl, 0);
>  
>  	/* All fields are clean at this point */
> -	if (static_branch_unlikely(&enable_evmcs))
> +	if (static_branch_unlikely(&enable_evmcs)) {
> +		struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
> +
>  		current_evmcs->hv_clean_fields |=
>  			HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL;
>  
> -	if (static_branch_unlikely(&enable_evmcs))
> -		current_evmcs->hv_vp_id = vcpu->arch.hyperv.vp_index;
> +		current_evmcs->hv_vp_id = hv_vcpu->vp_index;
> +	}
>  
>  	/* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */
>  	if (vmx->host_debugctlmsr)
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 868d2bf8fb95..4c2b1f4260c6 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -8894,8 +8894,10 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
>  			goto out;
>  		}
>  		if (kvm_check_request(KVM_REQ_HV_EXIT, vcpu)) {
> +			struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
> +
>  			vcpu->run->exit_reason = KVM_EXIT_HYPERV;
> -			vcpu->run->hyperv = vcpu->arch.hyperv.exit;
> +			vcpu->run->hyperv = hv_vcpu->exit;
>  			r = 0;
>  			goto out;
>  		}



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 10/15] KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct kvm_vcpu_hv'
  2021-02-08 23:06   ` Maxim Levitsky
@ 2021-02-09  8:38     ` Vitaly Kuznetsov
  2021-02-09 10:31       ` Maxim Levitsky
  0 siblings, 1 reply; 25+ messages in thread
From: Vitaly Kuznetsov @ 2021-02-09  8:38 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson, kvm, Paolo Bonzini

Maxim Levitsky <mlevitsk@redhat.com> writes:

> On Tue, 2021-01-26 at 14:48 +0100, Vitaly Kuznetsov wrote:
>
>
> ...
>> _vcpu_mask(
>>  static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, u64 ingpa, u16 rep_cnt, bool ex)
>>  {
>>  	struct kvm *kvm = vcpu->kvm;
>> -	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
>> +	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(current_vcpu);
> You probably mean vcpu here instead of current_vcpu. Today I smoke tested the kvm/nested-svm branch,
> and had this fail on me while testing windows guests.
>

Yes!!!

We were using 'current_vcpu' instead of 'vcpu' here before but Sean
warned me about the danger of shadowing global 'current_vcpu' so I added
'KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable' to
the series. Aparently, I missed this 'current_vcpu' while
rebasing. AFAIU, normally vcpu == current_vcpu when entering this
function so nothing blew up in my testing.

Thanks for the report! I'll be sending a patch to fix this shortly.

>
> Other than that HyperV seems to work and even survive nested migration (I had one
> windows reboot but I suspect windows update did it.)
> I'll leave my test overnight (now with updates disabled) to see if it
> is stable.

That's good to hear! Are you testing on Intel or AMD? With AMD there's a
stale bug somewhere which prevents Gen2 (UEFI) L2 guests from booting,
the firmare just hangs somewhere not making any progress. Both Hyper-V
2016 and 2019 seem to be affected. Gen1 guests (including Windows in
root partition) work fine. I tried approaching it a couple times but
with no luck so far. Not sure if this is CPU specific or something...

-- 
Vitaly


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 10/15] KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct kvm_vcpu_hv'
  2021-02-09  8:38     ` Vitaly Kuznetsov
@ 2021-02-09 10:31       ` Maxim Levitsky
  0 siblings, 0 replies; 25+ messages in thread
From: Maxim Levitsky @ 2021-02-09 10:31 UTC (permalink / raw)
  To: Vitaly Kuznetsov
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson, kvm, Paolo Bonzini

On Tue, 2021-02-09 at 09:38 +0100, Vitaly Kuznetsov wrote:
> Maxim Levitsky <mlevitsk@redhat.com> writes:
> 
> > On Tue, 2021-01-26 at 14:48 +0100, Vitaly Kuznetsov wrote:
> > 
> > 
> > ...
> > > _vcpu_mask(
> > >  static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, u64 ingpa, u16 rep_cnt, bool ex)
> > >  {
> > >  	struct kvm *kvm = vcpu->kvm;
> > > -	struct kvm_vcpu_hv *hv_vcpu = &vcpu->arch.hyperv;
> > > +	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(current_vcpu);
> > You probably mean vcpu here instead of current_vcpu. Today I smoke tested the kvm/nested-svm branch,
> > and had this fail on me while testing windows guests.
> > 
> 
> Yes!!!
> 
> We were using 'current_vcpu' instead of 'vcpu' here before but Sean
> warned me about the danger of shadowing global 'current_vcpu' so I added
> 'KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable' to
> the series. Aparently, I missed this 'current_vcpu' while
> rebasing. AFAIU, normally vcpu == current_vcpu when entering this
> function so nothing blew up in my testing.
> 
> Thanks for the report! I'll be sending a patch to fix this shortly.
> 
> > Other than that HyperV seems to work and even survive nested migration (I had one
> > windows reboot but I suspect windows update did it.)
> > I'll leave my test overnight (now with updates disabled) to see if it
> > is stable.
> 
> That's good to hear! Are you testing on Intel or AMD? With AMD there's a
> stale bug somewhere which prevents Gen2 (UEFI) L2 guests from booting,
> the firmare just hangs somewhere not making any progress. Both Hyper-V
> 2016 and 2019 seem to be affected. Gen1 guests (including Windows in
> root partition) work fine. I tried approaching it a couple times but
> with no luck so far. Not sure if this is CPU specific or something...
> 

I never had luck with Gen2 guests on AMD (they did work on Intel last time I tried).
I have both Gen1 and Gen2 guests installed, and I boot them once in a while. 

The VM I test HV with is running windows 10 pro build 1909.

On Intel both work, on AMD only Gen1 works. I can take a look, maybe I can spot something.

Do you know by a chance if WSL2 is a Gen2 guest? They have hidden it very well from the user
so you don't even know that you are running a VM.

About my 'windows update' theory, I was wrong, I just haven't given enough memory to
the HV host, and it eventually started getting out of memory crashes according to the event log, 
so I upped the HV memory a bit and it survived ~900 iterations of nested migration so far.

Besides this,
I do have two HV bugs that I am tracking. One relates to not correct initalization of mmu
on nested state load, which is not HV specific but seems to be triggered by it VM 
(I'll send a patch today)

Second issue, is if I run the HV host as a nested itself (which is overkill, but this can easily be not
related to this setup but just have different timings), 
the HV host bluescreens eventually, after doing repeated migration of L1 guest 
(L1 is linux with same patched kernel, L2 is HV host)
It does seem to work on Intel.

Best regards,
	Maxim Levitsky



^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2021-02-09 10:36 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-26 13:48 [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 01/15] selftests: kvm: Move kvm_get_supported_hv_cpuid() to common code Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 02/15] selftests: kvm: Properly set Hyper-V CPUIDs in evmcs_test Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 03/15] KVM: x86: hyper-v: Drop unused kvm_hv_vapic_assist_page_enabled() Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 04/15] KVM: x86: hyper-v: Rename vcpu_to_hv_vcpu() to to_hv_vcpu() Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 05/15] KVM: x86: hyper-v: Rename vcpu_to_synic()/synic_to_vcpu() Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 06/15] KVM: x86: hyper-v: Rename vcpu_to_stimer()/stimer_to_vcpu() Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 07/15] KVM: x86: hyper-v: Rename vcpu_to_hv_syndbg() to to_hv_syndbg() Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 08/15] KVM: x86: hyper-v: Introduce to_kvm_hv() helper Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 09/15] KVM: x86: hyper-v: Stop shadowing global 'current_vcpu' variable Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 10/15] KVM: x86: hyper-v: Always use to_hv_vcpu() accessor to get to 'struct kvm_vcpu_hv' Vitaly Kuznetsov
2021-02-08 23:06   ` Maxim Levitsky
2021-02-09  8:38     ` Vitaly Kuznetsov
2021-02-09 10:31       ` Maxim Levitsky
2021-01-26 13:48 ` [PATCH v2 11/15] KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context Vitaly Kuznetsov
2021-01-28 14:19   ` Paolo Bonzini
2021-01-28 15:21     ` Vitaly Kuznetsov
2021-01-28 16:58       ` Paolo Bonzini
2021-01-26 13:48 ` [PATCH v2 12/15] KVM: x86: hyper-v: Allocate 'struct kvm_vcpu_hv' dynamically Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 13/15] KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 14/15] KVM: x86: hyper-v: Allocate Hyper-V context lazily Vitaly Kuznetsov
2021-01-26 13:48 ` [PATCH v2 15/15] KVM: x86: hyper-v: Drop hv_vcpu_to_vcpu() helper Vitaly Kuznetsov
2021-01-28 14:25 ` [PATCH v2 00/15] KVM: x86: Conditional Hyper-V emulation enablement Paolo Bonzini
2021-02-08 14:18   ` Vitaly Kuznetsov
2021-02-08 15:02     ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).