All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>
To: xen-devel@lists.xenproject.org
Cc: "Stefano Stabellini" <sstabellini@kernel.org>,
	"Wei Liu" <wei.liu2@citrix.com>,
	"Konrad Rzeszutek Wilk" <konrad.wilk@oracle.com>,
	"George Dunlap" <George.Dunlap@eu.citrix.com>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Ian Jackson" <ian.jackson@eu.citrix.com>,
	"Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>,
	"Tim Deegan" <tim@xen.org>, "Julien Grall" <julien.grall@arm.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [PATCH 4/5] xen: fix handling framebuffer located above 4GB
Date: Mon,  6 May 2019 16:50:20 +0200	[thread overview]
Message-ID: <dfffbc1faf0884df46f5568cdcf9fa8c2340ae2b.1557154206.git-series.marmarek@invisiblethingslab.com> (raw)
In-Reply-To: <cover.5027956268821f50401d0ecdfad2447cbe4fdd6c.1557154206.git-series.marmarek@invisiblethingslab.com>
In-Reply-To: <cover.5027956268821f50401d0ecdfad2447cbe4fdd6c.1557154206.git-series.marmarek@invisiblethingslab.com>

On some machines (for example Thinkpad P52), UEFI GOP reports
framebuffer located above 4GB (0x4000000000 on that machine). This
address does not fit in {xen,dom0}_vga_console_info.u.vesa_lfb.lfb_base
field, which is 32bit. The overflow here cause all kind of memory
corruption when anything tries to write something on the screen,
starting with zeroing the whole framebuffer in vesa_init().

Fix this similar to how it's done in Linux: add ext_lfb_base field at
the end of the structure, to hold upper 32bits of the address. Since the
field is added at the end of the structure, it will work with older
Linux versions too (other than using possibly truncated address - no
worse than without this change). Thanks to ABI containing size of the
structure (start_info.console.dom0.info_size), Linux can detect when
this field is present and use it appropriately then.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
 xen/arch/x86/efi/efi-boot.h |  1 +
 xen/drivers/video/vesa.c    | 15 +++++++++++----
 xen/include/public/xen.h    |  2 ++
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 5789d2c..7a13a30 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -550,6 +550,7 @@ static void __init efi_arch_video_init(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
         vga_console_info.u.vesa_lfb.bytes_per_line =
             (mode_info->PixelsPerScanLine * bpp + 7) >> 3;
         vga_console_info.u.vesa_lfb.lfb_base = gop->Mode->FrameBufferBase;
+        vga_console_info.u.vesa_lfb.ext_lfb_base = gop->Mode->FrameBufferBase >> 32;
         vga_console_info.u.vesa_lfb.lfb_size =
             (gop->Mode->FrameBufferSize + 0xffff) >> 16;
     }
diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c
index c92497e..f22cf7f 100644
--- a/xen/drivers/video/vesa.c
+++ b/xen/drivers/video/vesa.c
@@ -84,6 +84,7 @@ void __init vesa_early_init(void)
 void __init vesa_init(void)
 {
     struct lfb_prop lfbp;
+    unsigned long lfb_base;
 
     if ( !font )
         return;
@@ -97,15 +98,17 @@ void __init vesa_init(void)
     lfbp.text_columns = vlfb_info.width / font->width;
     lfbp.text_rows = vlfb_info.height / font->height;
 
-    lfbp.lfb = lfb = ioremap(vlfb_info.lfb_base, vram_remap);
+    lfb_base = vlfb_info.lfb_base;
+    lfb_base |= (unsigned long)vlfb_info.ext_lfb_base << 32;
+    lfbp.lfb = lfb = ioremap(lfb_base, vram_remap);
     if ( !lfb )
         return;
 
     memset(lfb, 0, vram_remap);
 
-    printk(XENLOG_INFO "vesafb: framebuffer at %#x, mapped to 0x%p, "
+    printk(XENLOG_INFO "vesafb: framebuffer at %#lx, mapped to 0x%p, "
            "using %uk, total %uk\n",
-           vlfb_info.lfb_base, lfb,
+           lfb_base, lfb,
            vram_remap >> 10, vram_total >> 10);
     printk(XENLOG_INFO "vesafb: mode is %dx%dx%u, linelength=%d, font %ux%u\n",
            vlfb_info.width, vlfb_info.height,
@@ -152,6 +155,10 @@ void __init vesa_mtrr_init(void)
         MTRR_TYPE_WRCOMB, MTRR_TYPE_WRTHROUGH };
     unsigned int size_total;
     int rc, type;
+    unsigned long lfb_base;
+
+    lfb_base = vlfb_info.lfb_base;
+    lfb_base |= (unsigned long)vlfb_info.ext_lfb_base << 32;
 
     if ( !lfb || (vesa_mtrr == 0) || (vesa_mtrr >= ARRAY_SIZE(mtrr_types)) )
         return;
@@ -167,7 +174,7 @@ void __init vesa_mtrr_init(void)
 
     /* Try and find a power of two to add */
     do {
-        rc = mtrr_add(vlfb_info.lfb_base, size_total, type, 1);
+        rc = mtrr_add(lfb_base, size_total, type, 1);
         size_total >>= 1;
     } while ( (size_total >= PAGE_SIZE) && (rc == -EINVAL) );
 }
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index ccdffc0..b0f0f7e 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -923,6 +923,8 @@ typedef struct dom0_vga_console_info {
             /* Mode attributes (offset 0x0, VESA command 0x4f01). */
             uint16_t mode_attrs;
 #endif
+            /* high 32 bits of lfb_base */
+            uint32_t ext_lfb_base;
         } vesa_lfb;
     } u;
 } dom0_vga_console_info_t;
-- 
git-series 0.9.1

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

WARNING: multiple messages have this Message-ID (diff)
From: "Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>
To: xen-devel@lists.xenproject.org
Cc: "Stefano Stabellini" <sstabellini@kernel.org>,
	"Wei Liu" <wei.liu2@citrix.com>,
	"Konrad Rzeszutek Wilk" <konrad.wilk@oracle.com>,
	"George Dunlap" <George.Dunlap@eu.citrix.com>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Ian Jackson" <ian.jackson@eu.citrix.com>,
	"Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>,
	"Tim Deegan" <tim@xen.org>, "Julien Grall" <julien.grall@arm.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [Xen-devel] [PATCH 4/5] xen: fix handling framebuffer located above 4GB
Date: Mon,  6 May 2019 16:50:20 +0200	[thread overview]
Message-ID: <dfffbc1faf0884df46f5568cdcf9fa8c2340ae2b.1557154206.git-series.marmarek@invisiblethingslab.com> (raw)
Message-ID: <20190506145020.dgRmPpVGaZ6xjj2XBft5I9lUNB4vtBH430hs6oiNl54@z> (raw)
In-Reply-To: <cover.5027956268821f50401d0ecdfad2447cbe4fdd6c.1557154206.git-series.marmarek@invisiblethingslab.com>
In-Reply-To: <cover.5027956268821f50401d0ecdfad2447cbe4fdd6c.1557154206.git-series.marmarek@invisiblethingslab.com>

On some machines (for example Thinkpad P52), UEFI GOP reports
framebuffer located above 4GB (0x4000000000 on that machine). This
address does not fit in {xen,dom0}_vga_console_info.u.vesa_lfb.lfb_base
field, which is 32bit. The overflow here cause all kind of memory
corruption when anything tries to write something on the screen,
starting with zeroing the whole framebuffer in vesa_init().

Fix this similar to how it's done in Linux: add ext_lfb_base field at
the end of the structure, to hold upper 32bits of the address. Since the
field is added at the end of the structure, it will work with older
Linux versions too (other than using possibly truncated address - no
worse than without this change). Thanks to ABI containing size of the
structure (start_info.console.dom0.info_size), Linux can detect when
this field is present and use it appropriately then.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
 xen/arch/x86/efi/efi-boot.h |  1 +
 xen/drivers/video/vesa.c    | 15 +++++++++++----
 xen/include/public/xen.h    |  2 ++
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 5789d2c..7a13a30 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -550,6 +550,7 @@ static void __init efi_arch_video_init(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
         vga_console_info.u.vesa_lfb.bytes_per_line =
             (mode_info->PixelsPerScanLine * bpp + 7) >> 3;
         vga_console_info.u.vesa_lfb.lfb_base = gop->Mode->FrameBufferBase;
+        vga_console_info.u.vesa_lfb.ext_lfb_base = gop->Mode->FrameBufferBase >> 32;
         vga_console_info.u.vesa_lfb.lfb_size =
             (gop->Mode->FrameBufferSize + 0xffff) >> 16;
     }
diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c
index c92497e..f22cf7f 100644
--- a/xen/drivers/video/vesa.c
+++ b/xen/drivers/video/vesa.c
@@ -84,6 +84,7 @@ void __init vesa_early_init(void)
 void __init vesa_init(void)
 {
     struct lfb_prop lfbp;
+    unsigned long lfb_base;
 
     if ( !font )
         return;
@@ -97,15 +98,17 @@ void __init vesa_init(void)
     lfbp.text_columns = vlfb_info.width / font->width;
     lfbp.text_rows = vlfb_info.height / font->height;
 
-    lfbp.lfb = lfb = ioremap(vlfb_info.lfb_base, vram_remap);
+    lfb_base = vlfb_info.lfb_base;
+    lfb_base |= (unsigned long)vlfb_info.ext_lfb_base << 32;
+    lfbp.lfb = lfb = ioremap(lfb_base, vram_remap);
     if ( !lfb )
         return;
 
     memset(lfb, 0, vram_remap);
 
-    printk(XENLOG_INFO "vesafb: framebuffer at %#x, mapped to 0x%p, "
+    printk(XENLOG_INFO "vesafb: framebuffer at %#lx, mapped to 0x%p, "
            "using %uk, total %uk\n",
-           vlfb_info.lfb_base, lfb,
+           lfb_base, lfb,
            vram_remap >> 10, vram_total >> 10);
     printk(XENLOG_INFO "vesafb: mode is %dx%dx%u, linelength=%d, font %ux%u\n",
            vlfb_info.width, vlfb_info.height,
@@ -152,6 +155,10 @@ void __init vesa_mtrr_init(void)
         MTRR_TYPE_WRCOMB, MTRR_TYPE_WRTHROUGH };
     unsigned int size_total;
     int rc, type;
+    unsigned long lfb_base;
+
+    lfb_base = vlfb_info.lfb_base;
+    lfb_base |= (unsigned long)vlfb_info.ext_lfb_base << 32;
 
     if ( !lfb || (vesa_mtrr == 0) || (vesa_mtrr >= ARRAY_SIZE(mtrr_types)) )
         return;
@@ -167,7 +174,7 @@ void __init vesa_mtrr_init(void)
 
     /* Try and find a power of two to add */
     do {
-        rc = mtrr_add(vlfb_info.lfb_base, size_total, type, 1);
+        rc = mtrr_add(lfb_base, size_total, type, 1);
         size_total >>= 1;
     } while ( (size_total >= PAGE_SIZE) && (rc == -EINVAL) );
 }
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index ccdffc0..b0f0f7e 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -923,6 +923,8 @@ typedef struct dom0_vga_console_info {
             /* Mode attributes (offset 0x0, VESA command 0x4f01). */
             uint16_t mode_attrs;
 #endif
+            /* high 32 bits of lfb_base */
+            uint32_t ext_lfb_base;
         } vesa_lfb;
     } u;
 } dom0_vga_console_info_t;
-- 
git-series 0.9.1

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2019-05-06 15:03 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-06 14:50 [PATCH 0/5] Fixes for large framebuffer, placed above 4GB Marek Marczykowski-Górecki
2019-05-06 14:50 ` [Xen-devel] " Marek Marczykowski-Górecki
2019-05-06 14:50 ` [PATCH 1/5] xen/bitmap: fix bitmap_fill with zero-sized bitmap Marek Marczykowski-Górecki
2019-05-06 14:50   ` [Xen-devel] " Marek Marczykowski-Górecki
2019-05-06 15:19   ` Andrew Cooper
2019-05-06 15:19     ` [Xen-devel] " Andrew Cooper
2019-05-07  8:10   ` Jan Beulich
2019-05-07  8:10     ` [Xen-devel] " Jan Beulich
2019-05-07 15:19     ` Marek Marczykowski
2019-05-07 15:19       ` [Xen-devel] " Marek Marczykowski
2019-05-06 14:50 ` [PATCH 2/5] drivers/video: drop unused limits Marek Marczykowski-Górecki
2019-05-06 14:50   ` [Xen-devel] " Marek Marczykowski-Górecki
2019-05-06 15:19   ` Andrew Cooper
2019-05-06 15:19     ` [Xen-devel] " Andrew Cooper
2019-05-07  8:52   ` Jan Beulich
2019-05-07  8:52     ` [Xen-devel] " Jan Beulich
2019-05-06 14:50 ` [PATCH 3/5] drivers/video: Drop framebuffer size constraints Marek Marczykowski-Górecki
2019-05-06 14:50   ` [Xen-devel] " Marek Marczykowski-Górecki
2019-05-06 15:09   ` Olaf Hering
2019-05-06 15:09     ` [Xen-devel] " Olaf Hering
2019-05-06 15:33   ` Andrew Cooper
2019-05-06 15:33     ` [Xen-devel] " Andrew Cooper
2019-05-07  8:55   ` Jan Beulich
2019-05-07  8:55     ` [Xen-devel] " Jan Beulich
2019-05-06 14:50 ` Marek Marczykowski-Górecki [this message]
2019-05-06 14:50   ` [Xen-devel] [PATCH 4/5] xen: fix handling framebuffer located above 4GB Marek Marczykowski-Górecki
2019-05-06 15:15   ` Juergen Gross
2019-05-06 15:15     ` [Xen-devel] " Juergen Gross
2019-05-06 15:32     ` Marek Marczykowski-Górecki
2019-05-06 15:32       ` [Xen-devel] " Marek Marczykowski-Górecki
2019-05-07  5:07       ` Juergen Gross
2019-05-07  5:07         ` [Xen-devel] " Juergen Gross
2019-05-07  9:10       ` Jan Beulich
2019-05-07  9:10         ` [Xen-devel] " Jan Beulich
2019-05-07 15:38         ` Marek Marczykowski
2019-05-07 15:38           ` [Xen-devel] " Marek Marczykowski
2019-05-07 16:12           ` Jan Beulich
2019-05-07 16:12             ` [Xen-devel] " Jan Beulich
2019-05-07 16:43             ` Marek Marczykowski
2019-05-07 16:43               ` [Xen-devel] " Marek Marczykowski
2019-05-08  9:54               ` Jan Beulich
2019-05-08  9:54                 ` [Xen-devel] " Jan Beulich
2019-05-08 12:06                 ` Marek Marczykowski
2019-05-08 12:06                   ` [Xen-devel] " Marek Marczykowski
2019-05-08 12:45                   ` Jan Beulich
2019-05-08 12:45                     ` [Xen-devel] " Jan Beulich
2019-05-06 15:28   ` Andrew Cooper
2019-05-06 15:28     ` [Xen-devel] " Andrew Cooper
2019-05-07  9:07   ` Jan Beulich
2019-05-07  9:07     ` [Xen-devel] " Jan Beulich
2019-05-09  0:22     ` Marek Marczykowski
2019-05-09  0:22       ` [Xen-devel] " Marek Marczykowski
2019-05-09  8:59       ` Jan Beulich
2019-05-09  8:59         ` [Xen-devel] " Jan Beulich
2019-05-06 14:50 ` [PATCH 5/5] drivers/video: use vlfb_info consistently Marek Marczykowski-Górecki
2019-05-06 14:50   ` [Xen-devel] " Marek Marczykowski-Górecki
2019-05-06 15:33   ` Andrew Cooper
2019-05-06 15:33     ` [Xen-devel] " Andrew Cooper
2019-05-06 15:37 ` [PATCH 0/5] Fixes for large framebuffer, placed above 4GB Andrew Cooper
2019-05-06 15:37   ` [Xen-devel] " Andrew Cooper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dfffbc1faf0884df46f5568cdcf9fa8c2340ae2b.1557154206.git-series.marmarek@invisiblethingslab.com \
    --to=marmarek@invisiblethingslab.com \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=julien.grall@arm.com \
    --cc=konrad.wilk@oracle.com \
    --cc=roger.pau@citrix.com \
    --cc=sstabellini@kernel.org \
    --cc=tim@xen.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.