@@ -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>
@@ -288,6 +288,12 @@
#define LIBXL_HAVE_SCHED_CREDIT2_PARAMS 1
/*
+ * LIBXL_HAVE_VIRIDIAN_CRASH_CTL indicates that the 'crash_ctl' value
+ * is present in the viridian enlightenment enumeration.
+ */
+#define LIBXL_HAVE_VIRIDIAN_CRASH_CTL 1
+
+/*
* libxl ABI compatibility
*
* The only guarantee which libxl makes regarding ABI compatibility
@@ -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,
@@ -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", [
@@ -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",
@@ -26,6 +26,7 @@ struct viridian_vcpu
void *va;
int vector;
} vp_assist;
+ uint64_t crash_param[5];
};
union viridian_guest_os_id
@@ -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