Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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
...

+1207 -778
+2 -1
arch/s390/Kconfig
··· 21 21 def_bool y 22 22 23 23 config GENERIC_HWEIGHT 24 - def_bool y 24 + def_bool !HAVE_MARCH_Z196_FEATURES 25 25 26 26 config GENERIC_BUG 27 27 def_bool y if BUG ··· 142 142 select FUNCTION_ALIGNMENT_8B if CC_IS_GCC 143 143 select FUNCTION_ALIGNMENT_16B if !CC_IS_GCC 144 144 select GENERIC_ALLOCATOR 145 + select GENERIC_CPU_DEVICES 145 146 select GENERIC_CPU_AUTOPROBE 146 147 select GENERIC_CPU_VULNERABILITIES 147 148 select GENERIC_ENTRY
+2 -2
arch/s390/boot/ipl_parm.c
··· 51 51 : [r1] "+&d" (r1.pair), 52 52 [reg1] "=&d" (reg1), 53 53 [reg2] "=&a" (reg2), 54 - "+Q" (S390_lowcore.program_new_psw), 54 + "+Q" (get_lowcore()->program_new_psw), 55 55 "=Q" (old) 56 56 : [subcode] "d" (subcode), 57 57 [psw_old] "a" (&old), 58 - [psw_pgm] "a" (&S390_lowcore.program_new_psw) 58 + [psw_pgm] "a" (&get_lowcore()->program_new_psw) 59 59 : "cc", "memory"); 60 60 return r1.odd; 61 61 }
+1 -1
arch/s390/boot/ipl_report.c
··· 106 106 * the IPL parameter list, then align the address to a double 107 107 * word boundary. 108 108 */ 109 - tmp = (unsigned long) S390_lowcore.ipl_parmblock_ptr; 109 + tmp = (unsigned long)get_lowcore()->ipl_parmblock_ptr; 110 110 pl_hdr = (struct ipl_pl_hdr *) tmp; 111 111 tmp = (tmp + pl_hdr->len + 7) & -8UL; 112 112 rl_hdr = (struct ipl_rl_hdr *) tmp;
+9 -9
arch/s390/boot/pgm_check_info.c
··· 145 145 146 146 void print_pgm_check_info(void) 147 147 { 148 - unsigned long *gpregs = (unsigned long *)S390_lowcore.gpregs_save_area; 149 - struct psw_bits *psw = &psw_bits(S390_lowcore.psw_save_area); 148 + unsigned long *gpregs = (unsigned long *)get_lowcore()->gpregs_save_area; 149 + struct psw_bits *psw = &psw_bits(get_lowcore()->psw_save_area); 150 150 151 151 decompressor_printk("Linux version %s\n", kernel_version); 152 152 if (!is_prot_virt_guest() && early_command_line[0]) 153 153 decompressor_printk("Kernel command line: %s\n", early_command_line); 154 154 decompressor_printk("Kernel fault: interruption code %04x ilc:%x\n", 155 - S390_lowcore.pgm_code, S390_lowcore.pgm_ilc >> 1); 155 + get_lowcore()->pgm_code, get_lowcore()->pgm_ilc >> 1); 156 156 if (kaslr_enabled()) { 157 157 decompressor_printk("Kernel random base: %lx\n", __kaslr_offset); 158 158 decompressor_printk("Kernel random base phys: %lx\n", __kaslr_offset_phys); 159 159 } 160 160 decompressor_printk("PSW : %016lx %016lx (%pS)\n", 161 - S390_lowcore.psw_save_area.mask, 162 - S390_lowcore.psw_save_area.addr, 163 - (void *)S390_lowcore.psw_save_area.addr); 161 + get_lowcore()->psw_save_area.mask, 162 + get_lowcore()->psw_save_area.addr, 163 + (void *)get_lowcore()->psw_save_area.addr); 164 164 decompressor_printk( 165 165 " R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x P:%x AS:%x CC:%x PM:%x RI:%x EA:%x\n", 166 166 psw->per, psw->dat, psw->io, psw->ext, psw->key, psw->mcheck, ··· 174 174 gpregs[8], gpregs[9], gpregs[10], gpregs[11]); 175 175 decompressor_printk(" %016lx %016lx %016lx %016lx\n", 176 176 gpregs[12], gpregs[13], gpregs[14], gpregs[15]); 177 - print_stacktrace(S390_lowcore.gpregs_save_area[15]); 177 + print_stacktrace(get_lowcore()->gpregs_save_area[15]); 178 178 decompressor_printk("Last Breaking-Event-Address:\n"); 179 - decompressor_printk(" [<%016lx>] %pS\n", (unsigned long)S390_lowcore.pgm_last_break, 180 - (void *)S390_lowcore.pgm_last_break); 179 + decompressor_printk(" [<%016lx>] %pS\n", (unsigned long)get_lowcore()->pgm_last_break, 180 + (void *)get_lowcore()->pgm_last_break); 181 181 }
+4 -4
arch/s390/boot/physmem_info.c
··· 81 81 [reg2] "=&a" (reg2), 82 82 [rc] "+&d" (rc), 83 83 [ry] "+&d" (ry), 84 - "+Q" (S390_lowcore.program_new_psw), 84 + "+Q" (get_lowcore()->program_new_psw), 85 85 "=Q" (old) 86 86 : [rx] "d" (rx.pair), 87 87 [psw_old] "a" (&old), 88 - [psw_pgm] "a" (&S390_lowcore.program_new_psw) 88 + [psw_pgm] "a" (&get_lowcore()->program_new_psw) 89 89 : "cc", "memory"); 90 90 return rc == 0 ? ry : -1; 91 91 } ··· 129 129 : [reg1] "=&d" (reg1), 130 130 [reg2] "=&a" (reg2), 131 131 [rc] "+&d" (rc), 132 - "=Q" (S390_lowcore.program_new_psw.addr), 132 + "=Q" (get_lowcore()->program_new_psw.addr), 133 133 "=Q" (old) 134 134 : [psw_old] "a" (&old), 135 - [psw_pgm] "a" (&S390_lowcore.program_new_psw), 135 + [psw_pgm] "a" (&get_lowcore()->program_new_psw), 136 136 [addr] "a" (addr) 137 137 : "cc", "memory"); 138 138 return rc;
+6 -6
arch/s390/boot/startup.c
··· 78 78 [reg2] "=&a" (reg2), 79 79 [rc] "+&d" (rc), 80 80 [tmp] "=&d" (tmp), 81 - "+Q" (S390_lowcore.program_new_psw), 81 + "+Q" (get_lowcore()->program_new_psw), 82 82 "=Q" (old) 83 83 : [psw_old] "a" (&old), 84 - [psw_pgm] "a" (&S390_lowcore.program_new_psw), 84 + [psw_pgm] "a" (&get_lowcore()->program_new_psw), 85 85 [cmd] "i" (ESSA_GET_STATE) 86 86 : "cc", "memory"); 87 87 return rc; ··· 101 101 102 102 static void setup_lpp(void) 103 103 { 104 - S390_lowcore.current_pid = 0; 105 - S390_lowcore.lpp = LPP_MAGIC; 104 + get_lowcore()->current_pid = 0; 105 + get_lowcore()->lpp = LPP_MAGIC; 106 106 if (test_facility(40)) 107 - lpp(&S390_lowcore.lpp); 107 + lpp(&get_lowcore()->lpp); 108 108 } 109 109 110 110 #ifdef CONFIG_KERNEL_UNCOMPRESSED ··· 501 501 * Save KASLR offset for early dumps, before vmcore_info is set. 502 502 * Mark as uneven to distinguish from real vmcore_info pointer. 503 503 */ 504 - S390_lowcore.vmcore_info = __kaslr_offset_phys ? __kaslr_offset_phys | 0x1UL : 0; 504 + get_lowcore()->vmcore_info = __kaslr_offset_phys ? __kaslr_offset_phys | 0x1UL : 0; 505 505 506 506 /* 507 507 * Jump to the decompressed kernel entry point and switch DAT mode on.
+6 -6
arch/s390/boot/vmem.c
··· 476 476 477 477 kasan_populate_shadow(kernel_start, kernel_end); 478 478 479 - S390_lowcore.kernel_asce.val = swapper_pg_dir | asce_bits; 480 - S390_lowcore.user_asce = s390_invalid_asce; 479 + get_lowcore()->kernel_asce.val = swapper_pg_dir | asce_bits; 480 + get_lowcore()->user_asce = s390_invalid_asce; 481 481 482 - local_ctl_load(1, &S390_lowcore.kernel_asce); 483 - local_ctl_load(7, &S390_lowcore.user_asce); 484 - local_ctl_load(13, &S390_lowcore.kernel_asce); 482 + local_ctl_load(1, &get_lowcore()->kernel_asce); 483 + local_ctl_load(7, &get_lowcore()->user_asce); 484 + local_ctl_load(13, &get_lowcore()->kernel_asce); 485 485 486 - init_mm.context.asce = S390_lowcore.kernel_asce.val; 486 + init_mm.context.asce = get_lowcore()->kernel_asce.val; 487 487 init_mm.pgd = init_mm_pgd; 488 488 }
+1
arch/s390/crypto/crc32-vx.c
··· 297 297 module_exit(crc_vx_mod_exit); 298 298 299 299 MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>"); 300 + MODULE_DESCRIPTION("CRC-32 algorithms using z/Architecture Vector Extension Facility"); 300 301 MODULE_LICENSE("GPL"); 301 302 302 303 MODULE_ALIAS_CRYPTO("crc32");
+3 -1
arch/s390/hypfs/hypfs_dbfs.c
··· 39 39 return 0; 40 40 41 41 df = file_inode(file)->i_private; 42 - mutex_lock(&df->lock); 42 + if (mutex_lock_interruptible(&df->lock)) 43 + return -ERESTARTSYS; 44 + 43 45 data = hypfs_dbfs_data_alloc(df); 44 46 if (!data) { 45 47 mutex_unlock(&df->lock);
+14 -3
arch/s390/hypfs/hypfs_diag.c
··· 140 140 141 141 int diag204_store(void *buf, int pages) 142 142 { 143 + unsigned long subcode; 143 144 int rc; 144 145 145 - rc = diag204((unsigned long)diag204_store_sc | 146 - (unsigned long)diag204_get_info_type(), pages, buf); 147 - return rc < 0 ? -EOPNOTSUPP : 0; 146 + subcode = diag204_get_info_type(); 147 + subcode |= diag204_store_sc; 148 + if (diag204_has_bif()) 149 + subcode |= DIAG204_BIF_BIT; 150 + while (1) { 151 + rc = diag204(subcode, pages, buf); 152 + if (rc != -EBUSY) 153 + break; 154 + if (signal_pending(current)) 155 + return -ERESTARTSYS; 156 + schedule_timeout_interruptible(DIAG204_BUSY_WAIT); 157 + } 158 + return rc < 0 ? rc : 0; 148 159 } 149 160 150 161 struct dbfs_d204_hdr {
+76
arch/s390/include/asm/arch_hweight.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef _ASM_S390_ARCH_HWEIGHT_H 4 + #define _ASM_S390_ARCH_HWEIGHT_H 5 + 6 + #include <linux/types.h> 7 + 8 + static __always_inline unsigned long popcnt_z196(unsigned long w) 9 + { 10 + unsigned long cnt; 11 + 12 + asm volatile(".insn rrf,0xb9e10000,%[cnt],%[w],0,0" 13 + : [cnt] "=d" (cnt) 14 + : [w] "d" (w) 15 + : "cc"); 16 + return cnt; 17 + } 18 + 19 + static __always_inline unsigned long popcnt_z15(unsigned long w) 20 + { 21 + unsigned long cnt; 22 + 23 + asm volatile(".insn rrf,0xb9e10000,%[cnt],%[w],8,0" 24 + : [cnt] "=d" (cnt) 25 + : [w] "d" (w) 26 + : "cc"); 27 + return cnt; 28 + } 29 + 30 + static __always_inline unsigned long __arch_hweight64(__u64 w) 31 + { 32 + if (IS_ENABLED(CONFIG_HAVE_MARCH_Z15_FEATURES)) 33 + return popcnt_z15(w); 34 + if (IS_ENABLED(CONFIG_HAVE_MARCH_Z196_FEATURES)) { 35 + w = popcnt_z196(w); 36 + w += w >> 32; 37 + w += w >> 16; 38 + w += w >> 8; 39 + return w & 0xff; 40 + } 41 + return __sw_hweight64(w); 42 + } 43 + 44 + static __always_inline unsigned int __arch_hweight32(unsigned int w) 45 + { 46 + if (IS_ENABLED(CONFIG_HAVE_MARCH_Z15_FEATURES)) 47 + return popcnt_z15(w); 48 + if (IS_ENABLED(CONFIG_HAVE_MARCH_Z196_FEATURES)) { 49 + w = popcnt_z196(w); 50 + w += w >> 16; 51 + w += w >> 8; 52 + return w & 0xff; 53 + } 54 + return __sw_hweight32(w); 55 + } 56 + 57 + static __always_inline unsigned int __arch_hweight16(unsigned int w) 58 + { 59 + if (IS_ENABLED(CONFIG_HAVE_MARCH_Z15_FEATURES)) 60 + return popcnt_z15((unsigned short)w); 61 + if (IS_ENABLED(CONFIG_HAVE_MARCH_Z196_FEATURES)) { 62 + w = popcnt_z196(w); 63 + w += w >> 8; 64 + return w & 0xff; 65 + } 66 + return __sw_hweight16(w); 67 + } 68 + 69 + static __always_inline unsigned int __arch_hweight8(unsigned int w) 70 + { 71 + if (IS_ENABLED(CONFIG_HAVE_MARCH_Z196_FEATURES)) 72 + return popcnt_z196((unsigned char)w); 73 + return __sw_hweight8(w); 74 + } 75 + 76 + #endif /* _ASM_S390_ARCH_HWEIGHT_H */
+64 -20
arch/s390/include/asm/atomic_ops.h
··· 8 8 #ifndef __ARCH_S390_ATOMIC_OPS__ 9 9 #define __ARCH_S390_ATOMIC_OPS__ 10 10 11 + #include <linux/limits.h> 12 + 11 13 static __always_inline int __atomic_read(const atomic_t *v) 12 14 { 13 15 int c; 14 16 15 17 asm volatile( 16 - " l %0,%1\n" 17 - : "=d" (c) : "R" (v->counter)); 18 + " l %[c],%[counter]\n" 19 + : [c] "=d" (c) : [counter] "R" (v->counter)); 18 20 return c; 19 21 } 20 22 21 23 static __always_inline void __atomic_set(atomic_t *v, int i) 22 24 { 23 - asm volatile( 24 - " st %1,%0\n" 25 - : "=R" (v->counter) : "d" (i)); 25 + if (__builtin_constant_p(i) && i >= S16_MIN && i <= S16_MAX) { 26 + asm volatile( 27 + " mvhi %[counter], %[i]\n" 28 + : [counter] "=Q" (v->counter) : [i] "K" (i)); 29 + } else { 30 + asm volatile( 31 + " st %[i],%[counter]\n" 32 + : [counter] "=R" (v->counter) : [i] "d" (i)); 33 + } 26 34 } 27 35 28 36 static __always_inline s64 __atomic64_read(const atomic64_t *v) ··· 38 30 s64 c; 39 31 40 32 asm volatile( 41 - " lg %0,%1\n" 42 - : "=d" (c) : "RT" (v->counter)); 33 + " lg %[c],%[counter]\n" 34 + : [c] "=d" (c) : [counter] "RT" (v->counter)); 43 35 return c; 44 36 } 45 37 46 38 static __always_inline void __atomic64_set(atomic64_t *v, s64 i) 47 39 { 48 - asm volatile( 49 - " stg %1,%0\n" 50 - : "=RT" (v->counter) : "d" (i)); 40 + if (__builtin_constant_p(i) && i >= S16_MIN && i <= S16_MAX) { 41 + asm volatile( 42 + " mvghi %[counter], %[i]\n" 43 + : [counter] "=Q" (v->counter) : [i] "K" (i)); 44 + } else { 45 + asm volatile( 46 + " stg %[i],%[counter]\n" 47 + : [counter] "=RT" (v->counter) : [i] "d" (i)); 48 + } 51 49 } 52 50 53 51 #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES ··· 178 164 return old; 179 165 } 180 166 167 + static __always_inline long __atomic64_cmpxchg(long *ptr, long old, long new) 168 + { 169 + asm volatile( 170 + " csg %[old],%[new],%[ptr]" 171 + : [old] "+d" (old), [ptr] "+QS" (*ptr) 172 + : [new] "d" (new) 173 + : "cc", "memory"); 174 + return old; 175 + } 176 + 177 + #ifdef __GCC_ASM_FLAG_OUTPUTS__ 178 + 179 + static __always_inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new) 180 + { 181 + int cc; 182 + 183 + asm volatile( 184 + " cs %[old],%[new],%[ptr]" 185 + : [old] "+d" (old), [ptr] "+Q" (*ptr), "=@cc" (cc) 186 + : [new] "d" (new) 187 + : "memory"); 188 + return cc == 0; 189 + } 190 + 191 + static __always_inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new) 192 + { 193 + int cc; 194 + 195 + asm volatile( 196 + " csg %[old],%[new],%[ptr]" 197 + : [old] "+d" (old), [ptr] "+QS" (*ptr), "=@cc" (cc) 198 + : [new] "d" (new) 199 + : "memory"); 200 + return cc == 0; 201 + } 202 + 203 + #else /* __GCC_ASM_FLAG_OUTPUTS__ */ 204 + 181 205 static __always_inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new) 182 206 { 183 207 int old_expected = old; ··· 226 174 : [new] "d" (new) 227 175 : "cc", "memory"); 228 176 return old == old_expected; 229 - } 230 - 231 - static __always_inline long __atomic64_cmpxchg(long *ptr, long old, long new) 232 - { 233 - asm volatile( 234 - " csg %[old],%[new],%[ptr]" 235 - : [old] "+d" (old), [ptr] "+QS" (*ptr) 236 - : [new] "d" (new) 237 - : "cc", "memory"); 238 - return old; 239 177 } 240 178 241 179 static __always_inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new) ··· 239 197 : "cc", "memory"); 240 198 return old == old_expected; 241 199 } 200 + 201 + #endif /* __GCC_ASM_FLAG_OUTPUTS__ */ 242 202 243 203 #endif /* __ARCH_S390_ATOMIC_OPS__ */
+2 -1
arch/s390/include/asm/bitops.h
··· 379 379 return fls64(word); 380 380 } 381 381 382 + #include <asm/arch_hweight.h> 383 + #include <asm-generic/bitops/const_hweight.h> 382 384 #include <asm-generic/bitops/ffz.h> 383 - #include <asm-generic/bitops/hweight.h> 384 385 #include <asm-generic/bitops/sched.h> 385 386 #include <asm-generic/bitops/le.h> 386 387 #include <asm-generic/bitops/ext2-atomic-setbit.h>
+1 -1
arch/s390/include/asm/current.h
··· 14 14 15 15 struct task_struct; 16 16 17 - #define current ((struct task_struct *const)S390_lowcore.current_task) 17 + #define current ((struct task_struct *const)get_lowcore()->current_task) 18 18 19 19 #endif /* !(_S390_CURRENT_H) */
+170
arch/s390/include/asm/dat-bits.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * DAT table and related structures 4 + * 5 + * Copyright IBM Corp. 2024 6 + * 7 + */ 8 + 9 + #ifndef _S390_DAT_BITS_H 10 + #define _S390_DAT_BITS_H 11 + 12 + union asce { 13 + unsigned long val; 14 + struct { 15 + unsigned long rsto: 52;/* Region- or Segment-Table Origin */ 16 + unsigned long : 2; 17 + unsigned long g : 1; /* Subspace Group control */ 18 + unsigned long p : 1; /* Private Space control */ 19 + unsigned long s : 1; /* Storage-Alteration-Event control */ 20 + unsigned long x : 1; /* Space-Switch-Event control */ 21 + unsigned long r : 1; /* Real-Space control */ 22 + unsigned long : 1; 23 + unsigned long dt : 2; /* Designation-Type control */ 24 + unsigned long tl : 2; /* Region- or Segment-Table Length */ 25 + }; 26 + }; 27 + 28 + enum { 29 + ASCE_TYPE_SEGMENT = 0, 30 + ASCE_TYPE_REGION3 = 1, 31 + ASCE_TYPE_REGION2 = 2, 32 + ASCE_TYPE_REGION1 = 3 33 + }; 34 + 35 + union region1_table_entry { 36 + unsigned long val; 37 + struct { 38 + unsigned long rto: 52;/* Region-Table Origin */ 39 + unsigned long : 2; 40 + unsigned long p : 1; /* DAT-Protection Bit */ 41 + unsigned long : 1; 42 + unsigned long tf : 2; /* Region-Second-Table Offset */ 43 + unsigned long i : 1; /* Region-Invalid Bit */ 44 + unsigned long : 1; 45 + unsigned long tt : 2; /* Table-Type Bits */ 46 + unsigned long tl : 2; /* Region-Second-Table Length */ 47 + }; 48 + }; 49 + 50 + union region2_table_entry { 51 + unsigned long val; 52 + struct { 53 + unsigned long rto: 52;/* Region-Table Origin */ 54 + unsigned long : 2; 55 + unsigned long p : 1; /* DAT-Protection Bit */ 56 + unsigned long : 1; 57 + unsigned long tf : 2; /* Region-Third-Table Offset */ 58 + unsigned long i : 1; /* Region-Invalid Bit */ 59 + unsigned long : 1; 60 + unsigned long tt : 2; /* Table-Type Bits */ 61 + unsigned long tl : 2; /* Region-Third-Table Length */ 62 + }; 63 + }; 64 + 65 + struct region3_table_entry_fc0 { 66 + unsigned long sto: 52;/* Segment-Table Origin */ 67 + unsigned long : 1; 68 + unsigned long fc : 1; /* Format-Control */ 69 + unsigned long p : 1; /* DAT-Protection Bit */ 70 + unsigned long : 1; 71 + unsigned long tf : 2; /* Segment-Table Offset */ 72 + unsigned long i : 1; /* Region-Invalid Bit */ 73 + unsigned long cr : 1; /* Common-Region Bit */ 74 + unsigned long tt : 2; /* Table-Type Bits */ 75 + unsigned long tl : 2; /* Segment-Table Length */ 76 + }; 77 + 78 + struct region3_table_entry_fc1 { 79 + unsigned long rfaa: 33;/* Region-Frame Absolute Address */ 80 + unsigned long : 14; 81 + unsigned long av : 1; /* ACCF-Validity Control */ 82 + unsigned long acc : 4; /* Access-Control Bits */ 83 + unsigned long f : 1; /* Fetch-Protection Bit */ 84 + unsigned long fc : 1; /* Format-Control */ 85 + unsigned long p : 1; /* DAT-Protection Bit */ 86 + unsigned long iep : 1; /* Instruction-Execution-Protection */ 87 + unsigned long : 2; 88 + unsigned long i : 1; /* Region-Invalid Bit */ 89 + unsigned long cr : 1; /* Common-Region Bit */ 90 + unsigned long tt : 2; /* Table-Type Bits */ 91 + unsigned long : 2; 92 + }; 93 + 94 + union region3_table_entry { 95 + unsigned long val; 96 + struct region3_table_entry_fc0 fc0; 97 + struct region3_table_entry_fc1 fc1; 98 + struct { 99 + unsigned long : 53; 100 + unsigned long fc: 1; /* Format-Control */ 101 + unsigned long : 4; 102 + unsigned long i : 1; /* Region-Invalid Bit */ 103 + unsigned long cr: 1; /* Common-Region Bit */ 104 + unsigned long tt: 2; /* Table-Type Bits */ 105 + unsigned long : 2; 106 + }; 107 + }; 108 + 109 + struct segment_table_entry_fc0 { 110 + unsigned long pto: 53;/* Page-Table Origin */ 111 + unsigned long fc : 1; /* Format-Control */ 112 + unsigned long p : 1; /* DAT-Protection Bit */ 113 + unsigned long : 3; 114 + unsigned long i : 1; /* Segment-Invalid Bit */ 115 + unsigned long cs : 1; /* Common-Segment Bit */ 116 + unsigned long tt : 2; /* Table-Type Bits */ 117 + unsigned long : 2; 118 + }; 119 + 120 + struct segment_table_entry_fc1 { 121 + unsigned long sfaa: 44;/* Segment-Frame Absolute Address */ 122 + unsigned long : 3; 123 + unsigned long av : 1; /* ACCF-Validity Control */ 124 + unsigned long acc : 4; /* Access-Control Bits */ 125 + unsigned long f : 1; /* Fetch-Protection Bit */ 126 + unsigned long fc : 1; /* Format-Control */ 127 + unsigned long p : 1; /* DAT-Protection Bit */ 128 + unsigned long iep : 1; /* Instruction-Execution-Protection */ 129 + unsigned long : 2; 130 + unsigned long i : 1; /* Segment-Invalid Bit */ 131 + unsigned long cs : 1; /* Common-Segment Bit */ 132 + unsigned long tt : 2; /* Table-Type Bits */ 133 + unsigned long : 2; 134 + }; 135 + 136 + union segment_table_entry { 137 + unsigned long val; 138 + struct segment_table_entry_fc0 fc0; 139 + struct segment_table_entry_fc1 fc1; 140 + struct { 141 + unsigned long : 53; 142 + unsigned long fc: 1; /* Format-Control */ 143 + unsigned long : 4; 144 + unsigned long i : 1; /* Segment-Invalid Bit */ 145 + unsigned long cs: 1; /* Common-Segment Bit */ 146 + unsigned long tt: 2; /* Table-Type Bits */ 147 + unsigned long : 2; 148 + }; 149 + }; 150 + 151 + union page_table_entry { 152 + unsigned long val; 153 + struct { 154 + unsigned long pfra: 52;/* Page-Frame Real Address */ 155 + unsigned long z : 1; /* Zero Bit */ 156 + unsigned long i : 1; /* Page-Invalid Bit */ 157 + unsigned long p : 1; /* DAT-Protection Bit */ 158 + unsigned long iep : 1; /* Instruction-Execution-Protection */ 159 + unsigned long : 8; 160 + }; 161 + }; 162 + 163 + enum { 164 + TABLE_TYPE_SEGMENT = 0, 165 + TABLE_TYPE_REGION3 = 1, 166 + TABLE_TYPE_REGION2 = 2, 167 + TABLE_TYPE_REGION1 = 3 168 + }; 169 + 170 + #endif /* _S390_DAT_BITS_H */
+8
arch/s390/include/asm/diag.h
··· 12 12 #include <linux/if_ether.h> 13 13 #include <linux/percpu.h> 14 14 #include <asm/asm-extable.h> 15 + #include <asm/sclp.h> 15 16 #include <asm/cio.h> 16 17 17 18 enum diag_stat_enum { ··· 118 117 }; 119 118 120 119 #define DIAG204_SUBCODE_MASK 0xffff 120 + #define DIAG204_BIF_BIT 0x80000000 121 + #define DIAG204_BUSY_WAIT (HZ / 10) 121 122 122 123 /* The two available diag 204 data formats */ 123 124 enum diag204_format { ··· 328 325 unsigned long cpvc : 56; 329 326 }; 330 327 }; 328 + 329 + static inline bool diag204_has_bif(void) 330 + { 331 + return sclp.has_diag204_bif; 332 + } 331 333 332 334 int diag204(unsigned long subcode, unsigned long size, void *addr); 333 335 int diag224(void *ptr);
+8
arch/s390/include/asm/elf.h
··· 91 91 /* Keep this the last entry. */ 92 92 #define R_390_NUM 61 93 93 94 + /* 95 + * HWCAP flags - for AT_HWCAP 96 + * 97 + * Bits 32-63 are reserved for use by libc. 98 + * Bit 31 is reserved and will be used by libc to determine if a second 99 + * argument is passed to IFUNC resolvers. This will be implemented when 100 + * there is a need for AT_HWCAP2. 101 + */ 94 102 enum { 95 103 HWCAP_NR_ESAN3 = 0, 96 104 HWCAP_NR_ZARCH = 1,
+2 -2
arch/s390/include/asm/facility.h
··· 92 92 93 93 asm volatile( 94 94 " stfl 0(0)\n" 95 - : "=m" (S390_lowcore.stfl_fac_list)); 96 - stfl_fac_list = S390_lowcore.stfl_fac_list; 95 + : "=m" (get_lowcore()->stfl_fac_list)); 96 + stfl_fac_list = get_lowcore()->stfl_fac_list; 97 97 memcpy(stfle_fac_list, &stfl_fac_list, 4); 98 98 nr = 4; /* bytes stored by stfl */ 99 99 if (stfl_fac_list & 0x01000000) {
+3 -3
arch/s390/include/asm/hardirq.h
··· 13 13 14 14 #include <asm/lowcore.h> 15 15 16 - #define local_softirq_pending() (S390_lowcore.softirq_pending) 17 - #define set_softirq_pending(x) (S390_lowcore.softirq_pending = (x)) 18 - #define or_softirq_pending(x) (S390_lowcore.softirq_pending |= (x)) 16 + #define local_softirq_pending() (get_lowcore()->softirq_pending) 17 + #define set_softirq_pending(x) (get_lowcore()->softirq_pending = (x)) 18 + #define or_softirq_pending(x) (get_lowcore()->softirq_pending |= (x)) 19 19 20 20 #define __ARCH_IRQ_STAT 21 21 #define __ARCH_IRQ_EXIT_IRQS_DISABLED
+4 -3
arch/s390/include/asm/kvm_host.h
··· 1030 1030 void kvm_arch_crypto_set_masks(struct kvm *kvm, unsigned long *apm, 1031 1031 unsigned long *aqm, unsigned long *adm); 1032 1032 1033 - int __sie64a(phys_addr_t sie_block_phys, struct kvm_s390_sie_block *sie_block, u64 *rsa); 1033 + int __sie64a(phys_addr_t sie_block_phys, struct kvm_s390_sie_block *sie_block, u64 *rsa, 1034 + unsigned long gasce); 1034 1035 1035 - static inline int sie64a(struct kvm_s390_sie_block *sie_block, u64 *rsa) 1036 + static inline int sie64a(struct kvm_s390_sie_block *sie_block, u64 *rsa, unsigned long gasce) 1036 1037 { 1037 - return __sie64a(virt_to_phys(sie_block), sie_block, rsa); 1038 + return __sie64a(virt_to_phys(sie_block), sie_block, rsa, gasce); 1038 1039 } 1039 1040 1040 1041 extern char sie_exit;
+4 -1
arch/s390/include/asm/lowcore.h
··· 213 213 __u8 pad_0x1900[0x2000-0x1900]; /* 0x1900 */ 214 214 } __packed __aligned(8192); 215 215 216 - #define S390_lowcore (*((struct lowcore *) 0)) 216 + static __always_inline struct lowcore *get_lowcore(void) 217 + { 218 + return NULL; 219 + } 217 220 218 221 extern struct lowcore *lowcore_ptr[]; 219 222
+4 -4
arch/s390/include/asm/mmu_context.h
··· 76 76 int cpu = smp_processor_id(); 77 77 78 78 if (next == &init_mm) 79 - S390_lowcore.user_asce = s390_invalid_asce; 79 + get_lowcore()->user_asce = s390_invalid_asce; 80 80 else 81 - S390_lowcore.user_asce.val = next->context.asce; 81 + get_lowcore()->user_asce.val = next->context.asce; 82 82 cpumask_set_cpu(cpu, &next->context.cpu_attach_mask); 83 83 /* Clear previous user-ASCE from CR7 */ 84 84 local_ctl_load(7, &s390_invalid_asce); ··· 111 111 __tlb_flush_mm_lazy(mm); 112 112 preempt_enable(); 113 113 } 114 - local_ctl_load(7, &S390_lowcore.user_asce); 114 + local_ctl_load(7, &get_lowcore()->user_asce); 115 115 } 116 116 117 117 #define activate_mm activate_mm ··· 120 120 { 121 121 switch_mm(prev, next, current); 122 122 cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); 123 - local_ctl_load(7, &S390_lowcore.user_asce); 123 + local_ctl_load(7, &get_lowcore()->user_asce); 124 124 } 125 125 126 126 #include <asm-generic/mmu_context.h>
+5
arch/s390/include/asm/page.h
··· 162 162 #define _PAGE_ACC_BITS 0xf0 /* HW access control bits */ 163 163 164 164 struct page; 165 + struct folio; 165 166 void arch_free_page(struct page *page, int order); 166 167 void arch_alloc_page(struct page *page, int order); 167 168 ··· 175 174 #define HAVE_ARCH_ALLOC_PAGE 176 175 177 176 #if IS_ENABLED(CONFIG_PGSTE) 177 + int arch_make_folio_accessible(struct folio *folio); 178 + #define HAVE_ARCH_MAKE_FOLIO_ACCESSIBLE 178 179 int arch_make_page_accessible(struct page *page); 179 180 #define HAVE_ARCH_MAKE_PAGE_ACCESSIBLE 180 181 #endif ··· 250 247 #define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) 251 248 252 249 #define phys_to_page(phys) pfn_to_page(phys_to_pfn(phys)) 250 + #define phys_to_folio(phys) page_folio(phys_to_page(phys)) 253 251 #define page_to_phys(page) pfn_to_phys(page_to_pfn(page)) 252 + #define folio_to_phys(page) pfn_to_phys(folio_pfn(folio)) 254 253 255 254 static inline void *pfn_to_virt(unsigned long pfn) 256 255 {
+7 -10
arch/s390/include/asm/pai.h
··· 55 55 return; 56 56 if (!static_branch_unlikely(&pai_key)) 57 57 return; 58 - if (!S390_lowcore.ccd) 58 + if (!get_lowcore()->ccd) 59 59 return; 60 60 if (!user_mode(regs)) 61 61 return; 62 - WRITE_ONCE(S390_lowcore.ccd, S390_lowcore.ccd | PAI_CRYPTO_KERNEL_OFFSET); 62 + WRITE_ONCE(get_lowcore()->ccd, get_lowcore()->ccd | PAI_CRYPTO_KERNEL_OFFSET); 63 63 } 64 64 65 65 static __always_inline void pai_kernel_exit(struct pt_regs *regs) ··· 68 68 return; 69 69 if (!static_branch_unlikely(&pai_key)) 70 70 return; 71 - if (!S390_lowcore.ccd) 71 + if (!get_lowcore()->ccd) 72 72 return; 73 73 if (!user_mode(regs)) 74 74 return; 75 - WRITE_ONCE(S390_lowcore.ccd, S390_lowcore.ccd & ~PAI_CRYPTO_KERNEL_OFFSET); 75 + WRITE_ONCE(get_lowcore()->ccd, get_lowcore()->ccd & ~PAI_CRYPTO_KERNEL_OFFSET); 76 76 } 77 77 78 - enum paievt_mode { 79 - PAI_MODE_NONE, 80 - PAI_MODE_SAMPLING, 81 - PAI_MODE_COUNTING, 82 - }; 83 - 84 78 #define PAI_SAVE_AREA(x) ((x)->hw.event_base) 79 + #define PAI_CPU_MASK(x) ((x)->hw.addr_filters) 80 + #define PAI_SWLIST(x) (&(x)->hw.tp_list) 81 + 85 82 #endif
+1 -1
arch/s390/include/asm/percpu.h
··· 9 9 * s390 uses its own implementation for per cpu data, the offset of 10 10 * the cpu local data area is cached in the cpu's lowcore memory. 11 11 */ 12 - #define __my_cpu_offset S390_lowcore.percpu_offset 12 + #define __my_cpu_offset get_lowcore()->percpu_offset 13 13 14 14 /* 15 15 * For 64 bit module code, the module may be more than 4G above the
+27 -6
arch/s390/include/asm/pgtable.h
··· 609 609 : "cc"); 610 610 } 611 611 612 - static inline void cspg(unsigned long *ptr, unsigned long old, unsigned long new) 612 + /** 613 + * cspg() - Compare and Swap and Purge (CSPG) 614 + * @ptr: Pointer to the value to be exchanged 615 + * @old: The expected old value 616 + * @new: The new value 617 + * 618 + * Return: True if compare and swap was successful, otherwise false. 619 + */ 620 + static inline bool cspg(unsigned long *ptr, unsigned long old, unsigned long new) 613 621 { 614 622 union register_pair r1 = { .even = old, .odd = new, }; 615 623 unsigned long address = (unsigned long)ptr | 1; ··· 627 619 : [r1] "+&d" (r1.pair), "+m" (*ptr) 628 620 : [address] "d" (address) 629 621 : "cc"); 622 + return old == r1.even; 630 623 } 631 624 632 625 #define CRDTE_DTT_PAGE 0x00UL ··· 636 627 #define CRDTE_DTT_REGION2 0x18UL 637 628 #define CRDTE_DTT_REGION1 0x1cUL 638 629 639 - static inline void crdte(unsigned long old, unsigned long new, 630 + /** 631 + * crdte() - Compare and Replace DAT Table Entry 632 + * @old: The expected old value 633 + * @new: The new value 634 + * @table: Pointer to the value to be exchanged 635 + * @dtt: Table type of the table to be exchanged 636 + * @address: The address mapped by the entry to be replaced 637 + * @asce: The ASCE of this entry 638 + * 639 + * Return: True if compare and replace was successful, otherwise false. 640 + */ 641 + static inline bool crdte(unsigned long old, unsigned long new, 640 642 unsigned long *table, unsigned long dtt, 641 643 unsigned long address, unsigned long asce) 642 644 { ··· 658 638 : [r1] "+&d" (r1.pair) 659 639 : [r2] "d" (r2.pair), [asce] "a" (asce) 660 640 : "memory", "cc"); 641 + return old == r1.even; 661 642 } 662 643 663 644 /* ··· 1188 1167 res = ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID)); 1189 1168 /* At this point the reference through the mapping is still present */ 1190 1169 if (mm_is_protected(mm) && pte_present(res)) 1191 - uv_convert_owned_from_secure(pte_val(res) & PAGE_MASK); 1170 + uv_convert_from_secure_pte(res); 1192 1171 return res; 1193 1172 } 1194 1173 ··· 1206 1185 res = ptep_xchg_direct(vma->vm_mm, addr, ptep, __pte(_PAGE_INVALID)); 1207 1186 /* At this point the reference through the mapping is still present */ 1208 1187 if (mm_is_protected(vma->vm_mm) && pte_present(res)) 1209 - uv_convert_owned_from_secure(pte_val(res) & PAGE_MASK); 1188 + uv_convert_from_secure_pte(res); 1210 1189 return res; 1211 1190 } 1212 1191 ··· 1238 1217 * The notifier should have destroyed all protected vCPUs at this 1239 1218 * point, so the destroy should be successful. 1240 1219 */ 1241 - if (full && !uv_destroy_owned_page(pte_val(res) & PAGE_MASK)) 1220 + if (full && !uv_destroy_pte(res)) 1242 1221 return res; 1243 1222 /* 1244 1223 * If something went wrong and the page could not be destroyed, or 1245 1224 * if this is not a mm teardown, the slower export is used as 1246 1225 * fallback instead. 1247 1226 */ 1248 - uv_convert_owned_from_secure(pte_val(res) & PAGE_MASK); 1227 + uv_convert_from_secure_pte(res); 1249 1228 return res; 1250 1229 } 1251 1230
+15 -15
arch/s390/include/asm/preempt.h
··· 14 14 15 15 static __always_inline int preempt_count(void) 16 16 { 17 - return READ_ONCE(S390_lowcore.preempt_count) & ~PREEMPT_NEED_RESCHED; 17 + return READ_ONCE(get_lowcore()->preempt_count) & ~PREEMPT_NEED_RESCHED; 18 18 } 19 19 20 20 static __always_inline void preempt_count_set(int pc) ··· 22 22 int old, new; 23 23 24 24 do { 25 - old = READ_ONCE(S390_lowcore.preempt_count); 25 + old = READ_ONCE(get_lowcore()->preempt_count); 26 26 new = (old & PREEMPT_NEED_RESCHED) | 27 27 (pc & ~PREEMPT_NEED_RESCHED); 28 - } while (__atomic_cmpxchg(&S390_lowcore.preempt_count, 28 + } while (__atomic_cmpxchg(&get_lowcore()->preempt_count, 29 29 old, new) != old); 30 30 } 31 31 32 32 static __always_inline void set_preempt_need_resched(void) 33 33 { 34 - __atomic_and(~PREEMPT_NEED_RESCHED, &S390_lowcore.preempt_count); 34 + __atomic_and(~PREEMPT_NEED_RESCHED, &get_lowcore()->preempt_count); 35 35 } 36 36 37 37 static __always_inline void clear_preempt_need_resched(void) 38 38 { 39 - __atomic_or(PREEMPT_NEED_RESCHED, &S390_lowcore.preempt_count); 39 + __atomic_or(PREEMPT_NEED_RESCHED, &get_lowcore()->preempt_count); 40 40 } 41 41 42 42 static __always_inline bool test_preempt_need_resched(void) 43 43 { 44 - return !(READ_ONCE(S390_lowcore.preempt_count) & PREEMPT_NEED_RESCHED); 44 + return !(READ_ONCE(get_lowcore()->preempt_count) & PREEMPT_NEED_RESCHED); 45 45 } 46 46 47 47 static __always_inline void __preempt_count_add(int val) ··· 52 52 */ 53 53 if (!IS_ENABLED(CONFIG_PROFILE_ALL_BRANCHES)) { 54 54 if (__builtin_constant_p(val) && (val >= -128) && (val <= 127)) { 55 - __atomic_add_const(val, &S390_lowcore.preempt_count); 55 + __atomic_add_const(val, &get_lowcore()->preempt_count); 56 56 return; 57 57 } 58 58 } 59 - __atomic_add(val, &S390_lowcore.preempt_count); 59 + __atomic_add(val, &get_lowcore()->preempt_count); 60 60 } 61 61 62 62 static __always_inline void __preempt_count_sub(int val) ··· 66 66 67 67 static __always_inline bool __preempt_count_dec_and_test(void) 68 68 { 69 - return __atomic_add(-1, &S390_lowcore.preempt_count) == 1; 69 + return __atomic_add(-1, &get_lowcore()->preempt_count) == 1; 70 70 } 71 71 72 72 static __always_inline bool should_resched(int preempt_offset) 73 73 { 74 - return unlikely(READ_ONCE(S390_lowcore.preempt_count) == 74 + return unlikely(READ_ONCE(get_lowcore()->preempt_count) == 75 75 preempt_offset); 76 76 } 77 77 ··· 81 81 82 82 static __always_inline int preempt_count(void) 83 83 { 84 - return READ_ONCE(S390_lowcore.preempt_count); 84 + return READ_ONCE(get_lowcore()->preempt_count); 85 85 } 86 86 87 87 static __always_inline void preempt_count_set(int pc) 88 88 { 89 - S390_lowcore.preempt_count = pc; 89 + get_lowcore()->preempt_count = pc; 90 90 } 91 91 92 92 static __always_inline void set_preempt_need_resched(void) ··· 104 104 105 105 static __always_inline void __preempt_count_add(int val) 106 106 { 107 - S390_lowcore.preempt_count += val; 107 + get_lowcore()->preempt_count += val; 108 108 } 109 109 110 110 static __always_inline void __preempt_count_sub(int val) 111 111 { 112 - S390_lowcore.preempt_count -= val; 112 + get_lowcore()->preempt_count -= val; 113 113 } 114 114 115 115 static __always_inline bool __preempt_count_dec_and_test(void) 116 116 { 117 - return !--S390_lowcore.preempt_count && tif_need_resched(); 117 + return !--get_lowcore()->preempt_count && tif_need_resched(); 118 118 } 119 119 120 120 static __always_inline bool should_resched(int preempt_offset)
+4 -4
arch/s390/include/asm/processor.h
··· 46 46 47 47 static __always_inline void set_cpu_flag(int flag) 48 48 { 49 - S390_lowcore.cpu_flags |= (1UL << flag); 49 + get_lowcore()->cpu_flags |= (1UL << flag); 50 50 } 51 51 52 52 static __always_inline void clear_cpu_flag(int flag) 53 53 { 54 - S390_lowcore.cpu_flags &= ~(1UL << flag); 54 + get_lowcore()->cpu_flags &= ~(1UL << flag); 55 55 } 56 56 57 57 static __always_inline bool test_cpu_flag(int flag) 58 58 { 59 - return S390_lowcore.cpu_flags & (1UL << flag); 59 + return get_lowcore()->cpu_flags & (1UL << flag); 60 60 } 61 61 62 62 static __always_inline bool test_and_set_cpu_flag(int flag) ··· 269 269 270 270 static __always_inline bool on_thread_stack(void) 271 271 { 272 - unsigned long ksp = S390_lowcore.kernel_stack; 272 + unsigned long ksp = get_lowcore()->kernel_stack; 273 273 274 274 return !((ksp ^ current_stack_pointer) & ~(THREAD_SIZE - 1)); 275 275 }
+1
arch/s390/include/asm/sclp.h
··· 84 84 unsigned char has_ibs : 1; 85 85 unsigned char has_skey : 1; 86 86 unsigned char has_kss : 1; 87 + unsigned char has_diag204_bif : 1; 87 88 unsigned char has_gisaf : 1; 88 89 unsigned char has_diag318 : 1; 89 90 unsigned char has_diag320 : 1;
+17 -17
arch/s390/include/asm/setup.h
··· 77 77 /* The Write Back bit position in the physaddr is given by the SLPC PCI */ 78 78 extern unsigned long mio_wb_bit_mask; 79 79 80 - #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) 81 - #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) 82 - #define MACHINE_IS_LPAR (S390_lowcore.machine_flags & MACHINE_FLAG_LPAR) 80 + #define MACHINE_IS_VM (get_lowcore()->machine_flags & MACHINE_FLAG_VM) 81 + #define MACHINE_IS_KVM (get_lowcore()->machine_flags & MACHINE_FLAG_KVM) 82 + #define MACHINE_IS_LPAR (get_lowcore()->machine_flags & MACHINE_FLAG_LPAR) 83 83 84 - #define MACHINE_HAS_DIAG9C (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C) 85 - #define MACHINE_HAS_ESOP (S390_lowcore.machine_flags & MACHINE_FLAG_ESOP) 86 - #define MACHINE_HAS_IDTE (S390_lowcore.machine_flags & MACHINE_FLAG_IDTE) 87 - #define MACHINE_HAS_EDAT1 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1) 88 - #define MACHINE_HAS_EDAT2 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT2) 89 - #define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) 90 - #define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE) 91 - #define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC) 92 - #define MACHINE_HAS_TLB_GUEST (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_GUEST) 93 - #define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX) 94 - #define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS) 95 - #define MACHINE_HAS_SCC (S390_lowcore.machine_flags & MACHINE_FLAG_SCC) 96 - #define MACHINE_HAS_PCI_MIO (S390_lowcore.machine_flags & MACHINE_FLAG_PCI_MIO) 97 - #define MACHINE_HAS_RDP (S390_lowcore.machine_flags & MACHINE_FLAG_RDP) 84 + #define MACHINE_HAS_DIAG9C (get_lowcore()->machine_flags & MACHINE_FLAG_DIAG9C) 85 + #define MACHINE_HAS_ESOP (get_lowcore()->machine_flags & MACHINE_FLAG_ESOP) 86 + #define MACHINE_HAS_IDTE (get_lowcore()->machine_flags & MACHINE_FLAG_IDTE) 87 + #define MACHINE_HAS_EDAT1 (get_lowcore()->machine_flags & MACHINE_FLAG_EDAT1) 88 + #define MACHINE_HAS_EDAT2 (get_lowcore()->machine_flags & MACHINE_FLAG_EDAT2) 89 + #define MACHINE_HAS_TOPOLOGY (get_lowcore()->machine_flags & MACHINE_FLAG_TOPOLOGY) 90 + #define MACHINE_HAS_TE (get_lowcore()->machine_flags & MACHINE_FLAG_TE) 91 + #define MACHINE_HAS_TLB_LC (get_lowcore()->machine_flags & MACHINE_FLAG_TLB_LC) 92 + #define MACHINE_HAS_TLB_GUEST (get_lowcore()->machine_flags & MACHINE_FLAG_TLB_GUEST) 93 + #define MACHINE_HAS_NX (get_lowcore()->machine_flags & MACHINE_FLAG_NX) 94 + #define MACHINE_HAS_GS (get_lowcore()->machine_flags & MACHINE_FLAG_GS) 95 + #define MACHINE_HAS_SCC (get_lowcore()->machine_flags & MACHINE_FLAG_SCC) 96 + #define MACHINE_HAS_PCI_MIO (get_lowcore()->machine_flags & MACHINE_FLAG_PCI_MIO) 97 + #define MACHINE_HAS_RDP (get_lowcore()->machine_flags & MACHINE_FLAG_RDP) 98 98 99 99 /* 100 100 * Console mode. Override with conmode=
+2 -2
arch/s390/include/asm/smp.h
··· 11 11 #include <asm/lowcore.h> 12 12 #include <asm/processor.h> 13 13 14 - #define raw_smp_processor_id() (S390_lowcore.cpu_nr) 14 + #define raw_smp_processor_id() (get_lowcore()->cpu_nr) 15 15 16 16 extern struct mutex smp_cpu_state_mutex; 17 17 extern unsigned int smp_cpu_mt_shift; ··· 59 59 { 60 60 } 61 61 62 - extern int smp_rescan_cpus(void); 62 + extern int smp_rescan_cpus(bool early); 63 63 extern void __noreturn cpu_die(void); 64 64 extern void __cpu_die(unsigned int cpu); 65 65 extern int __cpu_disable(void);
+1 -1
arch/s390/include/asm/softirq_stack.h
··· 8 8 #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK 9 9 static inline void do_softirq_own_stack(void) 10 10 { 11 - call_on_stack(0, S390_lowcore.async_stack, void, __do_softirq); 11 + call_on_stack(0, get_lowcore()->async_stack, void, __do_softirq); 12 12 } 13 13 #endif 14 14 #endif /* __ASM_S390_SOFTIRQ_STACK_H */
+1 -1
arch/s390/include/asm/spinlock.h
··· 16 16 #include <asm/processor.h> 17 17 #include <asm/alternative.h> 18 18 19 - #define SPINLOCK_LOCKVAL (S390_lowcore.spinlock_lockval) 19 + #define SPINLOCK_LOCKVAL (get_lowcore()->spinlock_lockval) 20 20 21 21 extern int spin_retry; 22 22
+1
arch/s390/include/asm/stacktrace.h
··· 65 65 unsigned long sie_reason; 66 66 unsigned long sie_flags; 67 67 unsigned long sie_control_block_phys; 68 + unsigned long sie_guest_asce; 68 69 }; 69 70 }; 70 71 unsigned long gprs[10];
+5 -5
arch/s390/include/asm/timex.h
··· 161 161 { 162 162 unsigned long old; 163 163 164 - old = S390_lowcore.clock_comparator; 165 - S390_lowcore.clock_comparator = clock_comparator_max; 166 - set_clock_comparator(S390_lowcore.clock_comparator); 164 + old = get_lowcore()->clock_comparator; 165 + get_lowcore()->clock_comparator = clock_comparator_max; 166 + set_clock_comparator(get_lowcore()->clock_comparator); 167 167 return old; 168 168 } 169 169 170 170 static inline void local_tick_enable(unsigned long comp) 171 171 { 172 - S390_lowcore.clock_comparator = comp; 173 - set_clock_comparator(S390_lowcore.clock_comparator); 172 + get_lowcore()->clock_comparator = comp; 173 + set_clock_comparator(get_lowcore()->clock_comparator); 174 174 } 175 175 176 176 #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
+6 -6
arch/s390/include/asm/uv.h
··· 483 483 int uv_pin_shared(unsigned long paddr); 484 484 int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb); 485 485 int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr); 486 - int uv_destroy_owned_page(unsigned long paddr); 487 - int uv_convert_from_secure(unsigned long paddr); 488 - int uv_convert_owned_from_secure(unsigned long paddr); 486 + int uv_destroy_folio(struct folio *folio); 487 + int uv_destroy_pte(pte_t pte); 488 + int uv_convert_from_secure_pte(pte_t pte); 489 489 int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr); 490 490 491 491 void setup_uv(void); ··· 498 498 return 0; 499 499 } 500 500 501 - static inline int uv_destroy_owned_page(unsigned long paddr) 501 + static inline int uv_destroy_folio(struct folio *folio) 502 502 { 503 503 return 0; 504 504 } 505 505 506 - static inline int uv_convert_from_secure(unsigned long paddr) 506 + static inline int uv_destroy_pte(pte_t pte) 507 507 { 508 508 return 0; 509 509 } 510 510 511 - static inline int uv_convert_owned_from_secure(unsigned long paddr) 511 + static inline int uv_convert_from_secure_pte(pte_t pte) 512 512 { 513 513 return 0; 514 514 }
+10 -6
arch/s390/include/asm/vtime.h
··· 4 4 5 5 static inline void update_timer_sys(void) 6 6 { 7 - S390_lowcore.system_timer += S390_lowcore.last_update_timer - S390_lowcore.exit_timer; 8 - S390_lowcore.user_timer += S390_lowcore.exit_timer - S390_lowcore.sys_enter_timer; 9 - S390_lowcore.last_update_timer = S390_lowcore.sys_enter_timer; 7 + struct lowcore *lc = get_lowcore(); 8 + 9 + lc->system_timer += lc->last_update_timer - lc->exit_timer; 10 + lc->user_timer += lc->exit_timer - lc->sys_enter_timer; 11 + lc->last_update_timer = lc->sys_enter_timer; 10 12 } 11 13 12 14 static inline void update_timer_mcck(void) 13 15 { 14 - S390_lowcore.system_timer += S390_lowcore.last_update_timer - S390_lowcore.exit_timer; 15 - S390_lowcore.user_timer += S390_lowcore.exit_timer - S390_lowcore.mcck_enter_timer; 16 - S390_lowcore.last_update_timer = S390_lowcore.mcck_enter_timer; 16 + struct lowcore *lc = get_lowcore(); 17 + 18 + lc->system_timer += lc->last_update_timer - lc->exit_timer; 19 + lc->user_timer += lc->exit_timer - lc->mcck_enter_timer; 20 + lc->last_update_timer = lc->mcck_enter_timer; 17 21 } 18 22 19 23 #endif /* _S390_VTIME_H */
+1
arch/s390/kernel/asm-offsets.c
··· 63 63 OFFSET(__SF_SIE_REASON, stack_frame, sie_reason); 64 64 OFFSET(__SF_SIE_FLAGS, stack_frame, sie_flags); 65 65 OFFSET(__SF_SIE_CONTROL_PHYS, stack_frame, sie_control_block_phys); 66 + OFFSET(__SF_SIE_GUEST_ASCE, stack_frame, sie_guest_asce); 66 67 DEFINE(STACK_FRAME_OVERHEAD, sizeof(struct stack_frame)); 67 68 BLANK(); 68 69 OFFSET(__SFUSER_BACKCHAIN, stack_frame_user, back_chain);
+8 -4
arch/s390/kernel/diag.c
··· 185 185 } 186 186 EXPORT_SYMBOL(diag14); 187 187 188 + #define DIAG204_BUSY_RC 8 189 + 188 190 static inline int __diag204(unsigned long *subcode, unsigned long size, void *addr) 189 191 { 190 192 union register_pair rp = { .even = *subcode, .odd = size }; ··· 217 215 { 218 216 if (addr) { 219 217 if (WARN_ON_ONCE(!is_vmalloc_addr(addr))) 220 - return -1; 218 + return -EINVAL; 221 219 if (WARN_ON_ONCE(!IS_ALIGNED((unsigned long)addr, PAGE_SIZE))) 222 - return -1; 220 + return -EINVAL; 223 221 } 224 222 if ((subcode & DIAG204_SUBCODE_MASK) == DIAG204_SUBC_STIB4) 225 223 addr = (void *)pfn_to_phys(vmalloc_to_pfn(addr)); 226 224 diag_stat_inc(DIAG_STAT_X204); 227 225 size = __diag204(&subcode, size, addr); 228 - if (subcode) 229 - return -1; 226 + if (subcode == DIAG204_BUSY_RC) 227 + return -EBUSY; 228 + else if (subcode) 229 + return -EOPNOTSUPP; 230 230 return size; 231 231 } 232 232 EXPORT_SYMBOL(diag204);
+4 -4
arch/s390/kernel/dumpstack.c
··· 61 61 62 62 static bool in_irq_stack(unsigned long sp, struct stack_info *info) 63 63 { 64 - unsigned long stack = S390_lowcore.async_stack - STACK_INIT_OFFSET; 64 + unsigned long stack = get_lowcore()->async_stack - STACK_INIT_OFFSET; 65 65 66 66 return in_stack(sp, info, STACK_TYPE_IRQ, stack); 67 67 } 68 68 69 69 static bool in_nodat_stack(unsigned long sp, struct stack_info *info) 70 70 { 71 - unsigned long stack = S390_lowcore.nodat_stack - STACK_INIT_OFFSET; 71 + unsigned long stack = get_lowcore()->nodat_stack - STACK_INIT_OFFSET; 72 72 73 73 return in_stack(sp, info, STACK_TYPE_NODAT, stack); 74 74 } 75 75 76 76 static bool in_mcck_stack(unsigned long sp, struct stack_info *info) 77 77 { 78 - unsigned long stack = S390_lowcore.mcck_stack - STACK_INIT_OFFSET; 78 + unsigned long stack = get_lowcore()->mcck_stack - STACK_INIT_OFFSET; 79 79 80 80 return in_stack(sp, info, STACK_TYPE_MCCK, stack); 81 81 } 82 82 83 83 static bool in_restart_stack(unsigned long sp, struct stack_info *info) 84 84 { 85 - unsigned long stack = S390_lowcore.restart_stack - STACK_INIT_OFFSET; 85 + unsigned long stack = get_lowcore()->restart_stack - STACK_INIT_OFFSET; 86 86 87 87 return in_stack(sp, info, STACK_TYPE_RESTART, stack); 88 88 }
+18 -18
arch/s390/kernel/early.c
··· 72 72 73 73 memset(&tod_clock_base, 0, sizeof(tod_clock_base)); 74 74 tod_clock_base.tod = TOD_UNIX_EPOCH; 75 - S390_lowcore.last_update_clock = TOD_UNIX_EPOCH; 75 + get_lowcore()->last_update_clock = TOD_UNIX_EPOCH; 76 76 } 77 77 78 78 /* ··· 99 99 100 100 /* Check current-configuration-level */ 101 101 if (stsi(NULL, 0, 0, 0) <= 2) { 102 - S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR; 102 + get_lowcore()->machine_flags |= MACHINE_FLAG_LPAR; 103 103 return; 104 104 } 105 105 /* Get virtual-machine cpu information. */ ··· 108 108 109 109 /* Detect known hypervisors */ 110 110 if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3)) 111 - S390_lowcore.machine_flags |= MACHINE_FLAG_KVM; 111 + get_lowcore()->machine_flags |= MACHINE_FLAG_KVM; 112 112 else if (!memcmp(vmms->vm[0].cpi, "\xa9\x61\xe5\xd4", 4)) 113 - S390_lowcore.machine_flags |= MACHINE_FLAG_VM; 113 + get_lowcore()->machine_flags |= MACHINE_FLAG_VM; 114 114 } 115 115 116 116 /* Remove leading, trailing and double whitespace. */ ··· 166 166 167 167 if (!test_facility(11)) 168 168 return; 169 - S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY; 169 + get_lowcore()->machine_flags |= MACHINE_FLAG_TOPOLOGY; 170 170 for (max_mnest = 6; max_mnest > 1; max_mnest--) { 171 171 if (stsi(&sysinfo_page, 15, 1, max_mnest) == 0) 172 172 break; ··· 186 186 187 187 psw.addr = (unsigned long)early_pgm_check_handler; 188 188 psw.mask = PSW_KERNEL_BITS; 189 - S390_lowcore.program_new_psw = psw; 190 - S390_lowcore.preempt_count = INIT_PREEMPT_COUNT; 189 + get_lowcore()->program_new_psw = psw; 190 + get_lowcore()->preempt_count = INIT_PREEMPT_COUNT; 191 191 } 192 192 193 193 static noinline __init void setup_facility_list(void) ··· 211 211 EX_TABLE(0b,1b) 212 212 : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); 213 213 if (!rc) 214 - S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG9C; 214 + get_lowcore()->machine_flags |= MACHINE_FLAG_DIAG9C; 215 215 } 216 216 217 217 static __init void detect_machine_facilities(void) 218 218 { 219 219 if (test_facility(8)) { 220 - S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT1; 220 + get_lowcore()->machine_flags |= MACHINE_FLAG_EDAT1; 221 221 system_ctl_set_bit(0, CR0_EDAT_BIT); 222 222 } 223 223 if (test_facility(78)) 224 - S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT2; 224 + get_lowcore()->machine_flags |= MACHINE_FLAG_EDAT2; 225 225 if (test_facility(3)) 226 - S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; 226 + get_lowcore()->machine_flags |= MACHINE_FLAG_IDTE; 227 227 if (test_facility(50) && test_facility(73)) { 228 - S390_lowcore.machine_flags |= MACHINE_FLAG_TE; 228 + get_lowcore()->machine_flags |= MACHINE_FLAG_TE; 229 229 system_ctl_set_bit(0, CR0_TRANSACTIONAL_EXECUTION_BIT); 230 230 } 231 231 if (test_facility(51)) 232 - S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC; 232 + get_lowcore()->machine_flags |= MACHINE_FLAG_TLB_LC; 233 233 if (test_facility(129)) 234 234 system_ctl_set_bit(0, CR0_VECTOR_BIT); 235 235 if (test_facility(130)) 236 - S390_lowcore.machine_flags |= MACHINE_FLAG_NX; 236 + get_lowcore()->machine_flags |= MACHINE_FLAG_NX; 237 237 if (test_facility(133)) 238 - S390_lowcore.machine_flags |= MACHINE_FLAG_GS; 238 + get_lowcore()->machine_flags |= MACHINE_FLAG_GS; 239 239 if (test_facility(139) && (tod_clock_base.tod >> 63)) { 240 240 /* Enabled signed clock comparator comparisons */ 241 - S390_lowcore.machine_flags |= MACHINE_FLAG_SCC; 241 + get_lowcore()->machine_flags |= MACHINE_FLAG_SCC; 242 242 clock_comparator_max = -1ULL >> 1; 243 243 system_ctl_set_bit(0, CR0_CLOCK_COMPARATOR_SIGN_BIT); 244 244 } 245 245 if (IS_ENABLED(CONFIG_PCI) && test_facility(153)) { 246 - S390_lowcore.machine_flags |= MACHINE_FLAG_PCI_MIO; 246 + get_lowcore()->machine_flags |= MACHINE_FLAG_PCI_MIO; 247 247 /* the control bit is set during PCI initialization */ 248 248 } 249 249 if (test_facility(194)) 250 - S390_lowcore.machine_flags |= MACHINE_FLAG_RDP; 250 + get_lowcore()->machine_flags |= MACHINE_FLAG_RDP; 251 251 } 252 252 253 253 static inline void save_vector_registers(void)
+3 -5
arch/s390/kernel/entry.S
··· 179 179 * %r2 pointer to sie control block phys 180 180 * %r3 pointer to sie control block virt 181 181 * %r4 guest register save area 182 + * %r5 guest asce 182 183 */ 183 184 SYM_FUNC_START(__sie64a) 184 185 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers ··· 187 186 stg %r2,__SF_SIE_CONTROL_PHYS(%r15) # save sie block physical.. 188 187 stg %r3,__SF_SIE_CONTROL(%r15) # ...and virtual addresses 189 188 stg %r4,__SF_SIE_SAVEAREA(%r15) # save guest register save area 189 + stg %r5,__SF_SIE_GUEST_ASCE(%r15) # save guest asce 190 190 xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0 191 191 mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags 192 192 lmg %r0,%r13,0(%r4) # load guest gprs 0-13 193 - lg %r14,__LC_GMAP # get gmap pointer 194 - ltgr %r14,%r14 195 - jz .Lsie_gmap 196 193 oi __LC_CPU_FLAGS+7,_CIF_SIE 197 - lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce 198 - .Lsie_gmap: 194 + lctlg %c1,%c1,__SF_SIE_GUEST_ASCE(%r15) # load primary asce 199 195 lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer 200 196 oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now 201 197 tm __SIE_PROG20+3(%r14),3 # last exit...
+6 -5
arch/s390/kernel/idle.c
··· 24 24 void account_idle_time_irq(void) 25 25 { 26 26 struct s390_idle_data *idle = this_cpu_ptr(&s390_idle); 27 + struct lowcore *lc = get_lowcore(); 27 28 unsigned long idle_time; 28 29 u64 cycles_new[8]; 29 30 int i; ··· 35 34 this_cpu_add(mt_cycles[i], cycles_new[i] - idle->mt_cycles_enter[i]); 36 35 } 37 36 38 - idle_time = S390_lowcore.int_clock - idle->clock_idle_enter; 37 + idle_time = lc->int_clock - idle->clock_idle_enter; 39 38 40 - S390_lowcore.steal_timer += idle->clock_idle_enter - S390_lowcore.last_update_clock; 41 - S390_lowcore.last_update_clock = S390_lowcore.int_clock; 39 + lc->steal_timer += idle->clock_idle_enter - lc->last_update_clock; 40 + lc->last_update_clock = lc->int_clock; 42 41 43 - S390_lowcore.system_timer += S390_lowcore.last_update_timer - idle->timer_idle_enter; 44 - S390_lowcore.last_update_timer = S390_lowcore.sys_enter_timer; 42 + lc->system_timer += lc->last_update_timer - idle->timer_idle_enter; 43 + lc->last_update_timer = lc->sys_enter_timer; 45 44 46 45 /* Account time spent with enabled wait psw loaded as idle time. */ 47 46 WRITE_ONCE(idle->idle_time, READ_ONCE(idle->idle_time) + idle_time);
+9 -9
arch/s390/kernel/irq.c
··· 100 100 101 101 static void do_IRQ(struct pt_regs *regs, int irq) 102 102 { 103 - if (tod_after_eq(S390_lowcore.int_clock, 104 - S390_lowcore.clock_comparator)) 103 + if (tod_after_eq(get_lowcore()->int_clock, 104 + get_lowcore()->clock_comparator)) 105 105 /* Serve timer interrupts first. */ 106 106 clock_comparator_work(); 107 107 generic_handle_irq(irq); ··· 111 111 { 112 112 unsigned long frame = current_frame_address(); 113 113 114 - return ((S390_lowcore.async_stack ^ frame) & ~(THREAD_SIZE - 1)) == 0; 114 + return ((get_lowcore()->async_stack ^ frame) & ~(THREAD_SIZE - 1)) == 0; 115 115 } 116 116 117 117 static void do_irq_async(struct pt_regs *regs, int irq) ··· 119 119 if (on_async_stack()) { 120 120 do_IRQ(regs, irq); 121 121 } else { 122 - call_on_stack(2, S390_lowcore.async_stack, void, do_IRQ, 122 + call_on_stack(2, get_lowcore()->async_stack, void, do_IRQ, 123 123 struct pt_regs *, regs, int, irq); 124 124 } 125 125 } ··· 153 153 154 154 set_cpu_flag(CIF_NOHZ_DELAY); 155 155 do { 156 - regs->tpi_info = S390_lowcore.tpi_info; 157 - if (S390_lowcore.tpi_info.adapter_IO) 156 + regs->tpi_info = get_lowcore()->tpi_info; 157 + if (get_lowcore()->tpi_info.adapter_IO) 158 158 do_irq_async(regs, THIN_INTERRUPT); 159 159 else 160 160 do_irq_async(regs, IO_INTERRUPT); ··· 183 183 current->thread.last_break = regs->last_break; 184 184 } 185 185 186 - regs->int_code = S390_lowcore.ext_int_code_addr; 187 - regs->int_parm = S390_lowcore.ext_params; 188 - regs->int_parm_long = S390_lowcore.ext_params2; 186 + regs->int_code = get_lowcore()->ext_int_code_addr; 187 + regs->int_parm = get_lowcore()->ext_params; 188 + regs->int_parm_long = get_lowcore()->ext_params2; 189 189 190 190 from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT); 191 191 if (from_idle)
+2 -2
arch/s390/kernel/machine_kexec.c
··· 52 52 purgatory = (purgatory_t)image->start; 53 53 54 54 /* store_status() saved the prefix register to lowcore */ 55 - prefix = (unsigned long) S390_lowcore.prefixreg_save_area; 55 + prefix = (unsigned long)get_lowcore()->prefixreg_save_area; 56 56 57 57 /* Now do the reset */ 58 58 s390_reset_system(); ··· 91 91 continue; 92 92 } 93 93 /* Store status of the boot CPU */ 94 - mcesa = __va(S390_lowcore.mcesad & MCESA_ORIGIN_MASK); 94 + mcesa = __va(get_lowcore()->mcesad & MCESA_ORIGIN_MASK); 95 95 if (cpu_has_vx()) 96 96 save_vx_regs((__vector128 *) mcesa->vector_save_area); 97 97 if (MACHINE_HAS_GS) {
+16 -15
arch/s390/kernel/nmi.c
··· 117 117 118 118 static notrace void s390_handle_damage(void) 119 119 { 120 + struct lowcore *lc = get_lowcore(); 120 121 union ctlreg0 cr0, cr0_new; 121 122 char message[100]; 122 123 psw_t psw_save; ··· 126 125 smp_emergency_stop(); 127 126 diag_amode31_ops.diag308_reset(); 128 127 ptr = nmi_puts(message, "System stopped due to unrecoverable machine check, code: 0x"); 129 - u64_to_hex(ptr, S390_lowcore.mcck_interruption_code); 128 + u64_to_hex(ptr, lc->mcck_interruption_code); 130 129 131 130 /* 132 131 * Disable low address protection and make machine check new PSW a ··· 136 135 cr0_new = cr0; 137 136 cr0_new.lap = 0; 138 137 local_ctl_load(0, &cr0_new.reg); 139 - psw_save = S390_lowcore.mcck_new_psw; 140 - psw_bits(S390_lowcore.mcck_new_psw).io = 0; 141 - psw_bits(S390_lowcore.mcck_new_psw).ext = 0; 142 - psw_bits(S390_lowcore.mcck_new_psw).wait = 1; 138 + psw_save = lc->mcck_new_psw; 139 + psw_bits(lc->mcck_new_psw).io = 0; 140 + psw_bits(lc->mcck_new_psw).ext = 0; 141 + psw_bits(lc->mcck_new_psw).wait = 1; 143 142 sclp_emergency_printk(message); 144 143 145 144 /* 146 145 * Restore machine check new PSW and control register 0 to original 147 146 * values. This makes possible system dump analysis easier. 148 147 */ 149 - S390_lowcore.mcck_new_psw = psw_save; 148 + lc->mcck_new_psw = psw_save; 150 149 local_ctl_load(0, &cr0.reg); 151 150 disabled_wait(); 152 151 while (1); ··· 227 226 /* 228 227 * Set the clock comparator register to the next expected value. 229 228 */ 230 - set_clock_comparator(S390_lowcore.clock_comparator); 229 + set_clock_comparator(get_lowcore()->clock_comparator); 231 230 if (!mci.gr || !mci.fp || !mci.fc) 232 231 return false; 233 232 /* ··· 253 252 * check handling must take care of this. The host values are saved by 254 253 * KVM and are not affected. 255 254 */ 256 - cr2.reg = S390_lowcore.cregs_save_area[2]; 255 + cr2.reg = get_lowcore()->cregs_save_area[2]; 257 256 if (cr2.gse && !mci.gs && !test_cpu_flag(CIF_MCCK_GUEST)) 258 257 return false; 259 258 if (!mci.ms || !mci.pm || !mci.ia) ··· 279 278 280 279 sie_page = container_of(sie_block, struct sie_page, sie_block); 281 280 mcck_backup = &sie_page->mcck_info; 282 - mcck_backup->mcic = S390_lowcore.mcck_interruption_code & 281 + mcck_backup->mcic = get_lowcore()->mcck_interruption_code & 283 282 ~(MCCK_CODE_CP | MCCK_CODE_EXT_DAMAGE); 284 - mcck_backup->ext_damage_code = S390_lowcore.external_damage_code; 285 - mcck_backup->failing_storage_address 286 - = S390_lowcore.failing_storage_address; 283 + mcck_backup->ext_damage_code = get_lowcore()->external_damage_code; 284 + mcck_backup->failing_storage_address = get_lowcore()->failing_storage_address; 287 285 } 288 286 NOKPROBE_SYMBOL(s390_backup_mcck_info); 289 287 ··· 302 302 static int ipd_count; 303 303 static DEFINE_SPINLOCK(ipd_lock); 304 304 static unsigned long long last_ipd; 305 + struct lowcore *lc = get_lowcore(); 305 306 struct mcck_struct *mcck; 306 307 unsigned long long tmp; 307 308 irqentry_state_t irq_state; ··· 315 314 if (user_mode(regs)) 316 315 update_timer_mcck(); 317 316 inc_irq_stat(NMI_NMI); 318 - mci.val = S390_lowcore.mcck_interruption_code; 317 + mci.val = lc->mcck_interruption_code; 319 318 mcck = this_cpu_ptr(&cpu_mcck); 320 319 321 320 /* ··· 383 382 } 384 383 if (mci.ed && mci.ec) { 385 384 /* External damage */ 386 - if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC)) 385 + if (lc->external_damage_code & (1U << ED_STP_SYNC)) 387 386 mcck->stp_queue |= stp_sync_check(); 388 - if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND)) 387 + if (lc->external_damage_code & (1U << ED_STP_ISLAND)) 389 388 mcck->stp_queue |= stp_island_check(); 390 389 mcck_pending = 1; 391 390 }
+1 -1
arch/s390/kernel/perf_cpum_sf.c
··· 1022 1022 } 1023 1023 1024 1024 /* Load current program parameter */ 1025 - lpp(&S390_lowcore.lpp); 1025 + lpp(&get_lowcore()->lpp); 1026 1026 1027 1027 debug_sprintf_event(sfdbg, 6, "%s: es %i cs %i ed %i cd %i " 1028 1028 "interval %#lx tear %#lx dear %#lx\n", __func__,
+115 -74
arch/s390/kernel/perf_pai_crypto.c
··· 36 36 struct pai_userdata *save; /* Page to store no-zero counters */ 37 37 unsigned int active_events; /* # of PAI crypto users */ 38 38 refcount_t refcnt; /* Reference count mapped buffers */ 39 - enum paievt_mode mode; /* Type of event */ 40 39 struct perf_event *event; /* Perf event for sampling */ 40 + struct list_head syswide_list; /* List system-wide sampling events */ 41 41 }; 42 42 43 43 struct paicrypt_mapptr { ··· 84 84 /* Adjust usage counters and remove allocated memory when all users are 85 85 * gone. 86 86 */ 87 - static void paicrypt_event_destroy(struct perf_event *event) 87 + static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu) 88 88 { 89 - struct paicrypt_mapptr *mp = per_cpu_ptr(paicrypt_root.mapptr, 90 - event->cpu); 89 + struct paicrypt_mapptr *mp = per_cpu_ptr(paicrypt_root.mapptr, cpu); 91 90 struct paicrypt_map *cpump = mp->mapptr; 92 91 93 - static_branch_dec(&pai_key); 94 92 mutex_lock(&pai_reserve_mutex); 95 - debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d" 96 - " mode %d refcnt %u\n", __func__, 97 - event->attr.config, event->cpu, 98 - cpump->active_events, cpump->mode, 93 + debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d " 94 + "refcnt %u\n", __func__, event->attr.config, 95 + event->cpu, cpump->active_events, 99 96 refcount_read(&cpump->refcnt)); 100 - free_page(PAI_SAVE_AREA(event)); 101 97 if (refcount_dec_and_test(&cpump->refcnt)) { 102 98 debug_sprintf_event(cfm_dbg, 4, "%s page %#lx save %p\n", 103 99 __func__, (unsigned long)cpump->page, ··· 105 109 } 106 110 paicrypt_root_free(); 107 111 mutex_unlock(&pai_reserve_mutex); 112 + } 113 + 114 + static void paicrypt_event_destroy(struct perf_event *event) 115 + { 116 + int cpu; 117 + 118 + static_branch_dec(&pai_key); 119 + free_page(PAI_SAVE_AREA(event)); 120 + if (event->cpu == -1) { 121 + struct cpumask *mask = PAI_CPU_MASK(event); 122 + 123 + for_each_cpu(cpu, mask) 124 + paicrypt_event_destroy_cpu(event, cpu); 125 + kfree(mask); 126 + } else { 127 + paicrypt_event_destroy_cpu(event, event->cpu); 128 + } 108 129 } 109 130 110 131 static u64 paicrypt_getctr(unsigned long *page, int nr, bool kernel) ··· 169 156 return sum; 170 157 } 171 158 172 - /* Used to avoid races in checking concurrent access of counting and 173 - * sampling for crypto events 174 - * 175 - * Only one instance of event pai_crypto/CRYPTO_ALL/ for sampling is 176 - * allowed and when this event is running, no counting event is allowed. 177 - * Several counting events are allowed in parallel, but no sampling event 178 - * is allowed while one (or more) counting events are running. 179 - * 159 + /* Check concurrent access of counting and sampling for crypto events. 180 160 * This function is called in process context and it is save to block. 181 161 * When the event initialization functions fails, no other call back will 182 162 * be invoked. 183 163 * 184 164 * Allocate the memory for the event. 185 165 */ 186 - static struct paicrypt_map *paicrypt_busy(struct perf_event *event) 166 + static struct paicrypt_map *paicrypt_busy(struct perf_event *event, int cpu) 187 167 { 188 - struct perf_event_attr *a = &event->attr; 189 168 struct paicrypt_map *cpump = NULL; 190 169 struct paicrypt_mapptr *mp; 191 170 int rc; ··· 190 185 goto unlock; 191 186 192 187 /* Allocate node for this event */ 193 - mp = per_cpu_ptr(paicrypt_root.mapptr, event->cpu); 188 + mp = per_cpu_ptr(paicrypt_root.mapptr, cpu); 194 189 cpump = mp->mapptr; 195 190 if (!cpump) { /* Paicrypt_map allocated? */ 196 191 cpump = kzalloc(sizeof(*cpump), GFP_KERNEL); ··· 198 193 rc = -ENOMEM; 199 194 goto free_root; 200 195 } 196 + INIT_LIST_HEAD(&cpump->syswide_list); 201 197 } 202 - 203 - if (a->sample_period) { /* Sampling requested */ 204 - if (cpump->mode != PAI_MODE_NONE) 205 - rc = -EBUSY; /* ... sampling/counting active */ 206 - } else { /* Counting requested */ 207 - if (cpump->mode == PAI_MODE_SAMPLING) 208 - rc = -EBUSY; /* ... and sampling active */ 209 - } 210 - /* 211 - * This error case triggers when there is a conflict: 212 - * Either sampling requested and counting already active, or visa 213 - * versa. Therefore the struct paicrypto_map for this CPU is 214 - * needed or the error could not have occurred. Only adjust root 215 - * node refcount. 216 - */ 217 - if (rc) 218 - goto free_root; 219 198 220 199 /* Allocate memory for counter page and counter extraction. 221 200 * Only the first counting event has to allocate a page. ··· 224 235 /* Set mode and reference count */ 225 236 rc = 0; 226 237 refcount_set(&cpump->refcnt, 1); 227 - cpump->mode = a->sample_period ? PAI_MODE_SAMPLING : PAI_MODE_COUNTING; 228 238 mp->mapptr = cpump; 229 - debug_sprintf_event(cfm_dbg, 5, "%s sample_period %#llx users %d" 230 - " mode %d refcnt %u page %#lx save %p rc %d\n", 231 - __func__, a->sample_period, cpump->active_events, 232 - cpump->mode, refcount_read(&cpump->refcnt), 239 + debug_sprintf_event(cfm_dbg, 5, "%s users %d refcnt %u page %#lx " 240 + "save %p rc %d\n", __func__, cpump->active_events, 241 + refcount_read(&cpump->refcnt), 233 242 (unsigned long)cpump->page, cpump->save, rc); 234 243 goto unlock; 235 244 236 245 free_paicrypt_map: 246 + /* Undo memory allocation */ 237 247 kfree(cpump); 238 248 mp->mapptr = NULL; 239 249 free_root: 240 250 paicrypt_root_free(); 241 - 242 251 unlock: 243 252 mutex_unlock(&pai_reserve_mutex); 244 253 return rc ? ERR_PTR(rc) : cpump; 254 + } 255 + 256 + static int paicrypt_event_init_all(struct perf_event *event) 257 + { 258 + struct paicrypt_map *cpump; 259 + struct cpumask *maskptr; 260 + int cpu, rc = -ENOMEM; 261 + 262 + maskptr = kzalloc(sizeof(*maskptr), GFP_KERNEL); 263 + if (!maskptr) 264 + goto out; 265 + 266 + for_each_online_cpu(cpu) { 267 + cpump = paicrypt_busy(event, cpu); 268 + if (IS_ERR(cpump)) { 269 + for_each_cpu(cpu, maskptr) 270 + paicrypt_event_destroy_cpu(event, cpu); 271 + kfree(maskptr); 272 + rc = PTR_ERR(cpump); 273 + goto out; 274 + } 275 + cpumask_set_cpu(cpu, maskptr); 276 + } 277 + 278 + /* 279 + * On error all cpumask are freed and all events have been destroyed. 280 + * Save of which CPUs data structures have been allocated for. 281 + * Release them in paicrypt_event_destroy call back function 282 + * for this event. 283 + */ 284 + PAI_CPU_MASK(event) = maskptr; 285 + rc = 0; 286 + out: 287 + return rc; 245 288 } 246 289 247 290 /* Might be called on different CPU than the one the event is intended for. */ ··· 290 269 if (a->config < PAI_CRYPTO_BASE || 291 270 a->config > PAI_CRYPTO_BASE + paicrypt_cnt) 292 271 return -EINVAL; 293 - /* Allow only CPU wide operation, no process context for now. */ 294 - if ((event->attach_state & PERF_ATTACH_TASK) || event->cpu == -1) 295 - return -ENOENT; 296 - /* Allow only CRYPTO_ALL for sampling. */ 272 + /* Allow only CRYPTO_ALL for sampling */ 297 273 if (a->sample_period && a->config != PAI_CRYPTO_BASE) 298 274 return -EINVAL; 299 275 /* Get a page to store last counter values for sampling */ ··· 302 284 } 303 285 } 304 286 305 - cpump = paicrypt_busy(event); 306 - if (IS_ERR(cpump)) { 287 + if (event->cpu >= 0) { 288 + cpump = paicrypt_busy(event, event->cpu); 289 + if (IS_ERR(cpump)) 290 + rc = PTR_ERR(cpump); 291 + } else { 292 + rc = paicrypt_event_init_all(event); 293 + } 294 + if (rc) { 307 295 free_page(PAI_SAVE_AREA(event)); 308 - rc = PTR_ERR(cpump); 309 296 goto out; 310 297 } 311 - 312 298 event->destroy = paicrypt_event_destroy; 313 299 314 300 if (a->sample_period) { ··· 353 331 sum = paicrypt_getall(event); /* Get current value */ 354 332 local64_set(&event->hw.prev_count, sum); 355 333 } else { /* Sampling */ 356 - cpump->event = event; 357 - perf_sched_cb_inc(event->pmu); 334 + memcpy((void *)PAI_SAVE_AREA(event), cpump->page, PAGE_SIZE); 335 + /* Enable context switch callback for system-wide sampling */ 336 + if (!(event->attach_state & PERF_ATTACH_TASK)) { 337 + list_add_tail(PAI_SWLIST(event), &cpump->syswide_list); 338 + perf_sched_cb_inc(event->pmu); 339 + } else { 340 + cpump->event = event; 341 + } 358 342 } 359 343 } 360 344 ··· 372 344 373 345 if (++cpump->active_events == 1) { 374 346 ccd = virt_to_phys(cpump->page) | PAI_CRYPTO_KERNEL_OFFSET; 375 - WRITE_ONCE(S390_lowcore.ccd, ccd); 347 + WRITE_ONCE(get_lowcore()->ccd, ccd); 376 348 local_ctl_set_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT); 377 349 } 378 350 if (flags & PERF_EF_START) ··· 381 353 return 0; 382 354 } 383 355 356 + static void paicrypt_have_sample(struct perf_event *, struct paicrypt_map *); 384 357 static void paicrypt_stop(struct perf_event *event, int flags) 385 358 { 386 359 struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); ··· 390 361 if (!event->attr.sample_period) { /* Counting */ 391 362 paicrypt_read(event); 392 363 } else { /* Sampling */ 393 - perf_sched_cb_dec(event->pmu); 394 - cpump->event = NULL; 364 + if (!(event->attach_state & PERF_ATTACH_TASK)) { 365 + perf_sched_cb_dec(event->pmu); 366 + list_del(PAI_SWLIST(event)); 367 + } else { 368 + paicrypt_have_sample(event, cpump); 369 + cpump->event = NULL; 370 + } 395 371 } 396 372 event->hw.state = PERF_HES_STOPPED; 397 373 } ··· 409 375 paicrypt_stop(event, PERF_EF_UPDATE); 410 376 if (--cpump->active_events == 0) { 411 377 local_ctl_clear_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT); 412 - WRITE_ONCE(S390_lowcore.ccd, 0); 378 + WRITE_ONCE(get_lowcore()->ccd, 0); 413 379 } 414 380 } 415 381 ··· 489 455 } 490 456 491 457 /* Check if there is data to be saved on schedule out of a task. */ 492 - static int paicrypt_have_sample(void) 458 + static void paicrypt_have_sample(struct perf_event *event, 459 + struct paicrypt_map *cpump) 460 + { 461 + size_t rawsize; 462 + 463 + if (!event) /* No event active */ 464 + return; 465 + rawsize = paicrypt_copy(cpump->save, cpump->page, 466 + (unsigned long *)PAI_SAVE_AREA(event), 467 + event->attr.exclude_user, 468 + event->attr.exclude_kernel); 469 + if (rawsize) /* No incremented counters */ 470 + paicrypt_push_sample(rawsize, cpump, event); 471 + } 472 + 473 + /* Check if there is data to be saved on schedule out of a task. */ 474 + static void paicrypt_have_samples(void) 493 475 { 494 476 struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); 495 477 struct paicrypt_map *cpump = mp->mapptr; 496 - struct perf_event *event = cpump->event; 497 - size_t rawsize; 498 - int rc = 0; 478 + struct perf_event *event; 499 479 500 - if (!event) /* No event active */ 501 - return 0; 502 - rawsize = paicrypt_copy(cpump->save, cpump->page, 503 - (unsigned long *)PAI_SAVE_AREA(event), 504 - cpump->event->attr.exclude_user, 505 - cpump->event->attr.exclude_kernel); 506 - if (rawsize) /* No incremented counters */ 507 - rc = paicrypt_push_sample(rawsize, cpump, event); 508 - return rc; 480 + list_for_each_entry(event, &cpump->syswide_list, hw.tp_list) 481 + paicrypt_have_sample(event, cpump); 509 482 } 510 483 511 484 /* Called on schedule-in and schedule-out. No access to event structure, ··· 521 480 static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in) 522 481 { 523 482 /* We started with a clean page on event installation. So read out 524 - * results on schedule_out and if page was dirty, clear values. 483 + * results on schedule_out and if page was dirty, save old values. 525 484 */ 526 485 if (!sched_in) 527 - paicrypt_have_sample(); 486 + paicrypt_have_samples(); 528 487 } 529 488 530 489 /* Attribute definitions for paicrypt interface. As with other CPU ··· 568 527 569 528 /* Performance monitoring unit for mapped counters */ 570 529 static struct pmu paicrypt = { 571 - .task_ctx_nr = perf_invalid_context, 530 + .task_ctx_nr = perf_hw_context, 572 531 .event_init = paicrypt_event_init, 573 532 .add = paicrypt_add, 574 533 .del = paicrypt_del,
+99 -47
arch/s390/kernel/perf_pai_ext.c
··· 47 47 struct paiext_map { 48 48 unsigned long *area; /* Area for CPU to store counters */ 49 49 struct pai_userdata *save; /* Area to store non-zero counters */ 50 - enum paievt_mode mode; /* Type of event */ 51 50 unsigned int active_events; /* # of PAI Extension users */ 52 51 refcount_t refcnt; 53 52 struct perf_event *event; /* Perf event for sampling */ 54 53 struct paiext_cb *paiext_cb; /* PAI extension control block area */ 54 + struct list_head syswide_list; /* List system-wide sampling events */ 55 55 }; 56 56 57 57 struct paiext_mapptr { ··· 70 70 free_percpu(paiext_root.mapptr); 71 71 paiext_root.mapptr = NULL; 72 72 } 73 + debug_sprintf_event(paiext_dbg, 5, "%s root.refcount %d\n", __func__, 74 + refcount_read(&paiext_root.refcnt)); 73 75 } 74 76 75 77 /* On initialization of first event also allocate per CPU data dynamically. ··· 117 115 } 118 116 119 117 /* Release the PMU if event is the last perf event */ 120 - static void paiext_event_destroy(struct perf_event *event) 118 + static void paiext_event_destroy_cpu(struct perf_event *event, int cpu) 121 119 { 122 - struct paiext_mapptr *mp = per_cpu_ptr(paiext_root.mapptr, event->cpu); 120 + struct paiext_mapptr *mp = per_cpu_ptr(paiext_root.mapptr, cpu); 123 121 struct paiext_map *cpump = mp->mapptr; 124 122 125 - free_page(PAI_SAVE_AREA(event)); 126 123 mutex_lock(&paiext_reserve_mutex); 127 124 if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */ 128 125 paiext_free(mp); 129 126 paiext_root_free(); 130 127 mutex_unlock(&paiext_reserve_mutex); 131 - debug_sprintf_event(paiext_dbg, 4, "%s cpu %d mapptr %p\n", __func__, 132 - event->cpu, mp->mapptr); 128 + } 133 129 130 + static void paiext_event_destroy(struct perf_event *event) 131 + { 132 + int cpu; 133 + 134 + free_page(PAI_SAVE_AREA(event)); 135 + if (event->cpu == -1) { 136 + struct cpumask *mask = PAI_CPU_MASK(event); 137 + 138 + for_each_cpu(cpu, mask) 139 + paiext_event_destroy_cpu(event, cpu); 140 + kfree(mask); 141 + } else { 142 + paiext_event_destroy_cpu(event, event->cpu); 143 + } 144 + debug_sprintf_event(paiext_dbg, 4, "%s cpu %d\n", __func__, 145 + event->cpu); 134 146 } 135 147 136 148 /* Used to avoid races in checking concurrent access of counting and ··· 161 145 * 162 146 * Allocate the memory for the event. 163 147 */ 164 - static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event) 148 + static int paiext_alloc_cpu(struct perf_event *event, int cpu) 165 149 { 166 150 struct paiext_mapptr *mp; 167 151 struct paiext_map *cpump; 168 152 int rc; 169 153 170 154 mutex_lock(&paiext_reserve_mutex); 171 - 172 155 rc = paiext_root_alloc(); 173 156 if (rc) 174 157 goto unlock; 175 158 176 - mp = per_cpu_ptr(paiext_root.mapptr, event->cpu); 159 + mp = per_cpu_ptr(paiext_root.mapptr, cpu); 177 160 cpump = mp->mapptr; 178 161 if (!cpump) { /* Paiext_map allocated? */ 179 162 rc = -ENOMEM; ··· 200 185 paiext_free(mp); 201 186 goto undo; 202 187 } 188 + INIT_LIST_HEAD(&cpump->syswide_list); 203 189 refcount_set(&cpump->refcnt, 1); 204 - cpump->mode = a->sample_period ? PAI_MODE_SAMPLING 205 - : PAI_MODE_COUNTING; 190 + rc = 0; 206 191 } else { 207 - /* Multiple invocation, check what is active. 208 - * Supported are multiple counter events or only one sampling 209 - * event concurrently at any one time. 210 - */ 211 - if (cpump->mode == PAI_MODE_SAMPLING || 212 - (cpump->mode == PAI_MODE_COUNTING && a->sample_period)) { 213 - rc = -EBUSY; 214 - goto undo; 215 - } 216 192 refcount_inc(&cpump->refcnt); 217 193 } 218 - 219 - rc = 0; 220 194 221 195 undo: 222 196 if (rc) { ··· 218 214 unlock: 219 215 mutex_unlock(&paiext_reserve_mutex); 220 216 /* If rc is non-zero, no increment of counter/sampler was done. */ 217 + return rc; 218 + } 219 + 220 + static int paiext_alloc(struct perf_event *event) 221 + { 222 + struct cpumask *maskptr; 223 + int cpu, rc = -ENOMEM; 224 + 225 + maskptr = kzalloc(sizeof(*maskptr), GFP_KERNEL); 226 + if (!maskptr) 227 + goto out; 228 + 229 + for_each_online_cpu(cpu) { 230 + rc = paiext_alloc_cpu(event, cpu); 231 + if (rc) { 232 + for_each_cpu(cpu, maskptr) 233 + paiext_event_destroy_cpu(event, cpu); 234 + kfree(maskptr); 235 + goto out; 236 + } 237 + cpumask_set_cpu(cpu, maskptr); 238 + } 239 + 240 + /* 241 + * On error all cpumask are freed and all events have been destroyed. 242 + * Save of which CPUs data structures have been allocated for. 243 + * Release them in paicrypt_event_destroy call back function 244 + * for this event. 245 + */ 246 + PAI_CPU_MASK(event) = maskptr; 247 + rc = 0; 248 + out: 221 249 return rc; 222 250 } 223 251 ··· 282 246 rc = paiext_event_valid(event); 283 247 if (rc) 284 248 return rc; 285 - /* Allow only CPU wide operation, no process context for now. */ 286 - if ((event->attach_state & PERF_ATTACH_TASK) || event->cpu == -1) 287 - return -ENOENT; 288 249 /* Allow only event NNPA_ALL for sampling. */ 289 250 if (a->sample_period && a->config != PAI_NNPA_BASE) 290 251 return -EINVAL; ··· 295 262 return -ENOMEM; 296 263 } 297 264 298 - rc = paiext_alloc(a, event); 265 + if (event->cpu >= 0) 266 + rc = paiext_alloc_cpu(event, event->cpu); 267 + else 268 + rc = paiext_alloc(event); 299 269 if (rc) { 300 270 free_page(PAI_SAVE_AREA(event)); 301 271 return rc; ··· 370 334 sum = paiext_getall(event); /* Get current value */ 371 335 local64_set(&event->hw.prev_count, sum); 372 336 } else { /* Sampling */ 373 - cpump->event = event; 374 - perf_sched_cb_inc(event->pmu); 337 + memcpy((void *)PAI_SAVE_AREA(event), cpump->area, 338 + PAIE1_CTRBLOCK_SZ); 339 + /* Enable context switch callback for system-wide sampling */ 340 + if (!(event->attach_state & PERF_ATTACH_TASK)) { 341 + list_add_tail(PAI_SWLIST(event), &cpump->syswide_list); 342 + perf_sched_cb_inc(event->pmu); 343 + } else { 344 + cpump->event = event; 345 + } 375 346 } 376 347 } 377 348 ··· 389 346 struct paiext_cb *pcb = cpump->paiext_cb; 390 347 391 348 if (++cpump->active_events == 1) { 392 - S390_lowcore.aicd = virt_to_phys(cpump->paiext_cb); 349 + get_lowcore()->aicd = virt_to_phys(cpump->paiext_cb); 393 350 pcb->acc = virt_to_phys(cpump->area) | 0x1; 394 351 /* Enable CPU instruction lookup for PAIE1 control block */ 395 352 local_ctl_set_bit(0, CR0_PAI_EXTENSION_BIT); 396 - debug_sprintf_event(paiext_dbg, 4, "%s 1508 %llx acc %llx\n", 397 - __func__, S390_lowcore.aicd, pcb->acc); 398 353 } 399 354 if (flags & PERF_EF_START) 400 355 paiext_start(event, PERF_EF_RELOAD); ··· 400 359 return 0; 401 360 } 402 361 362 + static void paiext_have_sample(struct perf_event *, struct paiext_map *); 403 363 static void paiext_stop(struct perf_event *event, int flags) 404 364 { 405 365 struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); ··· 409 367 if (!event->attr.sample_period) { /* Counting */ 410 368 paiext_read(event); 411 369 } else { /* Sampling */ 412 - perf_sched_cb_dec(event->pmu); 413 - cpump->event = NULL; 370 + if (!(event->attach_state & PERF_ATTACH_TASK)) { 371 + list_del(PAI_SWLIST(event)); 372 + perf_sched_cb_dec(event->pmu); 373 + } else { 374 + paiext_have_sample(event, cpump); 375 + cpump->event = NULL; 376 + } 414 377 } 415 378 event->hw.state = PERF_HES_STOPPED; 416 379 } ··· 431 384 /* Disable CPU instruction lookup for PAIE1 control block */ 432 385 local_ctl_clear_bit(0, CR0_PAI_EXTENSION_BIT); 433 386 pcb->acc = 0; 434 - S390_lowcore.aicd = 0; 435 - debug_sprintf_event(paiext_dbg, 4, "%s 1508 %llx acc %llx\n", 436 - __func__, S390_lowcore.aicd, pcb->acc); 387 + get_lowcore()->aicd = 0; 437 388 } 438 389 } 439 390 ··· 515 470 } 516 471 517 472 /* Check if there is data to be saved on schedule out of a task. */ 518 - static int paiext_have_sample(void) 473 + static void paiext_have_sample(struct perf_event *event, 474 + struct paiext_map *cpump) 519 475 { 520 - struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); 521 - struct paiext_map *cpump = mp->mapptr; 522 - struct perf_event *event = cpump->event; 523 476 size_t rawsize; 524 - int rc = 0; 525 477 526 478 if (!event) 527 - return 0; 479 + return; 528 480 rawsize = paiext_copy(cpump->save, cpump->area, 529 481 (unsigned long *)PAI_SAVE_AREA(event)); 530 482 if (rawsize) /* Incremented counters */ 531 - rc = paiext_push_sample(rawsize, cpump, event); 532 - return rc; 483 + paiext_push_sample(rawsize, cpump, event); 484 + } 485 + 486 + /* Check if there is data to be saved on schedule out of a task. */ 487 + static void paiext_have_samples(void) 488 + { 489 + struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); 490 + struct paiext_map *cpump = mp->mapptr; 491 + struct perf_event *event; 492 + 493 + list_for_each_entry(event, &cpump->syswide_list, hw.tp_list) 494 + paiext_have_sample(event, cpump); 533 495 } 534 496 535 497 /* Called on schedule-in and schedule-out. No access to event structure, ··· 545 493 static void paiext_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in) 546 494 { 547 495 /* We started with a clean page on event installation. So read out 548 - * results on schedule_out and if page was dirty, clear values. 496 + * results on schedule_out and if page was dirty, save old values. 549 497 */ 550 498 if (!sched_in) 551 - paiext_have_sample(); 499 + paiext_have_samples(); 552 500 } 553 501 554 502 /* Attribute definitions for pai extension1 interface. As with other CPU ··· 594 542 595 543 /* Performance monitoring unit for mapped counters */ 596 544 static struct pmu paiext = { 597 - .task_ctx_nr = perf_invalid_context, 545 + .task_ctx_nr = perf_hw_context, 598 546 .event_init = paiext_event_init, 599 547 .add = paiext_add, 600 548 .del = paiext_del,
+3 -3
arch/s390/kernel/process.c
··· 71 71 72 72 void arch_setup_new_exec(void) 73 73 { 74 - if (S390_lowcore.current_pid != current->pid) { 75 - S390_lowcore.current_pid = current->pid; 74 + if (get_lowcore()->current_pid != current->pid) { 75 + get_lowcore()->current_pid = current->pid; 76 76 if (test_facility(40)) 77 - lpp(&S390_lowcore.lpp); 77 + lpp(&get_lowcore()->lpp); 78 78 } 79 79 } 80 80
+12 -12
arch/s390/kernel/setup.c
··· 421 421 lc->clock_comparator = clock_comparator_max; 422 422 lc->current_task = (unsigned long)&init_task; 423 423 lc->lpp = LPP_MAGIC; 424 - lc->machine_flags = S390_lowcore.machine_flags; 425 - lc->preempt_count = S390_lowcore.preempt_count; 424 + lc->machine_flags = get_lowcore()->machine_flags; 425 + lc->preempt_count = get_lowcore()->preempt_count; 426 426 nmi_alloc_mcesa_early(&lc->mcesad); 427 - lc->sys_enter_timer = S390_lowcore.sys_enter_timer; 428 - lc->exit_timer = S390_lowcore.exit_timer; 429 - lc->user_timer = S390_lowcore.user_timer; 430 - lc->system_timer = S390_lowcore.system_timer; 431 - lc->steal_timer = S390_lowcore.steal_timer; 432 - lc->last_update_timer = S390_lowcore.last_update_timer; 433 - lc->last_update_clock = S390_lowcore.last_update_clock; 427 + lc->sys_enter_timer = get_lowcore()->sys_enter_timer; 428 + lc->exit_timer = get_lowcore()->exit_timer; 429 + lc->user_timer = get_lowcore()->user_timer; 430 + lc->system_timer = get_lowcore()->system_timer; 431 + lc->steal_timer = get_lowcore()->steal_timer; 432 + lc->last_update_timer = get_lowcore()->last_update_timer; 433 + lc->last_update_clock = get_lowcore()->last_update_clock; 434 434 /* 435 435 * Allocate the global restart stack which is the same for 436 436 * all CPUs in case *one* of them does a PSW restart. ··· 439 439 lc->mcck_stack = stack_alloc_early() + STACK_INIT_OFFSET; 440 440 lc->async_stack = stack_alloc_early() + STACK_INIT_OFFSET; 441 441 lc->nodat_stack = stack_alloc_early() + STACK_INIT_OFFSET; 442 - lc->kernel_stack = S390_lowcore.kernel_stack; 442 + lc->kernel_stack = get_lowcore()->kernel_stack; 443 443 /* 444 444 * Set up PSW restart to call ipl.c:do_restart(). Copy the relevant 445 445 * restart data to the absolute zero lowcore. This is necessary if ··· 455 455 lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); 456 456 lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); 457 457 lc->preempt_count = PREEMPT_DISABLED; 458 - lc->kernel_asce = S390_lowcore.kernel_asce; 459 - lc->user_asce = S390_lowcore.user_asce; 458 + lc->kernel_asce = get_lowcore()->kernel_asce; 459 + lc->user_asce = get_lowcore()->user_asce; 460 460 461 461 system_ctlreg_init_save_area(lc); 462 462 abs_lc = get_abs_lowcore();
+38 -50
arch/s390/kernel/smp.c
··· 74 74 CPU_STATE_CONFIGURED, 75 75 }; 76 76 77 - static DEFINE_PER_CPU(struct cpu *, cpu_device); 78 - 79 77 struct pcpu { 80 78 unsigned long ec_mask; /* bit mask for ec_xxx functions */ 81 79 unsigned long ec_clk; /* sigp timestamp for ec_xxx */ ··· 201 203 mcck_stack = stack_alloc(); 202 204 if (!lc || !nodat_stack || !async_stack || !mcck_stack) 203 205 goto out; 204 - memcpy(lc, &S390_lowcore, 512); 206 + memcpy(lc, get_lowcore(), 512); 205 207 memset((char *) lc + 512, 0, sizeof(*lc) - 512); 206 208 lc->async_stack = async_stack + STACK_INIT_OFFSET; 207 209 lc->nodat_stack = nodat_stack + STACK_INIT_OFFSET; ··· 263 265 lc->spinlock_lockval = arch_spin_lockval(cpu); 264 266 lc->spinlock_index = 0; 265 267 lc->percpu_offset = __per_cpu_offset[cpu]; 266 - lc->kernel_asce = S390_lowcore.kernel_asce; 268 + lc->kernel_asce = get_lowcore()->kernel_asce; 267 269 lc->user_asce = s390_invalid_asce; 268 - lc->machine_flags = S390_lowcore.machine_flags; 270 + lc->machine_flags = get_lowcore()->machine_flags; 269 271 lc->user_timer = lc->system_timer = 270 272 lc->steal_timer = lc->avg_steal_timer = 0; 271 273 abs_lc = get_abs_lowcore(); ··· 405 407 struct lowcore *lc = lowcore_ptr[0]; 406 408 407 409 if (pcpu_devices[0].address == stap()) 408 - lc = &S390_lowcore; 410 + lc = get_lowcore(); 409 411 410 412 pcpu_delegate(&pcpu_devices[0], func, data, 411 413 lc->nodat_stack); ··· 717 719 } 718 720 } 719 721 720 - static int smp_add_present_cpu(int cpu); 721 - 722 722 static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail, 723 723 bool configured, bool early) 724 724 { ··· 740 744 pcpu->state = CPU_STATE_STANDBY; 741 745 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 742 746 set_cpu_present(cpu, true); 743 - if (!early && smp_add_present_cpu(cpu) != 0) 747 + if (!early && arch_register_cpu(cpu)) 744 748 set_cpu_present(cpu, false); 745 749 else 746 750 nr++; ··· 827 831 s_cpus += smp_cpu_mtid + 1; 828 832 } 829 833 pr_info("%d configured CPUs, %d standby CPUs\n", c_cpus, s_cpus); 830 - 831 - /* Add CPUs present at boot */ 832 - __smp_rescan_cpus(info, true); 833 834 memblock_free(info, sizeof(*info)); 834 835 } 835 836 ··· 835 842 */ 836 843 static void smp_start_secondary(void *cpuvoid) 837 844 { 845 + struct lowcore *lc = get_lowcore(); 838 846 int cpu = raw_smp_processor_id(); 839 847 840 - S390_lowcore.last_update_clock = get_tod_clock(); 841 - S390_lowcore.restart_stack = (unsigned long)restart_stack; 842 - S390_lowcore.restart_fn = (unsigned long)do_restart; 843 - S390_lowcore.restart_data = 0; 844 - S390_lowcore.restart_source = -1U; 845 - S390_lowcore.restart_flags = 0; 846 - restore_access_regs(S390_lowcore.access_regs_save_area); 848 + lc->last_update_clock = get_tod_clock(); 849 + lc->restart_stack = (unsigned long)restart_stack; 850 + lc->restart_fn = (unsigned long)do_restart; 851 + lc->restart_data = 0; 852 + lc->restart_source = -1U; 853 + lc->restart_flags = 0; 854 + restore_access_regs(lc->access_regs_save_area); 847 855 cpu_init(); 848 856 rcutree_report_cpu_starting(cpu); 849 857 init_cpu_timer(); ··· 967 973 if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt)) 968 974 panic("Couldn't request external interrupt 0x1202"); 969 975 system_ctl_set_bit(0, 13); 976 + smp_rescan_cpus(true); 970 977 } 971 978 972 979 void __init smp_prepare_boot_cpu(void) ··· 976 981 977 982 WARN_ON(!cpu_present(0) || !cpu_online(0)); 978 983 pcpu->state = CPU_STATE_CONFIGURED; 979 - S390_lowcore.percpu_offset = __per_cpu_offset[0]; 984 + get_lowcore()->percpu_offset = __per_cpu_offset[0]; 980 985 smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); 981 986 } 982 987 983 988 void __init smp_setup_processor_id(void) 984 989 { 990 + struct lowcore *lc = get_lowcore(); 991 + 985 992 pcpu_devices[0].address = stap(); 986 - S390_lowcore.cpu_nr = 0; 987 - S390_lowcore.spinlock_lockval = arch_spin_lockval(0); 988 - S390_lowcore.spinlock_index = 0; 993 + lc->cpu_nr = 0; 994 + lc->spinlock_lockval = arch_spin_lockval(0); 995 + lc->spinlock_index = 0; 989 996 } 990 997 991 998 /* ··· 1105 1108 1106 1109 static int smp_cpu_online(unsigned int cpu) 1107 1110 { 1108 - struct device *s = &per_cpu(cpu_device, cpu)->dev; 1111 + struct cpu *c = &per_cpu(cpu_devices, cpu); 1109 1112 1110 - return sysfs_create_group(&s->kobj, &cpu_online_attr_group); 1113 + return sysfs_create_group(&c->dev.kobj, &cpu_online_attr_group); 1111 1114 } 1112 1115 1113 1116 static int smp_cpu_pre_down(unsigned int cpu) 1114 1117 { 1115 - struct device *s = &per_cpu(cpu_device, cpu)->dev; 1118 + struct cpu *c = &per_cpu(cpu_devices, cpu); 1116 1119 1117 - sysfs_remove_group(&s->kobj, &cpu_online_attr_group); 1120 + sysfs_remove_group(&c->dev.kobj, &cpu_online_attr_group); 1118 1121 return 0; 1119 1122 } 1120 1123 1121 - static int smp_add_present_cpu(int cpu) 1124 + bool arch_cpu_is_hotpluggable(int cpu) 1122 1125 { 1123 - struct device *s; 1124 - struct cpu *c; 1126 + return !!cpu; 1127 + } 1128 + 1129 + int arch_register_cpu(int cpu) 1130 + { 1131 + struct cpu *c = &per_cpu(cpu_devices, cpu); 1125 1132 int rc; 1126 1133 1127 - c = kzalloc(sizeof(*c), GFP_KERNEL); 1128 - if (!c) 1129 - return -ENOMEM; 1130 - per_cpu(cpu_device, cpu) = c; 1131 - s = &c->dev; 1132 - c->hotpluggable = !!cpu; 1134 + c->hotpluggable = arch_cpu_is_hotpluggable(cpu); 1133 1135 rc = register_cpu(c, cpu); 1134 1136 if (rc) 1135 1137 goto out; 1136 - rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group); 1138 + rc = sysfs_create_group(&c->dev.kobj, &cpu_common_attr_group); 1137 1139 if (rc) 1138 1140 goto out_cpu; 1139 1141 rc = topology_cpu_init(c); ··· 1141 1145 return 0; 1142 1146 1143 1147 out_topology: 1144 - sysfs_remove_group(&s->kobj, &cpu_common_attr_group); 1148 + sysfs_remove_group(&c->dev.kobj, &cpu_common_attr_group); 1145 1149 out_cpu: 1146 1150 unregister_cpu(c); 1147 1151 out: 1148 1152 return rc; 1149 1153 } 1150 1154 1151 - int __ref smp_rescan_cpus(void) 1155 + int __ref smp_rescan_cpus(bool early) 1152 1156 { 1153 1157 struct sclp_core_info *info; 1154 1158 int nr; ··· 1157 1161 if (!info) 1158 1162 return -ENOMEM; 1159 1163 smp_get_core_info(info, 0); 1160 - nr = __smp_rescan_cpus(info, false); 1164 + nr = __smp_rescan_cpus(info, early); 1161 1165 kfree(info); 1162 1166 if (nr) 1163 1167 topology_schedule_update(); ··· 1174 1178 rc = lock_device_hotplug_sysfs(); 1175 1179 if (rc) 1176 1180 return rc; 1177 - rc = smp_rescan_cpus(); 1181 + rc = smp_rescan_cpus(false); 1178 1182 unlock_device_hotplug(); 1179 1183 return rc ? rc : count; 1180 1184 } ··· 1183 1187 static int __init s390_smp_init(void) 1184 1188 { 1185 1189 struct device *dev_root; 1186 - int cpu, rc = 0; 1190 + int rc; 1187 1191 1188 1192 dev_root = bus_get_dev_root(&cpu_subsys); 1189 1193 if (dev_root) { ··· 1192 1196 if (rc) 1193 1197 return rc; 1194 1198 } 1195 - 1196 - for_each_present_cpu(cpu) { 1197 - rc = smp_add_present_cpu(cpu); 1198 - if (rc) 1199 - goto out; 1200 - } 1201 - 1202 1199 rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "s390/smp:online", 1203 1200 smp_cpu_online, smp_cpu_pre_down); 1204 1201 rc = rc <= 0 ? rc : 0; 1205 - out: 1206 1202 return rc; 1207 1203 } 1208 1204 subsys_initcall(s390_smp_init);
+66 -29
arch/s390/kernel/sthyi.c
··· 300 300 return (struct diag204_x_part_block *)&block->cpus[i]; 301 301 } 302 302 303 - static void fill_diag(struct sthyi_sctns *sctns) 303 + static void *diag204_get_data(bool diag204_allow_busy) 304 304 { 305 - int i, r, pages; 306 - bool this_lpar; 305 + unsigned long subcode; 307 306 void *diag204_buf; 307 + int pages, rc; 308 + 309 + subcode = DIAG204_SUBC_RSI; 310 + subcode |= DIAG204_INFO_EXT; 311 + pages = diag204(subcode, 0, NULL); 312 + if (pages < 0) 313 + return ERR_PTR(pages); 314 + if (pages == 0) 315 + return ERR_PTR(-ENODATA); 316 + diag204_buf = __vmalloc_node(array_size(pages, PAGE_SIZE), 317 + PAGE_SIZE, GFP_KERNEL, NUMA_NO_NODE, 318 + __builtin_return_address(0)); 319 + if (!diag204_buf) 320 + return ERR_PTR(-ENOMEM); 321 + subcode = DIAG204_SUBC_STIB7; 322 + subcode |= DIAG204_INFO_EXT; 323 + if (diag204_has_bif() && diag204_allow_busy) 324 + subcode |= DIAG204_BIF_BIT; 325 + rc = diag204(subcode, pages, diag204_buf); 326 + if (rc < 0) { 327 + vfree(diag204_buf); 328 + return ERR_PTR(rc); 329 + } 330 + return diag204_buf; 331 + } 332 + 333 + static bool is_diag204_cached(struct sthyi_sctns *sctns) 334 + { 335 + /* 336 + * Check if validity bits are set when diag204 data 337 + * is gathered. 338 + */ 339 + if (sctns->par.infpval1) 340 + return true; 341 + return false; 342 + } 343 + 344 + static void fill_diag(struct sthyi_sctns *sctns, void *diag204_buf) 345 + { 346 + int i; 347 + bool this_lpar; 308 348 void *diag224_buf = NULL; 309 349 struct diag204_x_info_blk_hdr *ti_hdr; 310 350 struct diag204_x_part_block *part_block; 311 351 struct diag204_x_phys_block *phys_block; 312 352 struct lpar_cpu_inf lpar_inf = {}; 313 - 314 - /* Errors are handled through the validity bits in the response. */ 315 - pages = diag204((unsigned long)DIAG204_SUBC_RSI | 316 - (unsigned long)DIAG204_INFO_EXT, 0, NULL); 317 - if (pages <= 0) 318 - return; 319 - 320 - diag204_buf = __vmalloc_node(array_size(pages, PAGE_SIZE), 321 - PAGE_SIZE, GFP_KERNEL, NUMA_NO_NODE, 322 - __builtin_return_address(0)); 323 - if (!diag204_buf) 324 - return; 325 - 326 - r = diag204((unsigned long)DIAG204_SUBC_STIB7 | 327 - (unsigned long)DIAG204_INFO_EXT, pages, diag204_buf); 328 - if (r < 0) 329 - goto out; 330 353 331 354 diag224_buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); 332 355 if (!diag224_buf || diag224(diag224_buf)) ··· 415 392 416 393 out: 417 394 free_page((unsigned long)diag224_buf); 418 - vfree(diag204_buf); 419 395 } 420 396 421 397 static int sthyi(u64 vaddr, u64 *rc) ··· 436 414 437 415 static int fill_dst(void *dst, u64 *rc) 438 416 { 417 + void *diag204_buf; 418 + 439 419 struct sthyi_sctns *sctns = (struct sthyi_sctns *)dst; 440 420 441 421 /* 442 422 * If the facility is on, we don't want to emulate the instruction. 443 423 * We ask the hypervisor to provide the data. 444 424 */ 445 - if (test_facility(74)) 425 + if (test_facility(74)) { 426 + memset(dst, 0, PAGE_SIZE); 446 427 return sthyi((u64)dst, rc); 447 - 428 + } 429 + /* 430 + * When emulating, if diag204 returns BUSY don't reset dst buffer 431 + * and use cached data. 432 + */ 433 + *rc = 0; 434 + diag204_buf = diag204_get_data(is_diag204_cached(sctns)); 435 + if (IS_ERR(diag204_buf)) 436 + return PTR_ERR(diag204_buf); 437 + memset(dst, 0, PAGE_SIZE); 448 438 fill_hdr(sctns); 449 439 fill_stsi(sctns); 450 - fill_diag(sctns); 451 - *rc = 0; 440 + fill_diag(sctns, diag204_buf); 441 + vfree(diag204_buf); 452 442 return 0; 453 443 } 454 444 ··· 479 445 { 480 446 int r; 481 447 482 - memset(sthyi_cache.info, 0, PAGE_SIZE); 483 448 r = fill_dst(sthyi_cache.info, rc); 484 - if (r) 485 - return r; 486 - sthyi_cache.end = jiffies + CACHE_VALID_JIFFIES; 449 + if (r == 0) { 450 + sthyi_cache.end = jiffies + CACHE_VALID_JIFFIES; 451 + } else if (r == -EBUSY) { 452 + /* mark as expired and return 0 to keep using cached data */ 453 + sthyi_cache.end = jiffies - 1; 454 + r = 0; 455 + } 487 456 return r; 488 457 } 489 458
+2 -2
arch/s390/kernel/syscall.c
··· 124 124 { 125 125 add_random_kstack_offset(); 126 126 enter_from_user_mode(regs); 127 - regs->psw = S390_lowcore.svc_old_psw; 128 - regs->int_code = S390_lowcore.svc_int_code; 127 + regs->psw = get_lowcore()->svc_old_psw; 128 + regs->int_code = get_lowcore()->svc_int_code; 129 129 update_timer_sys(); 130 130 if (static_branch_likely(&cpu_has_bear)) 131 131 current->thread.last_break = regs->last_break;
+11 -11
arch/s390/kernel/time.c
··· 131 131 { 132 132 struct clock_event_device *cd; 133 133 134 - S390_lowcore.clock_comparator = clock_comparator_max; 134 + get_lowcore()->clock_comparator = clock_comparator_max; 135 135 cd = this_cpu_ptr(&comparators); 136 136 cd->event_handler(cd); 137 137 } ··· 139 139 static int s390_next_event(unsigned long delta, 140 140 struct clock_event_device *evt) 141 141 { 142 - S390_lowcore.clock_comparator = get_tod_clock() + delta; 143 - set_clock_comparator(S390_lowcore.clock_comparator); 142 + get_lowcore()->clock_comparator = get_tod_clock() + delta; 143 + set_clock_comparator(get_lowcore()->clock_comparator); 144 144 return 0; 145 145 } 146 146 ··· 153 153 struct clock_event_device *cd; 154 154 int cpu; 155 155 156 - S390_lowcore.clock_comparator = clock_comparator_max; 157 - set_clock_comparator(S390_lowcore.clock_comparator); 156 + get_lowcore()->clock_comparator = clock_comparator_max; 157 + set_clock_comparator(get_lowcore()->clock_comparator); 158 158 159 159 cpu = smp_processor_id(); 160 160 cd = &per_cpu(comparators, cpu); ··· 184 184 unsigned long param64) 185 185 { 186 186 inc_irq_stat(IRQEXT_CLK); 187 - if (S390_lowcore.clock_comparator == clock_comparator_max) 188 - set_clock_comparator(S390_lowcore.clock_comparator); 187 + if (get_lowcore()->clock_comparator == clock_comparator_max) 188 + set_clock_comparator(get_lowcore()->clock_comparator); 189 189 } 190 190 191 191 static void stp_timing_alert(struct stp_irq_parm *); ··· 408 408 static void clock_sync_local(long delta) 409 409 { 410 410 /* Add the delta to the clock comparator. */ 411 - if (S390_lowcore.clock_comparator != clock_comparator_max) { 412 - S390_lowcore.clock_comparator += delta; 413 - set_clock_comparator(S390_lowcore.clock_comparator); 411 + if (get_lowcore()->clock_comparator != clock_comparator_max) { 412 + get_lowcore()->clock_comparator += delta; 413 + set_clock_comparator(get_lowcore()->clock_comparator); 414 414 } 415 415 /* Adjust the last_update_clock time-stamp. */ 416 - S390_lowcore.last_update_clock += delta; 416 + get_lowcore()->last_update_clock += delta; 417 417 } 418 418 419 419 /* Single threaded workqueue used for stp sync events */
+1 -7
arch/s390/kernel/topology.c
··· 320 320 321 321 int arch_update_cpu_topology(void) 322 322 { 323 - struct device *dev; 324 - int cpu, rc; 323 + int rc; 325 324 326 325 rc = __arch_update_cpu_topology(); 327 326 on_each_cpu(__arch_update_dedicated_flag, NULL, 0); 328 - for_each_online_cpu(cpu) { 329 - dev = get_cpu_device(cpu); 330 - if (dev) 331 - kobject_uevent(&dev->kobj, KOBJ_CHANGE); 332 - } 333 327 return rc; 334 328 } 335 329
+15 -13
arch/s390/kernel/traps.c
··· 288 288 289 289 void __init trap_init(void) 290 290 { 291 + struct lowcore *lc = get_lowcore(); 291 292 unsigned long flags; 292 293 struct ctlreg cr0; 293 294 294 295 local_irq_save(flags); 295 296 cr0 = local_ctl_clear_bit(0, CR0_LOW_ADDRESS_PROTECTION_BIT); 296 - psw_bits(S390_lowcore.external_new_psw).mcheck = 1; 297 - psw_bits(S390_lowcore.program_new_psw).mcheck = 1; 298 - psw_bits(S390_lowcore.svc_new_psw).mcheck = 1; 299 - psw_bits(S390_lowcore.io_new_psw).mcheck = 1; 297 + psw_bits(lc->external_new_psw).mcheck = 1; 298 + psw_bits(lc->program_new_psw).mcheck = 1; 299 + psw_bits(lc->svc_new_psw).mcheck = 1; 300 + psw_bits(lc->io_new_psw).mcheck = 1; 300 301 local_ctl_load(0, &cr0); 301 302 local_irq_restore(flags); 302 303 local_mcck_enable(); ··· 308 307 309 308 void noinstr __do_pgm_check(struct pt_regs *regs) 310 309 { 311 - unsigned int trapnr; 310 + struct lowcore *lc = get_lowcore(); 312 311 irqentry_state_t state; 312 + unsigned int trapnr; 313 313 314 - regs->int_code = S390_lowcore.pgm_int_code; 315 - regs->int_parm_long = S390_lowcore.trans_exc_code; 314 + regs->int_code = lc->pgm_int_code; 315 + regs->int_parm_long = lc->trans_exc_code; 316 316 317 317 state = irqentry_enter(regs); 318 318 ··· 326 324 current->thread.last_break = regs->last_break; 327 325 } 328 326 329 - if (S390_lowcore.pgm_code & 0x0200) { 327 + if (lc->pgm_code & 0x0200) { 330 328 /* transaction abort */ 331 - current->thread.trap_tdb = S390_lowcore.pgm_tdb; 329 + current->thread.trap_tdb = lc->pgm_tdb; 332 330 } 333 331 334 - if (S390_lowcore.pgm_code & PGM_INT_CODE_PER) { 332 + if (lc->pgm_code & PGM_INT_CODE_PER) { 335 333 if (user_mode(regs)) { 336 334 struct per_event *ev = &current->thread.per_event; 337 335 338 336 set_thread_flag(TIF_PER_TRAP); 339 - ev->address = S390_lowcore.per_address; 340 - ev->cause = S390_lowcore.per_code_combined; 341 - ev->paid = S390_lowcore.per_access_id; 337 + ev->address = lc->per_address; 338 + ev->cause = lc->per_code_combined; 339 + ev->paid = lc->per_access_id; 342 340 } else { 343 341 /* PER event in kernel is kprobes */ 344 342 __arch_local_irq_ssm(regs->psw.mask & ~PSW_MASK_PER);
+139 -68
arch/s390/kernel/uv.c
··· 110 110 * 111 111 * @paddr: Absolute host address of page to be destroyed 112 112 */ 113 - static int uv_destroy_page(unsigned long paddr) 113 + static int uv_destroy(unsigned long paddr) 114 114 { 115 115 struct uv_cb_cfs uvcb = { 116 116 .header.cmd = UVC_CMD_DESTR_SEC_STOR, ··· 131 131 } 132 132 133 133 /* 134 - * The caller must already hold a reference to the page 134 + * The caller must already hold a reference to the folio 135 135 */ 136 - int uv_destroy_owned_page(unsigned long paddr) 136 + int uv_destroy_folio(struct folio *folio) 137 137 { 138 - struct page *page = phys_to_page(paddr); 139 138 int rc; 140 139 141 - get_page(page); 142 - rc = uv_destroy_page(paddr); 140 + /* See gmap_make_secure(): large folios cannot be secure */ 141 + if (unlikely(folio_test_large(folio))) 142 + return 0; 143 + 144 + folio_get(folio); 145 + rc = uv_destroy(folio_to_phys(folio)); 143 146 if (!rc) 144 - clear_bit(PG_arch_1, &page->flags); 145 - put_page(page); 147 + clear_bit(PG_arch_1, &folio->flags); 148 + folio_put(folio); 146 149 return rc; 150 + } 151 + 152 + /* 153 + * The present PTE still indirectly holds a folio reference through the mapping. 154 + */ 155 + int uv_destroy_pte(pte_t pte) 156 + { 157 + VM_WARN_ON(!pte_present(pte)); 158 + return uv_destroy_folio(pfn_folio(pte_pfn(pte))); 147 159 } 148 160 149 161 /* ··· 164 152 * 165 153 * @paddr: Absolute host address of page to be exported 166 154 */ 167 - int uv_convert_from_secure(unsigned long paddr) 155 + static int uv_convert_from_secure(unsigned long paddr) 168 156 { 169 157 struct uv_cb_cfs uvcb = { 170 158 .header.cmd = UVC_CMD_CONV_FROM_SEC_STOR, ··· 178 166 } 179 167 180 168 /* 181 - * The caller must already hold a reference to the page 169 + * The caller must already hold a reference to the folio. 182 170 */ 183 - int uv_convert_owned_from_secure(unsigned long paddr) 171 + static int uv_convert_from_secure_folio(struct folio *folio) 184 172 { 185 - struct page *page = phys_to_page(paddr); 186 173 int rc; 187 174 188 - get_page(page); 189 - rc = uv_convert_from_secure(paddr); 175 + /* See gmap_make_secure(): large folios cannot be secure */ 176 + if (unlikely(folio_test_large(folio))) 177 + return 0; 178 + 179 + folio_get(folio); 180 + rc = uv_convert_from_secure(folio_to_phys(folio)); 190 181 if (!rc) 191 - clear_bit(PG_arch_1, &page->flags); 192 - put_page(page); 182 + clear_bit(PG_arch_1, &folio->flags); 183 + folio_put(folio); 193 184 return rc; 185 + } 186 + 187 + /* 188 + * The present PTE still indirectly holds a folio reference through the mapping. 189 + */ 190 + int uv_convert_from_secure_pte(pte_t pte) 191 + { 192 + VM_WARN_ON(!pte_present(pte)); 193 + return uv_convert_from_secure_folio(pfn_folio(pte_pfn(pte))); 194 194 } 195 195 196 196 /* ··· 291 267 } 292 268 293 269 /* 270 + * Drain LRU caches: the local one on first invocation and the ones of all 271 + * CPUs on successive invocations. Returns "true" on the first invocation. 272 + */ 273 + static bool drain_lru(bool *drain_lru_called) 274 + { 275 + /* 276 + * If we have tried a local drain and the folio refcount 277 + * still does not match our expected safe value, try with a 278 + * system wide drain. This is needed if the pagevecs holding 279 + * the page are on a different CPU. 280 + */ 281 + if (*drain_lru_called) { 282 + lru_add_drain_all(); 283 + /* We give up here, don't retry immediately. */ 284 + return false; 285 + } 286 + /* 287 + * We are here if the folio refcount does not match the 288 + * expected safe value. The main culprits are usually 289 + * pagevecs. With lru_add_drain() we drain the pagevecs 290 + * on the local CPU so that hopefully the refcount will 291 + * reach the expected safe value. 292 + */ 293 + lru_add_drain(); 294 + *drain_lru_called = true; 295 + /* The caller should try again immediately */ 296 + return true; 297 + } 298 + 299 + /* 294 300 * Requests the Ultravisor to make a page accessible to a guest. 295 301 * If it's brought in the first time, it will be cleared. If 296 302 * it has been exported before, it will be decrypted and integrity ··· 329 275 int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb) 330 276 { 331 277 struct vm_area_struct *vma; 332 - bool local_drain = false; 278 + bool drain_lru_called = false; 333 279 spinlock_t *ptelock; 334 280 unsigned long uaddr; 335 281 struct folio *folio; ··· 362 308 goto out; 363 309 if (pte_present(*ptep) && !(pte_val(*ptep) & _PAGE_INVALID) && pte_write(*ptep)) { 364 310 folio = page_folio(pte_page(*ptep)); 365 - rc = -EINVAL; 366 - if (folio_test_large(folio)) 367 - goto unlock; 368 311 rc = -EAGAIN; 369 - if (folio_trylock(folio)) { 312 + if (folio_test_large(folio)) { 313 + rc = -E2BIG; 314 + } else if (folio_trylock(folio)) { 370 315 if (should_export_before_import(uvcb, gmap->mm)) 371 316 uv_convert_from_secure(PFN_PHYS(folio_pfn(folio))); 372 317 rc = make_folio_secure(folio, uvcb); 373 318 folio_unlock(folio); 374 319 } 320 + 321 + /* 322 + * Once we drop the PTL, the folio may get unmapped and 323 + * freed immediately. We need a temporary reference. 324 + */ 325 + if (rc == -EAGAIN || rc == -E2BIG) 326 + folio_get(folio); 375 327 } 376 - unlock: 377 328 pte_unmap_unlock(ptep, ptelock); 378 329 out: 379 330 mmap_read_unlock(gmap->mm); 380 331 381 - if (rc == -EAGAIN) { 332 + switch (rc) { 333 + case -E2BIG: 334 + folio_lock(folio); 335 + rc = split_folio(folio); 336 + folio_unlock(folio); 337 + folio_put(folio); 338 + 339 + switch (rc) { 340 + case 0: 341 + /* Splitting succeeded, try again immediately. */ 342 + goto again; 343 + case -EAGAIN: 344 + /* Additional folio references. */ 345 + if (drain_lru(&drain_lru_called)) 346 + goto again; 347 + return -EAGAIN; 348 + case -EBUSY: 349 + /* Unexpected race. */ 350 + return -EAGAIN; 351 + } 352 + WARN_ON_ONCE(1); 353 + return -ENXIO; 354 + case -EAGAIN: 382 355 /* 383 356 * If we are here because the UVC returned busy or partial 384 357 * completion, this is just a useless check, but it is safe. 385 358 */ 386 359 folio_wait_writeback(folio); 387 - } else if (rc == -EBUSY) { 388 - /* 389 - * If we have tried a local drain and the folio refcount 390 - * still does not match our expected safe value, try with a 391 - * system wide drain. This is needed if the pagevecs holding 392 - * the page are on a different CPU. 393 - */ 394 - if (local_drain) { 395 - lru_add_drain_all(); 396 - /* We give up here, and let the caller try again */ 397 - return -EAGAIN; 398 - } 399 - /* 400 - * We are here if the folio refcount does not match the 401 - * expected safe value. The main culprits are usually 402 - * pagevecs. With lru_add_drain() we drain the pagevecs 403 - * on the local CPU so that hopefully the refcount will 404 - * reach the expected safe value. 405 - */ 406 - lru_add_drain(); 407 - local_drain = true; 408 - /* And now we try again immediately after draining */ 409 - goto again; 410 - } else if (rc == -ENXIO) { 360 + folio_put(folio); 361 + return -EAGAIN; 362 + case -EBUSY: 363 + /* Additional folio references. */ 364 + if (drain_lru(&drain_lru_called)) 365 + goto again; 366 + return -EAGAIN; 367 + case -ENXIO: 411 368 if (gmap_fault(gmap, gaddr, FAULT_FLAG_WRITE)) 412 369 return -EFAULT; 413 370 return -EAGAIN; ··· 453 388 { 454 389 struct vm_area_struct *vma; 455 390 unsigned long uaddr; 391 + struct folio *folio; 456 392 struct page *page; 457 393 int rc; 458 394 ··· 477 411 page = follow_page(vma, uaddr, FOLL_WRITE | FOLL_GET); 478 412 if (IS_ERR_OR_NULL(page)) 479 413 goto out; 480 - rc = uv_destroy_owned_page(page_to_phys(page)); 414 + folio = page_folio(page); 415 + rc = uv_destroy_folio(folio); 481 416 /* 482 417 * Fault handlers can race; it is possible that two CPUs will fault 483 418 * on the same secure page. One CPU can destroy the page, reboot, ··· 489 422 * we instead try to export the page. 490 423 */ 491 424 if (rc) 492 - rc = uv_convert_owned_from_secure(page_to_phys(page)); 493 - put_page(page); 425 + rc = uv_convert_from_secure_folio(folio); 426 + folio_put(folio); 494 427 out: 495 428 mmap_read_unlock(gmap->mm); 496 429 return rc; ··· 498 431 EXPORT_SYMBOL_GPL(gmap_destroy_page); 499 432 500 433 /* 501 - * To be called with the page locked or with an extra reference! This will 502 - * prevent gmap_make_secure from touching the page concurrently. Having 2 503 - * parallel make_page_accessible is fine, as the UV calls will become a 504 - * no-op if the page is already exported. 434 + * To be called with the folio locked or with an extra reference! This will 435 + * prevent gmap_make_secure from touching the folio concurrently. Having 2 436 + * parallel arch_make_folio_accessible is fine, as the UV calls will become a 437 + * no-op if the folio is already exported. 505 438 */ 506 - int arch_make_page_accessible(struct page *page) 439 + int arch_make_folio_accessible(struct folio *folio) 507 440 { 508 441 int rc = 0; 509 442 510 - /* Hugepage cannot be protected, so nothing to do */ 511 - if (PageHuge(page)) 443 + /* See gmap_make_secure(): large folios cannot be secure */ 444 + if (unlikely(folio_test_large(folio))) 512 445 return 0; 513 446 514 447 /* 515 - * PG_arch_1 is used in 3 places: 516 - * 1. for kernel page tables during early boot 517 - * 2. for storage keys of huge pages and KVM 518 - * 3. As an indication that this page might be secure. This can 448 + * PG_arch_1 is used in 2 places: 449 + * 1. for storage keys of hugetlb folios and KVM 450 + * 2. As an indication that this small folio might be secure. This can 519 451 * overindicate, e.g. we set the bit before calling 520 452 * convert_to_secure. 521 - * As secure pages are never huge, all 3 variants can co-exists. 453 + * As secure pages are never large folios, both variants can co-exists. 522 454 */ 523 - if (!test_bit(PG_arch_1, &page->flags)) 455 + if (!test_bit(PG_arch_1, &folio->flags)) 524 456 return 0; 525 457 526 - rc = uv_pin_shared(page_to_phys(page)); 458 + rc = uv_pin_shared(folio_to_phys(folio)); 527 459 if (!rc) { 528 - clear_bit(PG_arch_1, &page->flags); 460 + clear_bit(PG_arch_1, &folio->flags); 529 461 return 0; 530 462 } 531 463 532 - rc = uv_convert_from_secure(page_to_phys(page)); 464 + rc = uv_convert_from_secure(folio_to_phys(folio)); 533 465 if (!rc) { 534 - clear_bit(PG_arch_1, &page->flags); 466 + clear_bit(PG_arch_1, &folio->flags); 535 467 return 0; 536 468 } 537 469 538 470 return rc; 539 471 } 540 - EXPORT_SYMBOL_GPL(arch_make_page_accessible); 472 + EXPORT_SYMBOL_GPL(arch_make_folio_accessible); 541 473 474 + int arch_make_page_accessible(struct page *page) 475 + { 476 + return arch_make_folio_accessible(page_folio(page)); 477 + } 478 + EXPORT_SYMBOL_GPL(arch_make_page_accessible); 542 479 #endif 543 480 544 481 #if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM)
+44 -38
arch/s390/kernel/vtime.c
··· 35 35 36 36 static inline void set_vtimer(u64 expires) 37 37 { 38 + struct lowcore *lc = get_lowcore(); 38 39 u64 timer; 39 40 40 41 asm volatile( 41 42 " stpt %0\n" /* Store current cpu timer value */ 42 43 " spt %1" /* Set new value imm. afterwards */ 43 44 : "=Q" (timer) : "Q" (expires)); 44 - S390_lowcore.system_timer += S390_lowcore.last_update_timer - timer; 45 - S390_lowcore.last_update_timer = expires; 45 + lc->system_timer += lc->last_update_timer - timer; 46 + lc->last_update_timer = expires; 46 47 } 47 48 48 49 static inline int virt_timer_forward(u64 elapsed) ··· 118 117 static int do_account_vtime(struct task_struct *tsk) 119 118 { 120 119 u64 timer, clock, user, guest, system, hardirq, softirq; 120 + struct lowcore *lc = get_lowcore(); 121 121 122 - timer = S390_lowcore.last_update_timer; 123 - clock = S390_lowcore.last_update_clock; 122 + timer = lc->last_update_timer; 123 + clock = lc->last_update_clock; 124 124 asm volatile( 125 125 " stpt %0\n" /* Store current cpu timer value */ 126 126 " stckf %1" /* Store current tod clock value */ 127 - : "=Q" (S390_lowcore.last_update_timer), 128 - "=Q" (S390_lowcore.last_update_clock) 127 + : "=Q" (lc->last_update_timer), 128 + "=Q" (lc->last_update_clock) 129 129 : : "cc"); 130 - clock = S390_lowcore.last_update_clock - clock; 131 - timer -= S390_lowcore.last_update_timer; 130 + clock = lc->last_update_clock - clock; 131 + timer -= lc->last_update_timer; 132 132 133 133 if (hardirq_count()) 134 - S390_lowcore.hardirq_timer += timer; 134 + lc->hardirq_timer += timer; 135 135 else 136 - S390_lowcore.system_timer += timer; 136 + lc->system_timer += timer; 137 137 138 138 /* Update MT utilization calculation */ 139 139 if (smp_cpu_mtid && ··· 143 141 144 142 /* Calculate cputime delta */ 145 143 user = update_tsk_timer(&tsk->thread.user_timer, 146 - READ_ONCE(S390_lowcore.user_timer)); 144 + READ_ONCE(lc->user_timer)); 147 145 guest = update_tsk_timer(&tsk->thread.guest_timer, 148 - READ_ONCE(S390_lowcore.guest_timer)); 146 + READ_ONCE(lc->guest_timer)); 149 147 system = update_tsk_timer(&tsk->thread.system_timer, 150 - READ_ONCE(S390_lowcore.system_timer)); 148 + READ_ONCE(lc->system_timer)); 151 149 hardirq = update_tsk_timer(&tsk->thread.hardirq_timer, 152 - READ_ONCE(S390_lowcore.hardirq_timer)); 150 + READ_ONCE(lc->hardirq_timer)); 153 151 softirq = update_tsk_timer(&tsk->thread.softirq_timer, 154 - READ_ONCE(S390_lowcore.softirq_timer)); 155 - S390_lowcore.steal_timer += 152 + READ_ONCE(lc->softirq_timer)); 153 + lc->steal_timer += 156 154 clock - user - guest - system - hardirq - softirq; 157 155 158 156 /* Push account value */ ··· 178 176 179 177 void vtime_task_switch(struct task_struct *prev) 180 178 { 179 + struct lowcore *lc = get_lowcore(); 180 + 181 181 do_account_vtime(prev); 182 - prev->thread.user_timer = S390_lowcore.user_timer; 183 - prev->thread.guest_timer = S390_lowcore.guest_timer; 184 - prev->thread.system_timer = S390_lowcore.system_timer; 185 - prev->thread.hardirq_timer = S390_lowcore.hardirq_timer; 186 - prev->thread.softirq_timer = S390_lowcore.softirq_timer; 187 - S390_lowcore.user_timer = current->thread.user_timer; 188 - S390_lowcore.guest_timer = current->thread.guest_timer; 189 - S390_lowcore.system_timer = current->thread.system_timer; 190 - S390_lowcore.hardirq_timer = current->thread.hardirq_timer; 191 - S390_lowcore.softirq_timer = current->thread.softirq_timer; 182 + prev->thread.user_timer = lc->user_timer; 183 + prev->thread.guest_timer = lc->guest_timer; 184 + prev->thread.system_timer = lc->system_timer; 185 + prev->thread.hardirq_timer = lc->hardirq_timer; 186 + prev->thread.softirq_timer = lc->softirq_timer; 187 + lc->user_timer = current->thread.user_timer; 188 + lc->guest_timer = current->thread.guest_timer; 189 + lc->system_timer = current->thread.system_timer; 190 + lc->hardirq_timer = current->thread.hardirq_timer; 191 + lc->softirq_timer = current->thread.softirq_timer; 192 192 } 193 193 194 194 /* ··· 200 196 */ 201 197 void vtime_flush(struct task_struct *tsk) 202 198 { 199 + struct lowcore *lc = get_lowcore(); 203 200 u64 steal, avg_steal; 204 201 205 202 if (do_account_vtime(tsk)) 206 203 virt_timer_expire(); 207 204 208 - steal = S390_lowcore.steal_timer; 209 - avg_steal = S390_lowcore.avg_steal_timer; 205 + steal = lc->steal_timer; 206 + avg_steal = lc->avg_steal_timer; 210 207 if ((s64) steal > 0) { 211 - S390_lowcore.steal_timer = 0; 208 + lc->steal_timer = 0; 212 209 account_steal_time(cputime_to_nsecs(steal)); 213 210 avg_steal += steal; 214 211 } 215 - S390_lowcore.avg_steal_timer = avg_steal / 2; 212 + lc->avg_steal_timer = avg_steal / 2; 216 213 } 217 214 218 215 static u64 vtime_delta(void) 219 216 { 220 - u64 timer = S390_lowcore.last_update_timer; 217 + struct lowcore *lc = get_lowcore(); 218 + u64 timer = lc->last_update_timer; 221 219 222 - S390_lowcore.last_update_timer = get_cpu_timer(); 223 - 224 - return timer - S390_lowcore.last_update_timer; 220 + lc->last_update_timer = get_cpu_timer(); 221 + return timer - lc->last_update_timer; 225 222 } 226 223 227 224 /* ··· 231 226 */ 232 227 void vtime_account_kernel(struct task_struct *tsk) 233 228 { 229 + struct lowcore *lc = get_lowcore(); 234 230 u64 delta = vtime_delta(); 235 231 236 232 if (tsk->flags & PF_VCPU) 237 - S390_lowcore.guest_timer += delta; 233 + lc->guest_timer += delta; 238 234 else 239 - S390_lowcore.system_timer += delta; 235 + lc->system_timer += delta; 240 236 241 237 virt_timer_forward(delta); 242 238 } ··· 247 241 { 248 242 u64 delta = vtime_delta(); 249 243 250 - S390_lowcore.softirq_timer += delta; 244 + get_lowcore()->softirq_timer += delta; 251 245 252 246 virt_timer_forward(delta); 253 247 } ··· 256 250 { 257 251 u64 delta = vtime_delta(); 258 252 259 - S390_lowcore.hardirq_timer += delta; 253 + get_lowcore()->hardirq_timer += delta; 260 254 261 255 virt_timer_forward(delta); 262 256 }
+3 -160
arch/s390/kvm/gaccess.c
··· 14 14 #include <asm/access-regs.h> 15 15 #include <asm/fault.h> 16 16 #include <asm/gmap.h> 17 + #include <asm/dat-bits.h> 17 18 #include "kvm-s390.h" 18 19 #include "gaccess.h" 19 - 20 - union asce { 21 - unsigned long val; 22 - struct { 23 - unsigned long origin : 52; /* Region- or Segment-Table Origin */ 24 - unsigned long : 2; 25 - unsigned long g : 1; /* Subspace Group Control */ 26 - unsigned long p : 1; /* Private Space Control */ 27 - unsigned long s : 1; /* Storage-Alteration-Event Control */ 28 - unsigned long x : 1; /* Space-Switch-Event Control */ 29 - unsigned long r : 1; /* Real-Space Control */ 30 - unsigned long : 1; 31 - unsigned long dt : 2; /* Designation-Type Control */ 32 - unsigned long tl : 2; /* Region- or Segment-Table Length */ 33 - }; 34 - }; 35 - 36 - enum { 37 - ASCE_TYPE_SEGMENT = 0, 38 - ASCE_TYPE_REGION3 = 1, 39 - ASCE_TYPE_REGION2 = 2, 40 - ASCE_TYPE_REGION1 = 3 41 - }; 42 - 43 - union region1_table_entry { 44 - unsigned long val; 45 - struct { 46 - unsigned long rto: 52;/* Region-Table Origin */ 47 - unsigned long : 2; 48 - unsigned long p : 1; /* DAT-Protection Bit */ 49 - unsigned long : 1; 50 - unsigned long tf : 2; /* Region-Second-Table Offset */ 51 - unsigned long i : 1; /* Region-Invalid Bit */ 52 - unsigned long : 1; 53 - unsigned long tt : 2; /* Table-Type Bits */ 54 - unsigned long tl : 2; /* Region-Second-Table Length */ 55 - }; 56 - }; 57 - 58 - union region2_table_entry { 59 - unsigned long val; 60 - struct { 61 - unsigned long rto: 52;/* Region-Table Origin */ 62 - unsigned long : 2; 63 - unsigned long p : 1; /* DAT-Protection Bit */ 64 - unsigned long : 1; 65 - unsigned long tf : 2; /* Region-Third-Table Offset */ 66 - unsigned long i : 1; /* Region-Invalid Bit */ 67 - unsigned long : 1; 68 - unsigned long tt : 2; /* Table-Type Bits */ 69 - unsigned long tl : 2; /* Region-Third-Table Length */ 70 - }; 71 - }; 72 - 73 - struct region3_table_entry_fc0 { 74 - unsigned long sto: 52;/* Segment-Table Origin */ 75 - unsigned long : 1; 76 - unsigned long fc : 1; /* Format-Control */ 77 - unsigned long p : 1; /* DAT-Protection Bit */ 78 - unsigned long : 1; 79 - unsigned long tf : 2; /* Segment-Table Offset */ 80 - unsigned long i : 1; /* Region-Invalid Bit */ 81 - unsigned long cr : 1; /* Common-Region Bit */ 82 - unsigned long tt : 2; /* Table-Type Bits */ 83 - unsigned long tl : 2; /* Segment-Table Length */ 84 - }; 85 - 86 - struct region3_table_entry_fc1 { 87 - unsigned long rfaa : 33; /* Region-Frame Absolute Address */ 88 - unsigned long : 14; 89 - unsigned long av : 1; /* ACCF-Validity Control */ 90 - unsigned long acc: 4; /* Access-Control Bits */ 91 - unsigned long f : 1; /* Fetch-Protection Bit */ 92 - unsigned long fc : 1; /* Format-Control */ 93 - unsigned long p : 1; /* DAT-Protection Bit */ 94 - unsigned long iep: 1; /* Instruction-Execution-Protection */ 95 - unsigned long : 2; 96 - unsigned long i : 1; /* Region-Invalid Bit */ 97 - unsigned long cr : 1; /* Common-Region Bit */ 98 - unsigned long tt : 2; /* Table-Type Bits */ 99 - unsigned long : 2; 100 - }; 101 - 102 - union region3_table_entry { 103 - unsigned long val; 104 - struct region3_table_entry_fc0 fc0; 105 - struct region3_table_entry_fc1 fc1; 106 - struct { 107 - unsigned long : 53; 108 - unsigned long fc : 1; /* Format-Control */ 109 - unsigned long : 4; 110 - unsigned long i : 1; /* Region-Invalid Bit */ 111 - unsigned long cr : 1; /* Common-Region Bit */ 112 - unsigned long tt : 2; /* Table-Type Bits */ 113 - unsigned long : 2; 114 - }; 115 - }; 116 - 117 - struct segment_entry_fc0 { 118 - unsigned long pto: 53;/* Page-Table Origin */ 119 - unsigned long fc : 1; /* Format-Control */ 120 - unsigned long p : 1; /* DAT-Protection Bit */ 121 - unsigned long : 3; 122 - unsigned long i : 1; /* Segment-Invalid Bit */ 123 - unsigned long cs : 1; /* Common-Segment Bit */ 124 - unsigned long tt : 2; /* Table-Type Bits */ 125 - unsigned long : 2; 126 - }; 127 - 128 - struct segment_entry_fc1 { 129 - unsigned long sfaa : 44; /* Segment-Frame Absolute Address */ 130 - unsigned long : 3; 131 - unsigned long av : 1; /* ACCF-Validity Control */ 132 - unsigned long acc: 4; /* Access-Control Bits */ 133 - unsigned long f : 1; /* Fetch-Protection Bit */ 134 - unsigned long fc : 1; /* Format-Control */ 135 - unsigned long p : 1; /* DAT-Protection Bit */ 136 - unsigned long iep: 1; /* Instruction-Execution-Protection */ 137 - unsigned long : 2; 138 - unsigned long i : 1; /* Segment-Invalid Bit */ 139 - unsigned long cs : 1; /* Common-Segment Bit */ 140 - unsigned long tt : 2; /* Table-Type Bits */ 141 - unsigned long : 2; 142 - }; 143 - 144 - union segment_table_entry { 145 - unsigned long val; 146 - struct segment_entry_fc0 fc0; 147 - struct segment_entry_fc1 fc1; 148 - struct { 149 - unsigned long : 53; 150 - unsigned long fc : 1; /* Format-Control */ 151 - unsigned long : 4; 152 - unsigned long i : 1; /* Segment-Invalid Bit */ 153 - unsigned long cs : 1; /* Common-Segment Bit */ 154 - unsigned long tt : 2; /* Table-Type Bits */ 155 - unsigned long : 2; 156 - }; 157 - }; 158 - 159 - enum { 160 - TABLE_TYPE_SEGMENT = 0, 161 - TABLE_TYPE_REGION3 = 1, 162 - TABLE_TYPE_REGION2 = 2, 163 - TABLE_TYPE_REGION1 = 3 164 - }; 165 - 166 - union page_table_entry { 167 - unsigned long val; 168 - struct { 169 - unsigned long pfra : 52; /* Page-Frame Real Address */ 170 - unsigned long z : 1; /* Zero Bit */ 171 - unsigned long i : 1; /* Page-Invalid Bit */ 172 - unsigned long p : 1; /* DAT-Protection Bit */ 173 - unsigned long iep: 1; /* Instruction-Execution-Protection */ 174 - unsigned long : 8; 175 - }; 176 - }; 177 20 178 21 /* 179 22 * vaddress union in order to easily decode a virtual address into its ··· 475 632 iep = ctlreg0.iep && test_kvm_facility(vcpu->kvm, 130); 476 633 if (asce.r) 477 634 goto real_address; 478 - ptr = asce.origin * PAGE_SIZE; 635 + ptr = asce.rsto * PAGE_SIZE; 479 636 switch (asce.dt) { 480 637 case ASCE_TYPE_REGION1: 481 638 if (vaddr.rfx01 > asce.tl) ··· 1222 1379 parent = sg->parent; 1223 1380 vaddr.addr = saddr; 1224 1381 asce.val = sg->orig_asce; 1225 - ptr = asce.origin * PAGE_SIZE; 1382 + ptr = asce.rsto * PAGE_SIZE; 1226 1383 if (asce.r) { 1227 1384 *fake = 1; 1228 1385 ptr = 0;
+3 -2
arch/s390/kvm/kvm-s390.c
··· 4080 4080 bool kvm_arch_no_poll(struct kvm_vcpu *vcpu) 4081 4081 { 4082 4082 /* do not poll with more than halt_poll_max_steal percent of steal time */ 4083 - if (S390_lowcore.avg_steal_timer * 100 / (TICK_USEC << 12) >= 4083 + if (get_lowcore()->avg_steal_timer * 100 / (TICK_USEC << 12) >= 4084 4084 READ_ONCE(halt_poll_max_steal)) { 4085 4085 vcpu->stat.halt_no_poll_steal++; 4086 4086 return true; ··· 4830 4830 sizeof(sie_page->pv_grregs)); 4831 4831 } 4832 4832 exit_reason = sie64a(vcpu->arch.sie_block, 4833 - vcpu->run->s.regs.gprs); 4833 + vcpu->run->s.regs.gprs, 4834 + gmap_get_enabled()->asce); 4834 4835 if (kvm_s390_pv_cpu_is_protected(vcpu)) { 4835 4836 memcpy(vcpu->run->s.regs.gprs, 4836 4837 sie_page->pv_grregs,
+1 -1
arch/s390/kvm/vsie.c
··· 1150 1150 vcpu->arch.sie_block->prog0c |= PROG_IN_SIE; 1151 1151 barrier(); 1152 1152 if (!kvm_s390_vcpu_sie_inhibited(vcpu)) 1153 - rc = sie64a(scb_s, vcpu->run->s.regs.gprs); 1153 + rc = sie64a(scb_s, vcpu->run->s.regs.gprs, gmap_get_enabled()->asce); 1154 1154 barrier(); 1155 1155 vcpu->arch.sie_block->prog0c &= ~PROG_IN_SIE; 1156 1156
+2 -2
arch/s390/lib/spinlock.c
··· 119 119 struct spin_wait *node, *next; 120 120 int lockval, ix, node_id, tail_id, old, new, owner, count; 121 121 122 - ix = S390_lowcore.spinlock_index++; 122 + ix = get_lowcore()->spinlock_index++; 123 123 barrier(); 124 124 lockval = SPINLOCK_LOCKVAL; /* cpu + 1 */ 125 125 node = this_cpu_ptr(&spin_wait[ix]); ··· 205 205 } 206 206 207 207 out: 208 - S390_lowcore.spinlock_index--; 208 + get_lowcore()->spinlock_index--; 209 209 } 210 210 211 211 static inline void arch_spin_lock_classic(arch_spinlock_t *lp)
+1
arch/s390/lib/test_kprobes.c
··· 72 72 73 73 kunit_test_suites(&kprobes_test_suite); 74 74 75 + MODULE_DESCRIPTION("KUnit tests for kprobes"); 75 76 MODULE_LICENSE("GPL");
+1
arch/s390/lib/test_modules.c
··· 29 29 30 30 kunit_test_suites(&modules_test_suite); 31 31 32 + MODULE_DESCRIPTION("KUnit test that modules with many relocations are loaded properly"); 32 33 MODULE_LICENSE("GPL");
+2 -1
arch/s390/lib/test_unwind.c
··· 356 356 if (u->flags & UWM_SWITCH_STACK) { 357 357 local_irq_save(flags); 358 358 local_mcck_save(mflags); 359 - rc = call_on_stack(1, S390_lowcore.nodat_stack, 359 + rc = call_on_stack(1, get_lowcore()->nodat_stack, 360 360 int, unwindme_func3, struct unwindme *, u); 361 361 local_mcck_restore(mflags); 362 362 local_irq_restore(flags); ··· 519 519 520 520 kunit_test_suites(&test_unwind_suite); 521 521 522 + MODULE_DESCRIPTION("KUnit test for unwind_for_each_frame"); 522 523 MODULE_LICENSE("GPL");
+2 -2
arch/s390/lib/uaccess.c
··· 21 21 22 22 local_ctl_store(1, &cr1); 23 23 local_ctl_store(7, &cr7); 24 - if (cr1.val == S390_lowcore.kernel_asce.val && cr7.val == S390_lowcore.user_asce.val) 24 + if (cr1.val == get_lowcore()->kernel_asce.val && cr7.val == get_lowcore()->user_asce.val) 25 25 return; 26 26 panic("incorrect ASCE on kernel %s\n" 27 27 "cr1: %016lx cr7: %016lx\n" 28 28 "kernel: %016lx user: %016lx\n", 29 29 exit ? "exit" : "entry", cr1.val, cr7.val, 30 - S390_lowcore.kernel_asce.val, S390_lowcore.user_asce.val); 30 + get_lowcore()->kernel_asce.val, get_lowcore()->user_asce.val); 31 31 } 32 32 #endif /*CONFIG_DEBUG_ENTRY */ 33 33
+1
arch/s390/mm/cmm.c
··· 427 427 } 428 428 module_exit(cmm_exit); 429 429 430 + MODULE_DESCRIPTION("Cooperative memory management interface"); 430 431 MODULE_LICENSE("GPL");
+1 -1
arch/s390/mm/dump_pagetables.c
··· 288 288 * kernel ASCE. We need this to keep the page table walker functions 289 289 * from accessing non-existent entries. 290 290 */ 291 - max_addr = (S390_lowcore.kernel_asce.val & _REGION_ENTRY_TYPE_MASK) >> 2; 291 + max_addr = (get_lowcore()->kernel_asce.val & _REGION_ENTRY_TYPE_MASK) >> 2; 292 292 max_addr = 1UL << (max_addr * 11 + 31); 293 293 address_markers[IDENTITY_AFTER_END_NR].start_address = ident_map_size; 294 294 address_markers[AMODE31_START_NR].start_address = (unsigned long)__samode31;
+18 -15
arch/s390/mm/fault.c
··· 74 74 return USER_FAULT; 75 75 if (!IS_ENABLED(CONFIG_PGSTE)) 76 76 return KERNEL_FAULT; 77 - gmap = (struct gmap *)S390_lowcore.gmap; 77 + gmap = (struct gmap *)get_lowcore()->gmap; 78 78 if (gmap && gmap->asce == regs->cr1) 79 79 return GMAP_FAULT; 80 80 return KERNEL_FAULT; ··· 182 182 pr_cont("mode while using "); 183 183 switch (get_fault_type(regs)) { 184 184 case USER_FAULT: 185 - asce = S390_lowcore.user_asce.val; 185 + asce = get_lowcore()->user_asce.val; 186 186 pr_cont("user "); 187 187 break; 188 188 case GMAP_FAULT: 189 - asce = ((struct gmap *)S390_lowcore.gmap)->asce; 189 + asce = ((struct gmap *)get_lowcore()->gmap)->asce; 190 190 pr_cont("gmap "); 191 191 break; 192 192 case KERNEL_FAULT: 193 - asce = S390_lowcore.kernel_asce.val; 193 + asce = get_lowcore()->kernel_asce.val; 194 194 pr_cont("kernel "); 195 195 break; 196 196 default: ··· 351 351 mmap_read_lock(mm); 352 352 gmap = NULL; 353 353 if (IS_ENABLED(CONFIG_PGSTE) && type == GMAP_FAULT) { 354 - gmap = (struct gmap *)S390_lowcore.gmap; 354 + gmap = (struct gmap *)get_lowcore()->gmap; 355 355 current->thread.gmap_addr = address; 356 356 current->thread.gmap_write_flag = !!(flags & FAULT_FLAG_WRITE); 357 357 current->thread.gmap_int_code = regs->int_code & 0xffff; ··· 433 433 handle_fault_error_nolock(regs, 0); 434 434 else 435 435 do_sigsegv(regs, SEGV_MAPERR); 436 - } else if (fault & VM_FAULT_SIGBUS) { 436 + } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON)) { 437 437 if (!user_mode(regs)) 438 438 handle_fault_error_nolock(regs, 0); 439 439 else 440 440 do_sigbus(regs); 441 441 } else { 442 + pr_emerg("Unexpected fault flags: %08x\n", fault); 442 443 BUG(); 443 444 } 444 445 } ··· 493 492 unsigned long addr = get_fault_address(regs); 494 493 struct vm_area_struct *vma; 495 494 struct mm_struct *mm; 495 + struct folio *folio; 496 496 struct page *page; 497 497 struct gmap *gmap; 498 498 int rc; ··· 523 521 switch (get_fault_type(regs)) { 524 522 case GMAP_FAULT: 525 523 mm = current->mm; 526 - gmap = (struct gmap *)S390_lowcore.gmap; 524 + gmap = (struct gmap *)get_lowcore()->gmap; 527 525 mmap_read_lock(mm); 528 526 addr = __gmap_translate(gmap, addr); 529 527 mmap_read_unlock(mm); ··· 541 539 mmap_read_unlock(mm); 542 540 break; 543 541 } 544 - if (arch_make_page_accessible(page)) 542 + folio = page_folio(page); 543 + if (arch_make_folio_accessible(folio)) 545 544 send_sig(SIGSEGV, current, 0); 546 - put_page(page); 545 + folio_put(folio); 547 546 mmap_read_unlock(mm); 548 547 break; 549 548 case KERNEL_FAULT: 550 - page = phys_to_page(addr); 551 - if (unlikely(!try_get_page(page))) 549 + folio = phys_to_folio(addr); 550 + if (unlikely(!folio_try_get(folio))) 552 551 break; 553 - rc = arch_make_page_accessible(page); 554 - put_page(page); 552 + rc = arch_make_folio_accessible(folio); 553 + folio_put(folio); 555 554 if (rc) 556 555 BUG(); 557 556 break; ··· 564 561 565 562 void do_non_secure_storage_access(struct pt_regs *regs) 566 563 { 567 - struct gmap *gmap = (struct gmap *)S390_lowcore.gmap; 564 + struct gmap *gmap = (struct gmap *)get_lowcore()->gmap; 568 565 unsigned long gaddr = get_fault_address(regs); 569 566 570 567 if (WARN_ON_ONCE(get_fault_type(regs) != GMAP_FAULT)) ··· 576 573 577 574 void do_secure_storage_violation(struct pt_regs *regs) 578 575 { 579 - struct gmap *gmap = (struct gmap *)S390_lowcore.gmap; 576 + struct gmap *gmap = (struct gmap *)get_lowcore()->gmap; 580 577 unsigned long gaddr = get_fault_address(regs); 581 578 582 579 /*
+9 -7
arch/s390/mm/gmap.c
··· 287 287 */ 288 288 void gmap_enable(struct gmap *gmap) 289 289 { 290 - S390_lowcore.gmap = (unsigned long) gmap; 290 + get_lowcore()->gmap = (unsigned long)gmap; 291 291 } 292 292 EXPORT_SYMBOL_GPL(gmap_enable); 293 293 ··· 297 297 */ 298 298 void gmap_disable(struct gmap *gmap) 299 299 { 300 - S390_lowcore.gmap = 0UL; 300 + get_lowcore()->gmap = 0UL; 301 301 } 302 302 EXPORT_SYMBOL_GPL(gmap_disable); 303 303 ··· 308 308 */ 309 309 struct gmap *gmap_get_enabled(void) 310 310 { 311 - return (struct gmap *) S390_lowcore.gmap; 311 + return (struct gmap *)get_lowcore()->gmap; 312 312 } 313 313 EXPORT_SYMBOL_GPL(gmap_get_enabled); 314 314 ··· 2733 2733 { 2734 2734 pmd_t *pmd = (pmd_t *)pte; 2735 2735 unsigned long start, end; 2736 - struct page *page = pmd_page(*pmd); 2736 + struct folio *folio = page_folio(pmd_page(*pmd)); 2737 2737 2738 2738 /* 2739 2739 * The write check makes sure we do not set a key on shared ··· 2748 2748 start = pmd_val(*pmd) & HPAGE_MASK; 2749 2749 end = start + HPAGE_SIZE; 2750 2750 __storage_key_init_range(start, end); 2751 - set_bit(PG_arch_1, &page->flags); 2751 + set_bit(PG_arch_1, &folio->flags); 2752 2752 cond_resched(); 2753 2753 return 0; 2754 2754 } ··· 2841 2841 */ 2842 2842 void s390_uv_destroy_pfns(unsigned long count, unsigned long *pfns) 2843 2843 { 2844 + struct folio *folio; 2844 2845 unsigned long i; 2845 2846 2846 2847 for (i = 0; i < count; i++) { 2848 + folio = pfn_folio(pfns[i]); 2847 2849 /* we always have an extra reference */ 2848 - uv_destroy_owned_page(pfn_to_phys(pfns[i])); 2850 + uv_destroy_folio(folio); 2849 2851 /* get rid of the extra reference */ 2850 - put_page(pfn_to_page(pfns[i])); 2852 + folio_put(folio); 2851 2853 cond_resched(); 2852 2854 } 2853 2855 }
+4 -4
arch/s390/mm/hugetlbpage.c
··· 121 121 122 122 static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste) 123 123 { 124 - struct page *page; 124 + struct folio *folio; 125 125 unsigned long size, paddr; 126 126 127 127 if (!mm_uses_skeys(mm) || ··· 129 129 return; 130 130 131 131 if ((rste & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) { 132 - page = pud_page(__pud(rste)); 132 + folio = page_folio(pud_page(__pud(rste))); 133 133 size = PUD_SIZE; 134 134 paddr = rste & PUD_MASK; 135 135 } else { 136 - page = pmd_page(__pmd(rste)); 136 + folio = page_folio(pmd_page(__pmd(rste))); 137 137 size = PMD_SIZE; 138 138 paddr = rste & PMD_MASK; 139 139 } 140 140 141 - if (!test_and_set_bit(PG_arch_1, &page->flags)) 141 + if (!test_and_set_bit(PG_arch_1, &folio->flags)) 142 142 __storage_key_init_range(paddr, paddr + size); 143 143 } 144 144
+2 -1
arch/s390/mm/init.c
··· 62 62 63 63 static void __init setup_zero_pages(void) 64 64 { 65 + unsigned long total_pages = PHYS_PFN(memblock_phys_mem_size() - memblock_reserved_size()); 65 66 unsigned int order; 66 67 struct page *page; 67 68 int i; ··· 71 70 order = 7; 72 71 73 72 /* Limit number of empty zero pages for small memory sizes */ 74 - while (order > 2 && (totalram_pages() >> 10) < (1UL << order)) 73 + while (order > 2 && (total_pages >> 10) < (1UL << order)) 75 74 order--; 76 75 77 76 empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
+1 -1
arch/s390/mm/pageattr.c
··· 75 75 break; 76 76 } 77 77 table = (unsigned long *)((unsigned long)old & mask); 78 - crdte(*old, new, table, dtt, addr, S390_lowcore.kernel_asce.val); 78 + crdte(*old, new, table, dtt, addr, get_lowcore()->kernel_asce.val); 79 79 } else if (MACHINE_HAS_IDTE) { 80 80 cspg(old, *old, new); 81 81 } else {
+2 -2
arch/s390/mm/pgalloc.c
··· 66 66 67 67 /* change all active ASCEs to avoid the creation of new TLBs */ 68 68 if (current->active_mm == mm) { 69 - S390_lowcore.user_asce.val = mm->context.asce; 70 - local_ctl_load(7, &S390_lowcore.user_asce); 69 + get_lowcore()->user_asce.val = mm->context.asce; 70 + local_ctl_load(7, &get_lowcore()->user_asce); 71 71 } 72 72 __tlb_flush_local(); 73 73 }
+1 -1
arch/s390/pci/pci.c
··· 1064 1064 return NULL; 1065 1065 } 1066 1066 if (!strcmp(str, "nomio")) { 1067 - S390_lowcore.machine_flags &= ~MACHINE_FLAG_PCI_MIO; 1067 + get_lowcore()->machine_flags &= ~MACHINE_FLAG_PCI_MIO; 1068 1068 return NULL; 1069 1069 } 1070 1070 if (!strcmp(str, "force_floating")) {
+1
drivers/s390/block/dcssblk.c
··· 1032 1032 "the contiguous segments - \n" 1033 1033 "e.g. segments=\"mydcss1,mydcss2:mydcss3,mydcss4(local)\""); 1034 1034 1035 + MODULE_DESCRIPTION("S/390 block driver for DCSS memory"); 1035 1036 MODULE_LICENSE("GPL");
+1
drivers/s390/char/con3270.c
··· 2185 2185 console_initcall(con3270_init); 2186 2186 #endif 2187 2187 2188 + MODULE_DESCRIPTION("IBM/3270 Driver - tty functions"); 2188 2189 MODULE_LICENSE("GPL"); 2189 2190 MODULE_ALIAS_CHARDEV_MAJOR(IBM_TTY3270_MAJOR); 2190 2191
+1
drivers/s390/char/fs3270.c
··· 559 559 __unregister_chrdev(IBM_FS3270_MAJOR, 0, 1, "fs3270"); 560 560 } 561 561 562 + MODULE_DESCRIPTION("IBM/3270 Driver - fullscreen driver"); 562 563 MODULE_LICENSE("GPL"); 563 564 MODULE_ALIAS_CHARDEV_MAJOR(IBM_FS3270_MAJOR); 564 565
+1
drivers/s390/char/raw3270.c
··· 1341 1341 class_unregister(&class3270); 1342 1342 } 1343 1343 1344 + MODULE_DESCRIPTION("IBM/3270 Driver - core functions"); 1344 1345 MODULE_LICENSE("GPL"); 1345 1346 1346 1347 module_init(raw3270_init);
+5 -2
drivers/s390/char/sclp_cmd.c
··· 31 31 32 32 #include "sclp.h" 33 33 34 + #define SCLP_CMDW_ASSIGN_STORAGE 0x000d0001 35 + #define SCLP_CMDW_UNASSIGN_STORAGE 0x000c0001 36 + 34 37 static void sclp_sync_callback(struct sclp_req *req, void *data) 35 38 { 36 39 struct completion *completion = data; ··· 228 225 unsigned long long start; 229 226 int rc; 230 227 231 - rc = do_assign_storage(0x000d0001, rn); 228 + rc = do_assign_storage(SCLP_CMDW_ASSIGN_STORAGE, rn); 232 229 if (rc) 233 230 return rc; 234 231 start = rn2addr(rn); ··· 238 235 239 236 static int sclp_unassign_storage(u16 rn) 240 237 { 241 - return do_assign_storage(0x000c0001, rn); 238 + return do_assign_storage(SCLP_CMDW_UNASSIGN_STORAGE, rn); 242 239 } 243 240 244 241 struct attach_storage_sccb {
+1 -1
drivers/s390/char/sclp_config.c
··· 60 60 static void __ref sclp_cpu_change_notify(struct work_struct *work) 61 61 { 62 62 lock_device_hotplug(); 63 - smp_rescan_cpus(); 63 + smp_rescan_cpus(false); 64 64 unlock_device_hotplug(); 65 65 } 66 66
+3 -2
drivers/s390/char/sclp_early.c
··· 50 50 sclp.has_aisi = !!(sccb->fac118 & 0x10); 51 51 sclp.has_zpci_lsi = !!(sccb->fac118 & 0x01); 52 52 if (sccb->fac85 & 0x02) 53 - S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; 53 + get_lowcore()->machine_flags |= MACHINE_FLAG_ESOP; 54 54 if (sccb->fac91 & 0x40) 55 - S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST; 55 + get_lowcore()->machine_flags |= MACHINE_FLAG_TLB_GUEST; 56 + sclp.has_diag204_bif = !!(sccb->fac98 & 0x80); 56 57 if (sccb->cpuoff > 134) { 57 58 sclp.has_diag318 = !!(sccb->byte_134 & 0x80); 58 59 sclp.has_diag320 = !!(sccb->byte_134 & 0x04);
+6 -6
drivers/s390/char/sclp_early_core.c
··· 38 38 cr0_new.sssm = 1; 39 39 local_ctl_load(0, &cr0_new.reg); 40 40 41 - psw_ext_save = S390_lowcore.external_new_psw; 41 + psw_ext_save = get_lowcore()->external_new_psw; 42 42 psw_mask = __extract_psw(); 43 - S390_lowcore.external_new_psw.mask = psw_mask; 43 + get_lowcore()->external_new_psw.mask = psw_mask; 44 44 psw_wait.mask = psw_mask | PSW_MASK_EXT | PSW_MASK_WAIT; 45 - S390_lowcore.ext_int_code = 0; 45 + get_lowcore()->ext_int_code = 0; 46 46 47 47 do { 48 48 asm volatile( ··· 53 53 "0:\n" 54 54 : [addr] "=&d" (addr), 55 55 [psw_wait_addr] "=Q" (psw_wait.addr), 56 - [psw_ext_addr] "=Q" (S390_lowcore.external_new_psw.addr) 56 + [psw_ext_addr] "=Q" (get_lowcore()->external_new_psw.addr) 57 57 : [psw_wait] "Q" (psw_wait) 58 58 : "cc", "memory"); 59 - } while (S390_lowcore.ext_int_code != EXT_IRQ_SERVICE_SIG); 59 + } while (get_lowcore()->ext_int_code != EXT_IRQ_SERVICE_SIG); 60 60 61 - S390_lowcore.external_new_psw = psw_ext_save; 61 + get_lowcore()->external_new_psw = psw_ext_save; 62 62 local_ctl_load(0, &cr0.reg); 63 63 } 64 64
+21 -5
drivers/s390/char/sclp_sd.c
··· 9 9 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 10 11 11 #include <linux/completion.h> 12 + #include <linux/jiffies.h> 12 13 #include <linux/kobject.h> 13 14 #include <linux/list.h> 14 15 #include <linux/printk.h> ··· 28 27 #define SD_EQ_SIZE 2 29 28 30 29 #define SD_DI_CONFIG 3 30 + 31 + #define SD_TIMEOUT msecs_to_jiffies(30000) 31 32 32 33 struct sclp_sd_evbuf { 33 34 struct evbuf_header hdr; ··· 197 194 struct sclp_sd_evbuf *evbuf; 198 195 int rc; 199 196 197 + if (!sclp_sd_register.sclp_send_mask || 198 + !sclp_sd_register.sclp_receive_mask) 199 + return -EIO; 200 + 200 201 sclp_sd_listener_init(&listener, __pa(sccb)); 201 202 sclp_sd_listener_add(&listener); 202 203 ··· 237 230 goto out; 238 231 } 239 232 if (!(evbuf->rflags & 0x80)) { 240 - rc = wait_for_completion_interruptible(&listener.completion); 241 - if (rc) 233 + rc = wait_for_completion_interruptible_timeout(&listener.completion, SD_TIMEOUT); 234 + if (rc == 0) 235 + rc = -ETIME; 236 + if (rc < 0) 242 237 goto out; 238 + rc = 0; 243 239 evbuf = &listener.evbuf; 244 240 } 245 241 switch (evbuf->status) { ··· 329 319 rc = sclp_sd_sync(page, SD_EQ_STORE_DATA, di, asce, (u64) data, &dsize, 330 320 &esize); 331 321 if (rc) { 332 - /* Cancel running request if interrupted */ 333 - if (rc == -ERESTARTSYS) 334 - sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL); 322 + /* Cancel running request if interrupted or timed out */ 323 + if (rc == -ERESTARTSYS || rc == -ETIME) { 324 + if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) { 325 + pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n", 326 + (size_t)dsize * PAGE_SIZE); 327 + data = NULL; 328 + asce = 0; 329 + } 330 + } 335 331 vfree(data); 336 332 goto out; 337 333 }
+1 -1
drivers/s390/cio/qdio_main.c
··· 695 695 return; 696 696 697 697 qdio_deliver_irq(irq_ptr); 698 - irq_ptr->last_data_irq_time = S390_lowcore.int_clock; 698 + irq_ptr->last_data_irq_time = get_lowcore()->int_clock; 699 699 } 700 700 701 701 static void qdio_handle_activate_check(struct qdio_irq *irq_ptr,
+1 -1
drivers/s390/cio/qdio_thinint.c
··· 99 99 static void tiqdio_thinint_handler(struct airq_struct *airq, 100 100 struct tpi_info *tpi_info) 101 101 { 102 - u64 irq_time = S390_lowcore.int_clock; 102 + u64 irq_time = get_lowcore()->int_clock; 103 103 u32 si_used = clear_shared_ind(); 104 104 struct qdio_irq *irq; 105 105
+1 -1
drivers/s390/cio/trace.h
··· 169 169 else if (addr) 170 170 __entry->tpi_info = *addr; 171 171 else 172 - __entry->tpi_info = S390_lowcore.tpi_info; 172 + __entry->tpi_info = get_lowcore()->tpi_info; 173 173 __entry->cssid = __entry->tpi_info.schid.cssid; 174 174 __entry->ssid = __entry->tpi_info.schid.ssid; 175 175 __entry->schno = __entry->tpi_info.schid.sch_no;