|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 3/3] x86/viridian: implement the crash MSRs
Section 2.4.4 of the Hypervisor Top Level Functional Specification states
that enabling bit 10 in EDX of CPUID leaf 3 advertises to Windows a set
of MSRs into which it can write crash information.
This patch advertises that bit and implements the MSRs such that Xen can
log the information if a Windows guest crashes.
Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Cc: Paul Durrant <paul.durrant@xxxxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
v4:
- Name the union in HV_CRASH_CTL_REG_CONTENTS to keep older gcc happy
v3:
- Use WARNING level message rather than INFO
v2:
- Make MSRs per-vcpu rather than per-domain
- Fix hypervisor stack leak
- Replicate BUILD_BOG_ON()
- Use gprintk() rather than printk()
---
docs/man/xl.cfg.pod.5.in | 10 ++++--
tools/libxl/libxl.h | 6 ++++
tools/libxl/libxl_dom.c | 4 +++
tools/libxl/libxl_types.idl | 1 +
xen/arch/x86/hvm/viridian.c | 69 ++++++++++++++++++++++++++++++++++++++
xen/include/asm-x86/hvm/viridian.h | 1 +
xen/include/public/hvm/params.h | 7 +++-
7 files changed, 95 insertions(+), 3 deletions(-)
diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in
index 52802d5..991960b 100644
--- a/docs/man/xl.cfg.pod.5.in
+++ b/docs/man/xl.cfg.pod.5.in
@@ -1601,11 +1601,17 @@ per-vcpu event channel upcall vectors.
Note that this enlightenment will have no effect if the guest is
using APICv posted interrupts.
+=item B<crash_ctl>
+
+This group incorporates the crash control MSRs. These enlightenments
+allow Windows to write crash information such that it can be logged
+by Xen.
+
=item B<defaults>
This is a special value that enables the default set of groups, which
-is currently the B<base>, B<freq>, B<time_ref_count> and B<apic_assist>
-groups.
+is currently the B<base>, B<freq>, B<time_ref_count>, B<apic_assist>
+and B<crash_ctl> groups.
=item B<all>
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 72ec39d..af45582 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -288,6 +288,12 @@
#define LIBXL_HAVE_SCHED_CREDIT2_PARAMS 1
/*
+ * LIBXL_HAVE_CRASH_CTL indicates that the 'crash_ctl' value
+ * is present in the viridian enlightenment enumeration.
+ */
+#define LIBXL_HAVE_CRASH_CTL 1
+
+/*
* libxl ABI compatibility
*
* The only guarantee which libxl makes regarding ABI compatibility
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index c88b904..cf03ded 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -214,6 +214,7 @@ static int hvm_set_viridian_features(libxl__gc *gc,
uint32_t domid,
libxl_bitmap_set(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_FREQ);
libxl_bitmap_set(&enlightenments,
LIBXL_VIRIDIAN_ENLIGHTENMENT_TIME_REF_COUNT);
libxl_bitmap_set(&enlightenments,
LIBXL_VIRIDIAN_ENLIGHTENMENT_APIC_ASSIST);
+ libxl_bitmap_set(&enlightenments,
LIBXL_VIRIDIAN_ENLIGHTENMENT_CRASH_CTL);
}
libxl_for_each_set_bit(v, info->u.hvm.viridian_enable) {
@@ -259,6 +260,9 @@ static int hvm_set_viridian_features(libxl__gc *gc,
uint32_t domid,
if (libxl_bitmap_test(&enlightenments,
LIBXL_VIRIDIAN_ENLIGHTENMENT_APIC_ASSIST))
mask |= HVMPV_apic_assist;
+ if (libxl_bitmap_test(&enlightenments,
LIBXL_VIRIDIAN_ENLIGHTENMENT_CRASH_CTL))
+ mask |= HVMPV_crash_ctl;
+
if (mask != 0 &&
xc_hvm_param_set(CTX->xch,
domid,
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 2475a4d..69e789a 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -224,6 +224,7 @@ libxl_viridian_enlightenment =
Enumeration("viridian_enlightenment", [
(3, "reference_tsc"),
(4, "hcall_remote_tlb_flush"),
(5, "apic_assist"),
+ (6, "crash_ctl"),
])
libxl_hdtype = Enumeration("hdtype", [
diff --git a/xen/arch/x86/hvm/viridian.c b/xen/arch/x86/hvm/viridian.c
index e18a453..c7a3b60 100644
--- a/xen/arch/x86/hvm/viridian.c
+++ b/xen/arch/x86/hvm/viridian.c
@@ -154,6 +154,19 @@ typedef struct {
uint64_t Reserved8:10;
} HV_PARTITION_PRIVILEGE_MASK;
+typedef union _HV_CRASH_CTL_REG_CONTENTS
+{
+ uint64_t AsUINT64;
+ struct
+ {
+ uint64_t Reserved:63;
+ uint64_t CrashNotify:1;
+ } u;
+} HV_CRASH_CTL_REG_CONTENTS;
+
+/* Viridian CPUID leaf 3, Hypervisor Feature Indication */
+#define CPUID3D_CRASH_MSRS (1 << 10)
+
/* Viridian CPUID leaf 4: Implementation Recommendations. */
#define CPUID4A_HCALL_REMOTE_TLB_FLUSH (1 << 2)
#define CPUID4A_MSR_BASED_APIC (1 << 3)
@@ -246,6 +259,10 @@ void cpuid_viridian_leaves(const struct vcpu *v, uint32_t
leaf,
res->a = u.lo;
res->b = u.hi;
+
+ if ( viridian_feature_mask(d) & HVMPV_crash_ctl )
+ res->d = CPUID3D_CRASH_MSRS;
+
break;
}
@@ -609,6 +626,36 @@ int wrmsr_viridian_regs(uint32_t idx, uint64_t val)
update_reference_tsc(d, 1);
break;
+ case HV_X64_MSR_CRASH_P0:
+ case HV_X64_MSR_CRASH_P1:
+ case HV_X64_MSR_CRASH_P2:
+ case HV_X64_MSR_CRASH_P3:
+ case HV_X64_MSR_CRASH_P4:
+ BUILD_BUG_ON(HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0 >=
+ ARRAY_SIZE(v->arch.hvm_vcpu.viridian.crash_param));
+
+ idx -= HV_X64_MSR_CRASH_P0;
+ v->arch.hvm_vcpu.viridian.crash_param[idx] = val;
+ break;
+
+ case HV_X64_MSR_CRASH_CTL:
+ {
+ HV_CRASH_CTL_REG_CONTENTS ctl;
+
+ ctl.AsUINT64 = val;
+
+ if ( !ctl.u.CrashNotify )
+ break;
+
+ gprintk(XENLOG_WARNING, "VIRIDIAN CRASH: %lx %lx %lx %lx %lx\n",
+ v->arch.hvm_vcpu.viridian.crash_param[0],
+ v->arch.hvm_vcpu.viridian.crash_param[1],
+ v->arch.hvm_vcpu.viridian.crash_param[2],
+ v->arch.hvm_vcpu.viridian.crash_param[3],
+ v->arch.hvm_vcpu.viridian.crash_param[4]);
+ break;
+ }
+
default:
if ( idx >= VIRIDIAN_MSR_MIN && idx <= VIRIDIAN_MSR_MAX )
gprintk(XENLOG_WARNING, "write to unimplemented MSR %#x\n",
@@ -736,6 +783,28 @@ int rdmsr_viridian_regs(uint32_t idx, uint64_t *val)
break;
}
+ case HV_X64_MSR_CRASH_P0:
+ case HV_X64_MSR_CRASH_P1:
+ case HV_X64_MSR_CRASH_P2:
+ case HV_X64_MSR_CRASH_P3:
+ case HV_X64_MSR_CRASH_P4:
+ BUILD_BUG_ON(HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0 >=
+ ARRAY_SIZE(v->arch.hvm_vcpu.viridian.crash_param));
+
+ idx -= HV_X64_MSR_CRASH_P0;
+ *val = v->arch.hvm_vcpu.viridian.crash_param[idx];
+ break;
+
+ case HV_X64_MSR_CRASH_CTL:
+ {
+ HV_CRASH_CTL_REG_CONTENTS ctl = {
+ .u.CrashNotify = 1,
+ };
+
+ *val = ctl.AsUINT64;
+ break;
+ }
+
default:
if ( idx >= VIRIDIAN_MSR_MIN && idx <= VIRIDIAN_MSR_MAX )
gprintk(XENLOG_WARNING, "read from unimplemented MSR %#x\n",
diff --git a/xen/include/asm-x86/hvm/viridian.h
b/xen/include/asm-x86/hvm/viridian.h
index 271c36d..30259e9 100644
--- a/xen/include/asm-x86/hvm/viridian.h
+++ b/xen/include/asm-x86/hvm/viridian.h
@@ -26,6 +26,7 @@ struct viridian_vcpu
void *va;
int vector;
} vp_assist;
+ uint64_t crash_param[5];
};
union viridian_guest_os_id
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index 58c8478..19c9eb8 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -135,13 +135,18 @@
#define _HVMPV_apic_assist 5
#define HVMPV_apic_assist (1 << _HVMPV_apic_assist)
+/* Enable crash MSRs */
+#define _HVMPV_crash_ctl 6
+#define HVMPV_crash_ctl (1 << _HVMPV_crash_ctl)
+
#define HVMPV_feature_mask \
(HVMPV_base_freq | \
HVMPV_no_freq | \
HVMPV_time_ref_count | \
HVMPV_reference_tsc | \
HVMPV_hcall_remote_tlb_flush | \
- HVMPV_apic_assist)
+ HVMPV_apic_assist | \
+ HVMPV_crash_ctl)
#endif
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |