From 1c588538f0e064729b76cbb01604359134a18a2d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 17 Jul 2019 09:24:13 +0900 Subject: [PATCH] 5.1-stable patches added patches: arc-hide-unused-function-unw_hdr_alloc.patch crypto-nx-set-receive-window-credits-to-max-number-of-crbs-in-rxfifo.patch crypto-talitos-fix-hash-on-sec1.patch crypto-talitos-move-struct-talitos_edesc-into-talitos.h.patch s390-fix-stfle-zero-padding.patch s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch s390-qdio-re-initialize-tiqdio-list-entries.patch --- ...c-hide-unused-function-unw_hdr_alloc.patch | 50 ++++ ...dits-to-max-number-of-crbs-in-rxfifo.patch | 49 ++++ .../crypto-talitos-fix-hash-on-sec1.patch | 219 ++++++++++++++++++ ...-struct-talitos_edesc-into-talitos.h.patch | 103 ++++++++ queue-5.1/s390-fix-stfle-zero-padding.patch | 83 +++++++ ...-the-dsci-in-tiqdio_add_input_queues.patch | 37 +++ ...io-re-initialize-tiqdio-list-entries.patch | 77 ++++++ queue-5.1/series | 7 + 8 files changed, 625 insertions(+) create mode 100644 queue-5.1/arc-hide-unused-function-unw_hdr_alloc.patch create mode 100644 queue-5.1/crypto-nx-set-receive-window-credits-to-max-number-of-crbs-in-rxfifo.patch create mode 100644 queue-5.1/crypto-talitos-fix-hash-on-sec1.patch create mode 100644 queue-5.1/crypto-talitos-move-struct-talitos_edesc-into-talitos.h.patch create mode 100644 queue-5.1/s390-fix-stfle-zero-padding.patch create mode 100644 queue-5.1/s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch create mode 100644 queue-5.1/s390-qdio-re-initialize-tiqdio-list-entries.patch diff --git a/queue-5.1/arc-hide-unused-function-unw_hdr_alloc.patch b/queue-5.1/arc-hide-unused-function-unw_hdr_alloc.patch new file mode 100644 index 00000000000..7f069cbd504 --- /dev/null +++ b/queue-5.1/arc-hide-unused-function-unw_hdr_alloc.patch @@ -0,0 +1,50 @@ +From fd5de2721ea7d16e2b16c4049ac49f229551b290 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 3 Jul 2019 15:39:25 +0200 +Subject: ARC: hide unused function unw_hdr_alloc + +From: Arnd Bergmann + +commit fd5de2721ea7d16e2b16c4049ac49f229551b290 upstream. + +As kernelci.org reports, this function is not used in +vdk_hs38_defconfig: + +arch/arc/kernel/unwind.c:188:14: warning: 'unw_hdr_alloc' defined but not used [-Wunused-function] + +Fixes: bc79c9a72165 ("ARC: dw2 unwind: Reinstante unwinding out of modules") +Link: https://kernelci.org/build/id/5d1cae3f59b514300340c132/logs/ +Cc: stable@vger.kernel.org +Signed-off-by: Arnd Bergmann +Signed-off-by: Vineet Gupta +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arc/kernel/unwind.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/arch/arc/kernel/unwind.c ++++ b/arch/arc/kernel/unwind.c +@@ -184,11 +184,6 @@ static void *__init unw_hdr_alloc_early( + return memblock_alloc_from(sz, sizeof(unsigned int), MAX_DMA_ADDRESS); + } + +-static void *unw_hdr_alloc(unsigned long sz) +-{ +- return kmalloc(sz, GFP_KERNEL); +-} +- + static void init_unwind_table(struct unwind_table *table, const char *name, + const void *core_start, unsigned long core_size, + const void *init_start, unsigned long init_size, +@@ -369,6 +364,10 @@ ret_err: + } + + #ifdef CONFIG_MODULES ++static void *unw_hdr_alloc(unsigned long sz) ++{ ++ return kmalloc(sz, GFP_KERNEL); ++} + + static struct unwind_table *last_table; + diff --git a/queue-5.1/crypto-nx-set-receive-window-credits-to-max-number-of-crbs-in-rxfifo.patch b/queue-5.1/crypto-nx-set-receive-window-credits-to-max-number-of-crbs-in-rxfifo.patch new file mode 100644 index 00000000000..b685a7fcf06 --- /dev/null +++ b/queue-5.1/crypto-nx-set-receive-window-credits-to-max-number-of-crbs-in-rxfifo.patch @@ -0,0 +1,49 @@ +From e52d484d9869eb291140545746ccbe5ffc7c9306 Mon Sep 17 00:00:00 2001 +From: Haren Myneni +Date: Tue, 18 Jun 2019 12:09:22 -0700 +Subject: crypto/NX: Set receive window credits to max number of CRBs in RxFIFO + +From: Haren Myneni + +commit e52d484d9869eb291140545746ccbe5ffc7c9306 upstream. + +System gets checkstop if RxFIFO overruns with more requests than the +maximum possible number of CRBs in FIFO at the same time. The max number +of requests per window is controlled by window credits. So find max +CRBs from FIFO size and set it to receive window credits. + +Fixes: b0d6c9bab5e4 ("crypto/nx: Add P9 NX support for 842 compression engine") +CC: stable@vger.kernel.org # v4.14+ +Signed-off-by:Haren Myneni +Signed-off-by: Greg Kroah-Hartman + +Signed-off-by: Herbert Xu + +--- + drivers/crypto/nx/nx-842-powernv.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/crypto/nx/nx-842-powernv.c ++++ b/drivers/crypto/nx/nx-842-powernv.c +@@ -36,8 +36,6 @@ MODULE_ALIAS_CRYPTO("842-nx"); + #define WORKMEM_ALIGN (CRB_ALIGN) + #define CSB_WAIT_MAX (5000) /* ms */ + #define VAS_RETRIES (10) +-/* # of requests allowed per RxFIFO at a time. 0 for unlimited */ +-#define MAX_CREDITS_PER_RXFIFO (1024) + + struct nx842_workmem { + /* Below fields must be properly aligned */ +@@ -821,7 +819,11 @@ static int __init vas_cfg_coproc_info(st + rxattr.lnotify_lpid = lpid; + rxattr.lnotify_pid = pid; + rxattr.lnotify_tid = tid; +- rxattr.wcreds_max = MAX_CREDITS_PER_RXFIFO; ++ /* ++ * Maximum RX window credits can not be more than #CRBs in ++ * RxFIFO. Otherwise, can get checkstop if RxFIFO overruns. ++ */ ++ rxattr.wcreds_max = fifo_size / CRB_SIZE; + + /* + * Open a VAS receice window which is used to configure RxFIFO diff --git a/queue-5.1/crypto-talitos-fix-hash-on-sec1.patch b/queue-5.1/crypto-talitos-fix-hash-on-sec1.patch new file mode 100644 index 00000000000..8ff177216c0 --- /dev/null +++ b/queue-5.1/crypto-talitos-fix-hash-on-sec1.patch @@ -0,0 +1,219 @@ +From 58cdbc6d2263beb36954408522762bbe73169306 Mon Sep 17 00:00:00 2001 +From: Christophe Leroy +Date: Mon, 24 Jun 2019 07:20:16 +0000 +Subject: crypto: talitos - fix hash on SEC1. + +From: Christophe Leroy + +commit 58cdbc6d2263beb36954408522762bbe73169306 upstream. + +On SEC1, hash provides wrong result when performing hashing in several +steps with input data SG list has more than one element. This was +detected with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS: + +[ 44.185947] alg: hash: md5-talitos test failed (wrong result) on test vector 6, cfg="random: may_sleep use_finup src_divs=[25.88%@+8063, 24.19%@+9588, 28.63%@+16333, 4.60%@+6756, 16.70%@+16281] dst_divs=[71.61%@alignmask+16361, 14.36%@+7756, 14.3%@+" +[ 44.325122] alg: hash: sha1-talitos test failed (wrong result) on test vector 3, cfg="random: inplace use_final src_divs=[16.56%@+16378, 52.0%@+16329, 21.42%@alignmask+16380, 10.2%@alignmask+16380] iv_offset=39" +[ 44.493500] alg: hash: sha224-talitos test failed (wrong result) on test vector 4, cfg="random: use_final nosimd src_divs=[52.27%@+7401, 17.34%@+16285, 17.71%@+26, 12.68%@+10644] iv_offset=43" +[ 44.673262] alg: hash: sha256-talitos test failed (wrong result) on test vector 4, cfg="random: may_sleep use_finup src_divs=[60.6%@+12790, 17.86%@+1329, 12.64%@alignmask+16300, 8.29%@+15, 0.40%@+13506, 0.51%@+16322, 0.24%@+16339] dst_divs" + +This is due to two issues: +- We have an overlap between the buffer used for copying the input +data (SEC1 doesn't do scatter/gather) and the chained descriptor. +- Data copy is wrong when the previous hash left less than one +blocksize of data to hash, implying a complement of the previous +block with a few bytes from the new request. + +Fix it by: +- Moving the second descriptor after the buffer, as moving the buffer +after the descriptor would make it more complex for other cipher +operations (AEAD, ABLKCIPHER) +- Skip the bytes taken from the new request to complete the previous +one by moving the SG list forward. + +Fixes: 37b5e8897eb5 ("crypto: talitos - chain in buffered data for ahash on SEC1") +Cc: stable@vger.kernel.org +Signed-off-by: Christophe Leroy +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/talitos.c | 69 +++++++++++++++++++++++++++-------------------- + 1 file changed, 41 insertions(+), 28 deletions(-) + +--- a/drivers/crypto/talitos.c ++++ b/drivers/crypto/talitos.c +@@ -334,6 +334,21 @@ int talitos_submit(struct device *dev, i + } + EXPORT_SYMBOL(talitos_submit); + ++static __be32 get_request_hdr(struct talitos_request *request, bool is_sec1) ++{ ++ struct talitos_edesc *edesc; ++ ++ if (!is_sec1) ++ return request->desc->hdr; ++ ++ if (!request->desc->next_desc) ++ return request->desc->hdr1; ++ ++ edesc = container_of(request->desc, struct talitos_edesc, desc); ++ ++ return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))->hdr1; ++} ++ + /* + * process what was done, notify callback of error if not + */ +@@ -355,12 +370,7 @@ static void flush_channel(struct device + + /* descriptors with their done bits set don't get the error */ + rmb(); +- if (!is_sec1) +- hdr = request->desc->hdr; +- else if (request->desc->next_desc) +- hdr = (request->desc + 1)->hdr1; +- else +- hdr = request->desc->hdr1; ++ hdr = get_request_hdr(request, is_sec1); + + if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE) + status = 0; +@@ -490,8 +500,14 @@ static u32 current_desc_hdr(struct devic + } + } + +- if (priv->chan[ch].fifo[iter].desc->next_desc == cur_desc) +- return (priv->chan[ch].fifo[iter].desc + 1)->hdr; ++ if (priv->chan[ch].fifo[iter].desc->next_desc == cur_desc) { ++ struct talitos_edesc *edesc; ++ ++ edesc = container_of(priv->chan[ch].fifo[iter].desc, ++ struct talitos_edesc, desc); ++ return ((struct talitos_desc *) ++ (edesc->buf + edesc->dma_len))->hdr; ++ } + + return priv->chan[ch].fifo[iter].desc->hdr; + } +@@ -1401,15 +1417,11 @@ static struct talitos_edesc *talitos_ede + edesc->dst_nents = dst_nents; + edesc->iv_dma = iv_dma; + edesc->dma_len = dma_len; +- if (dma_len) { +- void *addr = &edesc->link_tbl[0]; +- +- if (is_sec1 && !dst) +- addr += sizeof(struct talitos_desc); +- edesc->dma_link_tbl = dma_map_single(dev, addr, ++ if (dma_len) ++ edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0], + edesc->dma_len, + DMA_BIDIRECTIONAL); +- } ++ + return edesc; + } + +@@ -1676,14 +1688,16 @@ static void common_nonsnoop_hash_unmap(s + struct talitos_private *priv = dev_get_drvdata(dev); + bool is_sec1 = has_ftr_sec1(priv); + struct talitos_desc *desc = &edesc->desc; +- struct talitos_desc *desc2 = desc + 1; ++ struct talitos_desc *desc2 = (struct talitos_desc *) ++ (edesc->buf + edesc->dma_len); + + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE); + if (desc->next_desc && + desc->ptr[5].ptr != desc2->ptr[5].ptr) + unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE); + +- talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0); ++ if (req_ctx->psrc) ++ talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0); + + /* When using hashctx-in, must unmap it. */ + if (from_talitos_ptr_len(&edesc->desc.ptr[1], is_sec1)) +@@ -1750,7 +1764,6 @@ static void talitos_handle_buggy_hash(st + + static int common_nonsnoop_hash(struct talitos_edesc *edesc, + struct ahash_request *areq, unsigned int length, +- unsigned int offset, + void (*callback) (struct device *dev, + struct talitos_desc *desc, + void *context, int error)) +@@ -1789,9 +1802,7 @@ static int common_nonsnoop_hash(struct t + + sg_count = edesc->src_nents ?: 1; + if (is_sec1 && sg_count > 1) +- sg_pcopy_to_buffer(req_ctx->psrc, sg_count, +- edesc->buf + sizeof(struct talitos_desc), +- length, req_ctx->nbuf); ++ sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length); + else if (length) + sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count, + DMA_TO_DEVICE); +@@ -1804,7 +1815,7 @@ static int common_nonsnoop_hash(struct t + DMA_TO_DEVICE); + } else { + sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc, +- &desc->ptr[3], sg_count, offset, 0); ++ &desc->ptr[3], sg_count, 0, 0); + if (sg_count > 1) + sync_needed = true; + } +@@ -1828,7 +1839,8 @@ static int common_nonsnoop_hash(struct t + talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]); + + if (is_sec1 && req_ctx->nbuf && length) { +- struct talitos_desc *desc2 = desc + 1; ++ struct talitos_desc *desc2 = (struct talitos_desc *) ++ (edesc->buf + edesc->dma_len); + dma_addr_t next_desc; + + memset(desc2, 0, sizeof(*desc2)); +@@ -1849,7 +1861,7 @@ static int common_nonsnoop_hash(struct t + DMA_TO_DEVICE); + copy_talitos_ptr(&desc2->ptr[2], &desc->ptr[2], is_sec1); + sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc, +- &desc2->ptr[3], sg_count, offset, 0); ++ &desc2->ptr[3], sg_count, 0, 0); + if (sg_count > 1) + sync_needed = true; + copy_talitos_ptr(&desc2->ptr[5], &desc->ptr[5], is_sec1); +@@ -1960,7 +1972,6 @@ static int ahash_process_req(struct ahas + struct device *dev = ctx->dev; + struct talitos_private *priv = dev_get_drvdata(dev); + bool is_sec1 = has_ftr_sec1(priv); +- int offset = 0; + u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx]; + + if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) { +@@ -2000,6 +2011,8 @@ static int ahash_process_req(struct ahas + sg_chain(req_ctx->bufsl, 2, areq->src); + req_ctx->psrc = req_ctx->bufsl; + } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) { ++ int offset; ++ + if (nbytes_to_hash > blocksize) + offset = blocksize - req_ctx->nbuf; + else +@@ -2012,7 +2025,8 @@ static int ahash_process_req(struct ahas + sg_copy_to_buffer(areq->src, nents, + ctx_buf + req_ctx->nbuf, offset); + req_ctx->nbuf += offset; +- req_ctx->psrc = areq->src; ++ req_ctx->psrc = scatterwalk_ffwd(req_ctx->bufsl, areq->src, ++ offset); + } else + req_ctx->psrc = areq->src; + +@@ -2052,8 +2066,7 @@ static int ahash_process_req(struct ahas + if (ctx->keylen && (req_ctx->first || req_ctx->last)) + edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC; + +- return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, offset, +- ahash_done); ++ return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, ahash_done); + } + + static int ahash_update(struct ahash_request *areq) diff --git a/queue-5.1/crypto-talitos-move-struct-talitos_edesc-into-talitos.h.patch b/queue-5.1/crypto-talitos-move-struct-talitos_edesc-into-talitos.h.patch new file mode 100644 index 00000000000..808396d4b8c --- /dev/null +++ b/queue-5.1/crypto-talitos-move-struct-talitos_edesc-into-talitos.h.patch @@ -0,0 +1,103 @@ +From d44769e4ccb636e8238adbc151f25467a536711b Mon Sep 17 00:00:00 2001 +From: Christophe Leroy +Date: Mon, 24 Jun 2019 07:20:15 +0000 +Subject: crypto: talitos - move struct talitos_edesc into talitos.h + +From: Christophe Leroy + +commit d44769e4ccb636e8238adbc151f25467a536711b upstream. + +Moves struct talitos_edesc into talitos.h so that it can be used +from any place in talitos.c + +It will be required for next patch ("crypto: talitos - fix hash +on SEC1") + +Signed-off-by: Christophe Leroy +Cc: stable@vger.kernel.org +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/talitos.c | 30 ------------------------------ + drivers/crypto/talitos.h | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+), 30 deletions(-) + +--- a/drivers/crypto/talitos.c ++++ b/drivers/crypto/talitos.c +@@ -913,36 +913,6 @@ badkey: + return -EINVAL; + } + +-/* +- * talitos_edesc - s/w-extended descriptor +- * @src_nents: number of segments in input scatterlist +- * @dst_nents: number of segments in output scatterlist +- * @icv_ool: whether ICV is out-of-line +- * @iv_dma: dma address of iv for checking continuity and link table +- * @dma_len: length of dma mapped link_tbl space +- * @dma_link_tbl: bus physical address of link_tbl/buf +- * @desc: h/w descriptor +- * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2) +- * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1) +- * +- * if decrypting (with authcheck), or either one of src_nents or dst_nents +- * is greater than 1, an integrity check value is concatenated to the end +- * of link_tbl data +- */ +-struct talitos_edesc { +- int src_nents; +- int dst_nents; +- bool icv_ool; +- dma_addr_t iv_dma; +- int dma_len; +- dma_addr_t dma_link_tbl; +- struct talitos_desc desc; +- union { +- struct talitos_ptr link_tbl[0]; +- u8 buf[0]; +- }; +-}; +- + static void talitos_sg_unmap(struct device *dev, + struct talitos_edesc *edesc, + struct scatterlist *src, +--- a/drivers/crypto/talitos.h ++++ b/drivers/crypto/talitos.h +@@ -65,6 +65,36 @@ struct talitos_desc { + + #define TALITOS_DESC_SIZE (sizeof(struct talitos_desc) - sizeof(__be32)) + ++/* ++ * talitos_edesc - s/w-extended descriptor ++ * @src_nents: number of segments in input scatterlist ++ * @dst_nents: number of segments in output scatterlist ++ * @icv_ool: whether ICV is out-of-line ++ * @iv_dma: dma address of iv for checking continuity and link table ++ * @dma_len: length of dma mapped link_tbl space ++ * @dma_link_tbl: bus physical address of link_tbl/buf ++ * @desc: h/w descriptor ++ * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2) ++ * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1) ++ * ++ * if decrypting (with authcheck), or either one of src_nents or dst_nents ++ * is greater than 1, an integrity check value is concatenated to the end ++ * of link_tbl data ++ */ ++struct talitos_edesc { ++ int src_nents; ++ int dst_nents; ++ bool icv_ool; ++ dma_addr_t iv_dma; ++ int dma_len; ++ dma_addr_t dma_link_tbl; ++ struct talitos_desc desc; ++ union { ++ struct talitos_ptr link_tbl[0]; ++ u8 buf[0]; ++ }; ++}; ++ + /** + * talitos_request - descriptor submission request + * @desc: descriptor pointer (kernel virtual) diff --git a/queue-5.1/s390-fix-stfle-zero-padding.patch b/queue-5.1/s390-fix-stfle-zero-padding.patch new file mode 100644 index 00000000000..b2b9cb73707 --- /dev/null +++ b/queue-5.1/s390-fix-stfle-zero-padding.patch @@ -0,0 +1,83 @@ +From 4f18d869ffd056c7858f3d617c71345cf19be008 Mon Sep 17 00:00:00 2001 +From: Heiko Carstens +Date: Mon, 17 Jun 2019 14:02:41 +0200 +Subject: s390: fix stfle zero padding + +From: Heiko Carstens + +commit 4f18d869ffd056c7858f3d617c71345cf19be008 upstream. + +The stfle inline assembly returns the number of double words written +(condition code 0) or the double words it would have written +(condition code 3), if the memory array it got as parameter would have +been large enough. + +The current stfle implementation assumes that the array is always +large enough and clears those parts of the array that have not been +written to with a subsequent memset call. + +If however the array is not large enough memset will get a negative +length parameter, which means that memset clears memory until it gets +an exception and the kernel crashes. + +To fix this simply limit the maximum length. Move also the inline +assembly to an extra function to avoid clobbering of register 0, which +might happen because of the added min_t invocation together with code +instrumentation. + +The bug was introduced with commit 14375bc4eb8d ("[S390] cleanup +facility list handling") but was rather harmless, since it would only +write to a rather large array. It became a potential problem with +commit 3ab121ab1866 ("[S390] kernel: Add z/VM LGR detection"). Since +then it writes to an array with only four double words, while some +machines already deliver three double words. As soon as machines have +a facility bit within the fifth double a crash on IPL would happen. + +Fixes: 14375bc4eb8d ("[S390] cleanup facility list handling") +Cc: # v2.6.37+ +Reviewed-by: Vasily Gorbik +Signed-off-by: Heiko Carstens +Signed-off-by: Vasily Gorbik +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/include/asm/facility.h | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/arch/s390/include/asm/facility.h ++++ b/arch/s390/include/asm/facility.h +@@ -59,6 +59,18 @@ static inline int test_facility(unsigned + return __test_facility(nr, &S390_lowcore.stfle_fac_list); + } + ++static inline unsigned long __stfle_asm(u64 *stfle_fac_list, int size) ++{ ++ register unsigned long reg0 asm("0") = size - 1; ++ ++ asm volatile( ++ ".insn s,0xb2b00000,0(%1)" /* stfle */ ++ : "+d" (reg0) ++ : "a" (stfle_fac_list) ++ : "memory", "cc"); ++ return reg0; ++} ++ + /** + * stfle - Store facility list extended + * @stfle_fac_list: array where facility list can be stored +@@ -75,13 +87,8 @@ static inline void __stfle(u64 *stfle_fa + memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); + if (S390_lowcore.stfl_fac_list & 0x01000000) { + /* More facility bits available with stfle */ +- register unsigned long reg0 asm("0") = size - 1; +- +- asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */ +- : "+d" (reg0) +- : "a" (stfle_fac_list) +- : "memory", "cc"); +- nr = (reg0 + 1) * 8; /* # bytes stored by stfle */ ++ nr = __stfle_asm(stfle_fac_list, size); ++ nr = min_t(unsigned long, (nr + 1) * 8, size * 8); + } + memset((char *) stfle_fac_list + nr, 0, size * 8 - nr); + } diff --git a/queue-5.1/s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch b/queue-5.1/s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch new file mode 100644 index 00000000000..d5054f525e8 --- /dev/null +++ b/queue-5.1/s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch @@ -0,0 +1,37 @@ +From ac6639cd3db607d386616487902b4cc1850a7be5 Mon Sep 17 00:00:00 2001 +From: Julian Wiedmann +Date: Tue, 18 Jun 2019 13:12:20 +0200 +Subject: s390/qdio: don't touch the dsci in tiqdio_add_input_queues() + +From: Julian Wiedmann + +commit ac6639cd3db607d386616487902b4cc1850a7be5 upstream. + +Current code sets the dsci to 0x00000080. Which doesn't make any sense, +as the indicator area is located in the _left-most_ byte. + +Worse: if the dsci is the _shared_ indicator, this potentially clears +the indication of activity for a _different_ device. +tiqdio_thinint_handler() will then have no reason to call that device's +IRQ handler, and the device ends up stalling. + +Fixes: d0c9d4a89fff ("[S390] qdio: set correct bit in dsci") +Cc: +Signed-off-by: Julian Wiedmann +Signed-off-by: Vasily Gorbik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/s390/cio/qdio_thinint.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/s390/cio/qdio_thinint.c ++++ b/drivers/s390/cio/qdio_thinint.c +@@ -79,7 +79,6 @@ void tiqdio_add_input_queues(struct qdio + mutex_lock(&tiq_list_lock); + list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list); + mutex_unlock(&tiq_list_lock); +- xchg(irq_ptr->dsci, 1 << 7); + } + + void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr) diff --git a/queue-5.1/s390-qdio-re-initialize-tiqdio-list-entries.patch b/queue-5.1/s390-qdio-re-initialize-tiqdio-list-entries.patch new file mode 100644 index 00000000000..09647875a80 --- /dev/null +++ b/queue-5.1/s390-qdio-re-initialize-tiqdio-list-entries.patch @@ -0,0 +1,77 @@ +From e54e4785cb5cb4896cf4285964aeef2125612fb2 Mon Sep 17 00:00:00 2001 +From: Julian Wiedmann +Date: Tue, 18 Jun 2019 11:25:59 +0200 +Subject: s390/qdio: (re-)initialize tiqdio list entries + +From: Julian Wiedmann + +commit e54e4785cb5cb4896cf4285964aeef2125612fb2 upstream. + +When tiqdio_remove_input_queues() removes a queue from the tiq_list as +part of qdio_shutdown(), it doesn't re-initialize the queue's list entry +and the prev/next pointers go stale. + +If a subsequent qdio_establish() fails while sending the ESTABLISH cmd, +it calls qdio_shutdown() again in QDIO_IRQ_STATE_ERR state and +tiqdio_remove_input_queues() will attempt to remove the queue entry a +second time. This dereferences the stale pointers, and bad things ensue. +Fix this by re-initializing the list entry after removing it from the +list. + +For good practice also initialize the list entry when the queue is first +allocated, and remove the quirky checks that papered over this omission. +Note that prior to +commit e521813468f7 ("s390/qdio: fix access to uninitialized qdio_q fields"), +these checks were bogus anyway. + +setup_queues_misc() clears the whole queue struct, and thus needs to +re-init the prev/next pointers as well. + +Fixes: 779e6e1c724d ("[S390] qdio: new qdio driver.") +Cc: +Signed-off-by: Julian Wiedmann +Signed-off-by: Vasily Gorbik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/s390/cio/qdio_setup.c | 2 ++ + drivers/s390/cio/qdio_thinint.c | 4 ++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -150,6 +150,7 @@ static int __qdio_allocate_qs(struct qdi + return -ENOMEM; + } + irq_ptr_qs[i] = q; ++ INIT_LIST_HEAD(&q->entry); + } + return 0; + } +@@ -178,6 +179,7 @@ static void setup_queues_misc(struct qdi + q->mask = 1 << (31 - i); + q->nr = i; + q->handler = handler; ++ INIT_LIST_HEAD(&q->entry); + } + + static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, +--- a/drivers/s390/cio/qdio_thinint.c ++++ b/drivers/s390/cio/qdio_thinint.c +@@ -87,14 +87,14 @@ void tiqdio_remove_input_queues(struct q + struct qdio_q *q; + + q = irq_ptr->input_qs[0]; +- /* if establish triggered an error */ +- if (!q || !q->entry.prev || !q->entry.next) ++ if (!q) + return; + + mutex_lock(&tiq_list_lock); + list_del_rcu(&q->entry); + mutex_unlock(&tiq_list_lock); + synchronize_rcu(); ++ INIT_LIST_HEAD(&q->entry); + } + + static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq_ptr) diff --git a/queue-5.1/series b/queue-5.1/series index 0d2ab38351f..594193617d1 100644 --- a/queue-5.1/series +++ b/queue-5.1/series @@ -44,3 +44,10 @@ genirq-add-optional-hardware-synchronization-for-shutdown.patch x86-ioapic-implement-irq_get_irqchip_state-callback.patch x86-irq-handle-spurious-interrupt-after-shutdown-gracefully.patch x86-irq-seperate-unused-system-vectors-from-spurious-entry-again.patch +arc-hide-unused-function-unw_hdr_alloc.patch +s390-fix-stfle-zero-padding.patch +s390-qdio-re-initialize-tiqdio-list-entries.patch +s390-qdio-don-t-touch-the-dsci-in-tiqdio_add_input_queues.patch +crypto-talitos-move-struct-talitos_edesc-into-talitos.h.patch +crypto-talitos-fix-hash-on-sec1.patch +crypto-nx-set-receive-window-credits-to-max-number-of-crbs-in-rxfifo.patch -- 2.47.2