diff mbox

[7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers

Message ID 1435664007-4965-8-git-send-email-den@openvz.org
State New
Headers show

Commit Message

Denis V. Lunev June 30, 2015, 11:33 a.m. UTC
From: Andrey Smetanin <asmetanin@virtuozzo.com>

Added hyper-v crash msr's(HV_X64_MSR_CRASH*) data and control
geters and setters.

User space allowed to setup Hyper-V crash ctl msr.
This msr should be setup to HV_X64_MSR_CRASH_CTL_NOTIFY
value so Hyper-V guest knows it can send crash data to host.
But Hyper-V guest notifies about crash event by writing
the same HV_X64_MSR_CRASH_CTL_NOTIFY value into crash ctl msr.
So both user space and guest writes inside ctl msr the same value
and this patch distingiush the moment of actual guest crash
by checking host initiated value from msr info. Also patch
prevents modification of crash ctl msr by guest.

Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Gleb Natapov <gleb@kernel.org>
---
 arch/x86/kvm/hyperv.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++---
 arch/x86/kvm/hyperv.h |  2 +-
 arch/x86/kvm/x86.c    |  7 ++++-
 3 files changed, 78 insertions(+), 5 deletions(-)

Comments

Peter Hornyack July 1, 2015, 12:15 a.m. UTC | #1
On Tue, Jun 30, 2015 at 4:33 AM, Denis V. Lunev <den@openvz.org> wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> Added hyper-v crash msr's(HV_X64_MSR_CRASH*) data and control
> geters and setters.
>
> User space allowed to setup Hyper-V crash ctl msr.
> This msr should be setup to HV_X64_MSR_CRASH_CTL_NOTIFY
> value so Hyper-V guest knows it can send crash data to host.
> But Hyper-V guest notifies about crash event by writing
> the same HV_X64_MSR_CRASH_CTL_NOTIFY value into crash ctl msr.
> So both user space and guest writes inside ctl msr the same value
> and this patch distingiush the moment of actual guest crash
> by checking host initiated value from msr info. Also patch
> prevents modification of crash ctl msr by guest.
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
Reviewed-by: Peter Hornyack <peterhornyack@google.com>

> ---
>  arch/x86/kvm/hyperv.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++---
>  arch/x86/kvm/hyperv.h |  2 +-
>  arch/x86/kvm/x86.c    |  7 ++++-
>  3 files changed, 78 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
> index af83c96..a860165 100644
> --- a/arch/x86/kvm/hyperv.c
> +++ b/arch/x86/kvm/hyperv.c
> @@ -48,7 +48,63 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
>         return r;
>  }
>
> -static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> +static int kvm_hv_msr_get_crash_data(struct kvm_vcpu *vcpu,
> +                                    u32 index, u64 *pdata)
> +{
> +       struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> +       if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
> +               return -EINVAL;
> +
> +       *pdata = hv->hv_crash_param[index];
> +       return 0;
> +}
> +
> +static int kvm_hv_msr_get_crash_ctl(struct kvm_vcpu *vcpu, u64 *pdata)
> +{
> +       struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> +       *pdata = hv->hv_crash_ctl;
> +       return 0;
> +}
> +
> +static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host)
> +{
> +       struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> +       if (host)
> +               hv->hv_crash_ctl = data;
> +
> +       if ((data & HV_X64_MSR_CRASH_CTL_NOTIFY) && !host) {
> +
> +               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);
> +       }
> +
> +       return 0;
> +}
> +
> +static int kvm_hv_msr_set_crash_data(struct kvm_vcpu *vcpu,
> +                                    u32 index, u64 data)
> +{
> +       struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> +       if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
> +               return -EINVAL;
> +
> +       hv->hv_crash_param[index] = data;
> +       return 0;
> +}
> +
> +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;
> @@ -101,6 +157,12 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
>                 mark_page_dirty(kvm, gfn);
>                 break;
>         }
> +       case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
> +               return kvm_hv_msr_set_crash_data(vcpu,
> +                                                msr - HV_X64_MSR_CRASH_P0,
> +                                                data);
> +       case HV_X64_MSR_CRASH_CTL:
> +               return kvm_hv_msr_set_crash_ctl(vcpu, data, host);
>         default:
>                 vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
>                             msr, data);
> @@ -173,6 +235,12 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
>         case HV_X64_MSR_REFERENCE_TSC:
>                 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,
> +                                                msr - HV_X64_MSR_CRASH_P0,
> +                                                pdata);
> +       case HV_X64_MSR_CRASH_CTL:
> +               return kvm_hv_msr_get_crash_ctl(vcpu, pdata);
>         default:
>                 vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
>                 return 1;
> @@ -217,13 +285,13 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
>         return 0;
>  }
>
> -int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> +int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
>  {
>         if (kvm_hv_msr_partition_wide(msr)) {
>                 int r;
>
>                 mutex_lock(&vcpu->kvm->lock);
> -               r = kvm_hv_set_msr_pw(vcpu, msr, data);
> +               r = kvm_hv_set_msr_pw(vcpu, msr, data, host);
>                 mutex_unlock(&vcpu->kvm->lock);
>                 return r;
>         } else
> diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
> index 115c738..c7bce55 100644
> --- a/arch/x86/kvm/hyperv.h
> +++ b/arch/x86/kvm/hyperv.h
> @@ -24,7 +24,7 @@
>  #ifndef __ARCH_X86_KVM_HYPERV_H__
>  #define __ARCH_X86_KVM_HYPERV_H__
>
> -int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
> +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 kvm_hv_hypercall_enabled(struct kvm *kvm);
>  int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 301ee01..47b7507 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2103,7 +2103,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                  */
>                 break;
>         case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
> -               return kvm_hv_set_msr_common(vcpu, msr, data);
> +       case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
> +       case HV_X64_MSR_CRASH_CTL:
> +               return kvm_hv_set_msr_common(vcpu, msr, data,
> +                                            msr_info->host_initiated);
>         case MSR_IA32_BBL_CR_CTL3:
>                 /* Drop writes to this legacy MSR -- see rdmsr
>                  * counterpart for further detail.
> @@ -2304,6 +2307,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                 msr_info->data = 0x20000000;
>                 break;
>         case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
> +       case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
> +       case HV_X64_MSR_CRASH_CTL:
>                 return kvm_hv_get_msr_common(vcpu,
>                                              msr_info->index, &msr_info->data);
>                 break;
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini July 1, 2015, 4:47 p.m. UTC | #2
On 30/06/2015 13:33, Denis V. Lunev wrote:
> +static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host)
> +{
> +	struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> +	if (host)
> +		hv->hv_crash_ctl = data;
> +

You need to check against HV_X64_MSR_CRASH_CTL_CONTENTS here (or
HV_X64_MSR_CRASH_CTL_NOTIFY) here.

Paolo
diff mbox

Patch

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index af83c96..a860165 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -48,7 +48,63 @@  static bool kvm_hv_msr_partition_wide(u32 msr)
 	return r;
 }
 
-static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+static int kvm_hv_msr_get_crash_data(struct kvm_vcpu *vcpu,
+				     u32 index, u64 *pdata)
+{
+	struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+
+	if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
+		return -EINVAL;
+
+	*pdata = hv->hv_crash_param[index];
+	return 0;
+}
+
+static int kvm_hv_msr_get_crash_ctl(struct kvm_vcpu *vcpu, u64 *pdata)
+{
+	struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+
+	*pdata = hv->hv_crash_ctl;
+	return 0;
+}
+
+static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host)
+{
+	struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+
+	if (host)
+		hv->hv_crash_ctl = data;
+
+	if ((data & HV_X64_MSR_CRASH_CTL_NOTIFY) && !host) {
+
+		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);
+	}
+
+	return 0;
+}
+
+static int kvm_hv_msr_set_crash_data(struct kvm_vcpu *vcpu,
+				     u32 index, u64 data)
+{
+	struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+
+	if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
+		return -EINVAL;
+
+	hv->hv_crash_param[index] = data;
+	return 0;
+}
+
+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;
@@ -101,6 +157,12 @@  static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 		mark_page_dirty(kvm, gfn);
 		break;
 	}
+	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
+		return kvm_hv_msr_set_crash_data(vcpu,
+						 msr - HV_X64_MSR_CRASH_P0,
+						 data);
+	case HV_X64_MSR_CRASH_CTL:
+		return kvm_hv_msr_set_crash_ctl(vcpu, data, host);
 	default:
 		vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
 			    msr, data);
@@ -173,6 +235,12 @@  static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	case HV_X64_MSR_REFERENCE_TSC:
 		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,
+						 msr - HV_X64_MSR_CRASH_P0,
+						 pdata);
+	case HV_X64_MSR_CRASH_CTL:
+		return kvm_hv_msr_get_crash_ctl(vcpu, pdata);
 	default:
 		vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
 		return 1;
@@ -217,13 +285,13 @@  static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	return 0;
 }
 
-int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 {
 	if (kvm_hv_msr_partition_wide(msr)) {
 		int r;
 
 		mutex_lock(&vcpu->kvm->lock);
-		r = kvm_hv_set_msr_pw(vcpu, msr, data);
+		r = kvm_hv_set_msr_pw(vcpu, msr, data, host);
 		mutex_unlock(&vcpu->kvm->lock);
 		return r;
 	} else
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 115c738..c7bce55 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -24,7 +24,7 @@ 
 #ifndef __ARCH_X86_KVM_HYPERV_H__
 #define __ARCH_X86_KVM_HYPERV_H__
 
-int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
+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 kvm_hv_hypercall_enabled(struct kvm *kvm);
 int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 301ee01..47b7507 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2103,7 +2103,10 @@  int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		 */
 		break;
 	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
-		return kvm_hv_set_msr_common(vcpu, msr, data);
+	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
+	case HV_X64_MSR_CRASH_CTL:
+		return kvm_hv_set_msr_common(vcpu, msr, data,
+					     msr_info->host_initiated);
 	case MSR_IA32_BBL_CR_CTL3:
 		/* Drop writes to this legacy MSR -- see rdmsr
 		 * counterpart for further detail.
@@ -2304,6 +2307,8 @@  int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		msr_info->data = 0x20000000;
 		break;
 	case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
+	case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
+	case HV_X64_MSR_CRASH_CTL:
 		return kvm_hv_get_msr_common(vcpu,
 					     msr_info->index, &msr_info->data);
 		break;