llvmpipe: Align persistent mappings to page size

KVM requires memory mapping to be aligned to page size, otherwise it
refuses to do the mapping. In particular this causes KVM mapping errors
when llvmpipe is used by virtio-gpu on host and guest tries to map buffer
that has a persistent mapping, i.e. it tries to map the llvmpipe's host
blob/buffer. Mesa virgl driver uses host blobs only for the buffers with
persistent mapping, hence let's align buffer allocations to the page size
when the persistence flag is set to fix the KVM fault.

Reviewed-by: Dave Airlie <airlied@redhat.com>
Acked-by: Antonio Caggiano <antonio.caggiano@collabora.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18053>
This commit is contained in:
Dmitry Osipenko 2022-08-11 01:04:31 +03:00 committed by Marge Bot
parent 49efa73ba1
commit 79f47249e8

View file

@ -90,7 +90,16 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
* of a block for all formats) though this should not be strictly necessary
* neither. In any case it can only affect compressed or 1d textures.
*/
unsigned mip_align = MAX2(64, util_get_cpu_caps()->cacheline);
uint64_t mip_align = MAX2(64, util_get_cpu_caps()->cacheline);
/* KVM on Linux requires memory mapping to be aligned to the page size,
* otherwise Linux kernel errors out on trying to map host GPU mapping
* to guest (ARB_map_buffer_range). The improper alignment creates trouble
* for the virgl driver when host uses llvmpipe, causing Qemu and crosvm to
* bail out on the KVM error.
*/
if (lpr->base.flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
os_get_page_size(&mip_align);
assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
@ -280,7 +289,12 @@ llvmpipe_resource_create_all(struct pipe_screen *_screen,
lpr->size_required += (LP_RASTER_BLOCK_SIZE - 1) * 4 * sizeof(float);
if (alloc_backing) {
lpr->data = align_malloc(lpr->size_required, 64);
uint64_t alignment = 64;
if (templat->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
os_get_page_size(&alignment);
lpr->data = align_malloc(lpr->size_required, alignment);
if (!lpr->data)
goto fail;