Index: ioemu/hw/cirrus_vga.c
===================================================================
--- ioemu.orig/hw/cirrus_vga.c	2007-05-03 09:56:32.000000000 +0100
+++ ioemu/hw/cirrus_vga.c	2007-05-03 10:07:53.000000000 +0100
@@ -28,6 +28,9 @@
  */
 #include "vl.h"
 #include "vga_int.h"
+#ifndef _WIN32
+#include <sys/mman.h>
+#endif
 
 /*
  * TODO:
@@ -231,6 +234,8 @@
     int cirrus_linear_io_addr;
     int cirrus_linear_bitblt_io_addr;
     int cirrus_mmio_io_addr;
+    unsigned long cirrus_lfb_addr;
+    unsigned long cirrus_lfb_end;
     uint32_t cirrus_addr_mask;
     uint32_t linear_mmio_mask;
     uint8_t cirrus_shadow_gr0;
@@ -267,6 +272,8 @@
     int last_hw_cursor_y_end;
     int real_vram_size; /* XXX: suppress that */
     CPUWriteMemoryFunc **cirrus_linear_write;
+    unsigned long map_addr;
+    unsigned long map_end;
 } CirrusVGAState;
 
 typedef struct PCICirrusVGAState {
@@ -276,6 +283,8 @@
 
 static uint8_t rop_to_index[256];
     
+void *shared_vram;
+
 /***************************************
  *
  *  prototypes.
@@ -2520,6 +2529,83 @@
     cirrus_linear_bitblt_writel,
 };
 
+static void *set_vram_mapping(unsigned long begin, unsigned long end)
+{
+    xen_pfn_t *extent_start = NULL;
+    unsigned long nr_extents;
+    void *vram_pointer = NULL;
+    int i;
+
+    /* align begin and end address */
+    begin = begin & TARGET_PAGE_MASK;
+    end = begin + VGA_RAM_SIZE;
+    end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
+    nr_extents = (end - begin) >> TARGET_PAGE_BITS;
+
+    extent_start = malloc(sizeof(xen_pfn_t) * nr_extents);
+    if (extent_start == NULL) {
+        fprintf(stderr, "Failed malloc on set_vram_mapping\n");
+        return NULL;
+    }
+
+    memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
+
+    for (i = 0; i < nr_extents; i++)
+        extent_start[i] = (begin + i * TARGET_PAGE_SIZE) >> TARGET_PAGE_BITS;
+
+    set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
+
+    vram_pointer = xc_map_foreign_batch(xc_handle, domid,
+                                        PROT_READ|PROT_WRITE,
+                                        extent_start, nr_extents);
+    if (vram_pointer == NULL) {
+        fprintf(logfile, "xc_map_foreign_batch vgaram returned error %d\n",
+                errno);
+        return NULL;
+    }
+
+    memset(vram_pointer, 0, nr_extents * TARGET_PAGE_SIZE);
+
+    free(extent_start);
+
+    return vram_pointer;
+}
+
+static int unset_vram_mapping(unsigned long begin, unsigned long end, 
+                              void *mapping)
+{
+    xen_pfn_t *extent_start = NULL;
+    unsigned long nr_extents;
+    int i;
+
+    /* align begin and end address */
+
+    end = begin + VGA_RAM_SIZE;
+    begin = begin & TARGET_PAGE_MASK;
+    end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
+    nr_extents = (end - begin) >> TARGET_PAGE_BITS;
+
+    extent_start = malloc(sizeof(xen_pfn_t) * nr_extents);
+
+    if (extent_start == NULL) {
+        fprintf(stderr, "Failed malloc on set_mm_mapping\n");
+        return -1;
+    }
+
+    /* Drop our own references to the vram pages */
+    munmap(mapping, nr_extents * TARGET_PAGE_SIZE);
+
+    /* Now drop the guest's mappings */
+    memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
+    for (i = 0; i < nr_extents; i++)
+        extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> TARGET_PAGE_BITS;
+    unset_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
+
+    free(extent_start);
+
+    return 0;
+}
+
 /* Compute the memory access functions */
 static void cirrus_update_memory_access(CirrusVGAState *s)
 {
@@ -2538,11 +2624,37 @@
         
 	mode = s->gr[0x05] & 0x7;
 	if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
+            if (s->cirrus_lfb_addr && s->cirrus_lfb_end && !s->map_addr) {
+                void *vram_pointer, *old_vram;
+
+                vram_pointer = set_vram_mapping(s->cirrus_lfb_addr,
+                                                s->cirrus_lfb_end);
+                if (!vram_pointer)
+                    fprintf(stderr, "NULL vram_pointer\n");
+                else {
+                    old_vram = vga_update_vram((VGAState *)s, vram_pointer,
+                                               VGA_RAM_SIZE);
+                    qemu_free(old_vram);
+                }
+                s->map_addr = s->cirrus_lfb_addr;
+                s->map_end = s->cirrus_lfb_end;
+            }
             s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
             s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
             s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
         } else {
         generic_io:
+            if (s->cirrus_lfb_addr && s->cirrus_lfb_end && s->map_addr) {
+                void *old_vram;
+
+                old_vram = vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
+
+                unset_vram_mapping(s->cirrus_lfb_addr,
+                                   s->cirrus_lfb_end, 
+                                   old_vram);
+
+                s->map_addr = s->map_end = 0;
+            }
             s->cirrus_linear_write[0] = cirrus_linear_writeb;
             s->cirrus_linear_write[1] = cirrus_linear_writew;
             s->cirrus_linear_write[2] = cirrus_linear_writel;
@@ -3136,6 +3248,13 @@
     /* XXX: add byte swapping apertures */
     cpu_register_physical_memory(addr, s->vram_size,
 				 s->cirrus_linear_io_addr);
+    s->cirrus_lfb_addr = addr;
+    s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
+
+    if (s->map_addr && (s->cirrus_lfb_addr != s->map_addr) &&
+        (s->cirrus_lfb_end != s->map_end))
+        fprintf(logfile, "cirrus vga map change while on lfb mode\n");
+
     cpu_register_physical_memory(addr + 0x1000000, 0x400000,
 				 s->cirrus_linear_bitblt_io_addr);
 }
Index: ioemu/hw/pc.c
===================================================================
--- ioemu.orig/hw/pc.c	2007-05-03 10:07:53.000000000 +0100
+++ ioemu/hw/pc.c	2007-05-03 10:07:53.000000000 +0100
@@ -790,14 +790,14 @@
     if (cirrus_vga_enabled) {
         if (pci_enabled) {
             pci_cirrus_vga_init(pci_bus, 
-                                ds, phys_ram_base + ram_size, ram_size, 
+                                ds, NULL, ram_size,
                                 vga_ram_size);
         } else {
-            isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size, 
+            isa_cirrus_vga_init(ds, NULL, ram_size,
                                 vga_ram_size);
         }
     } else {
-        vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, 
+        vga_initialize(pci_bus, ds, NULL, ram_size,
                        vga_ram_size, 0, 0);
     }
 
Index: ioemu/hw/vga.c
===================================================================
--- ioemu.orig/hw/vga.c	2007-05-03 10:07:52.000000000 +0100
+++ ioemu/hw/vga.c	2007-05-03 10:07:53.000000000 +0100
@@ -1858,6 +1858,7 @@
     /* TODO: add vbe support if enabled */
 }
 
+/* when used on xen environment, the vga_ram_base is not used */
 void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
                      unsigned long vga_ram_offset, int vga_ram_size)
 {
@@ -1888,7 +1889,7 @@
 
     vga_reset(s);
 
-    s->vram_ptr = vga_ram_base;
+    s->vram_ptr = qemu_malloc(vga_ram_size);
     s->vram_offset = vga_ram_offset;
     s->vram_size = vga_ram_size;
     s->ds = ds;
@@ -2002,6 +2003,31 @@
     return 0;
 }
 
+void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
+{
+    uint8_t *old_pointer;
+
+    if (s->vram_size != vga_ram_size) {
+        fprintf(stderr, "No support to change vga_ram_size\n");
+        return NULL;
+    }
+
+    if (!vga_ram_base) {
+        vga_ram_base = qemu_malloc(vga_ram_size);
+        if (!vga_ram_base) {
+            fprintf(stderr, "reallocate error\n");
+            return NULL;
+        }
+    }
+
+    /* XXX lock needed? */
+    memcpy(vga_ram_base, s->vram_ptr, vga_ram_size);
+    old_pointer = s->vram_ptr;
+    s->vram_ptr = vga_ram_base;
+
+    return old_pointer;
+}
+
 /********************************************************/
 /* vga screen dump */
 
Index: ioemu/hw/vga_int.h
===================================================================
--- ioemu.orig/hw/vga_int.h	2007-05-03 09:56:32.000000000 +0100
+++ ioemu/hw/vga_int.h	2007-05-03 10:07:53.000000000 +0100
@@ -169,5 +169,6 @@
                              unsigned int color0, unsigned int color1,
                              unsigned int color_xor);
 
+void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
 extern const uint8_t sr_mask[8];
 extern const uint8_t gr_mask[16];
Index: ioemu/vl.c
===================================================================
--- ioemu.orig/vl.c	2007-05-03 10:07:53.000000000 +0100
+++ ioemu/vl.c	2007-05-03 10:07:53.000000000 +0100
@@ -5745,6 +5745,62 @@
 
 #define MAX_NET_CLIENTS 32
 
+#include <xg_private.h>
+
+/* FIXME Flush the shadow page */
+int unset_mm_mapping(int xc_handle, uint32_t domid,
+                     unsigned long nr_pages, unsigned int address_bits,
+                     xen_pfn_t *extent_start)
+{
+    int err = 0;
+    xc_dominfo_t info;
+
+    xc_domain_getinfo(xc_handle, domid, 1, &info);
+    if ((info.nr_pages - nr_pages) <= 0) {
+        fprintf(stderr, "unset_mm_mapping: error nr_pages\n");
+        err = -1;
+    }
+
+    err = xc_domain_memory_decrease_reservation(xc_handle, domid,
+                                                nr_pages, 0, extent_start);
+    if (err)
+        fprintf(stderr, "Failed to decrease physmap\n");
+
+
+    if (xc_domain_setmaxmem(xc_handle, domid, (info.nr_pages - nr_pages) *
+                            PAGE_SIZE/1024) != 0) {
+        fprintf(logfile, "set maxmem returned error %d\n", errno);
+        err = -1;
+    }
+
+    return err;
+}
+
+int set_mm_mapping(int xc_handle, uint32_t domid,
+                   unsigned long nr_pages, unsigned int address_bits,
+                   xen_pfn_t *extent_start)
+{
+    xc_dominfo_t info;
+    int err = 0;
+
+    xc_domain_getinfo(xc_handle, domid, 1, &info);
+
+    if (xc_domain_setmaxmem(xc_handle, domid, info.max_memkb +
+                            nr_pages * PAGE_SIZE/1024) != 0) {
+        fprintf(logfile, "set maxmem returned error %d\n", errno);
+        return -1;
+    }
+
+    err = xc_domain_memory_populate_physmap(xc_handle, domid, nr_pages, 0,
+                                            address_bits, extent_start);
+    if (err) {
+        fprintf(stderr, "Failed to populate physmap\n");
+        return -1;
+    }
+
+    return 0;
+}
+
 int main(int argc, char **argv)
 {
 #ifdef CONFIG_GDBSTUB
Index: ioemu/vl.h
===================================================================
--- ioemu.orig/vl.h	2007-05-03 10:07:53.000000000 +0100
+++ ioemu/vl.h	2007-05-03 10:07:53.000000000 +0100
@@ -145,6 +145,13 @@
 
 void main_loop_wait(int timeout);
 
+int unset_mm_mapping(int xc_handle, uint32_t domid, unsigned long nr_pages,
+                     unsigned int address_bits, unsigned long *extent_start);
+int set_mm_mapping(int xc_handle, uint32_t domid, unsigned long nr_pages,
+                   unsigned int address_bits, unsigned long *extent_start);
+
+extern void *shared_vram;
+
 extern FILE *logfile;
 
 extern int xc_handle;
