Re: Interested in working for GSoC project

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jan/ Kashyap/ All,

Thanks for the tips! It was really helpful. I was using a very old
version of kvm_intel module and it didn't have "nested" capabilities.

Now, I am using "-cpu core2duo,+vmx" option and kvm-intel.ko is also
inserted using nested=1. And, the CPUID returned the correct info, it
had VMX capabilities. Hence the test is passed.

Secondly, I am trying to test bit 13 of CR4 register, which is
necessary to be set before using instructions like vmxon. I am not
sure when and how is this bit set, or it never gets set in the tests?

I am attaching the patch, which as of now, first prints the vendor ID,
and Passes VMX capabilities test, and Fails for testing CR4.VMXE bit.

Command :
qemu-kvm -device testdev,chardev=testlog -chardev
file,id=testlog,path=msr.out -serial stdio -cpu core2duo,+vmx -kernel
./x86/vmx_test.flat

Output :
Vendor ID : GenuineIntel

VMX_CAPABILITIES_GUEST: PASS
CONTROL_REGISTER_VMX_ON: FAIL



----------------------------
Thanks & Regards
Mohit Dhingra
+919611190435


On 14 April 2013 15:59, Kashyap Chamarthy <kashyap.cv@xxxxxxxxx> wrote:
> On Sun, Apr 14, 2013 at 1:48 PM, Jan Kiszka <jan.kiszka@xxxxxx> wrote:
>> On 2013-04-13 20:24, Mohit Dhingra wrote:
>>> Hi All,
>>>
>>> I am Mohit Dhingra, planning to work in GSoC project "Improve nested
>>> virtualization support for x86". I got in touch with Jan
>>> (jan.kiszka@xxxxxx) few days back.
>>>
>>> As suggested by him, I am trying to write a simple unit test which
>>> tests the "vmx" functions. To start with, I have written a small code
>>> which checks whether "vmx" functionality is available on the current
>>> processor or not[1].
>>>
>>> I have used "cpuid" to check the VMX functionality. Before executing
>>> cpuid, eax is set to 1. cpuid then puts the feature flags in ecx and
>>> edx registers. Bit5 in ecx register tells whether VMX feature is
>>> present or not. I am attaching the patch along with this mail.
>>
>> Hint regarding assembly usage: Try to minimize the number of
>> instructions. Check, e.g., how the kernel implements cpuid. Result
>> evaluation can perfectly be done in C.
>>
>>>
>>> But there is a problem that I am facing. CPUID behaves differently
>>> when I run it using qemu-kvm, and when I run it directly in user mode.
>>>  Please check the below output. It would be great if someone can
>>> please help me out.
>>
>> To enable nested VMX, you need to tweak two things: first, you need
>> nested=1 as parameter for kvm_intel. And, second, you have to select a
>> CPU type via QEMU (-cpu) that supports VMX or explicitly add that
>> feature to the selected CPU (-cpu ...,+vmx).
>
> In addendum to Jan's above info,
>
> I posted some notes here while testing it on Fedora, see if its any helpful:
>
> - http://kashyapc.wordpress.com/tag/nested-virtualization/
> - https://github.com/kashyapc/nested-virt-notes-intel-f18
>
>>
>> By default, only core[2]duo and the synthetic KVM type "host" come with
>> VMX enabled, not much more modern Intel CPU like Nehalem or SandyBridge.
>> That's inconsistent, and if you want to fix something in QEMU, you could
>> check which CPU types in qemu/target-i386/cpu.c lack the flag and post a
>> patch to change this.
>>
>> Jan
>>
From 01f3cc5e424dca53a94f0cb349447f5c436a301b Mon Sep 17 00:00:00 2001
From: Mohit Dhingra <mohitdhingras@xxxxxxxxx>
Date: Sun, 21 Apr 2013 02:18:32 +0530
Subject: [PATCH 1/3] Unit test for checking VMX capabilities

---
 x86/vmx_test.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 98 insertions(+), 0 deletions(-)
 create mode 100644 x86/vmx_test.c

diff --git a/x86/vmx_test.c b/x86/vmx_test.c
new file mode 100644
index 0000000..d928f07
--- /dev/null
+++ b/x86/vmx_test.c
@@ -0,0 +1,98 @@
+
+#include "libcflat.h"
+#include "processor.h"
+#include "msr.h"
+
+
+struct vmx_info {
+    char *name;
+    int (*test_case)();
+};
+
+int test_vmx_capabilities(); // Returns 1 if VMX capabilities are present in the Guest, else Returns 0
+int test_cr4_vmx_set(); // Returns 1 if VMX bit is set in CR4 Register ( Must before executing instructions like vmxon )
+void VendorId(); // Prints Vendor ID
+
+
+struct vmx_info test_cases_array[]= {
+    {"VMX_CAPABILITIES_GUEST" , test_vmx_capabilities},
+    {"CONTROL_REGISTER_VMX_ON", test_cr4_vmx_set}
+};
+
+
+
+int main(int ac, char **av)
+{
+    int count = 0;
+  
+    VendorId();
+
+    for( count = 0 ; count < (sizeof(test_cases_array)/sizeof(struct vmx_info)) ; count++)
+    {
+        printf( "%s: %s\n", test_cases_array[count].name, (test_cases_array[count].test_case() ? "PASS" : "FAIL")  );
+    }
+
+
+ return 1;
+}
+ 
+
+int test_vmx_capabilities()
+{
+
+    int eax_initialize = 1;
+    uint32_t test_vmx_capabilities = 0;
+
+    asm volatile ("mov %1, %%eax\n\t"             // mov source destination
+                 "cpuid\n\t"                   // When eax = 1, cpuid puts Feature Flags in ecx and edx registers. 
+                "mov %%ecx, %0"                 // Storing the result into test_vmx_capabilities
+          
+                :"=r"(test_vmx_capabilities)    // Ouputs : test_vmx_capabilities
+                :"r"(eax_initialize)            // Inputs : eax_initialize
+                :"eax","ecx");
+
+//    printf("Feauture Flag returned in ecx : 0x%x ", test_vmx_capabilities);
+
+    if ( test_vmx_capabilities & 0x20 ) // ANDing ecx with 0x20 (00100000), if it results in non-zero, then VMX capabilities are present.
+        return 1;
+    else
+        return 0;
+
+}
+
+
+
+int test_cr4_vmx_set()
+{
+     unsigned long result;
+  
+    //CR4 cr4_reg;
+  
+    asm volatile("movq %%cr4, %%rax\n\t"
+                 : "=a"(result) ::  ); 
+
+    if ( result & 0x2000 )  // Bit 13 of CR4 should be set to use commands like vmxon
+        return 1;
+
+    return 0;
+
+}
+
+
+// Prints vendor ID 
+void VendorId()
+{
+    int code = 0;
+
+    union {
+        uint32_t where[4];
+        char vendor[17];
+    }s;
+
+    asm volatile("cpuid":"=a"(*s.where),"=b"(*(s.where+1)),"=c"(*(s.where+3)),"=d"(*(s.where+2)):"a"(code));
+
+    s.vendor[16] = '\0';
+
+    printf("Vendor ID : %s\n\n", (s.vendor+4));
+
+}
-- 
1.7.7


From c36899d742b91c26c7855f7bac4f35746d818622 Mon Sep 17 00:00:00 2001
From: Mohit Dhingra <mohitdhingras@xxxxxxxxx>
Date: Sun, 21 Apr 2013 02:18:44 +0530
Subject: [PATCH 2/3] Unit test for checking VMX capabilities

---
 config-x86-common.mak |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/config-x86-common.mak b/config-x86-common.mak
index 1f0f1ba..df2a42e 100644
--- a/config-x86-common.mak
+++ b/config-x86-common.mak
@@ -31,7 +31,7 @@ FLATLIBS = lib/libcflat.a $(libgcc)
 
 tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
                $(TEST_DIR)/smptest.flat  $(TEST_DIR)/port80.flat \
-               $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat \
+               $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat $(TEST_DIR)/vmx_test.flat \
                $(TEST_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat \
                $(TEST_DIR)/kvmclock_test.flat  $(TEST_DIR)/eventinj.flat \
                $(TEST_DIR)/s3.flat $(TEST_DIR)/pmu.flat \
@@ -79,6 +79,8 @@ $(TEST_DIR)/realmode.o: bits = 32
 
 $(TEST_DIR)/msr.elf: $(cstart.o) $(TEST_DIR)/msr.o
 
+$(TEST_DIR)/vmx_test.elf: $(cstart.o) $(TEST_DIR)/vmx_test.o
+
 $(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt_test.o
 
 $(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/xsave.o
-- 
1.7.7


From 1d61a82ec1525c087cbd205fb8ea4576cd30b04b Mon Sep 17 00:00:00 2001
From: Mohit Dhingra <mohitdhingras@xxxxxxxxx>
Date: Sun, 21 Apr 2013 02:18:53 +0530
Subject: [PATCH 3/3] Unit test for checking VMX capabilities

---
 x86/unittests.cfg |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index 5e08c55..1a65a14 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -63,6 +63,9 @@ file = hypercall.flat
 [idt_test]
 file = idt_test.flat
 
+[vmx_test]
+file = vmx_test.flat
+
 [msr]
 file = msr.flat
 
@@ -101,4 +104,4 @@ extra_params = --append "10000000 `date +%s`"
 
 [pcid]
 file = pcid.flat
-extra_params = -cpu qemu64,+pcid
\ No newline at end of file
+extra_params = -cpu qemu64,+pcid
-- 
1.7.7


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux