public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* adding support for above 2giga to kvm (include patchs)
@ 2007-08-12 19:26 Izik Eidus
       [not found] ` <64F9B87B6B770947A9F8391472E032160CBECF3E-yEcIvxbTEBqsx+V+t5oei8rau4O3wl8o3fe8/T/H7NteoWH0uzbU5w@public.gmane.org>
  0 siblings, 1 reply; 20+ messages in thread
From: Izik Eidus @ 2007-08-12 19:26 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 986 bytes --]

this is a request for comment for patchs that allow kvm to run with more than 2 giga.
there are 4 patchs.
the first patch(biospatch): is for the bios:now the bios know how to map memory about the 0xf0000000-0xffffffff hole.

the second  patch(qemu_change_types_patch):is for qemu ram_size types:it change the variables that hold the ram_size to unsigned long,
and it is based on patch from the qemu-devel list that targeted sparc.

the third patch(kvm_userspace_memmap):is for kvm and add to it another memory slot that hold the new memory region.

the last patch(kvm_new_slot_patch):is for kvmctl, and make it use the new memory region and map memory above 4giga to it.

i added compiled bios for to make it easy to run it.

(kvm was tested with 14giga of ram and had no problem to drive win3k and fedora 6 + x ,please note that i tryed in the patch to add support to the qemu emulator to run with above 4 giga as well,
it work without svga, need some work to do there)

[-- Attachment #1.2: Type: text/html, Size: 1444 bytes --]

[-- Attachment #2: bios.bin --]
[-- Type: application/octet-stream, Size: 131072 bytes --]

[-- Attachment #3: qemu_change_types_patch --]
[-- Type: application/octet-stream, Size: 8577 bytes --]

diff --git a/qemu/cpu-all.h b/qemu/cpu-all.h
index a325e05..90e4351 100644
--- a/qemu/cpu-all.h
+++ b/qemu/cpu-all.h
@@ -822,7 +822,7 @@ int cpu_inl(CPUState *env, int addr);
 
 /* memory API */
 
-extern int phys_ram_size;
+extern unsigned long phys_ram_size;
 extern int phys_ram_fd;
 extern uint8_t *phys_ram_base;
 extern uint8_t *phys_ram_dirty;
diff --git a/qemu/exec.c b/qemu/exec.c
index 2b050d1..f5cce06 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -85,7 +85,7 @@ spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
 uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32)));
 uint8_t *code_gen_ptr;
 
-int phys_ram_size;
+unsigned long phys_ram_size;
 int phys_ram_fd;
 uint8_t *phys_ram_base;
 uint8_t *phys_ram_dirty;
@@ -111,7 +111,7 @@ typedef struct PageDesc {
 
 typedef struct PhysPageDesc {
     /* offset in host memory of the page + io_index in the low 12 bits */
-    uint32_t phys_offset;
+    unsigned long phys_offset;
 } PhysPageDesc;
 
 #define L2_BITS 10
diff --git a/qemu/hw/i8524patch b/qemu/hw/i8524patch
deleted file mode 100644
index 5cc1a9b..0000000
--- a/qemu/hw/i8524patch
+++ /dev/null
@@ -1,37 +0,0 @@
---- oldi8254.c	2007-08-11 12:14:15.000000000 +0300
-+++ i8254.c	2007-08-11 12:10:02.000000000 +0300
-@@ -357,9 +357,6 @@
-     return ret;
- }
- 
--/* global counters for time-drift fix */
--int64_t timer_acks=0, timer_interrupts=0, timer_ints_to_push=0;
--
- static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
- {
-     int64_t expire_time;
-@@ -370,24 +367,6 @@
-     expire_time = pit_get_next_transition_time(s, current_time);
-     irq_level = pit_get_out1(s, current_time);
-     pic_set_irq(s->irq, irq_level);
--    if (time_drift_fix && irq_level==1) {
--        /* FIXME: fine tune timer_max_fix (max fix per tick). 
--         *        Should it be 1 (double time), 2 , 4, 10 ? 
--         *        Currently setting it to 5% of PIT-ticks-per-second (per PIT-tick)
--         */
--        const long pit_ticks_per_sec = (s->count>0) ? (PIT_FREQ/s->count) : 0;
--        const long timer_max_fix = pit_ticks_per_sec/20;
--        const long delta = timer_interrupts - timer_acks;
--        const long max_delta = pit_ticks_per_sec * 60; /* one minute */
--        if ((delta >  max_delta) && (pit_ticks_per_sec > 0)) {
--            printf("time drift is too long, %ld seconds were lost\n", delta/pit_ticks_per_sec);
--            timer_acks = timer_interrupts;
--            timer_ints_to_push = 0;
--        } else if (delta > 0) {
--            timer_ints_to_push = MIN(delta, timer_max_fix);
--        }
--        timer_interrupts++;
--    }
- #ifdef DEBUG_PIT
-     printf("irq_level=%d next_delay=%f\n",
-            irq_level, 
diff --git a/qemu/hw/i8529patch b/qemu/hw/i8529patch
deleted file mode 100644
index e295094..0000000
--- a/qemu/hw/i8529patch
+++ /dev/null
@@ -1,55 +0,0 @@
---- oldi8259.c	2007-08-11 12:14:05.000000000 +0300
-+++ i8259.c	2007-08-11 12:10:02.000000000 +0300
-@@ -67,6 +67,8 @@
- static uint64_t irq_count[16];
- #endif
- 
-+unsigned int lost_ticks;
-+
- /* set irq level. If an edge is detected, then the IRR is set to 1 */
- static inline void pic_set_irq1(PicState *s, int irq, int level)
- {
-@@ -137,6 +139,14 @@
- {
-     int irq2, irq;
- 
-+    if(lost_ticks > 0) {
-+        pic_set_irq1(&s->pics[0], 0, 0);
-+        pic_set_irq1(&s->pics[0], 0, 1);
-+        s->irq_request(s->irq_request_opaque, 1);
-+        lost_ticks--;
-+        return;
-+    }
-+
-     /* first look at slave pic */
-     irq2 = pic_get_irq(&s->pics[1]);
-     if (irq2 >= 0) {
-@@ -178,6 +188,11 @@
- {
-     PicState2 *s = opaque;
- 
-+    if (irq == 0 && (s->pics[0].irr & 1) == 1 && ~s->pics[0].imr & 1 == 1) {
-+        lost_ticks++;
-+        return;
-+    }
-+
- #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
-     if (level != irq_level[irq]) {
- #if defined(DEBUG_PIC)
-@@ -220,16 +235,6 @@
-     /* We don't clear a level sensitive interrupt here */
-     if (!(s->elcr & (1 << irq)))
-         s->irr &= ~(1 << irq);
--
--    if (time_drift_fix && irq == 0) {
--        extern int64_t timer_acks, timer_ints_to_push;
--        timer_acks++;
--        if (timer_ints_to_push > 0) {
--            timer_ints_to_push--;
--            pic_set_irq(0, 0); /* set it low (edge irq)*/
--            pic_set_irq(0, 1); /* interrupt again */
--        }
--    }
- }
- 
- int pic_read_irq(PicState2 *s)
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index ae92173..7bec234 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -163,7 +163,7 @@ static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd)
 }
 
 /* hd_table must contain 4 block drivers */
-static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table)
+static void cmos_init(unsigned long ram_size, int boot_device, BlockDriverState **hd_table)
 {
     RTCState *s = rtc_state;
     int val;
@@ -457,7 +457,7 @@ extern int kvm_allowed;
 #endif
 
 /* PC hardware initialisation */
-static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
+static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
                      DisplayState *ds, const char **fd_filename, int snapshot,
                      const char *kernel_filename, const char *kernel_cmdline,
                      const char *initrd_filename,
@@ -794,7 +794,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
 #endif
 }
 
-static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device,
+static void pc_init_pci(unsigned long ram_size, int vga_ram_size, int boot_device,
                         DisplayState *ds, const char **fd_filename, 
                         int snapshot, 
                         const char *kernel_filename, 
@@ -807,7 +807,7 @@ static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device,
              initrd_filename, 1);
 }
 
-static void pc_init_isa(int ram_size, int vga_ram_size, int boot_device,
+static void pc_init_isa(unsigned long ram_size, int vga_ram_size, int boot_device,
                         DisplayState *ds, const char **fd_filename, 
                         int snapshot, 
                         const char *kernel_filename, 
diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c
index fcb19b0..c1edd88 100644
--- a/qemu/hw/vga.c
+++ b/qemu/hw/vga.c
@@ -1399,10 +1399,11 @@ extern int kvm_allowed;
 static void vga_draw_graphic(VGAState *s, int full_update)
 {
     int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask;
-    int width, height, shift_control, line_offset, page0, page1, bwidth;
+    int width, height, shift_control, line_offset, bwidth;
     int disp_width, multi_scan, multi_run;
     uint8_t *d;
     uint32_t v, addr1, addr;
+    unsigned long page0, page1;
     vga_draw_line_func *vga_draw_line;
     
 #ifdef USE_KVM
diff --git a/qemu/vl.c b/qemu/vl.c
index b14233c..5dd6eec 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -101,8 +101,11 @@
 
 //#define DEBUG_UNUSED_IOPORT
 //#define DEBUG_IOPORT
-
+#if HOST_LONG_BITS < 64
 #define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
+#else
+#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024 * 1024ULL)
+#endif
 
 #ifdef TARGET_PPC
 #define DEFAULT_RAM_SIZE 144
@@ -135,7 +138,7 @@ int nographic;
 const char* keyboard_layout = NULL;
 int64_t ticks_per_sec;
 int boot_device = 'c';
-int ram_size;
+unsigned long ram_size;
 int pit_min_timer_count = 0;
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
@@ -7182,7 +7185,7 @@ int main(int argc, char **argv)
                 help();
                 break;
             case QEMU_OPTION_m:
-                ram_size = atoi(optarg) * 1024 * 1024;
+                ram_size = (unsigned long)atoi(optarg) * 1024 * 1024;
                 if (ram_size <= 0)
                     help();
                 if (ram_size > PHYS_RAM_MAX_SIZE) {
diff --git a/qemu/vl.h b/qemu/vl.h
index 43f56bd..d35b47f 100644
--- a/qemu/vl.h
+++ b/qemu/vl.h
@@ -153,7 +153,7 @@ void qemu_system_powerdown(void);
 
 void main_loop_wait(int timeout);
 
-extern int ram_size;
+extern unsigned long ram_size;
 extern int bios_size;
 extern int rtc_utc;
 extern int cirrus_vga_enabled;
@@ -716,7 +716,7 @@ void path_combine(char *dest, int dest_size,
 
 #ifndef QEMU_TOOL
 
-typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size, 
+typedef void QEMUMachineInitFunc(unsigned long ram_size, int vga_ram_size, 
                                  int boot_device,
              DisplayState *ds, const char **fd_filename, int snapshot,
              const char *kernel_filename, const char *kernel_cmdline,

[-- Attachment #4: kvm_new_slot_patch --]
[-- Type: application/octet-stream, Size: 796 bytes --]

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index fc27c2f..ac3fa1c 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -39,7 +39,7 @@
 
 #define KVM_MAX_VCPUS 4
 #define KVM_ALIAS_SLOTS 4
-#define KVM_MEMORY_SLOTS 4
+#define KVM_MEMORY_SLOTS 5
 #define KVM_NUM_MMU_PAGES 1024
 #define KVM_MIN_FREE_MMU_PAGES 5
 #define KVM_REFILL_PAGES 25
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index dac2f93..1613f23 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -905,7 +905,7 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
 	vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
 }
 
-static int rmode_tss_base(struct kvm* kvm)
+static gva_t rmode_tss_base(struct kvm* kvm)
 {
 	gfn_t base_gfn = kvm->memslots[0].base_gfn + kvm->memslots[0].npages - 3;
 	return base_gfn << PAGE_SHIFT;

[-- Attachment #5: biospatch --]
[-- Type: application/octet-stream, Size: 6922 bytes --]

--- rombios.c	2007-08-01 20:09:51.000000000 +0300
+++ newbios.c	2007-08-08 15:26:59.000000000 +0300
@@ -4077,24 +4077,32 @@
 }
 #endif
 
+struct MemoryMap {
+    Bit32u start;
+    Bit16u extra_start;
+    Bit32u end;
+    Bit8u extra_end;
+};
+
+typedef struct MemoryMap *MemoryMap_t;
 
-void set_e820_range(ES, DI, start, end, type)
+void set_e820_range(ES, DI, MemMap, type)
      Bit16u ES;
      Bit16u DI;
-     Bit32u start;
-     Bit32u end;
+     MemoryMap_t MemMap;
      Bit16u type;
 {
-    write_word(ES, DI, start);
-    write_word(ES, DI+2, start >> 16);
-    write_word(ES, DI+4, 0x00);
-    write_word(ES, DI+6, 0x00);
-
-    end -= start;
-    write_word(ES, DI+8, end);
-    write_word(ES, DI+10, end >> 16);
-    write_word(ES, DI+12, 0x0000);
-    write_word(ES, DI+14, 0x0000);
+    write_word(ES, DI, MemMap->start);
+    write_word(ES, DI+2, MemMap->start >> 16);
+    write_word(ES, DI+4, MemMap->extra_start);
+    write_word(ES, DI+6, 0x0);
+
+    MemMap->end -= MemMap->start;
+    MemMap->extra_end -= MemMap->extra_start;
+    write_word(ES, DI+8, MemMap->end);
+    write_word(ES, DI+10, MemMap->end >> 16);
+    write_word(ES, DI+12, MemMap->extra_end);
+    write_word(ES, DI+14, 0x0);
 
     write_word(ES, DI+16, type);
     write_word(ES, DI+18, 0x0);
@@ -4105,8 +4113,12 @@
   pushad_regs_t regs; // REGS pushed via pushad
   Bit16u ES, DS, FLAGS;
 {
+  struct MemoryMap MemMap;
+	char x1,x2;
   Bit32u  extended_memory_size=0; // 64bits long
+  Bit32u  extra_lowbits_memory_size=0;
   Bit16u  CX,DX;
+  Bit8u  extra_highbits_memory_size=0;
 
 BX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax);
 
@@ -4179,11 +4191,21 @@
                     extended_memory_size *= 1024;
                 }
 
-                switch(regs.u.r16.bx)
+                extra_lowbits_memory_size = inb_cmos(0x5c);
+		extra_lowbits_memory_size <<= 8;
+		extra_lowbits_memory_size |= inb_cmos(0x5b);
+		extra_lowbits_memory_size *= 64;
+		extra_lowbits_memory_size *= 1024;
+		extra_highbits_memory_size = inb_cmos(0x5d);
+                
+		switch(regs.u.r16.bx)
                 {
                     case 0:
-                        set_e820_range(ES, regs.u.r16.di,
-                                       0x0000000L, 0x0009fc00L, 1);
+                        MemMap.start = 0x0000000L;
+                        MemMap.extra_start = 0;
+                        MemMap.end = 0x0009fc00L;
+                        MemMap.extra_end = 0;
+                        set_e820_range(ES, regs.u.r16.di, &MemMap, 1);
                         regs.u.r32.ebx = 1;
                         regs.u.r32.eax = 0x534D4150;
                         regs.u.r32.ecx = 0x14;
@@ -4191,8 +4213,11 @@
                         return;
                         break;
                     case 1:
-                        set_e820_range(ES, regs.u.r16.di,
-                                       0x0009fc00L, 0x000a0000L, 2);
+                        MemMap.start = 0x0009fc00L;
+                        MemMap.extra_start = 0;
+                        MemMap.end = 0x000a0000L;
+                        MemMap.extra_end = 0;
+                        set_e820_range(ES, regs.u.r16.di, &MemMap, 2);
                         regs.u.r32.ebx = 2;
                         regs.u.r32.eax = 0x534D4150;
                         regs.u.r32.ecx = 0x14;
@@ -4200,8 +4225,11 @@
                         return;
                         break;
                     case 2:
-                        set_e820_range(ES, regs.u.r16.di,
-                                       0x000e8000L, 0x00100000L, 2);
+                        MemMap.start = 0x000e8000L;
+                        MemMap.extra_start = 0;
+                        MemMap.end = 0x00100000L;
+                        MemMap.extra_end = 0;
+                        set_e820_range(ES, regs.u.r16.di, &MemMap, 2);
                         regs.u.r32.ebx = 3;
                         regs.u.r32.eax = 0x534D4150;
                         regs.u.r32.ecx = 0x14;
@@ -4209,9 +4237,12 @@
                         return;
                         break;
                     case 3:
+                        MemMap.start = 0x00100000L;
+                        MemMap.extra_start = 0;
+                        MemMap.end = extended_memory_size - ACPI_DATA_SIZE;
+                        MemMap.extra_end = 0;
                         set_e820_range(ES, regs.u.r16.di,
-                                       0x00100000L,
-                                       extended_memory_size - ACPI_DATA_SIZE, 1);
+                                       &MemMap, 1);
                         regs.u.r32.ebx = 4;
                         regs.u.r32.eax = 0x534D4150;
                         regs.u.r32.ecx = 0x14;
@@ -4219,9 +4250,12 @@
                         return;
                         break;
                     case 4:
+                        MemMap.start = extended_memory_size - ACPI_DATA_SIZE;
+                        MemMap.extra_start = 0;
+                        MemMap.end = extended_memory_size;
+                        MemMap.extra_end = 0;
                         set_e820_range(ES, regs.u.r16.di,
-                                       extended_memory_size - ACPI_DATA_SIZE,
-                                       extended_memory_size, 3); // ACPI RAM
+                                       &MemMap, 3); // ACPI RAM
                         regs.u.r32.ebx = 5;
                         regs.u.r32.eax = 0x534D4150;
                         regs.u.r32.ecx = 0x14;
@@ -4230,8 +4264,26 @@
                         break;
                     case 5:
                         /* 256KB BIOS area at the end of 4 GB */
-                        set_e820_range(ES, regs.u.r16.di,
-                                       0xfffc0000L, 0x00000000L, 2);
+			MemMap.start = 0xfffc0000L;
+                        MemMap.extra_start = 0;
+                        MemMap.end = 0x00000000L;
+                        MemMap.extra_end = 0;
+                        set_e820_range(ES, regs.u.r16.di, &MemMap, 2);
+			if (extra_highbits_memory_size || extra_lowbits_memory_size)
+                        	regs.u.r32.ebx = 6;
+			else 
+				regs.u.r32.ebx = 0;
+                        regs.u.r32.eax = 0x534D4150;
+                        regs.u.r32.ecx = 0x14;
+                        CLEAR_CF();
+                        return;
+                    case 6:
+                        /* Maping of memory above 4 GB */
+                        MemMap.start = 0x0;
+                        MemMap.extra_start = 0x1;
+                        MemMap.end = extra_lowbits_memory_size + MemMap.start;
+                        MemMap.extra_end = extra_highbits_memory_size + MemMap.extra_start;
+			set_e820_range(ES, regs.u.r16.di, &MemMap, 1);
                         regs.u.r32.ebx = 0;
                         regs.u.r32.eax = 0x534D4150;
                         regs.u.r32.ecx = 0x14;

[-- Attachment #6: kvm_userspace_memmap --]
[-- Type: application/octet-stream, Size: 12518 bytes --]

diff --git a/qemu/exec.c b/qemu/exec.c
index f5cce06..e54711e 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -69,7 +69,7 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 42
 #else
 /* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#define TARGET_PHYS_ADDR_SPACE_BITS 42
 #endif
 
 #ifdef USE_KVM
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 7bec234..f938fd0 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -163,16 +163,18 @@ static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd)
 }
 
 /* hd_table must contain 4 block drivers */
-static void cmos_init(unsigned long ram_size, int boot_device, BlockDriverState **hd_table)
+static void cmos_init(unsigned long ram_size, unsigned long above_bios_ram_size, int boot_device, BlockDriverState **hd_table)
 {
     RTCState *s = rtc_state;
     int val;
     int fd0, fd1, nb;
     int i;
+    unsigned long above_bios_mem_bits;
 
     /* various important CMOS locations needed by PC/Bochs bios */
 
     /* memory size */
+    if (ram_size > 0xf0000000)
     val = 640; /* base memory in K */
     rtc_set_memory(s, 0x15, val);
     rtc_set_memory(s, 0x16, val >> 8);
@@ -184,7 +186,12 @@ static void cmos_init(unsigned long ram_size, int boot_device, BlockDriverState
     rtc_set_memory(s, 0x18, val >> 8);
     rtc_set_memory(s, 0x30, val);
     rtc_set_memory(s, 0x31, val >> 8);
-
+    
+    val = (unsigned int)above_bios_ram_size / 65536;
+    rtc_set_memory(s, 0x5b, val);
+    rtc_set_memory(s, 0x5c, val >> 8);
+    rtc_set_memory(s, 0x5d, above_bios_ram_size/0x100000000);
+    
     if (ram_size > (16 * 1024 * 1024))
         val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
     else
@@ -465,14 +472,17 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
 {
     char buf[1024];
     int ret, linux_boot, initrd_size, i;
-    unsigned long bios_offset, vga_bios_offset, option_rom_offset;
+    unsigned long bios_offset, vga_bios_offset, option_rom_offset, above_bios_mem_size = 0;
     ram_addr_t initrd_offset;
     int bios_size, isa_bios_size;
     PCIBus *pci_bus;
     int piix3_devfn = -1;
     CPUState *env;
     NICInfo *nd;
-
+    if (ram_size + (phys_ram_size - ram_size) >= 0xf0000000 ) {
+        above_bios_mem_size = ram_size - 0xf0000000;;
+       	ram_size = 0xf0000000 - (phys_ram_size - ram_size);
+    }
     linux_boot = (kernel_filename != NULL);
 
     /* init CPUs */
@@ -492,7 +502,9 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
     }
 
     /* allocate RAM */
-    cpu_register_physical_memory(0, ram_size, 0);
+    cpu_register_physical_memory(0, ram_size , 0);
+    if (above_bios_mem_size > 0)
+        cpu_register_physical_memory(0x100000000, above_bios_mem_size , 0x0);
 
     /* BIOS load */
     bios_offset = ram_size + vga_ram_size;
@@ -668,11 +680,10 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
     register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
 
     register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
-
     if (cirrus_vga_enabled) {
         if (pci_enabled) {
             pci_cirrus_vga_init(pci_bus, 
-                                ds, phys_ram_base + ram_size, ram_size, 
+                                ds, phys_ram_base + ram_size , ram_size, 
                                 vga_ram_size);
         } else {
             isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size, 
@@ -687,7 +698,6 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
                          vga_ram_size);
         }
     }
-
     rtc_state = rtc_init(0x70, 8);
 
     register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
@@ -756,7 +766,7 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
 
     floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
 
-    cmos_init(ram_size, boot_device, bs_table);
+    cmos_init(ram_size , above_bios_mem_size, boot_device, bs_table);
 
     if (pci_enabled && usb_enabled) {
         usb_uhci_init(pci_bus, piix3_devfn + 2);
@@ -0,0 +1,178 @@
+diff --git a/qemu/exec.c b/qemu/exec.c
+index f5cce06..e54711e 100644
+--- a/qemu/exec.c
++++ b/qemu/exec.c
+@@ -69,7 +69,7 @@
+ #define TARGET_PHYS_ADDR_SPACE_BITS 42
+ #else
+ /* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
+-#define TARGET_PHYS_ADDR_SPACE_BITS 32
++#define TARGET_PHYS_ADDR_SPACE_BITS 42
+ #endif
+ 
+ #ifdef USE_KVM
+diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
+index 7bec234..f938fd0 100644
+--- a/qemu/hw/pc.c
++++ b/qemu/hw/pc.c
+@@ -163,16 +163,18 @@ static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd)
+ }
+ 
+ /* hd_table must contain 4 block drivers */
+-static void cmos_init(unsigned long ram_size, int boot_device, BlockDriverState **hd_table)
++static void cmos_init(unsigned long ram_size, unsigned long above_bios_ram_size, int boot_device, BlockDriverState **hd_table)
+ {
+     RTCState *s = rtc_state;
+     int val;
+     int fd0, fd1, nb;
+     int i;
++    unsigned long above_bios_mem_bits;
+ 
+     /* various important CMOS locations needed by PC/Bochs bios */
+ 
+     /* memory size */
++    if (ram_size > 0xf0000000)
+     val = 640; /* base memory in K */
+     rtc_set_memory(s, 0x15, val);
+     rtc_set_memory(s, 0x16, val >> 8);
+@@ -184,7 +186,12 @@ static void cmos_init(unsigned long ram_size, int boot_device, BlockDriverState
+     rtc_set_memory(s, 0x18, val >> 8);
+     rtc_set_memory(s, 0x30, val);
+     rtc_set_memory(s, 0x31, val >> 8);
+-
++    
++    val = (unsigned int)above_bios_ram_size / 65536;
++    rtc_set_memory(s, 0x5b, val);
++    rtc_set_memory(s, 0x5c, val >> 8);
++    rtc_set_memory(s, 0x5d, above_bios_ram_size/0x100000000);
++    
+     if (ram_size > (16 * 1024 * 1024))
+         val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
+     else
+@@ -465,14 +472,17 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
+ {
+     char buf[1024];
+     int ret, linux_boot, initrd_size, i;
+-    unsigned long bios_offset, vga_bios_offset, option_rom_offset;
++    unsigned long bios_offset, vga_bios_offset, option_rom_offset, above_bios_mem_size = 0;
+     ram_addr_t initrd_offset;
+     int bios_size, isa_bios_size;
+     PCIBus *pci_bus;
+     int piix3_devfn = -1;
+     CPUState *env;
+     NICInfo *nd;
+-
++    if (ram_size + (phys_ram_size - ram_size) >= 0xf0000000 ) {
++        above_bios_mem_size = ram_size - 0xf0000000;;
++       	ram_size = 0xf0000000 - (phys_ram_size - ram_size);
++    }
+     linux_boot = (kernel_filename != NULL);
+ 
+     /* init CPUs */
+@@ -492,7 +502,9 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
+     }
+ 
+     /* allocate RAM */
+-    cpu_register_physical_memory(0, ram_size, 0);
++    cpu_register_physical_memory(0, ram_size , 0);
++    if (above_bios_mem_size > 0)
++        cpu_register_physical_memory(0x100000000, above_bios_mem_size , 0x0);
+ 
+     /* BIOS load */
+     bios_offset = ram_size + vga_ram_size;
+@@ -668,11 +680,10 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
+     register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
+ 
+     register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
+-
+     if (cirrus_vga_enabled) {
+         if (pci_enabled) {
+             pci_cirrus_vga_init(pci_bus, 
+-                                ds, phys_ram_base + ram_size, ram_size, 
++                                ds, phys_ram_base + ram_size , ram_size, 
+                                 vga_ram_size);
+         } else {
+             isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size, 
+@@ -687,7 +698,6 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
+                          vga_ram_size);
+         }
+     }
+-
+     rtc_state = rtc_init(0x70, 8);
+ 
+     register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
+@@ -756,7 +766,7 @@ static void pc_init1(unsigned long ram_size, int vga_ram_size, int boot_device,
+ 
+     floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
+ 
+-    cmos_init(ram_size, boot_device, bs_table);
++    cmos_init(ram_size , above_bios_mem_size, boot_device, bs_table);
+ 
+     if (pci_enabled && usb_enabled) {
+         usb_uhci_init(pci_bus, piix3_devfn + 2);
+diff --git a/qemu/vl.c b/qemu/vl.c
+index 5dd6eec..b7d4c9f 100644
+--- a/qemu/vl.c
++++ b/qemu/vl.c
+@@ -7546,6 +7546,7 @@ int main(int argc, char **argv)
+ 		    exit(1);
+ 	    }
+     } else {
++		phys_ram_size += KVM_EXTRA_PAGES * 4096;
+ 	    phys_ram_base = qemu_vmalloc(phys_ram_size);
+ 	    if (!phys_ram_base) {
+ 		    fprintf(stderr, "Could not allocate physical memory\n");
+diff --git a/user/kvmctl.c b/user/kvmctl.c
+index 43b374d..b07f8a8 100644
+--- a/user/kvmctl.c
++++ b/user/kvmctl.c
+@@ -43,7 +43,7 @@ static int kvm_abi = EXPECTED_KVM_API_VERSION;
+ 
+ /* FIXME: share this number with kvm */
+ /* FIXME: or dynamically alloc/realloc regions */
+-#define KVM_MAX_NUM_MEM_REGIONS 4u
++#define KVM_MAX_NUM_MEM_REGIONS 5u
+ #define MAX_VCPUS 4
+ 
+ /**
+@@ -236,6 +236,7 @@ int kvm_create(kvm_context_t kvm, unsigned long memory, void **vm_mem)
+ {
+ 	unsigned long dosmem = 0xa0000;
+ 	unsigned long exmem = 0xc0000;
++	unsigned long pcimem = 0xf0000000;
+ 	int fd = kvm->fd;
+ 	int zfd;
+ 	int r;
+@@ -249,6 +250,14 @@ int kvm_create(kvm_context_t kvm, unsigned long memory, void **vm_mem)
+ 		.memory_size = memory < exmem ? 0 : memory - exmem,
+ 		.guest_phys_addr = exmem,
+ 	};
++	struct kvm_memory_region above_bios_memory = {
++		.slot = 4,
++		.memory_size = memory < pcimem ? 0 : memory - pcimem,
++		.guest_phys_addr = 0x100000000,
++	};
++
++	if (extended_memory.memory_size > pcimem)
++		extended_memory.memory_size = pcimem - exmem;
+ 
+ 	kvm->vcpu_fd[0] = -1;
+ 
+@@ -273,8 +282,17 @@ int kvm_create(kvm_context_t kvm, unsigned long memory, void **vm_mem)
+ 		}
+ 	}
+ 
++	if (above_bios_memory.memory_size) {
++		r = ioctl(fd, KVM_SET_MEMORY_REGION, &above_bios_memory);
++		if (r == -1) {
++			fprintf(stderr, "kvm_create_memory_region: %m\n");
++			return -1;
++		}
++	}
++
+ 	kvm_memory_region_save_params(kvm, &low_memory);
+ 	kvm_memory_region_save_params(kvm, &extended_memory);
++	kvm_memory_region_save_params(kvm, &above_bios_memory);
+ 
+ 	*vm_mem = mmap(NULL, memory, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ 	if (*vm_mem == MAP_FAILED) {
diff --git a/qemu/vl.c b/qemu/vl.c
index 5dd6eec..b7d4c9f 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -7546,6 +7546,7 @@ int main(int argc, char **argv)
 		    exit(1);
 	    }
     } else {
+		phys_ram_size += KVM_EXTRA_PAGES * 4096;
 	    phys_ram_base = qemu_vmalloc(phys_ram_size);
 	    if (!phys_ram_base) {
 		    fprintf(stderr, "Could not allocate physical memory\n");
diff --git a/user/kvmctl.c b/user/kvmctl.c
index 43b374d..b07f8a8 100644
--- a/user/kvmctl.c
+++ b/user/kvmctl.c
@@ -43,7 +43,7 @@ static int kvm_abi = EXPECTED_KVM_API_VERSION;
 
 /* FIXME: share this number with kvm */
 /* FIXME: or dynamically alloc/realloc regions */
-#define KVM_MAX_NUM_MEM_REGIONS 4u
+#define KVM_MAX_NUM_MEM_REGIONS 5u
 #define MAX_VCPUS 4
 
 /**
@@ -236,6 +236,7 @@ int kvm_create(kvm_context_t kvm, unsigned long memory, void **vm_mem)
 {
 	unsigned long dosmem = 0xa0000;
 	unsigned long exmem = 0xc0000;
+	unsigned long pcimem = 0xf0000000;
 	int fd = kvm->fd;
 	int zfd;
 	int r;
@@ -249,6 +250,14 @@ int kvm_create(kvm_context_t kvm, unsigned long memory, void **vm_mem)
 		.memory_size = memory < exmem ? 0 : memory - exmem,
 		.guest_phys_addr = exmem,
 	};
+	struct kvm_memory_region above_bios_memory = {
+		.slot = 4,
+		.memory_size = memory < pcimem ? 0 : memory - pcimem,
+		.guest_phys_addr = 0x100000000,
+	};
+
+	if (extended_memory.memory_size > pcimem)
+		extended_memory.memory_size = pcimem - exmem;
 
 	kvm->vcpu_fd[0] = -1;
 
@@ -273,8 +282,17 @@ int kvm_create(kvm_context_t kvm, unsigned long memory, void **vm_mem)
 		}
 	}
 
+	if (above_bios_memory.memory_size) {
+		r = ioctl(fd, KVM_SET_MEMORY_REGION, &above_bios_memory);
+		if (r == -1) {
+			fprintf(stderr, "kvm_create_memory_region: %m\n");
+			return -1;
+		}
+	}
+
 	kvm_memory_region_save_params(kvm, &low_memory);
 	kvm_memory_region_save_params(kvm, &extended_memory);
+	kvm_memory_region_save_params(kvm, &above_bios_memory);
 
 	*vm_mem = mmap(NULL, memory, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
 	if (*vm_mem == MAP_FAILED) {

[-- Attachment #7: Type: text/plain, Size: 315 bytes --]

-------------------------------------------------------------------------
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/

[-- Attachment #8: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2007-08-15 10:09 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-12 19:26 adding support for above 2giga to kvm (include patchs) Izik Eidus
     [not found] ` <64F9B87B6B770947A9F8391472E032160CBECF3E-yEcIvxbTEBqsx+V+t5oei8rau4O3wl8o3fe8/T/H7NteoWH0uzbU5w@public.gmane.org>
2007-08-12 21:28   ` Luca Tettamanti
2007-08-12 21:56     ` adding support for above 2giga to kvm (includepatchs) Izik Eidus
2007-08-12 21:30   ` adding support for above 2giga to kvm (include patchs) Anthony Liguori
     [not found]     ` <64F9B87B6B770947A9F8391472E032160CBECF48@ehost011-8.exch011.intermedia.net>
2007-08-12 22:35       ` FW: adding support for above 2giga to kvm (includepatchs) Izik Eidus
2007-08-13 20:29   ` adding support for above 2giga to kvm (include patchs) Ryan Harper
     [not found]     ` <20070813202941.GB1228-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-08-14  2:22       ` Ryan Harper
     [not found]         ` <64F9B87B6B770947A9F8391472E032160CBECF4F@ehost011-8.exch011.intermedia.net>
2007-08-14  6:29           ` FW: " Izik Eidus
     [not found]           ` <20070814150937.GG1228@us.ibm.com>
     [not found]             ` <20070814150937.GG1228-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-08-14 15:47               ` Izik Eidus
     [not found]                 ` <1187106465.11302.27.camel-wV29XY6ncz+I84jL4+POOYeT0m0igiSA0E9HWUfgJXw@public.gmane.org>
2007-08-14 18:24                   ` Ryan Harper
     [not found]                     ` <20070814182454.GJ1228-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-08-14 18:58                       ` Izik Eidus
     [not found]                         ` <1187117890.14753.5.camel-wV29XY6ncz+I84jL4+POOYeT0m0igiSA0E9HWUfgJXw@public.gmane.org>
2007-08-14 19:26                           ` Ryan Harper
     [not found]                             ` <20070814192606.GL1228-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-08-14 19:40                               ` Izik Eidus
     [not found]                                 ` <1187120417.15054.12.camel-wV29XY6ncz+I84jL4+POOYeT0m0igiSA0E9HWUfgJXw@public.gmane.org>
2007-08-14 19:46                                   ` Ryan Harper
     [not found]                                     ` <20070814194613.GM1228-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-08-14 19:58                                       ` Izik Eidus
     [not found]                                         ` <1187121522.15054.22.camel-wV29XY6ncz+I84jL4+POOYeT0m0igiSA0E9HWUfgJXw@public.gmane.org>
2007-08-14 20:44                                           ` Ryan Harper
     [not found]                                             ` <20070814204420.GN1228-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-08-14 20:53                                               ` Izik Eidus
2007-08-14 22:21                                               ` Ryan Harper
     [not found]                                                 ` <20070814222150.GO1228-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-08-15  4:25                                                   ` Anthony Liguori
2007-08-15 10:09                                                   ` Izik Eidus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox