Question about guest MSR loading/saving (Intel)
Hi all, This is a vague/general question. For some background: I have a reason (control of IA32_PERF_GLOBAL_CTRL) for loading/saving MSRs on VM-entry/ exit. To get this to work correctly, I made changes to use the conventional VMX MSR load areas of the VMCS for this particular MSR. Works great. Is there a particular reason why MSRs are currently loaded/saved through KVM's unconventional facilities (vmx.c:save_msrs(), vmx.c:load_msrs()), rather than through VM entry/exit MSR load regions in the VMCS? I see that only long mode guests on x86_64 are effected by this. Any insight could be useful. Do you think MSR loading via VMCS would be faster? Are there downsides to doing it one way or the other? Kurt -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: A puzzle on the interrupt disposal of KVM?
I've been studying interrupt delivery in KVM myself lately. I hope I can explain what I've found, but, as I'm pretty new to this, please take my answer with a grain of salt (as I could be wrong). I would really appreciate if someone could correct me here if I am wrong or provide more details! Interrupts from the guest might be delivered via the ioctl KVM_INTERRUPT only when the KVM kmod can do interrupt routing. However, the default setup for KVM these days implements the interrupt controller in the kernel, so this ioctl is unused, and thus, vmx_inject_irq is not directly triggered from userspace. The call to vmx_inject_irq is made upon re-entry to the guest after I.E. the local APIC in the kmod flags that it needs service. To use the example of a PS2 keyboard press, the control flow works like this: 1. Userspace writes to appropriate locations as defined by the i8042 emulator 2. Userspace calls vm ioctl KVM_IRQ_LINE (IRQ=1, Level=1) 3. Control in the kmod eventually makes a call to kvm_apic_set_irq 4. In the local APIC, __apic_accept_irq does a part in setting up the need for service 5. Upon guest entry (vcpu_enter_guest), if there is no nmi and kvm_apic_has_interrupt, the host will call inject_pending_irq 6. inject_pending_irq calls vmx_inject_irq In attempting to answer the second part of your question, I realize this point isn't 100% clear to me either. It would seem the point at which the interrupt is delivered to KVM is always the point at which the guest VCPU is entered. Obviously, if you have a multi-cpu setup the calls to set up the local apic can be done in parallel to running the guest, but interrupt delivery won't happen until the vcpu is re- entered. This seems to mean that interrupts are only delivered when the guest is scheduled out and back in by the kernel. Is this right, guys? Kurt On Nov 23, 2009, at 4:49 PM, Liang YANG wrote: Does the vmx_inject_irq and vmx_inject_nmi inject all the interrupt from outer space ? Then when the interrrupt yielded from hardware is delieved to the QEMU or KVM ? Anyone can help me,, Thanks in advance!! -- BestRegards. YangLiang _ Master Candidate. Department of Computer Science . School of Electronics Engineering Computer Science . _ -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Recording interrupted instruction on ioapic_set_irq
Hi guys, I'm trying to record the instruction pointer at the exact time a guest was delivered an IOAPIC interrupt. Take for example a PS2 keyboard press. Clearly, when I read IP during the subsequent exit for IO_INSTRUCTION I'm just recording the IP of io_read in the handler, and not the IP at actual interrupt delivery. Maybe I'm missing something fundamental. It doesn't look like exits for EXTERNAL_INTERRUPT (shouldn't it?) or INTERRUPT_WINDOW correspond one-to-one with delivery of these PS2 interrupts. Just setting request_interrupt_window for these IRQs didn't give me an INTERRUPT_WINDOW for each key. I guess since the guest doesn't usually have interrupts masked when I press a key means delivery won't wait for the window. Could I record during delivery? I figure I could look at the stack during the IO_INSTRUCTION exit and figure out what instruction was actually interrupted, but this would be a Linux-specific solution. Any other ideas? I think even a simple description of how these interrupts are being delivered to the guest would help me out a lot. Thanks, Kurt -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Added VM Exit on RDTSC, trouble handling in userspace
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Hi all, In short, I have a need for trapping RDTSC with a VM Exit and this works, but I'm having trouble handling it in userspace. I have added the hooks I need (I only care about VMX right now), but a piece of the puzzle is missing and I don't know which. When I go back to userspace, it's triggering a different (faulty) execution vs. handling only in the kernel. Here's what I've done: 1. Added the CPU_BASED_RDTSC_EXITING flag to MSR_IA32_VMX_PROCBASED_CTLS in vmx.c:setup_vmcs_config() 2. Defined KVM_EXIT_RDTSC, and hooked into EXIT_REASON_RDTSC my handler for the exit: static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) = { // ... [EXIT_REASON_RDTSC] = handle_rdtsc, // ... } static int handle_rdtsc(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { u64 data; if (vmx_get_msr(vcpu, MSR_IA32_TIME_STAMP_COUNTER, data)) { kvm_inject_gp(vcpu, 0); return 1; } vcpu-run-exit_reason = KVM_EXIT_RDTSC; vcpu-arch.regs[VCPU_REGS_RAX] = data -1u; vcpu-arch.regs[VCPU_REGS_RDX] = (data 32) -1u; skip_emulated_instruction(vcpu); // flag a need for userspace invervention // note: this works when we return 1 and we don't involve userspace return 0; } 3. Handle KVM_EXIT_RDTSC in libkvm.c:kvm_run() : case KVM_EXIT_RDTSC: r = handle_rdtsc_usp(kvm, vcpu, env); break; via a handler where I do _nothing_ : static int handle_rdtsc_usp(kvm_context_t kvm, int vcpu, void *data) { return 0; } All well and good, right? I can add print statements to my userspace handle_rtsc_usp() and see I get in there just fine. However, when I try to boot Linux, the following code is called over and over and over, and Linux will never load: Breakpoint 4, 0xc01103d3 in ?? () (gdb) x/10i $rip-10 0xc01103c9: lea0x0(%rdi,%riz,1),%edi 0xc01103d0: push %rbp 0xc01103d1: mov%esp,%ebp 0xc01103d3: rdtsc 0xc01103d5: pop%rbp 0xc01103d6: retq If I only handle the exit in the kernel (by returning 1 from handle_rdtsc()), everything works and Linux will load! I counted the number of RDTSC exits before linux fully loads to be somewhere around 20. If I exit all the way to userspace (return 0 in my handle_rdtsc()) that count is infinitely surpassed in number of exits, wall time, and the value of RDTSC. So is anything glaringly wrong with my modifications? Maybe there is there some extra state that needs to be restored on VM entry? Is there an interrupt flag that needs to be cleared? Maybe I need to do something with kvm_run.if_flag or kvm_run.ready_for_interrupt_injection? Please, I need help, I'm losing sleep over this! Thanks, Kurt -BEGIN PGP SIGNATURE- Version: GnuPG/MacGPG2 v2.0.12 (Darwin) iEYEARECAAYFAkrVZvQACgkQYFGmU9mnI1FqvgCcC/+PswoXHQ5kVgv5tC6UadiA KKgAoKrLgsYSJN0+1d0pox9vzsLHoQIc =cQzR -END PGP SIGNATURE- -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html