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

Re: [PATCH] arm/ioreq: clean data field in ioreq struct on read operations


  • To: Julien Grall <julien@xxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Andrii Chepurnyi <Andrii_Chepurnyi@xxxxxxxx>
  • Date: Wed, 4 Oct 2023 08:42:15 +0000
  • Accept-language: uk-UA, en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=qBT7bNEVWvn3/HceSjgjLVnquEZtLkn7anQp2jkzFxA=; b=ct06c5Rl7IjDBgUnFcfv2iTTPJlotoxbqtR+d3XOf5r/Zx6jXRCPntVoUBu2pT6to5WgsKPiKqj4FSa7JVdVJpEP96OHjVWwjo4xfo3FUPzOFk3vNKvBM5gPNL9Ool52dZacEZt5lWBIWg3NsN3jbKjqI/zn59o77D2avTzSQSQCb0UL78wbA4uqt+/hBjIggKjL7bWjk+OdMOvECknqzeJxf+aNnMxjkygqYKgPINyrAOAQm4uxAWfv0SxS1B0kykSxIbWGrKQoIAhtWiFM4RmltGwn7ZzqvuIpL76pu0hTt4Am91iRjaJJoP/OqsQYiSH1h6yZAOYedQEF8/6W3w==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cZL74g3KaNrKswnoK7vK6zk2/LeI8NJfJvTymqZqZVd7hGmnTU0SeXbD3ZNLm6gkEoy8SCW3AwFw5ASq843gIxY2pdGXxIxiTm6QO7KN6gScLZTkjuNVgcj9wB28m6CX9eVC2X7LVd1JgxO26z5SLUE2XjqksXyFlfqE2zjFF1sJGSzdBni+yY/7SQ4DcWvsgZFIeveGy5NQL8mNcR5HAGnx3Os1s2nrw2whuD9d34/VjgxfOXR/FaRbXD3swm/sjTGwUmLTixEE7xcNdkNh/kv+vyDHJwRvt3H5DbFEFMcjPgi6YpHZemQgAHE8R8xAh9t191QyHlsTvIyhLcn1RA==
  • Cc: Oleksandr Tyshchenko <Oleksandr_Tyshchenko@xxxxxxxx>, "andrii.chepurnyi82@xxxxxxxxx" <andrii.chepurnyi82@xxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Wed, 04 Oct 2023 13:55:00 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHZ9fw82LZSu4lXwEi+r3jS4xqDm7A4FMmAgAE8lwA=
  • Thread-topic: [PATCH] arm/ioreq: clean data field in ioreq struct on read operations

Hello,

On 10/3/23 16:49, Julien Grall wrote:
> Hi,
> 
> On 03/10/2023 14:19, Andrii Chepurnyi wrote:
>> For read operations, there's a potential issue when the data field
>> of the ioreq struct is partially updated in the response. To address
>> this, zero data field during read operations. This modification
>> serves as a safeguard against implementations that may inadvertently
>> partially update the data field in response to read requests.
>> For instance, consider an 8-bit read operation. In such cases, QEMU,
>> returns the same content of the data field with only 8 bits of
>> updated data. 
> 
> Do you have a pointer to the code?

First of all, using the term "user-space" with respect to this problem 
was a mistake from my side.

In general, my use case is to run u-boot with virtio-blk inside the 
guest domain.
I.e. setup configuration(hardware renesas gen3 kingfisher board):  Dom0, 
DomD ( QEMU as backend) and running u-boot in DomA with virtio-blk.
The problem appeared inside the u-boot code :

static int virtio_pci_reset(struct udevice *udev)
{
        struct virtio_pci_priv *priv = dev_get_priv(udev);

        /* 0 status means a reset */
        iowrite8(0, &priv->common->device_status);

        /*
         * After writing 0 to device_status, the driver MUST wait for a read
         * of device_status to return 0 before reinitializing the device.
         * This will flush out the status write, and flush in device writes,
         * including MSI-X interrupts, if any.
         */
        while (ioread8(&priv->common->device_status))
                udelay(1000);

        return 0;
}


I found that if u-boot was built with clang, it stuck in while in 
virtio_pci_reset forever. At the same time with gcc is working.

Here is a part disassembly of the virtio_pci_reset for both cases:

gcc:

0000000000000000 <virtio_pci_reset>:
    0:   a9be7bfd        stp     x29, x30, [sp, #-32]!
    4:   910003fd        mov     x29, sp
    8:   f9000bf3        str     x19, [sp, #16]
    c:   94000000        bl      0 <dev_get_priv>
   10:   aa0003f3        mov     x19, x0
   14:   f9400000        ldr     x0, [x0]
   18:   d5033fbf        dmb     sy
   1c:   3900501f        strb    wzr, [x0, #20]
   20:   f9400260        ldr     x0, [x19]
   24:   39405000        ldrb    w0, [x0, #20]
   28:   12001c00        and     w0, w0, #0xff
   2c:   d5033fbf        dmb     sy
   30:   35000080        cbnz    w0, 40 <virtio_pci_reset+0x40>
   34:   f9400bf3        ldr     x19, [sp, #16]
   38:   a8c27bfd        ldp     x29, x30, [sp], #32
   3c:   d65f03c0        ret
   40:   d2807d00        mov     x0, #0x3e8                      // #1000
   44:   94000000        bl      0 <udelay>
   48:   17fffff6        b       20 <virtio_pci_reset+0x20>


clang:

0000000000000000 <virtio_pci_reset>:
    0:   a9be7bfd        stp     x29, x30, [sp, #-32]!
    4:   f9000bf3        str     x19, [sp, #16]
    8:   910003fd        mov     x29, sp
    c:   94000000        bl      0 <dev_get_priv>
   10:   f9400008        ldr     x8, [x0]
   14:   d5033fbf        dmb     sy
   18:   3900511f        strb    wzr, [x8, #20]
   1c:   f9400008        ldr     x8, [x0]
   20:   39405108        ldrb    w8, [x8, #20]
   24:   d5033fbf        dmb     sy
   28:   34000108        cbz     w8, 48 <virtio_pci_reset+0x48>
   2c:   aa0003f3        mov     x19, x0
   30:   52807d00        mov     w0, #0x3e8                      // #1000
   34:   94000000        bl      0 <udelay>
   38:   f9400268        ldr     x8, [x19]
   3c:   39405108        ldrb    w8, [x8, #20]
   40:   d5033fbf        dmb     sy
   44:   35ffff68        cbnz    w8, 30 <virtio_pci_reset+0x30>
   48:   f9400bf3        ldr     x19, [sp, #16]
   4c:   2a1f03e0        mov     w0, wzr
   50:   a8c27bfd        ldp     x29, x30, [sp], #32
   54:   d65f03c0        ret


As you may found, in case of gcc read of 8 bit data :

   24:   39405000        ldrb    w0, [x0, #20]
   28:   12001c00        and     w0, w0, #0xff
   2c:   d5033fbf        dmb     sy

in case of clang:

   20:   39405108        ldrb    w8, [x8, #20]
   24:   d5033fbf        dmb     sy

in second case we got trash inside upper bits w8 and loop forever.


> 
>> This behavior could potentially result in the
>> propagation of incorrect or unintended data to user-space applications.
> 
> I am a bit confused with the last sentence. Are you referring to the 
> device emulator or a guest user-space applications? If the latter, then 
> why are you singling out user-space applications?

I will rephrase description, since u-boot is not a "user-space 
applications".

> To take the 8-bits example, the assumption is that QEMU will not touch 
> the top 24-bits. I guess that's a fair assumption. But, at this point, I 
> feel it would be better to also zero the top 24-bits in handle_ioserv() 
> when writing back to the register.
> 
> Also, if you are worried about unintended data shared, then we should 
> also make the value of get_user_reg() to only share what matters to the 
> device model.

Ok, I will push v2 with respect to your comments.

Best regards,
Andrii.

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.