4.14.135-stable review
Subsystems (9)
Greg Kroah-Hartman
maintainerPATCH 159/293 Btrfs: add missing inode version, ctime and mtime updates when punching hole
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit 179006688a7e888cbff39577189f2e034786d06a upstream.
If the range for which we are punching a hole covers only part of a page, we end up updating the inode item but we skip the update of the inode's iversion, mtime and ctime. Fix that by ensuring we update those properties of the inode.
A patch for fstests test case generic/059 that tests this as been sent along with this fix.
--- fs/btrfs/file.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/btrfs/file.c +5 -0
@@ -2784,6 +2784,11 @@ out_only_mutex:* for detecting, at fsync time, if the inode isn't yet in the * log tree or it's there but not up to date. */ +struct timespec now =current_time (inode); + +inode_inc_iversion (inode); + inode->i_mtime = now; + inode->i_ctime = now; trans =btrfs_start_transaction (root,1 );if (IS_ERR (trans)) { err =PTR_ERR (trans);
Greg Kroah-Hartman
maintainerPATCH 160/293 HID: wacom: generic: only switch the mode on devices with LEDs
In reply to Greg Kroah-HartmanFrom: Aaron Armstrong Skomra <[email protected]>
commit d8e9806005f28bbb49899dab2068e3359e22ba35 upstream.
Currently, the driver will attempt to set the mode on all devices with a center button, but some devices with a center button lack LEDs, and attempting to set the LEDs on devices without LEDs results in the kernel error message of the form:
"leds input8::wacom-0.1: Setting an LED's brightness failed (-32)"
This is because the generic codepath erroneously assumes that the BUTTON_CENTER usage indicates that the device has LEDs, the previously ignored TOUCH_RING_SETTING usage is a more accurate indication of the existence of LEDs on the device.
--- drivers/hid/wacom_sys.c | 3 +++ drivers/hid/wacom_wac.c | 2 -- drivers/hid/wacom_wac.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-)
drivers/hid/wacom_sys.c +3 -0
@@ -118,6 +118,9 @@ static void wacom_feature_mapping(structu32 n;switch (equivalent_usage) { +case WACOM_HID_WD_TOUCH_RING_SETTING : + wacom->generic_has_leds = true; +break ;case HID_DG_CONTACTMAX :/* leave touch_max as is if predefined */ if (!features->touch_max) {
drivers/hid/wacom_wac.c +0 -2
@@ -1871,8 +1871,6 @@ static void wacom_wac_pad_usage_mapping( features->device_type |=WACOM_DEVICETYPE_PAD ;break ;case WACOM_HID_WD_BUTTONCENTER : - wacom->generic_has_leds = true; -/* fall through */ case WACOM_HID_WD_BUTTONHOME :case WACOM_HID_WD_BUTTONUP :case WACOM_HID_WD_BUTTONDOWN :
drivers/hid/wacom_wac.h +1 -0
@@ -140,6 +140,7 @@#define WACOM_HID_WD_OFFSETBOTTOM (WACOM_HID_UP_WACOMDIGITIZER | 0x0d33)#define WACOM_HID_WD_DATAMODE (WACOM_HID_UP_WACOMDIGITIZER | 0x1002)#define WACOM_HID_WD_DIGITIZERINFO (WACOM_HID_UP_WACOMDIGITIZER | 0x1013) +#define WACOM_HID_WD_TOUCH_RING_SETTING (WACOM_HID_UP_WACOMDIGITIZER | 0x1032)#define WACOM_HID_UP_G9 0xff090000#define WACOM_HID_G9_PEN (WACOM_HID_UP_G9 | 0x02)#define WACOM_HID_G9_TOUCHSCREEN (WACOM_HID_UP_G9 | 0x11)
Greg Kroah-Hartman
maintainerPATCH 161/293 HID: wacom: correct touch resolution x/y typo
In reply to Greg Kroah-HartmanFrom: Aaron Armstrong Skomra <[email protected]>
commit 68c20cc2164cc5c7c73f8012ae6491afdb1f7f72 upstream.
This affects the 2nd-gen Intuos Pro Medium and Large when using their Bluetooth connection.
--- drivers/hid/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hid/wacom_wac.c +1 -1
@@ -3550,7 +3550,7 @@ int wacom_setup_touch_input_capabilities 0, 5920, 4, 0); }input_abs_set_res (input_dev,ABS_MT_POSITION_X ,40 ); -input_abs_set_res (input_dev,ABS_MT_POSITION_X ,40 ); +input_abs_set_res (input_dev,ABS_MT_POSITION_Y ,40 );/* fall through */
Greg Kroah-Hartman
maintainerPATCH 162/293 libnvdimm/pfn: fix fsdax-mode namespace info-block zero-fields
In reply to Greg Kroah-HartmanFrom: Dan Williams <[email protected]>
commit 7e3e888dfc138089f4c15a81b418e88f0978f744 upstream.
At namespace creation time there is the potential for the "expected to be zero" fields of a 'pfn' info-block to be filled with indeterminate data. While the kernel buffer is zeroed on allocation it is immediately overwritten by nd_pfn_validate() filling it with the current contents of the on-media info-block location. For fields like, 'flags' and the 'padding' it potentially means that future implementations can not rely on those fields being zero.
In preparation to stop using the 'start_pad' and 'end_trunc' fields for section alignment, arrange for fields that are not explicitly initialized to be guaranteed zero. Bump the minor version to indicate it is safe to assume the 'padding' and 'flags' are zero. Otherwise, this corruption is expected to benign since all other critical fields are explicitly initialized.
Note The cc: stable is about spreading this new policy to as many kernels as possible not fixing an issue in those kernels. It is not until the change titled "libnvdimm/pfn: Stop padding pmem namespaces to section alignment" where this improper initialization becomes a problem. So if someone decides to backport "libnvdimm/pfn: Stop padding pmem namespaces to section alignment" (which is not tagged for stable), make sure this pre-requisite is flagged.
--- drivers/nvdimm/dax_devs.c | 2 +- drivers/nvdimm/pfn.h | 1 + drivers/nvdimm/pfn_devs.c | 18 +++++++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-)
drivers/nvdimm/dax_devs.c +1 -1
@@ -126,7 +126,7 @@ int nd_dax_probe(struct device *dev, strnvdimm_bus_unlock (&ndns->dev);if (!dax_dev)return -ENOMEM ; - pfn_sb =devm_kzalloc (dev,sizeof (*pfn_sb),GFP_KERNEL ); + pfn_sb =devm_kmalloc (dev,sizeof (*pfn_sb),GFP_KERNEL ); nd_pfn->pfn_sb = pfn_sb; rc =nd_pfn_validate (nd_pfn,DAX_SIG ); dev_dbg(dev, "%s: dax: %s\n", __func__,
drivers/nvdimm/pfn.h +1 -0
@@ -36,6 +36,7 @@ struct nd_pfn_sb {__le32 end_trunc;/* minor-version-2 record the base alignment of the mapping */ __le32 align; +/* minor-version-3 guarantee the padding and flags are zero */ u8 padding[4000 ];__le64 checksum; };
drivers/nvdimm/pfn_devs.c +15 -3
@@ -361,6 +361,15 @@ struct device *nd_pfn_create(struct nd_rreturn dev; } +/** +* nd_pfn_validate - read and validate info-block +* @nd_pfn: fsdax namespace runtime state / properties +* @sig: 'devdax' or 'fsdax' signature +* +* Upon return the info-block buffer contents (->pfn_sb) are +* indeterminate when validation fails, and a coherent info-block +* otherwise. +*/ int nd_pfn_validate (struct nd_pfn *nd_pfn,const char *sig) {u64 checksum, offset;
@@ -506,7 +515,7 @@ int nd_pfn_probe(struct device *dev, strnvdimm_bus_unlock (&ndns->dev);if (!pfn_dev)return -ENOMEM ; - pfn_sb =devm_kzalloc (dev,sizeof (*pfn_sb),GFP_KERNEL ); + pfn_sb =devm_kmalloc (dev,sizeof (*pfn_sb),GFP_KERNEL ); nd_pfn =to_nd_pfn (pfn_dev); nd_pfn->pfn_sb = pfn_sb; rc =nd_pfn_validate (nd_pfn,PFN_SIG );
@@ -637,7 +646,7 @@ static int nd_pfn_init(struct nd_pfn *ndu64 checksum;int rc; - pfn_sb =devm_kzalloc (&nd_pfn->dev,sizeof (*pfn_sb),GFP_KERNEL ); + pfn_sb =devm_kmalloc (&nd_pfn->dev,sizeof (*pfn_sb),GFP_KERNEL );if (!pfn_sb)return -ENOMEM ;
@@ -646,11 +655,14 @@ static int nd_pfn_init(struct nd_pfn *nd sig =DAX_SIG ; else sig =PFN_SIG ; + rc =nd_pfn_validate (nd_pfn, sig);if (rc != -ENODEV )return rc;/* no info block, do init */ ; +memset (pfn_sb,0 ,sizeof (*pfn_sb)); + nd_region =to_nd_region (nd_pfn->dev.parent);if (nd_region->ro) { dev_info(&nd_pfn->dev,
@@ -704,7 +716,7 @@ static int nd_pfn_init(struct nd_pfn *ndmemcpy (pfn_sb->uuid, nd_pfn->uuid,16 );memcpy (pfn_sb->parent_uuid,nd_dev_to_uuid (&ndns->dev),16 ); pfn_sb->version_major =cpu_to_le16 (1 ); - pfn_sb->version_minor =cpu_to_le16 (2 ); + pfn_sb->version_minor =cpu_to_le16 (3 ); pfn_sb->start_pad =cpu_to_le32 (start_pad); pfn_sb->end_trunc =cpu_to_le32 (end_trunc); pfn_sb->align =cpu_to_le32 (nd_pfn->align);
Greg Kroah-Hartman
maintainerPATCH 163/293 coda: pass the host file in vma->vm_file on mmap
In reply to Greg Kroah-HartmanFrom: Jan Harkes <[email protected]>
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.
--- fs/coda/file.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-)
fs/coda/file.c +68 -2
@@ -27,6 +27,13 @@#include "coda_linux.h" #include "coda_int.h" +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 ssize_t coda_file_read_iter (struct kiocb *iocb,struct iov_iter *to) {
@@ -61,6 +68,34 @@ coda_file_write_iter(struct kiocb *iocb,return ret; } +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) {
@@ -68,6 +103,8 @@ coda_file_mmap(struct file *coda_file, sstruct 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 );
@@ -76,6 +113,13 @@ coda_file_mmap(struct file *coda_file, sif (!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);
@@ -89,6 +133,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 ; }
@@ -97,7 +142,29 @@ coda_file_mmap(struct file *coda_file, s cfi->cfi_mapcount++;spin_unlock (&cii->c_lock); -return call_mmap (host_file, vma); + vma->vm_file =get_file (host_file); + ret =call_mmap (vma->vm_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)
@@ -207,4 +274,3 @@ const struct file_operations coda_file_o .fsync = coda_fsync, .splice_read = generic_file_splice_read, }; -
Greg Kroah-Hartman
maintainerPATCH 164/293 gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM
In reply to Greg Kroah-HartmanFrom: Steve Longerbeam <[email protected]>
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.
--- drivers/gpu/ipu-v3/ipu-ic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/ipu-v3/ipu-ic.c +1 -1
@@ -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) |
Greg Kroah-Hartman
maintainerPATCH 165/293 PCI: hv: Fix a use-after-free bug in hv_eject_device_work()
In reply to Greg Kroah-HartmanFrom: Dexuan Cui <[email protected]>
commit 4df591b20b80cb77920953812d894db259d85bd7 upstream.
Fix a use-after-free in hv_eject_device_work().
--- drivers/pci/host/pci-hyperv.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/pci/host/pci-hyperv.c +9 -6
@@ -1912,6 +1912,7 @@ static void hv_pci_devices_present(strucstatic 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;
@@ -1922,6 +1923,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);
@@ -1935,8 +1937,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);
@@ -1944,9 +1945,9 @@ static void hv_eject_device_work(structpci_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);if (hpdev->pci_slot)pci_destroy_slot (hpdev->pci_slot);
@@ -1955,14 +1956,16 @@ static void hv_eject_device_work(struct 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); }/**
Greg Kroah-Hartman
maintainerPATCH 166/293 crypto: caam - limit output IV to CBC to work around CTR mode DMA issue
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
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.
--- drivers/crypto/caam/caamalg.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/crypto/caam/caamalg.c +9 -6
@@ -853,6 +853,7 @@ static void ablkcipher_encrypt_done(strustruct 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
@@ -877,10 +878,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->cdata.algtype &OP_ALG_AAI_MASK ) ==OP_ALG_AAI_CBC ) +scatterwalk_map_and_copy (req->info, req->dst, req->nbytes - + ivsize, ivsize,0 );/* In case initial IV was generated, copy it in GIVCIPHER request */ if (edesc->iv_dir ==DMA_FROM_DEVICE ) {
@@ -1609,10 +1611,11 @@ static int ablkcipher_decrypt(struct abl/* * 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->cdata.algtype &OP_ALG_AAI_MASK ) ==OP_ALG_AAI_CBC ) +scatterwalk_map_and_copy (req->info, req->src, req->nbytes - + ivsize, ivsize,0 );/* Create and submit job descriptor*/ init_ablkcipher_job (ctx->sh_desc_dec, ctx->sh_desc_dec_dma, edesc, req);
Greg Kroah-Hartman
maintainerPATCH 167/293 parisc: Ensure userspace privilege for ptraced processes in regset functions
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
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.
--- arch/parisc/kernel/ptrace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/parisc/kernel/ptrace.c +2 -1
@@ -500,7 +500,8 @@ static void set_reg(struct pt_regs *regsreturn ;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 ;
Greg Kroah-Hartman
maintainerPATCH 168/293 parisc: Fix kernel panic due invalid values in IAOQ0 or IAOQ1
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
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.
--- arch/parisc/kernel/ptrace.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-)
arch/parisc/kernel/ptrace.c +18 -10
@@ -171,6 +171,9 @@ long arch_ptrace(struct task_struct *chiif ((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) ||
@@ -232,16 +235,18 @@ long arch_ptrace(struct task_struct *chistatic 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,
@@ -285,9 +290,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) ||
Greg Kroah-Hartman
maintainerPATCH 169/293 powerpc/32s: fix suspend/resume when IBATs 4-7 are used
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
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.
--- arch/powerpc/kernel/swsusp_32.S | 73 ++++++++++++++++++++++++++++---- arch/powerpc/platforms/powermac/sleep.S | 68 +++++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 13 deletions(-)
arch/powerpc/kernel/swsusp_32.S +65 -8
@@ -24,11 +24,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
@@ -113,6 +121,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
@@ -278,27 +321,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
arch/powerpc/platforms/powermac/sleep.S +63 -5
101 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 170/293 powerpc/watchpoint: Restore NV GPRs while returning from exception
In reply to Greg Kroah-HartmanFrom: Ravi Bangoria <[email protected]>
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.
--- arch/powerpc/kernel/exceptions-64s.S | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/powerpc/kernel/exceptions-64s.S +7 -2
@@ -1675,7 +1675,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
@@ -1690,7 +1690,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
Greg Kroah-Hartman
maintainerPATCH 171/293 eCryptfs: fix a couple type promotion bugs
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
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.
--- fs/ecryptfs/crypto.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
fs/ecryptfs/crypto.c +8 -4
@@ -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_regecryptfs_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);
Greg Kroah-Hartman
maintainerPATCH 172/293 intel_th: msu: Fix single mode with disabled IOMMU
In reply to Greg Kroah-HartmanFrom: Alexander Shishkin <[email protected]>
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.
--- drivers/hwtracing/intel_th/msu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/intel_th/msu.c +1 -1
@@ -640,7 +640,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;
Greg Kroah-Hartman
maintainerPATCH 173/293 Bluetooth: Add SMP workaround Microsoft Surface Precision Mouse bug
In reply to Greg Kroah-HartmanFrom: Szymon Janc <[email protected]>
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.
Quoted 1 line
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....
Quoted 1 line
ACL Data RX: Handle 75 flags
0x02dlen 12
SMP: Identity Address Information (0x09) len 7
Address type: Public (0x00)
Address: E0:52:33:93:3B:21Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199461
--- net/bluetooth/smp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
net/bluetooth/smp.c +13 -0
@@ -2571,6 +2571,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;
Greg Kroah-Hartman
maintainerPATCH 174/293 usb: Handle USB3 remote wakeup for LPM enabled devices correctly
In reply to Greg Kroah-HartmanFrom: Lee, Chiasheng <[email protected]>
commit e244c4699f859cf7149b0781b1894c7996a8a1df upstream.
With Link Power Management (LPM) enabled USB3 links transition to low power U1/U2 link states from U0 state automatically.
Current hub code detects USB3 remote wakeups by checking if the software state still shows suspended, but the link has transitioned from suspended U3 to enabled U0 state.
As it takes some time before the hub thread reads the port link state after a USB3 wake notification, the link may have transitioned from U0 to U1/U2, and wake is not detected by hub code.
Fix this by handling U1/U2 states in the same way as U0 in USB3 wakeup handling
This patch should be added to stable kernels since 4.13 where LPM was kept enabled during suspend/resume
--- drivers/usb/core/hub.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/usb/core/hub.c +5 -2
@@ -3532,6 +3532,7 @@ static int hub_handle_remote_wakeup(strustruct usb_device *hdev;struct usb_device *udev;int connect_change =0 ; +u16 link_state;int ret; hdev = hub->hdev;
@@ -3541,9 +3542,11 @@ static int hub_handle_remote_wakeup(strureturn 0 ;usb_clear_port_feature (hdev, port,USB_PORT_FEAT_C_SUSPEND ); }else { + link_state = portstatus &USB_PORT_STAT_LINK_STATE ;if (!udev || udev->state !=USB_STATE_SUSPENDED || - (portstatus &USB_PORT_STAT_LINK_STATE ) != -USB_SS_PORT_LS_U0 ) + (link_state !=USB_SS_PORT_LS_U0 && + link_state !=USB_SS_PORT_LS_U1 && + link_state !=USB_SS_PORT_LS_U2 ))return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 175/293 net: mvmdio: allow up to four clocks to be specified for orion-mdio
In reply to Greg Kroah-HartmanFrom: Josua Mayer <[email protected]>
commit 4aabed699c400810981d3dda170f05fa4d782905 upstream.
Allow up to four clocks to be specified and enabled for the orion-mdio interface, which are required by the Armada 8k and defined in armada-cp110.dtsi.
Fixes a hang in probing the mvmdio driver that was encountered on the Clearfog GT 8K with all drivers built as modules, but also affects other boards such as the MacchiatoBIN.
--- drivers/net/ethernet/marvell/mvmdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/marvell/mvmdio.c +1 -1
@@ -64,7 +64,7 @@struct orion_mdio_dev {void __iomem *regs; -struct clk *clk[3 ]; +struct clk *clk[4 ];/* * If we have access to the error interrupt pin (which is * somewhat misnamed as it not only reflects internal errors
Greg Kroah-Hartman
maintainerPATCH 176/293 dt-bindings: allow up to four clocks for orion-mdio
In reply to Greg Kroah-HartmanFrom: Josua Mayer <[email protected]>
commit 80785f5a22e9073e2ded5958feb7f220e066d17b upstream.
Armada 8040 needs four clocks to be enabled for MDIO accesses to work. Update the binding to allow the extra clock to be specified.
--- Documentation/devicetree/bindings/net/marvell-orion-mdio.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/devicetree/bindings/net/marvell-orion-mdio.txt +1 -1
@@ -16,7 +16,7 @@ Required properties: Optional properties: - interrupts: interrupt line number for the SMI error/done interrupt -- clocks: phandle for up to three required clocks for the MDIO instance +- clocks: phandle for up to four required clocks for the MDIO instance The child nodes of the MDIO driver are the individual PHY devices connected to this MDIO bus. They must have a "reg" property given the
Greg Kroah-Hartman
maintainerPATCH 177/293 dm bufio: fix deadlock with loop device
In reply to Greg Kroah-HartmanFrom: Junxiao Bi <[email protected]>
commit bd293d071ffe65e645b4d8104f9d8fe15ea13862 upstream.
When thin-volume is built on loop device, if available memory is low, the following deadlock can be triggered:
One process P1 allocates memory with GFP_FS flag, direct alloc fails, memory reclaim invokes memory shrinker in dm_bufio, dm_bufio_shrink_scan() runs, mutex dm_bufio_client->lock is acquired, then P1 waits for dm_buffer IO to complete in __try_evict_buffer().
But this IO may never complete if issued to an underlying loop device that forwards it using direct-IO, which allocates memory using GFP_KERNEL (see: do_blockdev_direct_IO()). If allocation fails, memory reclaim will invoke memory shrinker in dm_bufio, dm_bufio_shrink_scan() will be invoked, and since the mutex is already held by P1 the loop thread will hang, and IO will never complete. Resulting in ABBA deadlock.
--- drivers/md/dm-bufio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/md/dm-bufio.c +1 -3
@@ -1630,9 +1630,7 @@ dm_bufio_shrink_scan(struct shrinker *shunsigned long freed; c = container_of(shrink, struct dm_bufio_client, shrinker); -if (sc->gfp_mask & __GFP_FS) -dm_bufio_lock (c); -else if (!dm_bufio_trylock (c)) +if (!dm_bufio_trylock (c))return SHRINK_STOP ; freed =__scan (c, sc->nr_to_scan, sc->gfp_mask);
Greg Kroah-Hartman
maintainerPATCH 178/293 compiler.h, kasan: Avoid duplicating __read_once_size_nocheck()
In reply to Greg Kroah-Hartman[ Upstream commit bdb5ac801af3d81d36732c2f640d6a1d3df83826 ]
Instead of having two identical __read_once_size_nocheck() functions with different attributes, consolidate all the difference in new macro __no_kasan_or_inline and use it. No functional changes.
--- include/linux/compiler.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
include/linux/compiler.h +6 -8
@@ -185,23 +185,21 @@ void __read_once_size(const volatile void *p, void *res, int size)#ifdef CONFIG_KASAN /* -* This function is not 'inline' because __no_sanitize_address confilcts +* We can't declare function 'inline' because __no_sanitize_address confilcts * with inlining. Attempt to inline it may cause a build failure. * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 * '__maybe_unused' allows us to avoid defined-but-not-used warnings. */ -static __no_sanitize_address __maybe_unused -void __read_once_size_nocheck(const volatile void *p, void *res, int size) -{ - __READ_ONCE_SIZE; -} +# define __no_kasan_or_inline __no_sanitize_address __maybe_unused#else -static __always_inline +# define __no_kasan_or_inline __always_inline +#endif + +static __no_kasan_or_inline void __read_once_size_nocheck(const volatile void *p, void *res, int size) { __READ_ONCE_SIZE; } -#endif static __always_inline void __write_once_size(volatile void *p, void *res, int size) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 179/293 compiler.h: Add read_word_at_a_time() function.
In reply to Greg Kroah-Hartman[ Upstream commit 7f1e541fc8d57a143dd5df1d0a1276046e08c083 ]
Sometimes we know that it's safe to do potentially out-of-bounds access because we know it won't cross a page boundary. Still, KASAN will report this as a bug.
Add read_word_at_a_time() function which is supposed to be used in such cases. In read_word_at_a_time() KASAN performs relaxed check - only the first byte of access is validated.
--- include/linux/compiler.h | 8 ++++++++ 1 file changed, 8 insertions(+)
include/linux/compiler.h +8 -0
@@ -238,6 +238,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s* required ordering. */ #include <asm/barrier.h> +#include <linux/kasan-checks.h> #define __READ_ONCE (x, check) \ ({ \
@@ -257,6 +258,13 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s*/ #define READ_ONCE_NOCHECK (x) __READ_ONCE(x, 0) +static __no_kasan_or_inline +unsigned long read_word_at_a_time (const void *addr) +{ +kasan_check_read (addr,1 ); +return *(unsigned long *)addr; +} +#define WRITE_ONCE (x, val) \ ({ \ union { typeof(x) __val; char __c[1]; } __u = \
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 180/293 lib/strscpy: Shut up KASAN false-positives in strscpy()
In reply to Greg Kroah-Hartman[ Upstream commit 1a3241ff10d038ecd096d03380327f2a0b5840a6 ]
strscpy() performs the word-at-a-time optimistic reads. So it may may access the memory past the end of the object, which is perfectly fine since strscpy() doesn't use that (past-the-end) data and makes sure the optimistic read won't cross a page boundary.
Use new read_word_at_a_time() to shut up the KASAN.
Note that this potentially could hide some bugs. In example bellow, stscpy() will copy more than we should (1-3 extra uninitialized bytes):
char dst[8];
char *src;
src = kmalloc(5, GFP_KERNEL);
memset(src, 0xff, 5);
strscpy(dst, src, 8);--- lib/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/string.c +1 -1
@@ -203,7 +203,7 @@ ssize_t strscpy(char *dest, const char *src, size_t count)while (max >=sizeof (unsigned long )) {unsigned long c, data; - c = *(unsigned long *)(src+res); + c =read_word_at_a_time (src+res);if (has_zero (c, &data, &constants)) { data =prep_zero_mask (c, data, &constants); data =create_zero_mask (data);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 181/293 bnx2x: Prevent load reordering in tx completion processing
In reply to Greg Kroah-HartmanFrom: Brian King <[email protected]>
[ Upstream commit ea811b795df24644a8eb760b493c43fba4450677 ]
This patch fixes an issue seen on Power systems with bnx2x which results in the skb is NULL WARN_ON in bnx2x_free_tx_pkt firing due to the skb pointer getting loaded in bnx2x_free_tx_pkt prior to the hw_cons load in bnx2x_tx_int. Adding a read memory barrier resolves the issue.
--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +3 -0
@@ -286,6 +286,9 @@ int bnx2x_tx_int(struct bnx2x *bp, struc hw_cons =le16_to_cpu (*txdata->tx_cons_sb); sw_cons = txdata->tx_pkt_cons; +/* Ensure subsequent loads occur after hw_cons */ +smp_rmb (); +while (sw_cons != hw_cons) {u16 pkt_cons;
Greg Kroah-Hartman
maintainerPATCH 182/293 bnx2x: Prevent ptp_task to be rescheduled indefinitely
In reply to Greg Kroah-HartmanFrom: "Guilherme G. Piccoli" <[email protected]>
[ Upstream commit 3c91f25c2f72ba6001775a5932857c1d2131c531 ]
Currently bnx2x ptp worker tries to read a register with timestamp information in case of TX packet timestamping and in case it fails, the routine reschedules itself indefinitely. This was reported as a kworker always at 100% of CPU usage, which was narrowed down to be bnx2x ptp_task.
By following the ioctl handler, we could narrow down the problem to an NTP tool (chrony) requesting HW timestamping from bnx2x NIC with RX filter zeroed; this isn't reproducible for example with ptp4l (from linuxptp) since this tool requests a supported RX filter. It seems NIC FW timestamp mechanism cannot work well with RX_FILTER_NONE - driver's PTP filter init routine skips a register write to the adapter if there's not a supported filter request.
This patch addresses the problem of bnx2x ptp thread's everlasting reschedule by retrying the register read 10 times; between the read attempts the thread sleeps for an increasing amount of time starting in 1ms to give FW some time to perform the timestamping. If it still fails after all retries, we bail out in order to prevent an unbound resource consumption from bnx2x.
The patch also adds an ethtool statistic for accounting the skipped TX timestamp packets and it reduces the priority of timestamping error messages to prevent log flooding. The code was tested using both linuxptp and chrony.
--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 5 ++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 4 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 33 ++++++++++++++------ drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 3 + 4 files changed, 34 insertions(+), 11 deletions(-)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +4 -1
@@ -3859,9 +3859,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_bif (unlikely (skb_shinfo (skb)->tx_flags &SKBTX_HW_TSTAMP )) {if (!(bp->flags &TX_TIMESTAMPING_EN )) { + bp->eth_stats.ptp_skip_tx_ts++;BNX2X_ERR ("Tx timestamping was not enabled, this packet will not be timestamped\n" ); }else if (bp->ptp_tx_skb) { -BNX2X_ERR ("The device supports only a single outstanding packet to timestamp, this packet will not be timestamped\n" ); + bp->eth_stats.ptp_skip_tx_ts++; +dev_err_once (&bp->dev->dev, +"Device supports only a single outstanding packet to timestamp, this packet won't be timestamped\n" ); }else {skb_shinfo (skb)->tx_flags |=SKBTX_IN_PROGRESS ;/* schedule check for Tx timestamp */
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +3 -1
@@ -182,7 +182,9 @@ static const struct { {STATS_OFFSET32 (driver_filtered_tx_pkt), 4, false, "driver_filtered_tx_pkt" }, { STATS_OFFSET32(eee_tx_lpi), - 4, true, "Tx LPI entry count"} + 4, true, "Tx LPI entry count"}, + { STATS_OFFSET32(ptp_skip_tx_ts), + 4, false, "ptp_skipped_tx_tstamp" }, };#define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +24 -9
@@ -15264,11 +15264,24 @@ static void bnx2x_ptp_task(struct work_su32 val_seq;u64 timestamp, ns;struct skb_shared_hwtstamps shhwtstamps; +bool bail = true; +int i; -/* Read Tx timestamp registers */ - val_seq =REG_RD (bp, port ?NIG_REG_P1_TLLH_PTP_BUF_SEQID : -NIG_REG_P0_TLLH_PTP_BUF_SEQID ); -if (val_seq &0x10000 ) { +/* FW may take a while to complete timestamping; try a bit and if it's +* still not complete, may indicate an error state - bail out then. +*/ +for (i =0 ; i <10 ; i++) { +/* Read Tx timestamp registers */ + val_seq =REG_RD (bp, port ?NIG_REG_P1_TLLH_PTP_BUF_SEQID : +NIG_REG_P0_TLLH_PTP_BUF_SEQID ); +if (val_seq &0x10000 ) { + bail = false; +break ; + } +msleep (1 << i); + } + +if (!bail) {/* There is a valid timestamp value */ timestamp =REG_RD (bp, port ?NIG_REG_P1_TLLH_PTP_BUF_TS_MSB :NIG_REG_P0_TLLH_PTP_BUF_TS_MSB );
@@ -15283,16 +15296,18 @@ static void bnx2x_ptp_task(struct work_smemset (&shhwtstamps,0 ,sizeof (shhwtstamps)); shhwtstamps.hwtstamp =ns_to_ktime (ns);skb_tstamp_tx (bp->ptp_tx_skb, &shhwtstamps); -dev_kfree_skb_any (bp->ptp_tx_skb); - bp->ptp_tx_skb =NULL ;DP (BNX2X_MSG_PTP ,"Tx timestamp, timestamp cycles = %llu, ns = %llu\n" , timestamp, ns); }else { -DP (BNX2X_MSG_PTP ,"There is no valid Tx timestamp yet\n" ); -/* Reschedule to keep checking for a valid timestamp value */ -schedule_work (&bp->ptp_task); +DP (BNX2X_MSG_PTP , +"Tx timestamp is not recorded (register read=%u)\n" , + val_seq); + bp->eth_stats.ptp_skip_tx_ts++; } + +dev_kfree_skb_any (bp->ptp_tx_skb); + bp->ptp_tx_skb =NULL ; }void bnx2x_set_rx_ts (struct bnx2x *bp,struct sk_buff *skb)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +3 -0
@@ -207,6 +207,9 @@ struct bnx2x_eth_stats {u32 driver_filtered_tx_pkt;/* src: Clear-on-Read register; Will not survive PMF Migration */ u32 eee_tx_lpi; + +/* PTP */ +u32 ptp_skip_tx_ts; };struct bnx2x_eth_q_stats {
Greg Kroah-Hartman
maintainerPATCH 183/293 caif-hsi: fix possible deadlock in cfhsi_exit_module()
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit fdd258d49e88a9e0b49ef04a506a796f1c768a8e ]
cfhsi_exit_module() calls unregister_netdev() under rtnl_lock(). but unregister_netdev() internally calls rtnl_lock(). So deadlock would occur.
--- drivers/net/caif/caif_hsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/caif/caif_hsi.c +1 -1
@@ -1462,7 +1462,7 @@ static void __exit cfhsi_exit_module(voirtnl_lock ();list_for_each_safe (list_node, n, &cfhsi_list) { cfhsi = list_entry(list_node, struct cfhsi, list); -unregister_netdev (cfhsi->ndev); +unregister_netdevice (cfhsi->ndev); }rtnl_unlock (); }
Greg Kroah-Hartman
maintainerPATCH 184/293 igmp: fix memory leak in igmpv3_del_delrec()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit e5b1c6c6277d5a283290a8c033c72544746f9b5b ]
im->tomb and/or im->sources might not be NULL, but we currently overwrite their values blindly.
Using swap() will make sure the following call to kfree_pmc(pmc) will properly free the psf structures.
Tested with the C repro provided by syzbot, which basically does :
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
setsockopt(3, SOL_IP, IP_ADD_MEMBERSHIP, "\340\0\0\2\177\0\0\1\0\0\0\0", 12) = 0 ioctl(3, SIOCSIFFLAGS, {ifr_name="lo", ifr_flags=0}) = 0
setsockopt(3, SOL_IP, IP_MSFILTER, "\340\0\0\2\177\0\0\1\1\0\0\0\1\0\0\0\377\377\377\377", 20) = 0 ioctl(3, SIOCSIFFLAGS, {ifr_name="lo", ifr_flags=IFF_UP}) = 0
exit_group(0) = ?
BUG: memory leak
unreferenced object 0xffff88811450f140 (size 64):
comm "softirq", pid 0, jiffies 4294942448 (age 32.070s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 ................
00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
backtrace:
[<00000000c7bad083>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline]
[<00000000c7bad083>] slab_post_alloc_hook mm/slab.h:439 [inline]
[<00000000c7bad083>] slab_alloc mm/slab.c:3326 [inline]
[<00000000c7bad083>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553
[<000000009acc4151>] kmalloc include/linux/slab.h:547 [inline]
[<000000009acc4151>] kzalloc include/linux/slab.h:742 [inline]
[<000000009acc4151>] ip_mc_add1_src net/ipv4/igmp.c:1976 [inline]
[<000000009acc4151>] ip_mc_add_src+0x36b/0x400 net/ipv4/igmp.c:2100
[<000000004ac14566>] ip_mc_msfilter+0x22d/0x310 net/ipv4/igmp.c:2484
[<0000000052d8f995>] do_ip_setsockopt.isra.0+0x1795/0x1930 net/ipv4/ip_sockglue.c:959
[<000000004ee1e21f>] ip_setsockopt+0x3b/0xb0 net/ipv4/ip_sockglue.c:1248
[<0000000066cdfe74>] udp_setsockopt+0x4e/0x90 net/ipv4/udp.c:2618
[<000000009383a786>] sock_common_setsockopt+0x38/0x50 net/core/sock.c:3126
[<00000000d8ac0c94>] __sys_setsockopt+0x98/0x120 net/socket.c:2072
[<000000001b1e9666>] __do_sys_setsockopt net/socket.c:2083 [inline]
[<000000001b1e9666>] __se_sys_setsockopt net/socket.c:2080 [inline]
[<000000001b1e9666>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2080
[<00000000420d395e>] do_syscall_64+0x76/0x1a0 arch/x86/entry/common.c:301
[<000000007fd83a4b>] entry_SYSCALL_64_after_hwframe+0x44/0xa9--- net/ipv4/igmp.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
net/ipv4/igmp.c +2 -6
@@ -1220,12 +1220,8 @@ static void igmpv3_del_delrec(struct in_ im->interface = pmc->interface; im->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;if (im->sfmode ==MCAST_INCLUDE ) { - im->tomb = pmc->tomb; - pmc->tomb =NULL ; - - im->sources = pmc->sources; - pmc->sources =NULL ; - +swap (im->tomb, pmc->tomb); +swap (im->sources, pmc->sources);for (psf = im->sources; psf; psf = psf->sf_next) psf->sf_crcount = im->crcount; }
Greg Kroah-Hartman
maintainerPATCH 185/293 ipv4: dont set IPv6 only flags to IPv4 addresses
In reply to Greg Kroah-HartmanFrom: Matteo Croce <[email protected]>
[ Upstream commit 2e60546368165c2449564d71f6005dda9205b5fb ]
Avoid the situation where an IPV6 only flag is applied to an IPv4 address:
# ip addr add 192.0.2.1/24 dev dummy0 nodad home mngtmpaddr noprefixroute
# ip -4 addr show dev dummy0
2: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
inet 192.0.2.1/24 scope global noprefixroute dummy0
valid_lft forever preferred_lft foreverOr worse, by sending a malicious netlink command:
# ip -4 addr show dev dummy0
2: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
inet 192.0.2.1/24 scope global nodad optimistic dadfailed home tentative mngtmpaddr noprefixroute stable-privacy dummy0
valid_lft forever preferred_lft forever--- net/ipv4/devinet.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/ipv4/devinet.c +8 -0
@@ -66,6 +66,11 @@#include <net/net_namespace.h> #include <net/addrconf.h> +#define IPV6ONLY_FLAGS \ + (IFA_F_NODAD | IFA_F_OPTIMISTIC | IFA_F_DADFAILED | \ + IFA_F_HOMEADDRESS | IFA_F_TENTATIVE | \ + IFA_F_MANAGETEMPADDR | IFA_F_STABLE_PRIVACY) +static struct ipv4_devconf ipv4_devconf = { .data = { [IPV4_DEVCONF_ACCEPT_REDIRECTS -1 ] =1 ,
@@ -455,6 +460,9 @@ static int __inet_insert_ifa(struct in_i ifa->ifa_flags &= ~IFA_F_SECONDARY ; last_primary = &in_dev->ifa_list; +/* Don't set IPv6 only flags to IPv4 addresses */ + ifa->ifa_flags &= ~IPV6ONLY_FLAGS ; +for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) !=NULL ; ifap = &ifa1->ifa_next) { if (!(ifa1->ifa_flags & IFA_F_SECONDARY) &&
Greg Kroah-Hartman
maintainerPATCH 186/293 net: bcmgenet: use promisc for unsupported filters
In reply to Greg Kroah-HartmanFrom: Justin Chen <[email protected]>
[ Upstream commit 35cbef9863640f06107144687bd13151bc2e8ce3 ]
Currently we silently ignore filters if we cannot meet the filter requirements. This will lead to the MAC dropping packets that are expected to pass. A better solution would be to set the NIC to promisc mode when the required filters cannot be met.
Also correct the number of MDF filters supported. It should be 17, not 16.
--- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 57 +++++++++++-------------- 1 file changed, 26 insertions(+), 31 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +26 -31
@@ -3088,39 +3088,42 @@ static void bcmgenet_timeout(struct net_netif_tx_wake_all_queues (dev); } -#define MAX_MC_COUNT 16 +#define MAX_MDF_FILTER 17static inline void bcmgenet_set_mdf_addr (struct bcmgenet_priv *priv,unsigned char *addr, -int *i, -int *mc) +int *i) { -u32 reg; -bcmgenet_umac_writel (priv, addr[0 ] <<8 | addr[1 ],UMAC_MDF_ADDR + (*i *4 ));bcmgenet_umac_writel (priv, addr[2 ] <<24 | addr[3 ] <<16 | addr[4 ] <<8 | addr[5 ],UMAC_MDF_ADDR + ((*i +1 ) *4 )); - reg =bcmgenet_umac_readl (priv,UMAC_MDF_CTRL ); - reg |= (1 << (MAX_MC_COUNT - *mc)); -bcmgenet_umac_writel (priv, reg,UMAC_MDF_CTRL ); *i +=2 ; - (*mc)++; }static void bcmgenet_set_rx_mode (struct net_device *dev) {struct bcmgenet_priv *priv =netdev_priv (dev);struct netdev_hw_addr *ha; -int i, mc; +int i, nfilter;u32 reg;netif_dbg (priv, hw, dev,"%s: %08X\n" , __func__, dev->flags); -/* Promiscuous mode */ +/* Number of filters needed */ + nfilter =netdev_uc_count (dev) +netdev_mc_count (dev) +2 ; + +/* +* Turn on promicuous mode for three scenarios +* 1. IFF_PROMISC flag is set +* 2. IFF_ALLMULTI flag is set +* 3. The number of filters needed exceeds the number filters +* supported by the hardware. +*/ reg =bcmgenet_umac_readl (priv,UMAC_CMD ); -if (dev->flags &IFF_PROMISC ) { +if ((dev->flags & (IFF_PROMISC |IFF_ALLMULTI )) || + (nfilter >MAX_MDF_FILTER )) { reg |=CMD_PROMISC ;bcmgenet_umac_writel (priv, reg,UMAC_CMD );bcmgenet_umac_writel (priv,0 ,UMAC_MDF_CTRL );
@@ -3130,32 +3133,24 @@ static void bcmgenet_set_rx_mode(structbcmgenet_umac_writel (priv, reg,UMAC_CMD ); } -/* UniMac doesn't support ALLMULTI */ -if (dev->flags &IFF_ALLMULTI ) { -netdev_warn (dev,"ALLMULTI is not supported\n" ); -return ; - } -/* update MDF filter */ i =0 ; - mc =0 ;/* Broadcast */ -bcmgenet_set_mdf_addr (priv, dev->broadcast, &i, &mc); +bcmgenet_set_mdf_addr (priv, dev->broadcast, &i);/* my own address.*/ -bcmgenet_set_mdf_addr (priv, dev->dev_addr, &i, &mc); -/* Unicast list*/ -if (netdev_uc_count (dev) > (MAX_MC_COUNT - mc)) -return ; +bcmgenet_set_mdf_addr (priv, dev->dev_addr, &i); -if (!netdev_uc_empty (dev)) -netdev_for_each_uc_addr (ha, dev) -bcmgenet_set_mdf_addr (priv, ha->addr, &i, &mc); -/* Multicast */ -if (netdev_mc_empty (dev) ||netdev_mc_count (dev) >= (MAX_MC_COUNT - mc)) -return ; +/* Unicast */ +netdev_for_each_uc_addr (ha, dev) +bcmgenet_set_mdf_addr (priv, ha->addr, &i); +/* Multicast */ netdev_for_each_mc_addr (ha, dev) -bcmgenet_set_mdf_addr (priv, ha->addr, &i, &mc); +bcmgenet_set_mdf_addr (priv, ha->addr, &i); + +/* Enable filters */ + reg =GENMASK (MAX_MDF_FILTER -1 ,MAX_MDF_FILTER - nfilter); +bcmgenet_umac_writel (priv, reg,UMAC_MDF_CTRL ); }/* Set the hardware MAC address. */
Greg Kroah-Hartman
maintainerPATCH 187/293 net: dsa: mv88e6xxx: wait after reset deactivation
In reply to Greg Kroah-HartmanFrom: Baruch Siach <[email protected]>
[ Upstream commit 7b75e49de424ceb53d13e60f35d0a73765626fda ]
Add a 1ms delay after reset deactivation. Otherwise the chip returns bogus ID value. This is observed with 88E6390 (Peridot) chip.
--- drivers/net/dsa/mv88e6xxx/chip.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/dsa/mv88e6xxx/chip.c +2 -0
@@ -4044,6 +4044,8 @@ static int mv88e6xxx_probe(struct mdio_d goto out_g1_irq; } } +if (chip->reset) +usleep_range (1000 ,2000 ); err =mv88e6xxx_mdios_register (chip, np);if (err)
Greg Kroah-Hartman
maintainerPATCH 188/293 net: neigh: fix multiple neigh timer scheduling
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 071c37983d99da07797294ea78e9da1a6e287144 ]
Neigh timer can be scheduled multiple times from userspace adding multiple neigh entries and forcing the neigh timer scheduling passing NTF_USE in the netlink requests.
This will result in a refcount leak and in the following dump stack:
[ 32.465295] NEIGH: BUG, double timer add, state is 8 [ 32.465308] CPU: 0 PID: 416 Comm: double_timer_ad Not tainted 5.2.0+ #65 [ 32.465311] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.12.0-2.fc30 04/01/2014 [ 32.465313] Call Trace: [ 32.465318] dump_stack+0x7c/0xc0 [ 32.465323] __neigh_event_send+0x20c/0x880 [ 32.465326] ? ___neigh_create+0x846/0xfb0 [ 32.465329] ? neigh_lookup+0x2a9/0x410 [ 32.465332] ? neightbl_fill_info.constprop.0+0x800/0x800 [ 32.465334] neigh_add+0x4f8/0x5e0 [ 32.465337] ? neigh_xmit+0x620/0x620 [ 32.465341] ? find_held_lock+0x85/0xa0 [ 32.465345] rtnetlink_rcv_msg+0x204/0x570 [ 32.465348] ? rtnl_dellink+0x450/0x450 [ 32.465351] ? mark_held_locks+0x90/0x90 [ 32.465354] ? match_held_lock+0x1b/0x230 [ 32.465357] netlink_rcv_skb+0xc4/0x1d0 [ 32.465360] ? rtnl_dellink+0x450/0x450 [ 32.465363] ? netlink_ack+0x420/0x420 [ 32.465366] ? netlink_deliver_tap+0x115/0x560 [ 32.465369] ? __alloc_skb+0xc9/0x2f0 [ 32.465372] netlink_unicast+0x270/0x330 [ 32.465375] ? netlink_attachskb+0x2f0/0x2f0 [ 32.465378] netlink_sendmsg+0x34f/0x5a0 [ 32.465381] ? netlink_unicast+0x330/0x330 [ 32.465385] ? move_addr_to_kernel.part.0+0x20/0x20 [ 32.465388] ? netlink_unicast+0x330/0x330 [ 32.465391] sock_sendmsg+0x91/0xa0 [ 32.465394] ___sys_sendmsg+0x407/0x480 [ 32.465397] ? copy_msghdr_from_user+0x200/0x200 [ 32.465401] ? _raw_spin_unlock_irqrestore+0x37/0x40 [ 32.465404] ? lockdep_hardirqs_on+0x17d/0x250 [ 32.465407] ? __wake_up_common_lock+0xcb/0x110 [ 32.465410] ? __wake_up_common+0x230/0x230 [ 32.465413] ? netlink_bind+0x3e1/0x490 [ 32.465416] ? netlink_setsockopt+0x540/0x540 [ 32.465420] ? __fget_light+0x9c/0xf0 [ 32.465423] ? sockfd_lookup_light+0x8c/0xb0 [ 32.465426] __sys_sendmsg+0xa5/0x110 [ 32.465429] ? __ia32_sys_shutdown+0x30/0x30 [ 32.465432] ? __fd_install+0xe1/0x2c0 [ 32.465435] ? lockdep_hardirqs_off+0xb5/0x100 [ 32.465438] ? mark_held_locks+0x24/0x90 [ 32.465441] ? do_syscall_64+0xf/0x270 [ 32.465444] do_syscall_64+0x63/0x270 [ 32.465448] entry_SYSCALL_64_after_hwframe+0x49/0xbe
Fix the issue unscheduling neigh_timer if selected entry is in 'IN_TIMER' receiving a netlink request with NTF_USE flag set
--- net/core/neighbour.c | 2 ++ 1 file changed, 2 insertions(+)
net/core/neighbour.c +2 -0
@@ -1018,6 +1018,7 @@ int __neigh_event_send(struct neighbouratomic_set (&neigh->probes,NEIGH_VAR (neigh->parms,UCAST_PROBES )); +neigh_del_timer (neigh); neigh->nud_state =NUD_INCOMPLETE ; neigh->updated = now; next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME),
@@ -1034,6 +1035,7 @@ int __neigh_event_send(struct neighbour } }else if (neigh->nud_state &NUD_STALE ) {neigh_dbg (2 ,"neigh %p is delayed\n" , neigh); +neigh_del_timer (neigh); neigh->nud_state =NUD_DELAY ; neigh->updated = jiffies; neigh_add_timer(neigh, jiffies +
Greg Kroah-Hartman
maintainerPATCH 189/293 net: openvswitch: fix csum updates for MPLS actions
In reply to Greg Kroah-HartmanFrom: John Hurley <[email protected]>
[ Upstream commit 0e3183cd2a64843a95b62f8bd4a83605a4cf0615 ]
Skbs may have their checksum value populated by HW. If this is a checksum calculated over the entire packet then the CHECKSUM_COMPLETE field is marked. Changes to the data pointer on the skb throughout the network stack still try to maintain this complete csum value if it is required through functions such as skb_postpush_rcsum.
The MPLS actions in Open vSwitch modify a CHECKSUM_COMPLETE value when changes are made to packet data without a push or a pull. This occurs when the ethertype of the MAC header is changed or when MPLS lse fields are modified.
The modification is carried out using the csum_partial function to get the csum of a buffer and add it into the larger checksum. The buffer is an inversion of the data to be removed followed by the new data. Because the csum is calculated over 16 bits and these values align with 16 bits, the effect is the removal of the old value from the CHECKSUM_COMPLETE and addition of the new value.
However, the csum fed into the function and the outcome of the calculation are also inverted. This would only make sense if it was the new value rather than the old that was inverted in the input buffer.
Fix the issue by removing the bit inverts in the csum_partial calculation.
The bug was verified and the fix tested by comparing the folded value of the updated CHECKSUM_COMPLETE value with the folded value of a full software checksum calculation (reset skb->csum to 0 and run skb_checksum_complete(skb)). Prior to the fix the outcomes differed but after they produce the same result.
--- net/openvswitch/actions.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
net/openvswitch/actions.c +2 -4
@@ -174,8 +174,7 @@ static void update_ethertype(struct sk_bif (skb->ip_summed ==CHECKSUM_COMPLETE ) {__be16 diff[] = { ~(hdr->h_proto), ethertype }; - skb->csum = ~csum_partial ((char *)diff,sizeof (diff), - ~skb->csum); + skb->csum =csum_partial ((char *)diff,sizeof (diff), skb->csum); } hdr->h_proto = ethertype;
@@ -267,8 +266,7 @@ static int set_mpls(struct sk_buff *skb,if (skb->ip_summed ==CHECKSUM_COMPLETE ) {__be32 diff[] = { ~(stack->label_stack_entry), lse }; - skb->csum = ~csum_partial ((char *)diff,sizeof (diff), - ~skb->csum); + skb->csum =csum_partial ((char *)diff,sizeof (diff), skb->csum); } stack->label_stack_entry = lse;
Greg Kroah-Hartman
maintainerPATCH 190/293 nfc: fix potential illegal memory access
In reply to Greg Kroah-HartmanFrom: Yang Wei <[email protected]>
[ Upstream commit dd006fc434e107ef90f7de0db9907cbc1c521645 ]
The frags_q is not properly initialized, it may result in illegal memory access when conn_info is NULL.
The "goto free_exit" should be replaced by "goto exit".
--- net/nfc/nci/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/nfc/nci/data.c +1 -1
@@ -119,7 +119,7 @@ static int nci_queue_tx_data_frags(struc conn_info =nci_get_conn_info_by_conn_id (ndev, conn_id);if (!conn_info) { rc = -EPROTO ; - goto free_exit; + goto exit; }__skb_queue_head_init (&frags_q);
Greg Kroah-Hartman
maintainerPATCH 191/293 rxrpc: Fix send on a connected, but unbound socket
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit e835ada07091f40dcfb1bc735082bd0a7c005e59 ]
If sendmsg() or sendmmsg() is called on a connected socket that hasn't had bind() called on it, then an oops will occur when the kernel tries to connect the call because no local endpoint has been allocated.
Fix this by implicitly binding the socket if it is in the RXRPC_CLIENT_UNBOUND state, just like it does for the RXRPC_UNBOUND state.
Further, the state should be transitioned to RXRPC_CLIENT_BOUND after this to prevent further attempts to bind it.
This can be tested with:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/rxrpc.h>
static const unsigned char inet6_addr[16] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0xac, 0x14, 0x14, 0xaa
};
int main(void)
{
struct sockaddr_rxrpc srx;
struct cmsghdr *cm;
struct msghdr msg;
unsigned char control[16];
int fd;
memset(&srx, 0, sizeof(srx));
srx.srx_family = 0x21;
srx.srx_service = 0;
srx.transport_type = AF_INET;
srx.transport_len = 0x1c;
srx.transport.sin6.sin6_family = AF_INET6;
srx.transport.sin6.sin6_port = htons(0x4e22);
srx.transport.sin6.sin6_flowinfo = htons(0x4e22);
srx.transport.sin6.sin6_scope_id = htons(0xaa3b);
memcpy(&srx.transport.sin6.sin6_addr, inet6_addr, 16);
cm = (struct cmsghdr *)control;
cm->cmsg_len = CMSG_LEN(sizeof(unsigned long));
cm->cmsg_level = SOL_RXRPC;
cm->cmsg_type = RXRPC_USER_CALL_ID;
*(unsigned long *)CMSG_DATA(cm) = 0;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = NULL;
msg.msg_iovlen = 0;
msg.msg_control = control;
msg.msg_controllen = cm->cmsg_len;
msg.msg_flags = 0;
fd = socket(AF_RXRPC, SOCK_DGRAM, AF_INET);
connect(fd, (struct sockaddr *)&srx, sizeof(srx));
sendmsg(fd, &msg, 0);
return 0;
}Leading to the following oops:
BUG: kernel NULL pointer dereference, address: 0000000000000018 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page ... RIP: 0010:rxrpc_connect_call+0x42/0xa01 ... Call Trace: ? mark_held_locks+0x47/0x59 ? __local_bh_enable_ip+0xb6/0xba rxrpc_new_client_call+0x3b1/0x762 ? rxrpc_do_sendmsg+0x3c0/0x92e rxrpc_do_sendmsg+0x3c0/0x92e rxrpc_sendmsg+0x16b/0x1b5 sock_sendmsg+0x2d/0x39 ___sys_sendmsg+0x1a4/0x22a ? release_sock+0x19/0x9e ? reacquire_held_locks+0x136/0x160 ? release_sock+0x19/0x9e ? find_held_lock+0x2b/0x6e ? __lock_acquire+0x268/0xf73 ? rxrpc_connect+0xdd/0xe4 ? __local_bh_enable_ip+0xb6/0xba __sys_sendmsg+0x5e/0x94 do_syscall_64+0x7d/0x1bf entry_SYSCALL_64_after_hwframe+0x49/0xbe
--- net/rxrpc/af_rxrpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/rxrpc/af_rxrpc.c +2 -2
@@ -504,6 +504,7 @@ static int rxrpc_sendmsg(struct socket *switch (rx->sk.sk_state) {case RXRPC_UNBOUND : +case RXRPC_CLIENT_UNBOUND : rx->srx.srx_family =AF_RXRPC ; rx->srx.srx_service =0 ; rx->srx.transport_type =SOCK_DGRAM ;
@@ -528,10 +529,9 @@ static int rxrpc_sendmsg(struct socket * } rx->local = local; - rx->sk.sk_state =RXRPC_CLIENT_UNBOUND ; + rx->sk.sk_state =RXRPC_CLIENT_BOUND ;/* Fall through */ -case RXRPC_CLIENT_UNBOUND :case RXRPC_CLIENT_BOUND :if (!m->msg_name &&test_bit (RXRPC_SOCK_CONNECTED , &rx->flags)) {
Greg Kroah-Hartman
maintainerPATCH 192/293 sky2: Disable MSI on ASUS P6T
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit a261e3797506bd561700be643fe1a85bf81e9661 ]
The onboard sky2 NIC on ASUS P6T WS PRO doesn't work after PM resume due to the infamous IRQ problem. Disabling MSI works around it, so let's add it to the blacklist.
Unfortunately the BIOS on the machine doesn't fill the standard DMI_SYS_* entry, so we pick up DMI_BOARD_* entries instead.
--- drivers/net/ethernet/marvell/sky2.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/marvell/sky2.c +7 -0
@@ -4947,6 +4947,13 @@ static const struct dmi_system_id msi_bl DMI_MATCH(DMI_PRODUCT_NAME, "P-79"), }, }, + { + .ident = "ASUS P6T", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "P6T"), + }, + }, {} };
Greg Kroah-Hartman
maintainerPATCH 193/293 vrf: make sure skb->data contains ip header to make routing
In reply to Greg Kroah-HartmanFrom: Peter Kosyh <[email protected]>
[ Upstream commit 107e47cc80ec37cb332bd41b22b1c7779e22e018 ]
vrf_process_v4_outbound() and vrf_process_v6_outbound() do routing using ip/ipv6 addresses, but don't make sure the header is available in skb->data[] (skb_headlen() is less then header size).
Case:
1) igb driver from intel.
2) Packet size is greater then 255.
3) MPLS forwards to VRF device.
So, patch adds pskb_may_pull() calls in vrf_process_v4/v6_outbound() functions.
--- drivers/net/vrf.c | 58 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 23 deletions(-)
drivers/net/vrf.c +35 -23
@@ -167,23 +167,29 @@ static int vrf_ip6_local_out(struct netstatic netdev_tx_t vrf_process_v6_outbound (struct sk_buff *skb,struct net_device *dev) { -const struct ipv6hdr *iph =ipv6_hdr (skb); +const struct ipv6hdr *iph;struct net *net =dev_net (skb->dev); -struct flowi6 fl6 = { -/* needed to match OIF rule */ - .flowi6_oif = dev->ifindex, - .flowi6_iif =LOOPBACK_IFINDEX , - .daddr = iph->daddr, - .saddr = iph->saddr, - .flowlabel =ip6_flowinfo (iph), - .flowi6_mark = skb->mark, - .flowi6_proto = iph->nexthdr, - .flowi6_flags =FLOWI_FLAG_SKIP_NH_OIF , - }; +struct flowi6 fl6;int ret =NET_XMIT_DROP ;struct dst_entry *dst;struct dst_entry *dst_null = &net->ipv6.ip6_null_entry->dst; +if (!pskb_may_pull (skb,ETH_HLEN +sizeof (struct ipv6hdr ))) + goto err; + + iph =ipv6_hdr (skb); + +memset (&fl6,0 ,sizeof (fl6)); +/* needed to match OIF rule */ + fl6.flowi6_oif = dev->ifindex; + fl6.flowi6_iif =LOOPBACK_IFINDEX ; + fl6.daddr = iph->daddr; + fl6.saddr = iph->saddr; + fl6.flowlabel =ip6_flowinfo (iph); + fl6.flowi6_mark = skb->mark; + fl6.flowi6_proto = iph->nexthdr; + fl6.flowi6_flags =FLOWI_FLAG_SKIP_NH_OIF ; + dst =ip6_route_output (net,NULL , &fl6);if (dst == dst_null) goto err;
@@ -239,21 +245,27 @@ static int vrf_ip_local_out(struct net *static netdev_tx_t vrf_process_v4_outbound (struct sk_buff *skb,struct net_device *vrf_dev) { -struct iphdr *ip4h =ip_hdr (skb); +struct iphdr *ip4h;int ret =NET_XMIT_DROP ; -struct flowi4 fl4 = { -/* needed to match OIF rule */ - .flowi4_oif = vrf_dev->ifindex, - .flowi4_iif =LOOPBACK_IFINDEX , - .flowi4_tos =RT_TOS (ip4h->tos), - .flowi4_flags =FLOWI_FLAG_ANYSRC |FLOWI_FLAG_SKIP_NH_OIF , - .flowi4_proto = ip4h->protocol, - .daddr = ip4h->daddr, - .saddr = ip4h->saddr, - }; +struct flowi4 fl4;struct net *net =dev_net (vrf_dev);struct rtable *rt; +if (!pskb_may_pull (skb,ETH_HLEN +sizeof (struct iphdr ))) + goto err; + + ip4h =ip_hdr (skb); + +memset (&fl4,0 ,sizeof (fl4)); +/* needed to match OIF rule */ + fl4.flowi4_oif = vrf_dev->ifindex; + fl4.flowi4_iif =LOOPBACK_IFINDEX ; + fl4.flowi4_tos =RT_TOS (ip4h->tos); + fl4.flowi4_flags =FLOWI_FLAG_ANYSRC |FLOWI_FLAG_SKIP_NH_OIF ; + fl4.flowi4_proto = ip4h->protocol; + fl4.daddr = ip4h->daddr; + fl4.saddr = ip4h->saddr; + rt =ip_route_output_flow (net, &fl4,NULL );if (IS_ERR (rt)) goto err;
Greg Kroah-Hartman
maintainerPATCH 194/293 macsec: fix use-after-free of skb during RX
In reply to Greg Kroah-HartmanFrom: Andreas Steinmetz <[email protected]>
[ Upstream commit 095c02da80a41cf6d311c504d8955d6d1c2add10 ]
Fix use-after-free of skb when rx_handler returns RX_HANDLER_PASS.
--- drivers/net/macsec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/macsec.c +2 -3
@@ -1099,10 +1099,9 @@ static rx_handler_result_t macsec_handle } skb =skb_unshare (skb,GFP_ATOMIC ); -if (!skb) { - *pskb =NULL ; + *pskb = skb; +if (!skb)return RX_HANDLER_CONSUMED ; - } pulled_sci =pskb_may_pull (skb,macsec_extra_len (true));if (!pulled_sci) {
Greg Kroah-Hartman
maintainerPATCH 195/293 macsec: fix checksumming after decryption
In reply to Greg Kroah-HartmanFrom: Andreas Steinmetz <[email protected]>
[ Upstream commit 7d8b16b9facb0dd81d1469808dd9a575fa1d525a ]
Fix checksumming after decryption.
--- drivers/net/macsec.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/macsec.c +1 -0
@@ -865,6 +865,7 @@ static void macsec_reset_skb(struct sk_bstatic void macsec_finalize_skb (struct sk_buff *skb,u8 icv_len,u8 hdr_len) { + skb->ip_summed =CHECKSUM_NONE ;memmove (skb->data + hdr_len, skb->data,2 *ETH_ALEN );skb_pull (skb, hdr_len);pskb_trim_unique (skb, skb->len - icv_len);
Greg Kroah-Hartman
maintainerPATCH 196/293 netrom: fix a memory leak in nr_rx_frame()
In reply to Greg Kroah-HartmanFrom: Cong Wang <[email protected]>
[ Upstream commit c8c8218ec5af5d2598381883acbefbf604e56b5e ]
When the skb is associated with a new sock, just assigning it to skb->sk is not sufficient, we have to set its destructor to free the sock properly too.
--- net/netrom/af_netrom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/netrom/af_netrom.c +2 -1
@@ -871,7 +871,7 @@ int nr_rx_frame(struct sk_buff *skb, strunsigned short frametype, flags, window, timeout;int ret; - skb->sk =NULL ;/* Initially we don't know who it's for */ +skb_orphan (skb);/* * skb->data points to the netrom frame start
@@ -970,6 +970,7 @@ int nr_rx_frame(struct sk_buff *skb, str window = skb->data[20 ]; skb->sk = make; + skb->destructor = sock_efree; make->sk_state =TCP_ESTABLISHED ;/* Fill in his circuit details */
Greg Kroah-Hartman
maintainerPATCH 197/293 netrom: hold sock when setting skb->destructor
In reply to Greg Kroah-HartmanFrom: Cong Wang <[email protected]>
[ Upstream commit 4638faac032756f7eab5524be7be56bee77e426b ]
sock_efree() releases the sock refcnt, if we don't hold this refcnt when setting skb->destructor to it, the refcnt would not be balanced. This leads to several bug reports from syzbot.
I have checked other users of sock_efree(), all of them hold the sock refcnt.
--- net/netrom/af_netrom.c | 1 + 1 file changed, 1 insertion(+)
net/netrom/af_netrom.c +1 -0
@@ -969,6 +969,7 @@ int nr_rx_frame(struct sk_buff *skb, str window = skb->data[20 ]; +sock_hold (make); skb->sk = make; skb->destructor = sock_efree; make->sk_state =TCP_ESTABLISHED ;
Greg Kroah-Hartman
maintainerPATCH 198/293 bonding: validate ip header before check IPPROTO_IGMP
In reply to Greg Kroah-HartmanFrom: Cong Wang <[email protected]>
[ Upstream commit 9d1bc24b52fb8c5d859f9a47084bf1179470e04c ]
bond_xmit_roundrobin() checks for IGMP packets but it parses the IP header even before checking skb->protocol.
We should validate the IP header with pskb_may_pull() before using iph->protocol.
--- drivers/net/bonding/bond_main.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-)
drivers/net/bonding/bond_main.c +23 -14
@@ -3817,8 +3817,8 @@ static u32 bond_rr_gen_slave_id(struct bstatic int bond_xmit_roundrobin (struct sk_buff *skb,struct net_device *bond_dev) {struct bonding *bond =netdev_priv (bond_dev); -struct iphdr *iph =ip_hdr (skb);struct slave *slave; +int slave_cnt;u32 slave_id;/* Start with the curr_active_slave that joined the bond as the
@@ -3827,23 +3827,32 @@ static int bond_xmit_roundrobin(struct s* send the join/membership reports. The curr_active_slave found * will send all of this type of traffic. */ -if (iph->protocol ==IPPROTO_IGMP && skb->protocol ==htons (ETH_P_IP )) { - slave =rcu_dereference (bond->curr_active_slave); -if (slave) -bond_dev_queue_xmit (bond, skb, slave->dev); -else -bond_xmit_slave_id (bond, skb,0 ); - }else { -int slave_cnt =ACCESS_ONCE (bond->slave_cnt); +if (skb->protocol ==htons (ETH_P_IP )) { +int noff =skb_network_offset (skb); +struct iphdr *iph; + +if (unlikely (!pskb_may_pull (skb, noff +sizeof (*iph)))) + goto non_igmp; -if (likely (slave_cnt)) { - slave_id =bond_rr_gen_slave_id (bond); -bond_xmit_slave_id (bond, skb, slave_id % slave_cnt); - }else { -bond_tx_drop (bond_dev, skb); + iph =ip_hdr (skb); +if (iph->protocol ==IPPROTO_IGMP ) { + slave =rcu_dereference (bond->curr_active_slave); +if (slave) +bond_dev_queue_xmit (bond, skb, slave->dev); +else +bond_xmit_slave_id (bond, skb,0 ); +return NETDEV_TX_OK ; } } +non_igmp: + slave_cnt =ACCESS_ONCE (bond->slave_cnt); +if (likely (slave_cnt)) { + slave_id =bond_rr_gen_slave_id (bond); +bond_xmit_slave_id (bond, skb, slave_id % slave_cnt); + }else { +bond_tx_drop (bond_dev, skb); + }return NETDEV_TX_OK ; }
Greg Kroah-Hartman
maintainerPATCH 199/293 net: make skb_dst_force return true when dst is refcounted
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
[ Upstream commit b60a77386b1d4868f72f6353d35dabe5fbe981f2 ]
netfilter did not expect that skb_dst_force() can cause skb to lose its dst entry.
I got a bug report with a skb->dst NULL dereference in netfilter output path. The backtrace contains nf_reinject(), so the dst might have been cleared when skb got queued to userspace.
Other users were fixed via
if (skb_dst(skb)) {
skb_dst_force(skb);
if (!skb_dst(skb))
goto handle_err;
}But I think its preferable to make the 'dst might be cleared' part of the function explicit.
In netfilter case, skb with a null dst is expected when queueing in prerouting hook, so drop skb for the other hooks.
v2:
v1 of this patch returned true in case skb had no dst entry. Eric said:
Say if we have two skb_dst_force() calls for some reason on the same skb, only the first one will return false.
This now returns false even when skb had no dst, as per Erics suggestion, so callers might need to check skb_dst() first before skb_dst_force().
--- include/net/dst.h | 5 ++++- net/netfilter/nf_queue.c | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-)
include/net/dst.h +4 -1
@@ -329,8 +329,9 @@ static inline bool dst_hold_safe(struct* @skb: buffer * * If dst is not yet refcounted and not destroyed, grab a ref on it. +* Returns true if dst is refcounted. */ -static inline void skb_dst_force (struct sk_buff *skb) +static inline bool skb_dst_force (struct sk_buff *skb) {if (skb_dst_is_noref (skb)) {struct dst_entry *dst =skb_dst (skb);
@@ -341,6 +342,8 @@ static inline void skb_dst_force(struct skb->_skb_refdst = (unsigned long )dst; } + +return skb->_skb_refdst !=0UL ; }
net/netfilter/nf_queue.c +5 -1
@@ -138,6 +138,11 @@ static int __nf_queue(struct sk_buff *sk goto err; } +if (!skb_dst_force (skb) && state->hook !=NF_INET_PRE_ROUTING ) { + status = -ENETDOWN ; + goto err; + } + *entry = (struct nf_queue_entry ) { .skb = skb, .state = *state,
@@ -146,7 +151,6 @@ static int __nf_queue(struct sk_buff *sk };nf_queue_entry_get_refs (entry); -skb_dst_force (skb); afinfo->saveroute (skb, entry); status = qh->outfn (entry, queuenum);
Greg Kroah-Hartman
maintainerPATCH 200/293 tcp: fix tcp_set_congestion_control() use from bpf hook
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 8d650cdedaabb33e85e9b7c517c0c71fcecc1de9 ]
Neal reported incorrect use of ns_capable() from bpf hook.
bpf_setsockopt(...TCP_CONGESTION...)
-> tcp_set_congestion_control()
-> ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)
-> ns_capable_common()
-> current_cred()
-> rcu_dereference_protected(current->cred, 1)Accessing 'current' in bpf context makes no sense, since packets are processed from softirq context.
As Neal stated : The capability check in tcp_set_congestion_control() was written assuming a system call context, and then was reused from a BPF call site.
The fix is to add a new parameter to tcp_set_congestion_control(), so that the ns_capable() call is only performed under the right context.
--- include/net/tcp.h | 3 ++- net/core/filter.c | 3 ++- net/ipv4/tcp.c | 4 +++- net/ipv4/tcp_cong.c | 6 +++--- 4 files changed, 10 insertions(+), 6 deletions(-)
include/net/tcp.h +2 -1
@@ -1043,7 +1043,8 @@ void tcp_get_default_congestion_control(void tcp_get_available_congestion_control (char *buf,size_t len);void tcp_get_allowed_congestion_control (char *buf,size_t len);int tcp_set_allowed_congestion_control (char *allowed); -int tcp_set_congestion_control (struct sock *sk,const char *name,bool load,bool reinit); +int tcp_set_congestion_control (struct sock *sk,const char *name,bool load, +bool reinit,bool cap_net_admin);u32 tcp_slow_start (struct tcp_sock *tp,u32 acked);void tcp_cong_avoid_ai (struct tcp_sock *tp,u32 w,u32 acked);
net/core/filter.c +2 -1
@@ -3122,7 +3122,8 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sostrncpy (name, optval,min_t (long, optlen,TCP_CA_NAME_MAX -1 )); name[TCP_CA_NAME_MAX -1 ] =0 ; - ret =tcp_set_congestion_control (sk, name, false, reinit); + ret =tcp_set_congestion_control (sk, name, false, + reinit, true); }else {struct tcp_sock *tp =tcp_sk (sk);
net/ipv4/tcp.c +3 -1
@@ -2500,7 +2500,9 @@ static int do_tcp_setsockopt(struct sock name[val] =0 ;lock_sock (sk); - err =tcp_set_congestion_control (sk, name, true, true); + err =tcp_set_congestion_control (sk, name, true, true, +ns_capable (sock_net (sk)->user_ns, +CAP_NET_ADMIN ));release_sock (sk);return err; }
net/ipv4/tcp_cong.c +3 -3
@@ -338,7 +338,8 @@ out:* tcp_reinit_congestion_control (if the current congestion control was * already initialized. */ -int tcp_set_congestion_control (struct sock *sk,const char *name,bool load,bool reinit) +int tcp_set_congestion_control (struct sock *sk,const char *name,bool load, +bool reinit,bool cap_net_admin) {struct inet_connection_sock *icsk =inet_csk (sk);const struct tcp_congestion_ops *ca;
@@ -372,8 +373,7 @@ int tcp_set_congestion_control(struct so }else { err = -EBUSY ; } - }else if (!((ca->flags &TCP_CONG_NON_RESTRICTED ) || -ns_capable (sock_net (sk)->user_ns,CAP_NET_ADMIN ))) { + }else if (!((ca->flags &TCP_CONG_NON_RESTRICTED ) || cap_net_admin)) { err = -EPERM ; }else if (!try_module_get (ca->owner)) { err = -EBUSY ;
Greg Kroah-Hartman
maintainerPATCH 201/293 tcp: Reset bytes_acked and bytes_received when disconnecting
In reply to Greg Kroah-HartmanFrom: Christoph Paasch <[email protected]>
[ Upstream commit e858faf556d4e14c750ba1e8852783c6f9520a0e ]
If an app is playing tricks to reuse a socket via tcp_disconnect(), bytes_acked/received needs to be reset to 0. Otherwise tcp_info will report the sum of the current and the old connection..
--- net/ipv4/tcp.c | 2 ++ 1 file changed, 2 insertions(+)
net/ipv4/tcp.c +2 -0
@@ -2366,6 +2366,8 @@ int tcp_disconnect(struct sock *sk, intdst_release (sk->sk_rx_dst); sk->sk_rx_dst =NULL ;tcp_saved_syn_free (tp); + tp->bytes_acked =0 ; + tp->bytes_received =0 ;/* Clean up fastopen related fields */ tcp_free_fastopen_req (tp);
Greg Kroah-Hartman
maintainerPATCH 202/293 net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling
In reply to Greg Kroah-HartmanFrom: Nikolay Aleksandrov <[email protected]>
[ Upstream commit e57f61858b7cf478ed6fa23ed4b3876b1c9625c4 ]
We take a pointer to grec prior to calling pskb_may_pull and use it afterwards to get nsrcs so record nsrcs before the pull when handling igmp3 and we get a pointer to nsrcs and call pskb_may_pull when handling mld2 which again could lead to reading 2 bytes out-of-bounds.
==================================================================
BUG: KASAN: use-after-free in br_multicast_rcv+0x480c/0x4ad0 [bridge]
Read of size 2 at addr ffff8880421302b4 by task ksoftirqd/1/16
CPU: 1 PID: 16 Comm: ksoftirqd/1 Tainted: G OE 5.2.0-rc6+ #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
Call Trace:
dump_stack+0x71/0xab
print_address_description+0x6a/0x280
? br_multicast_rcv+0x480c/0x4ad0 [bridge]
__kasan_report+0x152/0x1aa
? br_multicast_rcv+0x480c/0x4ad0 [bridge]
? br_multicast_rcv+0x480c/0x4ad0 [bridge]
kasan_report+0xe/0x20
br_multicast_rcv+0x480c/0x4ad0 [bridge]
? br_multicast_disable_port+0x150/0x150 [bridge]
? ktime_get_with_offset+0xb4/0x150
? __kasan_kmalloc.constprop.6+0xa6/0xf0
? __netif_receive_skb+0x1b0/0x1b0
? br_fdb_update+0x10e/0x6e0 [bridge]
? br_handle_frame_finish+0x3c6/0x11d0 [bridge]
br_handle_frame_finish+0x3c6/0x11d0 [bridge]
? br_pass_frame_up+0x3a0/0x3a0 [bridge]
? virtnet_probe+0x1c80/0x1c80 [virtio_net]
br_handle_frame+0x731/0xd90 [bridge]
? select_idle_sibling+0x25/0x7d0
? br_handle_frame_finish+0x11d0/0x11d0 [bridge]
__netif_receive_skb_core+0xced/0x2d70
? virtqueue_get_buf_ctx+0x230/0x1130 [virtio_ring]
? do_xdp_generic+0x20/0x20
? virtqueue_napi_complete+0x39/0x70 [virtio_net]
? virtnet_poll+0x94d/0xc78 [virtio_net]
? receive_buf+0x5120/0x5120 [virtio_net]
? __netif_receive_skb_one_core+0x97/0x1d0
__netif_receive_skb_one_core+0x97/0x1d0
? __netif_receive_skb_core+0x2d70/0x2d70
? _raw_write_trylock+0x100/0x100
? __queue_work+0x41e/0xbe0
process_backlog+0x19c/0x650
? _raw_read_lock_irq+0x40/0x40
net_rx_action+0x71e/0xbc0
? __switch_to_asm+0x40/0x70
? napi_complete_done+0x360/0x360
? __switch_to_asm+0x34/0x70
? __switch_to_asm+0x40/0x70
? __schedule+0x85e/0x14d0
__do_softirq+0x1db/0x5f9
? takeover_tasklets+0x5f0/0x5f0
run_ksoftirqd+0x26/0x40
smpboot_thread_fn+0x443/0x680
? sort_range+0x20/0x20
? schedule+0x94/0x210
? __kthread_parkme+0x78/0xf0
? sort_range+0x20/0x20
kthread+0x2ae/0x3a0
? kthread_create_worker_on_cpu+0xc0/0xc0
ret_from_fork+0x35/0x40
The buggy address belongs to the page:
page:ffffea0001084c00 refcount:0 mapcount:-128 mapping:0000000000000000 index:0x0
flags: 0xffffc000000000()
raw: 00ffffc000000000 ffffea0000cfca08 ffffea0001098608 0000000000000000
raw: 0000000000000000 0000000000000003 00000000ffffff7f 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888042130180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff888042130200: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> ffff888042130280: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
^
ffff888042130300: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff888042130380: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
==================================================================
Disabling lock debugging due to kernel taint--- net/bridge/br_multicast.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-)
net/bridge/br_multicast.c +16 -11
@@ -1120,6 +1120,7 @@ static int br_ip4_multicast_igmp3_reportint type;int err =0 ;__be32 group; +u16 nsrcs; ih =igmpv3_report_hdr (skb); num =ntohs (ih->ngrec);
@@ -1133,8 +1134,9 @@ static int br_ip4_multicast_igmp3_report grec = (void *)(skb->data + len -sizeof (*grec)); group = grec->grec_mca; type = grec->grec_type; + nsrcs =ntohs (grec->grec_nsrcs); - len +=ntohs (grec->grec_nsrcs) *4 ; + len += nsrcs *4 ;if (!pskb_may_pull (skb, len))return -EINVAL ;
@@ -1155,7 +1157,7 @@ static int br_ip4_multicast_igmp3_report src =eth_hdr (skb)->h_source;if ((type ==IGMPV3_CHANGE_TO_INCLUDE || type ==IGMPV3_MODE_IS_INCLUDE ) && -ntohs (grec->grec_nsrcs) ==0 ) { + nsrcs ==0 ) {br_ip4_multicast_leave_group (br, port, group, vid, src); }else { err = br_ip4_multicast_add_group(br, port, group, vid,
@@ -1190,23 +1192,26 @@ static int br_ip6_multicast_mld2_report( len =skb_transport_offset (skb) +sizeof (*icmp6h);for (i =0 ; i < num; i++) { -__be16 *nsrcs, _nsrcs; +__be16 *_nsrcs, __nsrcs; +u16 nsrcs; - nsrcs =skb_header_pointer (skb, - len + offsetof(struct mld2_grec , - grec_nsrcs), -sizeof (_nsrcs), &_nsrcs); -if (!nsrcs) + _nsrcs =skb_header_pointer (skb, + len + offsetof(struct mld2_grec , + grec_nsrcs), +sizeof (__nsrcs), &__nsrcs); +if (!_nsrcs)return -EINVAL ; + nsrcs =ntohs (*_nsrcs); +if (!pskb_may_pull (skb, len +sizeof (*grec) + -sizeof (struct in6_addr ) *ntohs (*nsrcs))) +sizeof (struct in6_addr ) * nsrcs))return -EINVAL ; grec = (struct mld2_grec *)(skb->data + len); len +=sizeof (*grec) + -sizeof (struct in6_addr ) *ntohs (*nsrcs); +sizeof (struct in6_addr ) * nsrcs;/* We treat these as MLDv1 reports for now. */ switch (grec->grec_type) {
@@ -1225,7 +1230,7 @@ static int br_ip6_multicast_mld2_report( src =eth_hdr (skb)->h_source;if ((grec->grec_type ==MLD2_CHANGE_TO_INCLUDE || grec->grec_type ==MLD2_MODE_IS_INCLUDE ) && -ntohs (*nsrcs) ==0 ) { + nsrcs ==0 ) {br_ip6_multicast_leave_group (br, port, &grec->grec_mca, vid, src); }else {
Greg Kroah-Hartman
maintainerPATCH 203/293 net: bridge: mcast: fix stale ipv6 hdr pointer when handling v6 query
In reply to Greg Kroah-HartmanFrom: Nikolay Aleksandrov <[email protected]>
[ Upstream commit 3b26a5d03d35d8f732d75951218983c0f7f68dff ]
We get a pointer to the ipv6 hdr in br_ip6_multicast_query but we may call pskb_may_pull afterwards and end up using a stale pointer. So use the header directly, it's just 1 place where it's needed.
--- net/bridge/br_multicast.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/bridge/br_multicast.c +1 -2
@@ -1482,7 +1482,6 @@ static int br_ip6_multicast_query(struct struct sk_buff *skb, u16 vid) { -const struct ipv6hdr *ip6h =ipv6_hdr (skb);struct mld_msg *mld;struct net_bridge_mdb_entry *mp;struct mld2_query *mld2q;
@@ -1526,7 +1525,7 @@ static int br_ip6_multicast_query(structif (is_general_query) { saddr.proto =htons (ETH_P_IPV6 ); - saddr.u.ip6 = ip6h->saddr; + saddr.u.ip6 =ipv6_hdr (skb)->saddr;br_multicast_query_received (br, port, &br->ip6_other_query, &saddr, max_delay);
Greg Kroah-Hartman
maintainerPATCH 204/293 net: bridge: stp: dont cache eth dest pointer before skb pull
In reply to Greg Kroah-HartmanFrom: Nikolay Aleksandrov <[email protected]>
[ Upstream commit 2446a68ae6a8cee6d480e2f5b52f5007c7c41312 ]
Don't cache eth dest pointer before calling pskb_may_pull.
--- net/bridge/br_stp_bpdu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/bridge/br_stp_bpdu.c +1 -2
@@ -147,7 +147,6 @@ void br_send_tcn_bpdu(struct net_bridge_void br_stp_rcv (const struct stp_proto *proto,struct sk_buff *skb,struct net_device *dev) { -const unsigned char *dest =eth_hdr (skb)->h_dest;struct net_bridge_port *p;struct net_bridge *br;const unsigned char *buf;
@@ -176,7 +175,7 @@ void br_stp_rcv(const struct stp_proto *if (p->state ==BR_STATE_DISABLED ) goto out; -if (!ether_addr_equal (dest, br->group_addr)) +if (!ether_addr_equal (eth_hdr (skb)->h_dest, br->group_addr)) goto out;if (p->flags &BR_BPDU_GUARD ) {
Greg Kroah-Hartman
maintainerPATCH 205/293 dma-buf: balance refcount inbalance
In reply to Greg Kroah-HartmanFrom: Jérôme Glisse <[email protected]>
commit 5e383a9798990c69fc759a4930de224bb497e62c upstream.
The debugfs take reference on fence without dropping them.
--- drivers/dma-buf/dma-buf.c | 1 + 1 file changed, 1 insertion(+)
drivers/dma-buf/dma-buf.c +1 -0
@@ -1115,6 +1115,7 @@ static int dma_buf_debug_show(struct seq fence->ops->get_driver_name (fence), fence->ops->get_timeline_name (fence), dma_fence_is_signaled(fence) ? "" : "un"); +dma_fence_put (fence); }rcu_read_unlock ();
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Greg Kroah-Hartman
maintainerPATCH 206/293 dma-buf: Discard old fence_excl on retrying get_fences_rcu for realloc
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit f5b07b04e5f090a85d1e96938520f2b2b58e4a8e upstream.
If we have to drop the seqcount & rcu lock to perform a krealloc, we have to restart the loop. In doing so, be careful not to lose track of the already acquired exclusive fence.
--- drivers/dma-buf/reservation.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/dma-buf/reservation.c +4 -0
@@ -394,6 +394,10 @@ int reservation_object_get_fences_rcu(st GFP_NOWAIT | __GFP_NOWARN);if (!nshared) {rcu_read_unlock (); + +dma_fence_put (fence_excl); + fence_excl =NULL ; + nshared =krealloc (shared, sz,GFP_KERNEL );if (nshared) { shared = nshared;
Greg Kroah-Hartman
maintainerPATCH 207/293 MIPS: lb60: Fix pin mappings
In reply to Greg Kroah-HartmanFrom: Paul Cercueil <[email protected]>
commit 1323c3b72a987de57141cabc44bf9cd83656bc70 upstream.
The pin mappings introduced in commit 636f8ba67fb6
("MIPS: JZ4740: Qi LB60: Add pinctrl configuration for several drivers") are completely wrong. The pinctrl driver name is incorrect, and the function and group fields are swapped.
--- arch/mips/jz4740/board-qi_lb60.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/mips/jz4740/board-qi_lb60.c +8 -8
@@ -456,27 +456,27 @@ static unsigned long pin_cfg_bias_disablstatic struct pinctrl_map pin_map[]__initdata = {/* NAND pin configuration */ PIN_MAP_MUX_GROUP_DEFAULT ("jz4740-nand" , -"10010000.jz4740-pinctrl" ,"nand" ,"nand-cs1" ), +"10010000.pin-controller" ,"nand-cs1" ,"nand" ),/* fbdev pin configuration */ PIN_MAP_MUX_GROUP ("jz4740-fb" ,PINCTRL_STATE_DEFAULT , -"10010000.jz4740-pinctrl" ,"lcd" ,"lcd-8bit" ), +"10010000.pin-controller" ,"lcd-8bit" ,"lcd" ),PIN_MAP_MUX_GROUP ("jz4740-fb" ,PINCTRL_STATE_SLEEP , -"10010000.jz4740-pinctrl" ,"lcd" ,"lcd-no-pins" ), +"10010000.pin-controller" ,"lcd-no-pins" ,"lcd" ),/* MMC pin configuration */ PIN_MAP_MUX_GROUP_DEFAULT ("jz4740-mmc.0" , -"10010000.jz4740-pinctrl" ,"mmc" ,"mmc-1bit" ), +"10010000.pin-controller" ,"mmc-1bit" ,"mmc" ),PIN_MAP_MUX_GROUP_DEFAULT ("jz4740-mmc.0" , -"10010000.jz4740-pinctrl" ,"mmc" ,"mmc-4bit" ), +"10010000.pin-controller" ,"mmc-4bit" ,"mmc" ),PIN_MAP_CONFIGS_PIN_DEFAULT ("jz4740-mmc.0" , -"10010000.jz4740-pinctrl" ,"PD0" , pin_cfg_bias_disable), +"10010000.pin-controller" ,"PD0" , pin_cfg_bias_disable),PIN_MAP_CONFIGS_PIN_DEFAULT ("jz4740-mmc.0" , -"10010000.jz4740-pinctrl" ,"PD2" , pin_cfg_bias_disable), +"10010000.pin-controller" ,"PD2" , pin_cfg_bias_disable),/* PWM pin configuration */ PIN_MAP_MUX_GROUP_DEFAULT ("jz4740-pwm" , -"10010000.jz4740-pinctrl" ,"pwm4" ,"pwm4" ), +"10010000.pin-controller" ,"pwm4" ,"pwm4" ), };
Greg Kroah-Hartman
maintainerPATCH 208/293 ext4: dont allow any modifications to an immutable file
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
commit 2e53840362771c73eb0a5ff71611507e64e8eecd upstream.
Don't allow any modifications to a file that's marked immutable, which means that we have to flush all the writable pages to make the readonly and we have to check the setattr/setflags parameters more closely.
--- fs/ext4/ioctl.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-)
fs/ext4/ioctl.c +45 -1
@@ -210,6 +210,29 @@ static int uuid_is_zero(__u8 u[16]) }#endif +/* +* If immutable is set and we are not clearing it, we're not allowed to change +* anything else in the inode. Don't error out if we're only trying to set +* immutable on an immutable file. +*/ +static int ext4_ioctl_check_immutable (struct inode *inode,__u32 new_projid, +unsigned int flags) +{ +struct ext4_inode_info *ei =EXT4_I (inode); +unsigned int oldflags = ei->i_flags; + +if (!(oldflags &EXT4_IMMUTABLE_FL ) || !(flags &EXT4_IMMUTABLE_FL )) +return 0 ; + +if ((oldflags & ~EXT4_IMMUTABLE_FL ) != (flags & ~EXT4_IMMUTABLE_FL )) +return -EPERM ; +if (ext4_has_feature_project (inode->i_sb) && +__kprojid_val (ei->i_projid) != new_projid) +return -EPERM ; + +return 0 ; +} +static int ext4_ioctl_setflags (struct inode *inode,unsigned int flags) {
@@ -263,6 +286,20 @@ static int ext4_ioctl_setflags(struct in goto flags_out; } +/* +* Wait for all pending directio and then flush all the dirty pages +* for this file. The flush marks all the pages readonly, so any +* subsequent attempt to write to the file (particularly mmap pages) +* will come through the filesystem and fail. +*/ +if (S_ISREG (inode->i_mode) && !IS_IMMUTABLE (inode) && + (flags &EXT4_IMMUTABLE_FL )) { +inode_dio_wait (inode); + err =filemap_write_and_wait (inode->i_mapping); +if (err) + goto flags_out; + } + handle =ext4_journal_start (inode,EXT4_HT_INODE ,1 );if (IS_ERR (handle)) { err =PTR_ERR (handle);
@@ -653,7 +690,11 @@ long ext4_ioctl(struct file *filp, unsigreturn err;inode_lock (inode); - err =ext4_ioctl_setflags (inode, flags); + err =ext4_ioctl_check_immutable (inode, +from_kprojid (&init_user_ns, ei->i_projid), + flags); +if (!err) + err =ext4_ioctl_setflags (inode, flags);inode_unlock (inode);mnt_drop_write_file (filp);return err;
@@ -1061,6 +1102,9 @@ resizefs_out: goto out; flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE ) | (flags &EXT4_FL_XFLAG_VISIBLE ); + err =ext4_ioctl_check_immutable (inode, fa.fsx_projid, flags); +if (err) + goto out; err =ext4_ioctl_setflags (inode, flags);if (err) goto out;
Greg Kroah-Hartman
maintainerPATCH 209/293 ext4: enforce the immutable flag on open files
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
commit 02b016ca7f99229ae6227e7b2fc950c4e140d74a upstream.
According to the chattr man page, "a file with the 'i' attribute cannot be modified..." Historically, this was only enforced when the file was opened, per the rest of the description, "... and the file can not be opened in write mode".
There is general agreement that we should standardize all file systems to prevent modifications even for files that were opened at the time the immutable flag is set. Eventually, a change to enforce this at the VFS layer should be landing in mainline. Until then, enforce this at the ext4 level to prevent xfstests generic/553 from failing.
--- fs/ext4/file.c | 4 ++++ fs/ext4/inode.c | 11 +++++++++++ 2 files changed, 15 insertions(+)
fs/ext4/file.c +4 -0
@@ -163,6 +163,10 @@ static ssize_t ext4_write_checks(struct ret =generic_write_checks (iocb, from);if (ret <=0 )return ret; + +if (unlikely (IS_IMMUTABLE (inode))) +return -EPERM ; +/* * If we have encountered a bitmap-format file, the size limit * is smaller than s_maxbytes, which is for extent-mapped files.
fs/ext4/inode.c +11 -0
@@ -5341,6 +5341,14 @@ int ext4_setattr(struct dentry *dentry,if (unlikely (ext4_forced_shutdown (EXT4_SB (inode->i_sb))))return -EIO ; +if (unlikely (IS_IMMUTABLE (inode))) +return -EPERM ; + +if (unlikely (IS_APPEND (inode) && + (ia_valid & (ATTR_MODE |ATTR_UID | +ATTR_GID |ATTR_TIMES_SET )))) +return -EPERM ; + error =setattr_prepare (dentry, attr);if (error)return error;
@@ -6045,6 +6053,9 @@ int ext4_page_mkwrite(struct vm_fault *vget_block_t *get_block;int retries =0 ; +if (unlikely (IS_IMMUTABLE (inode))) +return VM_FAULT_SIGBUS ; +sb_start_pagefault (inode->i_sb);file_update_time (vma->vm_file);
Greg Kroah-Hartman
maintainerPATCH 210/293 mm: add filemap_fdatawait_range_keep_errors()
In reply to Greg Kroah-HartmanFrom: Ross Zwisler <[email protected]>
commit aa0bfcd939c30617385ffa28682c062d78050eba upstream.
In the spirit of filemap_fdatawait_range() and filemap_fdatawait_keep_errors(), introduce filemap_fdatawait_range_keep_errors() which both takes a range upon which to wait and does not clear errors from the address space.
--- include/linux/fs.h | 2 ++ mm/filemap.c | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+)
include/linux/fs.h +2 -0
@@ -2580,6 +2580,8 @@ extern int filemap_flush(struct address_extern int filemap_fdatawait_keep_errors (struct address_space *mapping);extern int filemap_fdatawait_range (struct address_space *,loff_t lstart,loff_t lend); +extern int filemap_fdatawait_range_keep_errors (struct address_space *mapping, +loff_t start_byte,loff_t end_byte);static inline int filemap_fdatawait (struct address_space *mapping) {
mm/filemap.c +22 -0
@@ -464,6 +464,28 @@ int filemap_fdatawait_range(struct addreEXPORT_SYMBOL (filemap_fdatawait_range);/** +* filemap_fdatawait_range_keep_errors - wait for writeback to complete +* @mapping: address space structure to wait for +* @start_byte: offset in bytes where the range starts +* @end_byte: offset in bytes where the range ends (inclusive) +* +* Walk the list of under-writeback pages of the given address space in the +* given range and wait for all of them. Unlike filemap_fdatawait_range(), +* this function does not clear error status of the address space. +* +* Use this function if callers don't handle errors themselves. Expected +* call sites are system-wide / filesystem-wide data flushers: e.g. sync(2), +* fsfreeze(8) +*/ +int filemap_fdatawait_range_keep_errors (struct address_space *mapping, +loff_t start_byte,loff_t end_byte) +{ +__filemap_fdatawait_range (mapping, start_byte, end_byte); +return filemap_check_and_keep_errors (mapping); +} +EXPORT_SYMBOL (filemap_fdatawait_range_keep_errors); + +/** * file_fdatawait_range - wait for writeback to complete * @file: file pointing to address space structure to wait for * @start_byte: offset in bytes where the range starts
Greg Kroah-Hartman
maintainerPATCH 211/293 jbd2: introduce jbd2_inode dirty range scoping
In reply to Greg Kroah-HartmanFrom: Ross Zwisler <[email protected]>
commit 6ba0e7dc64a5adcda2fbe65adc466891795d639e upstream.
Currently both journal_submit_inode_data_buffers() and journal_finish_inode_data_buffers() operate on the entire address space of each of the inodes associated with a given journal entry. The consequence of this is that if we have an inode where we are constantly appending dirty pages we can end up waiting for an indefinite amount of time in journal_finish_inode_data_buffers() while we wait for all the pages under writeback to be written out.
The easiest way to cause this type of workload is do just dd from /dev/zero to a file until it fills the entire filesystem. This can cause journal_finish_inode_data_buffers() to wait for the duration of the entire dd operation.
We can improve this situation by scoping each of the inode dirty ranges associated with a given transaction. We do this via the jbd2_inode structure so that the scoping is contained within jbd2 and so that it follows the lifetime and locking rules for that structure.
This allows us to limit the writeback & wait in journal_submit_inode_data_buffers() and journal_finish_inode_data_buffers() respectively to the dirty range for a given struct jdb2_inode, keeping us from waiting forever if the inode in question is still being appended to.
--- fs/jbd2/commit.c | 23 +++++++++++++++++------ fs/jbd2/journal.c | 4 ++++ fs/jbd2/transaction.c | 49 ++++++++++++++++++++++++++++--------------------- include/linux/jbd2.h | 22 ++++++++++++++++++++++ 4 files changed, 71 insertions(+), 27 deletions(-)
fs/jbd2/commit.c +17 -6
@@ -189,14 +189,15 @@ static int journal_wait_on_commit_record* use writepages() because with dealyed allocation we may be doing * block allocation in writepages(). */ -static int journal_submit_inode_data_buffers (struct address_space *mapping) +static int journal_submit_inode_data_buffers (struct address_space *mapping, +loff_t dirty_start,loff_t dirty_end) {int ret;struct writeback_control wbc = { .sync_mode =WB_SYNC_ALL , .nr_to_write = mapping->nrpages *2 , - .range_start =0 , - .range_end =i_size_read (mapping->host), + .range_start = dirty_start, + .range_end = dirty_end, }; ret =generic_writepages (mapping, &wbc);
@@ -220,6 +221,9 @@ static int journal_submit_data_buffers(jspin_lock (&journal->j_list_lock);list_for_each_entry (jinode, &commit_transaction->t_inode_list, i_list) { +loff_t dirty_start = jinode->i_dirty_start; +loff_t dirty_end = jinode->i_dirty_end; +if (!(jinode->i_flags &JI_WRITE_DATA ))continue ; mapping = jinode->i_vfs_inode->i_mapping;
@@ -232,7 +236,8 @@ static int journal_submit_data_buffers(j* only allocated blocks here. */ trace_jbd2_submit_inode_data (jinode->i_vfs_inode); - err =journal_submit_inode_data_buffers (mapping); + err =journal_submit_inode_data_buffers (mapping, dirty_start, + dirty_end);if (!ret) ret = err;spin_lock (&journal->j_list_lock);
@@ -259,12 +264,16 @@ static int journal_finish_inode_data_buf/* For locking, see the comment in journal_submit_data_buffers() */ spin_lock (&journal->j_list_lock);list_for_each_entry (jinode, &commit_transaction->t_inode_list, i_list) { +loff_t dirty_start = jinode->i_dirty_start; +loff_t dirty_end = jinode->i_dirty_end; +if (!(jinode->i_flags &JI_WAIT_DATA ))continue ; jinode->i_flags |=JI_COMMIT_RUNNING ;spin_unlock (&journal->j_list_lock); - err =filemap_fdatawait_keep_errors ( - jinode->i_vfs_inode->i_mapping); + err =filemap_fdatawait_range_keep_errors ( + jinode->i_vfs_inode->i_mapping, dirty_start, + dirty_end);if (!ret) ret = err;spin_lock (&journal->j_list_lock);
@@ -284,6 +293,8 @@ static int journal_finish_inode_data_buf &jinode->i_transaction->t_inode_list); }else { jinode->i_transaction =NULL ; + jinode->i_dirty_start =0 ; + jinode->i_dirty_end =0 ; } }spin_unlock (&journal->j_list_lock);
fs/jbd2/journal.c +4 -0
@@ -97,6 +97,8 @@ EXPORT_SYMBOL(jbd2_journal_try_to_free_bEXPORT_SYMBOL (jbd2_journal_force_commit);EXPORT_SYMBOL (jbd2_journal_inode_add_write);EXPORT_SYMBOL (jbd2_journal_inode_add_wait); +EXPORT_SYMBOL (jbd2_journal_inode_ranged_write); +EXPORT_SYMBOL (jbd2_journal_inode_ranged_wait);EXPORT_SYMBOL (jbd2_journal_init_jbd_inode);EXPORT_SYMBOL (jbd2_journal_release_jbd_inode);EXPORT_SYMBOL (jbd2_journal_begin_ordered_truncate);
@@ -2581,6 +2583,8 @@ void jbd2_journal_init_jbd_inode(struct jinode->i_next_transaction =NULL ; jinode->i_vfs_inode = inode; jinode->i_flags =0 ; + jinode->i_dirty_start =0 ; + jinode->i_dirty_end =0 ;INIT_LIST_HEAD (&jinode->i_list); }
fs/jbd2/transaction.c +28 -21
73 lines not on this page · raw message
include/linux/jbd2.h +22 -0
@@ -454,6 +454,22 @@ struct jbd2_inode {* @i_flags: Flags of inode [j_list_lock] */ unsigned long i_flags; + +/** +* @i_dirty_start: +* +* Offset in bytes where the dirty range for this inode starts. +* [j_list_lock] +*/ +loff_t i_dirty_start; + +/** +* @i_dirty_end: +* +* Inclusive offset in bytes where the dirty range for this inode +* ends. [j_list_lock] +*/ +loff_t i_dirty_end; };struct jbd2_revoke_table_s ;
@@ -1399,6 +1415,12 @@ extern int jbd2_journal_force_commit(extern int jbd2_journal_force_commit_nested (journal_t *);extern int jbd2_journal_inode_add_write (handle_t *handle,struct jbd2_inode *inode);extern int jbd2_journal_inode_add_wait (handle_t *handle,struct jbd2_inode *inode); +extern int jbd2_journal_inode_ranged_write (handle_t *handle, +struct jbd2_inode *inode,loff_t start_byte, +loff_t length); +extern int jbd2_journal_inode_ranged_wait (handle_t *handle, +struct jbd2_inode *inode,loff_t start_byte, +loff_t length);extern int jbd2_journal_begin_ordered_truncate (journal_t *journal,struct jbd2_inode *inode,loff_t new_size);extern void jbd2_journal_init_jbd_inode (struct jbd2_inode *jinode,struct inode *inode);
Greg Kroah-Hartman
maintainerPATCH 212/293 ext4: use jbd2_inode dirty range scoping
In reply to Greg Kroah-HartmanFrom: Ross Zwisler <[email protected]>
commit 73131fbb003b3691cfcf9656f234b00da497fcd6 upstream.
Use the newly introduced jbd2_inode dirty range scoping to prevent us from waiting forever when trying to complete a journal transaction.
--- fs/ext4/ext4_jbd2.h | 12 ++++++------ fs/ext4/inode.c | 13 ++++++++++--- fs/ext4/move_extent.c | 3 ++- 3 files changed, 18 insertions(+), 10 deletions(-)
fs/ext4/ext4_jbd2.h +6 -6
@@ -364,20 +364,20 @@ static inline int ext4_journal_force_com }static inline int ext4_jbd2_inode_add_write (handle_t *handle, -struct inode *inode) +struct inode *inode,loff_t start_byte,loff_t length) {if (ext4_handle_valid (handle)) -return jbd2_journal_inode_add_write (handle, -EXT4_I (inode)->jinode); +return jbd2_journal_inode_ranged_write (handle, +EXT4_I (inode)->jinode, start_byte, length);return 0 ; }static inline int ext4_jbd2_inode_add_wait (handle_t *handle, -struct inode *inode) +struct inode *inode,loff_t start_byte,loff_t length) {if (ext4_handle_valid (handle)) -return jbd2_journal_inode_add_wait (handle, -EXT4_I (inode)->jinode); +return jbd2_journal_inode_ranged_wait (handle, +EXT4_I (inode)->jinode, start_byte, length);return 0 ; }
fs/ext4/inode.c +10 -3
@@ -728,10 +728,16 @@ out_sem: !(flags & EXT4_GET_BLOCKS_ZERO) && !ext4_is_quota_file(inode) && ext4_should_order_data(inode)) { +loff_t start_byte = + (loff_t )map->m_lblk << inode->i_blkbits; +loff_t length = (loff_t )map->m_len << inode->i_blkbits; +if (flags &EXT4_GET_BLOCKS_IO_SUBMIT ) - ret =ext4_jbd2_inode_add_wait (handle, inode); + ret =ext4_jbd2_inode_add_wait (handle, inode, + start_byte, length);else - ret =ext4_jbd2_inode_add_write (handle, inode); + ret =ext4_jbd2_inode_add_write (handle, inode, + start_byte, length);if (ret)return ret; }
@@ -4004,7 +4010,8 @@ static int __ext4_block_zero_page_range( err =0 ;mark_buffer_dirty (bh);if (ext4_should_order_data (inode)) - err =ext4_jbd2_inode_add_write (handle, inode); + err =ext4_jbd2_inode_add_write (handle, inode, from, + length); } unlock:
fs/ext4/move_extent.c +2 -1
@@ -400,7 +400,8 @@ data_copy:/* Even in case of data=writeback it is reasonable to pin * inode to transaction, to prevent unexpected data loss */ - *err =ext4_jbd2_inode_add_write (handle, orig_inode); + *err =ext4_jbd2_inode_add_write (handle, orig_inode, + (loff_t )orig_page_offset <<PAGE_SHIFT , replaced_size); unlock_pages:unlock_page (pagep[0 ]);
Greg Kroah-Hartman
maintainerPATCH 213/293 ext4: allow directory holes
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
commit 4e19d6b65fb4fc42e352ce9883649e049da14743 upstream.
The largedir feature was intended to allow ext4 directories to have unmapped directory blocks (e.g., directory holes). And so the released e2fsprogs no longer enforces this for largedir file systems; however, the corresponding change to the kernel-side code was not made.
This commit fixes this oversight.
--- fs/ext4/dir.c | 19 +++++++++---------- fs/ext4/namei.c | 45 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 18 deletions(-)
fs/ext4/dir.c +9 -10
@@ -107,7 +107,6 @@ static int ext4_readdir(struct file *filstruct inode *inode =file_inode (file);struct super_block *sb = inode->i_sb;struct buffer_head *bh =NULL ; -int dir_has_error =0 ;struct fscrypt_str fstr =FSTR_INIT (NULL ,0 );if (ext4_encrypted_inode (inode)) {
@@ -143,8 +142,6 @@ static int ext4_readdir(struct file *filreturn err; } - offset = ctx->pos & (sb->s_blocksize -1 ); -while (ctx->pos < inode->i_size) {struct ext4_map_blocks map;
@@ -153,9 +150,18 @@ static int ext4_readdir(struct file *fil goto errout; }cond_resched (); + offset = ctx->pos & (sb->s_blocksize -1 ); map.m_lblk = ctx->pos >>EXT4_BLOCK_SIZE_BITS (sb); map.m_len =1 ; err =ext4_map_blocks (NULL , inode, &map,0 ); +if (err ==0 ) { +/* m_len should never be zero but let's avoid +* an infinite loop if it somehow is */ +if (map.m_len ==0 ) + map.m_len =1 ; + ctx->pos += map.m_len * sb->s_blocksize; +continue ; + }if (err >0 ) {pgoff_t index = map.m_pblk >> (PAGE_SHIFT - inode->i_blkbits);
@@ -174,13 +180,6 @@ static int ext4_readdir(struct file *fil }if (!bh) { -if (!dir_has_error) { -EXT4_ERROR_FILE (file,0 , -"directory contains a " -"hole at offset %llu" , - (unsigned long long ) ctx->pos); - dir_has_error =1 ; - }/* corrupt size? Maybe no more blocks to read */ if (ctx->pos > inode->i_blocks <<9 )break ;
fs/ext4/namei.c +37 -8
109 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 214/293 mm: vmscan: scan anonymous pages on file refaults
In reply to Greg Kroah-HartmanFrom: Kuo-Hsin Yang <[email protected]>
commit 2c012a4ad1a2cd3fb5a0f9307b9d219f84eda1fa upstream.
When file refaults are detected and there are many inactive file pages, the system never reclaim anonymous pages, the file pages are dropped aggressively when there are still a lot of cold anonymous pages and system thrashes. This issue impacts the performance of applications with large executable, e.g. chrome.
With this patch, when file refault is detected, inactive_list_is_low() always returns true for file pages in get_scan_count() to enable scanning anonymous pages.
The problem can be reproduced by the following test program.
---8<---
void fallocate_file(const char *filename, off_t size)
{
struct stat st;
int fd;
if (!stat(filename, &st) && st.st_size >= size)
return;
fd = open(filename, O_WRONLY | O_CREAT, 0600);
if (fd < 0) {
perror("create file");
exit(1);
}
if (posix_fallocate(fd, 0, size)) {
perror("fallocate");
exit(1);
}
close(fd);
}long *alloc_anon(long size)
{
long *start = malloc(size);
memset(start, 1, size);
return start;
}long access_file(const char *filename, long size, long rounds)
{
int fd, i;
volatile char *start1, *end1, *start2;
const int page_size = getpagesize();
long sum = 0;
fd = open(filename, O_RDONLY);
if (fd == -1) {
perror("open");
exit(1);
}
/*
* Some applications, e.g. chrome, use a lot of executable file
* pages, map some of the pages with PROT_EXEC flag to simulate
* the behavior.
*/
start1 = mmap(NULL, size / 2, PROT_READ | PROT_EXEC, MAP_SHARED,
fd, 0);
if (start1 == MAP_FAILED) {
perror("mmap");
exit(1);
}
end1 = start1 + size / 2;
start2 = mmap(NULL, size / 2, PROT_READ, MAP_SHARED, fd, size / 2);
if (start2 == MAP_FAILED) {
perror("mmap");
exit(1);
}
for (i = 0; i < rounds; ++i) {
struct timeval before, after;
volatile char *ptr1 = start1, *ptr2 = start2;
gettimeofday(&before, NULL);
for (; ptr1 < end1; ptr1 += page_size, ptr2 += page_size)
sum += *ptr1 + *ptr2;
gettimeofday(&after, NULL);
printf("File access time, round %d: %f (sec)
", i,
(after.tv_sec - before.tv_sec) +
(after.tv_usec - before.tv_usec) / 1000000.0);
}
return sum;
}int main(int argc, char *argv[])
{
const long MB = 1024 * 1024;
long anon_mb, file_mb, file_rounds;
const char filename[] = "large";
long *ret1;
long ret2;
if (argc != 4) {
printf("usage: thrash ANON_MB FILE_MB FILE_ROUNDS
");
exit(0);
}
anon_mb = atoi(argv[1]);
file_mb = atoi(argv[2]);
file_rounds = atoi(argv[3]);
fallocate_file(filename, file_mb * MB);
printf("Allocate %ld MB anonymous pages
", anon_mb);
ret1 = alloc_anon(anon_mb * MB);
printf("Access %ld MB file pages
", file_mb);
ret2 = access_file(filename, file_mb * MB, file_rounds);
printf("Print result to prevent optimization: %ld
",
*ret1 + ret2);
return 0;
}---8<---
Running the test program on 2GB RAM VM with kernel 5.2.0-rc5, the program fills ram with 2048 MB memory, access a 200 MB file for 10 times. Without this patch, the file cache is dropped aggresively and every access to the file is from disk.
$ ./thrash 2048 200 10 Allocate 2048 MB anonymous pages Access 200 MB file pages File access time, round 0: 2.489316 (sec) File access time, round 1: 2.581277 (sec) File access time, round 2: 2.487624 (sec) File access time, round 3: 2.449100 (sec) File access time, round 4: 2.420423 (sec) File access time, round 5: 2.343411 (sec) File access time, round 6: 2.454833 (sec) File access time, round 7: 2.483398 (sec) File access time, round 8: 2.572701 (sec) File access time, round 9: 2.493014 (sec)
With this patch, these file pages can be cached.
$ ./thrash 2048 200 10 Allocate 2048 MB anonymous pages Access 200 MB file pages File access time, round 0: 2.475189 (sec) File access time, round 1: 2.440777 (sec) File access time, round 2: 2.411671 (sec) File access time, round 3: 1.955267 (sec) File access time, round 4: 0.029924 (sec) File access time, round 5: 0.000808 (sec) File access time, round 6: 0.000771 (sec) File access time, round 7: 0.000746 (sec) File access time, round 8: 0.000738 (sec) File access time, round 9: 0.000747 (sec)
Checked the swap out stats during the test [1], 19006 pages swapped out with this patch, 3418 pages swapped out without this patch. There are more swap out, but I think it's within reasonable range when file backed data set doesn't fit into the memory.
$ ./thrash 2000 100 2100 5 1 # ANON_MB FILE_EXEC FILE_NOEXEC ROUNDS PROCESSES Allocate 2000 MB anonymous pages active_anon: 1613644, inactive_anon: 348656, active_file: 892, inactive_file: 1384 (kB) pswpout: 7972443, pgpgin: 478615246 Access 100 MB executable file pages Access 2100 MB regular file pages File access time, round 0: 12.165, (sec) active_anon: 1433788, inactive_anon: 478116, active_file: 17896, inactive_file: 24328 (kB) File access time, round 1: 11.493, (sec) active_anon: 1430576, inactive_anon: 477144, active_file: 25440, inactive_file: 26172 (kB) File access time, round 2: 11.455, (sec) active_anon: 1427436, inactive_anon: 476060, active_file: 21112, inactive_file: 28808 (kB) File access time, round 3: 11.454, (sec) active_anon: 1420444, inactive_anon: 473632, active_file: 23216, inactive_file: 35036 (kB) File access time, round 4: 11.479, (sec) active_anon: 1413964, inactive_anon: 471460, active_file: 31728, inactive_file: 32224 (kB) pswpout: 7991449 (+ 19006), pgpgin: 489924366 (+ 11309120)
With 4 processes accessing non-overlapping parts of a large file, 30316 pages swapped out with this patch, 5152 pages swapped out without this patch. The swapout number is small comparing to pgpgin.
[1]: https://github.com/vovo/testing/blob/master/mem_thrash.c
--- mm/vmscan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
mm/vmscan.c +3 -3
@@ -2120,7 +2120,7 @@ static void shrink_active_list(unsigned* 10TB 320 32GB */ static bool inactive_list_is_low (struct lruvec *lruvec,bool file, -struct scan_control *sc,bool actual_reclaim) +struct scan_control *sc,bool trace) {enum lru_list active_lru = file *LRU_FILE +LRU_ACTIVE ;struct pglist_data *pgdat =lruvec_pgdat (lruvec);
@@ -2146,7 +2146,7 @@ static bool inactive_list_is_low(struct* rid of the stale workingset quickly. */ refaults =lruvec_page_state (lruvec,WORKINGSET_ACTIVATE ); -if (file && actual_reclaim && lruvec->refaults != refaults) { +if (file && lruvec->refaults != refaults) { inactive_ratio =0 ; }else { gb = (inactive + active) >> (30 -PAGE_SHIFT );
@@ -2156,7 +2156,7 @@ static bool inactive_list_is_low(struct inactive_ratio =1 ; } -if (actual_reclaim) +if (trace) trace_mm_vmscan_inactive_list_is_low(pgdat->node_id, sc->reclaim_idx, lruvec_lru_size(lruvec, inactive_lru, MAX_NR_ZONES), inactive, lruvec_lru_size(lruvec, active_lru, MAX_NR_ZONES), active,
Greg Kroah-Hartman
maintainerPATCH 215/293 perf/events/amd/uncore: Fix amd_uncore_llc ID to use pre-defined cpu_llc_id
In reply to Greg Kroah-Hartman[ Upstream commit 812af433038f984fd951224e8239b09188e36a13 ]
Current logic iterates over CPUID Fn8000001d leafs (Cache Properties) to detect the last level cache, and derive the last-level cache ID. However, this information is already available in the cpu_llc_id. Therefore, make use of it instead.
--- arch/x86/events/amd/uncore.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-)
arch/x86/events/amd/uncore.c +2 -19
@@ -19,6 +19,7 @@#include <asm/cpufeature.h> #include <asm/perf_event.h> #include <asm/msr.h> +#include <asm/smp.h> #define NUM_COUNTERS_NB 4#define NUM_COUNTERS_L2 4
@@ -414,26 +415,8 @@ static int amd_uncore_cpu_starting(unsigned int cpu) }if (amd_uncore_llc) { -unsigned int apicid =cpu_data (cpu).apicid; -unsigned int nshared, subleaf, prev_eax =0 ; - uncore = *per_cpu_ptr (amd_uncore_llc, cpu); -/* -* Iterate over Cache Topology Definition leaves until no -* more cache descriptions are available. -*/ -for (subleaf =0 ; subleaf <5 ; subleaf++) { -cpuid_count (0x8000001d , subleaf, &eax, &ebx, &ecx, &edx); - -/* EAX[0:4] gives type of cache */ -if (!(eax &0x1f )) -break ; - - prev_eax = eax; - } - nshared = ((prev_eax >>14 ) &0xfff ) +1 ; - - uncore->id = apicid - (apicid % nshared); + uncore->id =per_cpu (cpu_llc_id, cpu); uncore =amd_uncore_find_online_sibling (uncore, amd_uncore_llc); *per_cpu_ptr (amd_uncore_llc, cpu) = uncore;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 216/293 NFSv4: Fix open create exclusive when the server reboots
In reply to Greg Kroah-Hartman[ Upstream commit 8fd1ab747d2b1ec7ec663ad0b41a32eaa35117a8 ]
If the server that does not implement NFSv4.1 persistent session semantics reboots while we are performing an exclusive create, then the return value of NFS4ERR_DELAY when we replay the open during the grace period causes us to lose the verifier. When the grace period expires, and we present a new verifier, the server will then correctly reply NFS4ERR_EXIST.
This commit ensures that we always present the same verifier when replaying the OPEN.
--- fs/nfs/nfs4proc.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-)
fs/nfs/nfs4proc.c +26 -15
@@ -1099,6 +1099,12 @@ struct nfs4_opendata {int rpc_status; }; +struct nfs4_open_createattrs { +struct nfs4_label *label; +struct iattr *sattr; +const __u32 verf[2 ]; +}; +static bool nfs4_clear_cap_atomic_open_v1 (struct nfs_server *server,int err,struct nfs4_exception *exception) {
@@ -1168,8 +1174,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)static struct nfs4_opendata *nfs4_opendata_alloc (struct dentry *dentry,struct nfs4_state_owner *sp,fmode_t fmode,int flags, -const struct iattr *attrs, -struct nfs4_label *label, +const struct nfs4_open_createattrs *c,enum open_claim_type4 claim,gfp_t gfp_mask) {
@@ -1177,6 +1182,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,struct inode *dir =d_inode (parent);struct nfs_server *server =NFS_SERVER (dir);struct nfs_seqid *(*alloc_seqid)(struct nfs_seqid_counter *,gfp_t ); +struct nfs4_label *label = (c !=NULL ) ? c->label :NULL ;struct nfs4_opendata *p; p =kzalloc (sizeof (*p), gfp_mask);
@@ -1242,15 +1248,11 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,case NFS4_OPEN_CLAIM_DELEG_PREV_FH : p->o_arg.fh =NFS_FH (d_inode (dentry)); } -if (attrs !=NULL && attrs->ia_valid !=0 ) { -__u32 verf[2 ]; - +if (c !=NULL && c->sattr !=NULL && c->sattr->ia_valid !=0 ) { p->o_arg.u.attrs = &p->attrs; -memcpy (&p->attrs, attrs,sizeof (p->attrs)); +memcpy (&p->attrs, c->sattr,sizeof (p->attrs)); - verf[0 ] = jiffies; - verf[1 ] = current->pid; -memcpy (p->o_arg.u.verifier.data, verf, +memcpy (p->o_arg.u.verifier.data, c->verf,sizeof (p->o_arg.u.verifier.data)); } p->c_arg.fh = &p->o_res.fh;
@@ -1816,7 +1818,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_contextstruct nfs4_opendata *opendata; opendata =nfs4_opendata_alloc (ctx->dentry, state->owner,0 ,0 , -NULL ,NULL , claim,GFP_NOFS ); +NULL , claim,GFP_NOFS );if (opendata ==NULL )return ERR_PTR (-ENOMEM ); opendata->state = state;
@@ -2757,8 +2759,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,static int _nfs4_do_open (struct inode *dir,struct nfs_open_context *ctx,int flags, -struct iattr *sattr, -struct nfs4_label *label, +const struct nfs4_open_createattrs *c,int *opened) {struct nfs4_state_owner *sp;
@@ -2770,6 +2771,8 @@ static int _nfs4_do_open(struct inode *dir,struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;fmode_t fmode = ctx->mode & (FMODE_READ |FMODE_WRITE |FMODE_EXEC );enum open_claim_type4 claim =NFS4_OPEN_CLAIM_NULL ; +struct iattr *sattr = c->sattr; +struct nfs4_label *label = c->label;struct nfs4_label *olabel =NULL ;int status;
@@ -2788,8 +2791,8 @@ static int _nfs4_do_open(struct inode *dir, status = -ENOMEM ;if (d_really_is_positive (dentry)) claim =NFS4_OPEN_CLAIM_FH ; - opendata =nfs4_opendata_alloc (dentry, sp, fmode, flags, sattr, - label, claim,GFP_KERNEL ); + opendata =nfs4_opendata_alloc (dentry, sp, fmode, flags, + c, claim,GFP_KERNEL );if (opendata ==NULL ) goto err_put_state_owner;
@@ -2870,10 +2873,18 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,struct nfs_server *server =NFS_SERVER (dir);struct nfs4_exception exception = { };struct nfs4_state *res; +struct nfs4_open_createattrs c = { + .label = label, + .sattr = sattr, + .verf = { + [0 ] = (__u32 )jiffies, + [1 ] = (__u32 )current->pid, + }, + };int status; do { - status = _nfs4_do_open(dir, ctx, flags, sattr, label, opened); + status = _nfs4_do_open(dir, ctx, flags, &c, opened); res = ctx->state; trace_nfs4_open_file(ctx, flags, status); if (status == 0)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 217/293 nfsd: increase DRC cache limit
In reply to Greg Kroah-Hartman[ Upstream commit 44d8660d3bb0a1c8363ebcb906af2343ea8e15f6 ]
An NFSv4.1+ client negotiates the size of its duplicate reply cache size in the initial CREATE_SESSION request. The server preallocates the memory for the duplicate reply cache to ensure that we'll never fail to record the response to a nonidempotent operation.
To prevent a few CREATE_SESSIONs from consuming all of memory we set an upper limit based on nr_free_buffer_pages(). 1/2^10 has been too limiting in practice; 1/2^7 is still less than one percent.
--- fs/nfsd/nfssvc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfssvc.c +1 -1
@@ -447,7 +447,7 @@ void nfsd_reset_versions(void)*/ static void set_max_drc (void ) { -#define NFSD_DRC_SIZE_SHIFT 10 +#define NFSD_DRC_SIZE_SHIFT 7 nfsd_drc_max_mem = (nr_free_buffer_pages () >>NFSD_DRC_SIZE_SHIFT ) *PAGE_SIZE ; nfsd_drc_mem_used =0 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 218/293 nfsd: give out fewer session slots as limit approaches
In reply to Greg Kroah-Hartman[ Upstream commit de766e570413bd0484af0b580299b495ada625c3 ]
Instead of granting client's full requests until we hit our DRC size limit and then failing CREATE_SESSIONs (and hence mounts) completely, start granting clients smaller slot tables as we approach the limit.
The factor chosen here is pretty much arbitrary.
--- fs/nfsd/nfs4state.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/nfsd/nfs4state.c +5 -0
@@ -1507,6 +1507,11 @@ static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca)spin_lock (&nfsd_drc_lock); avail =min ((unsigned long )NFSD_MAX_MEM_PER_SESSION , nfsd_drc_max_mem - nfsd_drc_mem_used); +/* +* Never use more than a third of the remaining memory, +* unless it's the only way to give this client a slot: +*/ + avail =clamp_t (int, avail, slotsize, avail/3 ); num =min_t (int, num, avail / slotsize); nfsd_drc_mem_used += num * slotsize;spin_unlock (&nfsd_drc_lock);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 219/293 nfsd: fix performance-limiting session calculation
In reply to Greg Kroah-Hartman[ Upstream commit c54f24e338ed2a35218f117a4a1afb5f9e2b4e64 ]
We're unintentionally limiting the number of slots per nfsv4.1 session to 10. Often more than 10 simultaneous RPCs are needed for the best performance.
This calculation was meant to prevent any one client from using up more than a third of the limit we set for total memory use across all clients and sessions. Instead, it's limiting the client to a third of the maximum for a single session.
Fix this.
--- fs/nfsd/nfs4state.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/nfsd/nfs4state.c +4 -4
@@ -1502,16 +1502,16 @@ static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca) {u32 slotsize =slot_bytes (ca);u32 num = ca->maxreqs; -int avail; +unsigned long avail, total_avail;spin_lock (&nfsd_drc_lock); - avail =min ((unsigned long )NFSD_MAX_MEM_PER_SESSION , - nfsd_drc_max_mem - nfsd_drc_mem_used); + total_avail = nfsd_drc_max_mem - nfsd_drc_mem_used; + avail =min ((unsigned long )NFSD_MAX_MEM_PER_SESSION , total_avail);/* * Never use more than a third of the remaining memory, * unless it's the only way to give this client a slot: */ - avail =clamp_t (int, avail, slotsize, avail/3 ); + avail =clamp_t (int, avail, slotsize, total_avail/3 ); num =min_t (int, num, avail / slotsize); nfsd_drc_mem_used += num * slotsize;spin_unlock (&nfsd_drc_lock);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 220/293 nfsd: Fix overflow causing non-working mounts on 1 TB machines
In reply to Greg Kroah-Hartman[ Upstream commit 3b2d4dcf71c4a91b420f835e52ddea8192300a3b ]
Since commit 10a68cdf10 (nfsd: fix performance-limiting session calculation) (Linux 5.1-rc1 and 4.19.31), shares from NFS servers with 1 TB of memory cannot be mounted anymore. The mount just hangs on the client.
The gist of commit 10a68cdf10 is the change below.
-avail = clamp_t(int, avail, slotsize, avail/3);
+avail = clamp_t(int, avail, slotsize, total_avail/3);Here are the macros.
#define min_t(type, x, y) __careful_cmp((type)(x), (type)(y), <)
#define clamp_t(type, val, lo, hi) min_t(type, max_t(type, val, lo), hi)total_avail is 8,434,659,328 on the 1 TB machine. clamp_t() casts the values to int, which for 32-bit integers can only hold values −2,147,483,648 (−2^31) through 2,147,483,647 (2^31 − 1).
avail (in the function signature) is just 65536, so that no overflow was happening. Before the commit the assignment would result in 21845, and num = 4.
When using total_avail, it is causing the assignment to be 18446744072226137429 (printed as %lu), and num is then 4164608182.
My next guess is, that nfsd_drc_mem_used is then exceeded, and the server thinks there is no memory available any more for this client.
Updating the arguments of clamp_t() and min_t() to unsigned long fixes the issue.
Now, avail = 65536 (before commit 10a68cdf10 avail = 21845), but num = 4 remains the same.
--- fs/nfsd/nfs4state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4state.c +1 -1
@@ -1511,7 +1511,7 @@ static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca)* Never use more than a third of the remaining memory, * unless it's the only way to give this client a slot: */ - avail =clamp_t (int, avail, slotsize, total_avail/3 ); + avail = clamp_t(unsigned long, avail, slotsize, total_avail/3); num =min_t (int, num, avail / slotsize); nfsd_drc_mem_used += num * slotsize;spin_unlock (&nfsd_drc_lock);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 221/293 hvsock: fix epollout hang from race condition
In reply to Greg Kroah-Hartman[ Upstream commit cb359b60416701c8bed82fec79de25a144beb893 ]
Currently, hvsock can enter into a state where epoll_wait on EPOLLOUT will not return even when the hvsock socket is writable, under some race condition. This can happen under the following sequence:
- fd = socket(hvsocket)
- fd_out = dup(fd)
- fd_in = dup(fd)
- start a writer thread that writes data to fd_out with a combination of epoll_wait(fd_out, EPOLLOUT) and
- start a reader thread that reads data from fd_in with a combination of epoll_wait(fd_in, EPOLLIN)
- On the host, there are two threads that are reading/writing data to the hvsocket
stack:hvs_stream_has_spacehvs_notify_poll_outvsock_pollsock_pollep_poll
Race condition:
check for epollout from ep_poll():
assume no writable space in the socket hvs_stream_has_space() returns 0
check for epollin from ep_poll():
assume socket has some free space < HVS_PKT_LEN(HVS_SEND_BUF_SIZE) hvs_stream_has_space() will clear the channel pending send size host will not notify the guest because the pending send size has
been cleared and so the hvsocket will never mark the socket writable
Now, the EPOLLOUT will never return even if the socket write buffer is empty.
The fix is to set the pending size to the default size and never change it. This way the host will always notify the guest whenever the writable space is bigger than the pending size. The host is already optimized to *only* notify the guest when the pending size threshold boundary is crossed and not everytime.
This change also reduces the cpu usage somewhat since hv_stream_has_space() is in the hotpath of send:
vsock_stream_sendmsg()->hv_stream_has_space()
Earlier hv_stream_has_space was setting/clearing the pending size on every call.
--- net/vmw_vsock/hyperv_transport.c | 44 ++++++++------------------------ 1 file changed, 11 insertions(+), 33 deletions(-)
net/vmw_vsock/hyperv_transport.c +11 -33
@@ -217,18 +217,6 @@ static void hvs_set_channel_pending_send_size(struct vmbus_channel *chan)set_channel_pending_send_size (chan,HVS_PKT_LEN (HVS_SEND_BUF_SIZE )); -/* See hvs_stream_has_space(): we must make sure the host has seen -* the new pending send size, before we can re-check the writable -* bytes. -*/ -virt_mb (); -} - -static void hvs_clear_channel_pending_send_size (struct vmbus_channel *chan) -{ -set_channel_pending_send_size (chan,0 ); - -/* Ditto */ virt_mb (); }
@@ -298,9 +286,6 @@ static void hvs_channel_cb(void *ctx)if (hvs_channel_readable (chan)) sk->sk_data_ready (sk); -/* See hvs_stream_has_space(): when we reach here, the writable bytes -* may be already less than HVS_PKT_LEN(HVS_SEND_BUF_SIZE). -*/ if (hv_get_bytes_to_write (&chan->outbound) >0 ) sk->sk_write_space (sk); }
@@ -328,8 +313,9 @@ static void hvs_open_connection(struct vmbus_channel *chan)struct sockaddr_vm addr;struct sock *sk, *new =NULL ; -struct vsock_sock *vnew; -struct hvsock *hvs, *hvs_new; +struct vsock_sock *vnew =NULL ; +struct hvsock *hvs =NULL ; +struct hvsock *hvs_new =NULL ;int ret; if_type = &chan->offermsg.offer.if_type;
@@ -389,6 +375,13 @@ static void hvs_open_connection(struct vmbus_channel *chan)set_per_channel_state (chan, conn_from_host ? new : sk);vmbus_set_chn_rescind_callback (chan, hvs_close_connection); +/* Set the pending send size to max packet size to always get +* notifications from the host when there is enough writable space. +* The host is optimized to send notifications only when the pending +* size boundary is crossed, and not always. +*/ +hvs_set_channel_pending_send_size (chan); +if (conn_from_host) { new->sk_state =SS_CONNECTED ; sk->sk_ack_backlog++;
@@ -652,23 +645,8 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)static s64 hvs_stream_has_space (struct vsock_sock *vsk) {struct hvsock *hvs = vsk->trans; -struct vmbus_channel *chan = hvs->chan; -s64 ret; - - ret =hvs_channel_writable_bytes (chan); -if (ret >0 ) { -hvs_clear_channel_pending_send_size (chan); - }else { -/* See hvs_channel_cb() */ -hvs_set_channel_pending_send_size (chan); - -/* Re-check the writable bytes to avoid race */ - ret =hvs_channel_writable_bytes (chan); -if (ret >0 ) -hvs_clear_channel_pending_send_size (chan); - } -return ret; +return hvs_channel_writable_bytes (hvs->chan); }static u64 hvs_stream_rcvhiwat (struct vsock_sock *vsk)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 222/293 drm/panel: simple: Fix panel_simple_dsi_probe
In reply to Greg Kroah-Hartman[ Upstream commit 7ad9db66fafb0f0ad53fd2a66217105da5ddeffe ]
In case mipi_dsi_attach() fails remove the registered panel to avoid added panel without corresponding device.
--- drivers/gpu/drm/panel/panel-simple.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/gpu/drm/panel/panel-simple.c +8 -1
@@ -2371,7 +2371,14 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi) dsi->format = desc->format; dsi->lanes = desc->lanes; -return mipi_dsi_attach (dsi); + err =mipi_dsi_attach (dsi); +if (err) { +struct panel_simple *panel =dev_get_drvdata (&dsi->dev); + +drm_panel_remove (&panel->base); + } + +return err; }static int panel_simple_dsi_remove (struct mipi_dsi_device *dsi)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 223/293 usb: core: hub: Disable hub-initiated U1/U2
In reply to Greg Kroah-Hartman[ Upstream commit 561759292774707b71ee61aecc07724905bb7ef1 ]
If the device rejects the control transfer to enable device-initiated U1/U2 entry, then the device will not initiate U1/U2 transition. To improve the performance, the downstream port should not initate transition to U1/U2 to avoid the delay from the device link command response (no packet can be transmitted while waiting for a response from the device). If the device has some quirks and does not implement U1/U2, it may reject all the link state change requests, and the downstream port may resend and flood the bus with more requests. This will affect the device performance even further. This patch disables the hub-initated U1/U2 if the device-initiated U1/U2 entry fails.
Reference: USB 3.2 spec 7.2.4.2.3
--- drivers/usb/core/hub.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
drivers/usb/core/hub.c +16 -12
@@ -3876,6 +3876,9 @@ static int usb_set_lpm_timeout(struct usb_device *udev,* control transfers to set the hub timeout or enable device-initiated U1/U2 * will be successful. * +* If the control transfer to enable device-initiated U1/U2 entry fails, then +* hub-initiated U1/U2 will be disabled. +* * If we cannot set the parent hub U1/U2 timeout, we attempt to let the xHCI * driver know about it. If that call fails, it should be harmless, and just * take up more slightly more bus bandwidth for unnecessary U1/U2 exit latency.
@@ -3930,23 +3933,24 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev,* host know that this link state won't be enabled. */ hcd->driver->disable_usb3_lpm_timeout (hcd, udev, state); - }else { -/* Only a configured device will accept the Set Feature -* U1/U2_ENABLE -*/ -if (udev->actconfig) -usb_set_device_initiated_lpm (udev, state, true); +return ; + } -/* As soon as usb_set_lpm_timeout(timeout) returns 0, the -* hub-initiated LPM is enabled. Thus, LPM is enabled no -* matter the result of usb_set_device_initiated_lpm(). -* The only difference is whether device is able to initiate -* LPM. -*/ +/* Only a configured device will accept the Set Feature +* U1/U2_ENABLE +*/ +if (udev->actconfig && +usb_set_device_initiated_lpm (udev, state, true) ==0 ) {if (state ==USB3_LPM_U1 ) udev->usb3_lpm_u1_enabled =1 ;else if (state ==USB3_LPM_U2 ) udev->usb3_lpm_u2_enabled =1 ; + }else { +/* Don't request U1/U2 entry if the device +* cannot transition to U1/U2. +*/ +usb_set_lpm_timeout (udev, state,0 ); + hcd->driver->disable_usb3_lpm_timeout (hcd, udev, state); } }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 224/293 tty: max310x: Fix invalid baudrate divisors calculator
In reply to Greg Kroah-Hartman[ Upstream commit 35240ba26a932b279a513f66fa4cabfd7af55221 ]
Current calculator doesn't do it' job quite correct. First of all the max310x baud-rates generator supports the divisor being less than 16. In this case the x2/x4 modes can be used to double or quadruple the reference frequency. But the current baud-rate setter function just filters all these modes out by the first condition and setups these modes only if there is a clocks-baud division remainder. The former doesn't seem right at all, since enabling the x2/x4 modes causes the line noise tolerance reduction and should be only used as a last resort to enable a requested too high baud-rate.
Finally the fraction is supposed to be calculated from D = Fref/(c*baud) formulae, but not from D % 16, which causes the precision loss. So to speak the current baud-rate calculator code works well only if the baud perfectly fits to the uart reference input frequency.
Lets fix the calculator by implementing the algo fully compliant with the fractional baud-rate generator described in the datasheet:
D = Fref / (c*baud), where c={16,8,4} is the x1/x2/x4 rate mode respectively, Fref - reference input frequency. The divisor fraction is calculated from the same formulae, but making sure it is found with a resolution of 0.0625 (four bits).
--- drivers/tty/serial/max310x.c | 51 ++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 20 deletions(-)
drivers/tty/serial/max310x.c +31 -20
@@ -494,37 +494,48 @@ static bool max310x_reg_precious(struct device *dev, unsigned int reg)static int max310x_set_baud (struct uart_port *port,int baud) { -unsigned int mode =0 , clk = port->uartclk, div = clk / baud; +unsigned int mode =0 , div =0 , frac =0 , c =0 ,F =0 ; -/* Check for minimal value for divider */ -if (div <16 ) - div =16 ; - -if (clk % baud && (div /16 ) <0x8000 ) { +/* +* Calculate the integer divisor first. Select a proper mode +* in case if the requested baud is too high for the pre-defined +* clocks frequency. +*/ + div = port->uartclk / baud; +if (div <8 ) { +/* Mode x4 */ + c =4 ; + mode =MAX310X_BRGCFG_4XMODE_BIT ; + }else if (div <16 ) {/* Mode x2 */ + c =8 ; mode =MAX310X_BRGCFG_2XMODE_BIT ; - clk = port->uartclk *2 ; - div = clk / baud; - -if (clk % baud && (div /16 ) <0x8000 ) { -/* Mode x4 */ - mode =MAX310X_BRGCFG_4XMODE_BIT ; - clk = port->uartclk *4 ; - div = clk / baud; - } + }else { + c =16 ; } -max310x_port_write (port,MAX310X_BRGDIVMSB_REG , (div /16 ) >>8 ); -max310x_port_write (port,MAX310X_BRGDIVLSB_REG , div /16 ); -max310x_port_write (port,MAX310X_BRGCFG_REG , (div %16 ) | mode); +/* Calculate the divisor in accordance with the fraction coefficient */ + div /= c; +F = c*baud; + +/* Calculate the baud rate fraction */ +if (div >0 ) + frac = (16 *(port->uartclk %F )) /F ; +else + div =1 ; + +max310x_port_write (port,MAX310X_BRGDIVMSB_REG , div >>8 ); +max310x_port_write (port,MAX310X_BRGDIVLSB_REG , div); +max310x_port_write (port,MAX310X_BRGCFG_REG , frac | mode); -return DIV_ROUND_CLOSEST (clk, div); +/* Return the actual baud rate we just programmed */ +return (16 *port->uartclk) / (c*(16 *div + frac)); }static int max310x_update_best_err (unsigned long f,long *besterr) {/* Use baudrate 115200 for calculate error */ -long err = f % (115200 *16 ); +long err = f % (460800 *16 );if ((*besterr <0 ) || (*besterr > err)) { *besterr = err;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 225/293 pinctrl: rockchip: fix leaked of_node references
In reply to Greg Kroah-Hartman[ Upstream commit 3c89c70634bb0b6f48512de873e7a45c7e1fbaa5 ]
The call to of_parse_phandle returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings:
./drivers/pinctrl/pinctrl-rockchip.c:3221:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 3196, but without a corresponding object release within this function. ./drivers/pinctrl/pinctrl-rockchip.c:3223:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 3196, but without a corresponding object release within this function.
--- drivers/pinctrl/pinctrl-rockchip.c | 1 + 1 file changed, 1 insertion(+)
drivers/pinctrl/pinctrl-rockchip.c +1 -0
@@ -2941,6 +2941,7 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, base, &rockchip_regmap_config); } +of_node_put (node); } bank->irq =irq_of_parse_and_map (bank->of_node,0 );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 226/293 tty: serial: cpm_uart - fix init when SMC is relocated
In reply to Greg Kroah-Hartman[ Upstream commit 06aaa3d066db87e8478522d910285141d44b1e58 ]
SMC relocation can also be activated earlier by the bootloader, so the driver's behaviour cannot rely on selected kernel config.
When the SMC is relocated, CPM_CR_INIT_TRX cannot be used.
But the only thing CPM_CR_INIT_TRX does is to clear the rstate and tstate registers, so this can be done manually, even when SMC is not relocated.
--- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/tty/serial/cpm_uart/cpm_uart_core.c +11 -6
@@ -421,7 +421,16 @@ static int cpm_uart_startup(struct uart_port *port)clrbits16 (&pinfo->sccp->scc_sccm,UART_SCCM_RX ); }cpm_uart_initbd (pinfo); -cpm_line_cr_cmd (pinfo,CPM_CR_INIT_TRX ); +if (IS_SMC (pinfo)) { +out_be32 (&pinfo->smcup->smc_rstate,0 ); +out_be32 (&pinfo->smcup->smc_tstate,0 ); +out_be16 (&pinfo->smcup->smc_rbptr, +in_be16 (&pinfo->smcup->smc_rbase)); +out_be16 (&pinfo->smcup->smc_tbptr, +in_be16 (&pinfo->smcup->smc_tbase)); + }else { +cpm_line_cr_cmd (pinfo,CPM_CR_INIT_TRX ); + } }/* Install interrupt handler. */ retval =request_irq (port->irq, cpm_uart_int,0 ,"cpm_uart" , port);
@@ -875,16 +884,14 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);/* -* In case SMC1 is being relocated... +* In case SMC is being relocated... */ -#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH )out_be16 (&up->smc_rbptr,in_be16 (&pinfo->smcup->smc_rbase));out_be16 (&up->smc_tbptr,in_be16 (&pinfo->smcup->smc_tbase));out_be32 (&up->smc_rstate,0 );out_be32 (&up->smc_tstate,0 );out_be16 (&up->smc_brkcr,1 );/* number of break chars */ out_be16 (&up->smc_brkec,0 ); -#endif /* Set up the uart parameters in the * parameter ram.
@@ -898,8 +905,6 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)out_be16 (&up->smc_brkec,0 );out_be16 (&up->smc_brkcr,1 ); -cpm_line_cr_cmd (pinfo,CPM_CR_INIT_TRX ); -/* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 227/293 drm/edid: Fix a missing-check bug in drm_load_edid_firmware()
In reply to Greg Kroah-Hartman[ Upstream commit 9f1f1a2dab38d4ce87a13565cf4dc1b73bef3a5f ]
In drm_load_edid_firmware(), fwstr is allocated by kstrdup(). And fwstr is dereferenced in the following codes. However, memory allocation functions such as kstrdup() may fail and returns NULL. Dereferencing this null pointer may cause the kernel go wrong. Thus we should check this kstrdup() operation.
Further, if kstrdup() returns NULL, we should return ERR_PTR(-ENOMEM) to the caller site.
--- drivers/gpu/drm/drm_edid_load.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/drm_edid_load.c +2 -0
@@ -274,6 +274,8 @@ struct edid *drm_load_edid_firmware(struct drm_connector *connector)* the last one found one as a fallback. */ fwstr =kstrdup (edid_firmware,GFP_KERNEL ); +if (!fwstr) +return ERR_PTR (-ENOMEM ); edidstr = fwstr;while ((edidname =strsep (&edidstr,"," ))) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 228/293 PCI: Return error if cannot probe VF
In reply to Greg Kroah-Hartman[ Upstream commit 76002d8b48c4b08c9bd414517dd295e132ad910b ]
Commit 0e7df22401a3 ("PCI: Add sysfs sriov_drivers_autoprobe to control VF driver binding") allows the user to specify that drivers for VFs of a PF should not be probed, but it actually causes pci_device_probe() to return success back to the driver core in this case. Therefore by all sysfs appearances the device is bound to a driver, the driver link from the device exists as does the device link back from the driver, yet the driver's probe function is never called on the device. We also fail to do any sort of cleanup when we're prohibited from probing the device, the IRQ setup remains in place and we even hold a device reference.
Instead, abort with errno before any setup or references are taken when pci_device_can_probe() prevents us from trying to probe the device.
--- drivers/pci/pci-driver.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/pci/pci-driver.c +7 -6
@@ -415,6 +415,9 @@ static int pci_device_probe(struct device *dev)struct pci_dev *pci_dev =to_pci_dev (dev);struct pci_driver *drv =to_pci_driver (dev->driver); +if (!pci_device_can_probe (pci_dev)) +return -ENODEV ; +pci_assign_irq (pci_dev); error =pcibios_alloc_irq (pci_dev);
@@ -422,12 +425,10 @@ static int pci_device_probe(struct device *dev)return error;pci_dev_get (pci_dev); -if (pci_device_can_probe (pci_dev)) { - error =__pci_device_probe (drv, pci_dev); -if (error) { -pcibios_free_irq (pci_dev); -pci_dev_put (pci_dev); - } + error =__pci_device_probe (drv, pci_dev); +if (error) { +pcibios_free_irq (pci_dev); +pci_dev_put (pci_dev); }return error;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 229/293 drm/bridge: tc358767: read display_props in get_modes()
In reply to Greg Kroah-Hartman[ Upstream commit 3231573065ad4f4ecc5c9147b24f29f846dc0c2f ]
We need to know the link bandwidth to filter out modes we cannot support, so we need to have read the display props before doing the filtering.
To ensure we have up to date display props, call tc_get_display_props() in the beginning of tc_connector_get_modes().
--- drivers/gpu/drm/bridge/tc358767.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/gpu/drm/bridge/tc358767.c +7 -0
@@ -1147,6 +1147,13 @@ static int tc_connector_get_modes(struct drm_connector *connector)struct tc_data *tc =connector_to_tc (connector);struct edid *edid;unsigned int count; +int ret; + + ret =tc_get_display_props (tc); +if (ret <0 ) { +dev_err (tc->dev,"failed to read display props: %d\n" , ret); +return 0 ; + }if (tc->panel && tc->panel->funcs && tc->panel->funcs->get_modes) { count = tc->panel->funcs->get_modes (tc->panel);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 230/293 drm/bridge: sii902x: pixel clock unit is 10kHz instead of 1kHz
In reply to Greg Kroah-Hartman[ Upstream commit 8dbfc5b65023b67397aca28e8adb25c819f6398c ]
The pixel clock unit in the first two registers (0x00 and 0x01) of sii9022 is 10kHz, not 1kHz as in struct drm_display_mode. Division by 10 fixes the issue.
--- drivers/gpu/drm/bridge/sii902x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/sii902x.c +3 -2
@@ -261,10 +261,11 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,struct regmap *regmap = sii902x->regmap;u8 buf[HDMI_INFOFRAME_SIZE (AVI )];struct hdmi_avi_infoframe frame; +u16 pixel_clock_10kHz = adj->clock /10 ;int ret; - buf[0 ] = adj->clock; - buf[1 ] = adj->clock >>8 ; + buf[0 ] = pixel_clock_10kHz &0xff ; + buf[1 ] = pixel_clock_10kHz >>8 ; buf[2 ] = adj->vrefresh; buf[3 ] =0x00 ; buf[4 ] = adj->hdisplay;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 231/293 drm/crc-debugfs: User irqsafe spinlock in drm_crtc_add_crc_entry
In reply to Greg Kroah-Hartman[ Upstream commit 1882018a70e06376234133e69ede9dd743b4dbd9 ]
We can be called from any context, we need to be prepared.
Noticed this while hacking on vkms, which calls this function from a normal worker. Which really upsets lockdep.
--- drivers/gpu/drm/drm_debugfs_crc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_debugfs_crc.c +3 -2
@@ -359,8 +359,9 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,struct drm_crtc_crc *crc = &crtc->crc;struct drm_crtc_crc_entry *entry;int head, tail; +unsigned long flags; -spin_lock (&crc->lock); +spin_lock_irqsave (&crc->lock, flags);/* Caller may not have noticed yet that userspace has stopped reading */ if (!crc->entries) {
@@ -385,7 +386,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, head = (head +1 ) & (DRM_CRC_ENTRIES_NR -1 ); crc->head = head; -spin_unlock (&crc->lock); +spin_unlock_irqrestore (&crc->lock, flags);wake_up_interruptible (&crc->wq);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 232/293 memstick: Fix error cleanup path of memstick_init
In reply to Greg Kroah-Hartman[ Upstream commit 65f1a0d39c289bb6fc85635528cd36c4b07f560e ]
If bus_register fails. On its error handling path, it has cleaned up what it has done. There is no need to call bus_unregister again. Otherwise, if bus_unregister is called, issues such as null-ptr-deref will arise.
Syzkaller report this:
kobject_add_internal failed for memstick (error: -12 parent: bus)
BUG: KASAN: null-ptr-deref in sysfs_remove_file_ns+0x1b/0x40 fs/sysfs/file.c:467 Read of size 8 at addr 0000000000000078 by task syz-executor.0/4460 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xa9/0x10e lib/dump_stack.c:113 __kasan_report+0x171/0x18d mm/kasan/report.c:321 kasan_report+0xe/0x20 mm/kasan/common.c:614 sysfs_remove_file_ns+0x1b/0x40 fs/sysfs/file.c:467 sysfs_remove_file include/linux/sysfs.h:519 [inline] bus_remove_file+0x6c/0x90 drivers/base/bus.c:145 remove_probe_files drivers/base/bus.c:599 [inline] bus_unregister+0x6e/0x100 drivers/base/bus.c:916 ? 0xffffffffc1590000 memstick_init+0x7a/0x1000 [memstick] do_one_initcall+0xb9/0x3b5 init/main.c:914 do_init_module+0xe0/0x330 kernel/module.c:3468 load_module+0x38eb/0x4270 kernel/module.c:3819 __do_sys_finit_module+0x162/0x190 kernel/module.c:3909 do_syscall_64+0x72/0x2a0 arch/x86/entry/common.c:298 entry_SYSCALL_64_after_hwframe+0x49/0xbe
--- drivers/memstick/core/memstick.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/memstick/core/memstick.c +9 -4
@@ -629,13 +629,18 @@ static int __init memstick_init(void)return -ENOMEM ; rc =bus_register (&memstick_bus_type); -if (!rc) - rc =class_register (&memstick_host_class); +if (rc) + goto error_destroy_workqueue; -if (!rc) -return 0 ; + rc =class_register (&memstick_host_class); +if (rc) + goto error_bus_unregister; + +return 0 ; +error_bus_unregister:bus_unregister (&memstick_bus_type); +error_destroy_workqueue:destroy_workqueue (workqueue);return rc;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 233/293 tty/serial: digicolor: Fix digicolor-usart already registered warning
In reply to Greg Kroah-Hartman[ Upstream commit c7ad9ba0611c53cfe194223db02e3bca015f0674 ]
When modprobe/rmmod/modprobe module, if platform_driver_register() fails, the kernel complained,
proc_dir_entry 'driver/digicolor-usart' already registered
WARNING: CPU: 1 PID: 5636 at fs/proc/generic.c:360 proc_register+0x19d/0x270
Fix this by adding uart_unregister_driver() when platform_driver_register() fails.
--- drivers/tty/serial/digicolor-usart.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/tty/serial/digicolor-usart.c +5 -1
@@ -545,7 +545,11 @@ static int __init digicolor_uart_init(void)if (ret)return ret; -return platform_driver_register (&digicolor_uart_platform); + ret =platform_driver_register (&digicolor_uart_platform); +if (ret) +uart_unregister_driver (&digicolor_uart); + +return ret; }module_init (digicolor_uart_init);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 234/293 tty: serial: msm_serial: avoid system lockup condition
In reply to Greg Kroah-Hartman[ Upstream commit ba3684f99f1b25d2a30b6956d02d339d7acb9799 ]
The function msm_wait_for_xmitr can be taken with interrupts disabled. In order to avoid a potential system lockup - demonstrated under stress testing conditions on SoC QCS404/5 - make sure we wait for a bounded amount of time.
Tested on SoC QCS404.
--- drivers/tty/serial/msm_serial.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/tty/serial/msm_serial.c +4 -0
@@ -391,10 +391,14 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base)static inline void msm_wait_for_xmitr (struct uart_port *port) { +unsigned int timeout =500000 ; +while (!(msm_read (port,UART_SR ) &UART_SR_TX_EMPTY )) {if (msm_read (port,UART_ISR ) &UART_ISR_TX_READY )break ;udelay (1 ); +if (!timeout--) +break ; }msm_write (port,UART_CR_CMD_RESET_TX_READY ,UART_CR ); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 235/293 serial: 8250: Fix TX interrupt handling condition
In reply to Greg Kroah-Hartman[ Upstream commit db1b5bc047b3cadaedab3826bba82c3d9e023c4b ]
Interrupt handler checked THRE bit (transmitter holding register empty) in LSR to detect if TX fifo is empty.
In case when there is only receive interrupts the TX handling got called because THRE bit in LSR is set when there is no transmission (FIFO empty). TX handling caused TX stop, which in RS-485 half-duplex mode actually resets receiver FIFO. This is not desired during reception because of possible data loss.
The fix is to check if THRI is set in IER in addition of the TX fifo status. THRI in IER is set when TX is started and cleared when TX is stopped.
This ensures that TX handling is only called when there is really transmission on going and an interrupt for THRE and not when there are only RX interrupts.
--- drivers/tty/serial/8250/8250_port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/serial/8250/8250_port.c +2 -1
@@ -1878,7 +1878,8 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) status =serial8250_rx_chars (up, status); }serial8250_modem_status (up); -if ((!up->dma || up->dma->tx_err) && (status &UART_LSR_THRE )) +if ((!up->dma || up->dma->tx_err) && (status &UART_LSR_THRE ) && + (up->ier &UART_IER_THRI ))serial8250_tx_chars (up);spin_unlock_irqrestore (&port->lock, flags);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 236/293 drm/virtio: Add memory barriers for capset cache.
In reply to Greg Kroah-Hartman[ Upstream commit 9ff3a5c88e1f1ab17a31402b96d45abe14aab9d7 ]
After data is copied to the cache entry, atomic_set is used indicate that the data is the entry is valid without appropriate memory barriers. Similarly the read side was missing the corresponding memory barriers.
--- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 3 +++ drivers/gpu/drm/virtio/virtgpu_vq.c | 2 ++ 2 files changed, 5 insertions(+)
drivers/gpu/drm/virtio/virtgpu_ioctl.c +3 -0
@@ -523,6 +523,9 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev, ret =wait_event_timeout (vgdev->resp_wq,atomic_read (&cache_ent->is_valid),5 *HZ ); +/* is_valid check must proceed before copy of the cache entry. */ +smp_rmb (); + ptr = cache_ent->caps_cache; copy_exit:
drivers/gpu/drm/virtio/virtgpu_vq.c +2 -0
@@ -585,6 +585,8 @@ static void virtio_gpu_cmd_capset_cb(struct virtio_gpu_device *vgdev, cache_ent->id == le32_to_cpu(cmd->capset_id)) {memcpy (cache_ent->caps_cache, resp->capset_data, cache_ent->size); +/* Copy must occur before is_valid is signalled. */ +smp_wmb ();atomic_set (&cache_ent->is_valid,1 );break ; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 237/293 phy: renesas: rcar-gen2: Fix memory leak at error paths
In reply to Greg Kroah-Hartman[ Upstream commit d4a36e82924d3305a17ac987a510f3902df5a4b2 ]
This patch fixes memory leak at error paths of the probe function. In for_each_child_of_node, if the loop returns, the driver should call of_put_node() before returns.
--- drivers/phy/renesas/phy-rcar-gen2.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/phy/renesas/phy-rcar-gen2.c +2 -0
@@ -288,6 +288,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) error =of_property_read_u32 (np,"reg" , &channel_num);if (error || channel_num >2 ) {dev_err (dev,"Invalid \"reg\" property\n" ); +of_node_put (np);return error; } channel->select_mask = select_mask[channel_num];
@@ -303,6 +304,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) &rcar_gen2_phy_ops);if (IS_ERR (phy->phy)) {dev_err (dev,"Failed to create PHY\n" ); +of_node_put (np);return PTR_ERR (phy->phy); }phy_set_drvdata (phy->phy, phy);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 238/293 powerpc/pseries/mobility: prevent cpu hotplug during DT update
In reply to Greg Kroah-Hartman[ Upstream commit e59a175faa8df9d674247946f2a5a9c29c835725 ]
CPU online/offline code paths are sensitive to parts of the device tree (various cpu node properties, cache nodes) that can be changed as a result of a migration.
Prevent CPU hotplug while the device tree potentially is inconsistent.
--- arch/powerpc/platforms/pseries/mobility.c | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/powerpc/platforms/pseries/mobility.c +9 -0
@@ -9,6 +9,7 @@* 2 as published by the Free Software Foundation. */ +#include <linux/cpu.h> #include <linux/kernel.h> #include <linux/kobject.h> #include <linux/smp.h>
@@ -343,11 +344,19 @@ void post_mobility_fixup(void)if (rc)printk (KERN_ERR "Post-mobility activate-fw failed: %d\n" , rc); +/* +* We don't want CPUs to go online/offline while the device +* tree is being updated. +*/ +cpus_read_lock (); + rc =pseries_devicetree_update (MIGRATION_SCOPE );if (rc)printk (KERN_ERR "Post-mobility device tree update " "failed: %d\n" , rc); +cpus_read_unlock (); +/* Possibly switch to a new RFI flush type */ pseries_setup_rfi_flush ();
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 239/293 drm/rockchip: Properly adjust to a true clock in adjusted_mode
In reply to Greg Kroah-Hartman[ Upstream commit 99b9683f2142b20bad78e61f7f829e8714e45685 ]
When fixing up the clock in vop_crtc_mode_fixup() we're not doing it quite correctly. Specifically if we've got the true clock 266666667 Hz, we'll perform this calculation:
266666667 / 1000 => 266666
Later when we try to set the clock we'll do clk_set_rate(266666 * 1000). The common clock framework won't actually pick the proper clock in this case since it always wants clocks <= the specified one.
Let's solve this by using DIV_ROUND_UP.
--- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/rockchip/rockchip_drm_vop.c +2 -1
@@ -861,7 +861,8 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,struct vop *vop =to_vop (crtc); adjusted_mode->clock = -clk_round_rate (vop->dclk, mode->clock *1000 ) /1000 ; +DIV_ROUND_UP (clk_round_rate (vop->dclk, mode->clock *1000 ), +1000 );return true; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 240/293 tty: serial_core: Set port active bit in uart_port_activate
In reply to Greg Kroah-Hartman[ Upstream commit 13b18d35909707571af9539f7731389fbf0feb31 ]
A bug was introduced by commit b3b576461864 ("tty: serial_core: convert uart_open to use tty_port_open"). It caused a constant warning printed into the system log regarding the tty and port counter mismatch:
[ 21.644197] ttyS ttySx: tty_port_close_start: tty->count = 1 port count = 2
in case if session hangup was detected so the warning is printed starting from the second open-close iteration.
Particularly the problem was discovered in situation when there is a serial tty device without hardware back-end being setup. It is considered by the tty-serial subsystems as a hardware problem with session hang up. In this case uart_startup() will return a positive value with TTY_IO_ERROR flag set in corresponding tty_struct instance. The same value will get passed to be returned from the activate() callback and then being returned from tty_port_open(). But since in this case tty_port_block_til_ready() isn't called the TTY_PORT_ACTIVE flag isn't set (while the method had been called before tty_port_open conversion was introduced and the rest of the subsystem code expected the bit being set in this case), which prevents the uart_hangup() method to perform any cleanups including the tty port counter setting to zero. So the next attempt to open/close the tty device will discover the counters mismatch.
In order to fix the problem we need to manually set the TTY_PORT_ACTIVE flag in case if uart_startup() returned a positive value. In this case the hang up procedure will perform a full set of cleanup actions including the port ref-counter resetting.
--- drivers/tty/serial/serial_core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/tty/serial/serial_core.c +6 -1
@@ -1742,6 +1742,7 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty) { struct uart_state *state = container_of(port, struct uart_state, port);struct uart_port *uport; +int ret; uport =uart_port_check (state);if (!uport || uport->flags &UPF_DEAD )
@@ -1752,7 +1753,11 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty)/* * Start up the serial port. */ -return uart_startup (tty, state,0 ); + ret =uart_startup (tty, state,0 ); +if (ret >0 ) +tty_port_set_active (port,1 ); + +return ret; }static const char *uart_type (struct uart_port *port)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 241/293 usb: gadget: Zero ffs_io_data
In reply to Greg Kroah-Hartman[ Upstream commit 508595515f4bcfe36246e4a565cf280937aeaade ]
In some cases the "Allocate & copy" block in ffs_epfile_io() is not executed. Consequently, in such a case ffs_alloc_buffer() is never called and struct ffs_io_data is not initialized properly. This in turn leads to problems when ffs_free_buffer() is called at the end of ffs_epfile_io().
This patch uses kzalloc() instead of kmalloc() in the aio case and memset() in non-aio case to properly initialize struct ffs_io_data.
--- drivers/usb/gadget/function/f_fs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/gadget/function/f_fs.c +4 -2
@@ -1102,11 +1102,12 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)ENTER ();if (!is_sync_kiocb (kiocb)) { - p =kmalloc (sizeof (io_data),GFP_KERNEL ); + p =kzalloc (sizeof (io_data),GFP_KERNEL );if (unlikely (!p))return -ENOMEM ; p->aio = true; }else { +memset (p,0 ,sizeof (*p)); p->aio = false; }
@@ -1138,11 +1139,12 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)ENTER ();if (!is_sync_kiocb (kiocb)) { - p =kmalloc (sizeof (io_data),GFP_KERNEL ); + p =kzalloc (sizeof (io_data),GFP_KERNEL );if (unlikely (!p))return -ENOMEM ; p->aio = true; }else { +memset (p,0 ,sizeof (*p)); p->aio = false; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 242/293 powerpc/pci/of: Fix OF flags parsing for 64bit BARs
In reply to Greg Kroah-Hartman[ Upstream commit df5be5be8735ef2ae80d5ae1f2453cd81a035c4b ]
When the firmware does PCI BAR resource allocation, it passes the assigned addresses and flags (prefetch/64bit/...) via the "reg" property of a PCI device device tree node so the kernel does not need to do resource allocation.
The flags are stored in resource::flags - the lower byte stores PCI_BASE_ADDRESS_SPACE/etc bits and the other bytes are IORESOURCE_IO/etc. Some flags from PCI_BASE_ADDRESS_xxx and IORESOURCE_xxx are duplicated, such as PCI_BASE_ADDRESS_MEM_PREFETCH/PCI_BASE_ADDRESS_MEM_TYPE_64/etc. When parsing the "reg" property, we copy the prefetch flag but we skip on PCI_BASE_ADDRESS_MEM_TYPE_64 which leaves the flags out of sync.
The missing IORESOURCE_MEM_64 flag comes into play under 2 conditions:
1. we remove PCI_PROBE_ONLY for pseries (by hacking pSeries_setup_arch() or by passing "/chosen/linux,pci-probe-only");
2. we request resource alignment (by passing pci=resource_alignment= via the kernel cmd line to request PAGE_SIZE alignment or defining ppc_md.pcibios_default_alignment which returns anything but 0). Note that the alignment requests are ignored if PCI_PROBE_ONLY is enabled.
With 1) and 2), the generic PCI code in the kernel unconditionally decides to:
- reassign the BARs in pci_specified_resource_alignment() (works fine)
- write new BARs to the device - this fails for 64bit BARs as the generic code looks at IORESOURCE_MEM_64 (not set) and writes only lower 32bits of the BAR and leaves the upper 32bit unmodified which breaks BAR mapping in the hypervisor.
This fixes the issue by copying the flag. This is useful if we want to enforce certain BAR alignment per platform as handling subpage sized BARs is proven to cause problems with hotplug (SLOF already aligns BARs to 64k).
--- arch/powerpc/kernel/pci_of_scan.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/kernel/pci_of_scan.c +2 -0
@@ -45,6 +45,8 @@ static unsigned int pci_parse_of_flags(u32 addr0, int bridge)if (addr0 &0x02000000 ) { flags =IORESOURCE_MEM |PCI_BASE_ADDRESS_SPACE_MEMORY ; flags |= (addr0 >>22 ) &PCI_BASE_ADDRESS_MEM_TYPE_64 ; +if (flags &PCI_BASE_ADDRESS_MEM_TYPE_64 ) + flags |=IORESOURCE_MEM_64 ; flags |= (addr0 >>28 ) &PCI_BASE_ADDRESS_MEM_TYPE_1M ;if (addr0 &0x40000000 ) flags |=IORESOURCE_PREFETCH
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 243/293 drm/msm: Depopulate platform on probe failure
In reply to Greg Kroah-Hartman[ Upstream commit 4368a1539c6b41ac3cddc06f5a5117952998804c ]
add_display_components() calls of_platform_populate, and we depopluate on pdev remove, but not when probe fails. So if we get a probe deferral in one of the components, we won't depopulate the platform. This causes the core to keep references to devices which should be destroyed, which causes issues when those same devices try to re-initialize on the next probe attempt.
I think this is the reason we had issues with the gmu's device-managed resources on deferral (worked around in commit 94e3a17f33a5).
--- drivers/gpu/drm/msm/msm_drv.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/gpu/drm/msm/msm_drv.c +11 -3
@@ -1097,16 +1097,24 @@ static int msm_pdev_probe(struct platform_device *pdev) ret =add_gpu_components (&pdev->dev, &match);if (ret) -return ret; + goto fail;/* on all devices that I am aware of, iommu's which can map * any address the cpu can see are used: */ ret =dma_set_mask_and_coherent (&pdev->dev, ~0 );if (ret) -return ret; + goto fail; + + ret =component_master_add_with_match (&pdev->dev, &msm_drm_ops, match); +if (ret) + goto fail; + +return 0 ; -return component_master_add_with_match (&pdev->dev, &msm_drm_ops, match); +fail: +of_platform_depopulate (&pdev->dev); +return ret; }static int msm_pdev_remove (struct platform_device *pdev)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 244/293 serial: mctrl_gpio: Check if GPIO property exisits before requesting it
In reply to Greg Kroah-Hartman[ Upstream commit d99482673f950817b30caf3fcdfb31179b050ce1 ]
This patch adds a check for the GPIOs property existence, before the GPIO is requested. This fixes an issue seen when the 8250 mctrl_gpio support is added (2nd patch in this patch series) on x86 platforms using ACPI.
Here Mika's comments from 2016-08-09:
"
I noticed that with v4.8-rc1 serial console of some of our Broxton systems does not work properly anymore. I'm able to see output but input does not work.
I bisected it down to commit 4ef03d328769eddbfeca1f1c958fdb181a69c341 ("tty/serial/8250: use mctrl_gpio helpers").
The reason why it fails is that in ACPI we do not have names for GPIOs (except when _DSD is used) so we use the "idx" to index into _CRS GPIO resources. Now mctrl_gpio_init_noauto() goes through a list of GPIOs calling devm_gpiod_get_index_optional() passing "idx" of 0 for each. The UART device in Broxton has following (simplified) ACPI description:
Device (URT4)
{
...
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.GPO0", 0x00, ResourceConsumer)
{
0x003A
}
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.GPO0", 0x00, ResourceConsumer)
{
0x003D
}
})In this case it finds the first GPIO (0x003A which happens to be RX pin for that UART), turns it into GPIO which then breaks input for the UART device. This also breaks systems with bluetooth connected to UART (those typically have some GPIOs in their _CRS).
Any ideas how to fix this?
We cannot just drop the _CRS index lookup fallback because that would break many existing machines out there so maybe we can limit this to only DT enabled machines. Or alternatively probe if the property first exists before trying to acquire the GPIOs (using device_property_present()).
"
This patch implements the fix suggested by Mika in his statement above.
--- drivers/tty/serial/serial_mctrl_gpio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/tty/serial/serial_mctrl_gpio.c +14 -0
@@ -21,6 +21,7 @@#include <linux/termios.h> #include <linux/serial_core.h> #include <linux/module.h> +#include <linux/property.h> #include "serial_mctrl_gpio.h"
@@ -124,6 +125,19 @@ struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx)for (i =0 ; i <UART_GPIO_MAX ; i++) {enum gpiod_flags flags; +char *gpio_str; +bool present; + +/* Check if GPIO property exists and continue if not */ + gpio_str =kasprintf (GFP_KERNEL ,"%s-gpios" , + mctrl_gpios_desc[i].name); +if (!gpio_str) +continue ; + + present =device_property_present (dev, gpio_str); +kfree (gpio_str); +if (!present) +continue ;if (mctrl_gpios_desc[i].dir_out) flags =GPIOD_OUT_LOW ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 245/293 PCI: sysfs: Ignore lockdep for remove attribute
In reply to Greg Kroah-Hartman[ Upstream commit dc6b698a86fe40a50525433eb8e92a267847f6f9 ]
With CONFIG_PROVE_LOCKING=y, using sysfs to remove a bridge with a device below it causes a lockdep warning, e.g.,
# echo 1 > /sys/class/pci_bus/0000:00/device/0000:00:00.0/remove ============================================ WARNING: possible recursive locking detected ... pci_bus 0000:01: busn_res: [bus 01] is released
The remove recursively removes the subtree below the bridge. Each call uses a different lock so there's no deadlock, but the locks were all created with the same lockdep key so the lockdep checker can't tell them apart.
Mark the "remove" sysfs attribute with __ATTR_IGNORE_LOCKDEP() as it is safe to ignore the lockdep check between different "remove" kernfs instances.
There's discussion about a similar issue in USB at [1], which resulted in 356c05d58af0 ("sysfs: get rid of some lockdep false positives") and e9b526fe7048 ("i2c: suppress lockdep warning on delete_device"), which do basically the same thing for USB "remove" and i2c "delete_device" files.
[1] https://lore.kernel.org/r/[email protected]
--- drivers/pci/pci-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/pci-sysfs.c +1 -1
@@ -496,7 +496,7 @@ static ssize_t remove_store(struct device *dev, struct device_attribute *attr,pci_stop_and_remove_bus_device_locked (to_pci_dev (dev));return count; } -static struct device_attribute dev_remove_attr =__ATTR (remove, +static struct device_attribute dev_remove_attr =__ATTR_IGNORE_LOCKDEP (remove, (S_IWUSR |S_IWGRP ),NULL , remove_store);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 246/293 kbuild: Add -Werror=unknown-warning-option to CLANG_FLAGS
In reply to Greg Kroah-Hartman[ Upstream commit 589834b3a0097a4908f4112eac0ca2feb486fa32 ]
In commit ebcc5928c5d9 ("arm64: Silence gcc warnings about arch ABI drift"), the arm64 Makefile added -Wno-psabi to KBUILD_CFLAGS, which is a GCC only option so clang rightfully complains:
warning: unknown warning option '-Wno-psabi' [-Wunknown-warning-option]
https://clang.llvm.org/docs/DiagnosticsReference.html#wunknown-warning-option
However, by default, this is merely a warning so the build happily goes on with a slew of these warnings in the process.
Commit c3f0d0bc5b01 ("kbuild, LLVMLinux: Add -Werror to cc-option to support clang") worked around this behavior in cc-option by adding -Werror so that unknown flags cause an error. However, this all happens silently and when an unknown flag is added to the build unconditionally like -Wno-psabi, cc-option will always fail because there is always an unknown flag in the list of flags. This manifested as link time failures in the arm64 libstub because -fno-stack-protector didn't get added to KBUILD_CFLAGS.
To avoid these weird cryptic failures in the future, make clang behave like gcc and immediately error when it encounters an unknown flag by adding -Werror=unknown-warning-option to CLANG_FLAGS. This can be added unconditionally for clang because it is supported by at least 3.0.0, according to godbolt [1] and 4.0.0, according to its documentation [2], which is far earlier than we typically support.
[1]: https://godbolt.org/z/7F7rm3
[2]: https://releases.llvm.org/4.0.0/tools/clang/docs/DiagnosticsReference.html#wunknown-warning-option
--- Makefile | 1 + 1 file changed, 1 insertion(+)
Makefile +1 -0
@@ -488,6 +488,7 @@ ifneq ($(GCC_TOOLCHAIN),) CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN) endif CLANG_FLAGS += -no-integrated-as +CLANG_FLAGS += -Werror=unknown-warning-option KBUILD_CFLAGS += $(CLANG_FLAGS) KBUILD_AFLAGS += $(CLANG_FLAGS) export CLANG_FLAGS
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 247/293 PCI: xilinx-nwl: Fix Multi MSI data programming
In reply to Greg Kroah-Hartman[ Upstream commit 181fa434d0514e40ebf6e9721f2b72700287b6e2 ]
According to the PCI Local Bus specification Revision 3.0, section 6.8.1.3 (Message Control for MSI), endpoints that are Multiple Message Capable as defined by bits [3:1] in the Message Control for MSI can request a number of vectors that is power of two aligned.
As specified in section 6.8.1.6 "Message data for MSI", the Multiple Message Enable field (bits [6:4] of the Message Control register) defines the number of low order message data bits the function is permitted to modify to generate its system software allocated vectors.
The MSI controller in the Xilinx NWL PCIe controller supports a number of MSI vectors specified through a bitmap and the hwirq number for an MSI, that is the value written in the MSI data TLP is determined by the bitmap allocation.
For instance, in a situation where two endpoints sitting on the PCI bus request the following MSI configuration, with the current PCI Xilinx bitmap allocation code (that does not align MSI vector allocation on a power of two boundary):
Endpoint #1: Requesting 1 MSI vector - allocated bitmap bits 0 Endpoint #2: Requesting 2 MSI vectors - allocated bitmap bits [1,2]
The bitmap value(s) corresponds to the hwirq number that is programmed into the Message Data for MSI field in the endpoint MSI capability and is detected by the root complex to fire the corresponding MSI irqs. The value written in Message Data for MSI field corresponds to the first bit allocated in the bitmap for Multi MSI vectors.
The current Xilinx NWL MSI allocation code allows a bitmap allocation that is not a power of two boundaries, so endpoint #2, is allowed to toggle Message Data bit[0] to differentiate between its two vectors (meaning that the MSI data will be respectively 0x0 and 0x1 for the two vectors allocated to endpoint #2).
This clearly aliases with the Endpoint #1 vector allocation, resulting in a broken Multi MSI implementation.
Update the code to allocate MSI bitmap ranges with a power of two alignment, fixing the bug.
--- drivers/pci/host/pcie-xilinx-nwl.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/pci/host/pcie-xilinx-nwl.c +5 -6
@@ -485,15 +485,13 @@ static int nwl_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,int i;mutex_lock (&msi->lock); - bit =bitmap_find_next_zero_area (msi->bitmap,INT_PCI_MSI_NR ,0 , - nr_irqs,0 ); -if (bit >=INT_PCI_MSI_NR ) { + bit =bitmap_find_free_region (msi->bitmap,INT_PCI_MSI_NR , +get_count_order (nr_irqs)); +if (bit <0 ) {mutex_unlock (&msi->lock);return -ENOSPC ; } -bitmap_set (msi->bitmap, bit, nr_irqs); -for (i =0 ; i < nr_irqs; i++) { irq_domain_set_info(domain, virq + i, bit + i, &nwl_irq_chip, domain->host_data, handle_simple_irq,
@@ -511,7 +509,8 @@ static void nwl_irq_domain_free(struct irq_domain *domain, unsigned int virq,struct nwl_msi *msi = &pcie->msi;mutex_lock (&msi->lock); -bitmap_clear (msi->bitmap, data->hwirq, nr_irqs); +bitmap_release_region (msi->bitmap, data->hwirq, +get_count_order (nr_irqs));mutex_unlock (&msi->lock); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 248/293 iio: iio-utils: Fix possible incorrect mask calculation
In reply to Greg Kroah-Hartman[ Upstream commit 208a68c8393d6041a90862992222f3d7943d44d6 ]
On some machines, iio-sensor-proxy was returning all 0's for IIO sensor values. It turns out that the bits_used for this sensor is 32, which makes the mask calculation:
*mask = (1 << 32) - 1;
If the compiler interprets the 1 literals as 32-bit ints, it generates undefined behavior depending on compiler version and optimization level. On my system, it optimizes out the shift, so the mask value becomes
*mask = (1) - 1;
With a mask value of 0, iio-sensor-proxy will always return 0 for every axis.
Avoid incorrect 0 values caused by compiler optimization.
See original fix by Brett Dutro <[email protected]> in iio-sensor-proxy:
https://github.com/hadess/iio-sensor-proxy/commit/9615ceac7c134d838660e209726cd86aa2064fd3
--- tools/iio/iio_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/iio/iio_utils.c +2 -2
@@ -159,9 +159,9 @@ int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, *be = (endianchar =='b' ); *bytes = padint /8 ;if (*bits_used ==64 ) - *mask = ~0 ; + *mask = ~(0ULL );else - *mask = (1ULL << *bits_used) -1 ; + *mask = (1ULL << *bits_used) -1ULL ; *is_signed = (signchar =='s' );if (fclose (sysfsfp)) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 249/293 powerpc/xmon: Fix disabling tracing while in xmon
In reply to Greg Kroah-Hartman[ Upstream commit aaf06665f7ea3ee9f9754e16c1a507a89f1de5b1 ]
Commit ed49f7fd6438d ("powerpc/xmon: Disable tracing when entering xmon") added code to disable recording trace entries while in xmon. The commit introduced a variable 'tracing_enabled' to record if tracing was enabled on xmon entry, and used this to conditionally enable tracing during exit from xmon.
However, we are not checking the value of 'fromipi' variable in xmon_core() when setting 'tracing_enabled'. Due to this, when secondary cpus enter xmon, they will see tracing as being disabled already and tracing won't be re-enabled on exit. Fix the same.
--- arch/powerpc/xmon/xmon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/powerpc/xmon/xmon.c +4 -2
@@ -465,8 +465,10 @@ static int xmon_core(struct pt_regs *regs, int fromipi)local_irq_save (flags);hard_irq_disable (); - tracing_enabled =tracing_is_on (); -tracing_off (); +if (!fromipi) { + tracing_enabled =tracing_is_on (); +tracing_off (); + } bp =in_breakpoint_table (regs->nip, &offset);if (bp !=NULL ) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 250/293 recordmcount: Fix spurious mcount entries on powerpc
In reply to Greg Kroah-Hartman[ Upstream commit 80e5302e4bc85a6b685b7668c36c6487b5f90e9a ]
An impending change to enable HAVE_C_RECORDMCOUNT on powerpc leads to warnings such as the following:
# modprobe kprobe_example ftrace-powerpc: Not expected bl: opcode is 3c4c0001 WARNING: CPU: 0 PID: 227 at kernel/trace/ftrace.c:2001 ftrace_bug+0x90/0x318 Modules linked in: CPU: 0 PID: 227 Comm: modprobe Not tainted 5.2.0-rc6-00678-g1c329100b942 #2 NIP: c000000000264318 LR: c00000000025d694 CTR: c000000000f5cd30 REGS: c000000001f2b7b0 TRAP: 0700 Not tainted (5.2.0-rc6-00678-g1c329100b942) MSR: 900000010282b033 <SF,HV,VEC,VSX,EE,FP,ME,IR,DR,RI,LE,TM[E]> CR: 28228222 XER: 00000000 CFAR: c0000000002642fc IRQMASK: 0 <snip> NIP [c000000000264318] ftrace_bug+0x90/0x318 LR [c00000000025d694] ftrace_process_locs+0x4f4/0x5e0 Call Trace: [c000000001f2ba40] [0000000000000004] 0x4 (unreliable) [c000000001f2bad0] [c00000000025d694] ftrace_process_locs+0x4f4/0x5e0 [c000000001f2bb90] [c00000000020ff10] load_module+0x25b0/0x30c0 [c000000001f2bd00] [c000000000210cb0] sys_finit_module+0xc0/0x130 [c000000001f2be20] [c00000000000bda4] system_call+0x5c/0x70 Instruction dump: 419e0018 2f83ffff 419e00bc 2f83ffea 409e00cc 4800001c 0fe00000 3c62ff96 39000001 39400000 386386d0 480000c4 <0fe00000> 3ce20003 39000001 3c62ff96 ---[ end trace 4c438d5cebf78381 ]--- ftrace failed to modify [<c0080000012a0008>] 0xc0080000012a0008 actual: 01:00:4c:3c Initializing ftrace call sites ftrace record flags: 2000000 (0) expected tramp: c00000000006af4c
Looking at the relocation records in __mcount_loc shows a few spurious entries:
RELOCATION RECORDS FOR [__mcount_loc]:
OFFSET TYPE VALUE 0000000000000000 R_PPC64_ADDR64 .text.unlikely+0x0000000000000008 0000000000000008 R_PPC64_ADDR64 .text.unlikely+0x0000000000000014 0000000000000010 R_PPC64_ADDR64 .text.unlikely+0x0000000000000060 0000000000000018 R_PPC64_ADDR64 .text.unlikely+0x00000000000000b4 0000000000000020 R_PPC64_ADDR64 .init.text+0x0000000000000008 0000000000000028 R_PPC64_ADDR64 .init.text+0x0000000000000014
The first entry in each section is incorrect. Looking at the relocation records, the spurious entries correspond to the R_PPC64_ENTRY records:
RELOCATION RECORDS FOR [.text.unlikely]:
OFFSET TYPE VALUE 0000000000000000 R_PPC64_REL64 .TOC.-0x0000000000000008 0000000000000008 R_PPC64_ENTRY *ABS* 0000000000000014 R_PPC64_REL24 _mcount
<snip>
The problem is that we are not validating the return value from get_mcountsym() in sift_rel_mcount(). With this entry, mcountsym is 0, but Elf_r_sym(relp) also ends up being 0. Fix this by ensuring mcountsym is valid before processing the entry.
--- scripts/recordmcount.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
scripts/recordmcount.h +2 -1
@@ -326,7 +326,8 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,if (!mcountsym) mcountsym =get_mcountsym (sym0, relp, str0); -if (mcountsym ==Elf_r_sym (relp) && !is_fake_mcount (relp)) { +if (mcountsym && mcountsym ==Elf_r_sym (relp) && + !is_fake_mcount (relp)) {uint_t const addend =_w (_w (relp->r_offset) - recval + mcount_adjust); mrelp->r_offset = _w(offbase
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 251/293 mfd: core: Set fwnode for created devices
In reply to Greg Kroah-Hartman[ Upstream commit c176c6d7e932662668bcaec2d763657096589d85 ]
The logic for setting the of_node on devices created by mfd did not set the fwnode pointer to match, which caused fwnode-based APIs to malfunction on these devices since the fwnode pointer was null. Fix this.
--- drivers/mfd/mfd-core.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/mfd-core.c +1 -0
@@ -179,6 +179,7 @@ static int mfd_add_device(struct device *parent, int id,for_each_child_of_node (parent->of_node, np) {if (of_device_is_compatible (np, cell->of_compatible)) { pdev->dev.of_node = np; + pdev->dev.fwnode = &np->fwnode;break ; } }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 252/293 mfd: arizona: Fix undefined behavior
In reply to Greg Kroah-Hartman[ Upstream commit 5da6cbcd2f395981aa9bfc571ace99f1c786c985 ]
When the driver is used with a subdevice that is disabled in the kernel configuration, clang gets a little confused about the control flow and fails to notice that n_subdevs is only uninitialized when subdevs is NULL, and we check for that, leading to a false-positive warning:
drivers/mfd/arizona-core.c:1423:19: error: variable 'n_subdevs' is uninitialized when used here
[-Werror,-Wuninitialized]
subdevs, n_subdevs, NULL, 0, NULL);
^~~~~~~~~
drivers/mfd/arizona-core.c:999:15: note: initialize the variable 'n_subdevs' to silence this warning
int n_subdevs, ret, i;
^
= 0Ideally, we would rearrange the code to avoid all those early initializations and have an explicit exit in each disabled case, but it's much easier to chicken out and add one more initialization here to shut up the warning.
--- drivers/mfd/arizona-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mfd/arizona-core.c +1 -1
@@ -1029,7 +1029,7 @@ int arizona_dev_init(struct arizona *arizona)unsigned int reg, val, mask;int (*apply_patch)(struct arizona *) =NULL ;const struct mfd_cell *subdevs =NULL ; -int n_subdevs, ret, i; +int n_subdevs =0 , ret, i;dev_set_drvdata (arizona->dev, arizona);mutex_init (&arizona->clk_lock);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 253/293 mfd: hi655x-pmic: Fix missing return value check for devm_regmap_init_mmio_clk
In reply to Greg Kroah-Hartman[ Upstream commit 7efd105c27fd2323789b41b64763a0e33ed79c08 ]
Since devm_regmap_init_mmio_clk can fail, add return value checking.
--- drivers/mfd/hi655x-pmic.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mfd/hi655x-pmic.c +2 -0
@@ -112,6 +112,8 @@ static int hi655x_pmic_probe(struct platform_device *pdev) pmic->regmap =devm_regmap_init_mmio_clk (dev,NULL , base, &hi655x_regmap_config); +if (IS_ERR (pmic->regmap)) +return PTR_ERR (pmic->regmap);regmap_read (pmic->regmap,HI655X_BUS_ADDR (HI655X_VER_REG ), &pmic->ver);if ((pmic->ver <PMU_VER_START ) || (pmic->ver >PMU_VER_END )) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 254/293 um: Silence lockdep complaint about mmap_sem
In reply to Greg Kroah-Hartman[ Upstream commit 80bf6ceaf9310b3f61934c69b382d4912deee049 ]
When we get into activate_mm(), lockdep complains that we're doing something strange:
WARNING: possible circular locking dependency detected
5.1.0-10252-gb00152307319-dirty #121 Not tainted
------------------------------------------------------
inside.sh/366 is trying to acquire lock:
(____ptrval____) (&(&p->alloc_lock)->rlock){+.+.}, at: flush_old_exec+0x703/0x8d7
but task is already holding lock:
(____ptrval____) (&mm->mmap_sem){++++}, at: flush_old_exec+0x6c5/0x8d7
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&mm->mmap_sem){++++}:
[...]
__lock_acquire+0x12ab/0x139f
lock_acquire+0x155/0x18e
down_write+0x3f/0x98
flush_old_exec+0x748/0x8d7
load_elf_binary+0x2ca/0xddb
[...]
-> #0 (&(&p->alloc_lock)->rlock){+.+.}:
[...]
__lock_acquire+0x12ab/0x139f
lock_acquire+0x155/0x18e
_raw_spin_lock+0x30/0x83
flush_old_exec+0x703/0x8d7
load_elf_binary+0x2ca/0xddb
[...]
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&mm->mmap_sem);
lock(&(&p->alloc_lock)->rlock);
lock(&mm->mmap_sem);
lock(&(&p->alloc_lock)->rlock);
*** DEADLOCK ***
2 locks held by inside.sh/366:
#0: (____ptrval____) (&sig->cred_guard_mutex){+.+.}, at: __do_execve_file+0x12d/0x869
#1: (____ptrval____) (&mm->mmap_sem){++++}, at: flush_old_exec+0x6c5/0x8d7
stack backtrace:
CPU: 0 PID: 366 Comm: inside.sh Not tainted 5.1.0-10252-gb00152307319-dirty #121
Stack:
[...]
Call Trace:
[<600420de>] show_stack+0x13b/0x155
[<6048906b>] dump_stack+0x2a/0x2c
[<6009ae64>] print_circular_bug+0x332/0x343
[<6009c5c6>] check_prev_add+0x669/0xdad
[<600a06b4>] __lock_acquire+0x12ab/0x139f
[<6009f3d0>] lock_acquire+0x155/0x18e
[<604a07e0>] _raw_spin_lock+0x30/0x83
[<60151e6a>] flush_old_exec+0x703/0x8d7
[<601a8eb8>] load_elf_binary+0x2ca/0xddb
[...]I think it's because in exec_mmap() we have
down_read(&old_mm->mmap_sem);
...
task_lock(tsk);
...
activate_mm(active_mm, mm);
(which does down_write(&mm->mmap_sem))I'm not really sure why lockdep throws in the whole knowledge about the task lock, but it seems that old_mm and mm shouldn't ever be the same (and it doesn't deadlock) so tell lockdep that they're different.
--- arch/um/include/asm/mmu_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/include/asm/mmu_context.h +1 -1
@@ -53,7 +53,7 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)* when the new ->mm is used for the first time. */ __switch_mm (&new->context.id); -down_write (&new->mmap_sem); +down_write_nested (&new->mmap_sem,1 );uml_setup_stubs (new);up_write (&new->mmap_sem); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 255/293 powerpc/4xx/uic: clear pending interrupt after irq type/pol change
In reply to Greg Kroah-Hartman[ Upstream commit 3ab3a0689e74e6aa5b41360bc18861040ddef5b1 ]
When testing out gpio-keys with a button, a spurious interrupt (and therefore a key press or release event) gets triggered as soon as the driver enables the irq line for the first time.
This patch clears any potential bogus generated interrupt that was caused by the switching of the associated irq's type and polarity.
--- arch/powerpc/platforms/4xx/uic.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/platforms/4xx/uic.c +1 -0
@@ -158,6 +158,7 @@ static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)mtdcr (uic->dcrbase +UIC_PR , pr);mtdcr (uic->dcrbase +UIC_TR , tr); +mtdcr (uic->dcrbase +UIC_SR , ~mask);raw_spin_unlock_irqrestore (&uic->lock, flags);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 256/293 RDMA/i40iw: Set queue pair state when being queried
In reply to Greg Kroah-Hartman[ Upstream commit 2e67e775845373905d2c2aecb9062c2c4352a535 ]
The API for ib_query_qp requires the driver to set qp_state and cur_qp_state on return, add the missing sets.
--- drivers/infiniband/hw/i40iw/i40iw_verbs.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/infiniband/hw/i40iw/i40iw_verbs.c +2 -0
@@ -821,6 +821,8 @@ static int i40iw_query_qp(struct ib_qp *ibqp,struct i40iw_qp *iwqp =to_iwqp (ibqp);struct i40iw_sc_qp *qp = &iwqp->sc_qp; + attr->qp_state = iwqp->ibqp_state; + attr->cur_qp_state = attr->qp_state; attr->qp_access_flags =0 ; attr->cap.max_send_wr = qp->qp_uk.sq_size; attr->cap.max_recv_wr = qp->qp_uk.rq_size;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 257/293 serial: sh-sci: Terminate TX DMA during buffer flushing
In reply to Greg Kroah-Hartman[ Upstream commit 775b7ffd7d6d5db320d99b0a485c51e04dfcf9f1 ]
While the .flush_buffer() callback clears sci_port.tx_dma_len since commit 1cf4a7efdc71cab8 ("serial: sh-sci: Fix race condition causing garbage during shutdown"), it does not terminate a transmit DMA operation that may be in progress.
Fix this by terminating any pending DMA operations, and resetting the corresponding cookie.
--- drivers/tty/serial/sh-sci.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/tty/serial/sh-sci.c +9 -2
@@ -1571,11 +1571,18 @@ static void sci_free_dma(struct uart_port *port)static void sci_flush_buffer (struct uart_port *port) { +struct sci_port *s =to_sci_port (port); +/* * In uart_flush_buffer(), the xmit circular buffer has just been -* cleared, so we have to reset tx_dma_len accordingly. +* cleared, so we have to reset tx_dma_len accordingly, and stop any +* pending transfers */ -to_sci_port (port)->tx_dma_len =0 ; + s->tx_dma_len =0 ; +if (s->chan_tx) { +dmaengine_terminate_async (s->chan_tx); + s->cookie_tx = -EINVAL ; + } }#else /* !CONFIG_SERIAL_SH_SCI_DMA */ static inline void sci_request_dma (struct uart_port *port)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 258/293 serial: sh-sci: Fix TX DMA buffer flushing and workqueue races
In reply to Greg Kroah-Hartman[ Upstream commit 8493eab02608b0e82f67b892aa72882e510c31d0 ]
When uart_flush_buffer() is called, the .flush_buffer() callback zeroes the tx_dma_len field. This may race with the work queue function handling transmit DMA requests:
1. If the buffer is flushed before the first DMA API call, dmaengine_prep_slave_single() may be called with a zero length, causing the DMA request to never complete, leading to messages like:
rcar-dmac e7300000.dma-controller: Channel Address Error happen
and, with debug enabled:
sh-sci e6e88000.serial: sci_dma_tx_work_fn: ffff800639b55000: 0...0, cookie 126
and DMA timeouts.
2. If the buffer is flushed after the first DMA API call, but before the second, dma_sync_single_for_device() may be called with a zero length, causing the transmit data not to be flushed to RAM, and leading to stale data being output.
Fix this by:
1. Letting sci_dma_tx_work_fn() return immediately if the transmit buffer is empty,
2. Extending the critical section to cover all DMA preparational work, so tx_dma_len stays consistent for all of it,
3. Using local copies of circ_buf.head and circ_buf.tail, to make sure they match the actual operation above.
--- drivers/tty/serial/sh-sci.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
drivers/tty/serial/sh-sci.c +15 -7
@@ -1319,6 +1319,7 @@ static void work_fn_tx(struct work_struct *work)struct uart_port *port = &s->port;struct circ_buf *xmit = &port->state->xmit;dma_addr_t buf; +int head, tail;/* * DMA is idle now.
@@ -1328,16 +1329,23 @@ static void work_fn_tx(struct work_struct *work)* consistent xmit buffer state. */ spin_lock_irq (&port->lock); - buf = s->tx_dma_addr + (xmit->tail & (UART_XMIT_SIZE -1 )); + head = xmit->head; + tail = xmit->tail; + buf = s->tx_dma_addr + (tail & (UART_XMIT_SIZE -1 )); s->tx_dma_len = min_t(unsigned int, -CIRC_CNT (xmit->head, xmit->tail,UART_XMIT_SIZE ), -CIRC_CNT_TO_END (xmit->head, xmit->tail,UART_XMIT_SIZE )); -spin_unlock_irq (&port->lock); +CIRC_CNT (head, tail,UART_XMIT_SIZE ), +CIRC_CNT_TO_END (head, tail,UART_XMIT_SIZE )); +if (!s->tx_dma_len) { +/* Transmit buffer has been flushed */ +spin_unlock_irq (&port->lock); +return ; + } desc =dmaengine_prep_slave_single (chan, buf, s->tx_dma_len,DMA_MEM_TO_DEV ,DMA_PREP_INTERRUPT |DMA_CTRL_ACK );if (!desc) { +spin_unlock_irq (&port->lock);dev_warn (port->dev,"Failed preparing Tx DMA descriptor\n" );/* switch to PIO */ sci_tx_dma_release (s, true);
@@ -1347,20 +1355,20 @@ static void work_fn_tx(struct work_struct *work)dma_sync_single_for_device (chan->device->dev, buf, s->tx_dma_len,DMA_TO_DEVICE ); -spin_lock_irq (&port->lock); desc->callback = sci_dma_tx_complete; desc->callback_param = s; -spin_unlock_irq (&port->lock); s->cookie_tx =dmaengine_submit (desc);if (dma_submit_error (s->cookie_tx)) { +spin_unlock_irq (&port->lock);dev_warn (port->dev,"Failed submitting Tx DMA descriptor\n" );/* switch to PIO */ sci_tx_dma_release (s, true);return ; } +spin_unlock_irq (&port->lock);dev_dbg (port->dev,"%s: %p: %d...%d, cookie %d\n" , - __func__, xmit->buf, xmit->tail, xmit->head, s->cookie_tx); + __func__, xmit->buf, tail, head, s->cookie_tx);dma_async_issue_pending (chan); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 259/293 kallsyms: exclude kasan local symbols on s390
In reply to Greg Kroah-Hartman[ Upstream commit 33177f01ca3fe550146bb9001bec2fd806b2f40c ]
gcc asan instrumentation emits the following sequence to store frame pc when the kernel is built with CONFIG_RELOCATABLE:debug/vsprintf.s:
.section .data.rel.ro.local,"aw"
.align 8
.LC3:
.quad .LASANPC4826@GOTOFF
.text
.align 8
.type number, @function
number:
.LASANPC4826:
and in case reloc is issued for LASANPC label it also gets into .symtab with the same address as actual function symbol:
$ nm -n vmlinux | grep 0000000001397150 0000000001397150 t .LASANPC4826 0000000001397150 t number
In the end kernel backtraces are almost unreadable:
[ 143.748476] Call Trace: [ 143.748484] ([<000000002da3e62c>] .LASANPC2671+0x114/0x190) [ 143.748492] [<000000002eca1a58>] .LASANPC2612+0x110/0x160 [ 143.748502] [<000000002de9d830>] print_address_description+0x80/0x3b0 [ 143.748511] [<000000002de9dd64>] __kasan_report+0x15c/0x1c8 [ 143.748521] [<000000002ecb56d4>] strrchr+0x34/0x60 [ 143.748534] [<000003ff800a9a40>] kasan_strings+0xb0/0x148 [test_kasan] [ 143.748547] [<000003ff800a9bba>] kmalloc_tests_init+0xe2/0x528 [test_kasan] [ 143.748555] [<000000002da2117c>] .LASANPC4069+0x354/0x748 [ 143.748563] [<000000002dbfbb16>] do_init_module+0x136/0x3b0 [ 143.748571] [<000000002dbff3f4>] .LASANPC3191+0x2164/0x25d0 [ 143.748580] [<000000002dbffc4c>] .LASANPC3196+0x184/0x1b8 [ 143.748587] [<000000002ecdf2ec>] system_call+0xd8/0x2d8
Since LASANPC labels are not even unique and get into .symtab only due to relocs filter them out in kallsyms.
--- scripts/kallsyms.c | 3 +++ 1 file changed, 3 insertions(+)
scripts/kallsyms.c +3 -0
@@ -160,6 +160,9 @@ static int read_symbol(FILE *in, struct sym_entry *s)/* exclude debugging symbols */ else if (stype == 'N' || stype == 'n')return -1 ; +/* exclude s390 kasan local symbols */ + else if (!strncmp(sym, ".LASANPC", 8)) +return -1 ;/* include the type field in the symbol name, so that it gets * compressed together */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 260/293 perf test mmap-thread-lookup: Initialize variable to suppress memory sanitizer warning
In reply to Greg Kroah-Hartman[ Upstream commit 4e4cf62b37da5ff45c904a3acf242ab29ed5881d ]
Running the 'perf test' command after building perf with a memory sanitizer causes a warning that says:
WARNING: MemorySanitizer: use-of-uninitialized-value... in mmap-thread-lookup.c
Initializing the go variable to 0 silences this harmless warning.
Committer warning:
This was harmless, just a simple test writing whatever was at that sizeof(int) memory area just to signal another thread blocked reading that file created with pipe(). Initialize it tho so that we don't get this warning.
--- tools/perf/tests/mmap-thread-lookup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/tests/mmap-thread-lookup.c +1 -1
@@ -52,7 +52,7 @@ static void *thread_fn(void *arg) {struct thread_data *td = arg;ssize_t ret; -int go; +int go =0 ;if (thread_init (td))return NULL ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 261/293 perf session: Fix potential NULL pointer dereference found by the smatch tool
In reply to Greg Kroah-Hartman[ Upstream commit f3c8d90757724982e5f07cd77d315eb64ca145ac ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/util/session.c:1252
dump_read() error: we previously assumed 'evsel' could be null (see line 1249)
tools/perf/util/session.c
1240 static void dump_read(struct perf_evsel *evsel, union perf_event *event)
1241 {
1242 struct read_event *read_event = &event->read;
1243 u64 read_format;
1244
1245 if (!dump_trace)
1246 return;
1247
1248 printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid,
1249 evsel ? perf_evsel__name(evsel) : "FAIL",
1250 event->read.value);
1251
1252 read_format = evsel->attr.read_format;
^^^^^^^'evsel' could be NULL pointer, for this case this patch directly bails out without dumping read_event.
--- tools/perf/util/session.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/util/session.c +3 -0
@@ -1145,6 +1145,9 @@ static void dump_read(struct perf_evsel *evsel, union perf_event *event) evsel ?perf_evsel__name (evsel) :"FAIL" , event->read.value); +if (!evsel) +return ; + read_format = evsel->attr.read_format;if (read_format &PERF_FORMAT_TOTAL_TIME_ENABLED )
Signature · 9 lines
2.20.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Greg Kroah-Hartman
maintainerPATCH 262/293 perf annotate: Fix dereferencing freed memory found by the smatch tool
In reply to Greg Kroah-Hartman[ Upstream commit 600c787dbf6521d8d07ee717ab7606d5070103ea ]
Based on the following report from Smatch, fix the potential dereferencing freed memory check.
tools/perf/util/annotate.c:1125
disasm_line__parse() error: dereferencing freed memory 'namep'
tools/perf/util/annotate.c
1100 static int disasm_line__parse(char *line, const char **namep, char **rawp)
1101 {
1102 char tmp, *name = ltrim(line);[...]
1114 *namep = strdup(name); 1115 1116 if (*namep == NULL) 1117 goto out_free_name;
[...]
1124 out_free_name:
1125 free((void *)namep);
^^^^^
1126 *namep = NULL;
^^^^^^
1127 return -1;
1128 }If strdup() fails to allocate memory space for *namep, we don't need to free memory with pointer 'namep', which is resident in data structure disasm_line::ins::name; and *namep is NULL pointer for this failure, so it's pointless to assign NULL to *namep again.
Committer note:
Freeing namep, which is the address of the first entry of the 'struct ins' that is the first member of struct disasm_line would in fact free that disasm_line instance, if it was allocated via malloc/calloc, which, later, would a dereference of freed memory.
--- tools/perf/util/annotate.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
tools/perf/util/annotate.c +2 -4
@@ -868,16 +868,14 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp) *namep =strdup (name);if (*namep ==NULL ) - goto out_free_name; + goto out; (*rawp)[0 ] = tmp; *rawp =ltrim (*rawp);return 0 ; -out_free_name: -free ((void *)namep); - *namep =NULL ; +out:return -1 ; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 263/293 RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM
In reply to Greg Kroah-Hartman[ Upstream commit bdce1290493caa3f8119f24b5dacc3fb7ca27389 ]
Calculate the correct byte_len on the receiving side when a work completion is generated with IB_WC_RECV_RDMA_WITH_IMM opcode.
According to the IBA byte_len must indicate the number of written bytes, whereas it was always equal to zero for the IB_WC_RECV_RDMA_WITH_IMM opcode, even though data was transferred.
--- drivers/infiniband/sw/rxe/rxe_resp.c | 5 ++++- drivers/infiniband/sw/rxe/rxe_verbs.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/infiniband/sw/rxe/rxe_resp.c +4 -1
@@ -435,6 +435,7 @@ static enum resp_states check_rkey(struct rxe_qp *qp, qp->resp.va =reth_va (pkt); qp->resp.rkey =reth_rkey (pkt); qp->resp.resid =reth_len (pkt); + qp->resp.length =reth_len (pkt); } access = (pkt->mask &RXE_READ_MASK ) ?IB_ACCESS_REMOTE_READ :IB_ACCESS_REMOTE_WRITE ;
@@ -860,7 +861,9 @@ static enum resp_states do_complete(struct rxe_qp *qp, pkt->mask & RXE_WRITE_MASK) ?IB_WC_RECV_RDMA_WITH_IMM :IB_WC_RECV ; wc->vendor_err =0 ; - wc->byte_len = wqe->dma.length - wqe->dma.resid; + wc->byte_len = (pkt->mask &RXE_IMMDT_MASK && + pkt->mask &RXE_WRITE_MASK ) ? + qp->resp.length : wqe->dma.length - wqe->dma.resid;/* fields after byte_len are different between kernel and user * space
drivers/infiniband/sw/rxe/rxe_verbs.h +1 -0
@@ -214,6 +214,7 @@ struct rxe_resp_info {struct rxe_mem *mr;u32 resid;u32 rkey; +u32 length;u64 atomic_orig;/* SRQ only */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 264/293 PCI: dwc: pci-dra7xx: Fix compilation when !CONFIG_GPIOLIB
In reply to Greg Kroah-Hartman[ Upstream commit 381ed79c8655a40268ee7391f716edd90c5c3a97 ]
If CONFIG_GPIOLIB is not selected the compilation results in the following build errors:
drivers/pci/controller/dwc/pci-dra7xx.c:
In function dra7xx_pcie_probe:drivers/pci/controller/dwc/pci-dra7xx.c:777:10:
error: implicit declaration of function devm_gpiod_get_optional;
did you mean devm_regulator_get_optional? [-Werror=implicit-function-declaration]
reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
drivers/pci/controller/dwc/pci-dra7xx.c:778:45: error: ‘GPIOD_OUT_HIGH’ undeclared (first use in this function); did you mean ‘GPIOF_INIT_HIGH’?
reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
^~~~~~~~~~~~~~
GPIOF_INIT_HIGHFix them by including the appropriate header file.
--- drivers/pci/dwc/pci-dra7xx.c | 1 + 1 file changed, 1 insertion(+)
drivers/pci/dwc/pci-dra7xx.c +1 -0
@@ -29,6 +29,7 @@#include <linux/types.h> #include <linux/mfd/syscon.h> #include <linux/regmap.h> +#include <linux/gpio/consumer.h> #include "pcie-designware.h"
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 265/293 powerpc/boot: add {get, put}_unaligned_be32 to xz_config.h
In reply to Greg Kroah-Hartman[ Upstream commit 9e005b761e7ad153dcf40a6cba1d681fe0830ac6 ]
The next commit will make the way of passing CONFIG options more robust. Unfortunately, it would uncover another hidden issue; without this commit, skiroot_defconfig would be broken like this:
| WRAP arch/powerpc/boot/zImage.pseries | arch/powerpc/boot/wrapper.a(decompress.o): In function `bcj_powerpc.isra.10': | decompress.c:(.text+0x720): undefined reference to `get_unaligned_be32' | decompress.c:(.text+0x7a8): undefined reference to `put_unaligned_be32' | make[1]: *** [arch/powerpc/boot/Makefile;383: arch/powerpc/boot/zImage.pseries] Error 1 | make: *** [arch/powerpc/Makefile;295: zImage] Error 2
skiroot_defconfig is the only defconfig that enables CONFIG_KERNEL_XZ for ppc, which has never been correctly built before.
I figured out the root cause in lib/decompress_unxz.c:
| #ifdef CONFIG_PPC | # define XZ_DEC_POWERPC | #endif
CONFIG_PPC is undefined here in the ppc bootwrapper because autoconf.h is not included except by arch/powerpc/boot/serial.c
XZ_DEC_POWERPC is not defined, therefore, bcj_powerpc() is not compiled for the bootwrapper.
With the next commit passing CONFIG_PPC correctly, we would realize that {get,put}_unaligned_be32 was missing.
Unlike the other decompressors, the ppc bootwrapper duplicates all the necessary helpers in arch/powerpc/boot/.
The other architectures define __KERNEL__ and pull in helpers for building the decompressors.
If ppc bootwrapper had defined __KERNEL__, lib/xz/xz_private.h would have included <asm/unaligned.h>:
| #ifdef __KERNEL__ | # include <linux/xz.h> | # include <linux/kernel.h> | # include <asm/unaligned.h>
However, doing so would cause tons of definition conflicts since the bootwrapper has duplicated everything.
I just added copies of {get,put}_unaligned_be32, following the bootwrapper coding convention.
--- arch/powerpc/boot/xz_config.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
arch/powerpc/boot/xz_config.h +20 -0
@@ -20,10 +20,30 @@ static inline uint32_t swab32p(void *p)#ifdef __LITTLE_ENDIAN__#define get_le32 (p) (*((uint32_t *) (p))) +#define cpu_to_be32 (x) swab32(x) +static inline u32 be32_to_cpup (const u32 *p) +{ +return swab32p ((u32 *)p); +}#else #define get_le32 (p) swab32p(p) +#define cpu_to_be32 (x) (x) +static inline u32 be32_to_cpup (const u32 *p) +{ +return *p; +}#endif +static inline uint32_t get_unaligned_be32 (const void *p) +{ +return be32_to_cpup (p); +} + +static inline void put_unaligned_be32 (u32 val,void *p) +{ + *((u32 *)p) =cpu_to_be32 (val); +} +#define memeq (a, b, size) (memcmp(a, b, size) == 0)#define memzero (buf, size) memset(buf, 0, size)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 266/293 f2fs: avoid out-of-range memory access
In reply to Greg Kroah-Hartman[ Upstream commit 56f3ce675103e3fb9e631cfb4131fc768bc23e9a ]
blkoff_off might over 512 due to fs corrupt or security vulnerability. That should be checked before being using.
Use ENTRIES_IN_SUM to protect invalid value in cur_data_blkoff.
--- fs/f2fs/segment.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/f2fs/segment.c +5 -0
@@ -2612,6 +2612,11 @@ static int read_compacted_summaries(struct f2fs_sb_info *sbi) seg_i =CURSEG_I (sbi, i); segno =le32_to_cpu (ckpt->cur_data_segno[i]); blk_off =le16_to_cpu (ckpt->cur_data_blkoff[i]); +if (blk_off >ENTRIES_IN_SUM ) { +f2fs_bug_on (sbi,1 ); +f2fs_put_page (page,1 ); +return -EFAULT ; + } seg_i->next_segno = segno;reset_curseg (sbi, i,0 ); seg_i->alloc_type = ckpt->alloc_type[i];
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 267/293 mailbox: handle failed named mailbox channel request
In reply to Greg Kroah-Hartman[ Upstream commit 25777e5784a7b417967460d4fcf9660d05a0c320 ]
Previously, if mbox_request_channel_byname was used with a name which did not exist in the "mbox-names" property of a mailbox client, the mailbox corresponding to the last entry in the "mbox-names" list would be incorrectly selected.
With this patch, -EINVAL is returned if the named mailbox is not found.
--- drivers/mailbox/mailbox.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/mailbox/mailbox.c +4 -2
@@ -391,11 +391,13 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,of_property_for_each_string (np,"mbox-names" , prop, mbox_name) {if (!strncmp (name, mbox_name,strlen (name))) -break ; +return mbox_request_channel (cl, index); index++; } -return mbox_request_channel (cl, index); +dev_err (cl->dev,"%s() could not locate channel named \"%s\"\n" , + __func__, name); +return ERR_PTR (-EINVAL ); }EXPORT_SYMBOL_GPL (mbox_request_channel_byname);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 268/293 powerpc/eeh: Handle hugepages in ioremap space
In reply to Greg Kroah-Hartman[ Upstream commit 33439620680be5225c1b8806579a291e0d761ca0 ]
In commit 4a7b06c157a2 ("powerpc/eeh: Handle hugepages in ioremap space") support for using hugepages in the vmalloc and ioremap areas was enabled for radix. Unfortunately this broke EEH MMIO error checking.
Detection works by inserting a hook which checks the results of the ioreadXX() set of functions. When a read returns a 0xFFs response we need to check for an error which we do by mapping the (virtual) MMIO address back to a physical address, then mapping physical address to a PCI device via an interval tree.
When translating virt -> phys we currently assume the ioremap space is only populated by PAGE_SIZE mappings. If a hugepage mapping is found we emit a WARN_ON(), but otherwise handles the check as though a normal page was found. In pathalogical cases such as copying a buffer containing a lot of 0xFFs from BAR memory this can result in the system not booting because it's too busy printing WARN_ON()s.
There's no real reason to assume huge pages can't be present and we're prefectly capable of handling them, so do that.
--- arch/powerpc/kernel/eeh.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
arch/powerpc/kernel/eeh.c +12 -3
@@ -361,10 +361,19 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) ptep =find_init_mm_pte (token, &hugepage_shift);if (!ptep)return token; -WARN_ON (hugepage_shift); - pa =pte_pfn (*ptep) <<PAGE_SHIFT ; -return pa | (token & (PAGE_SIZE -1 )); + pa =pte_pfn (*ptep); + +/* On radix we can do hugepage mappings for io, so handle that */ +if (hugepage_shift) { + pa <<= hugepage_shift; + pa |= token & ((1ul << hugepage_shift) -1 ); + }else { + pa <<=PAGE_SHIFT ; + pa |= token & (PAGE_SIZE -1 ); + } + +return pa; }/*
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 269/293 block/bio-integrity: fix a memory leak bug
In reply to Greg Kroah-Hartman[ Upstream commit e7bf90e5afe3aa1d1282c1635a49e17a32c4ecec ]
In bio_integrity_prep(), a kernel buffer is allocated through kmalloc() to hold integrity metadata. Later on, the buffer will be attached to the bio structure through bio_integrity_add_page(), which returns the number of bytes of integrity metadata attached. Due to unexpected situations, bio_integrity_add_page() may return 0. As a result, bio_integrity_prep() needs to be terminated with 'false' returned to indicate this error. However, the allocated kernel buffer is not freed on this execution path, leading to a memory leak.
To fix this issue, free the allocated buffer before returning from bio_integrity_prep().
--- block/bio-integrity.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
block/bio-integrity.c +6 -2
@@ -313,8 +313,12 @@ bool bio_integrity_prep(struct bio *bio) ret =bio_integrity_add_page (bio,virt_to_page (buf), bytes, offset); -if (ret ==0 ) -return false; +if (ret ==0 ) { +printk (KERN_ERR "could not attach integrity payload\n" ); +kfree (buf); + status =BLK_STS_RESOURCE ; + goto err_end_io; + }if (ret < bytes)break ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 270/293 sh: prevent warnings when using iounmap
In reply to Greg Kroah-Hartman[ Upstream commit 733f0025f0fb43e382b84db0930ae502099b7e62 ]
When building drm/exynos for sh, as part of an allmodconfig build, the following warning triggered:
exynos7_drm_decon.c: In function `decon_remove':
exynos7_drm_decon.c:769:24: warning: unused variable `ctx'
struct decon_context *ctx = dev_get_drvdata(&pdev->dev);
The ctx variable is only used as argument to iounmap().
In sh - allmodconfig CONFIG_MMU is not defined
so it ended up in:
\#define __iounmap(addr) do { } while (0)
\#define iounmap __iounmap
Fix the warning by introducing a static inline function for iounmap.
This is similar to several other architectures.
--- arch/sh/include/asm/io.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/sh/include/asm/io.h +5 -1
@@ -371,7 +371,11 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }#define ioremap_nocache ioremap#define ioremap_uc ioremap -#define iounmap __iounmap + +static inline void iounmap (void __iomem *addr) +{ +__iounmap (addr); +}/* * Convert a physical pointer to a virtual kernel pointer for /dev/mem
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 271/293 mm/kmemleak.c: fix check for softirq context
In reply to Greg Kroah-Hartman[ Upstream commit 6ef9056952532c3b746de46aa10d45b4d7797bd8 ]
in_softirq() is a wrong predicate to check if we are in a softirq context. It also returns true if we have BH disabled, so objects are falsely stamped with "softirq" comm. The correct predicate is in_serving_softirq().
If user does cat from /sys/kernel/debug/kmemleak previously they would see this, which is clearly wrong, this is system call context (see the comm):
unreferenced object 0xffff88805bd661c0 (size 64):
comm "softirq", pid 0, jiffies 4294942959 (age 12.400s) hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 ................
00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
backtrace:
[<0000000007dcb30c>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline]
[<0000000007dcb30c>] slab_post_alloc_hook mm/slab.h:439 [inline]
[<0000000007dcb30c>] slab_alloc mm/slab.c:3326 [inline]
[<0000000007dcb30c>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553
[<00000000969722b7>] kmalloc include/linux/slab.h:547 [inline]
[<00000000969722b7>] kzalloc include/linux/slab.h:742 [inline]
[<00000000969722b7>] ip_mc_add1_src net/ipv4/igmp.c:1961 [inline]
[<00000000969722b7>] ip_mc_add_src+0x36b/0x400 net/ipv4/igmp.c:2085
[<00000000a4134b5f>] ip_mc_msfilter+0x22d/0x310 net/ipv4/igmp.c:2475
[<00000000d20248ad>] do_ip_setsockopt.isra.0+0x19fe/0x1c00 net/ipv4/ip_sockglue.c:957
[<000000003d367be7>] ip_setsockopt+0x3b/0xb0 net/ipv4/ip_sockglue.c:1246
[<000000003c7c76af>] udp_setsockopt+0x4e/0x90 net/ipv4/udp.c:2616
[<000000000c1aeb23>] sock_common_setsockopt+0x3e/0x50 net/core/sock.c:3130
[<000000000157b92b>] __sys_setsockopt+0x9e/0x120 net/socket.c:2078
[<00000000a9f3d058>] __do_sys_setsockopt net/socket.c:2089 [inline]
[<00000000a9f3d058>] __se_sys_setsockopt net/socket.c:2086 [inline]
[<00000000a9f3d058>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2086
[<000000001b8da885>] do_syscall_64+0x7c/0x1a0 arch/x86/entry/common.c:301
[<00000000ba770c62>] entry_SYSCALL_64_after_hwframe+0x44/0xa9now they will see this:
unreferenced object 0xffff88805413c800 (size 64):
comm "syz-executor.4", pid 8960, jiffies 4294994003 (age 14.350s) hex dump (first 32 bytes):
00 7a 8a 57 80 88 ff ff e0 00 00 01 00 00 00 00 .z.W............
00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
backtrace:
[<00000000c5d3be64>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline]
[<00000000c5d3be64>] slab_post_alloc_hook mm/slab.h:439 [inline]
[<00000000c5d3be64>] slab_alloc mm/slab.c:3326 [inline]
[<00000000c5d3be64>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553
[<0000000023865be2>] kmalloc include/linux/slab.h:547 [inline]
[<0000000023865be2>] kzalloc include/linux/slab.h:742 [inline]
[<0000000023865be2>] ip_mc_add1_src net/ipv4/igmp.c:1961 [inline]
[<0000000023865be2>] ip_mc_add_src+0x36b/0x400 net/ipv4/igmp.c:2085
[<000000003029a9d4>] ip_mc_msfilter+0x22d/0x310 net/ipv4/igmp.c:2475
[<00000000ccd0a87c>] do_ip_setsockopt.isra.0+0x19fe/0x1c00 net/ipv4/ip_sockglue.c:957
[<00000000a85a3785>] ip_setsockopt+0x3b/0xb0 net/ipv4/ip_sockglue.c:1246
[<00000000ec13c18d>] udp_setsockopt+0x4e/0x90 net/ipv4/udp.c:2616
[<0000000052d748e3>] sock_common_setsockopt+0x3e/0x50 net/core/sock.c:3130
[<00000000512f1014>] __sys_setsockopt+0x9e/0x120 net/socket.c:2078
[<00000000181758bc>] __do_sys_setsockopt net/socket.c:2089 [inline]
[<00000000181758bc>] __se_sys_setsockopt net/socket.c:2086 [inline]
[<00000000181758bc>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2086
[<00000000d4b73623>] do_syscall_64+0x7c/0x1a0 arch/x86/entry/common.c:301
[<00000000c1098bec>] entry_SYSCALL_64_after_hwframe+0x44/0xa9--- mm/kmemleak.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/kmemleak.c +1 -1
@@ -577,7 +577,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size,if (in_irq ()) { object->pid =0 ;strncpy (object->comm,"hardirq" ,sizeof (object->comm)); - }else if (in_softirq ()) { + }else if (in_serving_softirq ()) { object->pid =0 ;strncpy (object->comm,"softirq" ,sizeof (object->comm)); }else {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 272/293 9p: pass the correct prototype to read_cache_page
In reply to Greg Kroah-Hartman[ Upstream commit f053cbd4366051d7eb6ba1b8d529d20f719c2963 ]
Fix the callback 9p passes to read_cache_page to actually have the proper type expected. Casting around function pointers can easily hide typing bugs, and defeats control flow protection.
--- fs/9p/vfs_addr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/9p/vfs_addr.c +4 -2
@@ -50,8 +50,9 @@* @page: structure to page * */ -static int v9fs_fid_readpage (struct p9_fid *fid,struct page *page) +static int v9fs_fid_readpage (void *data,struct page *page) { +struct p9_fid *fid = data;struct inode *inode = page->mapping->host;struct bio_vec bvec = {.bv_page = page, .bv_len =PAGE_SIZE };struct iov_iter to;
@@ -122,7 +123,8 @@ static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,if (ret ==0 )return ret; - ret =read_cache_pages (mapping, pages, (void *)v9fs_vfs_readpage, filp); + ret =read_cache_pages (mapping, pages, v9fs_fid_readpage, + filp->private_data);p9_debug (P9_DEBUG_VFS ," = %d\n" , ret);return ret; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 273/293 mm/gup.c: mark undo_dev_pagemap as __maybe_unused
In reply to Greg Kroah-Hartman[ Upstream commit 790c73690c2bbecb3f6f8becbdb11ddc9bcff8cc ]
Several mips builds generate the following build warning.
mm/gup.c:1788:13: warning: 'undo_dev_pagemap' defined but not used
The function is declared unconditionally but only called from behind various ifdefs. Mark it __maybe_unused.
--- mm/gup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
mm/gup.c +2 -1
@@ -1364,7 +1364,8 @@ static inline pte_t gup_get_pte(pte_t *ptep) }#endif -static void undo_dev_pagemap (int *nr,int nr_start,struct page **pages) +static void __maybe_unused undo_dev_pagemap (int *nr,int nr_start, +struct page **pages) {while ((*nr) - nr_start) {struct page *page = pages[--(*nr)];
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 274/293 mm/gup.c: remove some BUG_ONs from get_gate_page()
In reply to Greg Kroah-Hartman[ Upstream commit b5d1c39f34d1c9bca0c4b9ae2e339fbbe264a9c7 ]
If we end up without a PGD or PUD entry backing the gate area, don't BUG -- just fail gracefully.
It's not entirely implausible that this could happen some day on x86. It doesn't right now even with an execute-only emulated vsyscall page because the fixmap shares the PUD, but the core mm code shouldn't rely on that particular detail to avoid OOPSing.
--- mm/gup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
mm/gup.c +6 -3
@@ -442,11 +442,14 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address, pgd =pgd_offset_k (address); else pgd =pgd_offset_gate (mm, address); -BUG_ON (pgd_none (*pgd)); +if (pgd_none (*pgd)) +return -EFAULT ; p4d =p4d_offset (pgd, address); -BUG_ON (p4d_none (*p4d)); +if (p4d_none (*p4d)) +return -EFAULT ; pud =pud_offset (p4d, address); -BUG_ON (pud_none (*pud)); +if (pud_none (*pud)) +return -EFAULT ; pmd =pmd_offset (pud, address);if (!pmd_present (*pmd))return -EFAULT ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 275/293 mm/mmu_notifier: use hlist_add_head_rcu()
In reply to Greg Kroah-Hartman[ Upstream commit 543bdb2d825fe2400d6e951f1786d92139a16931 ]
Make mmu_notifier_register() safer by issuing a memory barrier before registering a new notifier. This fixes a theoretical bug on weakly ordered CPUs. For example, take this simplified use of notifiers by a driver:
my_struct->mn.ops = &my_ops; /* (1) */ mmu_notifier_register(&my_struct->mn, mm) ... hlist_add_head(&mn->hlist, &mm->mmu_notifiers); /* (2) */ ...
Once mmu_notifier_register() releases the mm locks, another thread can invalidate a range:
mmu_notifier_invalidate_range()
...
hlist_for_each_entry_rcu(mn, &mm->mmu_notifiers, hlist) {
if (mn->ops->invalidate_range)The read side relies on the data dependency between mn and ops to ensure that the pointer is properly initialized. But the write side doesn't have any dependency between (1) and (2), so they could be reordered and the readers could dereference an invalid mn->ops. mmu_notifier_register() does take all the mm locks before adding to the hlist, but those have acquire semantics which isn't sufficient.
By calling hlist_add_head_rcu() instead of hlist_add_head() we update the hlist using a store-release, ensuring that readers see prior initialization of my_struct. This situation is better illustated by litmus test MP+onceassign+derefonce.
--- mm/mmu_notifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/mmu_notifier.c +1 -1
@@ -267,7 +267,7 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn,* thanks to mm_take_all_locks(). */ spin_lock (&mm->mmu_notifier_mm->lock); -hlist_add_head (&mn->hlist, &mm->mmu_notifier_mm->list); +hlist_add_head_rcu (&mn->hlist, &mm->mmu_notifier_mm->list);spin_unlock (&mm->mmu_notifier_mm->lock);mm_drop_all_locks (mm);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 276/293 locking/lockdep: Fix lock used or unused stats error
In reply to Greg Kroah-Hartman[ Upstream commit 68d41d8c94a31dfb8233ab90b9baf41a2ed2da68 ]
The stats variable nr_unused_locks is incremented every time a new lock class is register and decremented when the lock is first used in __lock_acquire(). And after all, it is shown and checked in lockdep_stats.
However, under configurations that either CONFIG_TRACE_IRQFLAGS or CONFIG_PROVE_LOCKING is not defined:
The commit:
091806515124b20 ("locking/lockdep: Consolidate lock usage bit initialization")
missed marking the LOCK_USED flag at IRQ usage initialization because as mark_usage() is not called. And the commit:
886532aee3cd42d ("locking/lockdep: Move mark_lock() inside CONFIG_TRACE_IRQFLAGS && CONFIG_PROVE_LOCKING")further made mark_lock() not defined such that the LOCK_USED cannot be marked at all when the lock is first acquired.
As a result, we fix this by not showing and checking the stats under such configurations for lockdep_stats.
--- kernel/locking/lockdep_proc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/locking/lockdep_proc.c +3 -2
@@ -234,6 +234,7 @@ static int lockdep_stats_show(struct seq_file *m, void *v) nr_hardirq_read_safe =0 , nr_hardirq_read_unsafe =0 , sum_forward_deps =0 ; +#ifdef CONFIG_PROVE_LOCKING list_for_each_entry (class, &all_lock_classes, lock_entry) {if (class->usage_mask ==0 )
@@ -265,12 +266,12 @@ static int lockdep_stats_show(struct seq_file *m, void *v)if (class->usage_mask &LOCKF_ENABLED_HARDIRQ_READ ) nr_hardirq_read_unsafe++; -#ifdef CONFIG_PROVE_LOCKING sum_forward_deps +=lockdep_count_forward_deps (class); -#endif }#ifdef CONFIG_DEBUG_LOCKDEP DEBUG_LOCKS_WARN_ON (debug_atomic_read (nr_unused_locks) != nr_unused); +#endif +#endif seq_printf (m," lock-classes: %11lu [max: %lu]\n" , nr_lock_classes,MAX_LOCKDEP_KEYS );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 277/293 locking/lockdep: Hide unused class variable
In reply to Greg Kroah-Hartman[ Upstream commit 68037aa78208f34bda4e5cd76c357f718b838cbb ]
The usage is now hidden in an #ifdef, so we need to move the variable itself in there as well to avoid this warning:
kernel/locking/lockdep_proc.c:203:21: error: unused variable 'class' [-Werror,-Wunused-variable]
--- kernel/locking/lockdep_proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/locking/lockdep_proc.c +2 -1
@@ -224,7 +224,6 @@ static void lockdep_stats_debug_show(struct seq_file *m)static int lockdep_stats_show (struct seq_file *m,void *v) { -struct lock_class *class;unsigned long nr_unused =0 , nr_uncategorized =0 , nr_irq_safe =0 , nr_irq_unsafe =0 , nr_softirq_safe = 0, nr_softirq_unsafe = 0,
@@ -235,6 +234,8 @@ static int lockdep_stats_show(struct seq_file *m, void *v) sum_forward_deps =0 ;#ifdef CONFIG_PROVE_LOCKING +struct lock_class *class; +list_for_each_entry (class, &all_lock_classes, lock_entry) {if (class->usage_mask ==0 )
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 278/293 drm/crc: Only report a single overflow when a CRC fd is opened
In reply to Greg Kroah-Hartman[ Upstream commit a012024571d98e2e4bf29a9168fb7ddc44b7ab86 ]
This reduces the amount of spam when you debug a CRC reading program.
--- drivers/gpu/drm/drm_debugfs_crc.c | 9 ++++++++- include/drm/drm_debugfs_crc.h | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_debugfs_crc.c +8 -1
@@ -139,6 +139,7 @@ static int crtc_crc_data_count(struct drm_crtc_crc *crc)static void crtc_crc_cleanup (struct drm_crtc_crc *crc) {kfree (crc->entries); + crc->overflow = false; crc->entries =NULL ; crc->head =0 ; crc->tail =0 ;
@@ -373,8 +374,14 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, tail = crc->tail;if (CIRC_SPACE (head, tail,DRM_CRC_ENTRIES_NR ) <1 ) { +bool was_overflow = crc->overflow; + + crc->overflow = true;spin_unlock (&crc->lock); -DRM_ERROR ("Overflow of CRC buffer, userspace reads too slow.\n" ); + +if (!was_overflow) +DRM_ERROR ("Overflow of CRC buffer, userspace reads too slow.\n" ); +return -ENOBUFS ; }
include/drm/drm_debugfs_crc.h +2 -1
@@ -43,6 +43,7 @@ struct drm_crtc_crc_entry {* @lock: protects the fields in this struct * @source: name of the currently configured source of CRCs * @opened: whether userspace has opened the data file for reading +* @overflow: whether an overflow occured. * @entries: array of entries, with size of %DRM_CRC_ENTRIES_NR * @head: head of circular queue * @tail: tail of circular queue
@@ -52,7 +53,7 @@ struct drm_crtc_crc_entry {struct drm_crtc_crc {spinlock_t lock;const char *source; -bool opened; +bool opened, overflow;struct drm_crtc_crc_entry *entries;int head, tail;size_t values_cnt;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 279/293 drm/crc-debugfs: Also sprinkle irqrestore over early exits
In reply to Greg Kroah-Hartman[ Upstream commit d99004d7201aa653658ff2390d6e516567c96ebc ]
I. was. blind.
Caught with vkms, which has some really slow crc computation function.
--- drivers/gpu/drm/drm_debugfs_crc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_debugfs_crc.c +2 -2
@@ -366,7 +366,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,/* Caller may not have noticed yet that userspace has stopped reading */ if (!crc->entries) { -spin_unlock (&crc->lock); +spin_unlock_irqrestore (&crc->lock, flags);return -EINVAL ; }
@@ -377,7 +377,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,bool was_overflow = crc->overflow; crc->overflow = true; -spin_unlock (&crc->lock); +spin_unlock_irqrestore (&crc->lock, flags);if (!was_overflow)DRM_ERROR ("Overflow of CRC buffer, userspace reads too slow.\n" );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 280/293 usb: wusbcore: fix unbalanced get/put cluster_id
In reply to Greg Kroah-HartmanFrom: Phong Tran <[email protected]>
commit f90bf1ece48a736097ea224430578fe586a9544c upstream.
syzboot reported that
https://syzkaller.appspot.com/bug?extid=fd2bd7df88c606eea4ef
There is not consitency parameter in cluste_id_get/put calling. In case of getting the id with result is failure, the wusbhc->cluster_id will not be updated and this can not be used for wusb_cluster_id_put().
Tested report
https://groups.google.com/d/msg/syzkaller-bugs/0znZopp3-9k/oxOrhLkLEgAJ
Reproduce and gdb got the details:
139 addr = wusb_cluster_id_get();
(gdb) n
140 if (addr == 0)
(gdb) print addr
$1 = 254 '\376'
(gdb) n
142 result = __hwahc_set_cluster_id(hwahc, addr);
(gdb) print result
$2 = -71
(gdb) break wusb_cluster_id_put
Breakpoint 3 at 0xffffffff836e3f20: file drivers/usb/wusbcore/wusbhc.c, line 384. (gdb) s
Thread 2 hit Breakpoint 3, wusb_cluster_id_put (id=0 '\000') at drivers/usb/wusbcore/wusbhc.c:384
384 id = 0xff - id;
(gdb) n
385 BUG_ON(id >= CLUSTER_IDS);
(gdb) print id
$3 = 255 '\377'
--- drivers/usb/host/hwa-hc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/hwa-hc.c +1 -1
@@ -173,7 +173,7 @@ out:return result; error_set_cluster_id: -wusb_cluster_id_put (wusbhc->cluster_id); +wusb_cluster_id_put (addr); error_cluster_id_get: goto out;
Greg Kroah-Hartman
maintainerPATCH 281/293 usb: pci-quirks: Correct AMD PLL quirk detection
In reply to Greg Kroah-HartmanFrom: Ryan Kennedy <[email protected]>
commit f3dccdaade4118070a3a47bef6b18321431f9ac6 upstream.
The AMD PLL USB quirk is incorrectly enabled on newer Ryzen chipsets. The logic in usb_amd_find_chipset_info currently checks for unaffected chipsets rather than affected ones. This broke once a new chipset was added in e788787ef. It makes more sense to reverse the logic so it won't need to be updated as new chipsets are added. Note that the core of the workaround in usb_amd_quirk_pll does correctly check the chipset.
--- drivers/usb/host/pci-quirks.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
drivers/usb/host/pci-quirks.c +19 -12
@@ -204,7 +204,7 @@ int usb_amd_find_chipset_info(void) {unsigned long flags;struct amd_chipset_info info; -int ret; +int need_pll_quirk =0 ;spin_lock_irqsave (&amd_lock, flags);
@@ -218,21 +218,28 @@ int usb_amd_find_chipset_info(void)spin_unlock_irqrestore (&amd_lock, flags);if (!amd_chipset_sb_type_init (&info)) { - ret =0 ; goto commit; } -/* Below chipset generations needn't enable AMD PLL quirk */ -if (info.sb_type.gen ==AMD_CHIPSET_UNKNOWN || - info.sb_type.gen ==AMD_CHIPSET_SB600 || - info.sb_type.gen ==AMD_CHIPSET_YANGTZE || - (info.sb_type.gen ==AMD_CHIPSET_SB700 && - info.sb_type.rev >0x3b )) { +switch (info.sb_type.gen) { +case AMD_CHIPSET_SB700 : + need_pll_quirk = info.sb_type.rev <=0x3B ; +break ; +case AMD_CHIPSET_SB800 : +case AMD_CHIPSET_HUDSON2 : +case AMD_CHIPSET_BOLTON : + need_pll_quirk =1 ; +break ; +default : + need_pll_quirk =0 ; +break ; + } + +if (!need_pll_quirk) {if (info.smbus_dev) {pci_dev_put (info.smbus_dev); info.smbus_dev =NULL ; } - ret =0 ; goto commit; }
@@ -251,7 +258,7 @@ int usb_amd_find_chipset_info(void) } } - ret = info.probe_result =1 ; + need_pll_quirk = info.probe_result =1 ;printk (KERN_DEBUG "QUIRK: Enable AMD PLL fix\n" ); commit:
@@ -262,7 +269,7 @@ commit:/* Mark that we where here */ amd_chipset.probe_count++; - ret = amd_chipset.probe_result; + need_pll_quirk = amd_chipset.probe_result;spin_unlock_irqrestore (&amd_lock, flags);
@@ -276,7 +283,7 @@ commit:spin_unlock_irqrestore (&amd_lock, flags); } -return ret; +return need_pll_quirk; }EXPORT_SYMBOL_GPL (usb_amd_find_chipset_info);
Greg Kroah-Hartman
maintainerPATCH 282/293 KVM: nVMX: do not use dangling shadow VMCS after guest reset
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit 88dddc11a8d6b09201b4db9d255b3394d9bc9e57 upstream.
If a KVM guest is reset while running a nested guest, free_nested will disable the shadow VMCS execution control in the vmcs01. However, on the next KVM_RUN vmx_vcpu_run would nevertheless try to sync the VMCS12 to the shadow VMCS which has since been freed.
This causes a vmptrld of a NULL pointer on my machime, but Jan reports the host to hang altogether. Let's see how much this trivial patch fixes.
--- arch/x86/kvm/vmx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx.c +7 -1
@@ -7694,6 +7694,7 @@ static void vmx_disable_shadow_vmcs(stru {vmcs_clear_bits (SECONDARY_VM_EXEC_CONTROL ,SECONDARY_EXEC_SHADOW_VMCS );vmcs_write64 (VMCS_LINK_POINTER ,-1ull ); + vmx->nested.sync_shadow_vmcs = false; }static inline void nested_release_vmcs12 (struct vcpu_vmx *vmx)
@@ -7705,7 +7706,6 @@ static inline void nested_release_vmcs12/* copy to memory all shadowed fields in case they were modified */ copy_shadow_to_vmcs12 (vmx); - vmx->nested.sync_shadow_vmcs = false;vmx_disable_shadow_vmcs (vmx); } vmx->nested.posted_intr_nv =-1 ;
@@ -7891,6 +7891,9 @@ static void copy_shadow_to_vmcs12(structconst unsigned long *fields = shadow_read_write_fields;const int num_fields = max_shadow_read_write_fields; +if (WARN_ON (!shadow_vmcs)) +return ; +preempt_disable ();vmcs_load (shadow_vmcs);
@@ -7938,6 +7941,9 @@ static void copy_vmcs12_to_shadow(structu64 field_value =0 ;struct vmcs *shadow_vmcs = vmx->vmcs01.shadow_vmcs; +if (WARN_ON (!shadow_vmcs)) +return ; +vmcs_load (shadow_vmcs);for (q =0 ; q <ARRAY_SIZE (fields); q++) {
Greg Kroah-Hartman
maintainerPATCH 283/293 btrfs: inode: Dont compress if NODATASUM or NODATACOW set
In reply to Greg Kroah-HartmanFrom: Qu Wenruo <[email protected]>
commit 42c16da6d684391db83788eb680accd84f6c2083 upstream.
As btrfs(5) specified:
Note
If nodatacow or nodatasum are enabled, compression is disabled.
If NODATASUM or NODATACOW set, we should not compress the extent.
Normally NODATACOW is detected properly in run_delalloc_range() so compression won't happen for NODATACOW.
However for NODATASUM we don't have any check, and it can cause compressed extent without csum pretty easily, just by:
mkfs.btrfs -f $dev
mount $dev $mnt -o nodatasum
touch $mnt/foobar
mount -o remount,datasum,compress $mnt
xfs_io -f -c "pwrite 0 128K" $mnt/foobar
And in fact, we have a bug report about corrupted compressed extent without proper data checksum so even RAID1 can't recover the corruption.
(https://bugzilla.kernel.org/show_bug.cgi?id=199707)
Running compression without proper checksum could cause more damage when corruption happens, as compressed data could make the whole extent unreadable, so there is no need to allow compression for NODATACSUM.
The fix will refactor the inode compression check into two parts:
- inode_can_compress()
As the hard requirement, checked at btrfs_run_delalloc_range(), so no compression will happen for NODATASUM inode at all.
- inode_need_compress()
As the soft requirement, checked at btrfs_run_delalloc_range() and compress_file_range().
--- fs/btrfs/inode.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
fs/btrfs/inode.c +23 -1
@@ -405,10 +405,31 @@ static noinline int add_async_extent(strreturn 0 ; } +/* +* Check if the inode has flags compatible with compression +*/ +static inline bool inode_can_compress (struct inode *inode) +{ +if (BTRFS_I (inode)->flags &BTRFS_INODE_NODATACOW || +BTRFS_I (inode)->flags &BTRFS_INODE_NODATASUM ) +return false; +return true; +} + +/* +* Check if the inode needs to be submitted to compression, based on mount +* options, defragmentation, properties or heuristics. +*/ static inline int inode_need_compress (struct inode *inode,u64 start,u64 end) {struct btrfs_fs_info *fs_info =btrfs_sb (inode->i_sb); +if (!inode_can_compress (inode)) { +WARN (IS_ENABLED (CONFIG_BTRFS_DEBUG ), +KERN_ERR "BTRFS: unexpected compression for ino %llu\n" , +btrfs_ino (BTRFS_I (inode))); +return 0 ; + }/* force compress */ if (btrfs_test_opt (fs_info,FORCE_COMPRESS ))return 1 ;
@@ -1626,7 +1647,8 @@ static int run_delalloc_range(void *priv }else if (BTRFS_I (inode)->flags &BTRFS_INODE_PREALLOC && !force_cow) { ret =run_delalloc_nocow (inode, locked_page, start, end, page_started,0 , nr_written); - }else if (!inode_need_compress (inode, start, end)) { + }else if (!inode_can_compress (inode) || + !inode_need_compress (inode, start, end)) { ret =cow_file_range (inode, locked_page, start, end, end, page_started, nr_written,1 ,NULL ); }else {
Greg Kroah-Hartman
maintainerPATCH 284/293 x86/sysfb_efi: Add quirks for some devices with swapped width and height
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit d02f1aa39189e0619c3525d5cd03254e61bf606a upstream.
Some Lenovo 2-in-1s with a detachable keyboard have a portrait screen but advertise a landscape resolution and pitch, resulting in a messed up display if the kernel tries to show anything on the efifb (because of the wrong pitch).
Fix this by adding a new DMI match table for devices which need to have their width and height swapped.
At first it was tried to use the existing table for overriding some of the efifb parameters, but some of the affected devices have variants with different LCD resolutions which will not work with hardcoded override values.
Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1730783
--- arch/x86/kernel/sysfb_efi.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
arch/x86/kernel/sysfb_efi.c +46 -0
@@ -231,9 +231,55 @@ static const struct dmi_system_id efifb_ {}, }; +/* +* Some devices have a portrait LCD but advertise a landscape resolution (and +* pitch). We simply swap width and height for these devices so that we can +* correctly deal with some of them coming with multiple resolutions. +*/ +static const struct dmi_system_id efifb_dmi_swap_width_height[]__initconst = { + { +/* +* Lenovo MIIX310-10ICR, only some batches have the troublesome +* 800x1280 portrait screen. Luckily the portrait version has +* its own BIOS version, so we match on that. +*/ + .matches = { +DMI_EXACT_MATCH (DMI_SYS_VENDOR ,"LENOVO" ), +DMI_EXACT_MATCH (DMI_PRODUCT_VERSION ,"MIIX 310-10ICR" ), +DMI_EXACT_MATCH (DMI_BIOS_VERSION ,"1HCN44WW" ), + }, + }, + { +/* Lenovo MIIX 320-10ICR with 800x1280 portrait screen */ + .matches = { +DMI_EXACT_MATCH (DMI_SYS_VENDOR ,"LENOVO" ), +DMI_EXACT_MATCH (DMI_PRODUCT_VERSION , +"Lenovo MIIX 320-10ICR" ), + }, + }, + { +/* Lenovo D330 with 800x1280 or 1200x1920 portrait screen */ + .matches = { +DMI_EXACT_MATCH (DMI_SYS_VENDOR ,"LENOVO" ), +DMI_EXACT_MATCH (DMI_PRODUCT_VERSION , +"Lenovo ideapad D330-10IGM" ), + }, + }, + {}, +}; +__init void sysfb_apply_efi_quirks (void ) {if (screen_info.orig_video_isVGA !=VIDEO_TYPE_EFI || !(screen_info.capabilities &VIDEO_CAPABILITY_SKIP_QUIRKS ))dmi_check_system (efifb_dmi_system_table); + +if (screen_info.orig_video_isVGA ==VIDEO_TYPE_EFI && +dmi_check_system (efifb_dmi_swap_width_height)) { +u16 temp = screen_info.lfb_width; + + screen_info.lfb_width = screen_info.lfb_height; + screen_info.lfb_height = temp; + screen_info.lfb_linelength =4 * screen_info.lfb_width; + } }
Greg Kroah-Hartman
maintainerPATCH 285/293 x86/speculation/mds: Apply more accurate check on hypervisor platform
In reply to Greg Kroah-HartmanFrom: Zhenzhong Duan <[email protected]>
commit 517c3ba00916383af6411aec99442c307c23f684 upstream.
X86_HYPER_NATIVE isn't accurate for checking if running on native platform, e.g. CONFIG_HYPERVISOR_GUEST isn't set or "nopv" is enabled.
Checking the CPU feature bit X86_FEATURE_HYPERVISOR to determine if it's running on native platform is more accurate.
This still doesn't cover the platforms on which X86_FEATURE_HYPERVISOR is unsupported, e.g. VMware, but there is nothing which can be done about this scenario.
--- arch/x86/kernel/cpu/bugs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/bugs.c +1 -1
@@ -1196,7 +1196,7 @@ static ssize_t l1tf_show_state(char *bufstatic ssize_t mds_show_state (char *buf) { -if (!hypervisor_is_type (X86_HYPER_NATIVE )) { +if (boot_cpu_has (X86_FEATURE_HYPERVISOR )) {return sprintf (buf,"%s; SMT Host state unknown\n" , mds_strings[mds_mitigation]); }
Greg Kroah-Hartman
maintainerPATCH 286/293 binder: prevent transactions to context manager from its own process.
In reply to Greg Kroah-HartmanFrom: Hridya Valsaraju <[email protected]>
commit 49ed96943a8e0c62cc5a9b0a6cfc88be87d1fcec upstream.
Currently, a transaction to context manager from its own process is prevented by checking if its binder_proc struct is the same as that of the sender. However, this would not catch cases where the process opens the binder device again and uses the new fd to send a transaction to the context manager.
--- drivers/android/binder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/android/binder.c +1 -1
@@ -2785,7 +2785,7 @@ static void binder_transaction(struct bielse return_error =BR_DEAD_REPLY ;mutex_unlock (&context->context_mgr_node_lock); -if (target_node && target_proc == proc) { +if (target_node && target_proc->pid == proc->pid) {binder_user_error ("%d:%d got transaction to context manager from process owning it\n" , proc->pid, thread->pid); return_error =BR_FAILED_REPLY ;
Greg Kroah-Hartman
maintainerPATCH 287/293 fpga-manager: altera-ps-spi: Fix build error
In reply to Greg Kroah-HartmanFrom: YueHaibing <[email protected]>
commit 3d139703d397f6281368047ba7ad1c8bf95aa8ab upstream.
If BITREVERSE is m and FPGA_MGR_ALTERA_PS_SPI is y, build fails:
drivers/fpga/altera-ps-spi.o: In function `altera_ps_write':
altera-ps-spi.c:(.text+0x4ec): undefined reference to `byte_rev_table'
Select BITREVERSE to fix this.
--- drivers/fpga/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/fpga/Kconfig +1 -0
@@ -34,6 +34,7 @@ config FPGA_MGR_ALTERA_CVP config FPGA_MGR_ALTERA_PS_SPI tristate "Altera FPGA Passive Serial over SPI" depends on SPI + select BITREVERSE help FPGA manager driver support for Altera Arria/Cyclone/Stratix using the passive serial interface over SPI.
Greg Kroah-Hartman
maintainerPATCH 288/293 hpet: Fix division by zero in hpet_time_div()
In reply to Greg Kroah-HartmanFrom: Kefeng Wang <[email protected]>
commit 0c7d37f4d9b8446956e97b7c5e61173cdb7c8522 upstream.
The base value in do_div() called by hpet_time_div() is truncated from unsigned long to uint32_t, resulting in a divide-by-zero exception.
UBSAN: Undefined behaviour in ../drivers/char/hpet.c:572:2 division by zero CPU: 1 PID: 23682 Comm: syz-executor.3 Not tainted 4.4.184.x86_64+ #4 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 0000000000000000 b573382df1853d00 ffff8800a3287b98 ffffffff81ad7561 ffff8800a3287c00 ffffffff838b35b0 ffffffff838b3860 ffff8800a3287c20 0000000000000000 ffff8800a3287bb0 ffffffff81b8f25e ffffffff838b35a0 Call Trace: [<ffffffff81ad7561>] __dump_stack lib/dump_stack.c:15 [inline] [<ffffffff81ad7561>] dump_stack+0xc1/0x120 lib/dump_stack.c:51 [<ffffffff81b8f25e>] ubsan_epilogue+0x12/0x8d lib/ubsan.c:166 [<ffffffff81b900cb>] __ubsan_handle_divrem_overflow+0x282/0x2c8 lib/ubsan.c:262 [<ffffffff823560dd>] hpet_time_div drivers/char/hpet.c:572 [inline] [<ffffffff823560dd>] hpet_ioctl_common drivers/char/hpet.c:663 [inline] [<ffffffff823560dd>] hpet_ioctl_common.cold+0xa8/0xad drivers/char/hpet.c:577 [<ffffffff81e63d56>] hpet_ioctl+0xc6/0x180 drivers/char/hpet.c:676 [<ffffffff81711590>] vfs_ioctl fs/ioctl.c:43 [inline] [<ffffffff81711590>] file_ioctl fs/ioctl.c:470 [inline] [<ffffffff81711590>] do_vfs_ioctl+0x6e0/0xf70 fs/ioctl.c:605 [<ffffffff81711eb4>] SYSC_ioctl fs/ioctl.c:622 [inline] [<ffffffff81711eb4>] SyS_ioctl+0x94/0xc0 fs/ioctl.c:613 [<ffffffff82846003>] tracesys_phase2+0x90/0x95
The main C reproducer autogenerated by syzkaller,
syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0); memcpy((void*)0x20000100, "/dev/hpet\000", 10); syscall(__NR_openat, 0xffffffffffffff9c, 0x20000100, 0, 0); syscall(__NR_ioctl, r[0], 0x40086806, 0x40000000000000);
Fix it by using div64_ul().
--- drivers/char/hpet.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/char/hpet.c +1 -2
@@ -570,8 +570,7 @@ static inline unsigned long hpet_time_diunsigned long long m; m = hpets->hp_tick_freq + (dis >>1 ); -do_div (m, dis); -return (unsigned long )m; +return div64_ul (m, dis); } static int
Greg Kroah-Hartman
maintainerPATCH 289/293 ALSA: line6: Fix wrong altsetting for LINE6_PODHD500_1
In reply to Greg Kroah-HartmanFrom: Kai-Heng Feng <[email protected]>
commit 70256b42caaf3e13c2932c2be7903a73fbe8bb8b upstream.
Commit 7b9584fa1c0b ("staging: line6: Move altsetting to properties") set a wrong altsetting for LINE6_PODHD500_1 during refactoring.
Set the correct altsetting number to fix the issue.
--- sound/usb/line6/podhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/line6/podhd.c +1 -1
@@ -415,7 +415,7 @@ static const struct line6_properties pod .name = "POD HD500", .capabilities =LINE6_CAP_PCM | LINE6_CAP_HWMON, - .altsetting = 1, + .altsetting = 0, .ep_ctrl_r = 0x81, .ep_ctrl_w = 0x01, .ep_audio_r = 0x86,
Greg Kroah-Hartman
maintainerPATCH 290/293 ALSA: hda - Add a conexant codec entry to let mute led work
In reply to Greg Kroah-HartmanFrom: Hui Wang <[email protected]>
commit 3f8809499bf02ef7874254c5e23fc764a47a21a0 upstream.
This conexant codec isn't in the supported codec list yet, the hda generic driver can drive this codec well, but on a Lenovo machine with mute/mic-mute leds, we need to apply CXT_FIXUP_THINKPAD_ACPI to make the leds work. After adding this codec to the list, the driver patch_conexant.c will apply THINKPAD_ACPI to this machine.
--- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_conexant.c +1 -0
@@ -1127,6 +1127,7 @@ static int patch_conexant_auto(struct hd*/ static const struct hda_device_id snd_hda_id_conexant[] = { +HDA_CODEC_ENTRY (0x14f11f86 ,"CX8070" , patch_conexant_auto),HDA_CODEC_ENTRY (0x14f12008 ,"CX8200" , patch_conexant_auto),HDA_CODEC_ENTRY (0x14f15045 ,"CX20549 (Venice)" , patch_conexant_auto),HDA_CODEC_ENTRY (0x14f15047 ,"CX20551 (Waikiki)" , patch_conexant_auto),
Greg Kroah-Hartman
maintainerPATCH 291/293 powerpc/xive: Fix loop exit-condition in xive_find_target_in_mask()
In reply to Greg Kroah-HartmanFrom: Gautham R. Shenoy <[email protected]>
commit 4d202c8c8ed3822327285747db1765967110b274 upstream.
xive_find_target_in_mask() has the following for(;;) loop which has a bug when @first == cpumask_first(@mask) and condition 1 fails to hold for every CPU in @mask. In this case we loop forever in the for-loop.
first = cpu;
for (;;) {
if (cpu_online(cpu) && xive_try_pick_target(cpu)) // condition 1
return cpu; cpu = cpumask_next(cpu, mask); if (cpu == first) // condition 2 break; if (cpu >= nr_cpu_ids) // condition 3 cpu = cpumask_first(mask);
}
This is because, when @first == cpumask_first(@mask), we never hit the condition 2 (cpu == first) since prior to this check, we would have executed "cpu = cpumask_next(cpu, mask)" which will set the value of @cpu to a value greater than @first or to nr_cpus_ids. When this is coupled with the fact that condition 1 is not met, we will never exit this loop.
This was discovered by the hard-lockup detector while running LTP test concurrently with SMT switch tests.
watchdog: CPU 12 detected hard LOCKUP on other CPUs 68
watchdog: CPU 12 TB:85587019220796, last SMP heartbeat TB:85578827223399 (15999ms ago)
watchdog: CPU 68 Hard LOCKUP
watchdog: CPU 68 TB:85587019361273, last heartbeat TB:85576815065016 (19930ms ago)
CPU: 68 PID: 45050 Comm: hxediag Kdump: loaded Not tainted 4.18.0-100.el8.ppc64le #1 NIP: c0000000006f5578 LR: c000000000cba9ec CTR: 0000000000000000 REGS: c000201fff3c7d80 TRAP: 0100 Not tainted (4.18.0-100.el8.ppc64le) MSR: 9000000002883033 <SF,HV,VEC,VSX,FP,ME,IR,DR,RI,LE> CR: 24028424 XER: 00000000 CFAR: c0000000006f558c IRQMASK: 1 GPR00: c0000000000afc58 c000201c01c43400 c0000000015ce500 c000201cae26ec18 GPR04: 0000000000000800 0000000000000540 0000000000000800 00000000000000f8 GPR08: 0000000000000020 00000000000000a8 0000000080000000 c00800001a1beed8 GPR12: c0000000000b1410 c000201fff7f4c00 0000000000000000 0000000000000000 GPR16: 0000000000000000 0000000000000000 0000000000000540 0000000000000001 GPR20: 0000000000000048 0000000010110000 c00800001a1e3780 c000201cae26ed18 GPR24: 0000000000000000 c000201cae26ed8c 0000000000000001 c000000001116bc0 GPR28: c000000001601ee8 c000000001602494 c000201cae26ec18 000000000000001f NIP [c0000000006f5578] find_next_bit+0x38/0x90 LR [c000000000cba9ec] cpumask_next+0x2c/0x50 Call Trace: [c000201c01c43400] [c000201cae26ec18] 0xc000201cae26ec18 (unreliable) [c000201c01c43420] [c0000000000afc58] xive_find_target_in_mask+0x1b8/0x240 [c000201c01c43470] [c0000000000b0228] xive_pick_irq_target.isra.3+0x168/0x1f0 [c000201c01c435c0] [c0000000000b1470] xive_irq_startup+0x60/0x260 [c000201c01c43640] [c0000000001d8328] __irq_startup+0x58/0xf0 [c000201c01c43670] [c0000000001d844c] irq_startup+0x8c/0x1a0 [c000201c01c436b0] [c0000000001d57b0] __setup_irq+0x9f0/0xa90 [c000201c01c43760] [c0000000001d5aa0] request_threaded_irq+0x140/0x220 [c000201c01c437d0] [c00800001a17b3d4] bnx2x_nic_load+0x188c/0x3040 [bnx2x] [c000201c01c43950] [c00800001a187c44] bnx2x_self_test+0x1fc/0x1f70 [bnx2x] [c000201c01c43a90] [c000000000adc748] dev_ethtool+0x11d8/0x2cb0 [c000201c01c43b60] [c000000000b0b61c] dev_ioctl+0x5ac/0xa50 [c000201c01c43bf0] [c000000000a8d4ec] sock_do_ioctl+0xbc/0x1b0 [c000201c01c43c60] [c000000000a8dfb8] sock_ioctl+0x258/0x4f0 [c000201c01c43d20] [c0000000004c9704] do_vfs_ioctl+0xd4/0xa70 [c000201c01c43de0] [c0000000004ca274] sys_ioctl+0xc4/0x160 [c000201c01c43e30] [c00000000000b388] system_call+0x5c/0x70 Instruction dump: 78aad182 54a806be 3920ffff 78a50664 794a1f24 7d294036 7d43502a 7d295039 4182001c 48000034 78a9d182 79291f24 <7d23482a> 2fa90000 409e0020 38a50040
To fix this, move the check for condition 2 after the check for condition 3, so that we are able to break out of the loop soon after iterating through all the CPUs in the @mask in the problem case. Use do..while() to achieve this.
--- arch/powerpc/sysdev/xive/common.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
arch/powerpc/sysdev/xive/common.c +3 -4
@@ -482,7 +482,7 @@ static int xive_find_target_in_mask(cons* Now go through the entire mask until we find a valid * target. */ -for (;;) { + do { /* * We re-check online as the fallback case passes us * an untested affinity mask
@@ -490,12 +490,11 @@ static int xive_find_target_in_mask(consif (cpu_online (cpu) &&xive_try_pick_target (cpu))return cpu; cpu =cpumask_next (cpu, mask); -if (cpu == first) -break ;/* Wrap around */ if (cpu >= nr_cpu_ids) cpu =cpumask_first (mask); - } + }while (cpu != first); +return -1 ; }
Greg Kroah-Hartman
maintainerPATCH 292/293 powerpc/tm: Fix oops on sigreturn on systems without TM
In reply to Greg Kroah-HartmanFrom: Michael Neuling <[email protected]>
commit f16d80b75a096c52354c6e0a574993f3b0dfbdfe upstream.
On systems like P9 powernv where we have no TM (or P8 booted with ppc_tm=off), userspace can construct a signal context which still has the MSR TS bits set. The kernel tries to restore this context which results in the following crash:
Unexpected TM Bad Thing exception at c0000000000022fc (msr 0x8000000102a03031) tm_scratch=800000020280f033
Oops: Unrecoverable exception, sig: 6 [#1] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries Modules linked in: CPU: 0 PID: 1636 Comm: sigfuz Not tainted 5.2.0-11043-g0a8ad0ffa4 #69 NIP: c0000000000022fc LR: 00007fffb2d67e48 CTR: 0000000000000000 REGS: c00000003fffbd70 TRAP: 0700 Not tainted (5.2.0-11045-g7142b497d8) MSR: 8000000102a03031 <SF,VEC,VSX,FP,ME,IR,DR,LE,TM[E]> CR: 42004242 XER: 00000000 CFAR: c0000000000022e0 IRQMASK: 0 GPR00: 0000000000000072 00007fffb2b6e560 00007fffb2d87f00 0000000000000669 GPR04: 00007fffb2b6e728 0000000000000000 0000000000000000 00007fffb2b6f2a8 GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR12: 0000000000000000 00007fffb2b76900 0000000000000000 0000000000000000 GPR16: 00007fffb2370000 00007fffb2d84390 00007fffea3a15ac 000001000a250420 GPR20: 00007fffb2b6f260 0000000010001770 0000000000000000 0000000000000000 GPR24: 00007fffb2d843a0 00007fffea3a14a0 0000000000010000 0000000000800000 GPR28: 00007fffea3a14d8 00000000003d0f00 0000000000000000 00007fffb2b6e728 NIP [c0000000000022fc] rfi_flush_fallback+0x7c/0x80 LR [00007fffb2d67e48] 0x7fffb2d67e48 Call Trace: Instruction dump: e96a0220 e96a02a8 e96a0330 e96a03b8 394a0400 4200ffdc 7d2903a6 e92d0c00 e94d0c08 e96d0c10 e82d0c18 7db242a6 <4c000024> 7db243a6 7db142a6 f82d0c18
The problem is the signal code assumes TM is enabled when CONFIG_PPC_TRANSACTIONAL_MEM is enabled. This may not be the case as with P9 powernv or if ppc_tm=off is used on P8.
This means any local user can crash the system.
Fix the problem by returning a bad stack frame to the user if they try to set the MSR TS bits with sigreturn() on systems where TM is not supported.
Found with sigfuz kernel selftest on P9.
This fixes CVE-2019-13648.
--- arch/powerpc/kernel/signal_32.c | 3 +++ arch/powerpc/kernel/signal_64.c | 5 +++++ 2 files changed, 8 insertions(+)
arch/powerpc/kernel/signal_32.c +3 -0
@@ -1279,6 +1279,9 @@ long sys_rt_sigreturn(int r3, int r4, in goto bad;if (MSR_TM_ACTIVE (msr_hi<<32 )) { +/* Trying to start TM on non TM system */ +if (!cpu_has_feature (CPU_FTR_TM )) + goto bad;/* We only recheckpoint on return if we're * transaction. */
arch/powerpc/kernel/signal_64.c +5 -0
@@ -741,6 +741,11 @@ int sys_rt_sigreturn(unsigned long r3, uif (MSR_TM_ACTIVE (msr)) {/* We recheckpoint on return. */ struct ucontext __user *uc_transact; + +/* Trying to start TM on non TM system */ +if (!cpu_has_feature (CPU_FTR_TM )) + goto badframe; +if (__get_user (uc_transact, &uc->uc_link)) goto badframe; if (restore_tm_sigcontexts(current, &uc->uc_mcontext,
Greg Kroah-Hartman
maintainerPATCH 293/293 access: avoid the RCU grace period for the temporary subjective credentials
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
commit d7852fbd0f0423937fa287a598bfde188bb68c22 upstream.
It turns out that 'access()' (and 'faccessat()') can cause a lot of RCU work because it installs a temporary credential that gets allocated and freed for each system call.
The allocation and freeing overhead is mostly benign, but because credentials can be accessed under the RCU read lock, the freeing involves a RCU grace period.
Which is not a huge deal normally, but if you have a lot of access() calls, this causes a fair amount of seconday damage: instead of having a nice alloc/free patterns that hits in hot per-CPU slab caches, you have all those delayed free's, and on big machines with hundreds of cores, the RCU overhead can end up being enormous.
But it turns out that all of this is entirely unnecessary. Exactly because access() only installs the credential as the thread-local subjective credential, the temporary cred pointer doesn't actually need to be RCU free'd at all. Once we're done using it, we can just free it synchronously and avoid all the RCU overhead.
So add a 'non_rcu' flag to 'struct cred', which can be set by users that know they only use it in non-RCU context (there are other potential users for this). We can make it a union with the rcu freeing list head that we need for the RCU case, so this doesn't need any extra storage.
Note that this also makes 'get_current_cred()' clear the new non_rcu flag, in case we have filesystems that take a long-term reference to the cred and then expect the RCU delayed freeing afterwards. It's not entirely clear that this is required, but it makes for clear semantics:
the subjective cred remains non-RCU as long as you only access it synchronously using the thread-local accessors, but you _can_ use it as a generic cred if you want to.
It is possible that we should just remove the whole RCU markings for ->cred entirely. Only ->real_cred is really supposed to be accessed through RCU, and the long-term cred copies that nfs uses might want to explicitly re-enable RCU freeing if required, rather than have get_current_cred() do it implicitly.
But this is a "minimal semantic changes" change for the immediate problem.
--- fs/open.c | 19 +++++++++++++++++++ include/linux/cred.h | 7 ++++++- kernel/cred.c | 21 +++++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-)
fs/open.c +19 -0
@@ -379,6 +379,25 @@ SYSCALL_DEFINE3(faccessat, int, dfd, con override_cred->cap_permitted; } +/* +* The new set of credentials can *only* be used in +* task-synchronous circumstances, and does not need +* RCU freeing, unless somebody then takes a separate +* reference to it. +* +* NOTE! This is _only_ true because this credential +* is used purely for override_creds() that installs +* it as the subjective cred. Other threads will be +* accessing ->real_cred, not the subjective cred. +* +* If somebody _does_ make a copy of this (using the +* 'get_current_cred()' function), that will clear the +* non_rcu field, because now that other user may be +* expecting RCU freeing. But normal thread-synchronous +* cred accesses will keep things non-RCY. +*/ + override_cred->non_rcu =1 ; + old_cred =override_creds (override_cred); retry: res =user_path_at (dfd, filename, lookup_flags, &path);
include/linux/cred.h +6 -1
@@ -145,7 +145,11 @@ struct cred {struct user_struct *user;/* real user ID subscription */ struct user_namespace *user_ns;/* user_ns the caps and keyrings are relative to. */ struct group_info *group_info;/* supplementary groups for euid/fsgid */ -struct rcu_head rcu;/* RCU deletion hook */ +/* RCU deletion */ +union { +int non_rcu;/* Can we skip RCU deletion? */ +struct rcu_head rcu;/* RCU deletion hook */ + }; } __randomize_layout;extern void __put_cred (struct cred *);
@@ -243,6 +247,7 @@ static inline const struct cred *get_cre {struct cred *nonconst_cred = (struct cred *) cred;validate_creds (cred); + nonconst_cred->non_rcu =0 ;return get_new_cred (nonconst_cred); }
kernel/cred.c +19 -2
@@ -147,7 +147,10 @@ void __put_cred(struct cred *cred)BUG_ON (cred == current->cred);BUG_ON (cred == current->real_cred); -call_rcu (&cred->rcu, put_cred_rcu); +if (cred->non_rcu) +put_cred_rcu (&cred->rcu); +else +call_rcu (&cred->rcu, put_cred_rcu); }EXPORT_SYMBOL (__put_cred);
@@ -258,6 +261,7 @@ struct cred *prepare_creds(void) old = task->cred;memcpy (new, old,sizeof (struct cred )); + new->non_rcu =0 ;atomic_set (&new->usage,1 );set_cred_subscribers (new,0 );get_group_info (new->group_info);
@@ -537,7 +541,19 @@ const struct cred *override_creds(constvalidate_creds (old);validate_creds (new); -get_cred (new); + +/* +* NOTE! This uses 'get_new_cred()' rather than 'get_cred()'. +* +* That means that we do not clear the 'non_rcu' flag, since +* we are only installing the cred into the thread-synchronous +* '->cred' pointer, not the '->real_cred' pointer that is +* visible to other threads under RCU. +* +* Also note that we did validate_creds() manually, not depending +* on the validation in 'get_cred()'. +*/ +get_new_cred ((struct cred *)new);alter_cred_subscribers (new,1 );rcu_assign_pointer (current->cred, new);alter_cred_subscribers (old,-1 );
@@ -620,6 +636,7 @@ struct cred *prepare_kernel_cred(structvalidate_creds (old); *new = *old; + new->non_rcu =0 ;atomic_set (&new->usage,1 );set_cred_subscribers (new,0 );get_uid (new->user);
stable-rc/linux-4.14.y boot: 106 boots: 1 failed, 64 passed with 41 offline (v4.14.134-294-gf6ba73a2e356)
stable-rc/linux-4.14.y boot: 106 boots: 1 failed, 64 passed with 41 offline (v4.14.134-294-gf6ba73a2e356)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/branch/linux-4.14.y/kernel/v4.14.134-294-gf6ba73a2e356/
Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.14.y/kernel/v4.14.134-294-gf6ba73a2e356/
Tree: stable-rc
Branch: linux-4.14.y
Git Describe: v4.14.134-294-gf6ba73a2e356
Git Commit: f6ba73a2e356d3f40ed298dbf4097561f2cd9973
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
Tested: 58 unique boards, 25 SoC families, 16 builds out of 201
Boot Failure Detected:
arc:
hsdk_defconfig:
gcc-8:
hsdk: 1 failed lab
Offline Platforms:
arm64:
defconfig:
gcc-8
meson-gxbb-odroidc2: 1 offline lab
meson-gxl-s905d-p230: 1 offline lab
meson-gxl-s905x-libretech-cc: 1 offline lab
meson-gxl-s905x-nexbox-a95x: 1 offline lab
meson-gxl-s905x-p212: 1 offline lab
meson-gxm-nexbox-a1: 1 offline lab
rk3399-firefly: 1 offline lab
sun50i-a64-pine64-plus: 1 offline labmips:
pistachio_defconfig:
gcc-8
pistachio_marduk: 1 offline lab
arm:
tegra_defconfig:
gcc-8
tegra20-iris-512: 1 offline lab
exynos_defconfig:
gcc-8
exynos5250-arndale: 1 offline lab
exynos5420-arndale-octa: 1 offline lab
exynos5800-peach-pi: 1 offline lab
multi_v7_defconfig:
gcc-8
exynos5250-arndale: 1 offline lab
exynos5420-arndale-octa: 1 offline lab
exynos5800-peach-pi: 1 offline lab
imx6dl-wandboard_dual: 1 offline lab
imx6dl-wandboard_solo: 1 offline lab
imx6q-wandboard: 1 offline lab
imx7s-warp: 1 offline lab
meson8b-odroidc1: 1 offline lab
omap3-beagle: 1 offline lab
omap4-panda: 1 offline lab
qcom-apq8064-ifc6410: 1 offline lab
stih410-b2120: 1 offline lab
sun4i-a10-cubieboard: 1 offline lab
sun7i-a20-bananapi: 1 offline lab
tegra20-iris-512: 1 offline lab
vf610-colibri-eval-v3: 1 offline lab
omap2plus_defconfig:
gcc-8
omap3-beagle: 1 offline lab
omap4-panda: 1 offline lab
qcom_defconfig:
gcc-8
qcom-apq8064-ifc6410: 1 offline lab
davinci_all_defconfig:
gcc-8
da850-evm: 1 offline lab
dm365evm,legacy: 1 offline lab
imx_v6_v7_defconfig:
gcc-8
imx6dl-wandboard_dual: 1 offline lab
imx6dl-wandboard_solo: 1 offline lab
imx6q-wandboard: 1 offline lab
imx7s-warp: 1 offline lab
vf610-colibri-eval-v3: 1 offline lab
sunxi_defconfig:
gcc-8
sun4i-a10-cubieboard: 1 offline lab
sun7i-a20-bananapi: 1 offline lab
---
For more info write to <[email protected]>
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.135 release. There are 293 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.135-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 4.14.135-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.14.y
git commit: f6ba73a2e356d3f40ed298dbf4097561f2cd9973
git describe: v4.14.134-294-gf6ba73a2e356
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.14-oe/build/v4.14.134-294-gf6ba73a2e356
No regressions (compared to build v4.14.134)
No fixes (compared to build v4.14.134)
Ran 22754 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c - arm64
- hi6220-hikey - arm64
- i386
- juno-r2 - arm64
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15 - arm
- x86_64
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* kselftest
* libhugetlbfs
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-cpuhotplug-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-timers-tests
* perf
* spectre-meltdown-checker-test
* v4l2-compliance
* ltp-fs-tests
* ltp-syscalls-tests
* network-basic-tests
* ltp-open-posix-tests
* kvm-unit-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.135 release. There are 293 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.135-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.135 release. There are 293 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
Build results:
total: 172 pass: 172 fail: 0 Qemu test results: total: 346 pass: 346 fail: 0
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.135 release. There are 293 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.135-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted with no regressions on my system.
Cheers,
Kelsey
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.135 release. There are 293 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.135-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v4.14:
8 builds: 8 pass, 0 fail
16 boots: 16 pass, 0 fail
24 tests: 24 pass, 0 failLinux version: 4.14.135-rc1-gf6ba73a2e356
Boards tested: tegra124-jetson-tk1, tegra20-ventana,
tegra210-p2371-2180, tegra30-cardhu-a04
Cheers
Jon
Signature · 1 line
nvpublic