qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

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