fbdev: Push pgprot_decrypted() into mmap implementations
authorThomas Zimmermann <tzimmermann@suse.de>
Mon, 27 Nov 2023 13:15:58 +0000 (14:15 +0100)
committerThomas Zimmermann <tzimmermann@suse.de>
Wed, 29 Nov 2023 11:20:44 +0000 (12:20 +0100)
If a driver sets struct fb_ops.fb_mmap, the fbdev core automatically
calls pgprot_decrypted(). But the default fb_mmap code doesn't handle
pgprot_decrypted().

Move the call to pgprot_decrypted() into each drivers' fb_mmap function.
This only concerns fb_mmap functions for system and DMA memory. For
I/O memory, which is the default case, nothing changes. The fb_mmap
for I/O-memory can later be moved into a helper as well.

DRM's fbdev emulation handles pgprot_decrypted() internally via the
Prime helpers. Fbdev doesn't have to do anything in this case. In
cases where DRM uses deferred I/O, this patch updates fb_mmap correctly.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231127131655.4020-30-tzimmermann@suse.de
19 files changed:
drivers/auxdisplay/cfag12864bfb.c
drivers/auxdisplay/ht16k33.c
drivers/video/fbdev/amba-clcd.c
drivers/video/fbdev/au1100fb.c
drivers/video/fbdev/au1200fb.c
drivers/video/fbdev/core/fb_chrdev.c
drivers/video/fbdev/core/fb_defio.c
drivers/video/fbdev/ep93xx-fb.c
drivers/video/fbdev/gbefb.c
drivers/video/fbdev/omap/omapfb_main.c
drivers/video/fbdev/omap2/omapfb/omapfb-main.c
drivers/video/fbdev/ps3fb.c
drivers/video/fbdev/sa1100fb.c
drivers/video/fbdev/sbuslib.c
drivers/video/fbdev/sh_mobile_lcdcfb.c
drivers/video/fbdev/smscufx.c
drivers/video/fbdev/udlfb.c
drivers/video/fbdev/vermilion/vermilion.c
drivers/video/fbdev/vfb.c

index ede0f9a513110465810157241a68a5d70072e463..5ba19c339f088f76eaad57a9db8e5da3a193b9a6 100644 (file)
@@ -51,6 +51,8 @@ static int cfag12864bfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        struct page *pages = virt_to_page(cfag12864b_buffer);
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        return vm_map_pages_zero(vma, &pages, 1);
 }
 
index 2f1dc6b4e27653f9365773ceaf159d0f31befa75..a90430b7d07ba438c40685ecc043cd0fdd745775 100644 (file)
@@ -351,6 +351,8 @@ static int ht16k33_mmap(struct fb_info *info, struct vm_area_struct *vma)
        struct ht16k33_priv *priv = info->par;
        struct page *pages = virt_to_page(priv->fbdev.buffer);
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        return vm_map_pages_zero(vma, &pages, 1);
 }
 
index 0399db369e709d102617be637f29e3a4f25b0ef1..47d373f04f3f0367e51672db57241e8fdbcb1079 100644 (file)
@@ -829,6 +829,8 @@ static int clcdfb_of_dma_setup(struct clcd_fb *fb)
 
 static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
 {
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base,
                           fb->fb.fix.smem_start, fb->fb.fix.smem_len);
 }
index a9c8d33a6ef71f2bb119dcca108304ba455cb84f..08109ce535cd4e9a8396bfd62ca751572ecb58c4 100644 (file)
@@ -342,6 +342,8 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
 {
        struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
 
        return dma_mmap_coherent(fbdev->dev, vma, fbdev->fb_mem, fbdev->fb_phys,
index 16ebbab5009721c652c7abe566dfbc65b387475d..6f20efc663d7e4b4e6971503c8d6682355f86e47 100644 (file)
@@ -1236,6 +1236,8 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        struct au1200fb_device *fbdev = info->par;
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        return dma_mmap_coherent(fbdev->dev, vma,
                                 fbdev->fb_mem, fbdev->fb_phys, fbdev->fb_len);
 }
index 32a7315b4b6dd32147414643170006bd6fc8a759..b73a122950a940c3b16f992117dc897cb77a3f9f 100644 (file)
@@ -325,11 +325,6 @@ static int fb_mmap(struct file *file, struct vm_area_struct *vma)
        if (info->fbops->fb_mmap) {
                int res;
 
-               /*
-                * The framebuffer needs to be accessed decrypted, be sure
-                * SME protection is removed ahead of the call
-                */
-               vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
                res = info->fbops->fb_mmap(info, vma);
                mutex_unlock(&info->mm_lock);
                return res;
index 274f5d0fa24714ab31a7a6fcb1aa1667bda78c8a..1b0b85e59e5e130c29ac6e333942a1e040e637d0 100644 (file)
@@ -227,6 +227,8 @@ static const struct address_space_operations fb_deferred_io_aops = {
 
 int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        vma->vm_ops = &fb_deferred_io_vm_ops;
        vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
        if (!(info->flags & FBINFO_VIRTFB))
index cae00deee00148cf8ec732cafa7a01efddd5b101..3e378874ccc79ea673d340c8a183cddbd227cb78 100644 (file)
@@ -311,6 +311,8 @@ static int ep93xxfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        unsigned int offset = vma->vm_pgoff << PAGE_SHIFT;
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        if (offset < info->fix.smem_len) {
                return dma_mmap_wc(info->device, vma, info->screen_base,
                                   info->fix.smem_start, info->fix.smem_len);
index e89e5579258efd70706ff146b532cba6aa54c605..8463de833d1e19efb27b2c4d2b6d1952e139fb71 100644 (file)
@@ -1000,6 +1000,8 @@ static int gbefb_mmap(struct fb_info *info,
        unsigned long phys_addr, phys_size;
        u16 *tile;
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        /* check range */
        if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
                return -EINVAL;
index 694cf6318782bc8e60fe6dfd4445894099ba74ff..aa31c0d26e92531db9245249bd51ffd527dc0856 100644 (file)
@@ -1203,6 +1203,8 @@ static int omapfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
        struct omapfb_device *fbdev = plane->fbdev;
        int r;
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        omapfb_rqueue_lock(fbdev);
        r = fbdev->ctrl->mmap(info, vma);
        omapfb_rqueue_unlock(fbdev);
index c9fd0ad352d7fec0b177359b47a7aa48909a3ff1..0db9c55fce5a281b21aeadb386a77be469638908 100644 (file)
@@ -1095,6 +1095,8 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
        u32 len;
        int r;
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        rg = omapfb_get_mem_region(ofbi->region);
 
        start = omapfb_get_region_paddr(ofbi);
index de8d78bf070a09b717a3596657fd03ba93a8af4f..dbcda307f6a671dd5070ad15a497bde1307de90f 100644 (file)
@@ -708,6 +708,8 @@ static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        int r;
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        r = vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len);
 
        dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n",
index befd3fe2f6596179c5d5f319b843b023321b0d5f..0d362d2bf0e38982d9d4afb424fa2a04844d438b 100644 (file)
@@ -562,6 +562,8 @@ static int sa1100fb_mmap(struct fb_info *info,
                container_of(info, struct sa1100fb_info, fb);
        unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        if (off < info->fix.smem_len) {
                vma->vm_pgoff += 1; /* skip over the palette */
                return dma_mmap_wc(fbi->dev, vma, fbi->map_cpu, fbi->map_dma,
index 4d524db5c4f26acab77783d030c3803207c80763..634e3d159452c1619a311b13f22fedd787478563 100644 (file)
@@ -60,6 +60,7 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map,
 
        /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
        /* Each page, see which map applies */
index d84628de51893ad083d546d34308903b8d96368c..eb2297b37504c90437f8f09eb6c970a357865f57 100644 (file)
@@ -1482,6 +1482,8 @@ sh_mobile_lcdc_overlay_mmap(struct fb_info *info, struct vm_area_struct *vma)
        if (info->fbdefio)
                return fb_deferred_io_mmap(info, vma);
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        return dma_mmap_coherent(ovl->channel->lcdc->dev, vma, ovl->fb_mem,
                                 ovl->dma_handle, ovl->fb_size);
 }
@@ -1956,6 +1958,8 @@ sh_mobile_lcdc_mmap(struct fb_info *info, struct vm_area_struct *vma)
        if (info->fbdefio)
                return fb_deferred_io_mmap(info, vma);
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem,
                                 ch->dma_handle, ch->fb_size);
 }
index 90a77d19b236baa922535519597af33c8e015673..35d682b110c428aaf8ed6e39f386bb678f033d75 100644 (file)
@@ -783,6 +783,8 @@ static int ufx_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
        if (info->fbdefio)
                return fb_deferred_io_mmap(info, vma);
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
                return -EINVAL;
        if (size > info->fix.smem_len)
index 2460ff4ac86b427e8985c81cd305b068f657e36a..1514ddac4cafc4b4b9483d707dc6bb7dc07a2c79 100644 (file)
@@ -331,6 +331,8 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
        if (info->fbdefio)
                return fb_deferred_io_mmap(info, vma);
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
                return -EINVAL;
        if (size > info->fix.smem_len)
index 840ead69654b85ea2e2927fc315dc3e7b90cec0d..a087b42ca652f9aa55d4a545a650d35a63ec6deb 100644 (file)
@@ -998,6 +998,8 @@ static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
        int ret;
        unsigned long prot;
 
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        ret = vmlfb_vram_offset(vinfo, offset);
        if (ret)
                return -EINVAL;
index f6140f247e4b0b6c27308b0117a0a6c750e684e4..f86149ba383523c1f3c1fede4dcb3f7dd3d47783 100644 (file)
@@ -382,6 +382,8 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
 static int vfb_mmap(struct fb_info *info,
                    struct vm_area_struct *vma)
 {
+       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+
        return remap_vmalloc_range(vma, (void *)info->fix.smem_start, vma->vm_pgoff);
 }