qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] memory: fix limiting of translation at a page boundary
@ 2014-02-06 23:40 Paolo Bonzini
  2014-02-07 14:30 ` Mark Cave-Ayland
  0 siblings, 1 reply; 2+ messages in thread
From: Paolo Bonzini @ 2014-02-06 23:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Perard, Stefano Stabellini, Mark Cave-Ayland, qemu-stable

Commit 360e607 (address_space_translate: do not cross page boundaries,
2014-01-30) broke MMIO accesses in cases where the section is shorter
than the full register width.  This can happen for example with the
Bochs DISPI registers, which are 16 bits wide but have only a 1-byte
long MemoryRegion (if you write to the "second byte" of the register
your access is discarded; it doesn't write only to half of the register).

Restrict the action of commit 360e607 to direct RAM accesses.  This
is enough for Xen, since MMIO will not go through the mapcache.

Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: Anthony Perard <anthony.perard@citrix.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/exec.c b/exec.c
index 9ad0a4b..ecfda77 100644
--- a/exec.c
+++ b/exec.c
@@ -325,7 +325,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
                                  hwaddr *plen, bool resolve_subpage)
 {
     MemoryRegionSection *section;
-    Int128 diff, diff_page;
+    Int128 diff;
 
     section = address_space_lookup_region(d, addr, resolve_subpage);
     /* Compute offset within MemoryRegionSection */
@@ -334,13 +334,23 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
     /* Compute offset within MemoryRegion */
     *xlat = addr + section->offset_within_region;
 
-    diff_page = int128_make64(((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr);
     diff = int128_sub(section->mr->size, int128_make64(addr));
-    diff = int128_min(diff, diff_page);
     *plen = int128_get64(int128_min(diff, int128_make64(*plen)));
     return section;
 }
 
+static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+{
+    if (memory_region_is_ram(mr)) {
+        return !(is_write && mr->readonly);
+    }
+    if (memory_region_is_romd(mr)) {
+        return !is_write;
+    }
+
+    return false;
+}
+
 MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
                                       hwaddr *xlat, hwaddr *plen,
                                       bool is_write)
@@ -370,6 +380,11 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
         as = iotlb.target_as;
     }
 
+    if (memory_access_is_direct(mr, is_write)) {
+        hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
+        len = MIN(page, len);
+    }
+
     *plen = len;
     *xlat = addr;
     return mr;
@@ -1925,18 +1940,6 @@ static void invalidate_and_set_dirty(hwaddr addr,
     xen_modified_memory(addr, length);
 }
 
-static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
-{
-    if (memory_region_is_ram(mr)) {
-        return !(is_write && mr->readonly);
-    }
-    if (memory_region_is_romd(mr)) {
-        return !is_write;
-    }
-
-    return false;
-}
-
 static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
 {
     unsigned access_size_max = mr->ops->valid.max_access_size;
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Qemu-devel] [PATCH] memory: fix limiting of translation at a page boundary
  2014-02-06 23:40 [Qemu-devel] [PATCH] memory: fix limiting of translation at a page boundary Paolo Bonzini
@ 2014-02-07 14:30 ` Mark Cave-Ayland
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Cave-Ayland @ 2014-02-07 14:30 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Anthony Perard, Stefano Stabellini, qemu-devel, qemu-stable

On 06/02/14 23:40, Paolo Bonzini wrote:

> Commit 360e607 (address_space_translate: do not cross page boundaries,
> 2014-01-30) broke MMIO accesses in cases where the section is shorter
> than the full register width.  This can happen for example with the
> Bochs DISPI registers, which are 16 bits wide but have only a 1-byte
> long MemoryRegion (if you write to the "second byte" of the register
> your access is discarded; it doesn't write only to half of the register).
>
> Restrict the action of commit 360e607 to direct RAM accesses.  This
> is enough for Xen, since MMIO will not go through the mapcache.
>
> Reported-by: Mark Cave-Ayland<mark.cave-ayland@ilande.co.uk>
> Tested-by: Anthony Perard<anthony.perard@citrix.com>
> Cc: qemu-stable@nongnu.org
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>

Hi Paolo,

Unfortunately I've just tested this patch on qemu-system-ppc and it 
still doesn't fix the issue for me :(  This is with current git master 
bc1c7 plus your patch applied.

The symptoms haven't changed in that the VGA output stays black and 
doesn't resize, again implying that the VGA VBE calls aren't working. If 
it helps, the OpenBIOS VGA driver vga.fs can be found at 
http://git.qemu.org/?p=openbios.git;a=blob;f=drivers/vga.fs;h=ec4c6c5f10ea2c4c784c3c6888c3805ec3b14496;hb=888126272f92294b0da45158393f1b862742cf6b. 



ATB,

Mark.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-02-07 14:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-06 23:40 [Qemu-devel] [PATCH] memory: fix limiting of translation at a page boundary Paolo Bonzini
2014-02-07 14:30 ` Mark Cave-Ayland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).