[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 4/5] xen: fix handling framebuffer located above 4GB


  • To: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Juergen Gross <jgross@xxxxxxxx>
  • Date: Mon, 6 May 2019 17:15:19 +0200
  • Autocrypt: addr=jgross@xxxxxxxx; prefer-encrypt=mutual; keydata= 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
  • Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>, Wei Liu <wei.liu2@xxxxxxxxxx>, Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>, George Dunlap <George.Dunlap@xxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Ian Jackson <ian.jackson@xxxxxxxxxxxxx>, Tim Deegan <tim@xxxxxxx>, Julien Grall <julien.grall@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Mon, 06 May 2019 15:15:39 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Openpgp: preference=signencrypt

On 06/05/2019 16:50, Marek Marczykowski-Górecki wrote:
> 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@xxxxxxxxxxxxxxxxxxxxxx>
> ---
>  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;

You will need to put this addition into an:

#if __XEN_INTERFACE_VERSION__ >= 0x00040d00
...
#endif

section (only available from Xen 4.13 onwards).


Juergen

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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.