From patchwork Fri Jun 15 10:48:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 138670 Delivered-To: patch@linaro.org Received: by 2002:a2e:970d:0:0:0:0:0 with SMTP id r13-v6csp678336lji; Fri, 15 Jun 2018 03:48:30 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIga/TM05ZVTg+49JM56vfKXC725rV0ukD2teqfjFI2oj4UXQvJ7uRszEn3+zPayJWpUnWJ X-Received: by 2002:a17:902:b590:: with SMTP id a16-v6mr1436812pls.225.1529059709921; Fri, 15 Jun 2018 03:48:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529059709; cv=none; d=google.com; s=arc-20160816; b=GGht3aak9M/Ps4BIeb3/OW5vqdO4EqhwsjJEuGV5UKl5cFCMkocDoXly+nt44+ropE lfl6wtaf/hMpipGiO9kum1GY5hMCPRjC98fnEV9hXbIOIxQDbVLfPwxaEVioJHTsUWxc xx6HYeR3mQDXtgN7Ffw0fF8ALpMUwy6LZEB6vD6PtIKnSVjbPHX/3zFVOqtqm3Vat+Mc N4F1VfJ1Bh26rpEgMYz+FgPTy9t3Ypa81tTMtP44xFcw5B0kp06zo5vBy3iAa9NwA8uw ZMG/cV6Gx2VDRqaqs+hkOKE6klZiUbVVaCITnpoK7GVDPSSqb8DBV5fOABF7gMVBpzy0 sQdg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=1SdQvxHegKb61jUCxAbFzgSxIklJHsiu2JVHK+f79Zs=; b=LBuKOmqOcEeGR2as9CYMMTgiQSBQcOLeorgc01Vv6on90IZROO/x4vYbk3viCnduLl XlQMRjs8XwDzg4IWzp+JKMI/nmsCdVMQJH0v9mlWUoLIeDdE6nlVU7ZZNXdAq70mMcl9 tRAt78wctaD77J4P/Z5luEpGixJYfvaKmJAQhW5FWPjcbLA5YQt88IgXzqG612PTtM6F uE0EIZGS6eC0ooNZDoCrCXKn9LvpWednWdw9YJNuqv4ofaI0hG/ZZAlGBha0EQXo1LBD dGI4ijJw0Rw7tpvUZncN+JQTWS89rGwTlkf/KqKoSO0XgUL6sCvKfR7m9B1K5t6qMrIs bW1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=iLGdoZ25; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m12-v6si7693135pll.461.2018.06.15.03.48.29; Fri, 15 Jun 2018 03:48:29 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=iLGdoZ25; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965590AbeFOKs3 (ORCPT + 2 others); Fri, 15 Jun 2018 06:48:29 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:45103 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965639AbeFOKs2 (ORCPT ); Fri, 15 Jun 2018 06:48:28 -0400 Received: by mail-wr0-f196.google.com with SMTP id o12-v6so9448347wrm.12 for ; Fri, 15 Jun 2018 03:48:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cPKfVWxcLbqfV3prDZofsBTbyU28R8bjcFrDo3puhRg=; b=iLGdoZ25xdxSv0AuZWNEnxo4lQpfp+JENR0CREQx3p5IFbMzM8Hp464TAszaFttI3+ mwrbIrGNNFRpEiZmwrWwbRCOUF0j+mItnfTHQxvibKP4GpcJko0GS0IBvK6sc1lMFGAd Gjd2EsvklRZEWSsCsevnY8aKmWkRK1qow+ktk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cPKfVWxcLbqfV3prDZofsBTbyU28R8bjcFrDo3puhRg=; b=Qa/GaGGKLtjXU2hjDMNogsWQupdqmMk35Hz6WAyZkGiOnjLo9eCUNROO04g+HtIzYa zIbx2ypvnpT+4/1p6BHHdHukiemn9zyTIxJuTL9BXoI8SQ9zDpC7+hHAxCA4DnwccKeS /01CPEFjR1yubmOcm7QPJMwkDp7VFt/qn0VNTvamIhiW/20ZfY+cy1a1Unir7SipAQuX BkeUQ/uGjlwFpsm43rDCOn1BbGZ0/3D2rM2tUoAD8yjPnFLTWGs+yi9g6p+S3Wks3V/j nselaqXK7ijriQkjtntXwNdAcKX/ABVGCqZFBk3fw+gHDEv8xfpqGsVuFIRYScj5onZz HzbQ== X-Gm-Message-State: APt69E181zZhpm7ychfGZB4mL2U9BFrRLcxc5UzZ4yogQvv7+XgqXJGR 6oz/RpHsQia73GGXzguqmIfpGlDe86s= X-Received: by 2002:adf:9487:: with SMTP id 7-v6mr1263438wrr.82.1529059707153; Fri, 15 Jun 2018 03:48:27 -0700 (PDT) Received: from dogfood.home ([2a01:cb1d:112:6f00:3805:d7d2:48be:b40a]) by smtp.gmail.com with ESMTPSA id a9-v6sm1393914wmh.38.2018.06.15.03.48.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Jun 2018 03:48:26 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: lersek@redhat.com, pjones@redhat.com, kraxel@redhat.com, Ard Biesheuvel Subject: [PATCH 2/2] fbdev/efifb: honour UEFI memory map attributes when mapping the fb Date: Fri, 15 Jun 2018 12:48:18 +0200 Message-Id: <20180615104818.23013-3-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180615104818.23013-1-ard.biesheuvel@linaro.org> References: <20180615104818.23013-1-ard.biesheuvel@linaro.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org If the framebuffer address provided by the Graphics Output Protocol (GOP) is covered by the UEFI memory map, it will tell us which memory attributes are permitted when mapping this region. In some cases, (KVM guest on ARM), violating this will result in loss of coherency, which means that updates sent to the framebuffer by the guest will not be observeable by the host, and the emulated display simply does not work. So if the memory map contains such a description, take the attributes field into account, and add support for creating WT or WB mappings of the framebuffer region. Cc: Peter Jones Signed-off-by: Ard Biesheuvel --- drivers/video/fbdev/efifb.c | 52 ++++++++++++++++---- 1 file changed, 42 insertions(+), 10 deletions(-) -- 2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index 46a4484e3da7..d5e0a74e6124 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -20,7 +20,7 @@ #include /* For DRM_MODE_PANEL_ORIENTATION_* */ static bool request_mem_succeeded = false; -static bool nowc = false; +static u64 mem_flags = EFI_MEMORY_WC | EFI_MEMORY_UC; static struct fb_var_screeninfo efifb_defined = { .activate = FB_ACTIVATE_NOW, @@ -68,8 +68,12 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, static void efifb_destroy(struct fb_info *info) { - if (info->screen_base) - iounmap(info->screen_base); + if (info->screen_base) { + if (mem_flags & (EFI_MEMORY_WT | EFI_MEMORY_WB)) + memunmap(info->screen_base); + else + iounmap(info->screen_base); + } if (request_mem_succeeded) release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); @@ -104,7 +108,7 @@ static int efifb_setup(char *options) else if (!strncmp(this_opt, "width:", 6)) screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0); else if (!strcmp(this_opt, "nowc")) - nowc = true; + mem_flags &= ~EFI_MEMORY_WC; } } @@ -164,6 +168,8 @@ static int efifb_probe(struct platform_device *dev) unsigned int size_remap; unsigned int size_total; char *option = NULL; + efi_memory_desc_t md; + if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled) return -ENODEV; @@ -272,12 +278,35 @@ static int efifb_probe(struct platform_device *dev) info->apertures->ranges[0].base = efifb_fix.smem_start; info->apertures->ranges[0].size = size_remap; - if (nowc) - info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); - else - info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len); + if (!efi_mem_desc_lookup(efifb_fix.smem_start, &md)) { + if ((efifb_fix.smem_start + efifb_fix.smem_len) > + (md.phys_addr + (md.num_pages << EFI_PAGE_SHIFT))) { + pr_err("efifb: video memory @ 0x%lx spans multiple EFI memory regions\n", + efifb_fix.smem_start); + err = -EIO; + goto err_release_fb; + } + /* + * If the UEFI memory map covers the efifb region, we may only + * remap it using the attributes the memory map prescribes. + */ + mem_flags |= EFI_MEMORY_WT | EFI_MEMORY_WB; + mem_flags &= md.attribute; + } + if (mem_flags & EFI_MEMORY_WC) + info->screen_base = ioremap_wc(efifb_fix.smem_start, + efifb_fix.smem_len); + else if (mem_flags & EFI_MEMORY_UC) + info->screen_base = ioremap(efifb_fix.smem_start, + efifb_fix.smem_len); + else if (mem_flags & EFI_MEMORY_WT) + info->screen_base = memremap(efifb_fix.smem_start, + efifb_fix.smem_len, MEMREMAP_WT); + else if (mem_flags & EFI_MEMORY_WB) + info->screen_base = memremap(efifb_fix.smem_start, + efifb_fix.smem_len, MEMREMAP_WB); if (!info->screen_base) { - pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n", + pr_err("efifb: abort, cannot remap video memory 0x%x @ 0x%lx\n", efifb_fix.smem_len, efifb_fix.smem_start); err = -EIO; goto err_release_fb; @@ -371,7 +400,10 @@ static int efifb_probe(struct platform_device *dev) err_groups: sysfs_remove_groups(&dev->dev.kobj, efifb_groups); err_unmap: - iounmap(info->screen_base); + if (mem_flags & (EFI_MEMORY_WT | EFI_MEMORY_WB)) + memunmap(info->screen_base); + else + iounmap(info->screen_base); err_release_fb: framebuffer_release(info); err_release_mem: