ia64/xen-unstable

changeset 18132:a47770d74b69

ioemu: fix vram tracking when !s->lfb_addr

When we don't have an LFB (standard VGA), we can not and do not need
vram tracking at all since we always get explicit dirtying.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jul 22 15:57:19 2008 +0100 (2008-07-22)
parents a637c023e066
children f86941c1b523
files tools/ioemu/hw/vga.c
line diff
     1.1 --- a/tools/ioemu/hw/vga.c	Tue Jul 22 13:36:56 2008 +0100
     1.2 +++ b/tools/ioemu/hw/vga.c	Tue Jul 22 15:57:19 2008 +0100
     1.3 @@ -1511,51 +1511,52 @@ static void vga_draw_graphic(VGAState *s
     1.4             width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
     1.5  #endif
     1.6  
     1.7 -    if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) != 3
     1.8 -            || !s->lfb_addr) {
     1.9 -        /* Tricky things happen, just track all video memory */
    1.10 -        start = 0;
    1.11 -        end = s->vram_size;
    1.12 -    } else {
    1.13 -        /* Tricky things won't have any effect, i.e. we are in the very simple
    1.14 -         * (and very usual) case of a linear buffer. */
    1.15 -        /* use page table dirty bit tracking for the LFB plus border */
    1.16 -        start = (s->start_addr * 4) & TARGET_PAGE_MASK;
    1.17 -        end = ((s->start_addr * 4 + height * line_offset) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
    1.18 -    }
    1.19 -
    1.20 -    for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)
    1.21 -        /* We will not read that anyway. */
    1.22 -        cpu_physical_memory_set_dirty(s->vram_offset + y);
    1.23 +    if (s->lfb_addr) {
    1.24 +        if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) != 3) {
    1.25 +            /* Tricky things happen, just track all video memory */
    1.26 +            start = 0;
    1.27 +            end = s->vram_size;
    1.28 +        } else {
    1.29 +            /* Tricky things won't have any effect, i.e. we are in the very simple
    1.30 +             * (and very usual) case of a linear buffer. */
    1.31 +            /* use page table dirty bit tracking for the LFB plus border */
    1.32 +            start = (s->start_addr * 4) & TARGET_PAGE_MASK;
    1.33 +            end = ((s->start_addr * 4 + height * line_offset) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
    1.34 +        }
    1.35  
    1.36 -    {
    1.37 -        unsigned long npages = (end - y) / TARGET_PAGE_SIZE;
    1.38 -        const int width = sizeof(unsigned long) * 8;
    1.39 -        unsigned long bitmap[(npages + width - 1) / width];
    1.40 -        int err;
    1.41 +        for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)
    1.42 +            /* We will not read that anyway. */
    1.43 +            cpu_physical_memory_set_dirty(s->vram_offset + y);
    1.44  
    1.45 -        if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
    1.46 -                    (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, bitmap))) {
    1.47 -            int i, j;
    1.48 -            for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
    1.49 -                unsigned long map = bitmap[i];
    1.50 -                for (j = i * width; map && j < npages; map >>= 1, j++)
    1.51 -                    if (map & 1)
    1.52 -                        cpu_physical_memory_set_dirty(s->vram_offset + y
    1.53 -                            + j * TARGET_PAGE_SIZE);
    1.54 +        {
    1.55 +            unsigned long npages = (end - y) / TARGET_PAGE_SIZE;
    1.56 +            const int width = sizeof(unsigned long) * 8;
    1.57 +            unsigned long bitmap[(npages + width - 1) / width];
    1.58 +            int err;
    1.59 +
    1.60 +            if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
    1.61 +                        (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, bitmap))) {
    1.62 +                int i, j;
    1.63 +                for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
    1.64 +                    unsigned long map = bitmap[i];
    1.65 +                    for (j = i * width; map && j < npages; map >>= 1, j++)
    1.66 +                        if (map & 1)
    1.67 +                            cpu_physical_memory_set_dirty(s->vram_offset + y
    1.68 +                                + j * TARGET_PAGE_SIZE);
    1.69 +                }
    1.70 +                y += npages * TARGET_PAGE_SIZE;
    1.71 +            } else {
    1.72 +                /* ENODATA just means we have changed mode and will succeed
    1.73 +                 * next time */
    1.74 +                if (err != -ENODATA)
    1.75 +                    fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d)\n", s->lfb_addr + y, npages, err);
    1.76              }
    1.77 -            y += npages * TARGET_PAGE_SIZE;
    1.78 -        } else {
    1.79 -            /* ENODATA just means we have changed mode and will succeed
    1.80 -             * next time */
    1.81 -            if (err != -ENODATA)
    1.82 -                fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d)\n", s->lfb_addr + y, npages, err);
    1.83          }
    1.84 -    }
    1.85  
    1.86 -    for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
    1.87 -        /* We will not read that anyway. */
    1.88 -        cpu_physical_memory_set_dirty(s->vram_offset + y);
    1.89 +        for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
    1.90 +            /* We will not read that anyway. */
    1.91 +            cpu_physical_memory_set_dirty(s->vram_offset + y);
    1.92 +    }
    1.93  
    1.94      addr1 = (s->start_addr * 4);
    1.95      bwidth = (width * bits + 7) / 8;