break;
case VM_EVENT_REASON_CPUID:
printf("CPUID executed: rip=%016"PRIx64", vcpu %d. Insn length: %"PRIu32" " \
- "EAX: 0x%"PRIx64" EBX: 0x%"PRIx64" ECX: 0x%"PRIx64" EDX: 0x%"PRIx64"\n",
+ "0x%"PRIx32" 0x%"PRIx32": EAX=0x%"PRIx64" EBX=0x%"PRIx64" ECX=0x%"PRIx64" EDX=0x%"PRIx64"\n",
req.data.regs.x86.rip,
req.vcpu_id,
req.u.cpuid.insn_length,
+ req.u.cpuid.leaf,
+ req.u.cpuid.subleaf,
req.data.regs.x86.rax,
req.data.regs.x86.rbx,
req.data.regs.x86.rcx,
return monitor_traps(curr, sync, &req);
}
-int hvm_monitor_cpuid(unsigned long insn_length)
+int hvm_monitor_cpuid(unsigned long insn_length, unsigned int leaf,
+ unsigned int subleaf)
{
struct vcpu *curr = current;
struct arch_domain *ad = &curr->domain->arch;
req.reason = VM_EVENT_REASON_CPUID;
req.vcpu_id = curr->vcpu_id;
req.u.cpuid.insn_length = insn_length;
+ req.u.cpuid.leaf = leaf;
+ req.u.cpuid.subleaf = subleaf;
return monitor_traps(curr, 1, &req);
}
static int vmx_do_cpuid(struct cpu_user_regs *regs)
{
unsigned int eax, ebx, ecx, edx;
+ unsigned int leaf, subleaf;
eax = regs->eax;
ebx = regs->ebx;
ecx = regs->ecx;
edx = regs->edx;
+ leaf = regs->eax;
+ subleaf = regs->ecx;
+
vmx_cpuid_intercept(&eax, &ebx, &ecx, &edx);
regs->eax = eax;
regs->ecx = ecx;
regs->edx = edx;
- return hvm_monitor_cpuid(get_instruction_length());
+ return hvm_monitor_cpuid(get_instruction_length(), leaf, subleaf);
}
static void vmx_dr_access(unsigned long exit_qualification,
void hvm_monitor_msr(unsigned int msr, uint64_t value);
int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
unsigned long trap_type, unsigned long insn_length);
-int hvm_monitor_cpuid(unsigned long insn_length);
+int hvm_monitor_cpuid(unsigned long insn_length, unsigned int leaf,
+ unsigned int subleaf);
#endif /* __ASM_X86_HVM_MONITOR_H__ */
struct vm_event_cpuid {
uint32_t insn_length;
+ uint32_t leaf;
+ uint32_t subleaf;
uint32_t _pad;
};