On 3 February 2014 23:28, Alexander Graf <ag...@suse.de> wrote: > That means that something relies on the incorrect behavior we did > before to set *plen (end) = *plen (start) after the loop when > !mr->iommu_ops. I wonder what that could be...
I bounced around in a debugger for a bit looking for cases where the *plen got updated. One of them is cpu_physical_memory_write_rom_internal(): we now rather less efficiently do memcpy of 4K at a time into the guest RAM rather than blasting the entire ROM image, but the code still works. This backtrace, on the other hand, looks rather more suspect: #0 portio_write (opaque=0x101686160, addr=0, data=4, size=1) at /Users/pm215/src/qemu/ioport.c:203 #1 0x000000010032f143 in memory_region_write_accessor (mr=0x101686160, addr=0, value=0x105fab508, size=1, shift=0, mask=255) at /Users/pm215/src/qemu/memory.c:441 #2 0x000000010032f062 in access_with_adjusted_size (addr=0, value=0x105fab508, size=1, access_size_min=1, access_size_max=4, access=0x10032f0a0 <memory_region_write_accessor>, mr=0x101686160) at /Users/pm215/src/qemu/memory.c:478 #3 0x000000010032e16f in memory_region_dispatch_write (mr=0x101686160, addr=0, data=4, size=1) at /Users/pm215/src/qemu/memory.c:985 #4 0x000000010032e079 in io_mem_write (mr=0x101686160, addr=0, val=4, size=1) at /Users/pm215/src/qemu/memory.c:1744 #5 0x00000001002c47c1 in address_space_rw (as=0x10067fd80, addr=4261413326, buf=0x105fab66c "\004", len=2, is_write=true) at /Users/pm215/src/qemu/exec.c:2011 #6 0x00000001002c511f in address_space_write (as=0x10067fd80, addr=4261413326, buf=0x105fab66c "\004", len=2) at /Users/pm215/src/qemu/exec.c:2068 #7 0x00000001002c3b13 in subpage_write (opaque=0x103058200, addr=462, value=1024, len=2) at /Users/pm215/src/qemu/exec.c:1662 #8 0x000000010032f143 in memory_region_write_accessor (mr=0x103058200, addr=462, value=0x105fab798, size=2, shift=0, mask=65535) at /Users/pm215/src/qemu/memory.c:441 #9 0x000000010032f00a in access_with_adjusted_size (addr=462, value=0x105fab798, size=2, access_size_min=1, access_size_max=4, access=0x10032f0a0 <memory_region_write_accessor>, mr=0x103058200) at /Users/pm215/src/qemu/memory.c:473 #10 0x000000010032e16f in memory_region_dispatch_write (mr=0x103058200, addr=462, data=1024, size=2) at /Users/pm215/src/qemu/memory.c:985 #11 0x000000010032e079 in io_mem_write (mr=0x103058200, addr=462, val=1024, size=2) at /Users/pm215/src/qemu/memory.c:1744 #12 0x000000010037da52 in io_writew (env=0x1019ae338, physaddr=462, val=1024, addr=4261413326, retaddr=4430414751) at softmmu_template.h:336 #13 0x000000010037dc37 in helper_be_stw_mmu (env=0x1019ae338, addr=4261413326, val=1024, mmu_idx=1, retaddr=4430414751) at softmmu_template.h:448 The address_space access/write functions from subpage_write have decided that len==2 isn't valid (ie we called address_space_translate with plen pointing at a value of 2, address_space_translate_internal updated that to 1 (prior to this commit it would have left it alone) and we are now going to do what started off as a 16 bit access as two single byte writes. I have a feeling this is also bypassing the endianness swapping that would otherwise happen for this 16 bit write, as well. This happens because the IO port we're trying to access: { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data }, is declared as having a length of 1 and a size of 2. That would be nonsensical for MMIO but is apparently entirely fine for IO ports (go x86 madness). With this change, the memory system is now refusing to allow an access of size 2 through, because it's greater than the region length. So it splits it into two 1 byte accesses, and find_portio() then says "no, no such port" because find_portio() insists on an exact match between size and mrp->size. I'll leave you all to figure out exactly how this is supposed to work; I'm going to bed :-) thanks -- PMM