Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Suchanek <msuchanek@suse.de>2019-10-03 10:22:15 +0200
committerMichal Suchanek <msuchanek@suse.de>2019-10-03 10:22:18 +0200
commited9227d8ec5659452f79a43be3039eabf2c16e9b (patch)
tree4cd0743eb1583984a8a8b859e26db5661c4c59a7
parent9ecbb0dadd66379c024170c046156199d8b4400c (diff)
powerpc/pseries: Call H_BLOCK_REMOVE when supported
(bsc#1109158).
-rw-r--r--patches.suse/powerpc-pseries-Call-H_BLOCK_REMOVE-when-supported.patch137
-rw-r--r--series.conf1
2 files changed, 138 insertions, 0 deletions
diff --git a/patches.suse/powerpc-pseries-Call-H_BLOCK_REMOVE-when-supported.patch b/patches.suse/powerpc-pseries-Call-H_BLOCK_REMOVE-when-supported.patch
new file mode 100644
index 0000000000..8be5656f5b
--- /dev/null
+++ b/patches.suse/powerpc-pseries-Call-H_BLOCK_REMOVE-when-supported.patch
@@ -0,0 +1,137 @@
+From 59545ebe331917afcb1ebbd6f3e5dc3ed51beb05 Mon Sep 17 00:00:00 2001
+From: Laurent Dufour <ldufour@linux.ibm.com>
+Date: Fri, 20 Sep 2019 15:05:23 +0200
+Subject: [PATCH] powerpc/pseries: Call H_BLOCK_REMOVE when supported
+
+References: bsc#1109158
+Patch-mainline: v5.4-rc1
+Git-commit: 59545ebe331917afcb1ebbd6f3e5dc3ed51beb05
+
+Depending on the hardware and the hypervisor, the hcall H_BLOCK_REMOVE
+may not be able to process all the page sizes for a segment base page
+size, as reported by the TLB Invalidate Characteristics.
+
+For each pair of base segment page size and actual page size, this
+characteristic tells us the size of the block the hcall supports.
+
+In the case, the hcall is not supporting a pair of base segment page
+size, actual page size, it is returning H_PARAM which leads to a panic
+like this:
+
+ kernel BUG at /home/srikar/work/linux.git/arch/powerpc/platforms/pseries/lpar.c:466!
+ Oops: Exception in kernel mode, sig: 5 [#1]
+ BE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
+ Modules linked in:
+ CPU: 28 PID: 583 Comm: modprobe Not tainted 5.2.0-master #5
+ NIP: c0000000000be8dc LR: c0000000000be880 CTR: 0000000000000000
+ REGS: c0000007e77fb130 TRAP: 0700 Not tainted (5.2.0-master)
+ MSR: 8000000000029032 <SF,EE,ME,IR,DR,RI> CR: 42224824 XER: 20000000
+ CFAR: c0000000000be8fc IRQMASK: 0
+ GPR00: 0000000022224828 c0000007e77fb3c0 c000000001434d00 0000000000000005
+ GPR04: 9000000004fa8c00 0000000000000000 0000000000000003 0000000000000001
+ GPR08: c0000007e77fb450 0000000000000000 0000000000000001 ffffffffffffffff
+ GPR12: c0000007e77fb450 c00000000edfcb80 0000cd7d3ea30000 c0000000016022b0
+ GPR16: 00000000000000b0 0000cd7d3ea30000 0000000000000001 c080001f04f00105
+ GPR20: 0000000000000003 0000000000000004 c000000fbeb05f58 c000000001602200
+ GPR24: 0000000000000000 0000000000000004 8800000000000000 c000000000c5d148
+ GPR28: c000000000000000 8000000000000000 a000000000000000 c0000007e77fb580
+ NIP [c0000000000be8dc] .call_block_remove+0x12c/0x220
+ LR [c0000000000be880] .call_block_remove+0xd0/0x220
+ Call Trace:
+ 0xc000000fb8c00240 (unreliable)
+ .pSeries_lpar_flush_hash_range+0x578/0x670
+ .flush_hash_range+0x44/0x100
+ .__flush_tlb_pending+0x3c/0xc0
+ .zap_pte_range+0x7ec/0x830
+ .unmap_page_range+0x3f4/0x540
+ .unmap_vmas+0x94/0x120
+ .exit_mmap+0xac/0x1f0
+ .mmput+0x9c/0x1f0
+ .do_exit+0x388/0xd60
+ .do_group_exit+0x54/0x100
+ .__se_sys_exit_group+0x14/0x20
+ system_call+0x5c/0x70
+ Instruction dump:
+ 39400001 38a00000 4800003c 60000000 60420000 7fa9e800 38e00000 419e0014
+ 7d29d278 7d290074 7929d182 69270001 <0b070000> 7d495378 394a0001 7fa93040
+
+The call to H_BLOCK_REMOVE should only be made for the supported pair
+of base segment page size, actual page size and using the correct
+maximum block size.
+
+Due to the required complexity in do_block_remove() and
+call_block_remove(), and the fact that currently a block size of 8 is
+returned by the hypervisor, we are only supporting 8 size block to the
+H_BLOCK_REMOVE hcall.
+
+In order to identify this limitation easily in the code, a local
+define HBLKR_SUPPORTED_SIZE defining the currently supported block
+size, and a dedicated checking helper is_supported_hlbkr() are
+introduced.
+
+For regular pages and hugetlb, the assumption is made that the page
+size is equal to the base page size. For THP the page size is assumed
+to be 16M.
+
+Fixes: ba2dd8a26baa ("powerpc/pseries/mm: call H_BLOCK_REMOVE")
+Signed-off-by: Laurent Dufour <ldufour@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20190920130523.20441-3-ldufour@linux.ibm.com
+Acked-by: Michal Suchanek <msuchanek@suse.de>
+---
+ arch/powerpc/platforms/pseries/lpar.c | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -73,6 +73,13 @@ EXPORT_SYMBOL(plpar_hcall_norets);
+ */
+ static int hblkrm_size[MMU_PAGE_COUNT][MMU_PAGE_COUNT] __ro_after_init;
+
++/*
++ * Due to the involved complexity, and that the current hypervisor is only
++ * returning this value or 0, we are limiting the support of the H_BLOCK_REMOVE
++ * buffer size to 8 size block.
++ */
++#define HBLKRM_SUPPORTED_BLOCK_SIZE 8
++
+ void vpa_init(int cpu)
+ {
+ int hwcpu = get_hard_smp_processor_id(cpu);
+@@ -434,6 +441,17 @@ static void pSeries_lpar_hpte_invalidate
+ #define HBLKR_CTRL_ERRNOTFOUND 0x8800000000000000UL
+ #define HBLKR_CTRL_ERRBUSY 0xa000000000000000UL
+
++/*
++ * Returned true if we are supporting this block size for the specified segment
++ * base page size and actual page size.
++ *
++ * Currently, we only support 8 size block.
++ */
++static inline bool is_supported_hlbkrm(int bpsize, int psize)
++{
++ return (hblkrm_size[bpsize][psize] == HBLKRM_SUPPORTED_BLOCK_SIZE);
++}
++
+ /**
+ * H_BLOCK_REMOVE caller.
+ * @idx should point to the latest @param entry set with a PTEX.
+@@ -593,7 +611,8 @@ static inline void __pSeries_lpar_hugepa
+ if (lock_tlbie)
+ spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
+
+- if (firmware_has_feature(FW_FEATURE_BLOCK_REMOVE))
++ /* Assuming THP size is 16M */
++ if (is_supported_hlbkrm(psize, MMU_PAGE_16M))
+ hugepage_block_invalidate(slot, vpn, count, psize, ssize);
+ else
+ hugepage_bulk_invalidate(slot, vpn, count, psize, ssize);
+@@ -911,7 +930,7 @@ static void pSeries_lpar_flush_hash_rang
+ if (lock_tlbie)
+ spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
+
+- if (firmware_has_feature(FW_FEATURE_BLOCK_REMOVE)) {
++ if (is_supported_hlbkrm(batch->psize, batch->psize)) {
+ do_block_remove(number, batch, param);
+ goto out;
+ }
diff --git a/series.conf b/series.conf
index b779a224b5..686de48c1c 100644
--- a/series.conf
+++ b/series.conf
@@ -24660,6 +24660,7 @@
patches.suse/livepatch-nullify-obj-mod-in-klp_module_coming-s-error-path.patch
patches.suse/suse-hv-PCI-hv-Detect-and-fix-Hyper-V-PCI-domain-number-coll.patch
patches.suse/powerpc-pseries-Read-TLB-Block-Invalidate-Characteri.patch
+ patches.suse/powerpc-pseries-Call-H_BLOCK_REMOVE-when-supported.patch
patches.suse/powerpc-book3s64-mm-Don-t-do-tlbie-fixup-for-some-ha.patch
patches.suse/powerpc-book3s64-radix-Rename-CPU_FTR_P9_TLBIE_BUG-f.patch
patches.suse/powerpc-mm-Fixup-tlbie-vs-mtpidr-mtlpidr-ordering-is.patch