Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 520

kvm-83-164.el5_5.9.src.rpm

From 602f09e7fb018fac56555ed1ed50407a8f60499f Mon Sep 17 00:00:00 2001
From: Michael S. Tsirkin <mst@redhat.com>
Date: Wed, 27 Jan 2010 12:19:45 -0200
Subject: [PATCH 2/5] qemu: add routines for atomic 16 bit accesses

RH-Author: Michael S. Tsirkin <mst@redhat.com>
Message-id: <20100127121945.GB7223@redhat.com>
Patchwork-id: 6702
O-Subject: [PATCHv3-repost 1/2] qemu: add routines for atomic 16 bit accesses
Bugzilla: 525323
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 qemu/cpu-all.h |    2 +
 qemu/exec.c    |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 0 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/cpu-all.h |    2 +
 qemu/exec.c    |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/qemu/cpu-all.h b/qemu/cpu-all.h
index 7a0539b..4c3a669 100644
--- a/qemu/cpu-all.h
+++ b/qemu/cpu-all.h
@@ -925,6 +925,7 @@ static inline void cpu_physical_memory_write(target_phys_addr_t addr,
     cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
 }
 uint32_t ldub_phys(target_phys_addr_t addr);
+uint32_t lduw_phys_atomic(target_phys_addr_t addr);
 uint32_t lduw_phys(target_phys_addr_t addr);
 uint32_t ldl_phys(target_phys_addr_t addr);
 uint64_t ldq_phys(target_phys_addr_t addr);
@@ -932,6 +933,7 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
 void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
 void stb_phys(target_phys_addr_t addr, uint32_t val);
 void stw_phys(target_phys_addr_t addr, uint32_t val);
+void stw_phys_atomic(target_phys_addr_t addr, uint32_t val);
 void stl_phys(target_phys_addr_t addr, uint32_t val);
 void stq_phys(target_phys_addr_t addr, uint64_t val);
 
diff --git a/qemu/exec.c b/qemu/exec.c
index 68e9fa8..becc8da 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -3175,6 +3175,38 @@ uint32_t lduw_phys(target_phys_addr_t addr)
     return tswap16(val);
 }
 
+/* warning: addr must be aligned */
+uint32_t lduw_phys_atomic(target_phys_addr_t addr)
+{
+    int io_index;
+    uint8_t *ptr;
+    uint64_t val;
+    unsigned long pd;
+    PhysPageDesc *p;
+
+    p = phys_page_find(addr >> TARGET_PAGE_BITS);
+    if (!p) {
+        pd = IO_MEM_UNASSIGNED;
+    } else {
+        pd = p->phys_offset;
+    }
+
+    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
+        !(pd & IO_MEM_ROMD)) {
+        /* I/O case */
+        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+        if (p)
+            addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+        val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
+    } else {
+        /* RAM case */
+        ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
+            (addr & ~TARGET_PAGE_MASK);
+        val = lduw_p(ptr);
+    }
+    return val;
+}
+
 #ifdef __GNUC__
 #define likely(x) __builtin_expect(!!(x), 1)
 #define unlikely(x) __builtin_expect(!!(x), 0)
@@ -3304,6 +3336,42 @@ void stw_phys(target_phys_addr_t addr, uint32_t val)
     cpu_physical_memory_write(addr, (const uint8_t *)&v, 2);
 }
 
+/* warning: addr must be aligned */
+void stw_phys_atomic(target_phys_addr_t addr, uint32_t val)
+{
+    int io_index;
+    uint8_t *ptr;
+    unsigned long pd;
+    PhysPageDesc *p;
+
+    p = phys_page_find(addr >> TARGET_PAGE_BITS);
+    if (!p) {
+        pd = IO_MEM_UNASSIGNED;
+    } else {
+        pd = p->phys_offset;
+    }
+
+    if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
+        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+        if (p)
+            addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+        io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
+    } else {
+        unsigned long addr1;
+        addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
+        /* RAM case */
+        ptr = phys_ram_base + addr1;
+        stw_p(ptr, val);
+        if (!cpu_physical_memory_is_dirty(addr1)) {
+            /* invalidate code */
+            tb_invalidate_phys_page_range(addr1, addr1 + 2, 0);
+            /* set dirty bit */
+            phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
+                (0xff & ~CODE_DIRTY_FLAG);
+        }
+    }
+}
+
 /* XXX: optimize */
 void stq_phys(target_phys_addr_t addr, uint64_t val)
 {
-- 
1.6.3.rc4.29.g8146