Linux-HyperV Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs
@ 2021-04-13 12:26 Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 01/22] asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition Vitaly Kuznetsov
                   ` (21 more replies)
  0 siblings, 22 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Currently, all implemented Hyper-V features (MSRs and hypercalls) are
available unconditionally to all Hyper-V enabled guests. This is not
ideal as KVM userspace may decide to provide only a subset of the
currently implemented features to emulate an older Hyper-V version,
to reduce attack surface,... Implement checks against guest visible
CPUIDs for all currently implemented MSRs and hypercalls.

RFC part:
- KVM has KVM_CAP_ENFORCE_PV_FEATURE_CPUID for KVM PV features. Should
 we use it for Hyper-V as well or should we rather add a Hyper-V specific
 CAP (or neither)?

TODO:
- Write a selftest
- Check with various Windows/Hyper-V versions that CPUID feature bits
 are actually respected.

Vitaly Kuznetsov (22):
  asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition
  KVM: x86: hyper-v: Cache guest CPUID leaves determining features
    availability
  KVM: x86: hyper-v: Honor HV_MSR_VP_RUNTIME_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_MSR_TIME_REF_COUNT_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_MSR_HYPERCALL_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_MSR_VP_INDEX_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_MSR_RESET_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_MSR_REFERENCE_TSC_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_MSR_SYNIC_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_MSR_SYNTIMER_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_MSR_APIC_ACCESS_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_ACCESS_FREQUENCY_MSRS privilege bit
  KVM: x86: hyper-v: Honor HV_ACCESS_REENLIGHTENMENT privilege bit
  KVM: x86: hyper-v: Honor HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
    privilege bit
  KVM: x86: hyper-v: Honor HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
    privilege bit
  KVM: x86: hyper-v: Honor HV_STIMER_DIRECT_MODE_AVAILABLE privilege bit
  KVM: x86: hyper-v: Honor HV_POST_MESSAGES privilege bit
  KVM: x86: hyper-v: Honor HV_SIGNAL_EVENTS privilege bit
  KVM: x86: hyper-v: Honor HV_DEBUGGING privilege bit
  KVM: x86: hyper-v: Honor HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED bit
  KVM: x86: hyper-v: Honor HV_X64_CLUSTER_IPI_RECOMMENDED bit
  KVM: x86: hyper-v: Check access to HVCALL_NOTIFY_LONG_SPIN_WAIT
    hypercall

 arch/x86/include/asm/kvm_host.h   |   8 +
 arch/x86/kvm/hyperv.c             | 305 +++++++++++++++++++++++++++---
 include/asm-generic/hyperv-tlfs.h |   1 +
 3 files changed, 291 insertions(+), 23 deletions(-)

-- 
2.30.2


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

* [PATCH RFC 01/22] asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-15 14:14   ` Wei Liu
  2021-04-13 12:26 ` [PATCH RFC 02/22] KVM: x86: hyper-v: Cache guest CPUID leaves determining features availability Vitaly Kuznetsov
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

From TLFSv6.0b, this status means: "The caller did not possess sufficient
access rights to perform the requested operation."

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 include/asm-generic/hyperv-tlfs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
index 83448e837ded..e01a3bade13a 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -187,6 +187,7 @@ enum HV_GENERIC_SET_FORMAT {
 #define HV_STATUS_INVALID_HYPERCALL_INPUT	3
 #define HV_STATUS_INVALID_ALIGNMENT		4
 #define HV_STATUS_INVALID_PARAMETER		5
+#define HV_STATUS_ACCESS_DENIED			6
 #define HV_STATUS_OPERATION_DENIED		8
 #define HV_STATUS_INSUFFICIENT_MEMORY		11
 #define HV_STATUS_INVALID_PORT_ID		17
-- 
2.30.2


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

* [PATCH RFC 02/22] KVM: x86: hyper-v: Cache guest CPUID leaves determining features availability
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 01/22] asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 03/22] KVM: x86: hyper-v: Honor HV_MSR_VP_RUNTIME_AVAILABLE privilege bit Vitaly Kuznetsov
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/include/asm/kvm_host.h |  8 ++++++
 arch/x86/kvm/hyperv.c           | 50 ++++++++++++++++++++++++++-------
 2 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 3768819693e5..04bddcaa8cad 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -530,6 +530,14 @@ struct kvm_vcpu_hv {
 	struct kvm_vcpu_hv_stimer stimer[HV_SYNIC_STIMER_COUNT];
 	DECLARE_BITMAP(stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
 	cpumask_t tlb_flush;
+	struct {
+		u32 features_eax; /* HYPERV_CPUID_FEATURES.EAX */
+		u32 features_ebx; /* HYPERV_CPUID_FEATURES.EBX */
+		u32 features_edx; /* HYPERV_CPUID_FEATURES.EDX */
+		u32 enlightenments_eax; /* HYPERV_CPUID_ENLIGHTMENT_INFO.EAX */
+		u32 enlightenments_ebx; /* HYPERV_CPUID_ENLIGHTMENT_INFO.EBX */
+		u32 syndbg_cap_eax; /* HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES.EAX */
+	} cpuid_cache;
 };
 
 /* Xen HVM per vcpu emulation context */
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index f98370a39936..781f9da9a418 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -273,15 +273,10 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
 
 static bool kvm_hv_is_syndbg_enabled(struct kvm_vcpu *vcpu)
 {
-	struct kvm_cpuid_entry2 *entry;
-
-	entry = kvm_find_cpuid_entry(vcpu,
-				     HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES,
-				     0);
-	if (!entry)
-		return false;
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
-	return entry->eax & HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING;
+	return hv_vcpu->cpuid_cache.syndbg_cap_eax &
+		HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING;
 }
 
 static int kvm_hv_syndbg_complete_userspace(struct kvm_vcpu *vcpu)
@@ -1801,12 +1796,47 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, u64 ingpa, u64 outgpa,
 void kvm_hv_set_cpuid(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpuid_entry2 *entry;
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
 	entry = kvm_find_cpuid_entry(vcpu, HYPERV_CPUID_INTERFACE, 0);
-	if (entry && entry->eax == HYPERV_CPUID_SIGNATURE_EAX)
+	if (entry && entry->eax == HYPERV_CPUID_SIGNATURE_EAX) {
 		vcpu->arch.hyperv_enabled = true;
-	else
+	} else {
 		vcpu->arch.hyperv_enabled = false;
+		return;
+	}
+
+	if (!to_hv_vcpu(vcpu) && kvm_hv_vcpu_init(vcpu))
+		return;
+
+	hv_vcpu = to_hv_vcpu(vcpu);
+
+	entry = kvm_find_cpuid_entry(vcpu, HYPERV_CPUID_FEATURES, 0);
+	if (entry) {
+		hv_vcpu->cpuid_cache.features_eax = entry->eax;
+		hv_vcpu->cpuid_cache.features_ebx = entry->ebx;
+		hv_vcpu->cpuid_cache.features_edx = entry->edx;
+	} else {
+		hv_vcpu->cpuid_cache.features_eax = 0;
+		hv_vcpu->cpuid_cache.features_ebx = 0;
+		hv_vcpu->cpuid_cache.features_edx = 0;
+	}
+
+	entry = kvm_find_cpuid_entry(vcpu, HYPERV_CPUID_ENLIGHTMENT_INFO, 0);
+	if (entry) {
+		hv_vcpu->cpuid_cache.enlightenments_eax = entry->eax;
+		hv_vcpu->cpuid_cache.enlightenments_ebx = entry->ebx;
+	} else {
+		hv_vcpu->cpuid_cache.enlightenments_eax = 0;
+		hv_vcpu->cpuid_cache.enlightenments_ebx = 0;
+	}
+
+	entry = kvm_find_cpuid_entry(vcpu, HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES, 0);
+	if (entry) {
+		hv_vcpu->cpuid_cache.syndbg_cap_eax = entry->eax;
+	} else {
+		hv_vcpu->cpuid_cache.syndbg_cap_eax = 0;
+	}
 }
 
 bool kvm_hv_hypercall_enabled(struct kvm_vcpu *vcpu)
-- 
2.30.2


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

* [PATCH RFC 03/22] KVM: x86: hyper-v: Honor HV_MSR_VP_RUNTIME_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 01/22] asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 02/22] KVM: x86: hyper-v: Cache guest CPUID leaves determining features availability Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 04/22] KVM: x86: hyper-v: Honor HV_MSR_TIME_REF_COUNT_AVAILABLE " Vitaly Kuznetsov
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_VP_RUNTIME is only available to guest when
HV_MSR_VP_RUNTIME_AVAILABLE bit is exposed.

Note, writing to HV_X64_MSR_VP_RUNTIME is only available from the host so
kvm_hv_set_msr() doesn't need an additional check.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 781f9da9a418..b39445aabbc2 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1504,6 +1504,10 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 		data = hv_vcpu->hv_vapic;
 		break;
 	case HV_X64_MSR_VP_RUNTIME:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_VP_RUNTIME_AVAILABLE)))
+			return 1;
+
 		data = current_task_runtime_100ns() + hv_vcpu->runtime_offset;
 		break;
 	case HV_X64_MSR_SCONTROL:
-- 
2.30.2


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

* [PATCH RFC 04/22] KVM: x86: hyper-v: Honor HV_MSR_TIME_REF_COUNT_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (2 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 03/22] KVM: x86: hyper-v: Honor HV_MSR_VP_RUNTIME_AVAILABLE privilege bit Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 05/22] KVM: x86: hyper-v: Honor HV_MSR_HYPERCALL_AVAILABLE " Vitaly Kuznetsov
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_TIME_REF_COUNT is only available to guest when
HV_MSR_TIME_REF_COUNT_AVAILABLE bit is exposed.

Note, writing to HV_X64_MSR_TIME_REF_COUNT is unsupported so
kvm_hv_set_msr_pw() doesn't need an additional check.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index b39445aabbc2..efb3d69c98fd 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1440,6 +1440,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 = to_kvm_hv(kvm);
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
 	switch (msr) {
 	case HV_X64_MSR_GUEST_OS_ID:
@@ -1449,6 +1450,10 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 		data = hv->hv_hypercall;
 		break;
 	case HV_X64_MSR_TIME_REF_COUNT:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_TIME_REF_COUNT_AVAILABLE)))
+			return 1;
+
 		data = get_time_ref_counter(kvm);
 		break;
 	case HV_X64_MSR_REFERENCE_TSC:
-- 
2.30.2


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

* [PATCH RFC 05/22] KVM: x86: hyper-v: Honor HV_MSR_HYPERCALL_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (3 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 04/22] KVM: x86: hyper-v: Honor HV_MSR_TIME_REF_COUNT_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 06/22] KVM: x86: hyper-v: Honor HV_MSR_VP_INDEX_AVAILABLE " Vitaly Kuznetsov
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_GUEST_OS_ID/HV_X64_MSR_HYPERCALL are only available to guest
when HV_MSR_HYPERCALL_AVAILABLE bit is exposed.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index efb3d69c98fd..7fdd9b9c50d6 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1198,9 +1198,14 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
 {
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_hv *hv = to_kvm_hv(kvm);
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
 	switch (msr) {
 	case HV_X64_MSR_GUEST_OS_ID:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_HYPERCALL_AVAILABLE)))
+			return 1;
+
 		hv->hv_guest_os_id = data;
 		/* setting guest os id to zero disables hypercall page */
 		if (!hv->hv_guest_os_id)
@@ -1211,6 +1216,10 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
 		int i = 0;
 		u64 addr;
 
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_HYPERCALL_AVAILABLE)))
+			return 1;
+
 		/* if guest os id is not set hypercall should remain disabled */
 		if (!hv->hv_guest_os_id)
 			break;
@@ -1444,9 +1453,17 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 
 	switch (msr) {
 	case HV_X64_MSR_GUEST_OS_ID:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_HYPERCALL_AVAILABLE)))
+			return 1;
+
 		data = hv->hv_guest_os_id;
 		break;
 	case HV_X64_MSR_HYPERCALL:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_HYPERCALL_AVAILABLE)))
+			return 1;
+
 		data = hv->hv_hypercall;
 		break;
 	case HV_X64_MSR_TIME_REF_COUNT:
-- 
2.30.2


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

* [PATCH RFC 06/22] KVM: x86: hyper-v: Honor HV_MSR_VP_INDEX_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (4 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 05/22] KVM: x86: hyper-v: Honor HV_MSR_HYPERCALL_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 07/22] KVM: x86: hyper-v: Honor HV_MSR_RESET_AVAILABLE " Vitaly Kuznetsov
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_VP_INDEX is only available to guest when
HV_MSR_VP_INDEX_AVAILABLE bit is exposed.

Note, writing to HV_X64_MSR_VP_INDEX is only available from the host so
kvm_hv_set_msr() doesn't need an additional check.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 7fdd9b9c50d6..07f1fc8575e5 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1514,6 +1514,10 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 
 	switch (msr) {
 	case HV_X64_MSR_VP_INDEX:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_VP_INDEX_AVAILABLE)))
+			return 1;
+
 		data = hv_vcpu->vp_index;
 		break;
 	case HV_X64_MSR_EOI:
-- 
2.30.2


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

* [PATCH RFC 07/22] KVM: x86: hyper-v: Honor HV_MSR_RESET_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (5 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 06/22] KVM: x86: hyper-v: Honor HV_MSR_VP_INDEX_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 08/22] KVM: x86: hyper-v: Honor HV_MSR_REFERENCE_TSC_AVAILABLE " Vitaly Kuznetsov
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_RESET is only available to guest when HV_MSR_RESET_AVAILABLE bit
is exposed.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 07f1fc8575e5..15d557ce32b5 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1289,6 +1289,10 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
 		}
 		break;
 	case HV_X64_MSR_RESET:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_RESET_AVAILABLE)))
+			return 1;
+
 		if (data == 1) {
 			vcpu_debug(vcpu, "hyper-v reset requested\n");
 			kvm_make_request(KVM_REQ_HV_RESET, vcpu);
@@ -1483,6 +1487,10 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 	case HV_X64_MSR_CRASH_CTL:
 		return kvm_hv_msr_get_crash_ctl(kvm, pdata);
 	case HV_X64_MSR_RESET:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_RESET_AVAILABLE)))
+			return 1;
+
 		data = 0;
 		break;
 	case HV_X64_MSR_REENLIGHTENMENT_CONTROL:
-- 
2.30.2


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

* [PATCH RFC 08/22] KVM: x86: hyper-v: Honor HV_MSR_REFERENCE_TSC_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (6 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 07/22] KVM: x86: hyper-v: Honor HV_MSR_RESET_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 09/22] KVM: x86: hyper-v: Honor HV_MSR_SYNIC_AVAILABLE " Vitaly Kuznetsov
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_REFERENCE_TSC is only available to guest when
HV_MSR_REFERENCE_TSC_AVAILABLE bit is exposed.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 15d557ce32b5..48215ad72b6c 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1257,6 +1257,10 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
 		break;
 	}
 	case HV_X64_MSR_REFERENCE_TSC:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_REFERENCE_TSC_AVAILABLE)))
+			return 1;
+
 		hv->hv_tsc_page = data;
 		if (hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE) {
 			if (!host)
@@ -1478,6 +1482,10 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 		data = get_time_ref_counter(kvm);
 		break;
 	case HV_X64_MSR_REFERENCE_TSC:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_REFERENCE_TSC_AVAILABLE)))
+			return 1;
+
 		data = hv->hv_tsc_page;
 		break;
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
-- 
2.30.2


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

* [PATCH RFC 09/22] KVM: x86: hyper-v: Honor HV_MSR_SYNIC_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (7 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 08/22] KVM: x86: hyper-v: Honor HV_MSR_REFERENCE_TSC_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 10/22] KVM: x86: hyper-v: Honor HV_MSR_SYNTIMER_AVAILABLE " Vitaly Kuznetsov
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

SynIC MSRs (HV_X64_MSR_SCONTROL, HV_X64_MSR_SVERSION, HV_X64_MSR_SIEFP,
HV_X64_MSR_SIMP, HV_X64_MSR_EOM, HV_X64_MSR_SINT0 ... HV_X64_MSR_SINT15)
are only available to guest when HV_MSR_SYNIC_AVAILABLE bit is exposed.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 48215ad72b6c..d85c441011c4 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -211,7 +211,9 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
 	struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic);
 	int ret;
 
-	if (!synic->active && !host)
+	if (unlikely(!host &&
+		     (!synic->active || !(to_hv_vcpu(vcpu)->cpuid_cache.features_eax &
+					  HV_MSR_SYNIC_AVAILABLE))))
 		return 1;
 
 	trace_kvm_hv_synic_set_msr(vcpu->vcpu_id, msr, data, host);
@@ -383,9 +385,12 @@ static int syndbg_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host)
 static int synic_get_msr(struct kvm_vcpu_hv_synic *synic, u32 msr, u64 *pdata,
 			 bool host)
 {
+	struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic);
 	int ret;
 
-	if (!synic->active && !host)
+	if (unlikely(!host &&
+		     (!synic->active || !(to_hv_vcpu(vcpu)->cpuid_cache.features_eax &
+					  HV_MSR_SYNIC_AVAILABLE))))
 		return 1;
 
 	ret = 0;
-- 
2.30.2


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

* [PATCH RFC 10/22] KVM: x86: hyper-v: Honor HV_MSR_SYNTIMER_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (8 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 09/22] KVM: x86: hyper-v: Honor HV_MSR_SYNIC_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 11/22] KVM: x86: hyper-v: Honor HV_MSR_APIC_ACCESS_AVAILABLE " Vitaly Kuznetsov
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Synthetic timers MSRs (HV_X64_MSR_STIMER[0-3]_CONFIG,
HV_X64_MSR_STIMER[0-3]_COUNT) are only available to guest when
HV_MSR_SYNTIMER_AVAILABLE bit is exposed.

While on it, complement stimer_get_config()/stimer_get_count() with
the same '!synic->active' check we have in stimer_set_config()/
stimer_set_count().

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index d85c441011c4..032305ad5615 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -637,7 +637,9 @@ static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
 	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
 	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
 
-	if (!synic->active && !host)
+	if (unlikely(!host && (!synic->active ||
+			       !(to_hv_vcpu(vcpu)->cpuid_cache.features_eax &
+				 HV_MSR_SYNTIMER_AVAILABLE))))
 		return 1;
 
 	trace_kvm_hv_stimer_set_config(hv_stimer_to_vcpu(stimer)->vcpu_id,
@@ -661,7 +663,9 @@ static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
 	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
 	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
 
-	if (!synic->active && !host)
+	if (unlikely(!host && (!synic->active ||
+			       !(to_hv_vcpu(vcpu)->cpuid_cache.features_eax &
+				 HV_MSR_SYNTIMER_AVAILABLE))))
 		return 1;
 
 	trace_kvm_hv_stimer_set_count(hv_stimer_to_vcpu(stimer)->vcpu_id,
@@ -680,14 +684,32 @@ static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
 	return 0;
 }
 
-static int stimer_get_config(struct kvm_vcpu_hv_stimer *stimer, u64 *pconfig)
+static int stimer_get_config(struct kvm_vcpu_hv_stimer *stimer, u64 *pconfig,
+			     bool host)
 {
+	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
+	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
+
+	if (unlikely(!host && (!synic->active ||
+			       !(to_hv_vcpu(vcpu)->cpuid_cache.features_eax &
+				 HV_MSR_SYNTIMER_AVAILABLE))))
+		return 1;
+
 	*pconfig = stimer->config.as_uint64;
 	return 0;
 }
 
-static int stimer_get_count(struct kvm_vcpu_hv_stimer *stimer, u64 *pcount)
+static int stimer_get_count(struct kvm_vcpu_hv_stimer *stimer, u64 *pcount,
+			    bool host)
 {
+	struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer);
+	struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu);
+
+	if (unlikely(!host && (!synic->active ||
+			       !(to_hv_vcpu(vcpu)->cpuid_cache.features_eax &
+				 HV_MSR_SYNTIMER_AVAILABLE))))
+		return 1;
+
 	*pcount = stimer->count;
 	return 0;
 }
@@ -1571,7 +1593,7 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 		int timer_index = (msr - HV_X64_MSR_STIMER0_CONFIG)/2;
 
 		return stimer_get_config(to_hv_stimer(vcpu, timer_index),
-					 pdata);
+					 pdata, host);
 	}
 	case HV_X64_MSR_STIMER0_COUNT:
 	case HV_X64_MSR_STIMER1_COUNT:
@@ -1580,7 +1602,7 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 		int timer_index = (msr - HV_X64_MSR_STIMER0_COUNT)/2;
 
 		return stimer_get_count(to_hv_stimer(vcpu, timer_index),
-					pdata);
+					pdata, host);
 	}
 	case HV_X64_MSR_TSC_FREQUENCY:
 		data = (u64)vcpu->arch.virtual_tsc_khz * 1000;
-- 
2.30.2


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

* [PATCH RFC 11/22] KVM: x86: hyper-v: Honor HV_MSR_APIC_ACCESS_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (9 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 10/22] KVM: x86: hyper-v: Honor HV_MSR_SYNTIMER_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 12/22] KVM: x86: hyper-v: Honor HV_ACCESS_FREQUENCY_MSRS " Vitaly Kuznetsov
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_EOI, HV_X64_MSR_ICR, HV_X64_MSR_TPR, and
HV_X64_MSR_VP_ASSIST_PAGE  are only available to guest when
HV_MSR_APIC_ACCESS_AVAILABLE bit is exposed.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 032305ad5615..9c4454873e00 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1401,6 +1401,10 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 		u64 gfn;
 		unsigned long addr;
 
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_APIC_ACCESS_AVAILABLE)))
+			return 1;
+
 		if (!(data & HV_X64_MSR_VP_ASSIST_PAGE_ENABLE)) {
 			hv_vcpu->hv_vapic = data;
 			if (kvm_lapic_enable_pv_eoi(vcpu, 0, 0))
@@ -1428,10 +1432,22 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 		break;
 	}
 	case HV_X64_MSR_EOI:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_APIC_ACCESS_AVAILABLE)))
+			return 1;
+
 		return kvm_hv_vapic_msr_write(vcpu, APIC_EOI, data);
 	case HV_X64_MSR_ICR:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_APIC_ACCESS_AVAILABLE)))
+			return 1;
+
 		return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
 	case HV_X64_MSR_TPR:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_APIC_ACCESS_AVAILABLE)))
+			return 1;
+
 		return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
 	case HV_X64_MSR_VP_RUNTIME:
 		if (!host)
@@ -1564,12 +1580,28 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 		data = hv_vcpu->vp_index;
 		break;
 	case HV_X64_MSR_EOI:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_APIC_ACCESS_AVAILABLE)))
+			return 1;
+
 		return kvm_hv_vapic_msr_read(vcpu, APIC_EOI, pdata);
 	case HV_X64_MSR_ICR:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_APIC_ACCESS_AVAILABLE)))
+			return 1;
+
 		return kvm_hv_vapic_msr_read(vcpu, APIC_ICR, pdata);
 	case HV_X64_MSR_TPR:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_APIC_ACCESS_AVAILABLE)))
+			return 1;
+
 		return kvm_hv_vapic_msr_read(vcpu, APIC_TASKPRI, pdata);
 	case HV_X64_MSR_VP_ASSIST_PAGE:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_MSR_APIC_ACCESS_AVAILABLE)))
+			return 1;
+
 		data = hv_vcpu->hv_vapic;
 		break;
 	case HV_X64_MSR_VP_RUNTIME:
-- 
2.30.2


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

* [PATCH RFC 12/22] KVM: x86: hyper-v: Honor HV_ACCESS_FREQUENCY_MSRS privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (10 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 11/22] KVM: x86: hyper-v: Honor HV_MSR_APIC_ACCESS_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 13/22] KVM: x86: hyper-v: Honor HV_ACCESS_REENLIGHTENMENT " Vitaly Kuznetsov
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_TSC_FREQUENCY/HV_X64_MSR_APIC_FREQUENCY are only available to
guest when HV_ACCESS_FREQUENCY_MSRS bit is exposed.

Note, writing to HV_X64_MSR_TSC_FREQUENCY/HV_X64_MSR_APIC_FREQUENCY is
unsupported so kvm_hv_set_msr() doesn't need an additional check.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 9c4454873e00..e92a1109ad9b 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1637,9 +1637,17 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 					pdata, host);
 	}
 	case HV_X64_MSR_TSC_FREQUENCY:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_ACCESS_FREQUENCY_MSRS)))
+			return 1;
+
 		data = (u64)vcpu->arch.virtual_tsc_khz * 1000;
 		break;
 	case HV_X64_MSR_APIC_FREQUENCY:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_ACCESS_FREQUENCY_MSRS)))
+			return 1;
+
 		data = APIC_BUS_FREQUENCY;
 		break;
 	default:
-- 
2.30.2


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

* [PATCH RFC 13/22] KVM: x86: hyper-v: Honor HV_ACCESS_REENLIGHTENMENT privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (11 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 12/22] KVM: x86: hyper-v: Honor HV_ACCESS_FREQUENCY_MSRS " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 14/22] KVM: x86: hyper-v: Honor HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE " Vitaly Kuznetsov
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_REENLIGHTENMENT_CONTROL/HV_X64_MSR_TSC_EMULATION_CONTROL/
HV_X64_MSR_TSC_EMULATION_STATUS are only available to guest when
HV_ACCESS_REENLIGHTENMENT bit is exposed.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index e92a1109ad9b..259badd3a139 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1330,13 +1330,22 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
 		}
 		break;
 	case HV_X64_MSR_REENLIGHTENMENT_CONTROL:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_ACCESS_REENLIGHTENMENT)))
+			return 1;
+
 		hv->hv_reenlightenment_control = data;
 		break;
 	case HV_X64_MSR_TSC_EMULATION_CONTROL:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_ACCESS_REENLIGHTENMENT)))
+			return 1;
+
 		hv->hv_tsc_emulation_control = data;
 		break;
 	case HV_X64_MSR_TSC_EMULATION_STATUS:
-		if (data && !host)
+		if (unlikely(!host && (!(hv_vcpu->cpuid_cache.features_eax &
+					HV_ACCESS_REENLIGHTENMENT) || data)))
 			return 1;
 
 		hv->hv_tsc_emulation_status = data;
@@ -1545,12 +1554,24 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata,
 		data = 0;
 		break;
 	case HV_X64_MSR_REENLIGHTENMENT_CONTROL:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_ACCESS_REENLIGHTENMENT)))
+			return 1;
+
 		data = hv->hv_reenlightenment_control;
 		break;
 	case HV_X64_MSR_TSC_EMULATION_CONTROL:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_ACCESS_REENLIGHTENMENT)))
+			return 1;
+
 		data = hv->hv_tsc_emulation_control;
 		break;
 	case HV_X64_MSR_TSC_EMULATION_STATUS:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
+					HV_ACCESS_REENLIGHTENMENT)))
+			return 1;
+
 		data = hv->hv_tsc_emulation_status;
 		break;
 	case HV_X64_MSR_SYNDBG_OPTIONS:
-- 
2.30.2


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

* [PATCH RFC 14/22] KVM: x86: hyper-v: Honor HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (12 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 13/22] KVM: x86: hyper-v: Honor HV_ACCESS_REENLIGHTENMENT " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 15/22] " Vitaly Kuznetsov
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4, HV_X64_MSR_CRASH_CTL are only
available to guest when HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE bit is
exposed.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 259badd3a139..0678f1012ed7 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1300,10 +1300,18 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
 		}
 		break;
 	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_edx &
+					HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)))
+			return 1;
+
 		return kvm_hv_msr_set_crash_data(kvm,
 						 msr - HV_X64_MSR_CRASH_P0,
 						 data);
 	case HV_X64_MSR_CRASH_CTL:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_edx &
+					HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)))
+			return 1;
+
 		if (host)
 			return kvm_hv_msr_set_crash_ctl(kvm, data);
 
@@ -1541,10 +1549,18 @@ 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:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_edx &
+					HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)))
+			return 1;
+
 		return kvm_hv_msr_get_crash_data(kvm,
 						 msr - HV_X64_MSR_CRASH_P0,
 						 pdata);
 	case HV_X64_MSR_CRASH_CTL:
+		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_edx &
+					HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)))
+			return 1;
+
 		return kvm_hv_msr_get_crash_ctl(kvm, pdata);
 	case HV_X64_MSR_RESET:
 		if (unlikely(!host && !(hv_vcpu->cpuid_cache.features_eax &
-- 
2.30.2


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

* [PATCH RFC 15/22] KVM: x86: hyper-v: Honor HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (13 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 14/22] KVM: x86: hyper-v: Honor HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 16/22] KVM: x86: hyper-v: Honor HV_STIMER_DIRECT_MODE_AVAILABLE " Vitaly Kuznetsov
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Synthetic debugging MSRs (HV_X64_MSR_SYNDBG_CONTROL,
HV_X64_MSR_SYNDBG_STATUS, HV_X64_MSR_SYNDBG_SEND_BUFFER,
HV_X64_MSR_SYNDBG_RECV_BUFFER, HV_X64_MSR_SYNDBG_PENDING_BUFFER,
HV_X64_MSR_SYNDBG_OPTIONS) are only available to guest when
HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE bit is exposed.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 0678f1012ed7..1299847c89ba 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -312,7 +312,9 @@ static int syndbg_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 {
 	struct kvm_hv_syndbg *syndbg = to_hv_syndbg(vcpu);
 
-	if (!kvm_hv_is_syndbg_enabled(vcpu) && !host)
+	if (unlikely(!host && (!kvm_hv_is_syndbg_enabled(vcpu) ||
+			       !(to_hv_vcpu(vcpu)->cpuid_cache.features_edx &
+				 HV_FEATURE_DEBUG_MSRS_AVAILABLE))))
 		return 1;
 
 	trace_kvm_hv_syndbg_set_msr(vcpu->vcpu_id,
@@ -351,7 +353,9 @@ static int syndbg_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host)
 {
 	struct kvm_hv_syndbg *syndbg = to_hv_syndbg(vcpu);
 
-	if (!kvm_hv_is_syndbg_enabled(vcpu) && !host)
+	if (unlikely(!host && (!kvm_hv_is_syndbg_enabled(vcpu) ||
+			       !(to_hv_vcpu(vcpu)->cpuid_cache.features_edx &
+				 HV_FEATURE_DEBUG_MSRS_AVAILABLE))))
 		return 1;
 
 	switch (msr) {
-- 
2.30.2


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

* [PATCH RFC 16/22] KVM: x86: hyper-v: Honor HV_STIMER_DIRECT_MODE_AVAILABLE privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (14 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 15/22] " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 17/22] KVM: x86: hyper-v: Honor HV_POST_MESSAGES " Vitaly Kuznetsov
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Synthetic timers can only be configured in 'direct' mode when
HV_STIMER_DIRECT_MODE_AVAILABLE bit was exposed.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 1299847c89ba..0df18187d908 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -646,6 +646,11 @@ static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
 				 HV_MSR_SYNTIMER_AVAILABLE))))
 		return 1;
 
+	if (unlikely(!host && new_config.direct_mode &&
+		     !(to_hv_vcpu(vcpu)->cpuid_cache.features_edx &
+		       HV_STIMER_DIRECT_MODE_AVAILABLE)))
+		return 1;
+
 	trace_kvm_hv_stimer_set_config(hv_stimer_to_vcpu(stimer)->vcpu_id,
 				       stimer->index, config, host);
 
-- 
2.30.2


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

* [PATCH RFC 17/22] KVM: x86: hyper-v: Honor HV_POST_MESSAGES privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (15 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 16/22] KVM: x86: hyper-v: Honor HV_STIMER_DIRECT_MODE_AVAILABLE " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 18/22] KVM: x86: hyper-v: Honor HV_SIGNAL_EVENTS " Vitaly Kuznetsov
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Hyper-V partition must possess 'HV_POST_MESSAGES' privilege to issue
HVCALL_POST_MESSAGE hypercalls.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/hyperv.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 0df18187d908..6e4bf1da9dcf 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -2073,12 +2073,16 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 	u64 param, ingpa, outgpa, ret = HV_STATUS_SUCCESS;
 	uint16_t code, rep_idx, rep_cnt;
 	bool fast, rep;
+	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
 
 	/*
 	 * hypercall generates UD from non zero cpl and real mode
-	 * per HYPER-V spec
+	 * per HYPER-V spec. Fail the call when 'hv_vcpu' context
+	 * was not allocated (e.g. per-vCPU Hyper-V CPUID entries
+	 * are unset) as well.
 	 */
-	if (static_call(kvm_x86_get_cpl)(vcpu) != 0 || !is_protmode(vcpu)) {
+	if (static_call(kvm_x86_get_cpl)(vcpu) != 0 || !is_protmode(vcpu) ||
+	    !hv_vcpu) {
 		kvm_queue_exception(vcpu, UD_VECTOR);
 		return 1;
 	}
@@ -2125,6 +2129,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 			break;
 		fallthrough;	/* maybe userspace knows this conn_id */
 	case HVCALL_POST_MESSAGE:
+		if (unlikely(!(hv_vcpu->cpuid_cache.features_ebx &
+			       HV_POST_MESSAGES))) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		/* don't bother userspace if it has no way to handle it */
 		if (unlikely(rep || !to_hv_synic(vcpu)->active)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
-- 
2.30.2


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

* [PATCH RFC 18/22] KVM: x86: hyper-v: Honor HV_SIGNAL_EVENTS privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (16 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 17/22] KVM: x86: hyper-v: Honor HV_POST_MESSAGES " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 19/22] KVM: x86: hyper-v: Honor HV_DEBUGGING " Vitaly Kuznetsov
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Hyper-V partition must possess 'HV_SIGNAL_EVENTS' privilege to issue
HVCALL_SIGNAL_EVENT hypercalls.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 6e4bf1da9dcf..b661f92d90c8 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -2120,6 +2120,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 		kvm_vcpu_on_spin(vcpu, true);
 		break;
 	case HVCALL_SIGNAL_EVENT:
+		if (unlikely(!(hv_vcpu->cpuid_cache.features_ebx &
+			       HV_SIGNAL_EVENTS))) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		if (unlikely(rep)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
 			break;
-- 
2.30.2


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

* [PATCH RFC 19/22] KVM: x86: hyper-v: Honor HV_DEBUGGING privilege bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (17 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 18/22] KVM: x86: hyper-v: Honor HV_SIGNAL_EVENTS " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 20/22] KVM: x86: hyper-v: Honor HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED bit Vitaly Kuznetsov
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Hyper-V partition must possess 'HV_DEBUGGING' privilege to issue
HVCALL_POST_DEBUG_DATA/HVCALL_RETRIEVE_DEBUG_DATA/
HVCALL_RESET_DEBUG_SESSION hypercalls.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index b661f92d90c8..7cb1dd1a9fc1 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -2211,6 +2211,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 			break;
 		}
 
+		if (unlikely(!(hv_vcpu->cpuid_cache.features_ebx &
+			       HV_DEBUGGING))) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		if (!(syndbg->options & HV_X64_SYNDBG_OPTION_USE_HCALLS)) {
 			ret = HV_STATUS_OPERATION_DENIED;
 			break;
-- 
2.30.2


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

* [PATCH RFC 20/22] KVM: x86: hyper-v: Honor HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (18 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 19/22] KVM: x86: hyper-v: Honor HV_DEBUGGING " Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 21/22] KVM: x86: hyper-v: Honor HV_X64_CLUSTER_IPI_RECOMMENDED bit Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 22/22] KVM: x86: hyper-v: Check access to HVCALL_NOTIFY_LONG_SPIN_WAIT hypercall Vitaly Kuznetsov
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Hyper-V partition must possess 'HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED'
privilege ('recommended' is rather a misnomer) to issue
HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST/SPACE hypercalls. '_EX' versions of these
hypercalls also require HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 7cb1dd1a9fc1..3e8a34c08aef 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -2155,6 +2155,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 				kvm_hv_hypercall_complete_userspace;
 		return 0;
 	case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
+		if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+			       HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		if (unlikely(fast || !rep_cnt || rep_idx)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
 			break;
@@ -2162,6 +2168,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 		ret = kvm_hv_flush_tlb(vcpu, ingpa, rep_cnt, false);
 		break;
 	case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
+		if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+			       HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		if (unlikely(fast || rep)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
 			break;
@@ -2169,6 +2181,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 		ret = kvm_hv_flush_tlb(vcpu, ingpa, rep_cnt, false);
 		break;
 	case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
+		if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+			       HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED) ||
+			     !(hv_vcpu->cpuid_cache.enlightenments_eax &
+			       HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		if (unlikely(fast || !rep_cnt || rep_idx)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
 			break;
@@ -2176,6 +2196,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 		ret = kvm_hv_flush_tlb(vcpu, ingpa, rep_cnt, true);
 		break;
 	case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX:
+		if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+			       HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED) ||
+			     !(hv_vcpu->cpuid_cache.enlightenments_eax &
+			       HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		if (unlikely(fast || rep)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
 			break;
-- 
2.30.2


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

* [PATCH RFC 21/22] KVM: x86: hyper-v: Honor HV_X64_CLUSTER_IPI_RECOMMENDED bit
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (19 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 20/22] KVM: x86: hyper-v: Honor HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED bit Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  2021-04-13 12:26 ` [PATCH RFC 22/22] KVM: x86: hyper-v: Check access to HVCALL_NOTIFY_LONG_SPIN_WAIT hypercall Vitaly Kuznetsov
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

Hyper-V partition must possess 'HV_X64_CLUSTER_IPI_RECOMMENDED'
privilege ('recommended' is rather a misnomer) to issue
HVCALL_SEND_IPI hypercalls. 'HVCALL_SEND_IPI_EX' version of the
hypercall also requires HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED.

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 3e8a34c08aef..37b8ff30fc1d 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -2211,6 +2211,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 		ret = kvm_hv_flush_tlb(vcpu, ingpa, rep_cnt, true);
 		break;
 	case HVCALL_SEND_IPI:
+		if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+			       HV_X64_CLUSTER_IPI_RECOMMENDED))) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		if (unlikely(rep)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
 			break;
@@ -2218,6 +2224,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 		ret = kvm_hv_send_ipi(vcpu, ingpa, outgpa, false, fast);
 		break;
 	case HVCALL_SEND_IPI_EX:
+		if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+			       HV_X64_CLUSTER_IPI_RECOMMENDED) ||
+			     !(hv_vcpu->cpuid_cache.enlightenments_eax &
+			       HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		if (unlikely(fast || rep)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
 			break;
-- 
2.30.2


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

* [PATCH RFC 22/22] KVM: x86: hyper-v: Check access to HVCALL_NOTIFY_LONG_SPIN_WAIT hypercall
  2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
                   ` (20 preceding siblings ...)
  2021-04-13 12:26 ` [PATCH RFC 21/22] KVM: x86: hyper-v: Honor HV_X64_CLUSTER_IPI_RECOMMENDED bit Vitaly Kuznetsov
@ 2021-04-13 12:26 ` Vitaly Kuznetsov
  21 siblings, 0 replies; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-13 12:26 UTC (permalink / raw)
  To: kvm, Paolo Bonzini
  Cc: Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv

TLFS6.0b states that partition issuing HVCALL_NOTIFY_LONG_SPIN_WAIT must
posess 'UseHypercallForLongSpinWait' privilege but there's no
corresponding feature bit. Instead, we have "Recommended number of attempts
to retry a spinlock failure before notifying the hypervisor about the
failures. 0xFFFFFFFF indicates never notify." Use this to check access to
the hypercall. Also, check against zero as the corresponding CPUID must
be set (and '0' attempts before re-try is weird anyway).

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

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 37b8ff30fc1d..325446833bbe 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -2113,6 +2113,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
 
 	switch (code) {
 	case HVCALL_NOTIFY_LONG_SPIN_WAIT:
+		if (unlikely(!hv_vcpu->cpuid_cache.enlightenments_ebx ||
+			     hv_vcpu->cpuid_cache.enlightenments_ebx == U32_MAX)) {
+			ret = HV_STATUS_ACCESS_DENIED;
+			break;
+		}
+
 		if (unlikely(rep)) {
 			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
 			break;
-- 
2.30.2


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

* Re: [PATCH RFC 01/22] asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition
  2021-04-13 12:26 ` [PATCH RFC 01/22] asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition Vitaly Kuznetsov
@ 2021-04-15 14:14   ` Wei Liu
  2021-04-15 15:33     ` Vitaly Kuznetsov
  0 siblings, 1 reply; 26+ messages in thread
From: Wei Liu @ 2021-04-15 14:14 UTC (permalink / raw)
  To: Vitaly Kuznetsov
  Cc: kvm, Paolo Bonzini, Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv, Wei Liu

On Tue, Apr 13, 2021 at 02:26:09PM +0200, Vitaly Kuznetsov wrote:
> From TLFSv6.0b, this status means: "The caller did not possess sufficient
> access rights to perform the requested operation."
> 
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>

This can be applied to hyperv-next right away. Let me know what you
think.

Wei.

> ---
>  include/asm-generic/hyperv-tlfs.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
> index 83448e837ded..e01a3bade13a 100644
> --- a/include/asm-generic/hyperv-tlfs.h
> +++ b/include/asm-generic/hyperv-tlfs.h
> @@ -187,6 +187,7 @@ enum HV_GENERIC_SET_FORMAT {
>  #define HV_STATUS_INVALID_HYPERCALL_INPUT	3
>  #define HV_STATUS_INVALID_ALIGNMENT		4
>  #define HV_STATUS_INVALID_PARAMETER		5
> +#define HV_STATUS_ACCESS_DENIED			6
>  #define HV_STATUS_OPERATION_DENIED		8
>  #define HV_STATUS_INSUFFICIENT_MEMORY		11
>  #define HV_STATUS_INVALID_PORT_ID		17
> -- 
> 2.30.2
> 

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

* Re: [PATCH RFC 01/22] asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition
  2021-04-15 14:14   ` Wei Liu
@ 2021-04-15 15:33     ` Vitaly Kuznetsov
  2021-04-16 10:31       ` Wei Liu
  0 siblings, 1 reply; 26+ messages in thread
From: Vitaly Kuznetsov @ 2021-04-15 15:33 UTC (permalink / raw)
  To: Wei Liu
  Cc: kvm, Paolo Bonzini, Sean Christopherson, Wanpeng Li, Jim Mattson,
	Siddharth Chandrasekaran, linux-kernel, linux-hyperv, Wei Liu

Wei Liu <wei.liu@kernel.org> writes:

> On Tue, Apr 13, 2021 at 02:26:09PM +0200, Vitaly Kuznetsov wrote:
>> From TLFSv6.0b, this status means: "The caller did not possess sufficient
>> access rights to perform the requested operation."
>> 
>> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
>
> This can be applied to hyperv-next right away. Let me know what you
> think.
>

In case there's no immediate need for this constant outside of KVM, I'd
suggest you just give Paolo your 'Acked-by' so I can carry the patch in
the series for the time being. This will eliminate the need to track
dependencies between hyperv-next and kvm-next.

Thanks!

-- 
Vitaly


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

* Re: [PATCH RFC 01/22] asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition
  2021-04-15 15:33     ` Vitaly Kuznetsov
@ 2021-04-16 10:31       ` Wei Liu
  0 siblings, 0 replies; 26+ messages in thread
From: Wei Liu @ 2021-04-16 10:31 UTC (permalink / raw)
  To: Vitaly Kuznetsov
  Cc: Wei Liu, kvm, Paolo Bonzini, Sean Christopherson, Wanpeng Li,
	Jim Mattson, Siddharth Chandrasekaran, linux-kernel,
	linux-hyperv

On Thu, Apr 15, 2021 at 05:33:17PM +0200, Vitaly Kuznetsov wrote:
> Wei Liu <wei.liu@kernel.org> writes:
> 
> > On Tue, Apr 13, 2021 at 02:26:09PM +0200, Vitaly Kuznetsov wrote:
> >> From TLFSv6.0b, this status means: "The caller did not possess sufficient
> >> access rights to perform the requested operation."
> >> 
> >> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> >
> > This can be applied to hyperv-next right away. Let me know what you
> > think.
> >
> 
> In case there's no immediate need for this constant outside of KVM, I'd
> suggest you just give Paolo your 'Acked-by' so I can carry the patch in
> the series for the time being. This will eliminate the need to track
> dependencies between hyperv-next and kvm-next.

Acked-by: Wei Liu <wei.liu@kernel.org>

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

end of thread, back to index

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-13 12:26 [PATCH RFC 00/22] KVM: x86: hyper-v: Fine-grained access check to Hyper-V hypercalls and MSRs Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 01/22] asm-generic/hyperv: add HV_STATUS_ACCESS_DENIED definition Vitaly Kuznetsov
2021-04-15 14:14   ` Wei Liu
2021-04-15 15:33     ` Vitaly Kuznetsov
2021-04-16 10:31       ` Wei Liu
2021-04-13 12:26 ` [PATCH RFC 02/22] KVM: x86: hyper-v: Cache guest CPUID leaves determining features availability Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 03/22] KVM: x86: hyper-v: Honor HV_MSR_VP_RUNTIME_AVAILABLE privilege bit Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 04/22] KVM: x86: hyper-v: Honor HV_MSR_TIME_REF_COUNT_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 05/22] KVM: x86: hyper-v: Honor HV_MSR_HYPERCALL_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 06/22] KVM: x86: hyper-v: Honor HV_MSR_VP_INDEX_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 07/22] KVM: x86: hyper-v: Honor HV_MSR_RESET_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 08/22] KVM: x86: hyper-v: Honor HV_MSR_REFERENCE_TSC_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 09/22] KVM: x86: hyper-v: Honor HV_MSR_SYNIC_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 10/22] KVM: x86: hyper-v: Honor HV_MSR_SYNTIMER_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 11/22] KVM: x86: hyper-v: Honor HV_MSR_APIC_ACCESS_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 12/22] KVM: x86: hyper-v: Honor HV_ACCESS_FREQUENCY_MSRS " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 13/22] KVM: x86: hyper-v: Honor HV_ACCESS_REENLIGHTENMENT " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 14/22] KVM: x86: hyper-v: Honor HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 15/22] " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 16/22] KVM: x86: hyper-v: Honor HV_STIMER_DIRECT_MODE_AVAILABLE " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 17/22] KVM: x86: hyper-v: Honor HV_POST_MESSAGES " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 18/22] KVM: x86: hyper-v: Honor HV_SIGNAL_EVENTS " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 19/22] KVM: x86: hyper-v: Honor HV_DEBUGGING " Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 20/22] KVM: x86: hyper-v: Honor HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED bit Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 21/22] KVM: x86: hyper-v: Honor HV_X64_CLUSTER_IPI_RECOMMENDED bit Vitaly Kuznetsov
2021-04-13 12:26 ` [PATCH RFC 22/22] KVM: x86: hyper-v: Check access to HVCALL_NOTIFY_LONG_SPIN_WAIT hypercall Vitaly Kuznetsov

Linux-HyperV Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-hyperv/0 linux-hyperv/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-hyperv linux-hyperv/ https://lore.kernel.org/linux-hyperv \
		linux-hyperv@vger.kernel.org
	public-inbox-index linux-hyperv

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-hyperv


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git