Search code examples
intelkvmhypervisortscrdtsc

Intercept rdtsc instruction from guest vm userspace in KVM


I'm stuck in the problem as the title says.I want to do this in VMM by adding

the CPU_BASED_RDTSC_EXITING flag in vmx.c(arch/x86/kvm) in setup_vmcs_config function,and

then handle the vm_exit by myself(ref this:mail list).The question is that I cannot

tell whether the vm_exit of rdtsc is caused by the guest kernel or the guest vm user

space application, the latter one is what exactly I want to intercept.I have tried to search

through qemu-kvm-1.2.0 src to find other ways to intercept the rdtsc instruction,I find

rdtsc clue in target-i386/translate.c.And I add a printf there, but I got nothing.So I

wonder if anyone could give me some little guidance to break through.Thank you a lot~


Solution

  • After some experiment,I almost find the answer to my own question.See the code below:

    static int handle_rdtsc(struct kvm_vcpu *vcpu)
    {
        u64 data;
        if (vmx_get_msr(vcpu, MSR_IA32_TSC, &data)) {
        kvm_inject_gp(vcpu, 0);
        printk("wsh_handle_rdtsc_return\n");
        return 1;
      }
    
      vcpu->run->exit_reason = 20;
      vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u;
      vcpu->arch.regs[VCPU_REGS_RDX] = (data >> 32) & -1u;
      skip_emulated_instruction(vcpu);
      if(vmx_get_cpl(vcpu)>0)
      {
          printk("wsh_handle_rdtsc,cpl:%d\n",vmx_get_cpl(vcpu));
      }
      return 1;
    }
    

    As you have seen above,I use vmx_get_cpl to filter those rdtsc vm_exit caused by the guest kernel,and I fact,the printk always print 3,because the privellege level of guest vm applications is always 3.Any corrections is welcomed!