All of lore.kernel.org
 help / color / mirror / Atom feed
From: Samuel Thibault <samuel.thibault@eu.citrix.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH] ioemu: drop shadow vram
Date: Thu, 10 Jul 2008 17:58:37 +0100	[thread overview]
Message-ID: <20080710165837.GU4536@implementation.uk.xensource.com> (raw)

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@eu.citrix.com>

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

             reply	other threads:[~2008-07-10 16:58 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-10 16:58 Samuel Thibault [this message]
2008-07-14 15:20 ` [PATCH] ioemu: drop shadow vram Ian Jackson
2008-07-14 15:24   ` Samuel Thibault
2008-07-14 15:27     ` Ian Jackson
2008-07-14 15:27   ` Samuel Thibault

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080710165837.GU4536@implementation.uk.xensource.com \
    --to=samuel.thibault@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.