diff options
author | Linus Torvalds <[email protected]> | 2024-07-18 15:41:45 -0700 |
---|---|---|
committer | Linus Torvalds <[email protected]> | 2024-07-18 15:41:45 -0700 |
commit | 1c7d0c3af5cc8adafef6477f9416820fc894ca40 (patch) | |
tree | 449450c8ca1726cefb8197256b61c4de0b7cfddb /arch/s390/mm/fault.c | |
parent | dde1a0e1625c08cf4f958348a83434b2ddecf449 (diff) | |
parent | df39038cd89525d465c2c8827eb64116873f141a (diff) |
Merge tag 's390-6.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Vasily Gorbik:
- Remove restrictions on PAI NNPA and crypto counters, enabling
concurrent per-task and system-wide sampling and counting events
- Switch to GENERIC_CPU_DEVICES by setting up the CPU present mask in
the architecture code and letting the generic code handle CPU
bring-up
- Add support for the diag204 busy indication facility to prevent
undesirable blocking during hypervisor logical CPU utilization
queries. Implement results caching
- Improve the handling of Store Data SCLP events by suppressing
unnecessary warning, preventing buffer release in I/O during
failures, and adding timeout handling for Store Data requests to
address potential firmware issues
- Provide optimized __arch_hweight*() implementations
- Remove the unnecessary CPU KOBJ_CHANGE uevents generated during
topology updates, as they are unused and also not present on other
architectures
- Cleanup atomic_ops, optimize __atomic_set() for small values and
__atomic_cmpxchg_bool() for compilers supporting flag output
constraint
- Couple of cleanups for KVM:
- Move and improve KVM struct definitions for DAT tables from
gaccess.c to a new header
- Pass the asce as parameter to sie64a()
- Make the crdte() and cspg() page table handling wrappers return a
boolean to indicate success, like the other existing "compare and
swap" wrappers
- Add documentation for HWCAP flags
- Switch to obtaining total RAM pages from memblock instead of
totalram_pages() during mm init, to ensure correct calculation of
zero page size, when defer_init is enabled
- Refactor lowcore access and switch to using the get_lowcore()
function instead of the S390_lowcore macro
- Cleanups for PG_arch_1 and folio handling in UV and hugetlb code
- Add missing MODULE_DESCRIPTION() macros
- Fix VM_FAULT_HWPOISON handling in do_exception()
* tag 's390-6.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (54 commits)
s390/mm: Fix VM_FAULT_HWPOISON handling in do_exception()
s390/kvm: Move bitfields for dat tables
s390/entry: Pass the asce as parameter to sie64a()
s390/sthyi: Use cached data when diag is busy
s390/sthyi: Move diag operations
s390/hypfs_diag: Diag204 busy loop
s390/diag: Add busy-indication-facility requirements
s390/diag: Diag204 add busy return errno
s390/diag: Return errno's from diag204
s390/sclp: Diag204 busy indication facility detection
s390/atomic_ops: Make use of flag output constraint
s390/atomic_ops: Improve __atomic_set() for small values
s390/atomic_ops: Use symbolic names
s390/smp: Switch to GENERIC_CPU_DEVICES
s390/hwcaps: Add documentation for HWCAP flags
s390/pgtable: Make crdte() and cspg() return a value
s390/topology: Remove CPU KOBJ_CHANGE uevents
s390/sclp: Add timeout to Store Data requests
s390/sclp: Prevent release of buffer in I/O
s390/sclp: Suppress unnecessary Store Data warning
...
Diffstat (limited to 'arch/s390/mm/fault.c')
-rw-r--r-- | arch/s390/mm/fault.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 65747f15dbec..8e149ef5e89b 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -74,7 +74,7 @@ static enum fault_type get_fault_type(struct pt_regs *regs) return USER_FAULT; if (!IS_ENABLED(CONFIG_PGSTE)) return KERNEL_FAULT; - gmap = (struct gmap *)S390_lowcore.gmap; + gmap = (struct gmap *)get_lowcore()->gmap; if (gmap && gmap->asce == regs->cr1) return GMAP_FAULT; return KERNEL_FAULT; @@ -182,15 +182,15 @@ static void dump_fault_info(struct pt_regs *regs) pr_cont("mode while using "); switch (get_fault_type(regs)) { case USER_FAULT: - asce = S390_lowcore.user_asce.val; + asce = get_lowcore()->user_asce.val; pr_cont("user "); break; case GMAP_FAULT: - asce = ((struct gmap *)S390_lowcore.gmap)->asce; + asce = ((struct gmap *)get_lowcore()->gmap)->asce; pr_cont("gmap "); break; case KERNEL_FAULT: - asce = S390_lowcore.kernel_asce.val; + asce = get_lowcore()->kernel_asce.val; pr_cont("kernel "); break; default: @@ -351,7 +351,7 @@ lock_mmap: mmap_read_lock(mm); gmap = NULL; if (IS_ENABLED(CONFIG_PGSTE) && type == GMAP_FAULT) { - gmap = (struct gmap *)S390_lowcore.gmap; + gmap = (struct gmap *)get_lowcore()->gmap; current->thread.gmap_addr = address; current->thread.gmap_write_flag = !!(flags & FAULT_FLAG_WRITE); current->thread.gmap_int_code = regs->int_code & 0xffff; @@ -433,12 +433,13 @@ error: handle_fault_error_nolock(regs, 0); else do_sigsegv(regs, SEGV_MAPERR); - } else if (fault & VM_FAULT_SIGBUS) { + } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON)) { if (!user_mode(regs)) handle_fault_error_nolock(regs, 0); else do_sigbus(regs); } else { + pr_emerg("Unexpected fault flags: %08x\n", fault); BUG(); } } @@ -492,6 +493,7 @@ void do_secure_storage_access(struct pt_regs *regs) unsigned long addr = get_fault_address(regs); struct vm_area_struct *vma; struct mm_struct *mm; + struct folio *folio; struct page *page; struct gmap *gmap; int rc; @@ -521,7 +523,7 @@ void do_secure_storage_access(struct pt_regs *regs) switch (get_fault_type(regs)) { case GMAP_FAULT: mm = current->mm; - gmap = (struct gmap *)S390_lowcore.gmap; + gmap = (struct gmap *)get_lowcore()->gmap; mmap_read_lock(mm); addr = __gmap_translate(gmap, addr); mmap_read_unlock(mm); @@ -539,17 +541,18 @@ void do_secure_storage_access(struct pt_regs *regs) mmap_read_unlock(mm); break; } - if (arch_make_page_accessible(page)) + folio = page_folio(page); + if (arch_make_folio_accessible(folio)) send_sig(SIGSEGV, current, 0); - put_page(page); + folio_put(folio); mmap_read_unlock(mm); break; case KERNEL_FAULT: - page = phys_to_page(addr); - if (unlikely(!try_get_page(page))) + folio = phys_to_folio(addr); + if (unlikely(!folio_try_get(folio))) break; - rc = arch_make_page_accessible(page); - put_page(page); + rc = arch_make_folio_accessible(folio); + folio_put(folio); if (rc) BUG(); break; @@ -561,7 +564,7 @@ NOKPROBE_SYMBOL(do_secure_storage_access); void do_non_secure_storage_access(struct pt_regs *regs) { - struct gmap *gmap = (struct gmap *)S390_lowcore.gmap; + struct gmap *gmap = (struct gmap *)get_lowcore()->gmap; unsigned long gaddr = get_fault_address(regs); if (WARN_ON_ONCE(get_fault_type(regs) != GMAP_FAULT)) @@ -573,7 +576,7 @@ NOKPROBE_SYMBOL(do_non_secure_storage_access); void do_secure_storage_violation(struct pt_regs *regs) { - struct gmap *gmap = (struct gmap *)S390_lowcore.gmap; + struct gmap *gmap = (struct gmap *)get_lowcore()->gmap; unsigned long gaddr = get_fault_address(regs); /* |