Take the unused CPUID 0x40001xxx range as the backdoor instruction. Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu> --- backdoor/guest.h | 21 +++++++++++++++++++++ target-i386/cpuid.c | 27 +++++++++++++++++++++++++++ target-i386/helper.h | 4 ++++ target-i386/translate.c | 4 ++++ 4 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/backdoor/guest.h b/backdoor/guest.h index 8373762..3edcbc6 100644 --- a/backdoor/guest.h +++ b/backdoor/guest.h @@ -26,8 +26,29 @@ * - v32: value of 32 bits */ +#include <stdint.h> + +#if __i386__ || __i486__ || __x86_64__ + +#define _BACKDOOR(t, i8, v32) \ + ({ \ + uint32_t eax, ebx, ecx, edx; \ + uint32_t index = (uint32_t)0x40001000 + (t<<8) + (uint8_t)i8; \ + uint32_t count = (uint32_t)v32; \ + asm volatile ("cpuid" \ + : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) \ + : "0"(index), "2"(count) \ + ); \ + eax; \ + }) + +#define BACKDOOR_i8(i) _BACKDOOR(0, i, 0) +#define BACKDOOR_i8_v32(i, v) _BACKDOOR(1, i, v) + +#else #error Undefined instruction-based backdoor interface for guest architecture +#endif #endif /* BACKDOOR__GUEST_H */ diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c index 650a719..03fc973 100644 --- a/target-i386/cpuid.c +++ b/target-i386/cpuid.c @@ -27,6 +27,9 @@ #include "qemu-option.h" #include "qemu-config.h" +#include "helper.h" + + /* feature flags taken from "Intel Processor Identification and the CPUID * Instruction" and AMD's "CPUID Specification". In cases of disagreement * between feature naming conventions, aliases may be added. @@ -1033,6 +1036,30 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { +#if defined(CONFIG_BACKDOOR) /* synched with "backdoor/guest.h" */ + if ((index & ~0xfff) == 0x40001000) { + int type = (index >> 8) & 0xf; + uint8_t i8 = index & 0x0ff; + uint32_t v32 = count; + switch (type) { + case 0: + helper_backdoor_i8(i8); + break; + case 1: + helper_backdoor_i8_v32(i8, v32); + break; + default: + printf("invalid backdoor request\n"); + abort(); + } + *eax = 0; + *ebx = 0; + *ecx = 0; + *edx = 0; + return; + } +#endif + /* test if maximum index reached */ if (index & 0x80000000) { if (index > env->cpuid_xlevel) diff --git a/target-i386/helper.h b/target-i386/helper.h index 6b518ad..979d94e 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -217,4 +217,8 @@ DEF_HELPER_2(rclq, tl, tl, tl) DEF_HELPER_2(rcrq, tl, tl, tl) #endif +#if defined(CONFIG_BACKDOOR) +#include "backdoor/helper.h" +#endif + #include "def-helper.h" diff --git a/target-i386/translate.c b/target-i386/translate.c index 7b6e3c2..dfdc2f0 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -6941,6 +6941,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_op_set_cc_op(s->cc_op); gen_jmp_im(pc_start - s->cs_base); gen_helper_cpuid(); +#if defined(CONFIG_BACKDOOR) + gen_jmp_im(s->pc); + gen_eob(s); +#endif break; case 0xf4: /* hlt */ if (s->cpl != 0) {