mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
drm/nouveau: verify that hardware supports the flush page address
Ensure that the DMA address of the framebuffer flush page is not larger than its hardware register. On GPUs older than Hopper, the register for the address can hold up to a 40-bit address (right-shifted by 8 so that it fits in the 32-bit register), and on Hopper and later it can be 52 bits (64-bit register where bits 52-63 must be zero). Recently it was discovered that under certain conditions, the flush page could be allocated outside this range. Although this bug was fixed, we can ensure that any future changes to this code don't accidentally generate an invalid page address. Signed-off-by: Timur Tabi <ttabi@nvidia.com> Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patch.msgid.link/20251113230323.1271726-2-ttabi@nvidia.com
This commit is contained in:
parent
04d98b3452
commit
31d3354f42
|
|
@ -15,6 +15,9 @@ gb100_fb_sysmem_flush_page_init(struct nvkm_fb *fb)
|
|||
const u32 hshub = DRF_LO(NV_PFB_HSHUB0);
|
||||
struct nvkm_device *device = fb->subdev.device;
|
||||
|
||||
// Ensure that the address is within hardware limits
|
||||
WARN_ON(fb->sysmem.flush_page_addr > DMA_BIT_MASK(52));
|
||||
|
||||
nvkm_wr32(device, hshub + NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI, addr_hi);
|
||||
nvkm_wr32(device, hshub + NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO, addr_lo);
|
||||
nvkm_wr32(device, hshub + NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI, addr_hi);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ gb202_fb_sysmem_flush_page_init(struct nvkm_fb *fb)
|
|||
struct nvkm_device *device = fb->subdev.device;
|
||||
const u64 addr = fb->sysmem.flush_page_addr;
|
||||
|
||||
// Ensure that the address is within hardware limits
|
||||
WARN_ON(fb->sysmem.flush_page_addr > DMA_BIT_MASK(52));
|
||||
|
||||
nvkm_wr32(device, NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI, upper_32_bits(addr));
|
||||
nvkm_wr32(device, NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO, lower_32_bits(addr));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ gf100_fb_init_page(struct nvkm_fb *fb)
|
|||
void
|
||||
gf100_fb_sysmem_flush_page_init(struct nvkm_fb *fb)
|
||||
{
|
||||
// Ensure that the address can actually fit in the register
|
||||
WARN_ON(fb->sysmem.flush_page_addr > DMA_BIT_MASK(40));
|
||||
|
||||
nvkm_wr32(fb->subdev.device, 0x100c10, fb->sysmem.flush_page_addr >> 8);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ gh100_fb_sysmem_flush_page_init(struct nvkm_fb *fb)
|
|||
const u64 addr = fb->sysmem.flush_page_addr >> NV_PFB_NISO_FLUSH_SYSMEM_ADDR_SHIFT;
|
||||
struct nvkm_device *device = fb->subdev.device;
|
||||
|
||||
// Ensure that the address is within hardware limits
|
||||
WARN_ON(fb->sysmem.flush_page_addr > DMA_BIT_MASK(52));
|
||||
|
||||
nvkm_wr32(device, NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI, upper_32_bits(addr));
|
||||
nvkm_wr32(device, NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO, lower_32_bits(addr));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,6 +214,9 @@ nv50_fb_tags(struct nvkm_fb *base)
|
|||
static void
|
||||
nv50_fb_sysmem_flush_page_init(struct nvkm_fb *fb)
|
||||
{
|
||||
// Ensure that the address can actually fit in the register
|
||||
WARN_ON(fb->sysmem.flush_page_addr > DMA_BIT_MASK(40));
|
||||
|
||||
nvkm_wr32(fb->subdev.device, 0x100c08, fb->sysmem.flush_page_addr >> 8);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user