s390/traps: add struct to access transactional diagnostic block

gcc-11 warns:

arch/s390/kernel/traps.c: In function __do_pgm_check:
arch/s390/kernel/traps.c:319:17: warning: memcpy reading 256 bytes from a region of size 0 [-Wstringop-overread]
  319 |                 memcpy(&current->thread.trap_tdb, &S390_lowcore.pgm_tdb, 256);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fix this by adding a struct pgm_tdb to struct lowcore and copy that.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
Sven Schnelle 2021-05-05 22:01:16 +02:00 committed by Vasily Gorbik
parent 6c6a07fc7c
commit 755112b35c
4 changed files with 11 additions and 5 deletions

View file

@ -17,6 +17,10 @@
#define LC_ORDER 1
#define LC_PAGES 2
struct pgm_tdb {
u64 data[32];
};
struct lowcore {
__u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */
__u32 ipl_parmblock_ptr; /* 0x0014 */
@ -184,7 +188,7 @@ struct lowcore {
__u8 pad_0x1400[0x1800-0x1400]; /* 0x1400 */
/* Transaction abort diagnostic block */
__u8 pgm_tdb[256]; /* 0x1800 */
struct pgm_tdb pgm_tdb; /* 0x1800 */
__u8 pad_0x1900[0x2000-0x1900]; /* 0x1900 */
} __packed __aligned(8192);

View file

@ -129,7 +129,7 @@ struct thread_struct {
struct runtime_instr_cb *ri_cb;
struct gs_cb *gs_cb; /* Current guarded storage cb */
struct gs_cb *gs_bc_cb; /* Broadcast guarded storage cb */
unsigned char trap_tdb[256]; /* Transaction abort diagnose block */
struct pgm_tdb trap_tdb; /* Transaction abort diagnose block */
/*
* Warning: 'fpu' is dynamically-sized. It *MUST* be at
* the end.

View file

@ -975,10 +975,12 @@ static int s390_tdb_get(struct task_struct *target,
struct membuf to)
{
struct pt_regs *regs = task_pt_regs(target);
size_t size;
if (!(regs->int_code & 0x200))
return -ENODATA;
return membuf_write(&to, target->thread.trap_tdb, 256);
size = sizeof(target->thread.trap_tdb.data);
return membuf_write(&to, target->thread.trap_tdb.data, size);
}
static int s390_tdb_set(struct task_struct *target,

View file

@ -36,7 +36,7 @@ static inline void __user *get_trap_ip(struct pt_regs *regs)
unsigned long address;
if (regs->int_code & 0x200)
address = *(unsigned long *)(current->thread.trap_tdb + 24);
address = current->thread.trap_tdb.data[3];
else
address = regs->psw.addr;
return (void __user *) (address - (regs->int_code >> 16));
@ -318,7 +318,7 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
if (S390_lowcore.pgm_code & 0x0200) {
/* transaction abort */
memcpy(&current->thread.trap_tdb, &S390_lowcore.pgm_tdb, 256);
current->thread.trap_tdb = S390_lowcore.pgm_tdb;
}
if (S390_lowcore.pgm_code & PGM_INT_CODE_PER) {