From b886a9d1560d6c7d5d58344b16f53ab2cba5b666 Mon Sep 17 00:00:00 2001 From: Ingo Tuchscherer Date: Thu, 25 Aug 2016 11:19:58 +0200 Subject: s390/zcrypt: Introduce new zcrypt device status API Introduce new ioctl (ZDEVICESTATUS) to provide detailed information, like hardware type, domains, status and functionality of available crypto devices. Signed-off-by: Ingo Tuchscherer Signed-off-by: Martin Schwidefsky --- arch/s390/include/uapi/asm/zcrypt.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'arch/s390') diff --git a/arch/s390/include/uapi/asm/zcrypt.h b/arch/s390/include/uapi/asm/zcrypt.h index f2b18eacaca8..a777f87ef889 100644 --- a/arch/s390/include/uapi/asm/zcrypt.h +++ b/arch/s390/include/uapi/asm/zcrypt.h @@ -215,6 +215,42 @@ struct ep11_urb { uint64_t resp; } __attribute__((packed)); +/** + * struct zcrypt_device_status + * @hwtype: raw hardware type + * @qid: 6 bit device index, 8 bit domain + * @functions: AP device function bit field 'abcdef' + * a, b, c = reserved + * d = CCA coprocessor + * e = Accelerator + * f = EP11 coprocessor + * @online online status + * @reserved reserved + */ +struct zcrypt_device_status { + unsigned int hwtype:8; + unsigned int qid:14; + unsigned int online:1; + unsigned int functions:6; + unsigned int reserved:3; +}; + +#define MAX_ZDEV_CARDIDS 64 +#define MAX_ZDEV_DOMAINS 256 + +/** + * Maximum number of zcrypt devices + */ +#define MAX_ZDEV_ENTRIES (MAX_ZDEV_CARDIDS * MAX_ZDEV_DOMAINS) + +/** + * zcrypt_device_matrix + * Device matrix of all zcrypt devices + */ +struct zcrypt_device_matrix { + struct zcrypt_device_status device[MAX_ZDEV_ENTRIES]; +}; + #define AUTOSELECT ((unsigned int)0xFFFFFFFF) #define ZCRYPT_IOCTL_MAGIC 'z' @@ -321,6 +357,7 @@ struct ep11_urb { #define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0) #define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0) #define ZSENDEP11CPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x04, 0) +#define ZDEVICESTATUS _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x4f, 0) /* New status calls */ #define Z90STAT_TOTALCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int) -- cgit v1.2.3 From 13b251bdc8b97c45cc8b1d57193ab05ec0fe97e8 Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Fri, 25 Nov 2016 18:04:56 +0100 Subject: s390/zcrypt: tracepoint definitions for zcrypt device driver. This patch introduces tracepoint definitions and tracepoint event invocations for the s390 zcrypt device. Currently there are just two tracepoint events defined. An s390_zcrypt_req request event occurs as soon as the request is recognized by the zcrypt ioctl function. This event may act as some kind of request-processing-starts-now indication. As late as possible within the zcrypt ioctl function there occurs the s390_zcrypt_rep event which may act as the point in time where the request has been processed by the kernel and the result is about to be transferred back to userspace. The glue which binds together request and reply event is the ptr parameter, which is the local buffer address where the request from userspace has been stored by the ioctl function. The main purpose of this zcrypt tracepoint patch is to get some data for performance measurements together with information about the kind of request and on which card and queue the request has been processed. It is not an ffdc interface as there is already code in the zcrypt device driver to serve the s390 debug feature interface. Signed-off-by: Harald Freudenberger Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/trace/zcrypt.h | 122 +++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 arch/s390/include/asm/trace/zcrypt.h (limited to 'arch/s390') diff --git a/arch/s390/include/asm/trace/zcrypt.h b/arch/s390/include/asm/trace/zcrypt.h new file mode 100644 index 000000000000..adcb77fafa9d --- /dev/null +++ b/arch/s390/include/asm/trace/zcrypt.h @@ -0,0 +1,122 @@ +/* + * Tracepoint definitions for the s390 zcrypt device driver + * + * Copyright IBM Corp. 2016 + * Author(s): Harald Freudenberger + * + * Currently there are two tracepoint events defined here. + * An s390_zcrypt_req request event occurs as soon as the request is + * recognized by the zcrypt ioctl function. This event may act as some kind + * of request-processing-starts-now indication. + * As late as possible within the zcrypt ioctl function there occurs the + * s390_zcrypt_rep event which may act as the point in time where the + * request has been processed by the kernel and the result is about to be + * transferred back to userspace. + * The glue which binds together request and reply event is the ptr + * parameter, which is the local buffer address where the request from + * userspace has been stored by the ioctl function. + * + * The main purpose of this zcrypt tracepoint api is to get some data for + * performance measurements together with information about on which card + * and queue the request has been processed. It is not an ffdc interface as + * there is already code in the zcrypt device driver to serve the s390 + * debug feature interface. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM s390 + +#if !defined(_TRACE_S390_ZCRYPT_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_S390_ZCRYPT_H + +#include + +#define TP_ICARSAMODEXPO 0x0001 +#define TP_ICARSACRT 0x0002 +#define TB_ZSECSENDCPRB 0x0003 +#define TP_ZSENDEP11CPRB 0x0004 +#define TP_HWRNGCPRB 0x0005 + +#define show_zcrypt_tp_type(type) \ + __print_symbolic(type, \ + { TP_ICARSAMODEXPO, "ICARSAMODEXPO" }, \ + { TP_ICARSACRT, "ICARSACRT" }, \ + { TB_ZSECSENDCPRB, "ZSECSENDCPRB" }, \ + { TP_ZSENDEP11CPRB, "ZSENDEP11CPRB" }, \ + { TP_HWRNGCPRB, "HWRNGCPRB" }) + +/** + * trace_s390_zcrypt_req - zcrypt request tracepoint function + * @ptr: Address of the local buffer where the request from userspace + * is stored. Can be used as a unique id to relate together + * request and reply. + * @type: One of the TP_ defines above. + * + * Called when a request from userspace is recognised within the ioctl + * function of the zcrypt device driver and may act as an entry + * timestamp. + */ +TRACE_EVENT(s390_zcrypt_req, + TP_PROTO(void *ptr, u32 type), + TP_ARGS(ptr, type), + TP_STRUCT__entry( + __field(void *, ptr) + __field(u32, type)), + TP_fast_assign( + __entry->ptr = ptr; + __entry->type = type;), + TP_printk("ptr=%p type=%s", + __entry->ptr, + show_zcrypt_tp_type(__entry->type)) +); + +/** + * trace_s390_zcrypt_rep - zcrypt reply tracepoint function + * @ptr: Address of the local buffer where the request from userspace + * is stored. Can be used as a unique id to match together + * request and reply. + * @fc: Function code. + * @rc: The bare returncode as returned by the device driver ioctl + * function. + * @dev: The adapter nr where this request was actually processed. + * @dom: Domain id of the device where this request was processed. + * + * Called upon recognising the reply from the crypto adapter. This + * message may act as the exit timestamp for the request but also + * carries some info about on which adapter the request was processed + * and the returncode from the device driver. + */ +TRACE_EVENT(s390_zcrypt_rep, + TP_PROTO(void *ptr, u32 fc, u32 rc, u16 dev, u16 dom), + TP_ARGS(ptr, fc, rc, dev, dom), + TP_STRUCT__entry( + __field(void *, ptr) + __field(u32, fc) + __field(u32, rc) + __field(u16, device) + __field(u16, domain)), + TP_fast_assign( + __entry->ptr = ptr; + __entry->fc = fc; + __entry->rc = rc; + __entry->device = dev; + __entry->domain = dom;), + TP_printk("ptr=%p fc=0x%04x rc=%d dev=0x%02hx domain=0x%04hx", + __entry->ptr, + (unsigned int) __entry->fc, + (int) __entry->rc, + (unsigned short) __entry->device, + (unsigned short) __entry->domain) +); + +#endif /* _TRACE_S390_ZCRYPT_H */ + +/* This part must be outside protection */ + +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE + +#define TRACE_INCLUDE_PATH asm/trace +#define TRACE_INCLUDE_FILE zcrypt + +#include -- cgit v1.2.3 From 75a357341e7c9d3893405ea6f9d722036012dd1f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 13 Dec 2016 15:58:16 +0100 Subject: s390: fix compile error with memmove_early() inline assembly Old gcc versions can't handle a bogus early clobber on a Q constraint: arch/s390/kernel/early.c: In function 'memmove_early.part.1': arch/s390/kernel/early.c:432:2: error: '&' constraint used with no register class Simply remove it to fix this. Reported-by: Stefan Haberland Fixes: d543a106f96d ("s390: fix initrd corruptions with gcov/kcov instrumented kernels") Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/early.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index d038c8cea6cb..324f1c147a41 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -417,7 +417,7 @@ static __init void memmove_early(void *dst, const void *src, size_t n) " brctg %[n],0b\n" "1:\n" : [addr] "=&d" (addr), - [psw_pgm_addr] "=&Q" (S390_lowcore.program_new_psw.addr), + [psw_pgm_addr] "=Q" (S390_lowcore.program_new_psw.addr), [dst] "+&a" (dst), [src] "+&a" (src), [n] "+d" (n) : [incr] "d" (incr) : "cc", "memory"); -- cgit v1.2.3 From 6d7b2ee9d56af3d17d88b0f43b7dc14ee38161b7 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 13 Dec 2016 16:19:11 +0100 Subject: s390/setup: reword printk messages Two of the messages introduced by the memblock conversion are reworded. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index adfac9f0a89f..865a48871ca4 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -485,7 +485,7 @@ static void __init setup_memory_end(void) max_pfn = max_low_pfn = PFN_DOWN(memory_end); memblock_remove(memory_end, ULONG_MAX); - pr_notice("Max memory size: %luMB\n", memory_end >> 20); + pr_notice("The maximum memory size is %luMB\n", memory_end >> 20); } static void __init setup_vmcoreinfo(void) @@ -650,7 +650,7 @@ static void __init check_initrd(void) #ifdef CONFIG_BLK_DEV_INITRD if (INITRD_START && INITRD_SIZE && !memblock_is_region_memory(INITRD_START, INITRD_SIZE)) { - pr_err("initrd does not fit memory.\n"); + pr_err("The initial RAM disk does not fit into the memory\n"); memblock_free(INITRD_START, INITRD_SIZE); initrd_start = initrd_end = 0; } -- cgit v1.2.3 From 259acc5c255a4260b3db0461afd5d93fabfe8524 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 10 Dec 2016 10:37:32 +0100 Subject: s390/cpumf: fix qsi inline assembly The qsi inline assembly takes an initialized "cc" variable as output operand but specifies it as write-to operand only instead of read/write operand. This allows the compiler to omit the initialization, which in fact it also does (gcc 6.1). Use the "+" constraint modifier to fix this. In addition also use the Q constraint to specify the hws_qsi_info_block memory location, so the compiler can generate slightly better code. Also get rid of the cc clobber since none of the instructions within the inline assembly modify the condition code. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/cpu_mf.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h index b69d8bc231a5..428c41239a49 100644 --- a/arch/s390/include/asm/cpu_mf.h +++ b/arch/s390/include/asm/cpu_mf.h @@ -213,18 +213,14 @@ static inline int stcctm5(u64 num, u64 *val) /* Query sampling information */ static inline int qsi(struct hws_qsi_info_block *info) { - int cc; - cc = 1; + int cc = 1; asm volatile( - "0: .insn s,0xb2860000,0(%1)\n" + "0: .insn s,0xb2860000,%1\n" "1: lhi %0,0\n" "2:\n" EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) - : "=d" (cc), "+a" (info) - : "m" (*info) - : "cc", "memory"); - + : "+d" (cc), "+Q" (*info)); return cc ? -EINVAL : 0; } -- cgit v1.2.3 From 7a71fd1c59dfd20fac4d14486d63d3d5ab70498a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 13 Dec 2016 09:50:30 +0100 Subject: s390/lib: add missing memory barriers to string inline assemblies We have a couple of inline assemblies like memchr() and strlen() that read from memory, but tell the compiler only they need the addresses of the strings they access. This allows the compiler to omit the initialization of such strings and therefore generate broken code. Add the missing memory barrier to all string related inline assemblies to fix this potential issue. It looks like the compiler currently does not generate broken code due to these bugs. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/string.h | 8 ++++---- arch/s390/lib/string.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h index 15a3c005c274..e5f5c7074f2c 100644 --- a/arch/s390/include/asm/string.h +++ b/arch/s390/include/asm/string.h @@ -62,7 +62,7 @@ static inline void *memchr(const void * s, int c, size_t n) " jl 1f\n" " la %0,0\n" "1:" - : "+a" (ret), "+&a" (s) : "d" (r0) : "cc"); + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); return (void *) ret; } @@ -74,7 +74,7 @@ static inline void *memscan(void *s, int c, size_t n) asm volatile( "0: srst %0,%1\n" " jo 0b\n" - : "+a" (ret), "+&a" (s) : "d" (r0) : "cc"); + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); return (void *) ret; } @@ -115,7 +115,7 @@ static inline size_t strlen(const char *s) asm volatile( "0: srst %0,%1\n" " jo 0b" - : "+d" (r0), "+a" (tmp) : : "cc"); + : "+d" (r0), "+a" (tmp) : : "cc", "memory"); return r0 - (unsigned long) s; } @@ -128,7 +128,7 @@ static inline size_t strnlen(const char * s, size_t n) asm volatile( "0: srst %0,%1\n" " jo 0b" - : "+a" (end), "+a" (tmp) : "d" (r0) : "cc"); + : "+a" (end), "+a" (tmp) : "d" (r0) : "cc", "memory"); return end - s; } #else /* IN_ARCH_STRING_C */ diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c index 48352bffbc92..f71d9f655970 100644 --- a/arch/s390/lib/string.c +++ b/arch/s390/lib/string.c @@ -20,7 +20,7 @@ static inline char *__strend(const char *s) asm volatile ("0: srst %0,%1\n" " jo 0b" - : "+d" (r0), "+a" (s) : : "cc" ); + : "+d" (r0), "+a" (s) : : "cc", "memory"); return (char *) r0; } @@ -31,7 +31,7 @@ static inline char *__strnend(const char *s, size_t n) asm volatile ("0: srst %0,%1\n" " jo 0b" - : "+d" (p), "+a" (s) : "d" (r0) : "cc" ); + : "+d" (p), "+a" (s) : "d" (r0) : "cc", "memory"); return (char *) p; } @@ -213,7 +213,7 @@ int strcmp(const char *cs, const char *ct) " sr %0,%1\n" "1:" : "+d" (ret), "+d" (r0), "+a" (cs), "+a" (ct) - : : "cc" ); + : : "cc", "memory"); return ret; } EXPORT_SYMBOL(strcmp); @@ -250,7 +250,7 @@ static inline int clcle(const char *s1, unsigned long l1, " ipm %0\n" " srl %0,28" : "=&d" (cc), "+a" (r2), "+a" (r3), - "+a" (r4), "+a" (r5) : : "cc"); + "+a" (r4), "+a" (r5) : : "cc", "memory"); return cc; } @@ -298,7 +298,7 @@ void *memchr(const void *s, int c, size_t n) " jl 1f\n" " la %0,0\n" "1:" - : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); return (void *) ret; } EXPORT_SYMBOL(memchr); @@ -336,7 +336,7 @@ void *memscan(void *s, int c, size_t n) asm volatile ("0: srst %0,%1\n" " jo 0b\n" - : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); return (void *) ret; } EXPORT_SYMBOL(memscan); -- cgit v1.2.3 From 86fa7087d348b6c8a159c77ea20e530ee1230c34 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 13 Dec 2016 12:42:07 +0100 Subject: s390/nmi: fix inline assembly constraints Add missing memory clobbers / barriers or use the Q constraint where possible to tell the compiler that the inline assemblies actually access memory and not only pointers to memory. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/nmi.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index 9a32f7419d78..9862196b4b89 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c @@ -102,7 +102,7 @@ static int notrace s390_validate_registers(union mci mci, int umode) { int kill_task; u64 zero; - void *fpt_save_area, *fpt_creg_save_area; + void *fpt_save_area; kill_task = 0; zero = 0; @@ -130,7 +130,6 @@ static int notrace s390_validate_registers(union mci mci, int umode) kill_task = 1; } fpt_save_area = &S390_lowcore.floating_pt_save_area; - fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area; if (!mci.fc) { /* * Floating point control register can't be restored. @@ -142,11 +141,13 @@ static int notrace s390_validate_registers(union mci mci, int umode) */ if (S390_lowcore.fpu_flags & KERNEL_FPC) s390_handle_damage(); - asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero)); + asm volatile("lfpc %0" : : "Q" (zero)); if (!test_cpu_flag(CIF_FPU)) kill_task = 1; - } else - asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area)); + } else { + asm volatile("lfpc %0" + : : "Q" (S390_lowcore.fpt_creg_save_area)); + } if (!MACHINE_HAS_VX) { /* Validate floating point registers */ @@ -167,7 +168,7 @@ static int notrace s390_validate_registers(union mci mci, int umode) " ld 13,104(%0)\n" " ld 14,112(%0)\n" " ld 15,120(%0)\n" - : : "a" (fpt_save_area)); + : : "a" (fpt_save_area) : "memory"); } else { /* Validate vector registers */ union ctlreg0 cr0; @@ -217,7 +218,7 @@ static int notrace s390_validate_registers(union mci mci, int umode) } else { asm volatile( " lctlg 0,15,0(%0)" - : : "a" (&S390_lowcore.cregs_save_area)); + : : "a" (&S390_lowcore.cregs_save_area) : "memory"); } /* * We don't even try to validate the TOD register, since we simply @@ -234,9 +235,9 @@ static int notrace s390_validate_registers(union mci mci, int umode) : : : "0", "cc"); else asm volatile( - " l 0,0(%0)\n" + " l 0,%0\n" " sckpf" - : : "a" (&S390_lowcore.tod_progreg_save_area) + : : "Q" (S390_lowcore.tod_progreg_save_area) : "0", "cc"); /* Validate clock comparator register */ set_clock_comparator(S390_lowcore.clock_comparator); -- cgit v1.2.3 From f1c7ea26178176ca783cc2ac54f211630344290c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 13 Dec 2016 12:51:19 +0100 Subject: s390/extmem: add missing memory clobber to dcss_set_subcodes Add the missing memory clobber / barrier to dcss_set_subcodes() to tell the compiler that the inline assembly accesses memory (name string). Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/extmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/s390') diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 02042b6b66bf..362237203144 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -122,7 +122,7 @@ dcss_set_subcodes(void) "1: la %2,3\n" "2:\n" EX_TABLE(0b, 1b) - : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); + : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc", "memory"); kfree(name); /* Diag x'64' new subcodes are supported, set to new subcodes */ -- cgit v1.2.3 From 0b7589ecca2b6f962cf3314a3a5a675deeefb624 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Wed, 15 Jun 2016 13:07:51 +0200 Subject: s390/pci: query fmb length Query the length of the fmb and abort fmb registration if the size of the associated measurement block is too small. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pci.h | 1 + arch/s390/include/asm/pci_clp.h | 3 ++- arch/s390/pci/pci.c | 2 +- arch/s390/pci/pci_clp.c | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 6611f798d2be..4e3186649578 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -133,6 +133,7 @@ struct zpci_dev { /* Function measurement block */ struct zpci_fmb *fmb; u16 fmb_update; /* update interval */ + u16 fmb_length; /* software counters */ atomic64_t allocated_pages; atomic64_t mapped_pages; diff --git a/arch/s390/include/asm/pci_clp.h b/arch/s390/include/asm/pci_clp.h index c232ef9711f5..d6f1b1d94352 100644 --- a/arch/s390/include/asm/pci_clp.h +++ b/arch/s390/include/asm/pci_clp.h @@ -87,7 +87,8 @@ struct clp_rsp_query_pci { u16 pchid; u32 bar[PCI_BAR_COUNT]; u8 pfip[CLP_PFIP_NR_SEGMENTS]; /* pci function internal path */ - u32 : 24; + u32 : 16; + u8 fmb_len; u8 pft; /* pci function type */ u64 sdma; /* start dma as */ u64 edma; /* end dma as */ diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 64e1734bebb7..38e17d4d9884 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -180,7 +180,7 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev) { struct mod_pci_args args = { 0, 0, 0, 0 }; - if (zdev->fmb) + if (zdev->fmb || sizeof(*zdev->fmb) < zdev->fmb_length) return -EINVAL; zdev->fmb = kmem_cache_zalloc(zdev_fmb_cache, GFP_KERNEL); diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index e3ef63b36b5a..1c3332ac1957 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -148,6 +148,7 @@ static int clp_store_query_pci_fn(struct zpci_dev *zdev, zdev->pft = response->pft; zdev->vfn = response->vfn; zdev->uid = response->uid; + zdev->fmb_length = sizeof(u32) * response->fmb_len; memcpy(zdev->pfip, response->pfip, sizeof(zdev->pfip)); if (response->util_str_avail) { -- cgit v1.2.3