Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S937790AbdCJOIr (ORCPT ); Fri, 10 Mar 2017 09:08:47 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:42917 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933920AbdCJLvX (ORCPT ); Fri, 10 Mar 2017 06:51:23 -0500 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Joel Stanley" , "Russell Currey" , "Daniel Vetter" Date: Fri, 10 Mar 2017 11:46:22 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 118/370] drivers/gpu/drm/ast: Fix infinite loop if read fails In-Reply-To: X-SA-Exim-Connect-IP: 82.70.136.246 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1641 Lines: 48 3.16.42-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Russell Currey commit 298360af3dab45659810fdc51aba0c9f4097e4f6 upstream. ast_get_dram_info() configures a window in order to access BMC memory. A BMC register can be configured to disallow this, and if so, causes an infinite loop in the ast driver which renders the system unusable. Fix this by erroring out if an error is detected. On powerpc systems with EEH, this leads to the device being fenced and the system continuing to operate. Signed-off-by: Russell Currey Reviewed-by: Joel Stanley Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161215051241.20815-1-ruscur@russell.cc Signed-off-by: Ben Hutchings --- drivers/gpu/drm/ast/ast_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -178,7 +178,8 @@ static int ast_get_dram_info(struct drm_ ast_write32(ast, 0x10000, 0xfc600309); do { - ; + if (pci_channel_offline(dev->pdev)) + return -EIO; } while (ast_read32(ast, 0x10000) != 0x01); data = ast_read32(ast, 0x10004); @@ -369,7 +370,9 @@ int ast_driver_load(struct drm_device *d ast_detect_chip(dev); if (ast->chip != AST1180) { - ast_get_dram_info(dev); + ret = ast_get_dram_info(dev); + if (ret) + goto out_free; ast->vram_size = ast_get_vram_info(dev); DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); }