--- /dev/null
+From 1d87b88ba26eabd4745e158ecfd87c93a9b51dc2 Mon Sep 17 00:00:00 2001
+From: Szymon Janc <szymon.janc@codecoup.pl>
+Date: Wed, 19 Jun 2019 00:47:47 +0200
+Subject: Bluetooth: Add SMP workaround Microsoft Surface Precision Mouse bug
+
+From: Szymon Janc <szymon.janc@codecoup.pl>
+
+commit 1d87b88ba26eabd4745e158ecfd87c93a9b51dc2 upstream.
+
+Microsoft Surface Precision Mouse provides bogus identity address when
+pairing. It connects with Static Random address but provides Public
+Address in SMP Identity Address Information PDU. Address has same
+value but type is different. Workaround this by dropping IRK if ID
+address discrepancy is detected.
+
+> HCI Event: LE Meta Event (0x3e) plen 19
+ LE Connection Complete (0x01)
+ Status: Success (0x00)
+ Handle: 75
+ Role: Master (0x00)
+ Peer address type: Random (0x01)
+ Peer address: E0:52:33:93:3B:21 (Static)
+ Connection interval: 50.00 msec (0x0028)
+ Connection latency: 0 (0x0000)
+ Supervision timeout: 420 msec (0x002a)
+ Master clock accuracy: 0x00
+
+....
+
+> ACL Data RX: Handle 75 flags 0x02 dlen 12
+ SMP: Identity Address Information (0x09) len 7
+ Address type: Public (0x00)
+ Address: E0:52:33:93:3B:21
+
+Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
+Tested-by: Maarten Fonville <maarten.fonville@gmail.com>
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199461
+Cc: stable@vger.kernel.org
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/bluetooth/smp.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -2514,6 +2514,19 @@ static int smp_cmd_ident_addr_info(struc
+ goto distribute;
+ }
+
++ /* Drop IRK if peer is using identity address during pairing but is
++ * providing different address as identity information.
++ *
++ * Microsoft Surface Precision Mouse is known to have this bug.
++ */
++ if (hci_is_identity_address(&hcon->dst, hcon->dst_type) &&
++ (bacmp(&info->bdaddr, &hcon->dst) ||
++ info->addr_type != hcon->dst_type)) {
++ bt_dev_err(hcon->hdev,
++ "ignoring IRK with invalid identity address");
++ goto distribute;
++ }
++
+ bacpy(&smp->id_addr, &info->bdaddr);
+ smp->id_addr_type = info->addr_type;
+
--- /dev/null
+From 7fa0a1da3dadfd9216df7745a1331fdaa0940d1c Mon Sep 17 00:00:00 2001
+From: Jan Harkes <jaharkes@cs.cmu.edu>
+Date: Tue, 16 Jul 2019 16:28:04 -0700
+Subject: coda: pass the host file in vma->vm_file on mmap
+
+From: Jan Harkes <jaharkes@cs.cmu.edu>
+
+commit 7fa0a1da3dadfd9216df7745a1331fdaa0940d1c upstream.
+
+Patch series "Coda updates".
+
+The following patch series is a collection of various fixes for Coda,
+most of which were collected from linux-fsdevel or linux-kernel but
+which have as yet not found their way upstream.
+
+This patch (of 22):
+
+Various file systems expect that vma->vm_file points at their own file
+handle, several use file_inode(vma->vm_file) to get at their inode or
+use vma->vm_file->private_data. However the way Coda wrapped mmap on a
+host file broke this assumption, vm_file was still pointing at the Coda
+file and the host file systems would scribble over Coda's inode and
+private file data.
+
+This patch fixes the incorrect expectation and wraps vm_ops->open and
+vm_ops->close to allow Coda to track when the vm_area_struct is
+destroyed so we still release the reference on the Coda file handle at
+the right time.
+
+[This patch differs from the original upstream patch because older stable
+ kernels do not have the call_mmap vfs helper so we call f_ops->mmap
+ directly.]
+
+Link: http://lkml.kernel.org/r/0e850c6e59c0b147dc2dcd51a3af004c948c3697.1558117389.git.jaharkes@cs.cmu.edu
+Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Colin Ian King <colin.king@canonical.com>
+Cc: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: David Howells <dhowells@redhat.com>
+Cc: Fabian Frederick <fabf@skynet.be>
+Cc: Mikko Rapeli <mikko.rapeli@iki.fi>
+Cc: Sam Protsenko <semen.protsenko@linaro.org>
+Cc: Yann Droneaud <ydroneaud@opteya.com>
+Cc: Zhouyang Jia <jiazhouyang09@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/coda/file.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 68 insertions(+), 1 deletion(-)
+
+--- a/fs/coda/file.c
++++ b/fs/coda/file.c
+@@ -60,6 +60,41 @@ coda_file_write_iter(struct kiocb *iocb,
+ return ret;
+ }
+
++struct coda_vm_ops {
++ atomic_t refcnt;
++ struct file *coda_file;
++ const struct vm_operations_struct *host_vm_ops;
++ struct vm_operations_struct vm_ops;
++};
++
++static void
++coda_vm_open(struct vm_area_struct *vma)
++{
++ struct coda_vm_ops *cvm_ops =
++ container_of(vma->vm_ops, struct coda_vm_ops, vm_ops);
++
++ atomic_inc(&cvm_ops->refcnt);
++
++ if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->open)
++ cvm_ops->host_vm_ops->open(vma);
++}
++
++static void
++coda_vm_close(struct vm_area_struct *vma)
++{
++ struct coda_vm_ops *cvm_ops =
++ container_of(vma->vm_ops, struct coda_vm_ops, vm_ops);
++
++ if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->close)
++ cvm_ops->host_vm_ops->close(vma);
++
++ if (atomic_dec_and_test(&cvm_ops->refcnt)) {
++ vma->vm_ops = cvm_ops->host_vm_ops;
++ fput(cvm_ops->coda_file);
++ kfree(cvm_ops);
++ }
++}
++
+ static int
+ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
+ {
+@@ -67,6 +102,8 @@ coda_file_mmap(struct file *coda_file, s
+ struct coda_inode_info *cii;
+ struct file *host_file;
+ struct inode *coda_inode, *host_inode;
++ struct coda_vm_ops *cvm_ops;
++ int ret;
+
+ cfi = CODA_FTOC(coda_file);
+ BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+@@ -75,6 +112,13 @@ coda_file_mmap(struct file *coda_file, s
+ if (!host_file->f_op->mmap)
+ return -ENODEV;
+
++ if (WARN_ON(coda_file != vma->vm_file))
++ return -EIO;
++
++ cvm_ops = kmalloc(sizeof(struct coda_vm_ops), GFP_KERNEL);
++ if (!cvm_ops)
++ return -ENOMEM;
++
+ coda_inode = file_inode(coda_file);
+ host_inode = file_inode(host_file);
+
+@@ -88,6 +132,7 @@ coda_file_mmap(struct file *coda_file, s
+ * the container file on us! */
+ else if (coda_inode->i_mapping != host_inode->i_mapping) {
+ spin_unlock(&cii->c_lock);
++ kfree(cvm_ops);
+ return -EBUSY;
+ }
+
+@@ -96,7 +141,29 @@ coda_file_mmap(struct file *coda_file, s
+ cfi->cfi_mapcount++;
+ spin_unlock(&cii->c_lock);
+
+- return host_file->f_op->mmap(host_file, vma);
++ vma->vm_file = get_file(host_file);
++ ret = host_file->f_op->mmap(host_file, vma);
++
++ if (ret) {
++ /* if call_mmap fails, our caller will put coda_file so we
++ * should drop the reference to the host_file that we got.
++ */
++ fput(host_file);
++ kfree(cvm_ops);
++ } else {
++ /* here we add redirects for the open/close vm_operations */
++ cvm_ops->host_vm_ops = vma->vm_ops;
++ if (vma->vm_ops)
++ cvm_ops->vm_ops = *vma->vm_ops;
++
++ cvm_ops->vm_ops.open = coda_vm_open;
++ cvm_ops->vm_ops.close = coda_vm_close;
++ cvm_ops->coda_file = coda_file;
++ atomic_set(&cvm_ops->refcnt, 1);
++
++ vma->vm_ops = &cvm_ops->vm_ops;
++ }
++ return ret;
+ }
+
+ int coda_open(struct inode *coda_inode, struct file *coda_file)
--- /dev/null
+From ed527b13d800dd515a9e6c582f0a73eca65b2e1b Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Fri, 31 May 2019 10:13:06 +0200
+Subject: crypto: caam - limit output IV to CBC to work around CTR mode DMA issue
+
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit ed527b13d800dd515a9e6c582f0a73eca65b2e1b upstream.
+
+The CAAM driver currently violates an undocumented and slightly
+controversial requirement imposed by the crypto stack that a buffer
+referred to by the request structure via its virtual address may not
+be modified while any scatterlists passed via the same request
+structure are mapped for inbound DMA.
+
+This may result in errors like
+
+ alg: aead: decryption failed on test 1 for gcm_base(ctr-aes-caam,ghash-generic): ret=74
+ alg: aead: Failed to load transform for gcm(aes): -2
+
+on non-cache coherent systems, due to the fact that the GCM driver
+passes an IV buffer by virtual address which shares a cacheline with
+the auth_tag buffer passed via a scatterlist, resulting in corruption
+of the auth_tag when the IV is updated while the DMA mapping is live.
+
+Since the IV that is returned to the caller is only valid for CBC mode,
+and given that the in-kernel users of CBC (such as CTS) don't trigger the
+same issue as the GCM driver, let's just disable the output IV generation
+for all modes except CBC for the time being.
+
+Fixes: 854b06f76879 ("crypto: caam - properly set IV after {en,de}crypt")
+Cc: Horia Geanta <horia.geanta@nxp.com>
+Cc: Iuliana Prodan <iuliana.prodan@nxp.com>
+Reported-by: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Reviewed-by: Horia Geanta <horia.geanta@nxp.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+[ Horia: backported to 4.9 ]
+Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/caam/caamalg.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/crypto/caam/caamalg.c
++++ b/drivers/crypto/caam/caamalg.c
+@@ -2015,6 +2015,7 @@ static void ablkcipher_encrypt_done(stru
+ struct ablkcipher_request *req = context;
+ struct ablkcipher_edesc *edesc;
+ struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
++ struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
+ int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
+
+ #ifdef DEBUG
+@@ -2040,10 +2041,11 @@ static void ablkcipher_encrypt_done(stru
+
+ /*
+ * The crypto API expects us to set the IV (req->info) to the last
+- * ciphertext block. This is used e.g. by the CTS mode.
++ * ciphertext block when running in CBC mode.
+ */
+- scatterwalk_map_and_copy(req->info, req->dst, req->nbytes - ivsize,
+- ivsize, 0);
++ if ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == OP_ALG_AAI_CBC)
++ scatterwalk_map_and_copy(req->info, req->dst, req->nbytes -
++ ivsize, ivsize, 0);
+
+ kfree(edesc);
+
+@@ -2056,6 +2058,7 @@ static void ablkcipher_decrypt_done(stru
+ struct ablkcipher_request *req = context;
+ struct ablkcipher_edesc *edesc;
+ struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
++ struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
+ int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
+
+ #ifdef DEBUG
+@@ -2080,10 +2083,11 @@ static void ablkcipher_decrypt_done(stru
+
+ /*
+ * The crypto API expects us to set the IV (req->info) to the last
+- * ciphertext block.
++ * ciphertext block when running in CBC mode.
+ */
+- scatterwalk_map_and_copy(req->info, req->src, req->nbytes - ivsize,
+- ivsize, 0);
++ if ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == OP_ALG_AAI_CBC)
++ scatterwalk_map_and_copy(req->info, req->src, req->nbytes -
++ ivsize, ivsize, 0);
+
+ kfree(edesc);
+
--- /dev/null
+From 52393d617af7b554f03531e6756facf2ea687d2e Mon Sep 17 00:00:00 2001
+From: "Hook, Gary" <Gary.Hook@amd.com>
+Date: Thu, 27 Jun 2019 16:16:23 +0000
+Subject: crypto: ccp - Validate the the error value used to index error messages
+
+From: Hook, Gary <Gary.Hook@amd.com>
+
+commit 52393d617af7b554f03531e6756facf2ea687d2e upstream.
+
+The error code read from the queue status register is only 6 bits wide,
+but we need to verify its value is within range before indexing the error
+messages.
+
+Fixes: 81422badb3907 ("crypto: ccp - Make syslog errors human-readable")
+Cc: <stable@vger.kernel.org>
+Reported-by: Cfir Cohen <cfir@google.com>
+Signed-off-by: Gary R Hook <gary.hook@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/crypto/ccp/ccp-dev.c | 102 ++++++++++++++++++++++---------------------
+ drivers/crypto/ccp/ccp-dev.h | 2
+ 2 files changed, 55 insertions(+), 49 deletions(-)
+
+--- a/drivers/crypto/ccp/ccp-dev.c
++++ b/drivers/crypto/ccp/ccp-dev.c
+@@ -40,57 +40,63 @@ struct ccp_tasklet_data {
+ struct ccp_cmd *cmd;
+ };
+
+-/* Human-readable error strings */
+-char *ccp_error_codes[] = {
+- "",
+- "ERR 01: ILLEGAL_ENGINE",
+- "ERR 02: ILLEGAL_KEY_ID",
+- "ERR 03: ILLEGAL_FUNCTION_TYPE",
+- "ERR 04: ILLEGAL_FUNCTION_MODE",
+- "ERR 05: ILLEGAL_FUNCTION_ENCRYPT",
+- "ERR 06: ILLEGAL_FUNCTION_SIZE",
+- "ERR 07: Zlib_MISSING_INIT_EOM",
+- "ERR 08: ILLEGAL_FUNCTION_RSVD",
+- "ERR 09: ILLEGAL_BUFFER_LENGTH",
+- "ERR 10: VLSB_FAULT",
+- "ERR 11: ILLEGAL_MEM_ADDR",
+- "ERR 12: ILLEGAL_MEM_SEL",
+- "ERR 13: ILLEGAL_CONTEXT_ID",
+- "ERR 14: ILLEGAL_KEY_ADDR",
+- "ERR 15: 0xF Reserved",
+- "ERR 16: Zlib_ILLEGAL_MULTI_QUEUE",
+- "ERR 17: Zlib_ILLEGAL_JOBID_CHANGE",
+- "ERR 18: CMD_TIMEOUT",
+- "ERR 19: IDMA0_AXI_SLVERR",
+- "ERR 20: IDMA0_AXI_DECERR",
+- "ERR 21: 0x15 Reserved",
+- "ERR 22: IDMA1_AXI_SLAVE_FAULT",
+- "ERR 23: IDMA1_AIXI_DECERR",
+- "ERR 24: 0x18 Reserved",
+- "ERR 25: ZLIBVHB_AXI_SLVERR",
+- "ERR 26: ZLIBVHB_AXI_DECERR",
+- "ERR 27: 0x1B Reserved",
+- "ERR 27: ZLIB_UNEXPECTED_EOM",
+- "ERR 27: ZLIB_EXTRA_DATA",
+- "ERR 30: ZLIB_BTYPE",
+- "ERR 31: ZLIB_UNDEFINED_SYMBOL",
+- "ERR 32: ZLIB_UNDEFINED_DISTANCE_S",
+- "ERR 33: ZLIB_CODE_LENGTH_SYMBOL",
+- "ERR 34: ZLIB _VHB_ILLEGAL_FETCH",
+- "ERR 35: ZLIB_UNCOMPRESSED_LEN",
+- "ERR 36: ZLIB_LIMIT_REACHED",
+- "ERR 37: ZLIB_CHECKSUM_MISMATCH0",
+- "ERR 38: ODMA0_AXI_SLVERR",
+- "ERR 39: ODMA0_AXI_DECERR",
+- "ERR 40: 0x28 Reserved",
+- "ERR 41: ODMA1_AXI_SLVERR",
+- "ERR 42: ODMA1_AXI_DECERR",
+- "ERR 43: LSB_PARITY_ERR",
++ /* Human-readable error strings */
++#define CCP_MAX_ERROR_CODE 64
++ static char *ccp_error_codes[] = {
++ "",
++ "ILLEGAL_ENGINE",
++ "ILLEGAL_KEY_ID",
++ "ILLEGAL_FUNCTION_TYPE",
++ "ILLEGAL_FUNCTION_MODE",
++ "ILLEGAL_FUNCTION_ENCRYPT",
++ "ILLEGAL_FUNCTION_SIZE",
++ "Zlib_MISSING_INIT_EOM",
++ "ILLEGAL_FUNCTION_RSVD",
++ "ILLEGAL_BUFFER_LENGTH",
++ "VLSB_FAULT",
++ "ILLEGAL_MEM_ADDR",
++ "ILLEGAL_MEM_SEL",
++ "ILLEGAL_CONTEXT_ID",
++ "ILLEGAL_KEY_ADDR",
++ "0xF Reserved",
++ "Zlib_ILLEGAL_MULTI_QUEUE",
++ "Zlib_ILLEGAL_JOBID_CHANGE",
++ "CMD_TIMEOUT",
++ "IDMA0_AXI_SLVERR",
++ "IDMA0_AXI_DECERR",
++ "0x15 Reserved",
++ "IDMA1_AXI_SLAVE_FAULT",
++ "IDMA1_AIXI_DECERR",
++ "0x18 Reserved",
++ "ZLIBVHB_AXI_SLVERR",
++ "ZLIBVHB_AXI_DECERR",
++ "0x1B Reserved",
++ "ZLIB_UNEXPECTED_EOM",
++ "ZLIB_EXTRA_DATA",
++ "ZLIB_BTYPE",
++ "ZLIB_UNDEFINED_SYMBOL",
++ "ZLIB_UNDEFINED_DISTANCE_S",
++ "ZLIB_CODE_LENGTH_SYMBOL",
++ "ZLIB _VHB_ILLEGAL_FETCH",
++ "ZLIB_UNCOMPRESSED_LEN",
++ "ZLIB_LIMIT_REACHED",
++ "ZLIB_CHECKSUM_MISMATCH0",
++ "ODMA0_AXI_SLVERR",
++ "ODMA0_AXI_DECERR",
++ "0x28 Reserved",
++ "ODMA1_AXI_SLVERR",
++ "ODMA1_AXI_DECERR",
+ };
+
+-void ccp_log_error(struct ccp_device *d, int e)
++void ccp_log_error(struct ccp_device *d, unsigned int e)
+ {
+- dev_err(d->dev, "CCP error: %s (0x%x)\n", ccp_error_codes[e], e);
++ if (WARN_ON(e >= CCP_MAX_ERROR_CODE))
++ return;
++
++ if (e < ARRAY_SIZE(ccp_error_codes))
++ dev_err(d->dev, "CCP error %d: %s\n", e, ccp_error_codes[e]);
++ else
++ dev_err(d->dev, "CCP error %d: Unknown Error\n", e);
+ }
+
+ /* List of CCPs, CCP count, read-write access lock, and access functions
+--- a/drivers/crypto/ccp/ccp-dev.h
++++ b/drivers/crypto/ccp/ccp-dev.h
+@@ -607,7 +607,7 @@ void ccp_platform_exit(void);
+ void ccp_add_device(struct ccp_device *ccp);
+ void ccp_del_device(struct ccp_device *ccp);
+
+-extern void ccp_log_error(struct ccp_device *, int);
++extern void ccp_log_error(struct ccp_device *, unsigned int);
+
+ struct ccp_device *ccp_alloc_struct(struct device *dev);
+ bool ccp_queues_suspended(struct ccp_device *ccp);
--- /dev/null
+From 0bdf8a8245fdea6f075a5fede833a5fcf1b3466c Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 4 Jul 2018 12:35:56 +0300
+Subject: eCryptfs: fix a couple type promotion bugs
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 0bdf8a8245fdea6f075a5fede833a5fcf1b3466c upstream.
+
+ECRYPTFS_SIZE_AND_MARKER_BYTES is type size_t, so if "rc" is negative
+that gets type promoted to a high positive value and treated as success.
+
+Fixes: 778aeb42a708 ("eCryptfs: Cleanup and optimize ecryptfs_lookup_interpose()")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+[tyhicks: Use "if/else if" rather than "if/if"]
+Cc: stable@vger.kernel.org
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ecryptfs/crypto.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -1034,8 +1034,10 @@ int ecryptfs_read_and_validate_header_re
+
+ rc = ecryptfs_read_lower(file_size, 0, ECRYPTFS_SIZE_AND_MARKER_BYTES,
+ inode);
+- if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES)
+- return rc >= 0 ? -EINVAL : rc;
++ if (rc < 0)
++ return rc;
++ else if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES)
++ return -EINVAL;
+ rc = ecryptfs_validate_marker(marker);
+ if (!rc)
+ ecryptfs_i_size_init(file_size, inode);
+@@ -1397,8 +1399,10 @@ int ecryptfs_read_and_validate_xattr_reg
+ ecryptfs_inode_to_lower(inode),
+ ECRYPTFS_XATTR_NAME, file_size,
+ ECRYPTFS_SIZE_AND_MARKER_BYTES);
+- if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES)
+- return rc >= 0 ? -EINVAL : rc;
++ if (rc < 0)
++ return rc;
++ else if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES)
++ return -EINVAL;
+ rc = ecryptfs_validate_marker(marker);
+ if (!rc)
+ ecryptfs_i_size_init(file_size, inode);
--- /dev/null
+From 3d1f62c686acdedf5ed9642b763f3808d6a47d1e Mon Sep 17 00:00:00 2001
+From: Steve Longerbeam <slongerbeam@gmail.com>
+Date: Tue, 21 May 2019 18:03:13 -0700
+Subject: gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM
+
+From: Steve Longerbeam <slongerbeam@gmail.com>
+
+commit 3d1f62c686acdedf5ed9642b763f3808d6a47d1e upstream.
+
+The saturation bit was being set at bit 9 in the second 32-bit word
+of the TPMEM CSC. This isn't correct, the saturation bit is bit 42,
+which is bit 10 of the second word.
+
+Fixes: 1aa8ea0d2bd5d ("gpu: ipu-v3: Add Image Converter unit")
+
+Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Cc: stable@vger.kernel.org
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/ipu-v3/ipu-ic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/ipu-v3/ipu-ic.c
++++ b/drivers/gpu/ipu-v3/ipu-ic.c
+@@ -256,7 +256,7 @@ static int init_csc(struct ipu_ic *ic,
+ writel(param, base++);
+
+ param = ((a[0] & 0x1fe0) >> 5) | (params->scale << 8) |
+- (params->sat << 9);
++ (params->sat << 10);
+ writel(param, base++);
+
+ param = ((a[1] & 0x1f) << 27) | ((c[0][1] & 0x1ff) << 18) |
--- /dev/null
+From 918b8646497b5dba6ae82d4a7325f01b258972b9 Mon Sep 17 00:00:00 2001
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Date: Fri, 21 Jun 2019 19:19:29 +0300
+Subject: intel_th: msu: Fix single mode with disabled IOMMU
+
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+
+commit 918b8646497b5dba6ae82d4a7325f01b258972b9 upstream.
+
+Commit 4e0eaf239fb3 ("intel_th: msu: Fix single mode with IOMMU") switched
+the single mode code to use dma mapping pages obtained from the page
+allocator, but with IOMMU disabled, that may lead to using SWIOTLB bounce
+buffers and without additional sync'ing, produces empty trace buffers.
+
+Fix this by using a DMA32 GFP flag to the page allocation in single mode,
+as the device supports full 32-bit DMA addressing.
+
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Fixes: 4e0eaf239fb3 ("intel_th: msu: Fix single mode with IOMMU")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reported-by: Ammy Yi <ammy.yi@intel.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20190621161930.60785-4-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwtracing/intel_th/msu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hwtracing/intel_th/msu.c
++++ b/drivers/hwtracing/intel_th/msu.c
+@@ -638,7 +638,7 @@ static int msc_buffer_contig_alloc(struc
+ goto err_out;
+
+ ret = -ENOMEM;
+- page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
++ page = alloc_pages(GFP_KERNEL | __GFP_ZERO | GFP_DMA32, order);
+ if (!page)
+ goto err_free_sgt;
+
--- /dev/null
+From 34c32fc603311a72cb558e5e337555434f64c27b Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Thu, 4 Jul 2019 03:44:17 +0200
+Subject: parisc: Ensure userspace privilege for ptraced processes in regset functions
+
+From: Helge Deller <deller@gmx.de>
+
+commit 34c32fc603311a72cb558e5e337555434f64c27b upstream.
+
+On parisc the privilege level of a process is stored in the lowest two bits of
+the instruction pointers (IAOQ0 and IAOQ1). On Linux we use privilege level 0
+for the kernel and privilege level 3 for user-space. So userspace should not be
+allowed to modify IAOQ0 or IAOQ1 of a ptraced process to change it's privilege
+level to e.g. 0 to try to gain kernel privileges.
+
+This patch prevents such modifications in the regset support functions by
+always setting the two lowest bits to one (which relates to privilege level 3
+for user-space) if IAOQ0 or IAOQ1 are modified via ptrace regset calls.
+
+Link: https://bugs.gentoo.org/481768
+Cc: <stable@vger.kernel.org> # v4.7+
+Tested-by: Rolf Eike Beer <eike-kernel@sf-tec.de>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/kernel/ptrace.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/parisc/kernel/ptrace.c
++++ b/arch/parisc/kernel/ptrace.c
+@@ -499,7 +499,8 @@ static void set_reg(struct pt_regs *regs
+ return;
+ case RI(iaoq[0]):
+ case RI(iaoq[1]):
+- regs->iaoq[num - RI(iaoq[0])] = val;
++ /* set 2 lowest bits to ensure userspace privilege: */
++ regs->iaoq[num - RI(iaoq[0])] = val | 3;
+ return;
+ case RI(sar): regs->sar = val;
+ return;
--- /dev/null
+From 10835c854685393a921b68f529bf740fa7c9984d Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Tue, 16 Jul 2019 21:43:11 +0200
+Subject: parisc: Fix kernel panic due invalid values in IAOQ0 or IAOQ1
+
+From: Helge Deller <deller@gmx.de>
+
+commit 10835c854685393a921b68f529bf740fa7c9984d upstream.
+
+On parisc the privilege level of a process is stored in the lowest two bits of
+the instruction pointers (IAOQ0 and IAOQ1). On Linux we use privilege level 0
+for the kernel and privilege level 3 for user-space. So userspace should not be
+allowed to modify IAOQ0 or IAOQ1 of a ptraced process to change it's privilege
+level to e.g. 0 to try to gain kernel privileges.
+
+This patch prevents such modifications by always setting the two lowest bits to
+one (which relates to privilege level 3 for user-space) if IAOQ0 or IAOQ1 are
+modified via ptrace calls in the native and compat ptrace paths.
+
+Link: https://bugs.gentoo.org/481768
+Reported-by: Jeroen Roovers <jer@gentoo.org>
+Cc: <stable@vger.kernel.org>
+Tested-by: Rolf Eike Beer <eike-kernel@sf-tec.de>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/kernel/ptrace.c | 28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+--- a/arch/parisc/kernel/ptrace.c
++++ b/arch/parisc/kernel/ptrace.c
+@@ -170,6 +170,9 @@ long arch_ptrace(struct task_struct *chi
+ if ((addr & (sizeof(unsigned long)-1)) ||
+ addr >= sizeof(struct pt_regs))
+ break;
++ if (addr == PT_IAOQ0 || addr == PT_IAOQ1) {
++ data |= 3; /* ensure userspace privilege */
++ }
+ if ((addr >= PT_GR1 && addr <= PT_GR31) ||
+ addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
+ (addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
+@@ -231,16 +234,18 @@ long arch_ptrace(struct task_struct *chi
+
+ static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
+ {
+- if (offset < 0)
+- return sizeof(struct pt_regs);
+- else if (offset <= 32*4) /* gr[0..31] */
+- return offset * 2 + 4;
+- else if (offset <= 32*4+32*8) /* gr[0..31] + fr[0..31] */
+- return offset + 32*4;
+- else if (offset < sizeof(struct pt_regs)/2 + 32*4)
+- return offset * 2 + 4 - 32*8;
++ compat_ulong_t pos;
++
++ if (offset < 32*4) /* gr[0..31] */
++ pos = offset * 2 + 4;
++ else if (offset < 32*4+32*8) /* fr[0] ... fr[31] */
++ pos = (offset - 32*4) + PT_FR0;
++ else if (offset < sizeof(struct pt_regs)/2 + 32*4) /* sr[0] ... ipsw */
++ pos = (offset - 32*4 - 32*8) * 2 + PT_SR0 + 4;
+ else
+- return sizeof(struct pt_regs);
++ pos = sizeof(struct pt_regs);
++
++ return pos;
+ }
+
+ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+@@ -284,9 +289,12 @@ long compat_arch_ptrace(struct task_stru
+ addr = translate_usr_offset(addr);
+ if (addr >= sizeof(struct pt_regs))
+ break;
++ if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) {
++ data |= 3; /* ensure userspace privilege */
++ }
+ if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
+ /* Special case, fp regs are 64 bits anyway */
+- *(__u64 *) ((char *) task_regs(child) + addr) = data;
++ *(__u32 *) ((char *) task_regs(child) + addr) = data;
+ ret = 0;
+ }
+ else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
--- /dev/null
+From e74d2ebdda33b3bdd1826b5b92e9aa45bdf92bb3 Mon Sep 17 00:00:00 2001
+From: Dexuan Cui <decui@microsoft.com>
+Date: Thu, 10 Nov 2016 07:19:52 +0000
+Subject: PCI: hv: Delete the device earlier from hbus->children for hot-remove
+
+From: Dexuan Cui <decui@microsoft.com>
+
+commit e74d2ebdda33b3bdd1826b5b92e9aa45bdf92bb3 upstream.
+
+After we send a PCI_EJECTION_COMPLETE message to the host, the host will
+immediately send us a PCI_BUS_RELATIONS message with
+relations->device_count == 0, so pci_devices_present_work(), running on
+another thread, can find the being-ejected device, mark the
+hpdev->reported_missing to true, and run list_move_tail()/list_del() for
+the device -- this races hv_eject_device_work() -> list_del().
+
+Move the list_del() in hv_eject_device_work() to an earlier place, i.e.,
+before we send PCI_EJECTION_COMPLETE, so later the
+pci_devices_present_work() can't see the device.
+
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Jake Oshins <jakeo@microsoft.com>
+Acked-by: K. Y. Srinivasan <kys@microsoft.com>
+CC: Haiyang Zhang <haiyangz@microsoft.com>
+CC: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/host/pci-hyperv.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/pci/host/pci-hyperv.c
++++ b/drivers/pci/host/pci-hyperv.c
+@@ -1607,6 +1607,10 @@ static void hv_eject_device_work(struct
+ pci_unlock_rescan_remove();
+ }
+
++ spin_lock_irqsave(&hpdev->hbus->device_list_lock, flags);
++ list_del(&hpdev->list_entry);
++ spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags);
++
+ memset(&ctxt, 0, sizeof(ctxt));
+ ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message;
+ ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE;
+@@ -1615,10 +1619,6 @@ static void hv_eject_device_work(struct
+ sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt,
+ VM_PKT_DATA_INBAND, 0);
+
+- spin_lock_irqsave(&hpdev->hbus->device_list_lock, flags);
+- list_del(&hpdev->list_entry);
+- spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags);
+-
+ put_pcichild(hpdev, hv_pcidev_ref_childlist);
+ put_pcichild(hpdev, hv_pcidev_ref_initial);
+ put_pcichild(hpdev, hv_pcidev_ref_pnp);
--- /dev/null
+From 4df591b20b80cb77920953812d894db259d85bd7 Mon Sep 17 00:00:00 2001
+From: Dexuan Cui <decui@microsoft.com>
+Date: Fri, 21 Jun 2019 23:45:23 +0000
+Subject: PCI: hv: Fix a use-after-free bug in hv_eject_device_work()
+
+From: Dexuan Cui <decui@microsoft.com>
+
+commit 4df591b20b80cb77920953812d894db259d85bd7 upstream.
+
+Fix a use-after-free in hv_eject_device_work().
+
+Fixes: 05f151a73ec2 ("PCI: hv: Fix a memory leak in hv_eject_device_work()")
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/pci/host/pci-hyperv.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/drivers/pci/host/pci-hyperv.c
++++ b/drivers/pci/host/pci-hyperv.c
+@@ -1575,6 +1575,7 @@ static void hv_pci_devices_present(struc
+ static void hv_eject_device_work(struct work_struct *work)
+ {
+ struct pci_eject_response *ejct_pkt;
++ struct hv_pcibus_device *hbus;
+ struct hv_pci_dev *hpdev;
+ struct pci_dev *pdev;
+ unsigned long flags;
+@@ -1585,6 +1586,7 @@ static void hv_eject_device_work(struct
+ } ctxt;
+
+ hpdev = container_of(work, struct hv_pci_dev, wrk);
++ hbus = hpdev->hbus;
+
+ if (hpdev->state != hv_pcichild_ejecting) {
+ put_pcichild(hpdev, hv_pcidev_ref_pnp);
+@@ -1598,8 +1600,7 @@ static void hv_eject_device_work(struct
+ * because hbus->pci_bus may not exist yet.
+ */
+ wslot = wslot_to_devfn(hpdev->desc.win_slot.slot);
+- pdev = pci_get_domain_bus_and_slot(hpdev->hbus->sysdata.domain, 0,
+- wslot);
++ pdev = pci_get_domain_bus_and_slot(hbus->sysdata.domain, 0, wslot);
+ if (pdev) {
+ pci_lock_rescan_remove();
+ pci_stop_and_remove_bus_device(pdev);
+@@ -1607,22 +1608,24 @@ static void hv_eject_device_work(struct
+ pci_unlock_rescan_remove();
+ }
+
+- spin_lock_irqsave(&hpdev->hbus->device_list_lock, flags);
++ spin_lock_irqsave(&hbus->device_list_lock, flags);
+ list_del(&hpdev->list_entry);
+- spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags);
++ spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+
+ memset(&ctxt, 0, sizeof(ctxt));
+ ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message;
+ ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE;
+ ejct_pkt->wslot.slot = hpdev->desc.win_slot.slot;
+- vmbus_sendpacket(hpdev->hbus->hdev->channel, ejct_pkt,
++ vmbus_sendpacket(hbus->hdev->channel, ejct_pkt,
+ sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt,
+ VM_PKT_DATA_INBAND, 0);
+
+ put_pcichild(hpdev, hv_pcidev_ref_childlist);
+ put_pcichild(hpdev, hv_pcidev_ref_initial);
+ put_pcichild(hpdev, hv_pcidev_ref_pnp);
+- put_hvpcibus(hpdev->hbus);
++
++ /* hpdev has been freed. Do not use it any more. */
++ put_hvpcibus(hbus);
+ }
+
+ /**
--- /dev/null
+From 6ecb78ef56e08d2119d337ae23cb951a640dc52d Mon Sep 17 00:00:00 2001
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+Date: Mon, 17 Jun 2019 21:42:14 +0000
+Subject: powerpc/32s: fix suspend/resume when IBATs 4-7 are used
+
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+
+commit 6ecb78ef56e08d2119d337ae23cb951a640dc52d upstream.
+
+Previously, only IBAT1 and IBAT2 were used to map kernel linear mem.
+Since commit 63b2bc619565 ("powerpc/mm/32s: Use BATs for
+STRICT_KERNEL_RWX"), we may have all 8 BATs used for mapping
+kernel text. But the suspend/restore functions only save/restore
+BATs 0 to 3, and clears BATs 4 to 7.
+
+Make suspend and restore functions respectively save and reload
+the 8 BATs on CPUs having MMU_FTR_USE_HIGH_BATS feature.
+
+Reported-by: Andreas Schwab <schwab@linux-m68k.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/swsusp_32.S | 73 ++++++++++++++++++++++++++++----
+ arch/powerpc/platforms/powermac/sleep.S | 68 +++++++++++++++++++++++++++--
+ 2 files changed, 128 insertions(+), 13 deletions(-)
+
+--- a/arch/powerpc/kernel/swsusp_32.S
++++ b/arch/powerpc/kernel/swsusp_32.S
+@@ -23,11 +23,19 @@
+ #define SL_IBAT2 0x48
+ #define SL_DBAT3 0x50
+ #define SL_IBAT3 0x58
+-#define SL_TB 0x60
+-#define SL_R2 0x68
+-#define SL_CR 0x6c
+-#define SL_LR 0x70
+-#define SL_R12 0x74 /* r12 to r31 */
++#define SL_DBAT4 0x60
++#define SL_IBAT4 0x68
++#define SL_DBAT5 0x70
++#define SL_IBAT5 0x78
++#define SL_DBAT6 0x80
++#define SL_IBAT6 0x88
++#define SL_DBAT7 0x90
++#define SL_IBAT7 0x98
++#define SL_TB 0xa0
++#define SL_R2 0xa8
++#define SL_CR 0xac
++#define SL_LR 0xb0
++#define SL_R12 0xb4 /* r12 to r31 */
+ #define SL_SIZE (SL_R12 + 80)
+
+ .section .data
+@@ -112,6 +120,41 @@ _GLOBAL(swsusp_arch_suspend)
+ mfibatl r4,3
+ stw r4,SL_IBAT3+4(r11)
+
++BEGIN_MMU_FTR_SECTION
++ mfspr r4,SPRN_DBAT4U
++ stw r4,SL_DBAT4(r11)
++ mfspr r4,SPRN_DBAT4L
++ stw r4,SL_DBAT4+4(r11)
++ mfspr r4,SPRN_DBAT5U
++ stw r4,SL_DBAT5(r11)
++ mfspr r4,SPRN_DBAT5L
++ stw r4,SL_DBAT5+4(r11)
++ mfspr r4,SPRN_DBAT6U
++ stw r4,SL_DBAT6(r11)
++ mfspr r4,SPRN_DBAT6L
++ stw r4,SL_DBAT6+4(r11)
++ mfspr r4,SPRN_DBAT7U
++ stw r4,SL_DBAT7(r11)
++ mfspr r4,SPRN_DBAT7L
++ stw r4,SL_DBAT7+4(r11)
++ mfspr r4,SPRN_IBAT4U
++ stw r4,SL_IBAT4(r11)
++ mfspr r4,SPRN_IBAT4L
++ stw r4,SL_IBAT4+4(r11)
++ mfspr r4,SPRN_IBAT5U
++ stw r4,SL_IBAT5(r11)
++ mfspr r4,SPRN_IBAT5L
++ stw r4,SL_IBAT5+4(r11)
++ mfspr r4,SPRN_IBAT6U
++ stw r4,SL_IBAT6(r11)
++ mfspr r4,SPRN_IBAT6L
++ stw r4,SL_IBAT6+4(r11)
++ mfspr r4,SPRN_IBAT7U
++ stw r4,SL_IBAT7(r11)
++ mfspr r4,SPRN_IBAT7L
++ stw r4,SL_IBAT7+4(r11)
++END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
++
+ #if 0
+ /* Backup various CPU config stuffs */
+ bl __save_cpu_setup
+@@ -277,27 +320,41 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ mtibatu 3,r4
+ lwz r4,SL_IBAT3+4(r11)
+ mtibatl 3,r4
+-#endif
+-
+ BEGIN_MMU_FTR_SECTION
+- li r4,0
++ lwz r4,SL_DBAT4(r11)
+ mtspr SPRN_DBAT4U,r4
++ lwz r4,SL_DBAT4+4(r11)
+ mtspr SPRN_DBAT4L,r4
++ lwz r4,SL_DBAT5(r11)
+ mtspr SPRN_DBAT5U,r4
++ lwz r4,SL_DBAT5+4(r11)
+ mtspr SPRN_DBAT5L,r4
++ lwz r4,SL_DBAT6(r11)
+ mtspr SPRN_DBAT6U,r4
++ lwz r4,SL_DBAT6+4(r11)
+ mtspr SPRN_DBAT6L,r4
++ lwz r4,SL_DBAT7(r11)
+ mtspr SPRN_DBAT7U,r4
++ lwz r4,SL_DBAT7+4(r11)
+ mtspr SPRN_DBAT7L,r4
++ lwz r4,SL_IBAT4(r11)
+ mtspr SPRN_IBAT4U,r4
++ lwz r4,SL_IBAT4+4(r11)
+ mtspr SPRN_IBAT4L,r4
++ lwz r4,SL_IBAT5(r11)
+ mtspr SPRN_IBAT5U,r4
++ lwz r4,SL_IBAT5+4(r11)
+ mtspr SPRN_IBAT5L,r4
++ lwz r4,SL_IBAT6(r11)
+ mtspr SPRN_IBAT6U,r4
++ lwz r4,SL_IBAT6+4(r11)
+ mtspr SPRN_IBAT6L,r4
++ lwz r4,SL_IBAT7(r11)
+ mtspr SPRN_IBAT7U,r4
++ lwz r4,SL_IBAT7+4(r11)
+ mtspr SPRN_IBAT7L,r4
+ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
++#endif
+
+ /* Flush all TLBs */
+ lis r4,0x1000
+--- a/arch/powerpc/platforms/powermac/sleep.S
++++ b/arch/powerpc/platforms/powermac/sleep.S
+@@ -37,10 +37,18 @@
+ #define SL_IBAT2 0x48
+ #define SL_DBAT3 0x50
+ #define SL_IBAT3 0x58
+-#define SL_TB 0x60
+-#define SL_R2 0x68
+-#define SL_CR 0x6c
+-#define SL_R12 0x70 /* r12 to r31 */
++#define SL_DBAT4 0x60
++#define SL_IBAT4 0x68
++#define SL_DBAT5 0x70
++#define SL_IBAT5 0x78
++#define SL_DBAT6 0x80
++#define SL_IBAT6 0x88
++#define SL_DBAT7 0x90
++#define SL_IBAT7 0x98
++#define SL_TB 0xa0
++#define SL_R2 0xa8
++#define SL_CR 0xac
++#define SL_R12 0xb0 /* r12 to r31 */
+ #define SL_SIZE (SL_R12 + 80)
+
+ .section .text
+@@ -125,6 +133,41 @@ _GLOBAL(low_sleep_handler)
+ mfibatl r4,3
+ stw r4,SL_IBAT3+4(r1)
+
++BEGIN_MMU_FTR_SECTION
++ mfspr r4,SPRN_DBAT4U
++ stw r4,SL_DBAT4(r1)
++ mfspr r4,SPRN_DBAT4L
++ stw r4,SL_DBAT4+4(r1)
++ mfspr r4,SPRN_DBAT5U
++ stw r4,SL_DBAT5(r1)
++ mfspr r4,SPRN_DBAT5L
++ stw r4,SL_DBAT5+4(r1)
++ mfspr r4,SPRN_DBAT6U
++ stw r4,SL_DBAT6(r1)
++ mfspr r4,SPRN_DBAT6L
++ stw r4,SL_DBAT6+4(r1)
++ mfspr r4,SPRN_DBAT7U
++ stw r4,SL_DBAT7(r1)
++ mfspr r4,SPRN_DBAT7L
++ stw r4,SL_DBAT7+4(r1)
++ mfspr r4,SPRN_IBAT4U
++ stw r4,SL_IBAT4(r1)
++ mfspr r4,SPRN_IBAT4L
++ stw r4,SL_IBAT4+4(r1)
++ mfspr r4,SPRN_IBAT5U
++ stw r4,SL_IBAT5(r1)
++ mfspr r4,SPRN_IBAT5L
++ stw r4,SL_IBAT5+4(r1)
++ mfspr r4,SPRN_IBAT6U
++ stw r4,SL_IBAT6(r1)
++ mfspr r4,SPRN_IBAT6L
++ stw r4,SL_IBAT6+4(r1)
++ mfspr r4,SPRN_IBAT7U
++ stw r4,SL_IBAT7(r1)
++ mfspr r4,SPRN_IBAT7L
++ stw r4,SL_IBAT7+4(r1)
++END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
++
+ /* Backup various CPU config stuffs */
+ bl __save_cpu_setup
+
+@@ -325,22 +368,37 @@ grackle_wake_up:
+ mtibatl 3,r4
+
+ BEGIN_MMU_FTR_SECTION
+- li r4,0
++ lwz r4,SL_DBAT4(r1)
+ mtspr SPRN_DBAT4U,r4
++ lwz r4,SL_DBAT4+4(r1)
+ mtspr SPRN_DBAT4L,r4
++ lwz r4,SL_DBAT5(r1)
+ mtspr SPRN_DBAT5U,r4
++ lwz r4,SL_DBAT5+4(r1)
+ mtspr SPRN_DBAT5L,r4
++ lwz r4,SL_DBAT6(r1)
+ mtspr SPRN_DBAT6U,r4
++ lwz r4,SL_DBAT6+4(r1)
+ mtspr SPRN_DBAT6L,r4
++ lwz r4,SL_DBAT7(r1)
+ mtspr SPRN_DBAT7U,r4
++ lwz r4,SL_DBAT7+4(r1)
+ mtspr SPRN_DBAT7L,r4
++ lwz r4,SL_IBAT4(r1)
+ mtspr SPRN_IBAT4U,r4
++ lwz r4,SL_IBAT4+4(r1)
+ mtspr SPRN_IBAT4L,r4
++ lwz r4,SL_IBAT5(r1)
+ mtspr SPRN_IBAT5U,r4
++ lwz r4,SL_IBAT5+4(r1)
+ mtspr SPRN_IBAT5L,r4
++ lwz r4,SL_IBAT6(r1)
+ mtspr SPRN_IBAT6U,r4
++ lwz r4,SL_IBAT6+4(r1)
+ mtspr SPRN_IBAT6L,r4
++ lwz r4,SL_IBAT7(r1)
+ mtspr SPRN_IBAT7U,r4
++ lwz r4,SL_IBAT7+4(r1)
+ mtspr SPRN_IBAT7L,r4
+ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
+
--- /dev/null
+From f474c28fbcbe42faca4eb415172c07d76adcb819 Mon Sep 17 00:00:00 2001
+From: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
+Date: Thu, 13 Jun 2019 09:00:14 +0530
+Subject: powerpc/watchpoint: Restore NV GPRs while returning from exception
+
+From: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
+
+commit f474c28fbcbe42faca4eb415172c07d76adcb819 upstream.
+
+powerpc hardware triggers watchpoint before executing the instruction.
+To make trigger-after-execute behavior, kernel emulates the
+instruction. If the instruction is 'load something into non-volatile
+register', exception handler should restore emulated register state
+while returning back, otherwise there will be register state
+corruption. eg, adding a watchpoint on a list can corrput the list:
+
+ # cat /proc/kallsyms | grep kthread_create_list
+ c00000000121c8b8 d kthread_create_list
+
+Add watchpoint on kthread_create_list->prev:
+
+ # perf record -e mem:0xc00000000121c8c0
+
+Run some workload such that new kthread gets invoked. eg, I just
+logged out from console:
+
+ list_add corruption. next->prev should be prev (c000000001214e00), \
+ but was c00000000121c8b8. (next=c00000000121c8b8).
+ WARNING: CPU: 59 PID: 309 at lib/list_debug.c:25 __list_add_valid+0xb4/0xc0
+ CPU: 59 PID: 309 Comm: kworker/59:0 Kdump: loaded Not tainted 5.1.0-rc7+ #69
+ ...
+ NIP __list_add_valid+0xb4/0xc0
+ LR __list_add_valid+0xb0/0xc0
+ Call Trace:
+ __list_add_valid+0xb0/0xc0 (unreliable)
+ __kthread_create_on_node+0xe0/0x260
+ kthread_create_on_node+0x34/0x50
+ create_worker+0xe8/0x260
+ worker_thread+0x444/0x560
+ kthread+0x160/0x1a0
+ ret_from_kernel_thread+0x5c/0x70
+
+List corruption happened because it uses 'load into non-volatile
+register' instruction:
+
+Snippet from __kthread_create_on_node:
+
+ c000000000136be8: addis r29,r2,-19
+ c000000000136bec: ld r29,31424(r29)
+ if (!__list_add_valid(new, prev, next))
+ c000000000136bf0: mr r3,r30
+ c000000000136bf4: mr r5,r28
+ c000000000136bf8: mr r4,r29
+ c000000000136bfc: bl c00000000059a2f8 <__list_add_valid+0x8>
+
+Register state from WARN_ON():
+
+ GPR00: c00000000059a3a0 c000007ff23afb50 c000000001344e00 0000000000000075
+ GPR04: 0000000000000000 0000000000000000 0000001852af8bc1 0000000000000000
+ GPR08: 0000000000000001 0000000000000007 0000000000000006 00000000000004aa
+ GPR12: 0000000000000000 c000007ffffeb080 c000000000137038 c000005ff62aaa00
+ GPR16: 0000000000000000 0000000000000000 c000007fffbe7600 c000007fffbe7370
+ GPR20: c000007fffbe7320 c000007fffbe7300 c000000001373a00 0000000000000000
+ GPR24: fffffffffffffef7 c00000000012e320 c000007ff23afcb0 c000000000cb8628
+ GPR28: c00000000121c8b8 c000000001214e00 c000007fef5b17e8 c000007fef5b17c0
+
+Watchpoint hit at 0xc000000000136bec.
+
+ addis r29,r2,-19
+ => r29 = 0xc000000001344e00 + (-19 << 16)
+ => r29 = 0xc000000001214e00
+
+ ld r29,31424(r29)
+ => r29 = *(0xc000000001214e00 + 31424)
+ => r29 = *(0xc00000000121c8c0)
+
+0xc00000000121c8c0 is where we placed a watchpoint and thus this
+instruction was emulated by emulate_step. But because handle_dabr_fault
+did not restore emulated register state, r29 still contains stale
+value in above register state.
+
+Fixes: 5aae8a5370802 ("powerpc, hw_breakpoints: Implement hw_breakpoints for 64-bit server processors")
+Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
+Cc: stable@vger.kernel.org # 2.6.36+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/exceptions-64s.S | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -1505,7 +1505,7 @@ handle_page_fault:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_page_fault
+ cmpdi r3,0
+- beq+ 12f
++ beq+ ret_from_except_lite
+ bl save_nvgprs
+ mr r5,r3
+ addi r3,r1,STACK_FRAME_OVERHEAD
+@@ -1520,7 +1520,12 @@ handle_dabr_fault:
+ ld r5,_DSISR(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_break
+-12: b ret_from_except_lite
++ /*
++ * do_break() may have changed the NV GPRS while handling a breakpoint.
++ * If so, we need to restore them with their updated values. Don't use
++ * ret_from_except_lite here.
++ */
++ b ret_from_except
+
+
+ #ifdef CONFIG_PPC_STD_MMU_64
floppy-fix-out-of-bounds-read-in-next_valid_format.patch
floppy-fix-invalid-pointer-dereference-in-drive_name.patch
floppy-fix-out-of-bounds-read-in-copy_buffer.patch
+coda-pass-the-host-file-in-vma-vm_file-on-mmap.patch
+gpu-ipu-v3-ipu-ic-fix-saturation-bit-offset-in-tpmem.patch
+crypto-ccp-validate-the-the-error-value-used-to-index-error-messages.patch
+pci-hv-delete-the-device-earlier-from-hbus-children-for-hot-remove.patch
+pci-hv-fix-a-use-after-free-bug-in-hv_eject_device_work.patch
+crypto-caam-limit-output-iv-to-cbc-to-work-around-ctr-mode-dma-issue.patch
+um-allow-building-and-running-on-older-hosts.patch
+um-fix-fp-register-size-for-xstate-xsave.patch
+parisc-ensure-userspace-privilege-for-ptraced-processes-in-regset-functions.patch
+parisc-fix-kernel-panic-due-invalid-values-in-iaoq0-or-iaoq1.patch
+powerpc-32s-fix-suspend-resume-when-ibats-4-7-are-used.patch
+powerpc-watchpoint-restore-nv-gprs-while-returning-from-exception.patch
+ecryptfs-fix-a-couple-type-promotion-bugs.patch
+intel_th-msu-fix-single-mode-with-disabled-iommu.patch
+bluetooth-add-smp-workaround-microsoft-surface-precision-mouse-bug.patch
--- /dev/null
+From 0a987645672ebde7844a9c0732a5a25f3d4bb6c6 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Thu, 25 May 2017 11:36:26 -0700
+Subject: um: Allow building and running on older hosts
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+commit 0a987645672ebde7844a9c0732a5a25f3d4bb6c6 upstream.
+
+Commit a78ff1112263 ("um: add extended processor state save/restore
+support") and b6024b21fec8 ("um: extend fpstate to _xstate to support
+YMM registers") forced the use of the x86 FP _xstate and
+PTRACE_GETREGSET/SETREGSET. On older hosts, we would neither be able to
+build UML nor run it anymore with these two commits applied because we
+don't have definitions for struct _xstate nor these two ptrace requests.
+
+We can determine at build time which fp context structure to check
+against, just like we can keep using the old i387 fp save/restore if
+PTRACE_GETRESET/SETREGSET are not defined.
+
+Fixes: a78ff1112263 ("um: add extended processor state save/restore support")
+Fixes: b6024b21fec8 ("um: extend fpstate to _xstate to support YMM registers")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Alessio Balsini <balsini@android.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/um/os-Linux/registers.c | 12 ++++++++----
+ arch/x86/um/user-offsets.c | 4 ++++
+ 2 files changed, 12 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/um/os-Linux/registers.c
++++ b/arch/x86/um/os-Linux/registers.c
+@@ -26,6 +26,7 @@ int save_i387_registers(int pid, unsigne
+
+ int save_fp_registers(int pid, unsigned long *fp_regs)
+ {
++#ifdef PTRACE_GETREGSET
+ struct iovec iov;
+
+ if (have_xstate_support) {
+@@ -34,9 +35,9 @@ int save_fp_registers(int pid, unsigned
+ if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) < 0)
+ return -errno;
+ return 0;
+- } else {
++ } else
++#endif
+ return save_i387_registers(pid, fp_regs);
+- }
+ }
+
+ int restore_i387_registers(int pid, unsigned long *fp_regs)
+@@ -48,6 +49,7 @@ int restore_i387_registers(int pid, unsi
+
+ int restore_fp_registers(int pid, unsigned long *fp_regs)
+ {
++#ifdef PTRACE_SETREGSET
+ struct iovec iov;
+
+ if (have_xstate_support) {
+@@ -56,9 +58,9 @@ int restore_fp_registers(int pid, unsign
+ if (ptrace(PTRACE_SETREGSET, pid, NT_X86_XSTATE, &iov) < 0)
+ return -errno;
+ return 0;
+- } else {
++ } else
++#endif
+ return restore_i387_registers(pid, fp_regs);
+- }
+ }
+
+ #ifdef __i386__
+@@ -122,6 +124,7 @@ int put_fp_registers(int pid, unsigned l
+
+ void arch_init_registers(int pid)
+ {
++#ifdef PTRACE_GETREGSET
+ struct _xstate fp_regs;
+ struct iovec iov;
+
+@@ -129,6 +132,7 @@ void arch_init_registers(int pid)
+ iov.iov_len = sizeof(struct _xstate);
+ if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) == 0)
+ have_xstate_support = 1;
++#endif
+ }
+ #endif
+
+--- a/arch/x86/um/user-offsets.c
++++ b/arch/x86/um/user-offsets.c
+@@ -50,7 +50,11 @@ void foo(void)
+ DEFINE(HOST_GS, GS);
+ DEFINE(HOST_ORIG_AX, ORIG_EAX);
+ #else
++#if defined(PTRACE_GETREGSET) && defined(PTRACE_SETREGSET)
+ DEFINE(HOST_FP_SIZE, sizeof(struct _xstate) / sizeof(unsigned long));
++#else
++ DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
++#endif
+ DEFINE_LONGS(HOST_BX, RBX);
+ DEFINE_LONGS(HOST_CX, RCX);
+ DEFINE_LONGS(HOST_DI, RDI);
--- /dev/null
+From 6f602afda7275c24c20ba38b5b6cd4ed08561fff Mon Sep 17 00:00:00 2001
+From: Thomas Meyer <thomas@m3y3r.de>
+Date: Sat, 29 Jul 2017 17:03:23 +0200
+Subject: um: Fix FP register size for XSTATE/XSAVE
+
+From: Thomas Meyer <thomas@m3y3r.de>
+
+commit 6f602afda7275c24c20ba38b5b6cd4ed08561fff upstream.
+
+Hard code max size. Taken from
+https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/common/x86-xstate.h
+
+Signed-off-by: Thomas Meyer <thomas@m3y3r.de>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Alessio Balsini <balsini@android.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/um/include/asm/thread_info.h | 3 +++
+ arch/um/include/shared/os.h | 2 +-
+ arch/um/kernel/process.c | 4 ++--
+ arch/um/os-Linux/skas/process.c | 17 ++++++++---------
+ arch/x86/um/os-Linux/registers.c | 18 ++++++++++++------
+ arch/x86/um/user-offsets.c | 4 ++--
+ 6 files changed, 28 insertions(+), 20 deletions(-)
+
+--- a/arch/um/include/asm/thread_info.h
++++ b/arch/um/include/asm/thread_info.h
+@@ -11,6 +11,7 @@
+ #include <asm/types.h>
+ #include <asm/page.h>
+ #include <asm/segment.h>
++#include <sysdep/ptrace_user.h>
+
+ struct thread_info {
+ struct task_struct *task; /* main task structure */
+@@ -22,6 +23,8 @@ struct thread_info {
+ 0-0xBFFFFFFF for user
+ 0-0xFFFFFFFF for kernel */
+ struct thread_info *real_thread; /* Points to non-IRQ stack */
++ unsigned long aux_fp_regs[FP_SIZE]; /* auxiliary fp_regs to save/restore
++ them out-of-band */
+ };
+
+ #define INIT_THREAD_INFO(tsk) \
+--- a/arch/um/include/shared/os.h
++++ b/arch/um/include/shared/os.h
+@@ -274,7 +274,7 @@ extern int protect(struct mm_id * mm_idp
+ extern int is_skas_winch(int pid, int fd, void *data);
+ extern int start_userspace(unsigned long stub_stack);
+ extern int copy_context_skas0(unsigned long stack, int pid);
+-extern void userspace(struct uml_pt_regs *regs);
++extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs);
+ extern int map_stub_pages(int fd, unsigned long code, unsigned long data,
+ unsigned long stack);
+ extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
+--- a/arch/um/kernel/process.c
++++ b/arch/um/kernel/process.c
+@@ -128,7 +128,7 @@ void new_thread_handler(void)
+ * callback returns only if the kernel thread execs a process
+ */
+ n = fn(arg);
+- userspace(¤t->thread.regs.regs);
++ userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs);
+ }
+
+ /* Called magically, see new_thread_handler above */
+@@ -147,7 +147,7 @@ void fork_handler(void)
+
+ current->thread.prev_sched = NULL;
+
+- userspace(¤t->thread.regs.regs);
++ userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs);
+ }
+
+ int copy_thread(unsigned long clone_flags, unsigned long sp,
+--- a/arch/um/os-Linux/skas/process.c
++++ b/arch/um/os-Linux/skas/process.c
+@@ -87,12 +87,11 @@ bad_wait:
+
+ extern unsigned long current_stub_stack(void);
+
+-static void get_skas_faultinfo(int pid, struct faultinfo *fi)
++static void get_skas_faultinfo(int pid, struct faultinfo *fi, unsigned long *aux_fp_regs)
+ {
+ int err;
+- unsigned long fpregs[FP_SIZE];
+
+- err = get_fp_registers(pid, fpregs);
++ err = get_fp_registers(pid, aux_fp_regs);
+ if (err < 0) {
+ printk(UM_KERN_ERR "save_fp_registers returned %d\n",
+ err);
+@@ -112,7 +111,7 @@ static void get_skas_faultinfo(int pid,
+ */
+ memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
+
+- err = put_fp_registers(pid, fpregs);
++ err = put_fp_registers(pid, aux_fp_regs);
+ if (err < 0) {
+ printk(UM_KERN_ERR "put_fp_registers returned %d\n",
+ err);
+@@ -120,9 +119,9 @@ static void get_skas_faultinfo(int pid,
+ }
+ }
+
+-static void handle_segv(int pid, struct uml_pt_regs * regs)
++static void handle_segv(int pid, struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
+ {
+- get_skas_faultinfo(pid, ®s->faultinfo);
++ get_skas_faultinfo(pid, ®s->faultinfo, aux_fp_regs);
+ segv(regs->faultinfo, 0, 1, NULL);
+ }
+
+@@ -305,7 +304,7 @@ int start_userspace(unsigned long stub_s
+ return err;
+ }
+
+-void userspace(struct uml_pt_regs *regs)
++void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
+ {
+ int err, status, op, pid = userspace_pid[0];
+ /* To prevent races if using_sysemu changes under us.*/
+@@ -374,11 +373,11 @@ void userspace(struct uml_pt_regs *regs)
+ case SIGSEGV:
+ if (PTRACE_FULL_FAULTINFO) {
+ get_skas_faultinfo(pid,
+- ®s->faultinfo);
++ ®s->faultinfo, aux_fp_regs);
+ (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si,
+ regs);
+ }
+- else handle_segv(pid, regs);
++ else handle_segv(pid, regs, aux_fp_regs);
+ break;
+ case SIGTRAP + 0x80:
+ handle_trap(pid, regs, local_using_sysemu);
+--- a/arch/x86/um/os-Linux/registers.c
++++ b/arch/x86/um/os-Linux/registers.c
+@@ -5,6 +5,7 @@
+ */
+
+ #include <errno.h>
++#include <stdlib.h>
+ #include <sys/ptrace.h>
+ #ifdef __i386__
+ #include <sys/user.h>
+@@ -31,7 +32,7 @@ int save_fp_registers(int pid, unsigned
+
+ if (have_xstate_support) {
+ iov.iov_base = fp_regs;
+- iov.iov_len = sizeof(struct _xstate);
++ iov.iov_len = FP_SIZE * sizeof(unsigned long);
+ if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) < 0)
+ return -errno;
+ return 0;
+@@ -51,10 +52,9 @@ int restore_fp_registers(int pid, unsign
+ {
+ #ifdef PTRACE_SETREGSET
+ struct iovec iov;
+-
+ if (have_xstate_support) {
+ iov.iov_base = fp_regs;
+- iov.iov_len = sizeof(struct _xstate);
++ iov.iov_len = FP_SIZE * sizeof(unsigned long);
+ if (ptrace(PTRACE_SETREGSET, pid, NT_X86_XSTATE, &iov) < 0)
+ return -errno;
+ return 0;
+@@ -125,13 +125,19 @@ int put_fp_registers(int pid, unsigned l
+ void arch_init_registers(int pid)
+ {
+ #ifdef PTRACE_GETREGSET
+- struct _xstate fp_regs;
++ void * fp_regs;
+ struct iovec iov;
+
+- iov.iov_base = &fp_regs;
+- iov.iov_len = sizeof(struct _xstate);
++ fp_regs = malloc(FP_SIZE * sizeof(unsigned long));
++ if(fp_regs == NULL)
++ return;
++
++ iov.iov_base = fp_regs;
++ iov.iov_len = FP_SIZE * sizeof(unsigned long);
+ if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) == 0)
+ have_xstate_support = 1;
++
++ free(fp_regs);
+ #endif
+ }
+ #endif
+--- a/arch/x86/um/user-offsets.c
++++ b/arch/x86/um/user-offsets.c
+@@ -50,8 +50,8 @@ void foo(void)
+ DEFINE(HOST_GS, GS);
+ DEFINE(HOST_ORIG_AX, ORIG_EAX);
+ #else
+-#if defined(PTRACE_GETREGSET) && defined(PTRACE_SETREGSET)
+- DEFINE(HOST_FP_SIZE, sizeof(struct _xstate) / sizeof(unsigned long));
++#ifdef FP_XSTATE_MAGIC1
++ DEFINE_LONGS(HOST_FP_SIZE, 2696);
+ #else
+ DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
+ #endif