repository: /home/avi/kvm
branch: (no branch)
commit 923e758b38fd6402b67d12898afaa24650f771ab
Author: Izik Eidus <[EMAIL PROTECTED]>
Date:   Thu Nov 8 10:23:36 2007 +0200

    kvm: qemu: add kvm_cpu_register_physical_memory()
    
    this add a new function named kvm_cpu_register_physical_memory()
    that work the same as qemu_cpu_register_physical_memory but just with kvm,
    
    it is the first step in creating mechanisem that work just like qemu have.
    
    Signed-off-by: Izik Eidus <[EMAIL PROTECTED]>

diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c
index 00b2cb2..2d69571 100644
--- a/libkvm/libkvm-x86.c
+++ b/libkvm/libkvm-x86.c
@@ -87,109 +87,6 @@ int kvm_alloc_kernel_memory(kvm_context_t kvm, unsigned 
long memory,
        return 0;
 }
 
-
-#ifdef KVM_CAP_USER_MEMORY
-
-int kvm_alloc_userspace_memory(kvm_context_t kvm, unsigned long memory,
-                                                               void **vm_mem)
-{
-       unsigned long dosmem = 0xa0000;
-       unsigned long exmem = 0xc0000;
-       unsigned long pcimem = 0xe0000000;
-       int r;
-       int tss_ext;
-       struct kvm_userspace_memory_region low_memory = {
-               .memory_size = memory  < dosmem ? memory : dosmem,
-               .guest_phys_addr = 0,
-       };
-       struct kvm_userspace_memory_region extended_memory = {
-               .memory_size = memory < exmem ? 0 : memory - exmem,
-               .guest_phys_addr = exmem,
-       };
-       struct kvm_userspace_memory_region above_4g_memory = {
-               .memory_size = memory < pcimem ? 0 : memory - pcimem,
-               .guest_phys_addr = 0x100000000ULL,
-       };
-
-#ifdef KVM_CAP_SET_TSS_ADDR
-       tss_ext = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_TSS_ADDR);
-#else
-       tss_ext = 0;
-#endif
-
-       if (memory >= pcimem) {
-               extended_memory.memory_size = pcimem - exmem;
-               *vm_mem = mmap(NULL, memory + 0x100000000ULL - pcimem,
-                               PROT_READ|PROT_WRITE, MAP_ANONYMOUS |
-                                                       MAP_SHARED, -1, 0);
-       }
-       else
-               *vm_mem = mmap(NULL, memory, PROT_READ|PROT_WRITE, MAP_ANONYMOUS
-                                                       | MAP_SHARED, -1, 0);
-       if (*vm_mem == MAP_FAILED) {
-               fprintf(stderr, "kvm_alloc_userspace_memory: %s", 
strerror(errno));
-               return -1;
-       }
-
-       low_memory.userspace_addr = (unsigned long)*vm_mem;
-       low_memory.slot = get_free_slot(kvm);
-       /* 640K should be enough. */
-       r = ioctl(kvm->vm_fd, KVM_SET_USER_MEMORY_REGION, &low_memory);
-       if (r == -1) {
-               fprintf(stderr, "kvm_create_memory_region: %m\n");
-               return -1;
-       }
-       register_slot(low_memory.slot, low_memory.guest_phys_addr,
-                     low_memory.memory_size, 1, low_memory.userspace_addr);
-
-       if (extended_memory.memory_size) {
-               r = munmap(*vm_mem + dosmem, exmem - dosmem);
-               if (r == -1) {
-                       fprintf(stderr, "kvm_alloc_userspace_memory: %s",
-                                                       strerror(errno));
-                       return -1;
-               }
-               extended_memory.userspace_addr = (unsigned long)(*vm_mem + 
exmem);
-               if (tss_ext > 0)
-                       extended_memory.slot = get_free_slot(kvm);
-               else
-                       extended_memory.slot = 0;
-               r = ioctl(kvm->vm_fd, KVM_SET_USER_MEMORY_REGION, 
&extended_memory);
-               if (r == -1) {
-                       fprintf(stderr, "kvm_create_memory_region: %m\n");
-                       return -1;
-               }
-               register_slot(extended_memory.slot,
-                             extended_memory.guest_phys_addr,
-                             extended_memory.memory_size, 1,
-                             extended_memory.userspace_addr);
-       }
-
-       if (above_4g_memory.memory_size) {
-               r = munmap(*vm_mem + pcimem, 0x100000000ULL - pcimem);
-               if (r == -1) {
-                       fprintf(stderr, "kvm_alloc_userspace_memory: %s",
-                                                       strerror(errno));
-                       return -1;
-               }
-               above_4g_memory.userspace_addr = (unsigned long)(*vm_mem + 
0x100000000ULL);
-               above_4g_memory.slot = get_free_slot(kvm);
-               r = ioctl(kvm->vm_fd, KVM_SET_USER_MEMORY_REGION, 
&above_4g_memory);
-               if (r == -1) {
-                       fprintf(stderr, "kvm_create_memory_region: %m\n");
-                       return -1;
-               }
-               register_slot(above_4g_memory.slot,
-                             above_4g_memory.guest_phys_addr,
-                             above_4g_memory.memory_size, 1,
-                             above_4g_memory.userspace_addr);
-       }
-
-       return 0;
-}
-
-#endif
-
 int kvm_set_tss_addr(kvm_context_t kvm, unsigned long addr)
 {
 #ifdef KVM_CAP_SET_TSS_ADDR
diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
index 5caa96d..351d513 100644
--- a/libkvm/libkvm.c
+++ b/libkvm/libkvm.c
@@ -348,7 +348,7 @@ static int kvm_create_default_phys_mem(kvm_context_t kvm,
 #ifdef KVM_CAP_USER_MEMORY
        r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_USER_MEMORY);
        if (r > 0)
-               r = kvm_alloc_userspace_memory(kvm, memory, vm_mem);
+               return 0;
        else
 #endif
                r = kvm_alloc_kernel_memory(kvm, memory, vm_mem);
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 564aafe..6c71b09 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -697,9 +697,9 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, 
int boot_device,
     qemu_irq *cpu_irq;
     qemu_irq *i8259;
 
-    if (ram_size + (phys_ram_size - ram_size) >= 0xe0000000 ) {
+    if (ram_size >= 0xe0000000 ) {
         above_4g_mem_size = ram_size - 0xe0000000;
-        ram_size = 0xe0000000 - (phys_ram_size - ram_size);
+        ram_size = 0xe0000000;
     }
 
     linux_boot = (kernel_filename != NULL);
@@ -722,9 +722,23 @@ static void pc_init1(ram_addr_t ram_size, int 
vga_ram_size, int boot_device,
     }
 
     /* allocate RAM */
-    ram_addr = qemu_ram_alloc(ram_size);
-    cpu_register_physical_memory(0, ram_size, ram_addr);
-
+#ifdef USE_KVM
+ #ifdef KVM_CAP_USER_MEMORY
+    if (kvm_allowed && kvm_qemu_check_extension(KVM_CAP_USER_MEMORY)) {
+        ram_addr = qemu_ram_alloc(ram_size - 0x100000);
+        cpu_register_physical_memory(0x100000, ram_size - 0x100000, ram_addr);
+        kvm_cpu_register_physical_memory(0x100000, ram_size - 0x100000,
+                                         ram_addr);
+        ram_addr = qemu_ram_alloc(0xa0000);
+        cpu_register_physical_memory(0, 0xa0000, ram_addr);
+        kvm_cpu_register_physical_memory(0, 0xa0000, ram_addr);
+    } else
+ #endif
+#endif
+    {
+        ram_addr = qemu_ram_alloc(ram_size);
+        cpu_register_physical_memory(0, ram_size, ram_addr);
+    }
     /* allocate VGA RAM */
     vga_ram_addr = qemu_ram_alloc(vga_ram_size);
 
@@ -765,6 +779,11 @@ static void pc_init1(ram_addr_t ram_size, int 
vga_ram_size, int boot_device,
     if (above_4g_mem_size > 0) {
         ram_addr = qemu_ram_alloc(above_4g_mem_size);
         cpu_register_physical_memory(0x100000000, above_4g_mem_size, ram_addr);
+#ifdef USE_KVM
+    if (kvm_allowed)
+        kvm_cpu_register_physical_memory(0x100000000, above_4g_mem_size,
+                                         ram_addr);
+#endif
     }
 
     /* setup basic memory access */
@@ -772,8 +791,8 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, 
int boot_device,
                                  vga_bios_offset | IO_MEM_ROM);
 #ifdef USE_KVM
     if (kvm_allowed)
-           memcpy(phys_ram_base + 0xc0000, phys_ram_base + vga_bios_offset,
-                  0x10000);
+        kvm_cpu_register_physical_memory(0xc0000, 0x10000,
+                                         vga_bios_offset | IO_MEM_ROM);
 #endif
 
     /* map the last 128KB of the BIOS in ISA space */
@@ -785,26 +804,13 @@ static void pc_init1(ram_addr_t ram_size, int 
vga_ram_size, int boot_device,
     cpu_register_physical_memory(0x100000 - isa_bios_size,
                                  isa_bios_size,
                                  (bios_offset + bios_size - isa_bios_size) | 
IO_MEM_ROM);
-
 #ifdef USE_KVM
     if (kvm_allowed)
-           memcpy(phys_ram_base + 0x100000 - isa_bios_size,
-                  phys_ram_base + (bios_offset + bios_size - isa_bios_size),
-                  isa_bios_size);
+        kvm_cpu_register_physical_memory(0x100000 - isa_bios_size,
+                                         isa_bios_size,
+                                         (bios_offset + bios_size - 
isa_bios_size) | IO_MEM_ROM);
 #endif
 
-#ifdef USE_KVM
-    if (kvm_allowed) {
-           bios_mem = kvm_create_phys_mem(kvm_context, (uint32_t)(-bios_size),
-                                          bios_size, 0, 1);
-           if (!bios_mem)
-                   exit(1);
-           memcpy(bios_mem, phys_ram_base + bios_offset, bios_size);
-
-           cpu_register_physical_memory(phys_ram_size - KVM_EXTRA_PAGES * 
4096, KVM_EXTRA_PAGES * 4096,
-                                        (phys_ram_size - KVM_EXTRA_PAGES * 
4096) | IO_MEM_ROM);
-    }
-#endif
 
     {
         ram_addr_t option_rom_offset;
@@ -830,9 +836,12 @@ static void pc_init1(ram_addr_t ram_size, int 
vga_ram_size, int boot_device,
             size = (size + 4095) & ~4095;
             cpu_register_physical_memory(0xd0000 + offset,
                                          size, option_rom_offset | IO_MEM_ROM);
-           if (kvm_allowed)
-               memcpy(phys_ram_base + 0xd0000 + offset,
-                      phys_ram_base + option_rom_offset, size);
+#ifdef USE_KVM
+            if (kvm_allowed)
+                kvm_cpu_register_physical_memory(0xd0000 + offset,
+                                             size, option_rom_offset |
+                                             IO_MEM_ROM);
+#endif
 
             offset += size;
         }
@@ -841,6 +850,25 @@ static void pc_init1(ram_addr_t ram_size, int 
vga_ram_size, int boot_device,
     /* map all the bios at the top of memory */
     cpu_register_physical_memory((uint32_t)(-bios_size),
                                  bios_size, bios_offset | IO_MEM_ROM);
+#ifdef USE_KVM
+    if (kvm_allowed) {
+        int r;
+#ifdef KVM_CAP_USER_MEMORY
+        r = kvm_qemu_check_extension(KVM_CAP_USER_MEMORY);
+        if (r)
+            kvm_cpu_register_physical_memory((uint32_t)(-bios_size),
+                                           bios_size, bios_offset | 
IO_MEM_ROM);
+        else
+#endif
+        {
+            bios_mem = kvm_create_phys_mem(kvm_context, (uint32_t)(-bios_size),
+                                           bios_size, 0, 1);
+           if (!bios_mem)
+                exit(1);
+            memcpy(bios_mem, phys_ram_base + bios_offset, bios_size);
+        }
+    }
+#endif
 
     bochs_bios_init();
 
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index 38ba5c3..716b8fb 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -1033,6 +1033,53 @@ void kvm_qemu_destroy(void)
     kvm_finalize(kvm_context);
 }
 
+void kvm_cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                      unsigned long size,
+                                      unsigned long phys_offset)
+{
+#ifdef KVM_CAP_USER_MEMORY
+    int r = 0;
+
+    r = kvm_check_extension(kvm_context, KVM_CAP_USER_MEMORY);
+    if (r) {
+        if (!(phys_offset & ~TARGET_PAGE_MASK)) {
+                r = kvm_is_allocated_mem(kvm_context, start_addr, size);
+            if (r)
+                return;
+            r = kvm_is_intersecting_mem(kvm_context, start_addr);
+            if (r)
+                kvm_create_mem_hole(kvm_context, start_addr, size);
+            r = kvm_register_userspace_phys_mem(kvm_context, start_addr,
+                                                phys_ram_base + phys_offset,
+                                                size, 1);
+        }
+        if (phys_offset & IO_MEM_ROM) {
+            phys_offset &= ~IO_MEM_ROM;
+            r = kvm_is_intersecting_mem(kvm_context, start_addr);
+            if (r)
+                kvm_create_mem_hole(kvm_context, start_addr, size);
+            r = kvm_register_userspace_phys_mem(kvm_context, start_addr,
+                                                phys_ram_base + phys_offset,
+                                                size, 1);
+        }
+        if (r < 0) {
+            printf("kvm_cpu_register_physical_memory: failed\n");
+            exit(1);
+        }
+        return;
+    }
+#endif
+    if (phys_offset & IO_MEM_ROM) {
+        phys_offset &= ~IO_MEM_ROM;
+        memcpy(phys_ram_base + start_addr, phys_ram_base + phys_offset, size);
+    }
+}
+
+int kvm_qemu_check_extension(int ext)
+{
+    return kvm_check_extension(kvm_context, ext);
+}
+
 static void host_cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx,
                       uint32_t *ecx, uint32_t *edx)
 {
diff --git a/qemu/vl.c b/qemu/vl.c
index 634fb34..70d8c81 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -8664,6 +8664,20 @@ int main(int argc, char **argv)
                    fprintf(stderr, "Could not create KVM context\n");
                    exit(1);
            }
+#ifdef KVM_CAP_USER_MEMORY
+{
+            int ret;
+
+            ret = kvm_qemu_check_extension(KVM_CAP_USER_MEMORY);
+            if (ret) {
+                phys_ram_base = qemu_vmalloc(phys_ram_size);
+               if (!phys_ram_base) {
+                       fprintf(stderr, "Could not allocate physical memory\n");
+                       exit(1);
+               }
+            }
+}
+#endif
     } else {
            phys_ram_base = qemu_vmalloc(phys_ram_size);
            if (!phys_ram_base) {

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
kvm-commits mailing list
kvm-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-commits

Reply via email to