2
votes

I have been playing around with VMX and KVM and have a few more general and some more precise questions.

  1. I created a VM with the virtual manager because I assumed (from what I have read online) it to be the easiest way to have a guest running Ubuntu 18.04 (in my case) or, in general, an entire operating system. Does this add/change anything from the KVM/qemu implementation, or is it just an interface?
  2. As far as I understood in KVM (when the kernel modules (kvm and kvm_intel) are inserted), the kernel does take the role of a hypervisor. Is this correct? Under this assumption, I assumed that a new kernel module would then be part of the hypervisor. In a basic kernel module, I used VMREAD to read out a few values from the VMCS. One of the values was the GUEST_IDTR_BASE (defined in vmx.h ) to read out the IDTR of the guest. For some reason, the HOST_IDTR and the GUEST_IDTR have the same value? Is this correct? If yes, what is the reason behind it, and if not, what am I not understanding?
  3. I tried to change the handle_monitor_trap in vmx.c adding just some print statement to understand if something happens and when it is called and recompiled the kvm_intel module. When I then, in a separate module, change the MTF bit (following the intel manual, it should be the 27th bit in the CPU_BASED_VM_EXEC_CONTROL) with
__asm__ __volatile__ ("vmwrite %[value], %[encoding]; setna %[ret]" 
       : [ret]"=rm"(ret)
       : [value]"rm"(value), [encoding]"r"(encoding) : "cc", "memory"); 

where value is the old value I read from CPU_BASED_VM_EXEC_CONTROL OR 0x8000000 and encoding is just the CPU_BASED_VM_EXEC_CONTROL. when I insert the module into the kernel (and of course only when the VM is running) the handler I modified is called. Problems:

  • After a very brief amount of time, it just stops (and the bit is again 0). Does something reset the bit? How does this happen? Is qemu also somehow involved?
  • When printing out the Rip, for example, while executing a loop in the guest, the Rip that is being printed increases every step and never goes back. What is vm executing? Am I even exiting the correct VM or is there some other structure I am not aware of in KVM or in qemu?

I disabled all but one cpu to be sure that I would change the "correct" VMCS since, if I understood it correctly from the manual, there could be different VMCS on different cores.

In general, I would be very grateful for any help you can give me. If you also have any tips on navigating the source code better, I would be very thankful since my experience is minimal.

1
Re Q2, if you’re running the same OS in the host and guest, it’s not too surprising that they might have the same value for such things. - prl
Re Q3, my hypervisor enables MTF for very specific cases, and always disables it on the next VM entry unless the condition that caused it to be enabled is still present. I don’t know about qemu, but perhaps it is similar. I expect that qemu doesn’t expect another module to be manipulating the execution controls. - prl
There is always a separate VMCS for each CPU. - prl
Since you have the guest RIP value, it should be easy to look it up in the link map of the guest kernel, if it is a kernel address. If it’s a user address, then it’s harder. - prl
Thank you @prl ! Yes, of course, it is 0x8000000. I am not sure what I was thinking yesterday while writing the question. In my code I am setting the correct bit, otherwise, the handle_monitor_trap, I think, would not be called. Q2. That makes sense! Thank you. Where does then the translation happen? Or do they share the same IDT? But then when adding a new vector to the IDT and trying to call it from the guest it does not find the custom handler while my host does. - KL1894

1 Answers

0
votes
  1. Virt manager is a wrapper around libvirt, which is in turn a wrapper around multiple VMMs (including QEMU, which can wrap KVM).
  2. As @prl mentioned, nothing stops the host and guest from having the same idtr values. Despite being identical, they will not actually map to the same host physical address, since the guest's value represents a guest physical address. That guest physical address will, on non-ancient x86 hardware, be remapped through the EPT (extended page tables).
  3. Your driver doesn't "own" the VMCS. The next time that KVM writes to the CPU_BASED_VM_EXEC_CONTROL for that VMCS it will clobber what you wrote. You could change KVM to enable MTF.