ia64/xen-unstable

changeset 10051:1b55b85f8cb2

Fix the cirrus vga model to not leak memory when switching between
initial vga mode and linear framebuffer.

When creating device model, the vga memory is allocated through
xc_domain_memory_increase_reservation(), however, when switch to use
linear framebuffer, we didn't free that memory, and re-allocate the vga
memory through set_mm_mapping(), that caused memory leak. Now it is
changed to just using qemu_malloc when create device model, and free
that memory when switch to linear framebuffer.

After unset_vram_mapping(), the old memory pointer should be
unmapped; after set_vram_mapping(), the old memory should be freed.

Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri May 12 15:17:21 2006 +0100 (2006-05-12)
parents c92fbde4074d
children 7f98c67636f4
files tools/ioemu/hw/cirrus_vga.c tools/ioemu/hw/pc.c tools/ioemu/hw/vga.c tools/ioemu/hw/vga_int.h tools/ioemu/vl.c
line diff
     1.1 --- a/tools/ioemu/hw/cirrus_vga.c	Fri May 12 15:15:59 2006 +0100
     1.2 +++ b/tools/ioemu/hw/cirrus_vga.c	Fri May 12 15:17:21 2006 +0100
     1.3 @@ -272,7 +272,8 @@ typedef struct CirrusVGAState {
     1.4      int last_hw_cursor_y_end;
     1.5      int real_vram_size; /* XXX: suppress that */
     1.6      CPUWriteMemoryFunc **cirrus_linear_write;
     1.7 -    int set_mapping;
     1.8 +    unsigned long map_addr;
     1.9 +    unsigned long map_end;
    1.10  } CirrusVGAState;
    1.11  
    1.12  typedef struct PCICirrusVGAState {
    1.13 @@ -2543,12 +2544,12 @@ static int unset_vram_mapping(unsigned l
    1.14  static void * set_vram_mapping(unsigned long addr, unsigned long end) {}
    1.15  static int unset_vram_mapping(unsigned long addr, unsigned long end) {}
    1.16  #endif
    1.17 +extern int vga_accelerate;
    1.18  
    1.19  /* Compute the memory access functions */
    1.20  static void cirrus_update_memory_access(CirrusVGAState *s)
    1.21  {
    1.22      unsigned mode;
    1.23 -    extern int vga_accelerate;
    1.24  
    1.25      if ((s->sr[0x17] & 0x44) == 0x44) {
    1.26          goto generic_io;
    1.27 @@ -2563,18 +2564,21 @@ static void cirrus_update_memory_access(
    1.28  
    1.29      mode = s->gr[0x05] & 0x7;
    1.30      if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
    1.31 -            if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) {
    1.32 -                if (!s->set_mapping) {
    1.33 -                    void * vram_pointer;
    1.34 -                    s->set_mapping = 1;
    1.35 -                    vram_pointer = set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end);
    1.36 -                    if (!vram_pointer){
    1.37 +            if ( vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end ) {
    1.38 +                if (!s->map_addr) {
    1.39 +                    void *vram_pointer, *old_vram;
    1.40 +
    1.41 +                    vram_pointer =
    1.42 +                      set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end);
    1.43 +                    if (!vram_pointer) {
    1.44                          fprintf(stderr, "NULL vram_pointer\n");
    1.45 -                    } else
    1.46 -                    {
    1.47 -                        vga_update_vram((VGAState *)s, vram_pointer,
    1.48 +                    } else {
    1.49 +                        old_vram = vga_update_vram((VGAState *)s, vram_pointer,
    1.50                                          VGA_RAM_SIZE);
    1.51 +                        qemu_free(old_vram);
    1.52                      }
    1.53 +                    s->map_addr = s->cirrus_lfb_addr;
    1.54 +                    s->map_end = s->cirrus_lfb_end;
    1.55                  }
    1.56              }
    1.57              s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
    1.58 @@ -2583,13 +2587,19 @@ static void cirrus_update_memory_access(
    1.59          } else {
    1.60          generic_io:
    1.61              if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) {
    1.62 -                if(s->set_mapping) {
    1.63 +                if(s->map_addr) {
    1.64                      int error;
    1.65 -                    s->set_mapping = 0;
    1.66 +                    void *old_vram = NULL;
    1.67 +
    1.68                      error = unset_vram_mapping(s->cirrus_lfb_addr,
    1.69                                             s->cirrus_lfb_end);
    1.70                      if (!error)
    1.71 -                        vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
    1.72 +                        old_vram =
    1.73 +                          vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
    1.74 +
    1.75 +                    if (old_vram)
    1.76 +                        munmap(old_vram, s->map_addr - s->map_end);
    1.77 +                    s->map_addr = s->map_end = 0;
    1.78                  }
    1.79              }
    1.80  
    1.81 @@ -3184,6 +3194,12 @@ static void cirrus_pci_lfb_map(PCIDevice
    1.82  				 s->cirrus_linear_io_addr);
    1.83      s->cirrus_lfb_addr = addr;
    1.84      s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
    1.85 +
    1.86 +    if ( vga_accelerate && s->map_addr &&
    1.87 +         (s->cirrus_lfb_addr != s->map_addr) &&
    1.88 +         (s->cirrus_lfb_end != s->map_end))
    1.89 +        fprintf(logfile, "cirrus vga map change while on lfb mode\n");
    1.90 +
    1.91      cpu_register_physical_memory(addr + 0x1000000, 0x400000,
    1.92  				 s->cirrus_linear_bitblt_io_addr);
    1.93  }
     2.1 --- a/tools/ioemu/hw/pc.c	Fri May 12 15:15:59 2006 +0100
     2.2 +++ b/tools/ioemu/hw/pc.c	Fri May 12 15:17:21 2006 +0100
     2.3 @@ -385,7 +385,6 @@ void pc_init(uint64_t ram_size, int vga_
     2.4      char buf[1024];
     2.5      int ret, linux_boot, initrd_size, i, nb_nics1;
     2.6      PCIBus *pci_bus;
     2.7 -    extern void * shared_vram;
     2.8      
     2.9      linux_boot = (kernel_filename != NULL);
    2.10  
    2.11 @@ -512,14 +511,14 @@ void pc_init(uint64_t ram_size, int vga_
    2.12      if (cirrus_vga_enabled) {
    2.13          if (pci_enabled) {
    2.14              pci_cirrus_vga_init(pci_bus, 
    2.15 -                                ds, shared_vram, ram_size, 
    2.16 +                                ds, NULL, ram_size, 
    2.17                                  vga_ram_size);
    2.18          } else {
    2.19 -            isa_cirrus_vga_init(ds, shared_vram, ram_size, 
    2.20 +            isa_cirrus_vga_init(ds, NULL, ram_size, 
    2.21                                  vga_ram_size);
    2.22          }
    2.23      } else {
    2.24 -        vga_initialize(pci_bus, ds, shared_vram, ram_size, 
    2.25 +        vga_initialize(pci_bus, ds, NULL, ram_size, 
    2.26                         vga_ram_size);
    2.27      }
    2.28  
     3.1 --- a/tools/ioemu/hw/vga.c	Fri May 12 15:15:59 2006 +0100
     3.2 +++ b/tools/ioemu/hw/vga.c	Fri May 12 15:17:21 2006 +0100
     3.3 @@ -1946,11 +1946,11 @@ void vga_bios_init(VGAState *s)
     3.4  
     3.5  }
     3.6  
     3.7 +/* when used on xen environment, the vga_ram_base is not used */
     3.8  void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
     3.9                       unsigned long vga_ram_offset, int vga_ram_size)
    3.10  {
    3.11      int i, j, v, b;
    3.12 -    extern void* shared_vram;
    3.13  
    3.14      for(i = 0;i < 256; i++) {
    3.15          v = 0;
    3.16 @@ -1979,11 +1979,7 @@ void vga_common_init(VGAState *s, Displa
    3.17  
    3.18      /* qemu's vga mem is not detached from phys_ram_base and can cause DM abort
    3.19       * when guest write vga mem, so allocate a new one */
    3.20 -#if defined(__i386__) || defined(__x86_64__)
    3.21 -    s->vram_ptr = shared_vram;
    3.22 -#else
    3.23      s->vram_ptr = qemu_malloc(vga_ram_size);
    3.24 -#endif
    3.25      check_sse2();
    3.26      s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
    3.27      if (s->vram_shadow == NULL)
    3.28 @@ -2090,12 +2086,14 @@ int vga_initialize(PCIBus *bus, DisplayS
    3.29      return 0;
    3.30  }
    3.31  
    3.32 -int vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
    3.33 +void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
    3.34  {
    3.35 +    uint8_t *old_pointer;
    3.36 +
    3.37      if (s->vram_size != vga_ram_size)
    3.38      {
    3.39          fprintf(stderr, "No support to change vga_ram_size\n");
    3.40 -        return -1;
    3.41 +        return NULL;
    3.42      }
    3.43  
    3.44      if ( !vga_ram_base )
    3.45 @@ -2104,15 +2102,16 @@ int vga_update_vram(VGAState *s, void *v
    3.46          if (!vga_ram_base)
    3.47          {
    3.48              fprintf(stderr, "reallocate error\n");
    3.49 -            return -1;
    3.50 +            return NULL;
    3.51          }
    3.52      }
    3.53  
    3.54      /* XXX lock needed? */
    3.55      memcpy(vga_ram_base, s->vram_ptr, vga_ram_size);
    3.56 +    old_pointer = s->vram_ptr;
    3.57      s->vram_ptr = vga_ram_base;
    3.58  
    3.59 -    return 0;
    3.60 +    return old_pointer;
    3.61  }
    3.62  
    3.63  /********************************************************/
     4.1 --- a/tools/ioemu/hw/vga_int.h	Fri May 12 15:15:59 2006 +0100
     4.2 +++ b/tools/ioemu/hw/vga_int.h	Fri May 12 15:17:21 2006 +0100
     4.3 @@ -165,6 +165,6 @@ void vga_draw_cursor_line_32(uint8_t *d1
     4.4                               unsigned int color0, unsigned int color1,
     4.5                               unsigned int color_xor);
     4.6  
     4.7 -int vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
     4.8 +void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
     4.9  extern const uint8_t sr_mask[8];
    4.10  extern const uint8_t gr_mask[16];
     5.1 --- a/tools/ioemu/vl.c	Fri May 12 15:15:59 2006 +0100
     5.2 +++ b/tools/ioemu/vl.c	Fri May 12 15:17:21 2006 +0100
     5.3 @@ -147,12 +147,6 @@ int repeat_key = 1;
     5.4  TextConsole *vga_console;
     5.5  CharDriverState *serial_hds[MAX_SERIAL_PORTS];
     5.6  int xc_handle;
     5.7 -unsigned long *vgapage_array;
     5.8 -unsigned long *freepage_array;
     5.9 -unsigned long free_pages;
    5.10 -void *vtop_table;
    5.11 -unsigned long toptab;
    5.12 -unsigned long vgaram_pages;
    5.13  
    5.14  /***********************************************************/
    5.15  /* x86 ISA bus support */
    5.16 @@ -2454,32 +2448,6 @@ static uint8_t *signal_stack;
    5.17  
    5.18  #include <xg_private.h>
    5.19  
    5.20 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
    5.21 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    5.22 -
    5.23 -#ifdef __i386__
    5.24 -#define _LEVEL_3_ 0
    5.25 -#else
    5.26 -#define _LEVEL_3_ 1
    5.27 -#endif
    5.28 -
    5.29 -#if _LEVEL_3_
    5.30 -#define L3_PROT (_PAGE_PRESENT)
    5.31 -#define L1_PAGETABLE_ENTRIES    512
    5.32 -#else
    5.33 -#define L1_PAGETABLE_ENTRIES    1024
    5.34 -#endif
    5.35 -
    5.36 -inline int
    5.37 -get_vl2_table(unsigned long count, unsigned long start)
    5.38 -{
    5.39 -#if _LEVEL_3_
    5.40 -    return ((start + (count << PAGE_SHIFT)) >> L3_PAGETABLE_SHIFT) & 0x3;
    5.41 -#else
    5.42 -    return 0;
    5.43 -#endif
    5.44 -}
    5.45 -
    5.46  /* FIXME Flush the shadow page */
    5.47  int unset_mm_mapping(int xc_handle,
    5.48                       uint32_t domid,
    5.49 @@ -2584,10 +2552,8 @@ int main(int argc, char **argv)
    5.50      int serial_device_index;
    5.51      char qemu_dm_logfilename[64];
    5.52      const char *loadvm = NULL;
    5.53 -    unsigned long nr_pages, extra_pages, ram_pages, *page_array;
    5.54 -    xc_dominfo_t info;
    5.55 +    unsigned long nr_pages, *page_array;
    5.56      extern void *shared_page;
    5.57 -    extern void *shared_vram;
    5.58  
    5.59  #if !defined(CONFIG_SOFTMMU)
    5.60      /* we never want that malloc() uses mmap() */
    5.61 @@ -3045,29 +3011,10 @@ int main(int argc, char **argv)
    5.62      /* init the memory */
    5.63      phys_ram_size = ram_size + vga_ram_size + bios_size;
    5.64  
    5.65 -    ram_pages = ram_size/PAGE_SIZE;
    5.66 -#if defined(__i386__) || defined(__x86_64__)
    5.67 -    vgaram_pages =  (vga_ram_size -1) / PAGE_SIZE + 1;
    5.68 -    free_pages = vgaram_pages / L1_PAGETABLE_ENTRIES;
    5.69 -    extra_pages = vgaram_pages + free_pages;
    5.70 -#else
    5.71 -    /* Test vga acceleration later */
    5.72 -    extra_pages = 0;
    5.73 -#endif
    5.74 +    nr_pages = ram_size/PAGE_SIZE;
    5.75  
    5.76      xc_handle = xc_interface_open();
    5.77  
    5.78 -    xc_domain_getinfo(xc_handle, domid, 1, &info);
    5.79 -
    5.80 -    nr_pages = info.nr_pages + extra_pages;
    5.81 -
    5.82 -    if ( xc_domain_setmaxmem(xc_handle, domid,
    5.83 -                             (nr_pages) * PAGE_SIZE/1024 ) != 0)
    5.84 -    {
    5.85 -        fprintf(logfile, "set maxmem returned error %d\n", errno);
    5.86 -        exit(-1);
    5.87 -    }
    5.88 -
    5.89      if ( (page_array = (unsigned long *)
    5.90                          malloc(nr_pages * sizeof(unsigned long))) == NULL)
    5.91      {
    5.92 @@ -3075,24 +3022,16 @@ int main(int argc, char **argv)
    5.93          exit(-1);
    5.94      }
    5.95  
    5.96 -    if (xc_domain_memory_increase_reservation(xc_handle, domid,
    5.97 -                                              extra_pages , 0, 0, NULL) != 0)
    5.98 -    {
    5.99 -        fprintf(logfile, "increase reservation returned error %d\n", errno);
   5.100 -        exit(-1);
   5.101 -    }
   5.102 -
   5.103  #if defined(__i386__) || defined(__x86_64__)
   5.104      if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
   5.105      {
   5.106          fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
   5.107          exit(-1);
   5.108      }
   5.109 -
   5.110      if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
   5.111                            PROT_READ|PROT_WRITE,
   5.112                            page_array,
   5.113 -                          ram_pages - 1)) == 0 )
   5.114 +                          nr_pages - 1)) == 0 )
   5.115      {
   5.116          fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
   5.117          exit(-1);
   5.118 @@ -3100,31 +3039,11 @@ int main(int argc, char **argv)
   5.119  
   5.120      shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   5.121                                         PROT_READ|PROT_WRITE,
   5.122 -                                       page_array[ram_pages - 1]);
   5.123 -
   5.124 -    vgapage_array = &page_array[nr_pages - vgaram_pages];
   5.125 -
   5.126 -    if ( (shared_vram =  xc_map_foreign_batch(xc_handle, domid,
   5.127 -                                              PROT_READ|PROT_WRITE,
   5.128 -                                              vgapage_array,
   5.129 -                                              vgaram_pages)) == 0)
   5.130 -    {
   5.131 -        fprintf(logfile,
   5.132 -                "xc_map_foreign_batch vgaram returned error %d\n", errno);
   5.133 -        exit(-1);
   5.134 -    }
   5.135 -
   5.136 -    memset(shared_vram, 0, vgaram_pages * PAGE_SIZE);
   5.137 -    toptab = page_array[ram_pages] << PAGE_SHIFT;
   5.138 -
   5.139 -    vtop_table = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   5.140 -                                      PROT_READ|PROT_WRITE,
   5.141 -                                      page_array[ram_pages]);
   5.142 -
   5.143 -    freepage_array = &page_array[nr_pages - extra_pages];
   5.144 +                                       page_array[nr_pages - 1]);
   5.145 +
   5.146  #elif defined(__ia64__)
   5.147 -    if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, ram_pages)
   5.148 -         != ram_pages )
   5.149 +    if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, nr_pages)
   5.150 +         != nr_pages)
   5.151      {
   5.152          fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
   5.153          exit(-1);
   5.154 @@ -3133,7 +3052,7 @@ int main(int argc, char **argv)
   5.155      if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
   5.156                            PROT_READ|PROT_WRITE,
   5.157                            page_array,
   5.158 -                          ram_pages)) == 0 )
   5.159 +                          nr_pages)) == 0 )
   5.160      {
   5.161          fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
   5.162          exit(-1);
   5.163 @@ -3141,7 +3060,7 @@ int main(int argc, char **argv)
   5.164  
   5.165      if ( xc_ia64_get_pfn_list(xc_handle, domid,
   5.166                                page_array,
   5.167 -                              ram_pages + (GFW_SIZE >> PAGE_SHIFT), 1) != 1 )
   5.168 +                              nr_pages + (GFW_SIZE >> PAGE_SHIFT), 1) != 1 )
   5.169      {
   5.170          fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
   5.171          exit(-1);