From e01f36d6f7055f4cfde667e290aba834032954cd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Jul 2017 09:37:21 +0200 Subject: [PATCH] 4.9-stable patches added patches: drm-ast-handle-configuration-without-p2a-bridge.patch mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch --- ...dle-configuration-without-p2a-bridge.patch | 412 ++++++++++++++++++ ...le-when-neeed-in-swap_cgroup_swapoff.patch | 40 ++ queue-4.9/series | 2 + 3 files changed, 454 insertions(+) create mode 100644 queue-4.9/drm-ast-handle-configuration-without-p2a-bridge.patch create mode 100644 queue-4.9/mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch diff --git a/queue-4.9/drm-ast-handle-configuration-without-p2a-bridge.patch b/queue-4.9/drm-ast-handle-configuration-without-p2a-bridge.patch new file mode 100644 index 00000000000..acfb21572a0 --- /dev/null +++ b/queue-4.9/drm-ast-handle-configuration-without-p2a-bridge.patch @@ -0,0 +1,412 @@ +From 71f677a91046599ece96ebab21df956ce909c456 Mon Sep 17 00:00:00 2001 +From: Russell Currey +Date: Fri, 17 Feb 2017 14:33:01 +1100 +Subject: drm/ast: Handle configuration without P2A bridge + +From: Russell Currey + +commit 71f677a91046599ece96ebab21df956ce909c456 upstream. + +The ast driver configures a window to enable access into BMC +memory space in order to read some configuration registers. + +If this window is disabled, which it can be from the BMC side, +the ast driver can't function. + +Closing this window is a necessity for security if a machine's +host side and BMC side are controlled by different parties; +i.e. a cloud provider offering machines "bare metal". + +A recent patch went in to try to check if that window is open +but it does so by trying to access the registers in question +and testing if the result is 0xffffffff. + +This method will trigger a PCIe error when the window is closed +which on some systems will be fatal (it will trigger an EEH +for example on POWER which will take out the device). + +This patch improves this in two ways: + + - First, if the firmware has put properties in the device-tree +containing the relevant configuration information, we use these. + + - Otherwise, a bit in one of the SCU scratch registers (which +are readable via the VGA register space and writeable by the BMC) +will indicate if the BMC has closed the window. This bit has been +defined by Y.C Chen from Aspeed. + +If the window is closed and the configuration isn't available from +the device-tree, some sane defaults are used. Those defaults are +hopefully sufficient for standard video modes used on a server. + +Signed-off-by: Russell Currey +Acked-by: Joel Stanley +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Dave Airlie +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/ast/ast_drv.h | 6 + drivers/gpu/drm/ast/ast_main.c | 264 +++++++++++++++++++++++++---------------- + drivers/gpu/drm/ast/ast_post.c | 7 - + 3 files changed, 168 insertions(+), 109 deletions(-) + +--- a/drivers/gpu/drm/ast/ast_drv.h ++++ b/drivers/gpu/drm/ast/ast_drv.h +@@ -113,7 +113,11 @@ struct ast_private { + struct ttm_bo_kmap_obj cache_kmap; + int next_cursor; + bool support_wide_screen; +- bool DisableP2A; ++ enum { ++ ast_use_p2a, ++ ast_use_dt, ++ ast_use_defaults ++ } config_mode; + + enum ast_tx_chip tx_chip_type; + u8 dp501_maxclk; +--- a/drivers/gpu/drm/ast/ast_main.c ++++ b/drivers/gpu/drm/ast/ast_main.c +@@ -62,13 +62,84 @@ uint8_t ast_get_index_reg_mask(struct as + return ret; + } + ++static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) ++{ ++ struct device_node *np = dev->pdev->dev.of_node; ++ struct ast_private *ast = dev->dev_private; ++ uint32_t data, jregd0, jregd1; ++ ++ /* Defaults */ ++ ast->config_mode = ast_use_defaults; ++ *scu_rev = 0xffffffff; ++ ++ /* Check if we have device-tree properties */ ++ if (np && !of_property_read_u32(np, "aspeed,scu-revision-id", ++ scu_rev)) { ++ /* We do, disable P2A access */ ++ ast->config_mode = ast_use_dt; ++ DRM_INFO("Using device-tree for configuration\n"); ++ return; ++ } ++ ++ /* Not all families have a P2A bridge */ ++ if (dev->pdev->device != PCI_CHIP_AST2000) ++ return; ++ ++ /* ++ * The BMC will set SCU 0x40 D[12] to 1 if the P2 bridge ++ * is disabled. We force using P2A if VGA only mode bit ++ * is set D[7] ++ */ ++ jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); ++ jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); ++ if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) { ++ /* Double check it's actually working */ ++ data = ast_read32(ast, 0xf004); ++ if (data != 0xFFFFFFFF) { ++ /* P2A works, grab silicon revision */ ++ ast->config_mode = ast_use_p2a; ++ ++ DRM_INFO("Using P2A bridge for configuration\n"); ++ ++ /* Read SCU7c (silicon revision register) */ ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ *scu_rev = ast_read32(ast, 0x1207c); ++ return; ++ } ++ } ++ ++ /* We have a P2A bridge but it's disabled */ ++ DRM_INFO("P2A bridge disabled, using default configuration\n"); ++} + + static int ast_detect_chip(struct drm_device *dev, bool *need_post) + { + struct ast_private *ast = dev->dev_private; +- uint32_t data, jreg; ++ uint32_t jreg, scu_rev; ++ ++ /* ++ * If VGA isn't enabled, we need to enable now or subsequent ++ * access to the scratch registers will fail. We also inform ++ * our caller that it needs to POST the chip ++ * (Assumption: VGA not enabled -> need to POST) ++ */ ++ if (!ast_is_vga_enabled(dev)) { ++ ast_enable_vga(dev); ++ DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); ++ *need_post = true; ++ } else ++ *need_post = false; ++ ++ ++ /* Enable extended register access */ ++ ast_enable_mmio(dev); + ast_open_key(ast); + ++ /* Find out whether P2A works or whether to use device-tree */ ++ ast_detect_config_mode(dev, &scu_rev); ++ ++ /* Identify chipset */ + if (dev->pdev->device == PCI_CHIP_AST1180) { + ast->chip = AST1100; + DRM_INFO("AST 1180 detected\n"); +@@ -80,12 +151,7 @@ static int ast_detect_chip(struct drm_de + ast->chip = AST2300; + DRM_INFO("AST 2300 detected\n"); + } else if (dev->pdev->revision >= 0x10) { +- uint32_t data; +- ast_write32(ast, 0xf004, 0x1e6e0000); +- ast_write32(ast, 0xf000, 0x1); +- +- data = ast_read32(ast, 0x1207c); +- switch (data & 0x0300) { ++ switch (scu_rev & 0x0300) { + case 0x0200: + ast->chip = AST1100; + DRM_INFO("AST 1100 detected\n"); +@@ -110,26 +176,6 @@ static int ast_detect_chip(struct drm_de + } + } + +- /* +- * If VGA isn't enabled, we need to enable now or subsequent +- * access to the scratch registers will fail. We also inform +- * our caller that it needs to POST the chip +- * (Assumption: VGA not enabled -> need to POST) +- */ +- if (!ast_is_vga_enabled(dev)) { +- ast_enable_vga(dev); +- ast_enable_mmio(dev); +- DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); +- *need_post = true; +- } else +- *need_post = false; +- +- /* Check P2A Access */ +- ast->DisableP2A = true; +- data = ast_read32(ast, 0xf004); +- if (data != 0xFFFFFFFF) +- ast->DisableP2A = false; +- + /* Check if we support wide screen */ + switch (ast->chip) { + case AST1180: +@@ -146,17 +192,12 @@ static int ast_detect_chip(struct drm_de + ast->support_wide_screen = true; + else { + ast->support_wide_screen = false; +- if (ast->DisableP2A == false) { +- /* Read SCU7c (silicon revision register) */ +- ast_write32(ast, 0xf004, 0x1e6e0000); +- ast_write32(ast, 0xf000, 0x1); +- data = ast_read32(ast, 0x1207c); +- data &= 0x300; +- if (ast->chip == AST2300 && data == 0x0) /* ast1300 */ +- ast->support_wide_screen = true; +- if (ast->chip == AST2400 && data == 0x100) /* ast1400 */ +- ast->support_wide_screen = true; +- } ++ if (ast->chip == AST2300 && ++ (scu_rev & 0x300) == 0x0) /* ast1300 */ ++ ast->support_wide_screen = true; ++ if (ast->chip == AST2400 && ++ (scu_rev & 0x300) == 0x100) /* ast1400 */ ++ ast->support_wide_screen = true; + } + break; + } +@@ -220,85 +261,102 @@ static int ast_detect_chip(struct drm_de + + static int ast_get_dram_info(struct drm_device *dev) + { ++ struct device_node *np = dev->pdev->dev.of_node; + struct ast_private *ast = dev->dev_private; +- uint32_t data, data2; +- uint32_t denum, num, div, ref_pll; ++ uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap; ++ uint32_t denum, num, div, ref_pll, dsel; + +- if (ast->DisableP2A) +- { ++ switch (ast->config_mode) { ++ case ast_use_dt: ++ /* ++ * If some properties are missing, use reasonable ++ * defaults for AST2400 ++ */ ++ if (of_property_read_u32(np, "aspeed,mcr-configuration", ++ &mcr_cfg)) ++ mcr_cfg = 0x00000577; ++ if (of_property_read_u32(np, "aspeed,mcr-scu-mpll", ++ &mcr_scu_mpll)) ++ mcr_scu_mpll = 0x000050C0; ++ if (of_property_read_u32(np, "aspeed,mcr-scu-strap", ++ &mcr_scu_strap)) ++ mcr_scu_strap = 0; ++ break; ++ case ast_use_p2a: ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ mcr_cfg = ast_read32(ast, 0x10004); ++ mcr_scu_mpll = ast_read32(ast, 0x10120); ++ mcr_scu_strap = ast_read32(ast, 0x10170); ++ break; ++ case ast_use_defaults: ++ default: + ast->dram_bus_width = 16; + ast->dram_type = AST_DRAM_1Gx16; + ast->mclk = 396; ++ return 0; + } +- else +- { +- ast_write32(ast, 0xf004, 0x1e6e0000); +- ast_write32(ast, 0xf000, 0x1); +- data = ast_read32(ast, 0x10004); + +- if (data & 0x40) +- ast->dram_bus_width = 16; +- else +- ast->dram_bus_width = 32; +- +- if (ast->chip == AST2300 || ast->chip == AST2400) { +- switch (data & 0x03) { +- case 0: +- ast->dram_type = AST_DRAM_512Mx16; +- break; +- default: +- case 1: +- ast->dram_type = AST_DRAM_1Gx16; +- break; +- case 2: +- ast->dram_type = AST_DRAM_2Gx16; +- break; +- case 3: +- ast->dram_type = AST_DRAM_4Gx16; +- break; +- } +- } else { +- switch (data & 0x0c) { +- case 0: +- case 4: +- ast->dram_type = AST_DRAM_512Mx16; +- break; +- case 8: +- if (data & 0x40) +- ast->dram_type = AST_DRAM_1Gx16; +- else +- ast->dram_type = AST_DRAM_512Mx32; +- break; +- case 0xc: +- ast->dram_type = AST_DRAM_1Gx32; +- break; +- } +- } ++ if (mcr_cfg & 0x40) ++ ast->dram_bus_width = 16; ++ else ++ ast->dram_bus_width = 32; + +- data = ast_read32(ast, 0x10120); +- data2 = ast_read32(ast, 0x10170); +- if (data2 & 0x2000) +- ref_pll = 14318; +- else +- ref_pll = 12000; +- +- denum = data & 0x1f; +- num = (data & 0x3fe0) >> 5; +- data = (data & 0xc000) >> 14; +- switch (data) { +- case 3: +- div = 0x4; ++ if (ast->chip == AST2300 || ast->chip == AST2400) { ++ switch (mcr_cfg & 0x03) { ++ case 0: ++ ast->dram_type = AST_DRAM_512Mx16; + break; +- case 2: ++ default: + case 1: +- div = 0x2; ++ ast->dram_type = AST_DRAM_1Gx16; + break; +- default: +- div = 0x1; ++ case 2: ++ ast->dram_type = AST_DRAM_2Gx16; ++ break; ++ case 3: ++ ast->dram_type = AST_DRAM_4Gx16; ++ break; ++ } ++ } else { ++ switch (mcr_cfg & 0x0c) { ++ case 0: ++ case 4: ++ ast->dram_type = AST_DRAM_512Mx16; ++ break; ++ case 8: ++ if (mcr_cfg & 0x40) ++ ast->dram_type = AST_DRAM_1Gx16; ++ else ++ ast->dram_type = AST_DRAM_512Mx32; ++ break; ++ case 0xc: ++ ast->dram_type = AST_DRAM_1Gx32; + break; + } +- ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000); + } ++ ++ if (mcr_scu_strap & 0x2000) ++ ref_pll = 14318; ++ else ++ ref_pll = 12000; ++ ++ denum = mcr_scu_mpll & 0x1f; ++ num = (mcr_scu_mpll & 0x3fe0) >> 5; ++ dsel = (mcr_scu_mpll & 0xc000) >> 14; ++ switch (dsel) { ++ case 3: ++ div = 0x4; ++ break; ++ case 2: ++ case 1: ++ div = 0x2; ++ break; ++ default: ++ div = 0x1; ++ break; ++ } ++ ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000); + return 0; + } + +--- a/drivers/gpu/drm/ast/ast_post.c ++++ b/drivers/gpu/drm/ast/ast_post.c +@@ -375,17 +375,14 @@ void ast_post_gpu(struct drm_device *dev + ast_enable_mmio(dev); + ast_set_def_ext_reg(dev); + +- if (ast->DisableP2A == false) +- { ++ if (ast->config_mode == ast_use_p2a) { + if (ast->chip == AST2300 || ast->chip == AST2400) + ast_init_dram_2300(dev); + else + ast_init_dram_reg(dev); + + ast_init_3rdtx(dev); +- } +- else +- { ++ } else { + if (ast->tx_chip_type != AST_TX_NONE) + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); /* Enable DVO */ + } diff --git a/queue-4.9/mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch b/queue-4.9/mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch new file mode 100644 index 00000000000..b01b0def853 --- /dev/null +++ b/queue-4.9/mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch @@ -0,0 +1,40 @@ +From 460bcec84e11c75122ace5976214abbc596eb91b Mon Sep 17 00:00:00 2001 +From: David Rientjes +Date: Fri, 7 Apr 2017 16:05:00 -0700 +Subject: mm, swap_cgroup: reschedule when neeed in swap_cgroup_swapoff() + +From: David Rientjes + +commit 460bcec84e11c75122ace5976214abbc596eb91b upstream. + +We got need_resched() warnings in swap_cgroup_swapoff() because +swap_cgroup_ctrl[type].length is particularly large. + +Reschedule when needed. + +Link: http://lkml.kernel.org/r/alpine.DEB.2.10.1704061315270.80559@chino.kir.corp.google.com +Signed-off-by: David Rientjes +Acked-by: Michal Hocko +Cc: Johannes Weiner +Cc: Vladimir Davydov +Cc: KAMEZAWA Hiroyuki +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + mm/swap_cgroup.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/mm/swap_cgroup.c ++++ b/mm/swap_cgroup.c +@@ -204,6 +204,8 @@ void swap_cgroup_swapoff(int type) + struct page *page = map[i]; + if (page) + __free_page(page); ++ if (!(i % SWAP_CLUSTER_MAX)) ++ cond_resched(); + } + vfree(map); + } diff --git a/queue-4.9/series b/queue-4.9/series index df859de7613..85b89279bcc 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -28,3 +28,5 @@ netfilter-synproxy-fix-conntrackd-interaction.patch nfsv4-fix-a-reference-leak-caused-warning-messages.patch nfsv4.x-callback-create-the-callback-service-through-svc_create_pooled.patch xen-blkback-don-t-use-xen_blkif_get-in-xen-blkback-kthread.patch +drm-ast-handle-configuration-without-p2a-bridge.patch +mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch -- 2.47.3