#define X86_CR0_PE 0x01
#define X86_CR0_ET 0x10
+#define MTRR_TYPE_WRBACK 6
+#define MTRR_DEF_TYPE_ENABLE (1u << 11)
+
#define SPECIALPAGE_PAGING 0
#define SPECIALPAGE_ACCESS 1
#define SPECIALPAGE_SHARING 2
return rc;
}
+const static void *hvm_get_save_record(const void *ctx, unsigned int type,
+ unsigned int instance)
+{
+ const struct hvm_save_descriptor *header;
+
+ for ( header = ctx;
+ header->typecode != HVM_SAVE_CODE(END);
+ ctx += sizeof(*header) + header->length, header = ctx )
+ if ( header->typecode == type && header->instance == instance )
+ return ctx + sizeof(*header);
+
+ return NULL;
+}
+
static int vcpu_hvm(struct xc_dom_image *dom)
{
struct {
HVM_SAVE_TYPE(HEADER) header;
struct hvm_save_descriptor cpu_d;
HVM_SAVE_TYPE(CPU) cpu;
+ struct hvm_save_descriptor mtrr_d;
+ HVM_SAVE_TYPE(MTRR) mtrr;
struct hvm_save_descriptor end_d;
HVM_SAVE_TYPE(END) end;
} bsp_ctx;
+ const HVM_SAVE_TYPE(MTRR) *mtrr_record;
uint8_t *full_ctx = NULL;
int rc;
if ( dom->start_info_seg.pfn )
bsp_ctx.cpu.rbx = dom->start_info_seg.pfn << PAGE_SHIFT;
+ /* Set the MTRR. */
+ bsp_ctx.mtrr_d.typecode = HVM_SAVE_CODE(MTRR);
+ bsp_ctx.mtrr_d.instance = 0;
+ bsp_ctx.mtrr_d.length = HVM_SAVE_LENGTH(MTRR);
+
+ mtrr_record = hvm_get_save_record(full_ctx, HVM_SAVE_CODE(MTRR), 0);
+ if ( !mtrr_record )
+ {
+ xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+ "%s: unable to get MTRR save record", __func__);
+ goto out;
+ }
+
+ memcpy(&bsp_ctx.mtrr, mtrr_record, sizeof(bsp_ctx.mtrr));
+
+ /* TODO: maybe this should be a firmware option instead? */
+ if ( !dom->device_model )
+ /*
+ * Enable MTRR, set default type to WB.
+ * TODO: add MMIO areas as UC when passthrough is supported.
+ */
+ bsp_ctx.mtrr.msr_mtrr_def_type = MTRR_TYPE_WRBACK |
+ MTRR_DEF_TYPE_ENABLE;
+
/* Set the end descriptor. */
bsp_ctx.end_d.typecode = HVM_SAVE_CODE(END);
bsp_ctx.end_d.instance = 0;