return X86EMUL_EXCEPTION;
}
+uint64_t hvm_get_reg(struct vcpu *v, unsigned int reg)
+{
+ ASSERT(v == current || !vcpu_runnable(v));
+
+ switch ( reg )
+ {
+ default:
+ return alternative_call(hvm_funcs.get_reg, v, reg);
+ }
+}
+
+void hvm_set_reg(struct vcpu *v, unsigned int reg, uint64_t val)
+{
+ ASSERT(v == current || !vcpu_runnable(v));
+
+ switch ( reg )
+ {
+ default:
+ return alternative_vcall(hvm_funcs.set_reg, v, reg, val);
+ }
+}
+
static bool is_sysdesc_access(const struct x86_emulate_state *state,
const struct x86_emulate_ctxt *ctxt)
{
return true;
}
+static uint64_t svm_get_reg(struct vcpu *v, unsigned int reg)
+{
+ struct domain *d = v->domain;
+
+ switch ( reg )
+ {
+ default:
+ printk(XENLOG_G_ERR "%s(%pv, 0x%08x) Bad register\n",
+ __func__, v, reg);
+ domain_crash(d);
+ return 0;
+ }
+}
+
+static void svm_set_reg(struct vcpu *v, unsigned int reg, uint64_t val)
+{
+ struct domain *d = v->domain;
+
+ switch ( reg )
+ {
+ default:
+ printk(XENLOG_G_ERR "%s(%pv, 0x%08x, 0x%016"PRIx64") Bad register\n",
+ __func__, v, reg, val);
+ domain_crash(d);
+ }
+}
+
static struct hvm_function_table __initdata svm_function_table = {
.name = "SVM",
.cpu_up_prepare = svm_cpu_up_prepare,
.nhvm_intr_blocked = nsvm_intr_blocked,
.nhvm_hap_walk_L1_p2m = nsvm_hap_walk_L1_p2m,
+ .get_reg = svm_get_reg,
+ .set_reg = svm_set_reg,
+
.tsc_scaling = {
.max_ratio = ~TSC_RATIO_RSVD_BITS,
},
return 0;
}
+static uint64_t vmx_get_reg(struct vcpu *v, unsigned int reg)
+{
+ struct domain *d = v->domain;
+
+ switch ( reg )
+ {
+ default:
+ printk(XENLOG_G_ERR "%s(%pv, 0x%08x) Bad register\n",
+ __func__, v, reg);
+ domain_crash(d);
+ return 0;
+ }
+}
+
+static void vmx_set_reg(struct vcpu *v, unsigned int reg, uint64_t val)
+{
+ struct domain *d = v->domain;
+
+ switch ( reg )
+ {
+ default:
+ printk(XENLOG_G_ERR "%s(%pv, 0x%08x, 0x%016"PRIx64") Bad register\n",
+ __func__, v, reg, val);
+ domain_crash(d);
+ }
+}
+
static struct hvm_function_table __initdata vmx_function_table = {
.name = "VMX",
.cpu_up_prepare = vmx_cpu_up_prepare,
.vmtrace_set_option = vmtrace_set_option,
.vmtrace_get_option = vmtrace_get_option,
.vmtrace_reset = vmtrace_reset,
+
+ .get_reg = vmx_get_reg,
+ .set_reg = vmx_set_reg,
+
.tsc_scaling = {
.max_ratio = VMX_TSC_MULTIPLIER_MAX,
},
}
}
+uint64_t pv_get_reg(struct vcpu *v, unsigned int reg)
+{
+ struct domain *d = v->domain;
+
+ ASSERT(v == current || !vcpu_runnable(v));
+
+ switch ( reg )
+ {
+ default:
+ printk(XENLOG_G_ERR "%s(%pv, 0x%08x) Bad register\n",
+ __func__, v, reg);
+ domain_crash(d);
+ return 0;
+ }
+}
+
+void pv_set_reg(struct vcpu *v, unsigned int reg, uint64_t val)
+{
+ struct domain *d = v->domain;
+
+ ASSERT(v == current || !vcpu_runnable(v));
+
+ switch ( reg )
+ {
+ default:
+ printk(XENLOG_G_ERR "%s(%pv, 0x%08x, 0x%016"PRIx64") Bad register\n",
+ __func__, v, reg, val);
+ domain_crash(d);
+ }
+}
+
/*
* Local variables:
* mode: C
int (*vmtrace_get_option)(struct vcpu *v, uint64_t key, uint64_t *value);
int (*vmtrace_reset)(struct vcpu *v);
+ uint64_t (*get_reg)(struct vcpu *v, unsigned int reg);
+ void (*set_reg)(struct vcpu *v, unsigned int reg, uint64_t val);
+
/*
* Parameters and callbacks for hardware-assisted TSC scaling,
* which are valid only when the hardware feature is available.
return -EOPNOTSUPP;
}
+/*
+ * Accessors for registers which have per-guest-type or per-vendor locations
+ * (e.g. VMCS, msr load/save lists, VMCB, VMLOAD lazy, etc).
+ *
+ * The caller is responsible for all auditing - these accessors do not fail,
+ * but do use domain_crash() for usage errors.
+ *
+ * Must cope with being called in non-current context.
+ */
+uint64_t hvm_get_reg(struct vcpu *v, unsigned int reg);
+void hvm_set_reg(struct vcpu *v, unsigned int reg, uint64_t val);
+
/*
* This must be defined as a macro instead of an inline function,
* because it uses 'struct vcpu' and 'struct domain' which have
#endif
}
+/* See hvm_{get,set}_reg() for description. */
+uint64_t pv_get_reg(struct vcpu *v, unsigned int reg);
+void pv_set_reg(struct vcpu *v, unsigned int reg, uint64_t val);
+
#ifdef CONFIG_PV
void pv_vcpu_destroy(struct vcpu *v);