[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 4/5] ramfb: add sanity checks to ramfb_create_display_surface
From: |
Laszlo Ersek |
Subject: |
Re: [PATCH 4/5] ramfb: add sanity checks to ramfb_create_display_surface |
Date: |
Tue, 28 Apr 2020 15:09:00 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 |
On 04/27/20 13:11, Gerd Hoffmann wrote:
>>> - size = (hwaddr)linesize * height;
>>> - data = cpu_physical_memory_map(addr, &size, false);
>>> - if (size != (hwaddr)linesize * height) {
>>> - cpu_physical_memory_unmap(data, size, 0, 0);
>>> + mapsize = size = stride * (height - 1) + linesize;
>>> + data = cpu_physical_memory_map(addr, &mapsize, false);
>>> + if (size != mapsize) {
>>> + cpu_physical_memory_unmap(data, mapsize, 0, 0);
>>> return NULL;
>>> }
>>>
>>> surface = qemu_create_displaysurface_from(width, height,
>>> - format, linesize, data);
>>> + format, stride, data);
>>> pixman_image_set_destroy_function(surface->image,
>>> ramfb_unmap_display_surface, NULL);
>>>
>>>
>>
>> I don't understand two things about this patch:
>>
>> - "stride" can still be smaller than "linesize" (scanlines can still
>> overlap). Why is that not a problem?
>
> Why it should be? It is the guests choice. Not a very useful one, but
> hey, if the guest prefers it that way we are at your service ...
>
> We only must make sure our size calculations are correct. The patch
> does that. I think we can also outlaw stride < linesize if you are
> happier with that alternative approach. I doubt we have any guests
> relying on this working.
OK, thanks. I agree -- if it doesn't break QEMU, then we can let guests
break themselves.
>
>> - assuming "stride > linesize" (i.e., strictly larger), we don't seem to
>> map the last complete stride, and that seems to be intentional. Is that
>> safe with regard to qemu_create_displaysurface_from()? Ultimately the
>> stride is passed to pixman_image_create_bits(), and the underlying
>> "data" may not be large enough for that. What am I missing?
>
> Lets take a real-world example. Wayland rounds up width and height to
> multiples of 64 (probably for tiling on modern GPUs). So with 800x600
> you get an allocation of 832x640, like this:
>
> ###########** <- y 0
> ###########**
> ###########**
> ###########**
> ###########** <- y 600
> ************* <- y 640
>
> ^ ^ ^----- x 832
> | +------- x 800
> +----------------- x 0
>
> where "#" is image data and "*" is unused padding space. Pixman will
> access all "#", so we are mapping the region from the first "#" to the
> last "#", including the unused padding on each scanline, except for the
> last scanline. Any unused scanlines at the bottom are excluded too
> (ramfb doesn't even know whenever they exist).
>
> The unused padding is only mapped because it is the easiest way to
> handle things, not because we need it. Also the padding is typically
> *alot* smaller than PAGE_SIZE, so we couldn't exclude it from the
> mapping even if we would like to ;)
OK. If pixman only accesses the "#" marks, then it should be OK.
>
>> Hm... bonus question: qemu_create_displaysurface_from() still accepts
>> "linesize" as a signed int. (Not sure about pixman_image_create_bits().)
>> Should we do something specific to prevent that value from being
>> negative? The guest gives us a uint32_t.
>
> Not fully sure we can do that without breaking something, might be a
> negative stride is used for upside down images (last scanline comes
> first in memory).
Ugh... Upside down images???... Well, OK, I guess. :)
For the followup patch:
Acked-by: Laszlo Ersek <address@hidden>
Laszlo
[PATCH 3/5] ramfb: don't update RAMFBState on errors, Gerd Hoffmann, 2020/04/22
[PATCH 2/5] Revert "hw/display/ramfb: lock guest resolution after it's set", Gerd Hoffmann, 2020/04/22
[PATCH 1/5] Revert "hw/display/ramfb: initialize fw-config space with xres/ yres", Gerd Hoffmann, 2020/04/22
[PATCH 5/5] ramfb: drop leftover debug message, Gerd Hoffmann, 2020/04/22