WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] ioemu: drop shadow vram

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] ioemu: drop shadow vram
From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
Date: Thu, 10 Jul 2008 17:58:37 +0100
Delivery-date: Thu, 10 Jul 2008 09:58:57 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Mail-followup-to: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.12-2006-07-14
ioemu: drop shadow vram

We can now actually drop the shadow vram entirely thanks to dirty page
tracking.

Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>

diff -r 7a918e567837 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Thu Jul 10 15:34:44 2008 +0100
+++ b/tools/ioemu/hw/vga.c      Thu Jul 10 17:58:14 2008 +0100
@@ -1383,105 +1383,6 @@
     }
 }
 
-static inline int cmp_vram(VGAState *s, int offset, int n)
-{
-    long *vp, *sp;
-
-    if (s->vram_shadow == NULL)
-        return 1;
-    vp = (long *)(s->vram_ptr + offset);
-    sp = (long *)(s->vram_shadow + offset);
-    while ((n -= sizeof(*vp)) >= 0) {
-        if (*vp++ != *sp++) {
-            memcpy(sp - 1, vp - 1, n + sizeof(*vp));
-            return 1;
-        }
-    }
-    return 0;
-}
-
-#ifdef USE_SSE2
-
-#include <signal.h>
-#include <setjmp.h>
-#include <emmintrin.h>
-
-int sse2_ok = 1;
-
-static inline unsigned int cpuid_edx(unsigned int op)
-{
-    unsigned int eax, edx;
-
-#ifdef __x86_64__
-#define __bx "rbx"
-#else
-#define __bx "ebx"
-#endif
-    __asm__("push %%"__bx"; cpuid; pop %%"__bx
-            : "=a" (eax), "=d" (edx)
-            : "0" (op)
-            : "cx");
-#undef __bx
-
-    return edx;
-}
-
-jmp_buf sse_jbuf;
-
-void intr(int sig)
-{
-    sse2_ok = 0;
-    longjmp(sse_jbuf, 1);
-}
-
-void check_sse2(void)
-{
-    /* Check 1: What does CPUID say? */
-    if ((cpuid_edx(1) & 0x4000000) == 0) {
-        sse2_ok = 0;
-        return;
-    }
-
-    /* Check 2: Can we use SSE2 in anger? */
-    signal(SIGILL, intr);
-    if (setjmp(sse_jbuf) == 0)
-        __asm__("xorps %xmm0,%xmm0\n");
-}
-
-int vram_dirty(VGAState *s, int offset, int n)
-{
-    __m128i *sp, *vp;
-
-    if (s->vram_shadow == NULL)
-        return 1;
-    if (sse2_ok == 0)
-        return cmp_vram(s, offset, n);
-    vp = (__m128i *)(s->vram_ptr + offset);
-    sp = (__m128i *)(s->vram_shadow + offset);
-    while ((n -= sizeof(*vp)) >= 0) {
-        if (_mm_movemask_epi8(_mm_cmpeq_epi8(*sp, *vp)) != 0xffff) {
-            while (n >= 0) {
-                _mm_store_si128(sp++, _mm_load_si128(vp++));
-                n -= sizeof(*vp);
-            }
-            return 1;
-        }
-        sp++;
-        vp++;
-    }
-    return 0;
-}
-#else /* !USE_SSE2 */
-int vram_dirty(VGAState *s, int offset, int n)
-{
-    return cmp_vram(s, offset, n);
-}
-
-void check_sse2(void)
-{
-}
-#endif /* !USE_SSE2 */
-
 /* 
  * graphic modes
  */
@@ -1495,6 +1396,7 @@
     uint32_t v, addr1, addr;
     vga_draw_line_func *vga_draw_line;
     ram_addr_t page_min, page_max;
+    unsigned long start, end;
 
     full_update |= update_basic_params(s);
 
@@ -1609,69 +1511,51 @@
            width, height, v, line_offset, s->cr[9], s->cr[0x17], 
s->line_compare, s->sr[0x01]);
 #endif
 
-    y = 0;
-
     if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) != 3
             || !s->lfb_addr) {
-        /* Tricky things happen, disable dirty bit tracking */
-        xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
-
-        for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
-            if (vram_dirty(s, y, TARGET_PAGE_SIZE))
-                cpu_physical_memory_set_dirty(s->vram_offset + y);
+        /* Tricky things happen, just track all video memory */
+        start = 0;
+        end = s->vram_size;
     } else {
         /* Tricky things won't have any effect, i.e. we are in the very simple
          * (and very usual) case of a linear buffer. */
-        unsigned long end;
+        /* use page table dirty bit tracking for the LFB plus border */
+        start = (s->start_addr * 4) & TARGET_PAGE_MASK;
+        end = ((s->start_addr * 4 + height * line_offset) + TARGET_PAGE_SIZE - 
1) & TARGET_PAGE_MASK;
+    }
 
-        for ( ; y < ((s->start_addr * 4) & TARGET_PAGE_MASK); y += 
TARGET_PAGE_SIZE)
-            /* We will not read that anyway. */
-            cpu_physical_memory_set_dirty(s->vram_offset + y);
+    for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)
+        /* We will not read that anyway. */
+        cpu_physical_memory_set_dirty(s->vram_offset + y);
 
-        if (y < (s->start_addr * 4)) {
-            /* start address not aligned on a page, track dirtyness by hand. */
-            if (vram_dirty(s, y, TARGET_PAGE_SIZE))
-                cpu_physical_memory_set_dirty(s->vram_offset + y);
-            y += TARGET_PAGE_SIZE;
+    {
+        unsigned long npages = (end - y) / TARGET_PAGE_SIZE;
+        const int width = sizeof(unsigned long) * 8;
+        unsigned long bitmap[(npages + width - 1) / width];
+        int err;
+
+        if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
+                    (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, bitmap))) {
+            int i, j;
+            for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
+                unsigned long map = bitmap[i];
+                for (j = i * width; map && j < npages; map >>= 1, j++)
+                    if (map & 1)
+                        cpu_physical_memory_set_dirty(s->vram_offset + y
+                            + j * TARGET_PAGE_SIZE);
+            }
+            y += npages * TARGET_PAGE_SIZE;
+        } else {
+            /* ENODATA just means we have changed mode and will succeed
+             * next time */
+            if (err != -ENODATA)
+                fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d)\n", 
s->lfb_addr + y, npages, err);
         }
+    }
 
-        /* use page table dirty bit tracking for the inner of the LFB */
-        end = s->start_addr * 4 + height * line_offset;
-        {
-            unsigned long npages = ((end & TARGET_PAGE_MASK) - y) / 
TARGET_PAGE_SIZE;
-            const int width = sizeof(unsigned long) * 8;
-            unsigned long bitmap[(npages + width - 1) / width];
-            int err;
-
-            if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
-                        (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, 
bitmap))) {
-                int i, j;
-                for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
-                    unsigned long map = bitmap[i];
-                    for (j = i * width; map && j < npages; map >>= 1, j++)
-                        if (map & 1)
-                            cpu_physical_memory_set_dirty(s->vram_offset + y
-                                + j * TARGET_PAGE_SIZE);
-                }
-                y += npages * TARGET_PAGE_SIZE;
-            } else {
-                /* ENODATA just means we have changed mode and will succeed
-                 * next time */
-                if (err != -ENODATA)
-                    fprintf(stderr, "track_dirty_vram(%lx, %lx) failed 
(%d)\n", s->lfb_addr + y, npages, err);
-            }
-        }
-
-        for ( ; y < s->vram_size && y < end; y += TARGET_PAGE_SIZE)
-            /* failed or end address not aligned on a page, track dirtyness by
-             * hand. */
-            if (vram_dirty(s, y, TARGET_PAGE_SIZE))
-                cpu_physical_memory_set_dirty(s->vram_offset + y);
-
-        for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
-            /* We will not read that anyway. */
-            cpu_physical_memory_set_dirty(s->vram_offset + y);
-    }
+    for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
+        /* We will not read that anyway. */
+        cpu_physical_memory_set_dirty(s->vram_offset + y);
 
     addr1 = (s->start_addr * 4);
     bwidth = (width * bits + 7) / 8;
@@ -2140,16 +2024,7 @@
 
     vga_reset(s);
 
-    check_sse2();
-    s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
-    if (s->vram_shadow == NULL)
-        fprintf(stderr, "Cannot allocate %d bytes for VRAM shadow, "
-                "mouse will be slow\n", vga_ram_size);
-    s->vram_shadow = (uint8_t *)((long)(s->vram_shadow + TARGET_PAGE_SIZE - 1)
-                                 & ~(TARGET_PAGE_SIZE - 1));
-
-    /* Video RAM must be 128-bit aligned for SSE optimizations later */
-    /* and page-aligned for PVFB memory sharing */
+    /* Video RAM must be page-aligned for PVFB memory sharing */
     s->vram_ptr = s->vram_alloc = qemu_memalign(TARGET_PAGE_SIZE, 
vga_ram_size);
 
 #ifdef CONFIG_STUBDOM

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>