Received: by 2002:a25:86ce:0:0:0:0:0 with SMTP id y14csp2188327ybm; Thu, 23 May 2019 12:49:28 -0700 (PDT) X-Google-Smtp-Source: APXvYqxXRXDHo5oC11eB6EHO0+0Djoc+YW2QyaHfHYSoBIIR0W7tOAjJdDw4MeaIjJPj3rygt/pp X-Received: by 2002:a17:902:9f85:: with SMTP id g5mr95987914plq.29.1558640968034; Thu, 23 May 2019 12:49:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558640968; cv=none; d=google.com; s=arc-20160816; b=kofxhvDndwbvqJdzifxl1FOzmtlpTzZDBH7xs0OvXKTCsW1ygXuCZ/ZAhZ4mIKMbBv H8B53eLlt5JLnhkrrjPP2qjqqPMRdtDsRhjmURf9q4EnSQWemAAr/qoC+vDgcx0SGoai w7lgo525mrJTU5Fp/+pvIM99pmKwJU29KrviqAKKxxadC0ItwD+s4YHd0jpRfIfDqB26 rYhctHXb90I/NwNTrfuJWVGQWXM4xBCrnqGTnTaM2sLHVzcDZOzEBkptHfJ1w5zGoat3 YUXX2Ml9zfPkf2ytIWJEI72MCFhIUa0szu2Qn5im2lsLZavLxD6GUNPsfPvEBUDQKAdC Xzyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=N7iRhfKLTOwFURPjCIU39PPkGpBrOjvQXE0TPR44dd8=; b=fvrGEYxElIGId/djw9IoKlvSLyEtpwALCJeGVt/pwueWC/KrhOnxJ7S9uCp+WQ0sJc zjTQMWYTqISHAzUYUAudtGM2QCn80uGq4O2hZl8uYbEeY6ays+Vry4qEJvYwrFQTq8rV 22+KIgB7mlRdrWsmn2qNs4L2cEXOmW65JvGpWphAVLV11SOMPjMxCN808b8T2Z5Fu5kx 9pCgpq73ZECGSkvun4CgD+8jxh1rRdelM7KQzh44Lg47rpWkoHRz2zN3zVbVH0wRzQ1Y E78/N6jrqLtBs6+Iqfg2Aj7rtXXRPE2C7xzcaN4hUiVdCmgkux/2NV+ZwLVcFohv4Y8u tEjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=h+hekNXj; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v65si570412pfb.77.2019.05.23.12.49.13; Thu, 23 May 2019 12:49:28 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=h+hekNXj; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388423AbfEWTMR (ORCPT + 99 others); Thu, 23 May 2019 15:12:17 -0400 Received: from mail.kernel.org ([198.145.29.99]:45962 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388414AbfEWTMQ (ORCPT ); Thu, 23 May 2019 15:12:16 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 68676217D7; Thu, 23 May 2019 19:12:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558638734; bh=AxJsAR8dpjeA9qCIvZZYVwgDd+oYyxFSMJaIX6clBMk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=h+hekNXjW+FATUZKy8yn04bOWo0Ow2vAAfrwTf7xj/Q5fMkL+5N50jOztzkSFerP0 FRLCCcnUQUoZl7FqvmUIDwvk8f/VxOvFmxy2EnxlOGdZmlEnHEqGNGC01jgeMsvjtj SnxKCGX7PQAwc1h0AZ1SOzrza5k8H89tQljtlMsw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Yifeng Li , Sudip Mukherjee , Teddy Wang , Bartlomiej Zolnierkiewicz Subject: [PATCH 4.14 45/77] fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping VRAM Date: Thu, 23 May 2019 21:06:03 +0200 Message-Id: <20190523181726.327762305@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190523181719.982121681@linuxfoundation.org> References: <20190523181719.982121681@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Yifeng Li commit 9e0e59993df0601cddb95c4f6c61aa3d5e753c00 upstream. On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), running fbtest or X will crash the machine instantly, because the VRAM/framebuffer is not mapped correctly. On SM712, the framebuffer starts at the beginning of address space, but SM720's framebuffer starts at the 1 MiB offset from the beginning. However, sm712fb fails to take this into account, as a result, writing to the framebuffer will destroy all the registers and kill the system immediately. Another problem is the driver assumes 8 MiB of VRAM for SM720, but some SM720 system, such as this IBM Thinkpad, only has 4 MiB of VRAM. Fix this problem by removing the hardcoded VRAM size, adding a function to query the amount of VRAM from register MCR76 on SM720, and adding proper framebuffer offset. Please note that the memory map may have additional problems on Big-Endian system, which is not available for testing by myself. But I highly suspect that the original code is also broken on Big-Endian machines for SM720, so at least we are not making the problem worse. More, the driver also assumed SM710/SM712 has 4 MiB of VRAM, but it has a 2 MiB version as well, and used in earlier laptops, such as IBM Thinkpad 240X, the driver would probably crash on them. I've never seen one of those machines and cannot fix it, but I have documented these problems in the comments. Signed-off-by: Yifeng Li Tested-by: Sudip Mukherjee Cc: Teddy Wang Cc: # v4.4+ Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/sm712.h | 5 ---- drivers/video/fbdev/sm712fb.c | 48 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 9 deletions(-) --- a/drivers/video/fbdev/sm712.h +++ b/drivers/video/fbdev/sm712.h @@ -19,11 +19,6 @@ #define SCREEN_Y_RES 600 #define SCREEN_BPP 16 -/*Assume SM712 graphics chip has 4MB VRAM */ -#define SM712_VIDEOMEMORYSIZE 0x00400000 -/*Assume SM722 graphics chip has 8MB VRAM */ -#define SM722_VIDEOMEMORYSIZE 0x00800000 - #define dac_reg (0x3c8) #define dac_val (0x3c9) --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1329,6 +1329,11 @@ static int smtc_map_smem(struct smtcfb_i { sfb->fb->fix.smem_start = pci_resource_start(pdev, 0); + if (sfb->chip_id == 0x720) + /* on SM720, the framebuffer starts at the 1 MB offset */ + sfb->fb->fix.smem_start += 0x00200000; + + /* XXX: is it safe for SM720 on Big-Endian? */ if (sfb->fb->var.bits_per_pixel == 32) sfb->fb->fix.smem_start += big_addr; @@ -1366,12 +1371,45 @@ static inline void sm7xx_init_hw(void) outb_p(0x11, 0x3c5); } +static u_long sm7xx_vram_probe(struct smtcfb_info *sfb) +{ + u8 vram; + + switch (sfb->chip_id) { + case 0x710: + case 0x712: + /* + * Assume SM712 graphics chip has 4MB VRAM. + * + * FIXME: SM712 can have 2MB VRAM, which is used on earlier + * laptops, such as IBM Thinkpad 240X. This driver would + * probably crash on those machines. If anyone gets one of + * those and is willing to help, run "git blame" and send me + * an E-mail. + */ + return 0x00400000; + case 0x720: + outb_p(0x76, 0x3c4); + vram = inb_p(0x3c5) >> 6; + + if (vram == 0x00) + return 0x00800000; /* 8 MB */ + else if (vram == 0x01) + return 0x01000000; /* 16 MB */ + else if (vram == 0x02) + return 0x00400000; /* illegal, fallback to 4 MB */ + else if (vram == 0x03) + return 0x00400000; /* 4 MB */ + } + return 0; /* unknown hardware */ +} + static int smtcfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct smtcfb_info *sfb; struct fb_info *info; - u_long smem_size = 0x00800000; /* default 8MB */ + u_long smem_size; int err; unsigned long mmio_base; @@ -1428,12 +1466,15 @@ static int smtcfb_pci_probe(struct pci_d mmio_base = pci_resource_start(pdev, 0); pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id); + smem_size = sm7xx_vram_probe(sfb); + dev_info(&pdev->dev, "%lu MiB of VRAM detected.\n", + smem_size / 1048576); + switch (sfb->chip_id) { case 0x710: case 0x712: sfb->fb->fix.mmio_start = mmio_base + 0x00400000; sfb->fb->fix.mmio_len = 0x00400000; - smem_size = SM712_VIDEOMEMORYSIZE; sfb->lfb = ioremap(mmio_base, mmio_addr); if (!sfb->lfb) { dev_err(&pdev->dev, @@ -1465,8 +1506,7 @@ static int smtcfb_pci_probe(struct pci_d case 0x720: sfb->fb->fix.mmio_start = mmio_base; sfb->fb->fix.mmio_len = 0x00200000; - smem_size = SM722_VIDEOMEMORYSIZE; - sfb->dp_regs = ioremap(mmio_base, 0x00a00000); + sfb->dp_regs = ioremap(mmio_base, 0x00200000 + smem_size); sfb->lfb = sfb->dp_regs + 0x00200000; sfb->mmio = (smtc_regbaseaddress = sfb->dp_regs + 0x000c0000);