]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Jul 2017 07:37:04 +0000 (09:37 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Jul 2017 07:37:04 +0000 (09:37 +0200)
added patches:
drm-ast-handle-configuration-without-p2a-bridge.patch
mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch

queue-4.4/drm-ast-handle-configuration-without-p2a-bridge.patch [new file with mode: 0644]
queue-4.4/mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/drm-ast-handle-configuration-without-p2a-bridge.patch b/queue-4.4/drm-ast-handle-configuration-without-p2a-bridge.patch
new file mode 100644 (file)
index 0000000..acfb215
--- /dev/null
@@ -0,0 +1,412 @@
+From 71f677a91046599ece96ebab21df956ce909c456 Mon Sep 17 00:00:00 2001
+From: Russell Currey <ruscur@russell.cc>
+Date: Fri, 17 Feb 2017 14:33:01 +1100
+Subject: drm/ast: Handle configuration without P2A bridge
+
+From: Russell Currey <ruscur@russell.cc>
+
+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 <ruscur@russell.cc>
+Acked-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Cc: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.4/mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch b/queue-4.4/mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch
new file mode 100644 (file)
index 0000000..4f0385b
--- /dev/null
@@ -0,0 +1,40 @@
+From 460bcec84e11c75122ace5976214abbc596eb91b Mon Sep 17 00:00:00 2001
+From: David Rientjes <rientjes@google.com>
+Date: Fri, 7 Apr 2017 16:05:00 -0700
+Subject: mm, swap_cgroup: reschedule when neeed in swap_cgroup_swapoff()
+
+From: David Rientjes <rientjes@google.com>
+
+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 <rientjes@google.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
+Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/swap_cgroup.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/mm/swap_cgroup.c
++++ b/mm/swap_cgroup.c
+@@ -205,6 +205,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);
+       }
index aa65781bea9bd38174c022c13456b57ee75492a1..32bebf8d0e4cb4436c7037284349a6fe49608918 100644 (file)
@@ -17,3 +17,5 @@ rtnetlink-add-ifla_group-to-ifla_policy.patch
 netfilter-xt_tcpmss-add-more-sanity-tests-on-tcph-doff.patch
 netfilter-synproxy-fix-conntrackd-interaction.patch
 nfsv4-fix-a-reference-leak-caused-warning-messages.patch
+drm-ast-handle-configuration-without-p2a-bridge.patch
+mm-swap_cgroup-reschedule-when-neeed-in-swap_cgroup_swapoff.patch