Skip to content

Commit de927f6

Browse files
committed
Merge tag 's390-6.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Alexander Gordeev: - Add machine variable capacity information to /proc/sysinfo. - Limit the waste of page tables and always align vmalloc area size and base address on segment boundary. - Fix a memory leak when an attempt to register interruption sub class (ISC) for the adjunct-processor (AP) guest failed. - Reset response code AP_RESPONSE_INVALID_GISA to understandable by guest AP_RESPONSE_INVALID_ADDRESS in response to a failed interruption sub class (ISC) registration attempt. - Improve reaction to adjunct-processor (AP) AP_RESPONSE_OTHERWISE_CHANGED response code when enabling interrupts on behalf of a guest. - Fix incorrect sysfs 'status' attribute of adjunct-processor (AP) queue device bound to the vfio_ap device driver when the mediated device is attached to a guest, but the queue device is not passed through. - Rework struct ap_card to hold the whole adjunct-processor (AP) card hardware information. As result, all the ugly bit checks are replaced by simple evaluations of the required bit fields. - Improve handling of some weird scenarios between service element (SE) host and SE guest with adjunct-processor (AP) pass-through support. - Change local_ctl_set_bit() and local_ctl_clear_bit() so they return the previous value of the to be changed control register. This is useful if a bit is only changed temporarily and the previous content needs to be restored. - The kernel starts with machine checks disabled and is expected to enable it once trap_init() is called. However the implementation allows machine checks early. Consistently enable it in trap_init() only. - local_mcck_disable() and local_mcck_enable() assume that machine checks are always enabled. Instead implement and use local_mcck_save() and local_mcck_restore() to disable machine checks and restore the previous state. - Modification of floating point control (FPC) register of a traced process using ptrace interface may lead to corruption of the FPC register of the tracing process. Fix this. - kvm_arch_vcpu_ioctl_set_fpu() allows to set the floating point control (FPC) register in vCPU, but may lead to corruption of the FPC register of the host process. Fix this. - Use READ_ONCE() to read a vCPU floating point register value from the memory mapped area. This avoids that, depending on code generation, a different value is tested for validity than the one that is used. - Get rid of test_fp_ctl(), since it is quite subtle to use it correctly. Instead copy a new floating point control register value into its save area and test the validity of the new value when loading it. - Remove superfluous save_fpu_regs() call. - Remove s390 support for ARCH_WANTS_DYNAMIC_TASK_STRUCT. All machines provide the vector facility since many years and the need to make the task structure size dependent on the vector facility does not exist. - Remove the "novx" kernel command line option, as the vector code runs without any problems since many years. - Add the vector facility to the z13 architecture level set (ALS). All hypervisors support the vector facility since many years. This allows compile time optimizations of the kernel. - Get rid of MACHINE_HAS_VX and replace it with cpu_has_vx(). As result, the compiled code will have less runtime checks and less code. - Convert pgste_get_lock() and pgste_set_unlock() ASM inlines to C. - Convert the struct subchannel spinlock from pointer to member. * tag 's390-6.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (24 commits) Revert "s390: update defconfigs" s390/cio: make sch->lock spinlock pointer a member s390: update defconfigs s390/mm: convert pgste locking functions to C s390/fpu: get rid of MACHINE_HAS_VX s390/als: add vector facility to z13 architecture level set s390/fpu: remove "novx" option s390/fpu: remove ARCH_WANTS_DYNAMIC_TASK_STRUCT support KVM: s390: remove superfluous save_fpu_regs() call s390/fpu: get rid of test_fp_ctl() KVM: s390: use READ_ONCE() to read fpc register value KVM: s390: fix setting of fpc register s390/ptrace: handle setting of fpc register correctly s390/nmi: implement and use local_mcck_save() / local_mcck_restore() s390/nmi: consistently enable machine checks in trap_init() s390/ctlreg: return old register contents when changing bits s390/ap: handle outband SE bind state change s390/ap: store TAPQ hwinfo in struct ap_card s390/vfio-ap: fix sysfs status attribute for AP queue devices s390/vfio-ap: improve reaction to response code 07 from PQAP(AQIC) command ...
2 parents c299010 + b2b97a6 commit de927f6

50 files changed

Lines changed: 518 additions & 456 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

arch/s390/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ config S390
123123
select ARCH_USE_BUILTIN_BSWAP
124124
select ARCH_USE_CMPXCHG_LOCKREF
125125
select ARCH_USE_SYM_ANNOTATIONS
126-
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
127126
select ARCH_WANTS_NO_INSTR
128127
select ARCH_WANT_DEFAULT_BPF_JIT
129128
select ARCH_WANT_IPC_PARSE_VERSION

arch/s390/boot/ipl_parm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ void parse_boot_command_line(void)
274274
memory_limit = round_down(memparse(val, NULL), PAGE_SIZE);
275275

276276
if (!strcmp(param, "vmalloc") && val) {
277-
vmalloc_size = round_up(memparse(val, NULL), PAGE_SIZE);
277+
vmalloc_size = round_up(memparse(val, NULL), _SEGMENT_SIZE);
278278
vmalloc_size_set = 1;
279279
}
280280

arch/s390/boot/startup.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ static unsigned long setup_kernel_memory_layout(void)
255255
VMALLOC_END = MODULES_VADDR;
256256

257257
/* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */
258-
vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE));
258+
vsize = round_down(VMALLOC_END / 2, _SEGMENT_SIZE);
259+
vmalloc_size = min(vmalloc_size, vsize);
259260
VMALLOC_START = VMALLOC_END - vmalloc_size;
260261

261262
/* split remaining virtual space between 1:1 mapping & vmemmap array */

arch/s390/crypto/chacha-glue.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src,
8282
* it cannot handle a block of data or less, but otherwise
8383
* it can handle data of arbitrary size
8484
*/
85-
if (bytes <= CHACHA_BLOCK_SIZE || nrounds != 20 || !MACHINE_HAS_VX)
85+
if (bytes <= CHACHA_BLOCK_SIZE || nrounds != 20 || !cpu_has_vx())
8686
chacha_crypt_generic(state, dst, src, bytes, nrounds);
8787
else
8888
chacha20_crypt_s390(state, dst, src, bytes,

arch/s390/include/asm/ap.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,21 @@ static inline bool ap_instructions_available(void)
8888
}
8989

9090
/* TAPQ register GR2 response struct */
91-
struct ap_tapq_gr2 {
91+
struct ap_tapq_hwinfo {
9292
union {
9393
unsigned long value;
9494
struct {
9595
unsigned int fac : 32; /* facility bits */
9696
unsigned int apinfo : 32; /* ap type, ... */
9797
};
9898
struct {
99-
unsigned int s : 1; /* APSC */
100-
unsigned int m : 1; /* AP4KM */
101-
unsigned int c : 1; /* AP4KC */
102-
unsigned int mode : 3;
103-
unsigned int n : 1; /* APXA */
99+
unsigned int apsc : 1; /* APSC */
100+
unsigned int mex4k : 1; /* AP4KM */
101+
unsigned int crt4k : 1; /* AP4KC */
102+
unsigned int cca : 1; /* D */
103+
unsigned int accel : 1; /* A */
104+
unsigned int ep11 : 1; /* X */
105+
unsigned int apxa : 1; /* APXA */
104106
unsigned int : 1;
105107
unsigned int class : 8;
106108
unsigned int bs : 2; /* SE bind/assoc */
@@ -126,11 +128,12 @@ struct ap_tapq_gr2 {
126128
/**
127129
* ap_tapq(): Test adjunct processor queue.
128130
* @qid: The AP queue number
129-
* @info: Pointer to queue descriptor
131+
* @info: Pointer to tapq hwinfo struct
130132
*
131133
* Returns AP queue status structure.
132134
*/
133-
static inline struct ap_queue_status ap_tapq(ap_qid_t qid, struct ap_tapq_gr2 *info)
135+
static inline struct ap_queue_status ap_tapq(ap_qid_t qid,
136+
struct ap_tapq_hwinfo *info)
134137
{
135138
union ap_queue_status_reg reg1;
136139
unsigned long reg2;
@@ -158,7 +161,7 @@ static inline struct ap_queue_status ap_tapq(ap_qid_t qid, struct ap_tapq_gr2 *i
158161
* Returns AP queue status structure.
159162
*/
160163
static inline struct ap_queue_status ap_test_queue(ap_qid_t qid, int tbit,
161-
struct ap_tapq_gr2 *info)
164+
struct ap_tapq_hwinfo *info)
162165
{
163166
if (tbit)
164167
qid |= 1UL << 23; /* set T bit*/

arch/s390/include/asm/ctlreg.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,22 +141,26 @@ static __always_inline void local_ctl_store(unsigned int cr, struct ctlreg *reg)
141141
: [cr] "i" (cr));
142142
}
143143

144-
static __always_inline void local_ctl_set_bit(unsigned int cr, unsigned int bit)
144+
static __always_inline struct ctlreg local_ctl_set_bit(unsigned int cr, unsigned int bit)
145145
{
146-
struct ctlreg reg;
146+
struct ctlreg new, old;
147147

148-
local_ctl_store(cr, &reg);
149-
reg.val |= 1UL << bit;
150-
local_ctl_load(cr, &reg);
148+
local_ctl_store(cr, &old);
149+
new = old;
150+
new.val |= 1UL << bit;
151+
local_ctl_load(cr, &new);
152+
return old;
151153
}
152154

153-
static __always_inline void local_ctl_clear_bit(unsigned int cr, unsigned int bit)
155+
static __always_inline struct ctlreg local_ctl_clear_bit(unsigned int cr, unsigned int bit)
154156
{
155-
struct ctlreg reg;
157+
struct ctlreg new, old;
156158

157-
local_ctl_store(cr, &reg);
158-
reg.val &= ~(1UL << bit);
159-
local_ctl_load(cr, &reg);
159+
local_ctl_store(cr, &old);
160+
new = old;
161+
new.val &= ~(1UL << bit);
162+
local_ctl_load(cr, &new);
163+
return old;
160164
}
161165

162166
struct lowcore;

arch/s390/include/asm/fpu/api.h

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,26 +46,33 @@
4646

4747
#include <linux/preempt.h>
4848
#include <asm/asm-extable.h>
49+
#include <asm/fpu/internal.h>
4950

5051
void save_fpu_regs(void);
5152
void load_fpu_regs(void);
5253
void __load_fpu_regs(void);
5354

54-
static inline int test_fp_ctl(u32 fpc)
55+
/**
56+
* sfpc_safe - Set floating point control register safely.
57+
* @fpc: new value for floating point control register
58+
*
59+
* Set floating point control register. This may lead to an exception,
60+
* since a saved value may have been modified by user space (ptrace,
61+
* signal return, kvm registers) to an invalid value. In such a case
62+
* set the floating point control register to zero.
63+
*/
64+
static inline void sfpc_safe(u32 fpc)
5565
{
56-
u32 orig_fpc;
57-
int rc;
58-
59-
asm volatile(
60-
" efpc %1\n"
61-
" sfpc %2\n"
62-
"0: sfpc %1\n"
63-
" la %0,0\n"
64-
"1:\n"
65-
EX_TABLE(0b,1b)
66-
: "=d" (rc), "=&d" (orig_fpc)
67-
: "d" (fpc), "0" (-EINVAL));
68-
return rc;
66+
asm volatile("\n"
67+
"0: sfpc %[fpc]\n"
68+
"1: nopr %%r7\n"
69+
".pushsection .fixup, \"ax\"\n"
70+
"2: lghi %[fpc],0\n"
71+
" jg 0b\n"
72+
".popsection\n"
73+
EX_TABLE(1b, 2b)
74+
: [fpc] "+d" (fpc)
75+
: : "memory");
6976
}
7077

7178
#define KERNEL_FPC 1

arch/s390/include/asm/fpu/internal.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,14 @@
1010
#define _ASM_S390_FPU_INTERNAL_H
1111

1212
#include <linux/string.h>
13+
#include <asm/facility.h>
1314
#include <asm/fpu/types.h>
1415

16+
static inline bool cpu_has_vx(void)
17+
{
18+
return likely(test_facility(129));
19+
}
20+
1521
static inline void save_vx_regs(__vector128 *vxrs)
1622
{
1723
asm volatile(
@@ -41,7 +47,7 @@ static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
4147
{
4248
fpregs->pad = 0;
4349
fpregs->fpc = fpu->fpc;
44-
if (MACHINE_HAS_VX)
50+
if (cpu_has_vx())
4551
convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs);
4652
else
4753
memcpy((freg_t *)&fpregs->fprs, fpu->fprs,
@@ -51,7 +57,7 @@ static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
5157
static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu)
5258
{
5359
fpu->fpc = fpregs->fpc;
54-
if (MACHINE_HAS_VX)
60+
if (cpu_has_vx())
5561
convert_fp_to_vx(fpu->vxrs, (freg_t *)&fpregs->fprs);
5662
else
5763
memcpy(fpu->fprs, (freg_t *)&fpregs->fprs,

arch/s390/include/asm/processor.h

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,7 @@ struct thread_struct {
184184
struct gs_cb *gs_cb; /* Current guarded storage cb */
185185
struct gs_cb *gs_bc_cb; /* Broadcast guarded storage cb */
186186
struct pgm_tdb trap_tdb; /* Transaction abort diagnose block */
187-
/*
188-
* Warning: 'fpu' is dynamically-sized. It *MUST* be at
189-
* the end.
190-
*/
191-
struct fpu fpu; /* FP and VX register save area */
187+
struct fpu fpu; /* FP and VX register save area */
192188
};
193189

194190
/* Flag to disable transactions. */
@@ -331,14 +327,36 @@ static inline unsigned long __extract_psw(void)
331327
return (((unsigned long) reg1) << 32) | ((unsigned long) reg2);
332328
}
333329

334-
static inline void local_mcck_enable(void)
330+
static inline unsigned long __local_mcck_save(void)
335331
{
336-
__load_psw_mask(__extract_psw() | PSW_MASK_MCHECK);
332+
unsigned long mask = __extract_psw();
333+
334+
__load_psw_mask(mask & ~PSW_MASK_MCHECK);
335+
return mask & PSW_MASK_MCHECK;
336+
}
337+
338+
#define local_mcck_save(mflags) \
339+
do { \
340+
typecheck(unsigned long, mflags); \
341+
mflags = __local_mcck_save(); \
342+
} while (0)
343+
344+
static inline void local_mcck_restore(unsigned long mflags)
345+
{
346+
unsigned long mask = __extract_psw();
347+
348+
mask &= ~PSW_MASK_MCHECK;
349+
__load_psw_mask(mask | mflags);
337350
}
338351

339352
static inline void local_mcck_disable(void)
340353
{
341-
__load_psw_mask(__extract_psw() & ~PSW_MASK_MCHECK);
354+
__local_mcck_save();
355+
}
356+
357+
static inline void local_mcck_enable(void)
358+
{
359+
__load_psw_mask(__extract_psw() | PSW_MASK_MCHECK);
342360
}
343361

344362
/*

arch/s390/include/asm/setup.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#define MACHINE_FLAG_TOPOLOGY BIT(10)
2929
#define MACHINE_FLAG_TE BIT(11)
3030
#define MACHINE_FLAG_TLB_LC BIT(12)
31-
#define MACHINE_FLAG_VX BIT(13)
3231
#define MACHINE_FLAG_TLB_GUEST BIT(14)
3332
#define MACHINE_FLAG_NX BIT(15)
3433
#define MACHINE_FLAG_GS BIT(16)
@@ -90,7 +89,6 @@ extern unsigned long mio_wb_bit_mask;
9089
#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
9190
#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE)
9291
#define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC)
93-
#define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX)
9492
#define MACHINE_HAS_TLB_GUEST (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_GUEST)
9593
#define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX)
9694
#define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS)

0 commit comments

Comments
 (0)