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