|
@@ -3514,6 +3514,16 @@ static int em_cwd(struct x86_emulate_ctxt *ctxt)
|
|
|
return X86EMUL_CONTINUE;
|
|
|
}
|
|
|
|
|
|
+static int em_rdpid(struct x86_emulate_ctxt *ctxt)
|
|
|
+{
|
|
|
+ u64 tsc_aux = 0;
|
|
|
+
|
|
|
+ if (ctxt->ops->get_msr(ctxt, MSR_TSC_AUX, &tsc_aux))
|
|
|
+ return emulate_gp(ctxt, 0);
|
|
|
+ ctxt->dst.val = tsc_aux;
|
|
|
+ return X86EMUL_CONTINUE;
|
|
|
+}
|
|
|
+
|
|
|
static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
|
|
|
{
|
|
|
u64 tsc = 0;
|
|
@@ -4424,10 +4434,20 @@ static const struct opcode group8[] = {
|
|
|
F(DstMem | SrcImmByte | Lock | PageTable, em_btc),
|
|
|
};
|
|
|
|
|
|
+/*
|
|
|
+ * The "memory" destination is actually always a register, since we come
|
|
|
+ * from the register case of group9.
|
|
|
+ */
|
|
|
+static const struct gprefix pfx_0f_c7_7 = {
|
|
|
+ N, N, N, II(DstMem | ModRM | Op3264 | EmulateOnUD, em_rdpid, rdtscp),
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
static const struct group_dual group9 = { {
|
|
|
N, I(DstMem64 | Lock | PageTable, em_cmpxchg8b), N, N, N, N, N, N,
|
|
|
}, {
|
|
|
- N, N, N, N, N, N, N, N,
|
|
|
+ N, N, N, N, N, N, N,
|
|
|
+ GP(0, &pfx_0f_c7_7),
|
|
|
} };
|
|
|
|
|
|
static const struct opcode group11[] = {
|