Re: [Question] Switching VCPU CPL from the hypervisor ?
Paolo Bonzini redhat.com> writes: > On 15/12/2015 18:02, Hebbal Yacine wrote: > > What I want to do is: when a controlled process is in user mode, i > > change its cpl to 0, force it to execute a code that is injected in the > > VM, set back its cpl to 3 and let it run like if nothing happened > > Could you inject an SMI and place your code in the guest firmware's SMM > handler? What input is needed by this CPL=0 code? > > Paolo I think the the solution follows this logic, meaning we inject an interrupt, intercept execution of its handler (cpl is 0), save cpu context, execute the code we want, push a return address, and force the process to execute IRET instruction which will complete the cleaning, restore cpl to 3 and let the process resume its normal execution. I'll continue to dig this to see if there is any better approach, thanks for your help :) Yacine -- 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
[Question] Switching VCPU CPL from the hypervisor ?
Hi, I working on an application in which I control an arbitrary process to execute an a given code (injected code for example). I want the process I'm controlling to execute my code with root privilege. Is it possible to arbitrary switch vcpu cpl to 0 from the hypervisor level (process is in user mode) ? I'm aware that I can do this using some hacks and emulation or by controlling the process just after it enters or just before it quits kernel mode (but I need to wait and intercept these events). Is there a straightforward technique to switch vcpu cpl from the hypervisor level at demand ? -- 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: [Question] Switching VCPU CPL from the hypervisor ?
> > Would a hypercall do? VMCALL can be executed from CPL 3. > > Paolo > -- > > What I want to do is: when a controlled process is in user mode, i change its cpl to 0, force it to execute a code that is injected in the VM, set back its cpl to 3 and let it run like if nothing happened Yacine -- 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: gva_to_gpa function internals
In fact, my tool walks through paging data structures (entry by entry) using the function "kvm_read_guest" (sorry i don't have my machine with me right now to poste my code :-( ). for example to read PDPTEs, I do something like this: for(i = 0; i < 32; i= i + 8) { kvm_read_guest(kvm, cr3 + i, , 8); } I use the same logique for PDEs and PTEs (of couse by masking the flags bits to walk from one level to another) I hope this explains a little more. I'll poste more code tomorrow to give more details. Le 01/12/2015 22:31, Paolo Bonzini a écrit : On 01/12/2015 19:30, Yacine HEBBAL wrote: Hi all, I'm trying to build some tools on top of kvm in order to debug, monitor and reverse engineer the guest OS (ubuntu 12.04, 32 bits) One of my tools walks through (and prints) the guest paging data structures as following: cr3 -> pdpte -> pde -> pte -> page (PAE paging, 32 bits) According to my logs some accessed kernel PTEs are not present (pte = 9090909090909090) in all processes address spaces (even from init process cr3), however when I use the function kvm_read_guest_virt_helper on their corresponding virtual addresses (GVAs), I get a correct content (content correctness checked using system.map file). Just after calling kvm_read_guest_virt_helper, I check again the PTE corresponding to the read gva, I see that they are unmapped (invalid, always 9090909090909090) I investigated a little the code of kvm_read_guest_virt_helper, this function calls vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, ...) which in turn calls other functions until FNAME(walk_addr_generic) which seems to do the translation. walk_addr_generic seems to do the translation starting from cr3 of the current process (in line: mmu->get_cr3(vcpu);) and works fine regardless of the identity of the current process (i.e. current cr3). So how the function gva_to_gpa is able to the read correctly any GVA that my tool sees invalid (unmapped) in the paging structures, knowing that my tool is able to read and display correctly a content of (thousands) many other GVAs ? I would be very thankful for any feedback :) Unfortunately that's impossible to know without knowing your tool. How does it read guest memory? Paolo -- Hebbal Yacine PhD student Tel +33 6 45 42 10 96 -- 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
gva_to_gpa function internals
Hi all, I'm trying to build some tools on top of kvm in order to debug, monitor and reverse engineer the guest OS (ubuntu 12.04, 32 bits) One of my tools walks through (and prints) the guest paging data structures as following: cr3 -> pdpte -> pde -> pte -> page (PAE paging, 32 bits) According to my logs some accessed kernel PTEs are not present (pte = 9090909090909090) in all processes address spaces (even from init process cr3), however when I use the function kvm_read_guest_virt_helper on their corresponding virtual addresses (GVAs), I get a correct content (content correctness checked using system.map file). Just after calling kvm_read_guest_virt_helper, I check again the PTE corresponding to the read gva, I see that they are unmapped (invalid, always 9090909090909090) I investigated a little the code of kvm_read_guest_virt_helper, this function calls vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, ...) which in turn calls other functions until FNAME(walk_addr_generic) which seems to do the translation. walk_addr_generic seems to do the translation starting from cr3 of the current process (in line: mmu->get_cr3(vcpu);) and works fine regardless of the identity of the current process (i.e. current cr3). So how the function gva_to_gpa is able to the read correctly any GVA that my tool sees invalid (unmapped) in the paging structures, knowing that my tool is able to read and display correctly a content of (thousands) many other GVAs ? I would be very thankful for any feedback :) -- 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
Link kvm with Xed library: Unknown symbol error
Hi, I'm a student working on a monitoring application on top of KVM in which I need to disassemble some VM instructions from the hypervisor level. To do so (disassemble instructions), I want to use Xed library from the code I added to KVM. The problem is that Xed library comes with header files and a static library file. When I compile kvm-kmod with Xed (with some changes in the Kbuild file to include Xed). I get the following input: compilation OK with some warnings: WARNING: "xed_encode_order_limit" [/home/yacine/vmi/kvm-kmod/x86/kvm-intel] is COMMON symbol // omitted WARNING: "xed_chip_features2" [/home/yacine/vmi/kvm-kmod/x86/kvm-intel] is COMMON symbol WARNING: "stderr" [/home/yacine/vmi/kvm-kmod/x86/kvm-intel.ko] undefined! WARNING: "fprintf" [/home/yacine/vmi/kvm-kmod/x86/kvm-intel.ko] undefined! WARNING: "abort" [/home/yacine/vmi/kvm-kmod/x86/kvm-intel.ko] undefined! WARNING: "__umoddi3" [/home/yacine/vmi/kvm-kmod/x86/kvm-intel.ko] undefined! insmod: error inserting 'kvm-intel.ko': -1 Invalid module format when running dmesg: [17591.101368] kvm_intel: please compile with -fno-common ... // omitted [17591.101527] kvm_intel: Unknown symbol __umoddi3 (err 0) [17591.101553] kvm_intel: Unknown symbol abort (err 0) ... // omitted [17591.101763] kvm_intel: please compile with -fno-common If anyone has an idea how to solve this, I would be very grateful :) -- 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: Difference between vcpu_load and kvm_sched_in ?
Paolo Bonzini redhat.com> writes: > > > On 21/10/2015 12:17, Hebbal Yacine wrote: > > Thanks for the explanation, it's very clear. > > I tired that but I didn't succeed to send the ioctl from "run_on_cpu" > > function, I didn't find how to set the right CPUStat > > I've tried "current_cpu" > > Current_cpu is always NULL outside the VCPU thread. > > > > > kvm_main.c: > > > > // yacine.begin > > > > static void do_vmi_start_kvm_ioctl(void *type) { > > printf("do_vmi_start_kvm_ioctl\n"); > > kvm_vm_ioctl(kvm_state, type); //yacine.begin int hmp_vmi_op_result = 0; static void do_vmi_kvm_ioctl(void *type_ioctl) { int* type = (int*) type_ioctl; hmp_vmi_op_result = kvm_vcpu_ioctl(current_cpu, *type); //hmp_vmi_start_result = kvm_vm_ioctl(kvm_state, *type); } int vmi_kvm_ioctl(int type) { CPUState* cpu; CPU_FOREACH(cpu) { run_on_cpu(cpu, do_vmi_kvm_ioctl, ); } return hmp_vmi_op_result; } //yacine.end Yes, it works perfectly this way even when running multiple VCPUs, thank you a lot :) In fact, I was using an old version of qemu (1.5.x), and it doesn't have CPU_FOREACH, i searched a little for to replace it, but without any luck. So I upgraded my working version and now everything is cool > Are you sure you want a VM ioctl and not a VCPU ioctl? Or perhaps a VM > ioctl to do generic processing, and a VCPU ioctl that is then sent to > all VCPUs? >If you use a VCPU ioctl, you can use CPU_FOREACH or a for loop to > iterate over all VCPUs. In fact, I get the same result when using vm_ioctl or vcpu_ioctl. If I correctly understood you last paragraph, it is better to use vm_ioctl to do generic processing that doesn't rely on a given VCPU and hence I won't need to use "CPU_FOREACH, run_on_cpu and current_cpu". Thanks again :) > > Paolo > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo 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
Re: Difference between vcpu_load and kvm_sched_in ?
Paolo Bonzini redhat.com> writes: > > > On 21/10/2015 00:57, Wanpeng Li wrote: > >> kvm_sched_out and kvm_sched_in are part of KVM's preemption hooks. The > >> hooks are registered only between vcpu_load and vcpu_put, therefore they > >> know that the mutex is taken. The sequence will go like this: > >> > >> vcpu_load > >> kvm_sched_out > >> kvm_sched_in > >> kvm_sched_out > >> kvm_sched_in > >> ... > >> vcpu_put > > > > If this should be: > > > > vcpu_load > > kvm_sched_in > > kvm_sched_out > > kvm_sched_in > > kvm_sched_out > > ... > > vcpu_put > > No, because vcpu_load is called while the thread is running. Therefore, > the first preempt notifier call will be a sched_out notification, which > calls kvm_arch_vcpu_put. Extending the picture above: > > vcpu_load-> kvm_arch_vcpu_load > kvm_sched_out-> kvm_arch_vcpu_put > kvm_sched_in -> kvm_arch_vcpu_load > kvm_sched_out-> kvm_arch_vcpu_put > kvm_sched_in -> kvm_arch_vcpu_load > ... > kvm_sched_out-> kvm_arch_vcpu_put > kvm_sched_in -> kvm_arch_vcpu_load > vcpu_put -> kvm_arch_vcpu_put > > Thanks, > > Paolo > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > Thanks for the explanation, it's very clear. I tired that but I didn't succeed to send the ioctl from "run_on_cpu" function, I didn't find how to set the right CPUStat I've tried "current_cpu" kvm_main.c: // yacine.begin static void do_vmi_start_kvm_ioctl(void *type) { printf("do_vmi_start_kvm_ioctl\n"); kvm_vm_ioctl(kvm_state, type); } int vmi_start_kvm_ioctl(int type) { <- called from hmp.c printf("vmi_start_kvm_ioctl\n"); run_on_cpu(current_cpu, do_vmi_start_kvm_ioctl, (void *) ); return 0; } // yacine.end This gives me a segmentation fault Then I tired to replace current_cpu with ENV_GET_CPU(mon_get_cpu()), it didn't work, I get nothing, no error but doesn't work I tried also to pass mon->mon_cpu through int vmi_start_kvm_ioctl(int type) by adding a first parameter as CPUStat, i get compiler error "dereference pointer to incomplete type" I'm beginner to qemu and kvm code, can you please orient me to fix this problem ? Thanks in advance Yacine -- 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
Difference between vcpu_load and kvm_sched_in ?
Hi, I'm a student working on virtual machine introspection. I'm trying to implement an application on top of KVM in which I need to trap writes to CR3 (host with 8 cores and guest with one vcpu). When I do this when handling a VM EXIT using: vmcs_set_bits(CPU_BASED_VM_EXEC_CONTROL, CPU_BASED_CR3_LOAD_EXITING), it works correctly and I can see the traps in my log file. Now when I do the same thing after receiving a command from Qemu (command is handled in kvm_vm_ioctl by calling a function I added to kvm_x86_ops vmx_x86_ops) I get a vmwrite error. I found out that the problem is because the logical processor on the host that is handling the ioctl command is not the same that is running the VM and holding its state; so I must do the vmwrite on the one executing the VM To change the logical cpu executing the VM, I tried this: vcpu_load; start cr3 trapping; vcpu_put it worked correctly (in my logs I see that vcpu.cpu become equal to "cpu = raw_smp_processor_id();") but the VM blocks for a lot of time due to mutex in vcpu_load (up to serveral seconds and sometimes minutes !) I replaced vcpu_load with kvm_sched_in, now everything works perfectly and the VM doesn't block at all (logs here: http://pastebin.com/h5XNNMcb). So, what I want to know is: what is the difference between vcpu_load and kvm_sched_in ? both of this functions call kvm_arch_vcpu_loadbut the latter one does it without doing a mutex Is there a problem in using kvm_sched_in instead of vcpu_load for my use case ? -- 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