With us incremementally adding proper CPUID checks to x86_emulate()
(see commit
de05bd965a ["x86emul: correct {,F}CMOV and F{,U}COMI{,P}
emulation"]) it is no longer appropriate to invoke the function with
that hook being NULL, as long as respective instructions may get used
in that case.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Release-acked-by: Wei Liu <wei.liu2@citrix.com>
return X86EMUL_OKAY;
}
-static int hvmemul_cpuid(
+int hvmemul_cpuid(
unsigned int *eax,
unsigned int *ebx,
unsigned int *ecx,
.read = x86emul_unhandleable_rw,
.insn_fetch = hvmemul_insn_fetch,
.write = mmcfg_intercept_write,
+ .cpuid = hvmemul_cpuid,
};
static const struct x86_emulate_ops hvm_ro_emulate_ops_mmio = {
.read = x86emul_unhandleable_rw,
.insn_fetch = hvmemul_insn_fetch,
- .write = mmio_ro_emulated_write
+ .write = mmio_ro_emulated_write,
+ .cpuid = hvmemul_cpuid,
};
struct mmio_ro_emulate_ctxt mmio_ro_ctxt = { .cr2 = gla };
struct hvm_emulate_ctxt ctxt;
.insn_fetch = ptwr_emulated_read,
.write = ptwr_emulated_write,
.cmpxchg = ptwr_emulated_cmpxchg,
+ .cpuid = pv_emul_cpuid,
};
/* Write page fault handler: check if guest is trying to modify a PTE. */
.read = x86emul_unhandleable_rw,
.insn_fetch = ptwr_emulated_read,
.write = mmio_ro_emulated_write,
+ .cpuid = pv_emul_cpuid,
};
int mmcfg_intercept_write(
.read = x86emul_unhandleable_rw,
.insn_fetch = ptwr_emulated_read,
.write = mmcfg_intercept_write,
+ .cpuid = pv_emul_cpuid,
};
/* Check if guest is trying to modify a r/o MMIO page. */
.insn_fetch = hvm_emulate_insn_fetch,
.write = hvm_emulate_write,
.cmpxchg = hvm_emulate_cmpxchg,
+ .cpuid = hvmemul_cpuid,
};
static int
.insn_fetch = pv_emulate_read,
.write = pv_emulate_write,
.cmpxchg = pv_emulate_cmpxchg,
+ .cpuid = pv_emul_cpuid,
};
const struct x86_emulate_ops *shadow_init_emulation(
return X86EMUL_UNHANDLEABLE;
}
+int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
+ unsigned int *edx, struct x86_emulate_ctxt *ctxt)
+{
+ struct cpu_user_regs regs = *ctxt->regs;
+
+ regs._eax = *eax;
+ regs._ecx = *ecx;
+
+ pv_cpuid(®s);
+
+ *eax = regs._eax;
+ *ebx = regs._ebx;
+ *ecx = regs._ecx;
+ *edx = regs._edx;
+
+ return X86EMUL_OKAY;
+}
+
/* Instruction fetch with error handling. */
#define insn_fetch(type, base, eip, limit) \
({ unsigned long _rc, _ptr = (base) + (eip); \
unsigned int insn_bytes);
void hvm_emulate_writeback(
struct hvm_emulate_ctxt *hvmemul_ctxt);
+int hvmemul_cpuid(
+ unsigned int *eax,
+ unsigned int *ebx,
+ unsigned int *ecx,
+ unsigned int *edx,
+ struct x86_emulate_ctxt *ctxt);
struct segment_register *hvmemul_get_seg_reg(
enum x86_segment seg,
struct hvm_emulate_ctxt *hvmemul_ctxt);
void *p_data,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt);
+int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
+ unsigned int *edx, struct x86_emulate_ctxt *ctxt);
int ptwr_do_page_fault(struct vcpu *, unsigned long,
struct cpu_user_regs *);