qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] commit a87f39543a92 'memory: fix limiting of translatio


From: Laszlo Ersek
Subject: Re: [Qemu-devel] commit a87f39543a92 'memory: fix limiting of translation at a page boundary' breaks virtio-scsi for windows 64
Date: Fri, 11 Apr 2014 14:27:16 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0

On 04/11/14 14:02, Michael Tokarev wrote:
> Chris Boot updated his qemu from 1.7.0 to 1.7.1, and noticed that windows 
> guests
> which was using virtio-scsi does not work anymore.  Windows BSODs at
> boot with the following error:
> 
> 
>   STOP: c0000221 Unknown Hard Error
>    \StstenRiit\System32\ntdll.dll
> 
>   Collecting data for crash dump ...
>   ...
> 
> After reboot it offers to fix the error(s), apparently making the hdd image
> unusable even with older, previously working, versions.  I can confirm this
> on my machine too, using windows 7 64bit (32bit win7 boots very very slow
> on virtio-scsi, probably windows 32bit driver is broken).  Using windows
> drivers from virtio-win-0.1-74.iso.
> 
> 
> Bisecting between 1.7.0 and 1.7.1 was easy, and this is the first bad commit:
> 
> commit 819ddf7d1fbcb74ecab885dc35fea741c6316b17
> Author: Paolo Bonzini <address@hidden>
> Date:   Fri Feb 7 15:47:46 2014 +0100
> 
>     memory: fix limiting of translation at a page boundary
> 
>     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 <address@hidden>
>     Cc: address@hidden
>     Signed-off-by: Paolo Bonzini <address@hidden>
>     Tested-by: Mark Cave-Ayland <address@hidden>
>     Signed-off-by: Peter Maydell <address@hidden>
>     (cherry picked from commit a87f39543a9259f671c5413723311180ee2ad2a8)
>     Signed-off-by: Michael Roth <address@hidden>
> 
> Reverting this commit from 1.7.1 fixes the issue.
> 
> 
> More, the same issue exists on 2.0-tobe as well, but in this case, reverting
> the same commit from there -- a87f39543a9259f671c5413723311180ee2ad2a8 --
> does NOT fix the problem.  I'm bisecting between 1.7.0 and 2.0 now.
> 
> This is just a heads-up for now, dunno how important this use case is.

Disclaimer: I don't know what I'm talking about.

This hunk in 819ddf7d:

> @@ -295,6 +307,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;

limits "len" at the *first* page boundary that is strictly above "addr". Is 
that the intent? The commit subject says "at *a* page boundary".

Shouldn't it go like:

    if (memory_access_is_direct(mr, is_write)) {
        hwaddr page = (((addr + len) & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - 
addr;
        len = MIN(page, len);
    }

This would drop only the trailing portion beyond the last page boundary covered.

Thanks,
Laszlo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]