summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGerald Schaefer <gerald.schaefer@linux.ibm.com>2024-11-21 18:45:23 +0100
committerHeiko Carstens <hca@linux.ibm.com>2024-11-27 12:57:01 +0100
commit487ef5d4d912f6a32556d8a61cede17870925295 (patch)
treeba87553d680175faa57960092bb6e1d07b8590ac /arch
parentf934f6be76c1d033692f7fbfcbb06ec44a25bf3f (diff)
downloadlwn-487ef5d4d912f6a32556d8a61cede17870925295.tar.gz
lwn-487ef5d4d912f6a32556d8a61cede17870925295.zip
s390/mm: Add PTE_MARKER support for hugetlbfs mappings
Commit 8a13897fb0daa ("mm: userfaultfd: support UFFDIO_POISON for hugetlbfs") added support for PTE_MARKER_POISONED for hugetlbfs, but PTE_MARKER also needs support for swap entries. For s390, swap entries were only supported on PTE level, not on the PMD/PUD levels that are used for large hugetlbfs mappings. Therefore, when writing a PTE_MARKER_POISONED entry, the resulting entry on PMD/PUD level would be an invalid / empty entry. Further access would then generate a pagefault loop, instead of the expected SIGBUS. It is a loop inside the kernel, but interruptible and uffd fault handling also calls schedule() in between, so at least it won't completely block the system. Previous commits prepared support for swap entries on PMD/PUD levels. PTE_MARKER support for hugetlbfs can now be enabled by simply adding an extra is_pte_marker() check to huge_pte_none_mostly(). Fault handling code also needs to be adjusted to expect the VM_FAULT_HWPOISON_LARGE fault flag, which was not possible on s390 before. Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/include/asm/hugetlb.h2
-rw-r--r--arch/s390/mm/fault.c3
2 files changed, 3 insertions, 2 deletions
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index cf1b5d6fb1a6..0f621c99b216 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -91,7 +91,7 @@ static inline int huge_pte_none(pte_t pte)
static inline int huge_pte_none_mostly(pte_t pte)
{
- return huge_pte_none(pte);
+ return huge_pte_none(pte) || is_pte_marker(pte);
}
static inline int huge_pte_write(pte_t pte)
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 94cb2e092075..4ca35545010f 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -338,7 +338,8 @@ done:
handle_fault_error_nolock(regs, 0);
else
do_sigsegv(regs, SEGV_MAPERR);
- } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON)) {
+ } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON |
+ VM_FAULT_HWPOISON_LARGE)) {
if (!user_mode(regs))
handle_fault_error_nolock(regs, 0);
else