summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2023-10-24 10:15:20 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-12-08 08:52:24 +0100
commit7bfe7741468c47309ff2876e9ef4aff86f40ada1 (patch)
treeefa07cfe5ae93cee76337574b09501af3a634272 /arch
parent8db5cb33d6e4b63778413a82340ebae72db0e60d (diff)
downloadlinux-stable-7bfe7741468c47309ff2876e9ef4aff86f40ada1.tar.gz
linux-stable-7bfe7741468c47309ff2876e9ef4aff86f40ada1.tar.bz2
linux-stable-7bfe7741468c47309ff2876e9ef4aff86f40ada1.zip
s390/cmma: fix handling of swapper_pg_dir and invalid_pg_dir
[ Upstream commit 84bb41d5df48868055d159d9247b80927f1f70f9 ] If the cmma no-dat feature is available the kernel page tables are walked to identify and mark all pages which are used for address translation (all region, segment, and page tables). In a subsequent loop all other pages are marked as "no-dat" pages with the ESSA instruction. This information is visible to the hypervisor, so that the hypervisor can optimize purging of guest TLB entries. All pages used for swapper_pg_dir and invalid_pg_dir are incorrectly marked as no-dat, which in turn can result in incorrect guest TLB flushes. Fix this by marking those pages correctly as being used for DAT. Cc: <stable@vger.kernel.org> Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/mm/page-states.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c
index 00e7b0876dc5..79a037f49f70 100644
--- a/arch/s390/mm/page-states.c
+++ b/arch/s390/mm/page-states.c
@@ -181,6 +181,12 @@ void __init cmma_init_nodat(void)
return;
/* Mark pages used in kernel page tables */
mark_kernel_pgd();
+ page = virt_to_page(&swapper_pg_dir);
+ for (i = 0; i < 4; i++)
+ set_bit(PG_arch_1, &page[i].flags);
+ page = virt_to_page(&invalid_pg_dir);
+ for (i = 0; i < 4; i++)
+ set_bit(PG_arch_1, &page[i].flags);
/* Set all kernel pages not used for page tables to stable/no-dat */
for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, NULL) {