vb2: core: Skip planes array verification if pb is NULL
Subsystems (4)
A message that is not in the archive (sent off-list or not yet received): CGME20160818140817uscas1p238499f62d2adb3fdec69b8b057669de7@uscas1p2.samsung.com
A message that is not in the archive (sent off-list or not yet received): [email protected]
Greg Kroah-Hartman
maintainerPATCH 3/186 usb: gadget: pch_udc: reorder spin_[un]lock to avoid deadlock
4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Iago Abal <[email protected]>
commit 1d23d16a88e6c8143b07339435ba061b131ebb8c upstream.
The above commit reordered spin_lock/unlock and now &dev->lock' is acquired (rather than released) before calling dev->driver->disconnect', dev->driver->setup', dev->driver->suspend', usb_gadget_giveback_request', and usb_gadget_udc_reset'.
But this *may* not be the right way to fix the problem pointed by d3cb25a12138.
Note that the other usb/gadget/udc drivers do release the lock before calling these functions. There are also inconsistencies within pch_udc.c, where dev->driver->disconnect' is called while holding &dev->lock' in lines 613 and 1184, but not in line 2739.
Finally, commit d3cb25a12138 may have introduced several potential deadlocks.
For instance, EBA (https://github.com/models-team/eba) reports:
Double lock in drivers/usb/gadget/udc/pch_udc.c
first at 2791: spin_lock(& dev->lock); [pch_udc_isr]
second at 2694: spin_lock(& dev->lock); [pch_udc_svc_cfg_interrupt]
after calling from 2793: pch_udc_dev_isr(dev, dev_intr);
after calling from 2724: pch_udc_svc_cfg_interrupt(dev);Similarly, other potential deadlocks are 2791 -> 2793 -> 2721 -> 2657; and 2791 -> 2793 -> 2711 -> 2573 -> 1499 -> 1480.
--- drivers/usb/gadget/udc/pch_udc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/usb/gadget/udc/pch_udc.c +8 -8
@@ -1477,11 +1477,11 @@ static void complete_req(struct pch_udc_ req->dma_mapped =0 ; } ep->halted =1 ; -spin_lock (&dev->lock); +spin_unlock (&dev->lock);if (!ep->in)pch_udc_ep_clear_rrdy (ep);usb_gadget_giveback_request (&ep->ep, &req->req); -spin_unlock (&dev->lock); +spin_lock (&dev->lock); ep->halted = halted; }
@@ -2573,9 +2573,9 @@ static void pch_udc_svc_ur_interrupt(strempty_req_queue (ep); }if (dev->driver) { -spin_lock (&dev->lock); -usb_gadget_udc_reset (&dev->gadget, dev->driver);spin_unlock (&dev->lock); +usb_gadget_udc_reset (&dev->gadget, dev->driver); +spin_lock (&dev->lock); } }
@@ -2654,9 +2654,9 @@ static void pch_udc_svc_intf_interrupt(s dev->ep[i].halted =0 ; } dev->stall =0 ; -spin_lock (&dev->lock); - dev->driver->setup (&dev->gadget, &dev->setup_data);spin_unlock (&dev->lock); + dev->driver->setup (&dev->gadget, &dev->setup_data); +spin_lock (&dev->lock); }/**
@@ -2691,9 +2691,9 @@ static void pch_udc_svc_cfg_interrupt(st dev->stall =0 ;/* call gadget zero with setup data received */ -spin_lock (&dev->lock); - dev->driver->setup (&dev->gadget, &dev->setup_data);spin_unlock (&dev->lock); + dev->driver->setup (&dev->gadget, &dev->setup_data); +spin_lock (&dev->lock); }/**
Greg Kroah-Hartman
maintainerPATCH 7/186 USB: serial: option: add support for Telit LE910 PID 0x1206
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniele Palmas <[email protected]>
commit 3c0415fa08548e3bc63ef741762664497ab187ed upstream.
This patch adds support for 0x1206 PID of Telit LE910.
Since the interfaces positions are the same than the ones for 0x1043 PID of Telit LE922, telit_le922_blacklist_usbcfg3 is used.
--- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/serial/option.c +3 -0
@@ -273,6 +273,7 @@ static void option_instat_callback(struc#define TELIT_PRODUCT_LE922_USBCFG5 0x1045#define TELIT_PRODUCT_LE920 0x1200#define TELIT_PRODUCT_LE910 0x1201 +#define TELIT_PRODUCT_LE910_USBCFG4 0x1206/* ZTE PRODUCTS */ #define ZTE_VENDOR_ID 0x19d2
@@ -1198,6 +1199,8 @@ static const struct usb_device_id option .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), + .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
Greg Kroah-Hartman
maintainerPATCH 10/186 arm64: debug: unmask PSTATE.D earlier
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
commit 2ce39ad15182604beb6c8fa8bed5e46b59fd1082 upstream.
Clearing PSTATE.D is one of the requirements for generating a debug exception. The arm64 booting protocol requires that PSTATE.D is set, since many of the debug registers (for example, the hw_breakpoint registers) are UNKNOWN out of reset and could potentially generate spurious, fatal debug exceptions in early boot code if PSTATE.D was clear. Once the debug registers have been safely initialised, PSTATE.D is cleared, however this is currently broken for two reasons:
(1) The boot CPU clears PSTATE.D in a postcore_initcall and secondary CPUs clear PSTATE.D in secondary_start_kernel. Since the initcall runs after SMP (and the scheduler) have been initialised, there is no guarantee that it is actually running on the boot CPU. In this case, the boot CPU is left with PSTATE.D set and is not capable of generating debug exceptions.
(2) In a preemptible kernel, we may explicitly schedule on the IRQ return path to EL1. If an IRQ occurs with PSTATE.D set in the idle thread, then we may schedule the kthread_init thread, run the postcore_initcall to clear PSTATE.D and then context switch back to the idle thread before returning from the IRQ. The exception return path will then restore PSTATE.D from the stack, and set it again.
This patch fixes the problem by moving the clearing of PSTATE.D earlier to proc.S. This has the desirable effect of clearing it in one place for all CPUs, long before we have to worry about the scheduler or any exception handling. We ensure that the previous reset of MDSCR_EL1 has completed before unmasking the exception, so that any spurious exceptions resulting from UNKNOWN debug registers are not generated.
Without this patch applied, the kprobes selftests have been seen to fail under KVM, where we end up attempting to step the OOL instruction buffer with PSTATE.D set and therefore fail to complete the step.
--- arch/arm64/kernel/debug-monitors.c | 1 - arch/arm64/kernel/smp.c | 1 - arch/arm64/mm/proc.S | 2 ++ 3 files changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/debug-monitors.c +0 -1
@@ -151,7 +151,6 @@ static int debug_monitors_init(void)/* Clear the OS lock. */ on_each_cpu (clear_os_lock,NULL ,1 );isb (); -local_dbg_enable ();/* Register hotplug handler. */ __register_cpu_notifier (&os_lock_nb);
arch/arm64/kernel/smp.c +0 -1
@@ -267,7 +267,6 @@ asmlinkage void secondary_start_kernel(vset_cpu_online (cpu, true);complete (&cpu_running); -local_dbg_enable ();local_irq_enable ();local_async_enable ();
arch/arm64/mm/proc.S +2 -0
@@ -180,6 +180,8 @@ ENTRY(__cpu_setup) msr cpacr_el1, x0 // Enable FP/ASIMD mov x0, #1 << 12 // Reset mdscr_el1 and disable msr mdscr_el1, x0 // access to the DCC from EL0 + isb // Unmask debug exceptions now, + enable_dbg // since this is per-cpu reset_pmuserenr_el0 x0 // Disable PMU access from EL0 /* * Memory region attributes for LPAE:
Greg Kroah-Hartman
maintainerPATCH 11/186 arm64: Fix incorrect per-cpu usage for boot CPU
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suzuki K Poulose <[email protected]>
commit 9113c2aa05e9848cd4f1154abee17d4f265f012d upstream.
In smp_prepare_boot_cpu(), we invoke cpuinfo_store_boot_cpu to store the cpuinfo in a per-cpu ptr, before initialising the per-cpu offset for the boot CPU. This patch reorders the sequence to make sure we initialise the per-cpu offset before accessing the per-cpu area.
Commit 4b998ff1885eec ("arm64: Delay cpuinfo_store_boot_cpu") fixed the issue where we modified the per-cpu area even before the kernel initialises the per-cpu areas, but failed to wait until the boot cpu updated it's offset.
--- arch/arm64/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/smp.c +1 -1
@@ -436,9 +436,9 @@ void __init smp_cpus_done(unsigned int mvoid __init smp_prepare_boot_cpu (void ) { +set_my_cpu_offset (per_cpu_offset (smp_processor_id ()));cpuinfo_store_boot_cpu ();save_boot_cpu_run_el (); -set_my_cpu_offset (per_cpu_offset (smp_processor_id ())); }static u64 __init of_get_cpu_mpidr (struct device_node *dn)
Greg Kroah-Hartman
maintainerPATCH 22/186 arm64: mm: avoid fdt_check_header() before the FDT is fully mapped
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ard Biesheuvel <[email protected]>
commit 04a848106193b134741672f7e4e444b50c70b631 upstream.
As reported by Zijun, the fdt_check_header() call in __fixmap_remap_fdt() is not safe since it is not guaranteed that the FDT header is mapped completely. Due to the minimum alignment of 8 bytes, the only fields we can assume to be mapped are 'magic' and 'totalsize'.
Since the OF layer is in charge of validating the FDT image, and we are only interested in making reasonably sure that the size field contains a meaningful value, replace the fdt_check_header() call with an explicit comparison of the magic field's value against the expected value.
--- arch/arm64/mm/mmu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/mm/mmu.c +4 -4
@@ -748,9 +748,9 @@ void *__init __fixmap_remap_fdt(phys_add/* * Check whether the physical FDT address is set and meets the minimum * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be -* at least 8 bytes so that we can always access the size field of the -* FDT header after mapping the first chunk, double check here if that -* is indeed the case. +* at least 8 bytes so that we can always access the magic and size +* fields of the FDT header after mapping the first chunk, double check +* here if that is indeed the case. */ BUILD_BUG_ON (MIN_FDT_ALIGN <8 );if (!dt_phys || dt_phys %MIN_FDT_ALIGN )
@@ -778,7 +778,7 @@ void *__init __fixmap_remap_fdt(phys_addcreate_mapping_noalloc (round_down (dt_phys,SWAPPER_BLOCK_SIZE ), dt_virt_base,SWAPPER_BLOCK_SIZE , prot); -if (fdt_check_header (dt_virt) !=0 ) +if (fdt_magic (dt_virt) !=FDT_MAGIC )return NULL ; *size =fdt_totalsize (dt_virt);
Greg Kroah-Hartman
maintainerPATCH 31/186 KVM: nVMX: Fix memory corruption when using VMCS shadowing
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jim Mattson <[email protected]>
commit 2f1fe81123f59271bddda673b60116bde9660385 upstream.
When freeing the nested resources of a vcpu, there is an assumption that the vcpu's vmcs01 is the current VMCS on the CPU that executes nested_release_vmcs12(). If this assumption is violated, the vcpu's vmcs01 may be made active on multiple CPUs at the same time, in violation of Intel's specification. Moreover, since the vcpu's vmcs01 is not VMCLEARed on every CPU on which it is active, it can linger in a CPU's VMCS cache after it has been freed and potentially repurposed. Subsequent eviction from the CPU's VMCS cache on a capacity miss can result in memory corruption.
It is not sufficient for vmx_free_vcpu() to call vmx_load_vmcs01(). If the vcpu in question was last loaded on a different CPU, it must be migrated to the current CPU before calling vmx_load_vmcs01().
--- arch/x86/kvm/vmx.c | 19 +++++++++++++++++-- virt/kvm/kvm_main.c | 2 ++ 2 files changed, 19 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx.c +17 -2
@@ -8855,6 +8855,22 @@ static void vmx_load_vmcs01(struct kvm_vput_cpu (); } +/* +* Ensure that the current vmcs of the logical processor is the +* vmcs01 of the vcpu before calling free_nested(). +*/ +static void vmx_free_vcpu_nested (struct kvm_vcpu *vcpu) +{ +struct vcpu_vmx *vmx =to_vmx (vcpu); +int r; + + r =vcpu_load (vcpu); +BUG_ON (r); +vmx_load_vmcs01 (vcpu); +free_nested (vmx); +vcpu_put (vcpu); +} +static void vmx_free_vcpu (struct kvm_vcpu *vcpu) {struct vcpu_vmx *vmx =to_vmx (vcpu);
@@ -8863,8 +8879,7 @@ static void vmx_free_vcpu(struct kvm_vcpvmx_destroy_pml_buffer (vmx);free_vpid (vmx->vpid);leave_guest_mode (vcpu); -vmx_load_vmcs01 (vcpu); -free_nested (vmx); +vmx_free_vcpu_nested (vcpu);free_loaded_vmcs (vmx->loaded_vmcs);kfree (vmx->guest_msrs);kvm_vcpu_uninit (vcpu);
virt/kvm/kvm_main.c +2 -0
@@ -148,6 +148,7 @@ int vcpu_load(struct kvm_vcpu *vcpu)put_cpu ();return 0 ; } +EXPORT_SYMBOL_GPL (vcpu_load);void vcpu_put (struct kvm_vcpu *vcpu) {
@@ -157,6 +158,7 @@ void vcpu_put(struct kvm_vcpu *vcpu)preempt_enable ();mutex_unlock (&vcpu->mutex); } +EXPORT_SYMBOL_GPL (vcpu_put);static void ack_flush (void *_completed) {
Greg Kroah-Hartman
maintainerPATCH 33/186 s390/cio: allow to reset channel measurement block
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Ott <[email protected]>
commit 0f5d050ceaa31b2229102211d60c149f920df3aa upstream.
Prior to commit 1bc6664bdfb949bc69a08113801e7d6acbf6bc3f a call to enable_cmf for a device for which channel measurement was already enabled resulted in a reset of the measurement data.
What looked like bugs at the time (a 2nd allocation was triggered but failed, reset was called regardless of previous failures, and errors have not been reported to userspace) was actually something at least one userspace tool depended on. Restore that behavior in a sane way.
--- drivers/s390/cio/cmf.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
drivers/s390/cio/cmf.c +20 -9
@@ -753,6 +753,17 @@ static void reset_cmb(struct ccw_devicecmf_generic_reset (cdev); } +static int cmf_enabled (struct ccw_device *cdev) +{ +int enabled; + +spin_lock_irq (cdev->ccwlock); + enabled = !!cdev->private->cmb; +spin_unlock_irq (cdev->ccwlock); + +return enabled; +} +static struct attribute_group cmf_attr_group;static struct cmb_operations cmbops_basic = {
@@ -1153,13 +1164,8 @@ static ssize_t cmb_enable_show(struct de char *buf) {struct ccw_device *cdev =to_ccwdev (dev); -int enabled; -spin_lock_irq (cdev->ccwlock); - enabled = !!cdev->private->cmb; -spin_unlock_irq (cdev->ccwlock); - -return sprintf (buf,"%d\n" , enabled); +return sprintf (buf,"%d\n" ,cmf_enabled (cdev)); } static ssize_t cmb_enable_store(struct device *dev,
@@ -1199,15 +1205,20 @@ int ccw_set_cmf(struct ccw_device *cdev,* @cdev: The ccw device to be enabled * * Returns %0 for success or a negative error value. -* +* Note: If this is called on a device for which channel measurement is already +* enabled a reset of the measurement data is triggered. * Context: * non-atomic */ int enable_cmf (struct ccw_device *cdev) { -int ret; +int ret =0 ;device_lock (&cdev->dev); +if (cmf_enabled (cdev)) { + cmbops->reset (cdev); + goto out_unlock; + }get_device (&cdev->dev); ret = cmbops->alloc (cdev);if (ret)
@@ -1226,7 +1237,7 @@ int enable_cmf(struct ccw_device *cdev) out:if (ret)put_device (&cdev->dev); - +out_unlock:device_unlock (&cdev->dev);return ret; }
Greg Kroah-Hartman
maintainerPATCH 34/186 s390/mm: fix gmap tlb flush issues
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand <[email protected]>
commit f045402984404ddc11016358411e445192919047 upstream.
__tlb_flush_asce() should never be used if multiple asce belong to a mm.
As this function changes mm logic determining if local or global tlb flushes will be neded, we might end up flushing only the gmap asce on all CPUs and a follow up mm asce flushes will only flush on the local CPU, although that asce ran on multiple CPUs.
The missing tlb flushes will provoke strange faults in user space and even low address protections in user space, crashing the kernel.
--- arch/s390/include/asm/tlbflush.h | 3 ++- arch/s390/mm/gmap.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-)
arch/s390/include/asm/tlbflush.h +2 -1
@@ -81,7 +81,8 @@ static inline void __tlb_flush_full(stru }/* -* Flush TLB entries for a specific ASCE on all CPUs. +* Flush TLB entries for a specific ASCE on all CPUs. Should never be used +* when more than one asce (e.g. gmap) ran on this mm. */ static inline void __tlb_flush_asce (struct mm_struct *mm,unsigned long asce) {
arch/s390/mm/gmap.c +2 -2
@@ -85,7 +85,7 @@ EXPORT_SYMBOL_GPL(gmap_alloc);static void gmap_flush_tlb (struct gmap *gmap) {if (MACHINE_HAS_IDTE ) -__tlb_flush_asce (gmap->mm, gmap->asce); +__tlb_flush_idte (gmap->asce);else __tlb_flush_global (); }
@@ -124,7 +124,7 @@ void gmap_free(struct gmap *gmap)/* Flush tlb. */ if (MACHINE_HAS_IDTE ) -__tlb_flush_asce (gmap->mm, gmap->asce); +__tlb_flush_idte (gmap->asce);else __tlb_flush_global ();
Greg Kroah-Hartman
maintainerPATCH 36/186 intel_pstate: Fix MSR_CONFIG_TDP_x addressing in core_get_max_pstate()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kiszka <[email protected]>
commit 5fc8f707a2aa40c767c3a338738b9b6fcd151ac1 upstream.
If MSR_CONFIG_TDP_CONTROL is locked, we currently try to address some MSR 0x80000648 or so. Mask out the relevant level bits 0 and 1.
Found while running over the Jailhouse hypervisor which became upset about this strange MSR index.
--- drivers/cpufreq/intel_pstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/intel_pstate.c +1 -1
@@ -944,7 +944,7 @@ static int core_get_max_pstate(void)if (err) goto skip_tar; - tdp_msr =MSR_CONFIG_TDP_NOMINAL + tdp_ctrl; + tdp_msr =MSR_CONFIG_TDP_NOMINAL + (tdp_ctrl &0x3 ); err =rdmsrl_safe (tdp_msr, &tdp_ratio);if (err) goto skip_tar;
Greg Kroah-Hartman
maintainerPATCH 39/186 perf/x86/intel/uncore: Fix uncore num_counters
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kan Liang <[email protected]>
commit 10e9e7bd598f9a66a11a22514c68c13c41fc821b upstream.
Some uncore boxes' num_counters value for Haswell server and Broadwell server are not correct (too large, off by one).
This issue was found by comparing the code with the document. Although there is no bug report from users yet, accessing non-existent counters is dangerous and the behavior is undefined: it may cause miscounting or even crashes.
This patch makes them consistent with the uncore document.
--- arch/x86/events/intel/uncore_snbep.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
arch/x86/events/intel/uncore_snbep.c +5 -5
@@ -2546,7 +2546,7 @@ void hswep_uncore_cpu_init(void)static struct intel_uncore_type hswep_uncore_ha = { .name ="ha" , - .num_counters =5 , + .num_counters =4 , .num_boxes =2 , .perf_ctr_bits =48 ,SNBEP_UNCORE_PCI_COMMON_INIT (),
@@ -2565,7 +2565,7 @@ static struct uncore_event_desc hswep_unstatic struct intel_uncore_type hswep_uncore_imc = { .name ="imc" , - .num_counters =5 , + .num_counters =4 , .num_boxes =8 , .perf_ctr_bits =48 , .fixed_ctr_bits =48 ,
@@ -2611,7 +2611,7 @@ static struct intel_uncore_type hswep_unstatic struct intel_uncore_type hswep_uncore_qpi = { .name ="qpi" , - .num_counters =5 , + .num_counters =4 , .num_boxes =3 , .perf_ctr_bits =48 , .perf_ctr =SNBEP_PCI_PMON_CTR0 ,
@@ -2693,7 +2693,7 @@ static struct event_constraint hswep_uncstatic struct intel_uncore_type hswep_uncore_r3qpi = { .name ="r3qpi" , - .num_counters =4 , + .num_counters =3 , .num_boxes =3 , .perf_ctr_bits =44 , .constraints = hswep_uncore_r3qpi_constraints,
@@ -2892,7 +2892,7 @@ static struct intel_uncore_type bdx_uncostatic struct intel_uncore_type bdx_uncore_imc = { .name ="imc" , - .num_counters =5 , + .num_counters =4 , .num_boxes =8 , .perf_ctr_bits =48 , .fixed_ctr_bits =48 ,
Greg Kroah-Hartman
maintainerPATCH 41/186 media: usbtv: prevent access to freed resources
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Leach <[email protected]>
commit 2a00932f082aff93c3a55426e0c7af6d0ec03997 upstream.
When disconnecting the usbtv device, the sound card is unregistered from ALSA and the snd member of the usbtv struct is set to NULL. If the usbtv snd_trigger work is running, this can cause a race condition where the kernel will attempt to access free'd resources, shown in [1].
This patch fixes the disconnection code by cancelling any snd_trigger work before unregistering the sound card from ALSA and checking that the snd member still exists in the work function.
[1]:
usb 3-1.2: USB disconnect, device number 6
BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 IP: [<ffffffff81093850>] process_one_work+0x30/0x480 PGD 405bbf067 PUD 405bbe067 PMD 0 Call Trace: [<ffffffff81093ce8>] worker_thread+0x48/0x4e0 [<ffffffff81093ca0>] ? process_one_work+0x480/0x480 [<ffffffff81093ca0>] ? process_one_work+0x480/0x480 [<ffffffff81099998>] kthread+0xd8/0xf0 [<ffffffff815c73c2>] ret_from_fork+0x22/0x40 [<ffffffff810998c0>] ? kthread_worker_fn+0x170/0x170 ---[ end trace 0f3dac5c1a38e610 ]---
--- drivers/media/usb/usbtv/usbtv-audio.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/media/usb/usbtv/usbtv-audio.c +5 -0
@@ -278,6 +278,9 @@ static void snd_usbtv_trigger(struct wor { struct usbtv *chip = container_of(work, struct usbtv, snd_trigger); +if (!chip->snd) +return ; +if (atomic_read (&chip->snd_stream))usbtv_audio_start (chip);else
@@ -378,6 +381,8 @@ err:void usbtv_audio_free (struct usbtv *usbtv) { +cancel_work_sync (&usbtv->snd_trigger); +if (usbtv->snd && usbtv->udev) {snd_card_free (usbtv->snd); usbtv->snd =NULL ;
Greg Kroah-Hartman
maintainerPATCH 42/186 media: dvb_ringbuffer: Add memory barriers
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Soeren Moch <[email protected]>
commit ca6e6126db5494f18c6c6615060d4d803b528bff upstream.
Implement memory barriers according to Documentation/circular-buffers.txt:
- use smp_store_release() to update ringbuffer read/write pointers
- use smp_load_acquire() to load write pointer on reader side
- use ACCESS_ONCE() to load read pointer on writer side
This fixes data stream corruptions observed e.g. on an ARM Cortex-A9 quad core system with different types (PCI, USB) of DVB tuners.
--- drivers/media/dvb-core/dvb_ringbuffer.c | 74 ++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 13 deletions(-)
drivers/media/dvb-core/dvb_ringbuffer.c +61 -13
@@ -55,7 +55,13 @@ void dvb_ringbuffer_init(struct dvb_ringint dvb_ringbuffer_empty (struct dvb_ringbuffer *rbuf) { -return (rbuf->pread==rbuf->pwrite); +/* smp_load_acquire() to load write pointer on reader side +* this pairs with smp_store_release() in dvb_ringbuffer_write(), +* dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset() +* +* for memory barriers also see Documentation/circular-buffers.txt +*/ +return (rbuf->pread ==smp_load_acquire (&rbuf->pwrite)); }
@@ -64,7 +70,12 @@ ssize_t dvb_ringbuffer_free(struct dvb_r {ssize_t free; - free = rbuf->pread - rbuf->pwrite; +/* ACCESS_ONCE() to load read pointer on writer side +* this pairs with smp_store_release() in dvb_ringbuffer_read(), +* dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(), +* or dvb_ringbuffer_reset() +*/ + free =ACCESS_ONCE (rbuf->pread) - rbuf->pwrite;if (free <=0 ) free += rbuf->size;return free-1 ;
@@ -76,7 +87,11 @@ ssize_t dvb_ringbuffer_avail(struct dvb_ {ssize_t avail; - avail = rbuf->pwrite - rbuf->pread; +/* smp_load_acquire() to load write pointer on reader side +* this pairs with smp_store_release() in dvb_ringbuffer_write(), +* dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset() +*/ + avail =smp_load_acquire (&rbuf->pwrite) - rbuf->pread;if (avail <0 ) avail += rbuf->size;return avail;
@@ -86,14 +101,25 @@ ssize_t dvb_ringbuffer_avail(struct dvb_void dvb_ringbuffer_flush (struct dvb_ringbuffer *rbuf) { - rbuf->pread = rbuf->pwrite; +/* dvb_ringbuffer_flush() counts as read operation +* smp_load_acquire() to load write pointer +* smp_store_release() to update read pointer, this ensures that the +* correct pointer is visible for subsequent dvb_ringbuffer_free() +* calls on other cpu cores +*/ +smp_store_release (&rbuf->pread,smp_load_acquire (&rbuf->pwrite)); rbuf->error =0 ; }EXPORT_SYMBOL (dvb_ringbuffer_flush);void dvb_ringbuffer_reset (struct dvb_ringbuffer *rbuf) { - rbuf->pread = rbuf->pwrite =0 ; +/* dvb_ringbuffer_reset() counts as read and write operation +* smp_store_release() to update read pointer +*/ +smp_store_release (&rbuf->pread,0 ); +/* smp_store_release() to update write pointer */ +smp_store_release (&rbuf->pwrite,0 ); rbuf->error =0 ; }
@@ -119,12 +145,17 @@ ssize_t dvb_ringbuffer_read_user(structreturn -EFAULT ; buf += split; todo -= split; - rbuf->pread =0 ; +/* smp_store_release() for read pointer update to ensure +* that buf is not overwritten until read is complete, +* this pairs with ACCESS_ONCE() in dvb_ringbuffer_free() +*/ +smp_store_release (&rbuf->pread,0 ); }if (copy_to_user (buf, rbuf->data+rbuf->pread, todo))return -EFAULT ; - rbuf->pread = (rbuf->pread + todo) % rbuf->size; +/* smp_store_release() to update read pointer, see above */ +smp_store_release (&rbuf->pread, (rbuf->pread + todo) % rbuf->size);return len; }
@@ -139,11 +170,16 @@ void dvb_ringbuffer_read(struct dvb_ringmemcpy (buf, rbuf->data+rbuf->pread, split); buf += split; todo -= split; - rbuf->pread =0 ; +/* smp_store_release() for read pointer update to ensure +* that buf is not overwritten until read is complete, +* this pairs with ACCESS_ONCE() in dvb_ringbuffer_free() +*/ +smp_store_release (&rbuf->pread,0 ); }memcpy (buf, rbuf->data+rbuf->pread, todo); - rbuf->pread = (rbuf->pread + todo) % rbuf->size; +/* smp_store_release() to update read pointer, see above */ +smp_store_release (&rbuf->pread, (rbuf->pread + todo) % rbuf->size); }
@@ -158,10 +194,16 @@ ssize_t dvb_ringbuffer_write(struct dvb_memcpy (rbuf->data+rbuf->pwrite, buf, split); buf += split; todo -= split; - rbuf->pwrite =0 ; +/* smp_store_release() for write pointer update to ensure that +* written data is visible on other cpu cores before the pointer +* update, this pairs with smp_load_acquire() in +* dvb_ringbuffer_empty() or dvb_ringbuffer_avail() +*/ +smp_store_release (&rbuf->pwrite,0 ); }memcpy (rbuf->data+rbuf->pwrite, buf, todo); - rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size; +/* smp_store_release() for write pointer update, see above */ +smp_store_release (&rbuf->pwrite, (rbuf->pwrite + todo) % rbuf->size);return len; }
@@ -181,12 +223,18 @@ ssize_t dvb_ringbuffer_write_user(structreturn len - todo; buf += split; todo -= split; - rbuf->pwrite =0 ; +/* smp_store_release() for write pointer update to ensure that +* written data is visible on other cpu cores before the pointer +* update, this pairs with smp_load_acquire() in +* dvb_ringbuffer_empty() or dvb_ringbuffer_avail() +*/ +smp_store_release (&rbuf->pwrite,0 ); } status =copy_from_user (rbuf->data+rbuf->pwrite, buf, todo);if (status)return len - todo; - rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size; +/* smp_store_release() for write pointer update, see above */ +smp_store_release (&rbuf->pwrite, (rbuf->pwrite + todo) % rbuf->size);return len; }
Greg Kroah-Hartman
maintainerPATCH 44/186 videobuf2-v4l2: Verify planes array in buffer dequeueing
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <[email protected]>
commit 83934b75c368f529d084815c463a7ef781dc9751 upstream.
When a buffer is being dequeued using VIDIOC_DQBUF IOCTL, the exact buffer which will be dequeued is not known until the buffer has been removed from the queue. The number of planes is specific to a buffer, not to the queue.
This does lead to the situation where multi-plane buffers may be requested and queued with n planes, but VIDIOC_DQBUF IOCTL may be passed an argument struct with fewer planes.
__fill_v4l2_buffer() however uses the number of planes from the dequeued videobuf2 buffer, overwriting kernel memory (the m.planes array allocated in video_usercopy() in v4l2-ioctl.c) if the user provided fewer planes than the dequeued buffer had. Oops!
--- drivers/media/v4l2-core/videobuf2-v4l2.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/media/v4l2-core/videobuf2-v4l2.c +6 -0
@@ -74,6 +74,11 @@ static int __verify_planes_array(structreturn 0 ; } +static int __verify_planes_array_core (struct vb2_buffer *vb,const void *pb) +{ +return __verify_planes_array (vb, pb); +} +/** * __verify_length() - Verify that the bytesused value for each plane fits in * the plane length and that the data offset doesn't exceed the bytesused value.
@@ -437,6 +442,7 @@ static int __fill_vb2_buffer(struct vb2_ }static const struct vb2_buf_ops v4l2_buf_ops = { + .verify_planes_array = __verify_planes_array_core, .fill_user_buffer = __fill_v4l2_buffer, .fill_vb2_buffer = __fill_vb2_buffer, .copy_timestamp = __copy_timestamp,
Greg Kroah-Hartman
maintainerPATCH 45/186 vb2: core: Skip planes array verification if pb is NULL
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <[email protected]>
commit 126f40298446a82116e1f92a1aaf72b8c8228fae upstream.
An earlier patch fixing an input validation issue introduced another
issue: vb2_core_dqbuf() is called with pb argument value NULL in some cases, causing a NULL pointer dereference. Fix this by skipping the verification as there's nothing to verify.
--- drivers/media/v4l2-core/videobuf2-core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/media/v4l2-core/videobuf2-core.c +6 -4
@@ -1648,7 +1648,7 @@ static int __vb2_get_done_vb(struct vb2_ void *pb, int nonblocking) {unsigned long flags; -int ret; +int ret =0 ;/* * Wait for at least one buffer to become available on the done_list.
@@ -1664,10 +1664,12 @@ static int __vb2_get_done_vb(struct vb2_spin_lock_irqsave (&q->done_lock, flags); *vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry);/* -* Only remove the buffer from done_list if v4l2_buffer can handle all -* the planes. +* Only remove the buffer from done_list if all planes can be +* handled. Some cases such as V4L2 file I/O and DVB have pb +* == NULL; skip the check then as there's nothing to verify. */ - ret =call_bufop (q, verify_planes_array, *vb, pb); +if (pb) + ret =call_bufop (q, verify_planes_array, *vb, pb);if (!ret)list_del (&(*vb)->done_entry);spin_unlock_irqrestore (&q->done_lock, flags);
Greg Kroah-Hartman
maintainerPATCH 47/186 sur40: lower poll interval to fix occasional FPS drops to ~56 FPS
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Echtler <[email protected]>
commit af766ee005c496b8567976dc3eed7676443ed6de upstream.
The framerate sometimes drops below 60 Hz if the poll interval is too high. Lowering it to the minimum of 1 ms fixes this.
--- drivers/input/touchscreen/sur40.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/touchscreen/sur40.c +1 -1
@@ -126,7 +126,7 @@ struct sur40_image_header {#define VIDEO_PACKET_SIZE 16384/* polling interval (ms) */ -#define POLL_INTERVAL 4 +#define POLL_INTERVAL 1/* maximum number of contacts FIXME: this is a guess? */ #define MAX_CONTACTS 64
Greg Kroah-Hartman
maintainerPATCH 48/186 sur40: fix occasional oopses on device close
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Echtler <[email protected]>
commit 6a8588156657e607fcfdffd46c1daae8ba88a1e5 upstream.
Closing the V4L2 device sometimes triggers a kernel oops. Present patch fixes this.
--- drivers/input/touchscreen/sur40.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/input/touchscreen/sur40.c +2 -1
@@ -448,7 +448,7 @@ static void sur40_process_video(struct s/* return error if streaming was stopped in the meantime */ if (sur40->sequence ==-1 ) - goto err_poll; +return ;/* mark as finished */ new_buf->vb.vb2_buf.timestamp =ktime_get_ns ();
@@ -736,6 +736,7 @@ static int sur40_start_streaming(structstatic void sur40_stop_streaming (struct vb2_queue *vq) {struct sur40_state *sur40 =vb2_get_drv_priv (vq); +vb2_wait_for_all_buffers (vq); sur40->sequence =-1 ;/* Release all active buffers */
Greg Kroah-Hartman
maintainerPATCH 49/186 regulator: s2mps11: Fix the voltage linear range for s2mps15
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alim Akhtar <[email protected]>
commit 04c16b84e49a6d609c88f4f5523237ece3612b74 upstream.
This patch fixes some of the LDOs and BUCKs voltage range as per user manual of s2mps15 (REV0.4).
--- drivers/regulator/s2mps11.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/regulator/s2mps11.c +3 -3
@@ -750,7 +750,7 @@ static const struct regulator_linear_ran/* voltage range for s2mps15 LDO 7, 8, 9 and 10 */ static const struct regulator_linear_range s2mps15_ldo_voltage_ranges4[] = { -REGULATOR_LINEAR_RANGE (700000 ,0xc ,0x18 ,25000 ), +REGULATOR_LINEAR_RANGE (700000 ,0x10 ,0x20 ,25000 ), };/* voltage range for s2mps15 LDO 1 */
@@ -760,12 +760,12 @@ static const struct regulator_linear_ran/* voltage range for s2mps15 BUCK 1, 2, 3, 4, 5, 6 and 7 */ static const struct regulator_linear_range s2mps15_buck_voltage_ranges1[] = { -REGULATOR_LINEAR_RANGE (500000 ,0x20 ,0xb0 ,6250 ), +REGULATOR_LINEAR_RANGE (500000 ,0x20 ,0xc0 ,6250 ), };/* voltage range for s2mps15 BUCK 8, 9 and 10 */ static const struct regulator_linear_range s2mps15_buck_voltage_ranges2[] = { -REGULATOR_LINEAR_RANGE (1000000 ,0x20 ,0xc0 ,12500 ), +REGULATOR_LINEAR_RANGE (1000000 ,0x20 ,0x78 ,12500 ), };static const struct regulator_desc s2mps15_regulators[] = {
Greg Kroah-Hartman
maintainerPATCH 50/186 dm: fix second blk_delay_queue() parameter to be in msec units not jiffies
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tahsin Erdogan <[email protected]>
commit bd9f55ea1cf6e14eb054b06ea877d2d1fa339514 upstream.
Commit d548b34b062 ("dm: reduce the queue delay used in dm_request_fn from 100ms to 10ms") always intended the value to be 10 msecs -- it just expressed it in jiffies because earlier commit 7eaceaccab ("block:
remove per-queue plugging") did.
--- drivers/md/dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm.c +1 -1
@@ -2175,7 +2175,7 @@ static void dm_request_fn(struct request md_in_flight(md) && rq->bio && rq->bio->bi_vcnt == 1 && md->last_rq_pos == pos && md->last_rq_rw == rq_data_dir(rq)) || (ti->type->busy && ti->type->busy(ti))) { -blk_delay_queue (q,HZ /100 ); +blk_delay_queue (q,10 );return ; }
Greg Kroah-Hartman
maintainerPATCH 51/186 dm: set DMF_SUSPENDED* _before_ clearing DMF_NOFLUSH_SUSPENDING
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Snitzer <[email protected]>
commit eaf9a7361f47727b166688a9f2096854eef60fbe upstream.
Otherwise, there is potential for both DMF_SUSPENDED* and DMF_NOFLUSH_SUSPENDING to not be set during dm_suspend() -- which is definitely _not_ a valid state.
This fix, in conjuction with "dm rq: fix the starting and stopping of blk-mq queues", addresses the potential for request-based DM multipath's __multipath_map() to see !dm_noflush_suspending() during suspend.
--- drivers/md/dm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/md/dm.c +7 -7
@@ -3128,7 +3128,8 @@ static void unlock_fs(struct mapped_devi* Caller must hold md->suspend_lock */ static int __dm_suspend (struct mapped_device *md,struct dm_table *map, -unsigned suspend_flags,int interruptible) +unsigned suspend_flags,int interruptible, +int dmf_suspended_flag) {bool do_lockfs = suspend_flags &DM_SUSPEND_LOCKFS_FLAG ;bool noflush = suspend_flags &DM_SUSPEND_NOFLUSH_FLAG ;
@@ -3195,6 +3196,8 @@ static int __dm_suspend(struct mapped_de* to finish. */ r =dm_wait_for_completion (md, interruptible); +if (!r) +set_bit (dmf_suspended_flag, &md->flags);if (noflush)clear_bit (DMF_NOFLUSH_SUSPENDING , &md->flags);
@@ -3256,12 +3259,10 @@ retry: map =rcu_dereference_protected (md->map,lockdep_is_held (&md->suspend_lock)); - r =__dm_suspend (md, map, suspend_flags,TASK_INTERRUPTIBLE ); + r =__dm_suspend (md, map, suspend_flags,TASK_INTERRUPTIBLE ,DMF_SUSPENDED );if (r) goto out_unlock; -set_bit (DMF_SUSPENDED , &md->flags); -dm_table_postsuspend_targets (map); out_unlock:
@@ -3355,9 +3356,8 @@ static void __dm_internal_suspend(struct* would require changing .presuspend to return an error -- avoid this * until there is a need for more elaborate variants of internal suspend. */ - (void )__dm_suspend (md, map, suspend_flags,TASK_UNINTERRUPTIBLE ); - -set_bit (DMF_SUSPENDED_INTERNALLY , &md->flags); + (void )__dm_suspend (md, map, suspend_flags,TASK_UNINTERRUPTIBLE , +DMF_SUSPENDED_INTERNALLY );dm_table_postsuspend_targets (map); }
Greg Kroah-Hartman
maintainerPATCH 52/186 xfs: bufferhead chains are invalid after end_page_writeback
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chinner <[email protected]>
commit 28b783e47ad702b8e0f4861ef94cdfce6abd7c80 upstream.
In xfs_finish_page_writeback(), we have a loop that looks like this:
do {
if (off < bvec->bv_offset)
goto next_bh;
if (off > end)
break;
bh->b_end_io(bh, !error);
next_bh:
off += bh->b_size;
} while ((bh = bh->b_this_page) != head);The b_end_io function is end_buffer_async_write(), which will call end_page_writeback() once all the buffers have marked as no longer under IO. This issue here is that the only thing currently protecting both the bufferhead chain and the page from being reclaimed is the PageWriteback state held on the page.
While we attempt to limit the loop to just the buffers covered by the IO, we still read from the buffer size and follow the next pointer in the bufferhead chain. There is no guarantee that either of these are valid after the PageWriteback flag has been cleared. Hence, loops like this are completely unsafe, and result in use-after-free issues. One such problem was caught by Calvin Owens with KASAN:
.....
INFO: Freed in 0x103fc80ec age=18446651500051355200 cpu=2165122683 pid=-1
free_buffer_head+0x41/0x90 __slab_free+0x1ed/0x340 kmem_cache_free+0x270/0x300 free_buffer_head+0x41/0x90 try_to_free_buffers+0x171/0x240 xfs_vm_releasepage+0xcb/0x3b0 try_to_release_page+0x106/0x190 shrink_page_list+0x118e/0x1a10 shrink_inactive_list+0x42c/0xdf0 shrink_zone_memcg+0xa09/0xfa0 shrink_zone+0x2c3/0xbc0 ..... Call Trace: <IRQ> [<ffffffff81e8b8e4>] dump_stack+0x68/0x94 [<ffffffff8153a995>] print_trailer+0x115/0x1a0 [<ffffffff81541174>] object_err+0x34/0x40 [<ffffffff815436e7>] kasan_report_error+0x217/0x530 [<ffffffff81543b33>] __asan_report_load8_noabort+0x43/0x50 [<ffffffff819d651f>] xfs_destroy_ioend+0x3bf/0x4c0 [<ffffffff819d69d4>] xfs_end_bio+0x154/0x220 [<ffffffff81de0c58>] bio_endio+0x158/0x1b0 [<ffffffff81dff61b>] blk_update_request+0x18b/0xb80 [<ffffffff821baf57>] scsi_end_request+0x97/0x5a0 [<ffffffff821c5558>] scsi_io_completion+0x438/0x1690 [<ffffffff821a8d95>] scsi_finish_command+0x375/0x4e0 [<ffffffff821c3940>] scsi_softirq_done+0x280/0x340
Where the access is occuring during IO completion after the buffer had been freed from direct memory reclaim.
Prevent use-after-free accidents in this end_io processing loop by pre-calculating the loop conditionals before calling bh->b_end_io(). The loop is already limited to just the bufferheads covered by the IO in progress, so the offset checks are sufficient to prevent accessing buffers in the chain after end_page_writeback() has been called by the the bh->b_end_io() callout.
Yet another example of why Bufferheads Must Die.
--- fs/xfs/xfs_aops.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
fs/xfs/xfs_aops.c +12 -3
@@ -87,6 +87,12 @@ xfs_find_bdev_for_inode(* We're now finished for good with this page. Update the page state via the * associated buffer_heads, paying attention to the start and end offsets that * we need to process on the page. +* +* Landmine Warning: bh->b_end_io() will call end_page_writeback() on the last +* buffer in the IO. Once it does this, it is unsafe to access the bufferhead or +* the page at all, as we may be racing with memory reclaim and it can free both +* the bufferhead chain and the page as it will see the page as clean and +* unused. */ static void xfs_finish_page_writeback(
@@ -95,8 +101,9 @@ xfs_finish_page_writeback( int error) {unsigned int end = bvec->bv_offset + bvec->bv_len -1 ; -struct buffer_head *head, *bh; +struct buffer_head *head, *bh, *next;unsigned int off =0 ; +unsigned int bsize;ASSERT (bvec->bv_offset <PAGE_SIZE );ASSERT ((bvec->bv_offset & ((1 << inode->i_blkbits) -1 )) ==0 );
@@ -105,15 +112,17 @@ xfs_finish_page_writeback( bh = head =page_buffers (bvec->bv_page); + bsize = bh->b_size;do { + next = bh->b_this_page;if (off < bvec->bv_offset) goto next_bh;if (off > end)break ; bh->b_end_io (bh, !error); next_bh: - off += bh->b_size; - }while ((bh = bh->b_this_page) != head); + off += bsize; + }while ((bh = next) != head); }/*
Greg Kroah-Hartman
maintainerPATCH 53/186 hp-wmi: Fix wifi cannot be hard-unblocked
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
commit fc8a601e1175ae351f662506030f9939cb7fdbfe upstream.
Several users reported wifi cannot be unblocked as discussed in [1]. This patch removes the use of the 2009 flag by BIOS but uses the actual WMI function calls - it will be skipped if WMI reports unsupported.
[1] https://bugzilla.kernel.org/show_bug.cgi?id=69131
--- drivers/platform/x86/hp-wmi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/platform/x86/hp-wmi.c +6 -1
@@ -718,6 +718,11 @@ static int __init hp_wmi_rfkill_setup(stif (err)return err; + err =hp_wmi_perform_query (HPWMI_WIRELESS_QUERY ,1 , &wireless, +sizeof (wireless),0 ); +if (err) +return err; +if (wireless &0x1 ) { wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev, RFKILL_TYPE_WLAN,
@@ -882,7 +887,7 @@ static int __init hp_wmi_bios_setup(stru wwan_rfkill =NULL ; rfkill2_count =0 ; -if (hp_wmi_bios_2009_later () ||hp_wmi_rfkill_setup (device)) +if (hp_wmi_rfkill_setup (device))hp_wmi_rfkill2_setup (device); err =device_create_file (&device->dev, &dev_attr_display);
Greg Kroah-Hartman
maintainerPATCH 54/186 s5p-mfc: Set device name for reserved memory region devs
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Martinez Canillas <[email protected]>
commit 29debab0a94035a390801d1f177d171d014b7765 upstream.
The devices don't have a name set, so makes dev_name() returns NULL which makes harder to identify the devices that are causing issues, for example:
WARNING: CPU: 2 PID: 616 at drivers/base/core.c:251 device_release+0x8c/0x90
Device '(null)' does not have a release() function, it is broken and must be fixed.
And after setting the device name:
WARNING: CPU: 0 PID: 591 at drivers/base/core.c:251 device_release+0x8c/0x90
Device 's5p-mfc-l' does not have a release() function, it is broken and must be fixed.
--- drivers/media/platform/s5p-mfc/s5p_mfc.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/media/platform/s5p-mfc/s5p_mfc.c +4 -0
@@ -1062,6 +1062,8 @@ static int s5p_mfc_alloc_memdevs(structmfc_err ("Not enough memory\n" );return -ENOMEM ; } + +dev_set_name (dev->mem_dev_l,"%s" ,"s5p-mfc-l" );device_initialize (dev->mem_dev_l);of_property_read_u32_array (dev->plat_dev->dev.of_node,"samsung,mfc-l" , mem_info,2 );
@@ -1079,6 +1081,8 @@ static int s5p_mfc_alloc_memdevs(structmfc_err ("Not enough memory\n" );return -ENOMEM ; } + +dev_set_name (dev->mem_dev_r,"%s" ,"s5p-mfc-r" );device_initialize (dev->mem_dev_r);of_property_read_u32_array (dev->plat_dev->dev.of_node,"samsung,mfc-r" , mem_info,2 );
Greg Kroah-Hartman
maintainerPATCH 55/186 s5p-mfc: Add release callback for memory region devs
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Martinez Canillas <[email protected]>
commit 6311f1261f59ce5e51fbe5cc3b5e7737197316ac upstream.
When s5p_mfc_remove() calls put_device() for the reserved memory region devs, the driver core warns that the dev doesn't have a release callback:
WARNING: CPU: 0 PID: 591 at drivers/base/core.c:251 device_release+0x8c/0x90
Device 's5p-mfc-l' does not have a release() function, it is broken and must be fixed.
Also, the declared DMA memory using dma_declare_coherent_memory() isn't relased so add a dev .release that calls dma_release_declared_memory().
--- drivers/media/platform/s5p-mfc/s5p_mfc.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/media/platform/s5p-mfc/s5p_mfc.c +7 -0
@@ -1050,6 +1050,11 @@ static int match_child(struct device *dereturn !strcmp (dev_name (dev), (char *)data); } +static void s5p_mfc_memdev_release (struct device *dev) +{ +dma_release_declared_memory (dev); +} +static void *mfc_get_drv_data (struct platform_device *pdev);static int s5p_mfc_alloc_memdevs (struct s5p_mfc_dev *dev)
@@ -1064,6 +1069,7 @@ static int s5p_mfc_alloc_memdevs(struct }dev_set_name (dev->mem_dev_l,"%s" ,"s5p-mfc-l" ); + dev->mem_dev_l->release = s5p_mfc_memdev_release;device_initialize (dev->mem_dev_l);of_property_read_u32_array (dev->plat_dev->dev.of_node,"samsung,mfc-l" , mem_info,2 );
@@ -1083,6 +1089,7 @@ static int s5p_mfc_alloc_memdevs(struct }dev_set_name (dev->mem_dev_r,"%s" ,"s5p-mfc-r" ); + dev->mem_dev_r->release = s5p_mfc_memdev_release;device_initialize (dev->mem_dev_r);of_property_read_u32_array (dev->plat_dev->dev.of_node,"samsung,mfc-r" , mem_info,2 );
Greg Kroah-Hartman
maintainerPATCH 56/186 dm verity fec: fix block calculation
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sami Tolvanen <[email protected]>
commit 602d1657c603eedd7379a8bcde1ad3a2972ecc5f upstream.
do_div was replaced with div64_u64 at some point, causing a bug with block calculation due to incompatible semantics of the two functions.
--- drivers/md/dm-verity-fec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/md/dm-verity-fec.c +1 -3
@@ -453,9 +453,7 @@ int verity_fec_decode(struct dm_verity **/ offset = block << v->data_dev_block_bits; - - res = offset; -div64_u64 (res, v->fec->rounds << v->data_dev_block_bits); + res =div64_u64 (offset, v->fec->rounds << v->data_dev_block_bits);/* * The base RS block we can feed to the interleaver to find out all
Greg Kroah-Hartman
maintainerPATCH 57/186 iwlwifi: pcie: enable interrupts before releasing the NICs CPU
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
commit 2aabdbdc17b7c53490337bfc58de3409c84d85d2 upstream.
The NIC's CPU gets started after the firmware has been written to its memory. The first thing it does is to send an interrupt to let the driver know that it is running. In order to get that interrupt, the driver needs to make sure it is not masked. Of course, the interrupt needs to be enabled in the driver before the CPU starts to run.
I mistakenly inversed those two steps leading to races which prevented the driver from getting the alive interrupt from the firmware.
Fix that.
--- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/pcie/trans.c +4 -1
@@ -801,6 +801,8 @@ static int iwl_pcie_load_cpu_sections_80 *first_ucode_section = last_read_idx; +iwl_enable_interrupts (trans); +if (cpu ==1 )iwl_write_direct32 (trans,FH_UCODE_LOAD_STATUS ,0xFFFF );else
@@ -980,6 +982,8 @@ static int iwl_pcie_load_given_ucode(striwl_pcie_apply_destination (trans); } +iwl_enable_interrupts (trans); +/* release CPU reset */ iwl_write32 (trans,CSR_RESET ,0 );
@@ -1215,7 +1219,6 @@ static int iwl_trans_pcie_start_fw(struc ret =iwl_pcie_load_given_ucode_8000 (trans, fw); else ret =iwl_pcie_load_given_ucode (trans, fw); -iwl_enable_interrupts (trans);/* re-check RF-Kill state since we may have missed the interrupt */ hw_rfkill =iwl_is_rfkill_set (trans);
Greg Kroah-Hartman
maintainerPATCH 58/186 iwlwifi: pcie: fix a race in firmware loading flow
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
commit f16c3ebfa64fdf0e2dc88e6baa72da95ab70ffd7 upstream.
Upon firmware load interrupt (FH_TX), the ISR re-enables the firmware load interrupt only to avoid races with other flows as described in the commit below. When the firmware is completely loaded, the thread that is loading the firmware will enable all the interrupts to make sure that the driver gets the ALIVE interrupt.
The problem with that is that the thread that is loading the firmware is actually racing against the ISR and we can get to the following situation:
CPU0 CPU1iwl_pcie_load_given_ucode
... iwl_pcie_load_firmware_chunk wait_for_interrupt <interrupt> ISR handles CSR_INT_BIT_FH_TX ISR wakes up the thread on CPU0 /* enable all the interrupts * to get the ALIVE interrupt */ iwl_enable_interrupts ISR re-enables CSR_INT_BIT_FH_TX only /* start the firmware */ iwl_write32(trans, CSR_RESET, 0);
BUG! ALIVE interrupt will never arrive since it has been masked by CPU1.
In order to fix that, change the ISR to first check if STATUS_INT_ENABLED is set. If so, re-enable all the interrupts. If STATUS_INT_ENABLED is clear, then we can check what specific interrupt happened and re-enable only that specific interrupt (RFKILL or FH_TX).
All the credit for the analysis goes to Kirtika who did the actual debugging work.
--- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 21 +++++++++++++++++++-- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 16 +++++++++------- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 -------- 3 files changed, 28 insertions(+), 17 deletions(-)
drivers/net/wireless/intel/iwlwifi/pcie/internal.h +19 -2
@@ -496,7 +496,7 @@ void iwl_pcie_dump_csr(struct iwl_trans/***************************************************** * Helpers ******************************************************/ -static inline void iwl_disable_interrupts (struct iwl_trans *trans) +static inline void _iwl_disable_interrupts (struct iwl_trans *trans) {struct iwl_trans_pcie *trans_pcie =IWL_TRANS_GET_PCIE_TRANS (trans);
@@ -519,7 +519,16 @@ static inline void iwl_disable_interruptIWL_DEBUG_ISR (trans,"Disabled interrupts\n" ); } -static inline void iwl_enable_interrupts (struct iwl_trans *trans) +static inline void iwl_disable_interrupts (struct iwl_trans *trans) +{ +struct iwl_trans_pcie *trans_pcie =IWL_TRANS_GET_PCIE_TRANS (trans); + +spin_lock (&trans_pcie->irq_lock); +_iwl_disable_interrupts (trans); +spin_unlock (&trans_pcie->irq_lock); +} + +static inline void _iwl_enable_interrupts (struct iwl_trans *trans) {struct iwl_trans_pcie *trans_pcie =IWL_TRANS_GET_PCIE_TRANS (trans);
@@ -542,6 +551,14 @@ static inline void iwl_enable_interrupts } } +static inline void iwl_enable_interrupts (struct iwl_trans *trans) +{ +struct iwl_trans_pcie *trans_pcie =IWL_TRANS_GET_PCIE_TRANS (trans); + +spin_lock (&trans_pcie->irq_lock); +_iwl_enable_interrupts (trans); +spin_unlock (&trans_pcie->irq_lock); +}static inline void iwl_enable_hw_int_msk_msix (struct iwl_trans *trans,u32 msk) {struct iwl_trans_pcie *trans_pcie =IWL_TRANS_GET_PCIE_TRANS (trans);
drivers/net/wireless/intel/iwlwifi/pcie/rx.c +9 -7
@@ -1507,7 +1507,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq* have anything to service */ if (test_bit (STATUS_INT_ENABLED , &trans->status)) -iwl_enable_interrupts (trans); +_iwl_enable_interrupts (trans);spin_unlock (&trans_pcie->irq_lock);lock_map_release (&trans->sync_cmd_lockdep_map);return IRQ_NONE ;
@@ -1699,15 +1699,17 @@ irqreturn_t iwl_pcie_irq_handler(int irq inta & ~trans_pcie->inta_mask); } +spin_lock (&trans_pcie->irq_lock); +/* only Re-enable all interrupt if disabled by irq */ +if (test_bit (STATUS_INT_ENABLED , &trans->status)) +_iwl_enable_interrupts (trans);/* we are loading the firmware, enable FH_TX interrupt only */ -if (handled &CSR_INT_BIT_FH_TX ) +else if (handled &CSR_INT_BIT_FH_TX )iwl_enable_fw_load_int (trans); -/* only Re-enable all interrupt if disabled by irq */ -else if (test_bit (STATUS_INT_ENABLED , &trans->status)) -iwl_enable_interrupts (trans);/* Re-enable RF_KILL if it occurred */ else if (handled &CSR_INT_BIT_RF_KILL )iwl_enable_rfkill_int (trans); +spin_unlock (&trans_pcie->irq_lock); out:lock_map_release (&trans->sync_cmd_lockdep_map);
@@ -1771,7 +1773,7 @@ void iwl_pcie_reset_ict(struct iwl_transreturn ;spin_lock (&trans_pcie->irq_lock); -iwl_disable_interrupts (trans); +_iwl_disable_interrupts (trans);memset (trans_pcie->ict_tbl,0 ,ICT_SIZE );
@@ -1787,7 +1789,7 @@ void iwl_pcie_reset_ict(struct iwl_trans trans_pcie->use_ict = true; trans_pcie->ict_index =0 ;iwl_write32 (trans,CSR_INT , trans_pcie->inta_mask); -iwl_enable_interrupts (trans); +_iwl_enable_interrupts (trans);spin_unlock (&trans_pcie->irq_lock); }
drivers/net/wireless/intel/iwlwifi/pcie/trans.c +0 -8
@@ -1037,9 +1037,7 @@ static void _iwl_trans_pcie_stop_device( was_hw_rfkill =iwl_is_rfkill_set (trans);/* tell the device to stop sending interrupts */ -spin_lock (&trans_pcie->irq_lock);iwl_disable_interrupts (trans); -spin_unlock (&trans_pcie->irq_lock);/* device going down, Stop using ICT table */ iwl_pcie_disable_ict (trans);
@@ -1083,9 +1081,7 @@ static void _iwl_trans_pcie_stop_device(* the time, unless the interrupt is ACKed even if the interrupt * should be masked. Re-ACK all the interrupts here. */ -spin_lock (&trans_pcie->irq_lock);iwl_disable_interrupts (trans); -spin_unlock (&trans_pcie->irq_lock);/* clear all status bits */ clear_bit (STATUS_SYNC_HCMD_ACTIVE , &trans->status);
@@ -1570,15 +1566,11 @@ static void iwl_trans_pcie_op_mode_leavemutex_lock (&trans_pcie->mutex);/* disable interrupts - don't enable HW RF kill interrupt */ -spin_lock (&trans_pcie->irq_lock);iwl_disable_interrupts (trans); -spin_unlock (&trans_pcie->irq_lock);iwl_pcie_apm_stop (trans, true); -spin_lock (&trans_pcie->irq_lock);iwl_disable_interrupts (trans); -spin_unlock (&trans_pcie->irq_lock);iwl_pcie_disable_ict (trans);
Greg Kroah-Hartman
maintainerPATCH 59/186 iwlwifi: add new 8260 PCI IDs
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oren Givon <[email protected]>
commit 4b79deece5d45396422d469afa11f9d69ccb3d8b upstream.
Add 3 new 8260 series PCI IDs:
- (0x24F3, 0x10B0)
- (0x24F3, 0xD0B0)
- (0x24F3, 0xB0B0)
--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/intel/iwlwifi/pcie/drv.c +3 -0
@@ -433,6 +433,7 @@ static const struct pci_device_id iwl_hw/* 8000 Series */ {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x1010, iwl8260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x10B0, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x0130, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x1130, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x0132, iwl8260_2ac_cfg)},
@@ -454,6 +455,8 @@ static const struct pci_device_id iwl_hw {IWL_PCI_DEVICE(0x24F3, 0xD010, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xD0B0, iwl8260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0xB0B0, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x8110, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x9010, iwl8260_2ac_cfg)},
Greg Kroah-Hartman
maintainerPATCH 60/186 iwlwifi: add new 8265
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oren Givon <[email protected]>
commit f24bbae565d279cd90c904fe55b539a45631705e upstream.
Add 6 new 8265 series PCI IDs:
- (0x24FD, 0x1130)
- (0x24FD, 0x0130)
- (0x24FD, 0x0910)
- (0x24FD, 0x0930)
- (0x24FD, 0x0950)
- (0x24FD, 0x0850)
--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/wireless/intel/iwlwifi/pcie/drv.c +6 -0
@@ -484,6 +484,8 @@ static const struct pci_device_id iwl_hw {IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x0110, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x1110, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1130, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0130, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x1010, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x0050, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x0150, iwl8265_2ac_cfg)},
@@ -494,6 +496,10 @@ static const struct pci_device_id iwl_hw {IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x9110, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x8130, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0910, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0930, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0950, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0850, iwl8265_2ac_cfg)},/* 9000 Series */ {IWL_PCI_DEVICE(0x2526, 0x0000, iwl9260_2ac_cfg)},
Greg Kroah-Hartman
maintainerPATCH 63/186 spi: pxa2xx: Clear all RFT bits in reset_sccr1() on Intel Quark
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit 152bc19e2fc2b7fce7ffbc2a9cea94b147223702 upstream.
It seems the commit e5262d0568dc ("spi: spi-pxa2xx: SPI support for Intel Quark X1000") misses one place to be adapted for Intel Quark, i.e. in reset_sccr1().
Clear all RFT bits when call reset_sccr1() on Intel Quark.
--- drivers/spi/spi-pxa2xx.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/spi/spi-pxa2xx.c +8 -1
@@ -585,7 +585,14 @@ static void reset_sccr1(struct driver_dau32 sccr1_reg; sccr1_reg =pxa2xx_spi_read (drv_data,SSCR1 ) & ~drv_data->int_cr1; - sccr1_reg &= ~SSCR1_RFT ; +switch (drv_data->ssp_type) { +case QUARK_X1000_SSP : + sccr1_reg &= ~QUARK_X1000_SSCR1_RFT ; +break ; +default : + sccr1_reg &= ~SSCR1_RFT ; +break ; + } sccr1_reg |= chip->threshold;pxa2xx_spi_write (drv_data,SSCR1 , sccr1_reg); }
Greg Kroah-Hartman
maintainerPATCH 65/186 Bluetooth: Add support of 13d3:3490 AR3012 device
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Tunin <[email protected]>
commit 12d868964f7352e8b18e755488f7265a93431de1 upstream.
T: Bus=01 Lev=01 Prnt=01 Port=07 Cnt=05 Dev#= 5 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=13d3 ProdID=3490 Rev=00.01
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
--- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+)
drivers/bluetooth/ath3k.c +2 -0
@@ -123,6 +123,7 @@ static const struct usb_device_id ath3k_ { USB_DEVICE(0x13d3, 0x3472) }, { USB_DEVICE(0x13d3, 0x3474) }, { USB_DEVICE(0x13d3, 0x3487) }, + { USB_DEVICE(0x13d3, 0x3490) },/* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) },
@@ -190,6 +191,7 @@ static const struct usb_device_id ath3k_ { USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3487), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3490), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
drivers/bluetooth/btusb.c +1 -0
@@ -237,6 +237,7 @@ static const struct usb_device_id blackl { USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3487), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3490), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
Greg Kroah-Hartman
maintainerPATCH 67/186 EDAC: Correct channel count limit
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Borislav Petkov <[email protected]>
commit bba142957e04c400440d2df83c1b3b2dfc42e220 upstream.
c44696fff04f ("EDAC: Remove arbitrary limit on number of channels") lifted the arbitrary limit on memory controller channels in EDAC. However, the dynamic channel attributes dynamic_csrow_dimm_attr and dynamic_csrow_ce_count_attr remained 6.
This wasn't a problem except channels 6 and 7 weren't visible in sysfs on machines with more than 6 channels after the conversion to static attr groups with
2c1946b6d629 ("EDAC: Use static attribute groups for managing sysfs entries")
[ without that, we're exploding in edac_create_sysfs_mci_device()
because we're dereferencing out of the bounds of the dynamic_csrow_dimm_attr array. ]
Add attributes for channels 6 and 7 along with a guard for the future, should more channels be required and/or to sanity check for misconfigured machines.
We still need to check against the number of channels present on the MC first, as Thor reported.
--- drivers/edac/edac_mc_sysfs.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
drivers/edac/edac_mc_sysfs.c +19 -1
@@ -313,7 +313,6 @@ static struct device_type csrow_attr_typ* possible dynamic channel DIMM Label attribute files * */ -DEVICE_CHANNEL (ch0_dimm_label,S_IRUGO |S_IWUSR , channel_dimm_label_show, channel_dimm_label_store,0 ); DEVICE_CHANNEL(ch1_dimm_label, S_IRUGO | S_IWUSR,
@@ -326,6 +325,10 @@ DEVICE_CHANNEL(ch4_dimm_label, S_IRUGO | channel_dimm_label_show, channel_dimm_label_store, 4);DEVICE_CHANNEL (ch5_dimm_label,S_IRUGO |S_IWUSR , channel_dimm_label_show, channel_dimm_label_store,5 ); +DEVICE_CHANNEL (ch6_dimm_label,S_IRUGO |S_IWUSR , + channel_dimm_label_show, channel_dimm_label_store,6 ); +DEVICE_CHANNEL (ch7_dimm_label,S_IRUGO |S_IWUSR , + channel_dimm_label_show, channel_dimm_label_store,7 );/* Total possible dynamic DIMM Label attribute file table */ static struct attribute *dynamic_csrow_dimm_attr[] = {
@@ -335,6 +338,8 @@ static struct attribute *dynamic_csrow_d &dev_attr_legacy_ch3_dimm_label.attr.attr, &dev_attr_legacy_ch4_dimm_label.attr.attr, &dev_attr_legacy_ch5_dimm_label.attr.attr, + &dev_attr_legacy_ch6_dimm_label.attr.attr, + &dev_attr_legacy_ch7_dimm_label.attr.attr, NULL };
@@ -351,6 +356,10 @@ DEVICE_CHANNEL(ch4_ce_count, S_IRUGO, channel_ce_count_show, NULL, 4);DEVICE_CHANNEL (ch5_ce_count,S_IRUGO , channel_ce_count_show,NULL ,5 ); +DEVICE_CHANNEL (ch6_ce_count,S_IRUGO , + channel_ce_count_show,NULL ,6 ); +DEVICE_CHANNEL (ch7_ce_count,S_IRUGO , + channel_ce_count_show,NULL ,7 );/* Total possible dynamic ce_count attribute file table */ static struct attribute *dynamic_csrow_ce_count_attr[] = {
@@ -360,6 +369,8 @@ static struct attribute *dynamic_csrow_c &dev_attr_legacy_ch3_ce_count.attr.attr, &dev_attr_legacy_ch4_ce_count.attr.attr, &dev_attr_legacy_ch5_ce_count.attr.attr, + &dev_attr_legacy_ch6_ce_count.attr.attr, + &dev_attr_legacy_ch7_ce_count.attr.attr, NULL };
@@ -371,9 +382,16 @@ static umode_t csrow_dev_is_visible(struif (idx >= csrow->nr_channels)return 0 ; + +if (idx >=ARRAY_SIZE (dynamic_csrow_ce_count_attr) -1 ) { +WARN_ONCE (1 ,"idx: %d\n" , idx); +return 0 ; + } +/* Only expose populated DIMMs */ if (!csrow->channels[idx]->dimm->nr_pages)return 0 ; +return attr->mode; }
Greg Kroah-Hartman
maintainerPATCH 68/186 megaraid_sas: Do not fire MR_DCMD_PD_LIST_QUERY to controllers which do not support it
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumit Saxena <[email protected]>
commit d9083160c2f6ee456ea867ea2279c1fc6124e56f upstream.
There was an issue reported by Lucz Geza on Dell Perc 6i. As per issue reported, megaraid_sas driver goes into an infinite error reporting loop as soon as there is a change in the status of one of the arrays (degrade, resync online etc ). Below are the error logs reported continuously-
Jun 25 08:49:30 ns8 kernel: [ 757.757017] megaraid_sas 0000:02:00.0: DCMD failed/not supported by firmware: megasas_get_pd_list 4115 Jun 25 08:49:30 ns8 kernel: [ 757.778017] megaraid_sas 0000:02:00.0: DCMD failed/not supported by firmware: megasas_get_pd_list 4115 Jun 25 08:49:30 ns8 kernel: [ 757.799017] megaraid_sas 0000:02:00.0: DCMD failed/not supported by firmware: megasas_get_pd_list 4115 Jun 25 08:49:30 ns8 kernel: [ 757.820018] megaraid_sas 0000:02:00.0: DCMD failed/not supported by firmware: megasas_get_pd_list 4115 Jun 25 08:49:30 ns8 kernel: [ 757.841018] megaraid_sas 0000:02:00.0: DCMD failed/not supported by firmware: megasas_get_pd_list 4115
This issue is very much specific to controllers which do not support DCMD- MR_DCMD_PD_LIST_QUERY. In case of any hotplugging/rescanning of drives, AEN thread will be scheduled by driver and fire DCMD- MR_DCMD_PD_LIST_QUERY and if this DCMD is failed then driver will fail this event processing and will not go ahead for further events. This will cause infinite loop of same event getting retried infinitely and causing above mentioned logs.
Fix for this problem is: not to fire DCMD MR_DCMD_PD_LIST_QUERY for controllers which do not support it and send DCMD SUCCESS status to AEN function so that it can go ahead with other event processing.
--- drivers/scsi/megaraid/megaraid_sas_base.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/scsi/megaraid/megaraid_sas_base.c +6 -0
@@ -4079,6 +4079,12 @@ megasas_get_pd_list(struct megasas_instastruct MR_PD_ADDRESS *pd_addr;dma_addr_t ci_h =0 ; +if (instance->pd_list_not_supported) { +dev_info (&instance->pdev->dev,"MR_DCMD_PD_LIST_QUERY " +"not supported by firmware\n" ); +return ret; + } + cmd =megasas_get_cmd (instance);if (!cmd) {
Greg Kroah-Hartman
maintainerPATCH 69/186 HID: uhid: fix timeout when probe races with IO
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roderick Colenbrander <[email protected]>
commit 67f8ecc550b5bda03335f845dc869b8501d25fd0 upstream.
Many devices use userspace bluetooth stacks like BlueZ or Bluedroid in combination with uhid. If any of these stacks is used with a HID device for which the driver performs a HID request as part .probe (or technically another HID operation), this results in a deadlock situation. The deadlock results in a 5 second timeout for I/O operations in HID drivers, so isn't fatal, but none of the I/O operations have a chance of succeeding.
The root cause for the problem is that uhid only allows for one request to be processed at a time per uhid instance and locks out other operations. This means that if a user space is creating a new HID device through 'UHID_CREATE', which ultimately triggers '.probe' through the HID layer. Then any HID request e.g. a read for calibration data would trigger a HID operation on uhid again, but it won't go out to userspace, because it is still stuck in UHID_CREATE. In addition bluetooth stacks are typically single threaded, so they wouldn't be able to handle any requests while waiting on uhid.
Lucikly the UHID spec is somewhat flexible and allows for fixing the issue, without breaking user space. The idea which the patch implements as discussed with David Herrmann is to decouple adding of a hid device (which triggers .probe) from UHID_CREATE. The work will kick off roughly once UHID_CREATE completed (or else will wait a tiny bit of time in .probe for a lock). A HID driver has to call HID to call 'hid_hw_start()' as part of .probe once it is ready for I/O, which triggers UHID_START to user space. Any HID operations should function now within .probe and won't deadlock because userspace is stuck on UHID_CREATE.
We verified this patch on Bluedroid with Android 6.0 and on desktop Linux with BlueZ stacks. Prior to the patch they had the deadlock issue.
--- drivers/hid/uhid.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-)
drivers/hid/uhid.c +24 -9
@@ -51,10 +51,26 @@ struct uhid_device {u32 report_id;u32 report_type;struct uhid_event report_buf; +struct work_struct worker; };static struct miscdevice uhid_misc; +static void uhid_device_add_worker (struct work_struct *work) +{ + struct uhid_device *uhid = container_of(work, struct uhid_device, worker); +int ret; + + ret =hid_add_device (uhid->hid); +if (ret) { +hid_err (uhid->hid,"Cannot register HID device: error %d\n" , ret); + +hid_destroy_device (uhid->hid); + uhid->hid =NULL ; + uhid->running = false; + } +} +static void uhid_queue (struct uhid_device *uhid,struct uhid_event *ev) {__u8 newhead;
@@ -498,18 +514,14 @@ static int uhid_dev_create2(struct uhid_ uhid->hid = hid; uhid->running = true; - ret =hid_add_device (hid); -if (ret) { -hid_err (hid,"Cannot register HID device\n" ); - goto err_hid; - } +/* Adding of a HID device is done through a worker, to allow HID drivers +* which use feature requests during .probe to work, without they would +* be blocked on devlock, which is held by uhid_char_write. +*/ +schedule_work (&uhid->worker);return 0 ; -err_hid: -hid_destroy_device (hid); - uhid->hid =NULL ; - uhid->running = false; err_free:kfree (uhid->rd_data); uhid->rd_data =NULL ;
@@ -550,6 +562,8 @@ static int uhid_dev_destroy(struct uhid_ uhid->running = false;wake_up_interruptible (&uhid->report_wait); +cancel_work_sync (&uhid->worker); +hid_destroy_device (uhid->hid);kfree (uhid->rd_data);
@@ -612,6 +626,7 @@ static int uhid_char_open(struct inode *init_waitqueue_head (&uhid->waitq);init_waitqueue_head (&uhid->report_wait); uhid->running = false; +INIT_WORK (&uhid->worker, uhid_device_add_worker); file->private_data = uhid;nonseekable_open (inode, file);
Greg Kroah-Hartman
maintainerPATCH 70/186 ovl: disallow overlayfs as upperdir
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <[email protected]>
commit 76bc8e2843b66f8205026365966b49ec6da39ae7 upstream.
This does not work and does not make sense. So instead of fixing it (probably not hard) just disallow.
--- fs/overlayfs/super.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/overlayfs/super.c +2 -1
@@ -404,7 +404,8 @@ static struct ovl_entry *ovl_alloc_entrystatic bool ovl_dentry_remote (struct dentry *dentry) {return dentry->d_flags & - (DCACHE_OP_REVALIDATE |DCACHE_OP_WEAK_REVALIDATE ); + (DCACHE_OP_REVALIDATE |DCACHE_OP_WEAK_REVALIDATE | +DCACHE_OP_REAL ); }static bool ovl_dentry_weird (struct dentry *dentry)
Greg Kroah-Hartman
maintainerPATCH 71/186 remoteproc: Fix potential race condition in rproc_add
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Gerlach <[email protected]>
commit d2e12e66a939c54ed84e5f1b6947f0c45f6c56eb upstream.
rproc_add adds the newly created remoteproc to a list for use by rproc_get_by_phandle and then does some additional processing to finish adding the remoteproc. This leaves a small window of time in which the rproc is available in the list but not yet fully initialized, so if another driver comes along and gets a handle to the rproc, it will be invalid. Rearrange the code in rproc_add to make sure the rproc is added to the list only after it has been successfuly initialized.
--- drivers/remoteproc/remoteproc_core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/remoteproc/remoteproc_core.c +9 -6
@@ -1264,11 +1264,6 @@ int rproc_add(struct rproc *rproc)if (ret <0 )return ret; -/* expose to rproc_get_by_phandle users */ -mutex_lock (&rproc_list_mutex); -list_add (&rproc->node, &rproc_list); -mutex_unlock (&rproc_list_mutex); -dev_info (dev,"%s is available\n" , rproc->name);dev_info (dev,"Note: remoteproc is still under development and considered experimental.\n" );
@@ -1276,8 +1271,16 @@ int rproc_add(struct rproc *rproc)/* create debugfs entries */ rproc_create_debug_dir (rproc); + ret =rproc_add_virtio_devices (rproc); +if (ret <0 ) +return ret; + +/* expose to rproc_get_by_phandle users */ +mutex_lock (&rproc_list_mutex); +list_add (&rproc->node, &rproc_list); +mutex_unlock (&rproc_list_mutex); -return rproc_add_virtio_devices (rproc); +return 0 ; }EXPORT_SYMBOL (rproc_add);
Greg Kroah-Hartman
maintainerPATCH 72/186 ARC: mm: dont loose PTE_SPECIAL in pte_modify()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineet Gupta <[email protected]>
commit 3925a16ae980c79d1a8fd182d7f9487da1edd4dc upstream.
LTP madvise05 was generating mm splat
| [ARCLinux]# /sd/ltp/testcases/bin/madvise05 | BUG: Bad page map in process madvise05 pte:80e08211 pmd:9f7d4000 | page:9fdcfc90 count:1 mapcount:-1 mapping: (null) index:0x0 flags: 0x404(referenced|reserved) | page dumped because: bad pte | addr:200b8000 vm_flags:00000070 anon_vma: (null) mapping: (null) index:1005c | file: (null) fault: (null) mmap: (null) readpage: (null) | CPU: 2 PID: 6707 Comm: madvise05
And for newer kernels, the system was rendered unusable afterwards.
The problem was mprotect->pte_modify() clearing PTE_SPECIAL (which is set to identify the special zero page wired to the pte). When pte was finally unmapped, special casing for zero page was not done, and instead it was treated as a "normal" page, tripping on the map counts etc.
This fixes ARC STAR 9001053308
--- arch/arc/include/asm/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arc/include/asm/pgtable.h +1 -1
@@ -110,7 +110,7 @@#define ___DEF (_PAGE_PRESENT | _PAGE_CACHEABLE)/* Set of bits not changed in pte_modify */ -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_SPECIAL)/* More Abbrevaited helpers */ #define PAGE_U_NONE __pgprot(___DEF)
Greg Kroah-Hartman
maintainerPATCH 73/186 ARC: dma: fix address translation in arc_dma_free
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Kondratiev <[email protected]>
commit b4dff2874006e54b60ce4f4dbcfec9ab81c6aff4 upstream.
page should be calculated using physical address. If platform uses non-trivial dma-to-phys memory translation, dma_handle should be converted to physicval address before calculation of page.
Failing to do so results in struct page * pointing to wrong or non-existent memory.
--- arch/arc/mm/dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arc/mm/dma.c +2 -1
@@ -92,7 +92,8 @@ static void *arc_dma_alloc(struct devicestatic void arc_dma_free (struct device *dev,size_t size,void *vaddr,dma_addr_t dma_handle,struct dma_attrs *attrs) { -struct page *page =virt_to_page (dma_handle); +phys_addr_t paddr =plat_dma_to_phys (dev, dma_handle); +struct page *page =virt_to_page (paddr);int is_non_coh =1 ; is_non_coh = dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs) ||
Greg Kroah-Hartman
maintainerPATCH 74/186 jbd2: make journal y2038 safe
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit abcfb5d979892fc8b12574551fc907c05fe1b11b upstream.
The jbd2 journal stores the commit time in 64-bit seconds and 32-bit nanoseconds, which avoids an overflow in 2038, but it gets the numbers from current_kernel_time(), which uses 'long' seconds on 32-bit architectures.
This simply changes the code to call current_kernel_time64() so we use 64-bit seconds consistently.
--- fs/jbd2/commit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jbd2/commit.c +1 -1
@@ -124,7 +124,7 @@ static int journal_submit_commit_record(struct commit_header *tmp;struct buffer_head *bh;int ret; -struct timespec now =current_kernel_time (); +struct timespec64 now =current_kernel_time64 (); *cbh =NULL ;
Greg Kroah-Hartman
maintainerPATCH 75/186 fs/cifs: make share unaccessible at root level mountable
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aurelien Aptel <[email protected]>
commit a6b5058fafdf508904bbf16c29b24042cef3c496 upstream.
if, when mounting //HOST/share/sub/dir/foo we can query /sub/dir/foo but not any of the path components above:
- store the /sub/dir/foo prefix in the cifs super_block info
- in the superblock, set root dentry to the subpath dentry (instead of the share root)
- set a flag in the superblock to remember it
- use prefixpath when building path from a dentry
fixes bso#8950
--- fs/cifs/cifs_fs_sb.h | 4 ++++ fs/cifs/cifsfs.c | 14 +++++++++++++- fs/cifs/connect.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/dir.c | 20 ++++++++++++++++++-- fs/cifs/inode.c | 22 ++++++++++++++++++++-- 5 files changed, 104 insertions(+), 5 deletions(-)
fs/cifs/cifs_fs_sb.h +4 -0
@@ -46,6 +46,9 @@#define CIFS_MOUNT_CIFS_BACKUPUID 0x200000/* backup intent bit for a user */ #define CIFS_MOUNT_CIFS_BACKUPGID 0x400000/* backup intent bit for a group */ #define CIFS_MOUNT_MAP_SFM_CHR 0x800000/* SFM/MAC mapping for illegal chars */ +#define CIFS_MOUNT_USE_PREFIX_PATH 0x1000000/* make subpath with unaccessible +* root mountable +*/ struct cifs_sb_info {struct rb_root tlink_tree;
@@ -67,5 +70,6 @@ struct cifs_sb_info {struct backing_dev_info bdi;struct delayed_work prune_tlinks;struct rcu_head rcu; + char *prepath; };#endif /* _CIFS_FS_SB_H */
fs/cifs/cifsfs.c +13 -1
@@ -689,6 +689,14 @@ cifs_do_mount(struct file_system_type *f goto out_cifs_sb; } +if (volume_info->prepath) { + cifs_sb->prepath =kstrdup (volume_info->prepath,GFP_KERNEL ); +if (cifs_sb->prepath ==NULL ) { + root =ERR_PTR (-ENOMEM ); + goto out_cifs_sb; + } + } +cifs_setup_cifs_sb (volume_info, cifs_sb); rc =cifs_mount (cifs_sb, volume_info);
@@ -727,7 +735,11 @@ cifs_do_mount(struct file_system_type *f sb->s_flags |=MS_ACTIVE ; } - root =cifs_get_root (volume_info, sb); +if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_USE_PREFIX_PATH ) + root =dget (sb->s_root); +else + root =cifs_get_root (volume_info, sb); +if (IS_ERR (root)) goto out_super;
fs/cifs/connect.c +49 -0
67 lines not on this page · raw message
fs/cifs/dir.c +18 -2
@@ -84,6 +84,7 @@ build_path_from_dentry(struct dentry *distruct dentry *temp;int namelen;int dfsplen; +int pplen =0 ;char *full_path;char dirsep;struct cifs_sb_info *cifs_sb =CIFS_SB (direntry->d_sb);
@@ -95,8 +96,12 @@ build_path_from_dentry(struct dentry *di dfsplen =strnlen (tcon->treeName,MAX_TREE_SIZE +1 ); else dfsplen =0 ; + +if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_USE_PREFIX_PATH ) + pplen = cifs_sb->prepath ?strlen (cifs_sb->prepath) +1 :0 ; + cifs_bp_rename_retry: - namelen = dfsplen; + namelen = dfsplen + pplen; seq =read_seqbegin (&rename_lock);rcu_read_lock ();for (temp = direntry; !IS_ROOT (temp);) {
@@ -137,7 +142,7 @@ cifs_bp_rename_retry: } }rcu_read_unlock (); -if (namelen != dfsplen ||read_seqretry (&rename_lock, seq)) { +if (namelen != dfsplen + pplen ||read_seqretry (&rename_lock, seq)) {cifs_dbg (FYI ,"did not end path lookup where expected. namelen=%ddfsplen=%d\n" , namelen, dfsplen);/* presumably this is only possible if racing with a rename
@@ -153,6 +158,17 @@ cifs_bp_rename_retry:those safely to '/' if any are found in the middle of the prepath */ /* BB test paths to Windows with '/' in the midst of prepath */ +if (pplen) { +int i; + +cifs_dbg (FYI ,"using cifs_sb prepath <%s>\n" , cifs_sb->prepath); +memcpy (full_path+dfsplen+1 , cifs_sb->prepath, pplen-1 ); + full_path[dfsplen] ='\\' ; +for (i =0 ; i < pplen-1 ; i++) +if (full_path[dfsplen+1 +i] =='/' ) + full_path[dfsplen+1 +i] =CIFS_DIR_SEP (cifs_sb); + } +if (dfsplen) {strncpy (full_path, tcon->treeName, dfsplen);if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_POSIX_PATHS ) {
fs/cifs/inode.c +20 -2
@@ -1002,10 +1002,26 @@ struct inode *cifs_root_iget(struct supestruct inode *inode =NULL ;long rc;struct cifs_tcon *tcon =cifs_sb_master_tcon (cifs_sb); +char *path =NULL ; +int len; + +if ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_USE_PREFIX_PATH ) + && cifs_sb->prepath) { + len =strlen (cifs_sb->prepath); + path =kzalloc (len +2 /* leading sep + null */ ,GFP_KERNEL ); +if (path ==NULL ) +return ERR_PTR (-ENOMEM ); + path[0 ] ='/' ; +memcpy (path+1 , cifs_sb->prepath, len); + }else { + path =kstrdup ("" ,GFP_KERNEL ); +if (path ==NULL ) +return ERR_PTR (-ENOMEM ); + } xid =get_xid ();if (tcon->unix_ext) { - rc =cifs_get_inode_info_unix (&inode,"" , sb, xid); + rc =cifs_get_inode_info_unix (&inode, path, sb, xid);/* some servers mistakenly claim POSIX support */ if (rc != -EOPNOTSUPP ) goto iget_no_retry;
@@ -1013,7 +1029,8 @@ struct inode *cifs_root_iget(struct supe tcon->unix_ext = false; } - rc =cifs_get_inode_info (&inode,"" ,NULL , sb, xid,NULL ); +convert_delimiter (path,CIFS_DIR_SEP (cifs_sb)); + rc =cifs_get_inode_info (&inode, path,NULL , sb, xid,NULL ); iget_no_retry:if (!inode) {
@@ -1042,6 +1059,7 @@ iget_no_retry: } out: +kfree (path);/* can not call macro free_xid here since in a void func * TODO: This is no longer true */
Greg Kroah-Hartman
maintainerPATCH 76/186 cifs: Check for existing directory when opening file with O_CREAT
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sachin Prabhu <[email protected]>
commit 8d9535b6efd86e6c07da59f97e68f44efb7fe080 upstream.
When opening a file with O_CREAT flag, check to see if the file opened is an existing directory.
This prevents the directory from being opened which subsequently causes a crash when the close function for directories cifs_closedir() is called which frees up the file->private_data memory while the file is still listed on the open file list for the tcon.
--- fs/cifs/dir.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
fs/cifs/dir.c +21 -3
@@ -245,6 +245,13 @@ cifs_do_create(struct inode *inode, stru goto cifs_create_get_file_info; } +if (S_ISDIR (newinode->i_mode)) { +CIFSSMBClose (xid, tcon, fid->netfid); +iput (newinode); + rc = -EISDIR ; + goto out; + } +if (!S_ISREG (newinode->i_mode)) {/* * The server may allow us to open things like
@@ -415,10 +422,14 @@ cifs_create_set_dentry:if (rc !=0 ) {cifs_dbg (FYI ,"Create worked, get_inode_info failed rc = %d\n" , rc); -if (server->ops->close) - server->ops->close (xid, tcon, fid); - goto out; + goto out_err; } + +if (S_ISDIR (newinode->i_mode)) { + rc = -EISDIR ; + goto out_err; + } +d_drop (direntry);d_add (direntry, newinode);
@@ -426,6 +437,13 @@ out:kfree (buf);kfree (full_path);return rc; + +out_err: +if (server->ops->close) + server->ops->close (xid, tcon, fid); +if (newinode) +iput (newinode); + goto out; }int
Greg Kroah-Hartman
maintainerPATCH 77/186 cifs: unbreak TCP session reuse
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rabin Vincent <[email protected]>
commit b782fcc1cbeb7e336c0ed1f00004b2208f48ffe0 upstream.
adfeb3e0 ("cifs: Make echo interval tunable") added a comparison of vol->echo_interval to server->echo_interval as a criterium to match_server(), but:
(1) A default value is set for server->echo_interval but not for vol->echo_interval, meaning these can never match if the echo_interval option is not specified.
(2) vol->echo_interval is in seconds but server->echo_interval is in jiffies, meaning these can never match even if the echo_interval option is specified.
This broke TCP session reuse since match_server() can never return 1. Fix it.
--- fs/cifs/connect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/cifs/connect.c +3 -1
@@ -1228,6 +1228,8 @@ cifs_parse_mount_options(const char *mou vol->ops = &smb1_operations; vol->vals = &smb1_values; + vol->echo_interval =SMB_ECHO_INTERVAL_DEFAULT ; +if (!mountdata) goto cifs_parse_mount_err;
@@ -2049,7 +2051,7 @@ static int match_server(struct TCP_Serveif (!match_security (server, vol))return 0 ; -if (server->echo_interval != vol->echo_interval) +if (server->echo_interval != vol->echo_interval *HZ )return 0 ;return 1 ;
Greg Kroah-Hartman
maintainerPATCH 78/186 cifs: fix crash due to race in hmac(md5) handling
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rabin Vincent <[email protected]>
commit bd975d1eead2558b76e1079e861eacf1f678b73b upstream.
The secmech hmac(md5) structures are present in the TCP_Server_Info struct and can be shared among multiple CIFS sessions. However, the server mutex is not currently held when these structures are allocated and used, which can lead to a kernel crashes, as in the scenario below:
mount.cifs(8) #1 mount.cifs(8) #2
Is secmech.sdeschmaccmd5 allocated?
// false
Is secmech.sdeschmaccmd5 allocated? // false
secmech.hmacmd = crypto_alloc_shash..
secmech.sdeschmaccmd5 = kzalloc..sdeschmaccmd5->shash.tfm = &secmec.hmacmd;
secmech.sdeschmaccmd5 = kzalloc // sdeschmaccmd5->shash.tfm // not yet assigned
crypto_shash_update()
deref NULL sdeschmaccmd5->shash.tfm
Unable to handle kernel paging request at virtual address 00000030 epc : 8027ba34 crypto_shash_update+0x38/0x158 ra : 8020f2e8 setup_ntlmv2_rsp+0x4bc/0xa84 Call Trace: crypto_shash_update+0x38/0x158 setup_ntlmv2_rsp+0x4bc/0xa84 build_ntlmssp_auth_blob+0xbc/0x34c sess_auth_rawntlmssp_authenticate+0xac/0x248 CIFS_SessSetup+0xf0/0x178 cifs_setup_session+0x4c/0x84 cifs_get_smb_ses+0x2c8/0x314 cifs_mount+0x38c/0x76c cifs_do_mount+0x98/0x440 mount_fs+0x20/0xc0 vfs_kern_mount+0x58/0x138 do_mount+0x1e8/0xccc SyS_mount+0x88/0xd4 syscall_common+0x30/0x54
Fix this by locking the srv_mutex around the code which uses these hmac(md5) structures. All the other secmech algos already have similar locking.
--- fs/cifs/cifsencrypt.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
fs/cifs/cifsencrypt.c +10 -6
@@ -743,24 +743,26 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, cmemcpy (ses->auth_key.response + baselen, tiblob, tilen); +mutex_lock (&ses->server->srv_mutex); + rc =crypto_hmacmd5_alloc (ses->server);if (rc) {cifs_dbg (VFS ,"could not crypto alloc hmacmd5 rc %d\n" , rc); - goto setup_ntlmv2_rsp_ret; + goto unlock; }/* calculate ntlmv2_hash */ rc =calc_ntlmv2_hash (ses, ntlmv2_hash, nls_cp);if (rc) {cifs_dbg (VFS ,"could not get v2 hash rc %d\n" , rc); - goto setup_ntlmv2_rsp_ret; + goto unlock; }/* calculate first part of the client response (CR1) */ rc =CalcNTLMv2_response (ses, ntlmv2_hash);if (rc) {cifs_dbg (VFS ,"Could not calculate CR1 rc: %d\n" , rc); - goto setup_ntlmv2_rsp_ret; + goto unlock; }/* now calculate the session key for NTLMv2 */
@@ -769,13 +771,13 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, cif (rc) {cifs_dbg (VFS ,"%s: Could not set NTLMV2 Hash as a key\n" , __func__); - goto setup_ntlmv2_rsp_ret; + goto unlock; } rc =crypto_shash_init (&ses->server->secmech.sdeschmacmd5->shash);if (rc) {cifs_dbg (VFS ,"%s: Could not init hmacmd5\n" , __func__); - goto setup_ntlmv2_rsp_ret; + goto unlock; } rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
@@ -783,7 +785,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c CIFS_HMAC_MD5_HASH_SIZE);if (rc) {cifs_dbg (VFS ,"%s: Could not update with response\n" , __func__); - goto setup_ntlmv2_rsp_ret; + goto unlock; } rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
@@ -791,6 +793,8 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, cif (rc)cifs_dbg (VFS ,"%s: Could not generate md5 hash\n" , __func__); +unlock: +mutex_unlock (&ses->server->srv_mutex); setup_ntlmv2_rsp_ret:kfree (tiblob);
Greg Kroah-Hartman
maintainerPATCH 79/186 CIFS: Fix a possible invalid memory access in smb2_query_symlink()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Shilovsky <[email protected]>
commit 7893242e2465aea6f2cbc2639da8fa5ce96e8cc2 upstream.
During following a symbolic link we received err_buf from SMB2_open(). While the validity of SMB2 error response is checked previously in smb2_check_message() a symbolic link payload is not checked at all. Fix it by adding such checks.
--- fs/cifs/smb2ops.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-)
fs/cifs/smb2ops.c +29 -1
@@ -1044,6 +1044,9 @@ smb2_new_lease_key(struct cifs_fid *fid)get_random_bytes (fid->lease_key,SMB2_LEASE_KEY_SIZE ); } +#define SMB2_SYMLINK_STRUCT_SIZE \ + (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp)) + static int smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, const char *full_path, char **target_path,
@@ -1056,7 +1059,10 @@ smb2_query_symlink(const unsigned int xistruct cifs_fid fid;struct smb2_err_rsp *err_buf =NULL ;struct smb2_symlink_err_rsp *symlink; -unsigned int sub_len, sub_offset; +unsigned int sub_len; +unsigned int sub_offset; +unsigned int print_len; +unsigned int print_offset;cifs_dbg (FYI ,"%s: path: %s\n" , __func__, full_path);
@@ -1077,11 +1083,33 @@ smb2_query_symlink(const unsigned int xikfree (utf16_path);return -ENOENT ; } + +if (le32_to_cpu (err_buf->ByteCount) <sizeof (struct smb2_symlink_err_rsp ) || +get_rfc1002_length (err_buf) +4 <SMB2_SYMLINK_STRUCT_SIZE ) { +kfree (utf16_path); +return -ENOENT ; + } +/* open must fail on symlink - reset rc */ rc =0 ; symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData; sub_len =le16_to_cpu (symlink->SubstituteNameLength); sub_offset =le16_to_cpu (symlink->SubstituteNameOffset); + print_len =le16_to_cpu (symlink->PrintNameLength); + print_offset =le16_to_cpu (symlink->PrintNameOffset); + +if (get_rfc1002_length (err_buf) +4 < +SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { +kfree (utf16_path); +return -ENOENT ; + } + +if (get_rfc1002_length (err_buf) +4 < +SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { +kfree (utf16_path); +return -ENOENT ; + } + *target_path =cifs_strndup_from_utf16 ( (char *)symlink->PathBuffer + sub_offset, sub_len, true, cifs_sb->local_nls);
Greg Kroah-Hartman
maintainerPATCH 80/186 random: add interrupt callback to VMBus IRQ handler
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Mueller <[email protected]>
commit 4b44f2d18a330565227a7348844493c59366171e upstream.
The Hyper-V Linux Integration Services use the VMBus implementation for communication with the Hypervisor. VMBus registers its own interrupt handler that completely bypasses the common Linux interrupt handling. This implies that the interrupt entropy collector is not triggered.
This patch adds the interrupt entropy collection callback into the VMBus interrupt handler function.
--- drivers/char/random.c | 1 + drivers/hv/vmbus_drv.c | 3 +++ 2 files changed, 4 insertions(+)
drivers/char/random.c +1 -0
@@ -949,6 +949,7 @@ void add_interrupt_randomness(int irq, i/* award one bit for the contents of the fast pool */ credit_entropy_bits (r, credit +1 ); } +EXPORT_SYMBOL_GPL (add_interrupt_randomness);#ifdef CONFIG_BLOCK void add_disk_randomness (struct gendisk *disk)
drivers/hv/vmbus_drv.c +3 -0
@@ -42,6 +42,7 @@#include <linux/screen_info.h> #include <linux/kdebug.h> #include <linux/efi.h> +#include <linux/random.h> #include "hyperv_vmbus.h" static struct acpi_device *hv_acpi_dev;
@@ -806,6 +807,8 @@ static void vmbus_isr(void)else tasklet_schedule (hv_context.msg_dpc[cpu]); } + +add_interrupt_randomness (HYPERVISOR_CALLBACK_VECTOR ,0 ); }
Greg Kroah-Hartman
maintainerPATCH 81/186 random: properly align get_random_int_hash
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit b1132deac01c2332d234fa821a70022796b79182 upstream.
get_random_long() reads from the get_random_int_hash array using an unsigned long pointer. For this code to be guaranteed correct on all architectures, the array must be aligned to an unsigned long boundary.
--- drivers/char/random.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/char/random.c +3 -1
@@ -1775,13 +1775,15 @@ int random_int_secret_init(void)return 0 ; } +static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) +__aligned(sizeof(unsigned long)) ; +/* * Get a random word for internal kernel use only. Similar to urandom but * with the goal of minimal entropy pool depletion. As a result, the random * value is not cryptographically secure but for several uses the cost of * depleting entropy is too high */ -static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash);unsigned int get_random_int (void ) {__u32 *hash;
Greg Kroah-Hartman
maintainerPATCH 82/186 random: initialize the non-blocking pool via add_hwgenerator_randomness()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 3371f3da08cff4b75c1f2dce742d460539d6566d upstream.
If we have a hardware RNG and are using the in-kernel rngd, we should use this to initialize the non-blocking pool so that getrandom(2) doesn't block unnecessarily.
--- drivers/char/random.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/char/random.c +11 -5
@@ -1853,12 +1853,18 @@ void add_hwgenerator_randomness(const ch {struct entropy_store *poolp = &input_pool; -/* Suspend writing if we're above the trickle threshold. -* We'll be woken up again once below random_write_wakeup_thresh, -* or when the calling thread is about to terminate. -*/ -wait_event_interruptible (random_write_wait,kthread_should_stop () || +if (unlikely (nonblocking_pool.initialized ==0 )) + poolp = &nonblocking_pool; +else { +/* Suspend writing if we're above the trickle +* threshold. We'll be woken up again once below +* random_write_wakeup_thresh, or when the calling +* thread is about to terminate. +*/ +wait_event_interruptible (random_write_wait, +kthread_should_stop () ||ENTROPY_BITS (&input_pool) <= random_write_wakeup_bits); + }mix_pool_bytes (poolp, buffer, count);credit_entropy_bits (poolp, entropy); }
Greg Kroah-Hartman
maintainerPATCH 83/186 random: print a warning for the first ten uninitialized random users
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 9b4d008787f864f17d008c9c15bbe8a0f7e2fc24 upstream.
Since systemd is consistently using /dev/urandom before it is initialized, we can't see the other potentially dangerous users of /dev/urandom immediately after boot. So print the first ten such complaints instead.
--- drivers/char/random.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/char/random.c +8 -4
@@ -1462,12 +1462,16 @@ random_read(struct file *file, char __usstatic ssize_t urandom_read (struct file *file,char __user *buf,size_t nbytes,loff_t *ppos) { +static int maxwarn =10 ;int ret; -if (unlikely (nonblocking_pool.initialized ==0 )) -printk_once (KERN_NOTICE "random: %s urandom read " -"with %d bits of entropy available\n" , - current->comm, nonblocking_pool.entropy_total); +if (unlikely (nonblocking_pool.initialized ==0 ) && + maxwarn >0 ) { + maxwarn--; +printk (KERN_NOTICE "random: %s: uninitialized urandom read " +"(%zd bytes read, %d bits of entropy available)\n" , + current->comm, nbytes, nonblocking_pool.entropy_total); + } nbytes =min_t (size_t, nbytes,INT_MAX >> (ENTROPY_SHIFT +3 )); ret =extract_entropy_user (&nonblocking_pool, buf, nbytes);
Greg Kroah-Hartman
maintainerPATCH 84/186 cachefiles: Fix race between inactivating and culling a cache object
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
commit db20a8925bc420eed033c5d91ff6afa74465e521 upstream.
There's a race between cachefiles_mark_object_inactive() and cachefiles_cull():
(1) cachefiles_cull() can't delete a backing file until the cache object is marked inactive, but as soon as that's the case it's fair game.
(2) cachefiles_mark_object_inactive() marks the object as being inactive and *only then* reads the i_blocks on the backing inode - but cachefiles_cull() might've managed to delete it by this point.
Fix this by making sure cachefiles_mark_object_inactive() gets any data it needs from the backing inode before deactivating the object.
Without this, the following oops may occur:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000098 IP: [<ffffffffa06c5cc1>] cachefiles_mark_object_inactive+0x61/0xb0 [cachefiles] ... CPU: 11 PID: 527 Comm: kworker/u64:4 Tainted: G I ------------ 3.10.0-470.el7.x86_64 #1 Hardware name: Hewlett-Packard HP Z600 Workstation/0B54h, BIOS 786G4 v03.19 03/11/2011 Workqueue: fscache_object fscache_object_work_func [fscache] task: ffff880035edaf10 ti: ffff8800b77c0000 task.ti: ffff8800b77c0000 RIP: 0010:[<ffffffffa06c5cc1>] cachefiles_mark_object_inactive+0x61/0xb0 [cachefiles] RSP: 0018:ffff8800b77c3d70 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff8800bf6cc400 RCX: 0000000000000034 RDX: 0000000000000000 RSI: ffff880090ffc710 RDI: ffff8800bf761ef8 RBP: ffff8800b77c3d88 R08: 2000000000000000 R09: 0090ffc710000000 R10: ff51005d2ff1c400 R11: 0000000000000000 R12: ffff880090ffc600 R13: ffff8800bf6cc520 R14: ffff8800bf6cc400 R15: ffff8800bf6cc498 FS: 0000000000000000(0000) GS:ffff8800bb8c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000098 CR3: 00000000019ba000 CR4: 00000000000007e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Stack: ffff880090ffc600 ffff8800bf6cc400 ffff8800867df140 ffff8800b77c3db0 ffffffffa06c48cb ffff880090ffc600 ffff880090ffc180 ffff880090ffc658 ffff8800b77c3df0 ffffffffa085d846 ffff8800a96b8150 ffff880090ffc600 Call Trace: [<ffffffffa06c48cb>] cachefiles_drop_object+0x6b/0xf0 [cachefiles] [<ffffffffa085d846>] fscache_drop_object+0xd6/0x1e0 [fscache] [<ffffffffa085d615>] fscache_object_work_func+0xa5/0x200 [fscache] [<ffffffff810a605b>] process_one_work+0x17b/0x470 [<ffffffff810a6e96>] worker_thread+0x126/0x410 [<ffffffff810a6d70>] ? rescuer_thread+0x460/0x460 [<ffffffff810ae64f>] kthread+0xcf/0xe0 [<ffffffff810ae580>] ? kthread_create_on_node+0x140/0x140 [<ffffffff81695418>] ret_from_fork+0x58/0x90 [<ffffffff810ae580>] ? kthread_create_on_node+0x140/0x140
The oopsing code shows:
callq 0xffffffff810af6a0 <wake_up_bit> mov 0xf8(%r12),%rax mov 0x30(%rax),%rax mov 0x98(%rax),%rax <---- oops here lock add %rax,0x130(%rbx)
where this is:
d_backing_inode(object->dentry)->i_blocks
--- fs/cachefiles/namei.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/cachefiles/namei.c +3 -2
@@ -263,6 +263,8 @@ requeue:void cachefiles_mark_object_inactive (struct cachefiles_cache *cache,struct cachefiles_object *object) { +blkcnt_t i_blocks =d_backing_inode (object->dentry)->i_blocks; +write_lock (&cache->active_lock);rb_erase (&object->active_node, &cache->active_nodes);clear_bit (CACHEFILES_OBJECT_ACTIVE , &object->flags);
@@ -273,8 +275,7 @@ void cachefiles_mark_object_inactive(str/* This object can now be culled, so we need to let the daemon know * that there is something it can remove if it needs to. */ -atomic_long_add (d_backing_inode (object->dentry)->i_blocks, - &cache->b_released); +atomic_long_add (i_blocks, &cache->b_released);if (atomic_inc_return (&cache->f_released))cachefiles_state_changed (cache); }
Greg Kroah-Hartman
maintainerPATCH 85/186 MIPS: KVM: Fix mapped fault broken commpage handling
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <[email protected]>
commit c604cffa93478f8888bec62b23d6073dad03d43a upstream.
kvm_mips_handle_mapped_seg_tlb_fault() appears to map the guest page at virtual address 0 to PFN 0 if the guest has created its own mapping there. The intention is unclear, but it may have been an attempt to protect the zero page from being mapped to anything but the comm page in code paths you wouldn't expect from genuine commpage accesses (guest kernel mode cache instructions on that address, hitting trapping instructions when executing from that address with a coincidental TLB eviction during the KVM handling, and guest user mode accesses to that address).
Fix this to check for mappings exactly at KVM_GUEST_COMMPAGE_ADDR (it may not be at address 0 since commit 42aa12e74e91 ("MIPS: KVM: Move commpage so 0x0 is unmapped")), and set the corresponding EntryLo to be interpreted as 0 (invalid).
--- arch/mips/kvm/tlb.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-)
arch/mips/kvm/tlb.c +26 -19
@@ -373,25 +373,32 @@ int kvm_mips_handle_mapped_seg_tlb_faultunsigned long entryhi =0 , entrylo0 =0 , entrylo1 =0 ;struct kvm *kvm = vcpu->kvm;kvm_pfn_t pfn0, pfn1; +long tlb_lo[2 ];int ret; -if ((tlb->tlb_hi &VPN2_MASK ) ==0 ) { - pfn0 =0 ; - pfn1 =0 ; - }else { -if (kvm_mips_map_page (kvm,mips3_tlbpfn_to_paddr (tlb->tlb_lo0) - >>PAGE_SHIFT ) <0 ) -return -1 ; - -if (kvm_mips_map_page (kvm,mips3_tlbpfn_to_paddr (tlb->tlb_lo1) - >>PAGE_SHIFT ) <0 ) -return -1 ; - - pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr (tlb->tlb_lo0) - >>PAGE_SHIFT ]; - pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr (tlb->tlb_lo1) - >>PAGE_SHIFT ]; - } + tlb_lo[0 ] = tlb->tlb_lo0; + tlb_lo[1 ] = tlb->tlb_lo1; + +/* +* The commpage address must not be mapped to anything else if the guest +* TLB contains entries nearby, or commpage accesses will break. +*/ +if (!((tlb->tlb_hi ^KVM_GUEST_COMMPAGE_ADDR ) & +VPN2_MASK & (PAGE_MASK <<1 ))) + tlb_lo[(KVM_GUEST_COMMPAGE_ADDR >>PAGE_SHIFT ) &1 ] =0 ; + +if (kvm_mips_map_page (kvm,mips3_tlbpfn_to_paddr (tlb_lo[0 ]) + >>PAGE_SHIFT ) <0 ) +return -1 ; + +if (kvm_mips_map_page (kvm,mips3_tlbpfn_to_paddr (tlb_lo[1 ]) + >>PAGE_SHIFT ) <0 ) +return -1 ; + + pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr (tlb_lo[0 ]) + >>PAGE_SHIFT ]; + pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr (tlb_lo[1 ]) + >>PAGE_SHIFT ];if (hpa0) *hpa0 = pfn0 <<PAGE_SHIFT ;
@@ -401,9 +408,9 @@ int kvm_mips_handle_mapped_seg_tlb_fault/* Get attributes from the Guest TLB */ entrylo0 =mips3_paddr_to_tlbpfn (pfn0 <<PAGE_SHIFT ) | (0x3 <<3 ) | - (tlb->tlb_lo0 &MIPS3_PG_D ) | (tlb->tlb_lo0 &MIPS3_PG_V ); + (tlb_lo[0 ] &MIPS3_PG_D ) | (tlb_lo[0 ] &MIPS3_PG_V ); entrylo1 =mips3_paddr_to_tlbpfn (pfn1 <<PAGE_SHIFT ) | (0x3 <<3 ) | - (tlb->tlb_lo1 &MIPS3_PG_D ) | (tlb->tlb_lo1 &MIPS3_PG_V ); + (tlb_lo[1 ] &MIPS3_PG_D ) | (tlb_lo[1 ] &MIPS3_PG_V );kvm_debug ("@ %#lx tlb_lo0: 0x%08lx tlb_lo1: 0x%08lx\n" , vcpu->arch.pc, tlb->tlb_lo0, tlb->tlb_lo1);
Greg Kroah-Hartman
maintainerPATCH 86/186 MIPS: KVM: Add missing gfn range check
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <[email protected]>
commit 8985d50382359e5bf118fdbefc859d0dbf6cebc7 upstream.
kvm_mips_handle_mapped_seg_tlb_fault() calculates the guest frame number based on the guest TLB EntryLo values, however it is not range checked to ensure it lies within the guest_pmap. If the physical memory the guest refers to is out of range then dump the guest TLB and emit an internal error.
--- arch/mips/kvm/tlb.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
arch/mips/kvm/tlb.c +15 -8
@@ -373,6 +373,7 @@ int kvm_mips_handle_mapped_seg_tlb_faultunsigned long entryhi =0 , entrylo0 =0 , entrylo1 =0 ;struct kvm *kvm = vcpu->kvm;kvm_pfn_t pfn0, pfn1; +gfn_t gfn0, gfn1;long tlb_lo[2 ];int ret;
@@ -387,18 +388,24 @@ int kvm_mips_handle_mapped_seg_tlb_fault VPN2_MASK & (PAGE_MASK << 1))) tlb_lo[(KVM_GUEST_COMMPAGE_ADDR >>PAGE_SHIFT ) &1 ] =0 ; -if (kvm_mips_map_page (kvm,mips3_tlbpfn_to_paddr (tlb_lo[0 ]) - >>PAGE_SHIFT ) <0 ) + gfn0 =mips3_tlbpfn_to_paddr (tlb_lo[0 ]) >>PAGE_SHIFT ; + gfn1 =mips3_tlbpfn_to_paddr (tlb_lo[1 ]) >>PAGE_SHIFT ; +if (gfn0 >= kvm->arch.guest_pmap_npages || + gfn1 >= kvm->arch.guest_pmap_npages) { +kvm_err ("%s: Invalid gfn: [%#llx, %#llx], EHi: %#lx\n" , + __func__, gfn0, gfn1, tlb->tlb_hi); +kvm_mips_dump_guest_tlbs (vcpu);return -1 ; + } -if (kvm_mips_map_page (kvm,mips3_tlbpfn_to_paddr (tlb_lo[1 ]) - >>PAGE_SHIFT ) <0 ) +if (kvm_mips_map_page (kvm, gfn0) <0 )return -1 ; - pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr (tlb_lo[0 ]) - >>PAGE_SHIFT ]; - pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr (tlb_lo[1 ]) - >>PAGE_SHIFT ]; +if (kvm_mips_map_page (kvm, gfn1) <0 ) +return -1 ; + + pfn0 = kvm->arch.guest_pmap[gfn0]; + pfn1 = kvm->arch.guest_pmap[gfn1];if (hpa0) *hpa0 = pfn0 <<PAGE_SHIFT ;
Greg Kroah-Hartman
maintainerPATCH 87/186 MIPS: KVM: Fix gfn range check in kseg0 tlb faults
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <[email protected]>
commit 0741f52d1b980dbeb290afe67d88fc2928edd8ab upstream.
Two consecutive gfns are loaded into host TLB, so ensure the range check isn't off by one if guest_pmap_npages is odd.
--- arch/mips/kvm/tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/kvm/tlb.c +1 -1
@@ -284,7 +284,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsi } gfn = (KVM_GUEST_CPHYSADDR (badvaddr) >>PAGE_SHIFT ); -if (gfn >= kvm->arch.guest_pmap_npages) { +if ((gfn |1 ) >= kvm->arch.guest_pmap_npages) {kvm_err ("%s: Invalid gfn: %#llx, BadVaddr: %#lx\n" , __func__, gfn, badvaddr);kvm_mips_dump_host_tlbs ();
Greg Kroah-Hartman
maintainerPATCH 88/186 MIPS: KVM: Propagate kseg0/mapped tlb fault errors
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <[email protected]>
commit 9b731bcfdec4c159ad2e4312e25d69221709b96a upstream.
Propagate errors from kvm_mips_handle_kseg0_tlb_fault() and kvm_mips_handle_mapped_seg_tlb_fault(), usually triggering an internal error since they normally indicate the guest accessed bad physical memory or the commpage in an unexpected way.
--- arch/mips/kvm/emulate.c | 40 ++++++++++++++++++++++++++++------------ arch/mips/kvm/tlb.c | 14 ++++++++++---- 2 files changed, 38 insertions(+), 16 deletions(-)
arch/mips/kvm/emulate.c +28 -12
@@ -1615,8 +1615,14 @@ enum emulation_result kvm_mips_emulate_cpreempt_disable ();if (KVM_GUEST_KSEGX (va) ==KVM_GUEST_KSEG0 ) { -if (kvm_mips_host_tlb_lookup (vcpu, va) <0 ) -kvm_mips_handle_kseg0_tlb_fault (va, vcpu); +if (kvm_mips_host_tlb_lookup (vcpu, va) <0 && +kvm_mips_handle_kseg0_tlb_fault (va, vcpu)) { +kvm_err ("%s: handling mapped kseg0 tlb fault for %lx, vcpu: %p, ASID: %#lx\n" , + __func__, va, vcpu,read_c0_entryhi ()); + er =EMULATE_FAIL ; +preempt_enable (); + goto done; + } }else if ((KVM_GUEST_KSEGX (va) <KVM_GUEST_KSEG0 ) ||KVM_GUEST_KSEGX (va) ==KVM_GUEST_KSEG23 ) {int index;
@@ -1654,14 +1660,19 @@ enum emulation_result kvm_mips_emulate_c run, vcpu);preempt_enable (); goto dont_update_pc; - }else { -/* -* We fault an entry from the guest tlb to the -* shadow host TLB -*/ -kvm_mips_handle_mapped_seg_tlb_fault (vcpu, tlb, -NULL , -NULL ); + } +/* +* We fault an entry from the guest tlb to the +* shadow host TLB +*/ +if (kvm_mips_handle_mapped_seg_tlb_fault (vcpu, tlb, +NULL ,NULL )) { +kvm_err ("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n" , + __func__, va, index, vcpu, +read_c0_entryhi ()); + er =EMULATE_FAIL ; +preempt_enable (); + goto done; } } }else {
@@ -2625,8 +2636,13 @@ enum emulation_result kvm_mips_handle_tl* OK we have a Guest TLB entry, now inject it into the * shadow host TLB */ -kvm_mips_handle_mapped_seg_tlb_fault (vcpu, tlb,NULL , -NULL ); +if (kvm_mips_handle_mapped_seg_tlb_fault (vcpu, tlb, +NULL ,NULL )) { +kvm_err ("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n" , + __func__, va, index, vcpu, +read_c0_entryhi ()); + er =EMULATE_FAIL ; + } } }
arch/mips/kvm/tlb.c +10 -4
@@ -790,10 +790,16 @@ uint32_t kvm_get_inst(uint32_t *opc, strlocal_irq_restore (flags);return KVM_INVALID_INST ; } -kvm_mips_handle_mapped_seg_tlb_fault (vcpu, - &vcpu->arch. - guest_tlb[index], -NULL ,NULL ); +if (kvm_mips_handle_mapped_seg_tlb_fault (vcpu, + &vcpu->arch.guest_tlb[index], +NULL ,NULL )) { +kvm_err ("%s: handling mapped seg tlb fault failed for %p, index: %u, vcpu: %p, ASID: %#lx\n" , + __func__, opc, index, vcpu, +read_c0_entryhi ()); +kvm_mips_dump_guest_tlbs (vcpu); +local_irq_restore (flags); +return KVM_INVALID_INST ; + } inst = *(opc); }local_irq_restore (flags);
Greg Kroah-Hartman
maintainerPATCH 89/186 powerpc/tm: Fix stack pointer corruption in __tm_recheckpoint()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Neuling <[email protected]>
commit 6bcb80143e792becfd2b9cc6a339ce523e4e2219 upstream.
At the start of __tm_recheckpoint() we save the kernel stack pointer (r1) in SPRG SCRATCH0 (SPRG2) so that we can restore it after the trecheckpoint.
Unfortunately, the same SPRG is used in the SLB miss handler. If an SLB miss is taken between the save and restore of r1 to the SPRG, the SPRG is changed and hence r1 is also corrupted. We can end up with the following crash when we start using r1 again after the restore from the SPRG:
Oops: Bad kernel stack pointer, sig: 6 [#1] SMP NR_CPUS=2048 NUMA pSeries CPU: 658 PID: 143777 Comm: htm_demo Tainted: G EL X 4.4.13-0-default #1 task: c0000b56993a7810 ti: c00000000cfec000 task.ti: c0000b56993bc000 NIP: c00000000004f188 LR: 00000000100040b8 CTR: 0000000010002570 REGS: c00000000cfefd40 TRAP: 0300 Tainted: G EL X (4.4.13-0-default) MSR: 8000000300001033 <SF,ME,IR,DR,RI,LE> CR: 02000424 XER: 20000000 CFAR: c000000000008468 DAR: 00003ffd84e66880 DSISR: 40000000 SOFTE: 0 PACATMSCRATCH: 00003ffbc865e680 GPR00: fffffffcfabc4268 00003ffd84e667a0 00000000100d8c38 000000030544bb80 GPR04: 0000000000000002 00000000100cf200 0000000000000449 00000000100cf100 GPR08: 000000000000c350 0000000000002569 0000000000002569 00000000100d6c30 GPR12: 00000000100d6c28 c00000000e6a6b00 00003ffd84660000 0000000000000000 GPR16: 0000000000000003 0000000000000449 0000000010002570 0000010009684f20 GPR20: 0000000000800000 00003ffd84e5f110 00003ffd84e5f7a0 00000000100d0f40 GPR24: 0000000000000000 0000000000000000 0000000000000000 00003ffff0673f50 GPR28: 00003ffd84e5e960 00000000003d0f00 00003ffd84e667a0 00003ffd84e5e680 NIP [c00000000004f188] restore_gprs+0x110/0x17c LR [00000000100040b8] 0x100040b8 Call Trace: Instruction dump: f8a1fff0 e8e700a8 38a00000 7ca10164 e8a1fff8 e821fff0 7c0007dd 7c421378 7db142a6 7c3242a6 38800002 7c810164 <e9c100e0> e9e100e8 ea0100f0 ea2100f8
We hit this on large memory machines (> 2TB) but it can also be hit on smaller machines when 1TB segments are disabled.
To hit this, you also need to be virtualised to ensure SLBs are periodically removed by the hypervisor.
This patches moves the saving of r1 to the SPRG to the region where we are guaranteed not to take any further SLB misses.
--- arch/powerpc/kernel/tm.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/powerpc/kernel/tm.S +1 -2
@@ -338,8 +338,6 @@ _GLOBAL(__tm_recheckpoint) */ subi r7, r7, STACK_FRAME_OVERHEAD - SET_SCRATCH0(r1) - mfmsr r6 /* R4 = original MSR to indicate whether thread used FP/Vector etc. */
@@ -468,6 +466,7 @@ restore_gprs: * until we turn MSR RI back on. */ + SET_SCRATCH0(r1) ld r5, -8(r1) ld r1, -16(r1)
Greg Kroah-Hartman
maintainerPATCH 90/186 Btrfs: fix delalloc accounting after copy_from_user faults
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <[email protected]>
commit 8b8b08cbfb9021af4b54b4175fc4c51d655aac8c upstream.
Commit 56244ef151c3cd11 was almost but not quite enough to fix the reservation math after btrfs_copy_from_user returned partial copies.
Some users are still seeing warnings in btrfs_destroy_inode, and with a long enough test run I'm able to trigger them as well.
This patch fixes the accounting math again, bringing it much closer to the way it was before the sectorsize conversion Chandan did. The problem is accounting for the offset into the page/sector when we do a partial copy. This one just uses the dirty_sectors variable which should already be updated properly.
--- fs/btrfs/file.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
fs/btrfs/file.c +5 -7
@@ -1629,13 +1629,11 @@ again:* managed to copy. */ if (num_sectors > dirty_sectors) { -/* -* we round down because we don't want to count -* any partial blocks actually sent through the -* IO machines -*/ - release_bytes =round_down (release_bytes - copied, - root->sectorsize); + +/* release everything except the sectors we dirtied */ + release_bytes -= dirty_sectors << + root->fs_info->sb->s_blocksize_bits; +if (copied >0 ) {spin_lock (&BTRFS_I (inode)->lock);BTRFS_I (inode)->outstanding_extents++;
Greg Kroah-Hartman
maintainerPATCH 91/186 nfs: dont create zero-length requests
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Coddington <[email protected]>
commit 149a4fddd0a72d526abbeac0c8deaab03559836a upstream.
NFS doesn't expect requests with wb_bytes set to zero and may make unexpected decisions about how to handle that request at the page IO layer. Skip request creation if we won't have any wb_bytes in the request.
--- fs/nfs/write.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/nfs/write.c +4 -1
@@ -1289,6 +1289,9 @@ int nfs_updatepage(struct file *file, stdprintk ("NFS: nfs_updatepage(%pD2 %d@%lld)\n" , file, count, (long long )(page_file_offset (page) + offset)); +if (!count) + goto out; +if (nfs_can_extend_write (file, page, inode)) { count =max (count + offset,nfs_page_length (page)); offset =0 ;
@@ -1299,7 +1302,7 @@ int nfs_updatepage(struct file *file, stnfs_set_pageerror (page); else__set_page_dirty_nobuffers (page ); - +out:dprintk ("NFS: nfs_updatepage returns %d (isize %lld)\n" , status, (long long )i_size_read (inode));return status;
Greg Kroah-Hartman
maintainerPATCH 92/186 nfsd: Fix race between FREE_STATEID and LOCK
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
commit 42691398be08bd1fe99326911a0aa31f2c041d53 upstream.
When running LTP's nfslock01 test, the Linux client can send a LOCK and a FREE_STATEID request at the same time. The outcome is:
Frame 324 R OPEN stateid [2,O]
Frame 115004 C LOCK lockowner_is_new stateid [2,O] offset 672000 len 64 Frame 115008 R LOCK stateid [1,L]
Frame 115012 C WRITE stateid [0,L] offset 672000 len 64 Frame 115016 R WRITE NFS4_OK
Frame 115019 C LOCKU stateid [1,L] offset 672000 len 64 Frame 115022 R LOCKU NFS4_OK
Frame 115025 C FREE_STATEID stateid [2,L]
Frame 115026 C LOCK lockowner_is_new stateid [2,O] offset 672128 len 64 Frame 115029 R FREE_STATEID NFS4_OK
Frame 115030 R LOCK stateid [3,L]
Frame 115034 C WRITE stateid [0,L] offset 672128 len 64 Frame 115038 R WRITE NFS4ERR_BAD_STATEID
In other words, the server returns stateid L in a successful LOCK reply, but it has already released it. Subsequent uses of stateid L fail.
To address this, protect the generation check in nfsd4_free_stateid with the st_mutex. This should guarantee that only one of two outcomes occurs: either LOCK returns a fresh valid stateid, or FREE_STATEID returns NFS4ERR_LOCKS_HELD.
--- fs/nfsd/nfs4state.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-)
fs/nfsd/nfs4state.c +28 -12
@@ -4906,6 +4906,32 @@ nfsd4_test_stateid(struct svc_rqst *rqstreturn nfs_ok; } +static __be32 +nfsd4_free_lock_stateid (stateid_t *stateid,struct nfs4_stid *s) +{ +struct nfs4_ol_stateid *stp =openlockstateid (s); +__be32 ret; + +mutex_lock (&stp->st_mutex); + + ret =check_stateid_generation (stateid, &s->sc_stateid,1 ); +if (ret) + goto out; + + ret = nfserr_locks_held; +if (check_for_locks (stp->st_stid.sc_file, +lockowner (stp->st_stateowner))) + goto out; + +release_lock_stateid (stp); + ret = nfs_ok; + +out: +mutex_unlock (&stp->st_mutex); +nfs4_put_stid (s); +return ret; +} +__be32 nfsd4_free_stateid (struct svc_rqst *rqstp,struct nfsd4_compound_state *cstate,struct nfsd4_free_stateid *free_stateid)
@@ -4913,7 +4939,6 @@ nfsd4_free_stateid(struct svc_rqst *rqststateid_t *stateid = &free_stateid->fr_stateid;struct nfs4_stid *s;struct nfs4_delegation *dp; -struct nfs4_ol_stateid *stp;struct nfs4_client *cl = cstate->session->se_client;__be32 ret = nfserr_bad_stateid;
@@ -4932,18 +4957,9 @@ nfsd4_free_stateid(struct svc_rqst *rqst ret = nfserr_locks_held;break ;case NFS4_LOCK_STID : - ret =check_stateid_generation (stateid, &s->sc_stateid,1 ); -if (ret) -break ; - stp =openlockstateid (s); - ret = nfserr_locks_held; -if (check_for_locks (stp->st_stid.sc_file, -lockowner (stp->st_stateowner))) -break ; -WARN_ON (!unhash_lock_stateid (stp)); +atomic_inc (&s->sc_count);spin_unlock (&cl->cl_lock); -nfs4_put_stid (s); - ret = nfs_ok; + ret =nfsd4_free_lock_stateid (stateid, s); goto out;case NFS4_REVOKED_DELEG_STID : dp =delegstateid (s);
Greg Kroah-Hartman
maintainerPATCH 93/186 nfsd: dont return an unhashed lock stateid after taking mutex
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
commit dd257933fa4b9fea66a1195f8a15111029810abc upstream.
nfsd4_lock will take the st_mutex before working with the stateid it gets, but between the time when we drop the cl_lock and take the mutex, the stateid could become unhashed (a'la FREE_STATEID). If that happens the lock stateid returned to the client will be forgotten.
Fix this by first moving the st_mutex acquisition into lookup_or_create_lock_state. Then, have it check to see if the lock stateid is still hashed after taking the mutex. If it's not, then put the stateid and try the find/create again.
--- fs/nfsd/nfs4state.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
fs/nfsd/nfs4state.c +20 -5
@@ -5526,7 +5526,7 @@ static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, - struct nfs4_ol_stateid **lst, bool *new) + struct nfs4_ol_stateid **plst, bool *new) { __be32 status;struct nfs4_file *fi = ost->st_stid.sc_file;
@@ -5534,7 +5534,9 @@ lookup_or_create_lock_state(struct nfsd4struct nfs4_client *cl = oo->oo_owner.so_client;struct inode *inode =d_inode (cstate->current_fh.fh_dentry);struct nfs4_lockowner *lo; +struct nfs4_ol_stateid *lst;unsigned int strhashval; +bool hashed; lo =find_lockowner_str (cl, &lock->lk_new_owner);if (!lo) {
@@ -5550,12 +5552,27 @@ lookup_or_create_lock_state(struct nfsd4 goto out; } - *lst =find_or_create_lock_stateid (lo, fi, inode, ost, new); -if (*lst ==NULL ) { +retry: + lst =find_or_create_lock_stateid (lo, fi, inode, ost, new); +if (lst ==NULL ) { status = nfserr_jukebox; goto out; } + +mutex_lock (&lst->st_mutex); + +/* See if it's still hashed to avoid race with FREE_STATEID */ +spin_lock (&cl->cl_lock); + hashed = !list_empty (&lst->st_perfile); +spin_unlock (&cl->cl_lock); + +if (!hashed) { +mutex_unlock (&lst->st_mutex); +nfs4_put_stid (&lst->st_stid); + goto retry; + } status = nfs_ok; + *plst = lst; out:nfs4_put_stateowner (&lo->lo_owner);return status;
@@ -5622,8 +5639,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struc goto out; status =lookup_or_create_lock_state (cstate, open_stp, lock, &lock_stp, &new); -if (status == nfs_ok) -mutex_lock (&lock_stp->st_mutex); }else { status = nfs4_preprocess_seqid_op(cstate, lock->lk_old_lock_seqid,
Greg Kroah-Hartman
maintainerPATCH 94/186 pNFS: Separate handling of NFS4ERR_LAYOUTTRYLATER and RECALLCONFLICT
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit e85d7ee42003314652ab3ae2c60e3b8cd793b65f upstream.
They are not the same error, and need to be handled differently.
--- fs/nfs/nfs4proc.c | 23 ++++++++++++++--------- fs/nfs/pnfs.c | 1 + 2 files changed, 15 insertions(+), 9 deletions(-)
fs/nfs/nfs4proc.c +14 -9
@@ -427,6 +427,7 @@ static int nfs4_do_handle_exception(strucase -NFS4ERR_DELAY :nfs_inc_server_stats (server,NFSIOS_DELAY );case -NFS4ERR_GRACE : +case -NFS4ERR_LAYOUTTRYLATER :case -NFS4ERR_RECALLCONFLICT : exception->delay =1 ;return 0 ;
@@ -7869,11 +7870,12 @@ nfs4_layoutget_handle_exception(struct rstruct inode *inode = lgp->args.inode;struct nfs_server *server =NFS_SERVER (inode);struct pnfs_layout_hdr *lo; -int status = task->tk_status; +int nfs4err = task->tk_status; +int err, status =0 ;dprintk ("--> %s tk_status => %d\n" , __func__, -task->tk_status); -switch (status) { +switch (nfs4err) {case 0 : goto out;
@@ -7905,12 +7907,11 @@ nfs4_layoutget_handle_exception(struct r status = -EOVERFLOW ; goto out; } -/* Fallthrough */ + status = -EBUSY ; +break ;case -NFS4ERR_RECALLCONFLICT : -nfs4_handle_exception (server, -NFS4ERR_RECALLCONFLICT , - exception); status = -ERECALLCONFLICT ; - goto out; +break ;case -NFS4ERR_EXPIRED :case -NFS4ERR_BAD_STATEID : exception->timeout =0 ;
@@ -7941,9 +7942,13 @@ nfs4_layoutget_handle_exception(struct rspin_unlock (&inode->i_lock); } - status =nfs4_handle_exception (server, status, exception); -if (exception->retry) - status = -EAGAIN ; + err =nfs4_handle_exception (server, nfs4err, exception); +if (!status) { +if (exception->retry) + status = -EAGAIN ; +else + status = err; + } out:dprintk ("<-- %s\n" , __func__);return status;
fs/nfs/pnfs.c +1 -0
@@ -1647,6 +1647,7 @@ lookup_again: PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET);if (IS_ERR (lseg)) {switch (PTR_ERR (lseg)) { +case -EBUSY :case -ERECALLCONFLICT :if (time_after (jiffies, giveup)) lseg =NULL ;
Greg Kroah-Hartman
maintainerPATCH 95/186 pNFS: Fix post-layoutget error handling in pnfs_update_layout()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit 56b38a1f7c781519eef09c1668a3c97ea911f86b upstream.
The non-retry error path is currently broken and ends up releasing the reference to the layout twice. It also can end up clearing the NFS_LAYOUT_FIRST_LAYOUTGET flag twice, causing a race.
In addition, the retry path will fail to decrement the plh_outstanding counter.
--- fs/nfs/pnfs.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
fs/nfs/pnfs.c +11 -10
@@ -1645,6 +1645,7 @@ lookup_again: lseg =send_layoutget (lo, ctx, &stateid, &arg, &timeout, gfp_flags);trace_pnfs_update_layout (ino, pos, count, iomode, lo, lseg,PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET ); +atomic_dec (&lo->plh_outstanding);if (IS_ERR (lseg)) {switch (PTR_ERR (lseg)) {case -EBUSY :
@@ -1653,26 +1654,26 @@ lookup_again: lseg =NULL ;/* Fallthrough */ case -EAGAIN : -pnfs_put_layout_hdr (lo); -if (first) -pnfs_clear_first_layoutget (lo); -if (lseg) { -trace_pnfs_update_layout (ino, pos, count, - iomode, lo, lseg,PNFS_UPDATE_LAYOUT_RETRY ); - goto lookup_again; - } -/* Fallthrough */ +break ;default :if (!nfs_error_is_fatal (PTR_ERR (lseg))) {pnfs_layout_clear_fail_bit (lo,pnfs_iomode_to_fail_bit (iomode)); lseg =NULL ; } + goto out_put_layout_hdr; + } +if (lseg) { +if (first) +pnfs_clear_first_layoutget (lo); +trace_pnfs_update_layout (ino, pos, count, + iomode, lo, lseg,PNFS_UPDATE_LAYOUT_RETRY ); +pnfs_put_layout_hdr (lo); + goto lookup_again; } }else {pnfs_layout_clear_fail_bit (lo,pnfs_iomode_to_fail_bit (iomode)); } -atomic_dec (&lo->plh_outstanding); out_put_layout_hdr:if (first)pnfs_clear_first_layoutget (lo);
Greg Kroah-Hartman
maintainerPATCH 96/186 pNFS: Handle NFS4ERR_RECALLCONFLICT correctly in LAYOUTGET
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit 66b53f325876703b7ab815c482cd104609f8772c upstream.
Instead of giving up altogether and falling back to doing I/O through the MDS, which may make the situation worse, wait for 2 lease periods for the callback to resolve itself, and then try destroying the existing layout.
Only if this was an attempt at getting a first layout, do we give up altogether, as the server is clearly crazy.
--- fs/nfs/pnfs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
fs/nfs/pnfs.c +11 -2
@@ -1505,7 +1505,7 @@ pnfs_update_layout(struct inode *ino,struct pnfs_layout_segment *lseg =NULL ;nfs4_stateid stateid;long timeout =0 ; -unsigned long giveup = jiffies +rpc_get_timeout (server->client); +unsigned long giveup = jiffies + (clp->cl_lease_time <<1 );bool first;if (!pnfs_enabled_sb (NFS_SERVER (ino))) {
@@ -1649,9 +1649,18 @@ lookup_again:if (IS_ERR (lseg)) {switch (PTR_ERR (lseg)) {case -EBUSY : -case -ERECALLCONFLICT :if (time_after (jiffies, giveup)) lseg =NULL ; +break ; +case -ERECALLCONFLICT : +/* Huh? We hold no layouts, how is there a recall? */ +if (first) { + lseg =NULL ; +break ; + } +/* Destroy the existing layout and start over */ +if (time_after (jiffies, giveup)) +pnfs_destroy_layout (NFS_I (ino));/* Fallthrough */ case -EAGAIN :break ;
Greg Kroah-Hartman
maintainerPATCH 97/186 pNFS: Fix LAYOUTGET handling of NFS4ERR_BAD_STATEID and NFS4ERR_EXPIRED
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit f7db0b283868411dc6bc8a223fd032b211d2d91f upstream.
We want to recover the open stateid if there is no layout stateid and/or the stateid argument matches an open stateid. Otherwise throw out the existing layout and recover from scratch, as the layout stateid is bad.
--- fs/nfs/nfs4proc.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-)
fs/nfs/nfs4proc.c +14 -18
@@ -7872,6 +7872,7 @@ nfs4_layoutget_handle_exception(struct rstruct pnfs_layout_hdr *lo;int nfs4err = task->tk_status;int err, status =0 ; +LIST_HEAD (head);dprintk ("--> %s tk_status => %d\n" , __func__, -task->tk_status);
@@ -7916,30 +7917,25 @@ nfs4_layoutget_handle_exception(struct rcase -NFS4ERR_BAD_STATEID : exception->timeout =0 ;spin_lock (&inode->i_lock); -if (nfs4_stateid_match (&lgp->args.stateid, + lo =NFS_I (inode)->layout; +/* If the open stateid was bad, then recover it. */ +if (!lo ||test_bit (NFS_LAYOUT_INVALID_STID , &lo->plh_flags) || +nfs4_stateid_match_other (&lgp->args.stateid, &lgp->args.ctx->state->stateid)) {spin_unlock (&inode->i_lock); -/* If the open stateid was bad, then recover it. */ exception->state = lgp->args.ctx->state;break ; } - lo =NFS_I (inode)->layout; -if (lo && !test_bit (NFS_LAYOUT_INVALID_STID , &lo->plh_flags) && -nfs4_stateid_match_other (&lgp->args.stateid, &lo->plh_stateid)) { -LIST_HEAD (head); -/* -* Mark the bad layout state as invalid, then retry -* with the current stateid. -*/ -set_bit (NFS_LAYOUT_INVALID_STID , &lo->plh_flags); -pnfs_mark_matching_lsegs_invalid (lo, &head,NULL ,0 ); -spin_unlock (&inode->i_lock); -pnfs_free_lseg_list (&head); - status = -EAGAIN ; - goto out; - }else -spin_unlock (&inode->i_lock); +/* +* Mark the bad layout state as invalid, then retry +*/ +set_bit (NFS_LAYOUT_INVALID_STID , &lo->plh_flags); +pnfs_mark_matching_lsegs_invalid (lo, &head,NULL ,0 ); +spin_unlock (&inode->i_lock); +pnfs_free_lseg_list (&head); + status = -EAGAIN ; + goto out; } err =nfs4_handle_exception (server, nfs4err, exception);
Greg Kroah-Hartman
maintainerPATCH 99/186 iommu/exynos: Suppress unbinding to prevent system failure
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <[email protected]>
commit b54b874fbaf5e024723e50dfb035a9916d6752b4 upstream.
Removal of IOMMU driver cannot be done reliably, so Exynos IOMMU driver doesn't support this operation. It is essential for system operation, so it makes sense to prevent unbinding by disabling bind/unbind sysfs feature for SYSMMU controller driver to avoid kernel ops or trashing memory caused by such operation.
--- drivers/iommu/exynos-iommu.c | 1 + 1 file changed, 1 insertion(+)
drivers/iommu/exynos-iommu.c +1 -0
@@ -709,6 +709,7 @@ static struct platform_driver exynos_sys .name = "exynos-sysmmu", .of_match_table = sysmmu_of_match, .pm = &sysmmu_pm_ops, + .suppress_bind_attrs = true, } };
Greg Kroah-Hartman
maintainerPATCH 100/186 iommu/vt-d: Return error code in domain_context_mapping_one()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Yang <[email protected]>
commit 5c365d18a73d3979db37006eaacefc0008869c0f upstream.
In 'commit <55d940430ab9> ("iommu/vt-d: Get rid of domain->iommu_lock")', the error handling path is changed a little, which makes the function always return 0.
This path fixes this.
--- drivers/iommu/intel-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/intel-iommu.c +1 -1
@@ -2076,7 +2076,7 @@ out_unlock:spin_unlock (&iommu->lock);spin_unlock_irqrestore (&device_domain_lock, flags); -return 0 ; +return ret; }struct domain_context_mapping_data {
Greg Kroah-Hartman
maintainerPATCH 101/186 iommu/io-pgtable-arm: Fix iova_to_phys for block entries
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
commit 7c6d90e2bb1a98b86d73b9e8ab4d97ed5507e37c upstream.
The implementation of iova_to_phys for the long-descriptor ARM io-pgtable code always masks with the granule size when inserting the low virtual address bits into the physical address determined from the page tables. In cases where the leaf entry is found before the final level of table (i.e. due to a block mapping), this results in rounding down to the bottom page of the block mapping. Consequently, the physical address range batching in the vfio_unmap_unpin is defeated and we end up taking the long way home.
This patch fixes the problem by masking the virtual address with the appropriate mask for the level at which the leaf descriptor is located. The short-descriptor code already gets this right, so no change is needed there.
--- drivers/iommu/io-pgtable-arm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/io-pgtable-arm.c +1 -1
@@ -576,7 +576,7 @@ static phys_addr_t arm_lpae_iova_to_physreturn 0 ; found_translation: - iova &= (ARM_LPAE_GRANULE (data) -1 ); + iova &= (ARM_LPAE_BLOCK_SIZE (lvl, data) -1 );return ((phys_addr_t )iopte_to_pfn (pte,data) << data->pg_shift) | iova; }
Greg Kroah-Hartman
maintainerPATCH 102/186 iommu/amd: Handle IOMMU_DOMAIN_DMA in ops->domain_free call-back
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joerg Roedel <[email protected]>
commit cda7005ba2cbd0744fea343dd5b2aa637eba5b9e upstream.
This domain type is not yet handled in theiommu_ops->domain_free() call-back. Fix that.
--- drivers/iommu/amd_iommu.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
drivers/iommu/amd_iommu.c +18 -9
@@ -3103,9 +3103,7 @@ static struct iommu_domain *amd_iommu_dostatic void amd_iommu_domain_free (struct iommu_domain *dom) {struct protection_domain *domain; - -if (!dom) -return ; +struct dma_ops_domain *dma_dom; domain =to_pdomain (dom);
@@ -3114,13 +3112,24 @@ static void amd_iommu_domain_free(structBUG_ON (domain->dev_cnt !=0 ); -if (domain->mode !=PAGE_MODE_NONE ) -free_pagetable (domain); - -if (domain->flags &PD_IOMMUV2_MASK ) -free_gcr3_table (domain); +if (!dom) +return ; -protection_domain_free (domain); +switch (dom->type) { +case IOMMU_DOMAIN_DMA : + dma_dom = domain->priv; +dma_ops_domain_free (dma_dom); +break ; +default : +if (domain->mode !=PAGE_MODE_NONE ) +free_pagetable (domain); + +if (domain->flags &PD_IOMMUV2_MASK ) +free_gcr3_table (domain); + +protection_domain_free (domain); +break ; + } } static void amd_iommu_detach_device(struct iommu_domain *dom,
Greg Kroah-Hartman
maintainerPATCH 103/186 iommu/amd: Init unity mappings only for dma_ops domains
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joerg Roedel <[email protected]>
commit b548e786ce47017107765bbeb0f100202525ea83 upstream.
The default domain for a device might also be identity-mapped. In this case the kernel would crash when unity mappings are defined for the device. Fix that by making sure the domain is a dma_ops domain.
--- drivers/iommu/amd_iommu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/iommu/amd_iommu.c +4 -2
@@ -466,9 +466,11 @@ static void init_iommu_group(struct deviif (!domain) goto out; - dma_domain =to_pdomain (domain)->priv; +if (to_pdomain (domain)->flags ==PD_DMA_OPS_MASK ) { + dma_domain =to_pdomain (domain)->priv; +init_unity_mappings_for_device (dev, dma_domain); + } -init_unity_mappings_for_device (dev, dma_domain); out:iommu_group_put (group); }
Greg Kroah-Hartman
maintainerPATCH 104/186 iommu/amd: Update Alias-DTE in update_device_table()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joerg Roedel <[email protected]>
commit 3254de6bf74fe94c197c9f819fe62a3a3c36f073 upstream.
Not doing so might cause IO-Page-Faults when a device uses an alias request-id and the alias-dte is left in a lower page-mode which does not cover the address allocated from the iova-allocator.
--- drivers/iommu/amd_iommu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/iommu/amd_iommu.c +8 -1
@@ -2514,8 +2514,15 @@ static void update_device_table(struct p {struct iommu_dev_data *dev_data; -list_for_each_entry (dev_data, &domain->dev_list, list) +list_for_each_entry (dev_data, &domain->dev_list, list) {set_dte_entry (dev_data->devid, domain, dev_data->ats.enabled); + +if (dev_data->devid == dev_data->alias) +continue ; + +/* There is an alias, update device table entry for it */ +set_dte_entry (dev_data->alias, domain, dev_data->ats.enabled); + } }static void update_domain (struct protection_domain *domain)
Greg Kroah-Hartman
maintainerPATCH 105/186 audit: fix a double fetch in audit_log_single_execve_arg()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Moore <[email protected]>
commit 43761473c254b45883a64441dd0bc85a42f3645c upstream.
There is a double fetch problem in audit_log_single_execve_arg() where we first check the execve(2) argumnets for any "bad" characters which would require hex encoding and then re-fetch the arguments for logging in the audit record[1]. Of course this leaves a window of opportunity for an unsavory application to munge with the data.
This patch reworks things by only fetching the argument data once[2] into a buffer where it is scanned and logged into the audit records(s). In addition to fixing the double fetch, this patch improves on the original code in a few other ways: better handling of large arguments which require encoding, stricter record length checking, and some performance improvements (completely unverified, but we got rid of some strlen() calls, that's got to be a good thing).
As part of the development of this patch, I've also created a basic regression test for the audit-testsuite, the test can be tracked on GitHub at the following link:
* https://github.com/linux-audit/audit-testsuite/issues/25
[1] If you pay careful attention, there is actually a triple fetch problem due to a strnlen_user() call at the top of the function.
[2] This is a tiny white lie, we do make a call to strnlen_user() prior to fetching the argument data. I don't like it, but due to the way the audit record is structured we really have no choice unless we copy the entire argument at once (which would require a rather wasteful allocation). The good news is that with this patch the kernel no longer relies on this strnlen_user() value for anything beyond recording it in the log, we also update it with a trustworthy value whenever possible.
--- kernel/auditsc.c | 332 +++++++++++++++++++++++++++---------------------------- 1 file changed, 164 insertions(+), 168 deletions(-)
kernel/auditsc.c +164 -168
@@ -72,6 +72,7 @@#include <linux/compat.h> #include <linux/ctype.h> #include <linux/string.h> +#include <linux/uaccess.h> #include <uapi/linux/limits.h> #include "audit.h"
@@ -81,7 +82,8 @@#define AUDITSC_SUCCESS 1#define AUDITSC_FAILURE 2 -/* no execve audit message should be longer than this (userspace limits) */ +/* no execve audit message should be longer than this (userspace limits), +* see the note near the top of audit_log_execve_info() about this value */ #define MAX_EXECVE_AUDIT_LEN 7500/* max length to print of cmdline/proctitle value during audit */
@@ -987,184 +989,178 @@ static int audit_log_pid_context(structreturn rc; } -/* -* to_send and len_sent accounting are very loose estimates. We aren't -* really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being -* within about 500 bytes (next page boundary) -* -* why snprintf? an int is up to 12 digits long. if we just assumed when -* logging that a[%d]= was going to be 16 characters long we would be wasting -* space in every audit message. In one 7500 byte message we can log up to -* about 1000 min size arguments. That comes down to about 50% waste of space -* if we didn't do the snprintf to find out how long arg_num_len was. -*/ -static int audit_log_single_execve_arg (struct audit_context *context, -struct audit_buffer **ab, -int arg_num, -size_t *len_sent, -const char __user *p, -char *buf) -{ -char arg_num_len_buf[12 ]; -const char __user *tmp_p = p; -/* how many digits are in arg_num? 5 is the length of ' a=""' */ -size_t arg_num_len =snprintf (arg_num_len_buf,12 ,"%d" , arg_num) +5 ; -size_t len, len_left, to_send; -size_t max_execve_audit_len =MAX_EXECVE_AUDIT_LEN ; -unsigned int i, has_cntl =0 , too_long =0 ; -int ret; - -/* strnlen_user includes the null we don't want to send */ - len_left = len =strnlen_user (p,MAX_ARG_STRLEN ) -1 ; +static void audit_log_execve_info (struct audit_context *context, +struct audit_buffer **ab) +{ +long len_max; +long len_rem; +long len_full; +long len_buf; +long len_abuf; +long len_tmp; +bool require_data; +bool encode; +unsigned int iter; +unsigned int arg; +char *buf_head; +char *buf; +const char __user *p = (const char __user *)current->mm->arg_start; -/* -* We just created this mm, if we can't find the strings -* we just copied into it something is _very_ wrong. Similar -* for strings that are too long, we should not have created -* any. -*/ -if (WARN_ON_ONCE (len <0 || len >MAX_ARG_STRLEN -1 )) { -send_sig (SIGKILL , current,0 ); -return -1 ; +/* NOTE: this buffer needs to be large enough to hold all the non-arg +* data we put in the audit record for this argument (see the +* code below) ... at this point in time 96 is plenty */ +char abuf[96 ]; + +/* NOTE: we set MAX_EXECVE_AUDIT_LEN to a rather arbitrary limit, the +* current value of 7500 is not as important as the fact that it +* is less than 8k, a setting of 7500 gives us plenty of wiggle +* room if we go over a little bit in the logging below */ +WARN_ON_ONCE (MAX_EXECVE_AUDIT_LEN >7500 ); + len_max =MAX_EXECVE_AUDIT_LEN ; + +/* scratch buffer to hold the userspace args */ + buf_head =kmalloc (MAX_EXECVE_AUDIT_LEN +1 ,GFP_KERNEL ); +if (!buf_head) { +audit_panic ("out of memory for argv string" ); +return ; } + buf = buf_head; + +audit_log_format (*ab,"argc=%d" , context->execve.argc); -/* walk the whole argument looking for non-ascii chars */ + len_rem = len_max; + len_buf =0 ; + len_full =0 ; + require_data = true; + encode = false; + iter =0 ; + arg =0 ;do { -if (len_left >MAX_EXECVE_AUDIT_LEN ) - to_send =MAX_EXECVE_AUDIT_LEN ; -else - to_send = len_left; - ret =copy_from_user (buf, tmp_p, to_send); -/* -* There is no reason for this copy to be short. We just -* copied them here, and the mm hasn't been exposed to user- -* space yet. -*/ -if (ret) { -WARN_ON (1 ); -send_sig (SIGKILL , current,0 ); -return -1 ; - } - buf[to_send] ='\0' ; - has_cntl =audit_string_contains_control (buf, to_send); -if (has_cntl) { -/* -* hex messages get logged as 2 bytes, so we can only -* send half as much in each message -*/ - max_execve_audit_len =MAX_EXECVE_AUDIT_LEN /2 ; -break ; - } - len_left -= to_send; - tmp_p += to_send; - }while (len_left >0 ); - - len_left = len; - -if (len > max_execve_audit_len) - too_long =1 ; - -/* rewalk the argument actually logging the message */ -for (i =0 ; len_left >0 ; i++) { -int room_left; - -if (len_left > max_execve_audit_len) - to_send = max_execve_audit_len; -else - to_send = len_left; - -/* do we have space left to send this argument in this ab? */ - room_left =MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent; -if (has_cntl) - room_left -= (to_send *2 ); -else - room_left -= to_send; -if (room_left <0 ) { - *len_sent =0 ; -audit_log_end (*ab); - *ab =audit_log_start (context,GFP_KERNEL ,AUDIT_EXECVE ); -if (!*ab) -return 0 ; - } +/* NOTE: we don't ever want to trust this value for anything +* serious, but the audit record format insists we +* provide an argument length for really long arguments, +* e.g. > MAX_EXECVE_AUDIT_LEN, so we have no choice but +* to use strncpy_from_user() to obtain this value for +* recording in the log, although we don't use it +* anywhere here to avoid a double-fetch problem */ +if (len_full ==0 ) + len_full =strnlen_user (p,MAX_ARG_STRLEN ) -1 ; + +/* read more data from userspace */ +if (require_data) { +/* can we make more room in the buffer? */ +if (buf != buf_head) { +memmove (buf_head, buf, len_buf); + buf = buf_head; + } -/* -* first record needs to say how long the original string was -* so we can be sure nothing was lost. -*/ -if ((i ==0 ) && (too_long)) -audit_log_format (*ab," a%d_len=%zu" , arg_num, - has_cntl ?2 *len : len); - -/* -* normally arguments are small enough to fit and we already -* filled buf above when we checked for control characters -* so don't bother with another copy_from_user -*/ -if (len >= max_execve_audit_len) - ret =copy_from_user (buf, p, to_send); -else - ret =0 ; -if (ret) { -WARN_ON (1 ); -send_sig (SIGKILL , current,0 ); -return -1 ; - } - buf[to_send] ='\0' ; +/* fetch as much as we can of the argument */ + len_tmp =strncpy_from_user (&buf_head[len_buf], p, + len_max - len_buf); +if (len_tmp == -EFAULT ) { +/* unable to copy from userspace */ +send_sig (SIGKILL , current,0 ); + goto out; + }else if (len_tmp == (len_max - len_buf)) { +/* buffer is not large enough */ + require_data = true; +/* NOTE: if we are going to span multiple +* buffers force the encoding so we stand +* a chance at a sane len_full value and +* consistent record encoding */ + encode = true; + len_full = len_full *2 ; + p += len_tmp; + }else { + require_data = false; +if (!encode) + encode =audit_string_contains_control ( + buf, len_tmp); +/* try to use a trusted value for len_full */ +if (len_full < len_max) + len_full = (encode ? + len_tmp *2 : len_tmp); + p += len_tmp +1 ; + } + len_buf += len_tmp; + buf_head[len_buf] ='\0' ; -/* actually log it */ -audit_log_format (*ab," a%d" , arg_num); -if (too_long) -audit_log_format (*ab,"[%d]" , i); -audit_log_format (*ab,"=" ); -if (has_cntl) -audit_log_n_hex (*ab, buf, to_send); -else -audit_log_string (*ab, buf); - - p += to_send; - len_left -= to_send; - *len_sent += arg_num_len; -if (has_cntl) - *len_sent += to_send *2 ; -else - *len_sent += to_send; - } -/* include the null we didn't log */ -return len +1 ; -} +/* length of the buffer in the audit record? */ + len_abuf = (encode ? len_buf *2 : len_buf +2 ); + } -static void audit_log_execve_info (struct audit_context *context, -struct audit_buffer **ab) -{ -int i, len; -size_t len_sent =0 ; -const char __user *p; -char *buf; +/* write as much as we can to the audit log */ +if (len_buf >0 ) { +/* NOTE: some magic numbers here - basically if we +* can't fit a reasonable amount of data into the +* existing audit buffer, flush it and start with +* a new buffer */ +if ((sizeof (abuf) +8 ) > len_rem) { + len_rem = len_max; +audit_log_end (*ab); + *ab =audit_log_start (context, +GFP_KERNEL ,AUDIT_EXECVE ); +if (!*ab) + goto out; + } - p = (const char __user *)current->mm->arg_start; +/* create the non-arg portion of the arg record */ + len_tmp =0 ; +if (require_data || (iter >0 ) || + ((len_abuf +sizeof (abuf)) > len_rem)) { +if (iter ==0 ) { + len_tmp +=snprintf (&abuf[len_tmp], +sizeof (abuf) - len_tmp, +" a%d_len=%lu" , + arg, len_full); + } + len_tmp +=snprintf (&abuf[len_tmp], +sizeof (abuf) - len_tmp, +" a%d[%d]=" , arg, iter++); + }else + len_tmp +=snprintf (&abuf[len_tmp], +sizeof (abuf) - len_tmp, +" a%d=" , arg); +WARN_ON (len_tmp >=sizeof (abuf)); + abuf[sizeof (abuf) -1 ] ='\0' ; + +/* log the arg in the audit record */ +audit_log_format (*ab,"%s" , abuf); + len_rem -= len_tmp; + len_tmp = len_buf; +if (encode) { +if (len_abuf > len_rem) + len_tmp = len_rem /2 ;/* encoding */ +audit_log_n_hex (*ab, buf, len_tmp); + len_rem -= len_tmp *2 ; + len_abuf -= len_tmp *2 ; + }else { +if (len_abuf > len_rem) + len_tmp = len_rem -2 ;/* quotes */ +audit_log_n_string (*ab, buf, len_tmp); + len_rem -= len_tmp +2 ; +/* don't subtract the "2" because we still need +* to add quotes to the remaining string */ + len_abuf -= len_tmp; + } + len_buf -= len_tmp; + buf += len_tmp; + } -audit_log_format (*ab,"argc=%d" , context->execve.argc); +/* ready to move to the next argument? */ +if ((len_buf ==0 ) && !require_data) { + arg++; + iter =0 ; + len_full =0 ; + require_data = true; + encode = false; + } + }while (arg < context->execve.argc); -/* -* we need some kernel buffer to hold the userspace args. Just -* allocate one big one rather than allocating one of the right size -* for every single argument inside audit_log_single_execve_arg() -* should be <8k allocation so should be pretty safe. -*/ - buf =kmalloc (MAX_EXECVE_AUDIT_LEN +1 ,GFP_KERNEL ); -if (!buf) { -audit_panic ("out of memory for argv string" ); -return ; - } +/* NOTE: the caller handles the final audit_log_end() call */ -for (i =0 ; i < context->execve.argc; i++) { - len =audit_log_single_execve_arg (context, ab, i, - &len_sent, p, buf); -if (len <=0 ) -break ; - p += len; - } -kfree (buf); +out: +kfree (buf_head); }static void show_special (struct audit_context *context,int *call_panic)
Greg Kroah-Hartman
maintainerPATCH 106/186 ARM: 8561/3: dma-mapping: Dont use outer_flush_range when the L2C is coherent
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory CLEMENT <[email protected]>
commit f12708965069410691e47d1d216ec7ad1516bfd2 upstream.
When a L2 cache controller is used in a system that provides hardware coherency, the entire outer cache operations are useless, and can be skipped. Moreover, on some systems, it is harmful as it causes deadlocks between the Marvell coherency mechanism, the Marvell PCIe controller and the Cortex-A9.
In the current kernel implementation, the outer cache flush range operation is triggered by the dma_alloc function.
This operation can be take place during runtime and in some circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x SoCs.
This patch extends the __dma_clear_buffer() function to receive a boolean argument related to the coherency of the system. The same things is done for the calling functions.
--- arch/arm/mm/dma-mapping.c | 62 +++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 20 deletions(-)
arch/arm/mm/dma-mapping.c +42 -20
@@ -49,6 +49,7 @@ struct arm_dma_alloc_args {pgprot_t prot;const void *caller;bool want_vaddr; +int coherent_flag; };struct arm_dma_free_args {
@@ -59,6 +60,9 @@ struct arm_dma_free_args {bool want_vaddr; }; +#define NORMAL 0 +#define COHERENT 1 +struct arm_dma_allocator {void *(*alloc)(struct arm_dma_alloc_args *args,struct page **ret_page);
@@ -272,7 +276,7 @@ static u64 get_coherent_dma_mask(structreturn mask; } -static void __dma_clear_buffer (struct page *page,size_t size) +static void __dma_clear_buffer (struct page *page,size_t size,int coherent_flag) {/* * Ensure that the allocated pages are zeroed, and that any data
@@ -284,17 +288,21 @@ static void __dma_clear_buffer(struct pawhile (size >0 ) {void *ptr =kmap_atomic (page);memset (ptr,0 ,PAGE_SIZE ); -dmac_flush_range (ptr, ptr +PAGE_SIZE ); +if (coherent_flag !=COHERENT ) +dmac_flush_range (ptr, ptr +PAGE_SIZE );kunmap_atomic (ptr); page++; size -=PAGE_SIZE ; } -outer_flush_range (base, end); +if (coherent_flag !=COHERENT ) +outer_flush_range (base, end); }else {void *ptr =page_address (page);memset (ptr,0 , size); -dmac_flush_range (ptr, ptr + size); -outer_flush_range (__pa (ptr),__pa (ptr) + size); +if (coherent_flag !=COHERENT ) { +dmac_flush_range (ptr, ptr + size); +outer_flush_range (__pa (ptr),__pa (ptr) + size); + } } }
@@ -302,7 +310,8 @@ static void __dma_clear_buffer(struct pa* Allocate a DMA buffer for 'dev' of size 'size' using the * specified gfp mask. Note that 'size' must be page aligned. */ -static struct page *__dma_alloc_buffer (struct device *dev,size_t size,gfp_t gfp) +static struct page *__dma_alloc_buffer (struct device *dev,size_t size, +gfp_t gfp,int coherent_flag) {unsigned long order =get_order (size);struct page *page, *p, *e;
@@ -318,7 +327,7 @@ static struct page *__dma_alloc_buffer(sfor (p = page + (size >>PAGE_SHIFT ), e = page + (1 << order); p < e; p++)__free_page (p); -__dma_clear_buffer (page, size); +__dma_clear_buffer (page, size, coherent_flag);return page; }
@@ -340,7 +349,8 @@ static void __dma_free_buffer(struct pagstatic void *__alloc_from_contiguous (struct device *dev,size_t size,pgprot_t prot,struct page **ret_page, -const void *caller,bool want_vaddr); +const void *caller,bool want_vaddr, +int coherent_flag); static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, pgprot_t prot, struct page **ret_page,
@@ -405,10 +415,13 @@ static int __init atomic_pool_init(void) atomic_pool =gen_pool_create (PAGE_SHIFT ,-1 );if (!atomic_pool) goto out; - +/* +* The atomic pool is only used for non-coherent allocations +* so we must pass NORMAL for coherent_flag. +*/ if (dev_get_cma_area (NULL )) ptr =__alloc_from_contiguous (NULL , atomic_pool_size, prot, - &page, atomic_pool_init, true); + &page, atomic_pool_init, true,NORMAL );else ptr =__alloc_remap_buffer (NULL , atomic_pool_size, gfp, prot, &page, atomic_pool_init, true);
@@ -522,7 +535,11 @@ static void *__alloc_remap_buffer(struct {struct page *page;void *ptr =NULL ; - page =__dma_alloc_buffer (dev, size, gfp); +/* +* __alloc_remap_buffer is only called when the device is +* non-coherent +*/ + page =__dma_alloc_buffer (dev, size, gfp,NORMAL );if (!page)return NULL ;if (!want_vaddr)
@@ -577,7 +594,8 @@ static int __free_from_pool(void *start,static void *__alloc_from_contiguous (struct device *dev,size_t size,pgprot_t prot,struct page **ret_page, -const void *caller,bool want_vaddr) +const void *caller,bool want_vaddr, +int coherent_flag) {unsigned long order =get_order (size);size_t count = size >>PAGE_SHIFT ;
@@ -588,7 +606,7 @@ static void *__alloc_from_contiguous(strif (!page)return NULL ; -__dma_clear_buffer (page, size); +__dma_clear_buffer (page, size, coherent_flag);if (!want_vaddr) goto out;
@@ -638,7 +656,7 @@ static inline pgprot_t __get_dma_pgprot(#define __get_dma_pgprot (attrs, prot) __pgprot(0)#define __alloc_remap_buffer (dev, size, gfp, prot, ret, c, wv) NULL#define __alloc_from_pool (size, ret_page) NULL -#define __alloc_from_contiguous (dev, size, prot, ret, c, wv) NULL +#define __alloc_from_contiguous (dev, size, prot, ret, c, wv, coherent_flag) NULL#define __free_from_pool (cpu_addr, size) do { } while (0)#define __free_from_contiguous (dev, page, cpu_addr, size, wv) do { } while (0)#define __dma_free_remap (cpu_addr, size) do { } while (0)
@@ -649,7 +667,8 @@ static void *__alloc_simple_buffer(struc struct page **ret_page) {struct page *page; - page =__dma_alloc_buffer (dev, size, gfp); +/* __alloc_simple_buffer is only called when the device is coherent */ + page =__dma_alloc_buffer (dev, size, gfp,COHERENT );if (!page)return NULL ;
@@ -679,7 +698,7 @@ static void *cma_allocator_alloc(struct {return __alloc_from_contiguous (args->dev, args->size, args->prot, ret_page, args->caller, - args->want_vaddr); + args->want_vaddr, args->coherent_flag); }static void cma_allocator_free (struct arm_dma_free_args *args)
@@ -746,6 +765,7 @@ static void *__dma_alloc(struct device * .prot = prot, .caller = caller, .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs), + .coherent_flag = is_coherent ? COHERENT : NORMAL, };#ifdef CONFIG_DMA_API_DEBUG
@@ -1253,7 +1273,8 @@ static inline void __free_iova(struct dmstatic const int iommu_order_array[] = {9 ,8 ,4 ,0 };static struct page **__iommu_alloc_buffer (struct device *dev,size_t size, -gfp_t gfp,struct dma_attrs *attrs) +gfp_t gfp,struct dma_attrs *attrs, +int coherent_flag) {struct page **pages;int count = size >>PAGE_SHIFT ;
@@ -1277,7 +1298,7 @@ static struct page **__iommu_alloc_buffeif (!page) goto error; -__dma_clear_buffer (page, size); +__dma_clear_buffer (page, size, coherent_flag);for (i =0 ; i < count; i++) pages[i] = page + i;
@@ -1327,7 +1348,7 @@ static struct page **__iommu_alloc_buffe pages[i + j] = pages[i] + j; } -__dma_clear_buffer (pages[i],PAGE_SIZE << order); +__dma_clear_buffer (pages[i],PAGE_SIZE << order, coherent_flag); i +=1 << order; count -=1 << order; }
@@ -1505,7 +1526,8 @@ static void *arm_iommu_alloc_attrs(struc*/ gfp &= ~(__GFP_COMP); - pages =__iommu_alloc_buffer (dev, size, gfp, attrs); +/* For now always consider we are in a non-coherent case */ + pages =__iommu_alloc_buffer (dev, size, gfp, attrs,NORMAL );if (!pages)return NULL ;
Greg Kroah-Hartman
maintainerPATCH 107/186 ARM: dts: sunxi: Add a startup delay for fixed regulator enabled phys
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit fc51b632c7b047c25807023b76f3877aed19c770 upstream.
It seems that recent kernels have a shorter timeout when scanning for ethernet phys causing us to hit a timeout on boards where the phy's regulator gets enabled just before scanning, which leads to non working ethernet.
A 10ms startup delay seems to be enough to fix it, this commit adds a 20ms startup delay just to be safe.
This has been tested on a sun4i-a10-a1000 and sun5i-a10s-wobo-i5 board, both of which have non-working ethernet on recent kernels without this fix.
--- arch/arm/boot/dts/sun4i-a10-a1000.dts | 1 + arch/arm/boot/dts/sun4i-a10-hackberry.dts | 1 + arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts | 1 + arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts | 1 + 4 files changed, 4 insertions(+)
arch/arm/boot/dts/sun4i-a10-a1000.dts +1 -0
@@ -84,6 +84,7 @@ regulator-name = "emac-3v3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; + startup-delay-us = <20000>; enable-active-high; gpio = <&pio 7 15 GPIO_ACTIVE_HIGH>; };
arch/arm/boot/dts/sun4i-a10-hackberry.dts +1 -0
@@ -66,6 +66,7 @@ regulator-name = "emac-3v3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; + startup-delay-us = <20000>; enable-active-high; gpio = <&pio 7 19 GPIO_ACTIVE_HIGH>; };
arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts +1 -0
@@ -80,6 +80,7 @@ regulator-name = "emac-3v3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; + startup-delay-us = <20000>; enable-active-high; gpio = <&pio 7 19 GPIO_ACTIVE_HIGH>; /* PH19 */ };
arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts +1 -0
@@ -79,6 +79,7 @@ regulator-name = "emac-3v3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; + startup-delay-us = <20000>; enable-active-high; gpio = <&pio 0 2 GPIO_ACTIVE_HIGH>; };
Greg Kroah-Hartman
maintainerPATCH 108/186 ARM: dts: realview: Fix PBX-A9 cache description
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robin Murphy <[email protected]>
commit a20303725ec31ea0fcf498f1885b1d4245a4ee56 upstream.
Clearly QEMU is very permissive in how its PL310 model may be set up, but the real hardware turns out to be far more particular about things actually being correct. Fix up the DT description so that the real thing actually boots:
- The arm,data-latency and arm,tag-latency properties need 3 cells to be valid, otherwise we end up retaining the default 8-cycle latencies which leads pretty quickly to lockup.
- The arm,dirty-latency property is only relevant to L210/L220, so get rid of it.
- The cache geometry override also leads to lockup and/or general misbehaviour. Irritatingly, the manual doesn't state the actual PL310 configuration, but based on the boardfile code and poking registers from the Boot Monitor, it would seem to be 8 sets of 16KB ways.
With that, we can successfully boot to enjoy the fun of mismatched FPUs...
--- arch/arm/boot/dts/arm-realview-pbx-a9.dts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
arch/arm/boot/dts/arm-realview-pbx-a9.dts +4 -5
@@ -70,13 +70,12 @@ * associativity as these may be erroneously set * up by boot loader(s). */ - cache-size = <1048576>; // 1MB - cache-sets = <4096>; + cache-size = <131072>; // 128KB + cache-sets = <512>; cache-line-size = <32>; arm,parity-disable; - arm,tag-latency = <1>; - arm,data-latency = <1 1>; - arm,dirty-latency = <1>; + arm,tag-latency = <1 1 1>; + arm,data-latency = <1 1 1>; }; scu: scu@1f000000 {
Greg Kroah-Hartman
maintainerPATCH 109/186 ARM: tegra: fix erroneous address in dts
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralf Ramsauer <[email protected]>
commit b5c86b7496d74f6e454bcab5166efa023e1f0459 upstream.
c90bb7b enabled the high speed UARTs of the Jetson TK1. Due to a merge quirk, wrong addresses were introduced. Fix it and use the correct addresses.
Thierry let me know, that there is another patch (b5896f67ab3c in linux-next) in preparation which removes all the '0,' prefixes of unit addresses on Tegra124 and is planned to go upstream in 4.8, so this patch will get reverted then.
But for the moment, this patch is necessary to fix current misbehaviour.
--- arch/arm/boot/dts/tegra124-jetson-tk1.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/tegra124-jetson-tk1.dts +2 -2
@@ -1386,7 +1386,7 @@ * Pin 41: BR_UART1_TXD * Pin 44: BR_UART1_RXD */ - serial@70006000 { + serial@0,70006000 { compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; status = "okay"; };
@@ -1398,7 +1398,7 @@ * Pin 71: UART2_CTS_L * Pin 74: UART2_RTS_L */ - serial@70006040 { + serial@0,70006040 { compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; status = "okay"; };
Greg Kroah-Hartman
maintainerPATCH 110/186 Revert "ARM: aspeed: adapt defconfigs for new CONFIG_PRINTK_TIME"
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 7a376ac11fc2109dfd86442ff79982ecf16dcd6d upstream.
The patch that this was preparing for made it into neither v4.7 nor v4.8, so we should back this out as well to avoid the opposite warning:
arch/arm/configs/aspeed_g5_defconfig:62:warning: symbol value '1' invalid for PRINTK_TIME arch/arm/configs/aspeed_g4_defconfig:61:warning: symbol value '1' invalid for PRINTK_TIME
Sorry for not catching this earlier.
--- arch/arm/configs/aspeed_g4_defconfig | 2 +- arch/arm/configs/aspeed_g5_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/arm/configs/aspeed_g4_defconfig +1 -1
@@ -58,7 +58,7 @@ CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_FIRMWARE_MEMMAP=y CONFIG_FANOTIFY=y -CONFIG_PRINTK_TIME=1 +CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y CONFIG_STRIP_ASM_SYMS=y CONFIG_PAGE_POISONING=y
arch/arm/configs/aspeed_g5_defconfig +1 -1
@@ -59,7 +59,7 @@ CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_FIRMWARE_MEMMAP=y CONFIG_FANOTIFY=y -CONFIG_PRINTK_TIME=1 +CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y CONFIG_STRIP_ASM_SYMS=y CONFIG_PAGE_POISONING=y
Greg Kroah-Hartman
maintainerPATCH 111/186 cgroupns: Fix the locking in copy_cgroup_ns
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
commit 7bd8830875bfa380c68f390efbad893293749324 upstream.
If "clone(CLONE_NEWCGROUP...)" is called it results in a nice lockdep valid splat.
In __cgroup_proc_write the lock ordering is:
cgroup_mutex -- through cgroup_kn_lock_live
cgroup_threadgroup_rwsem
In copy_process the guts of clone the lock ordering is:
cgroup_threadgroup_rwsem -- through threadgroup_change_begin cgroup_mutex -- through copy_namespaces -- copy_cgroup_ns
lockdep reports some a different call chains for the first ordering of cgroup_mutex and cgroup_threadgroup_rwsem but it is harder to trace. This is most definitely deadlock potential under the right circumstances.
Fix this by by skipping the cgroup_mutex and making the locking in copy_cgroup_ns mirror the locking in cgroup_post_fork which also runs during fork under the cgroup_threadgroup_rwsem.
--- kernel/cgroup.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
kernel/cgroup.c +1 -4
@@ -6309,14 +6309,11 @@ struct cgroup_namespace *copy_cgroup_ns(if (!ns_capable (user_ns,CAP_SYS_ADMIN ))return ERR_PTR (-EPERM ); -mutex_lock (&cgroup_mutex); +/* It is not safe to take cgroup_mutex here */ spin_lock_irq (&css_set_lock); - cset =task_css_set (current);get_css_set (cset); -spin_unlock_irq (&css_set_lock); -mutex_unlock (&cgroup_mutex); new_ns =alloc_cgroup_ns ();if (IS_ERR (new_ns)) {
Greg Kroah-Hartman
maintainerPATCH 112/186 cgroupns: Close race between cgroup_post_fork and copy_cgroup_ns
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
commit eedd0f4cbf5f3b81e82649832091e1d9d53f0709 upstream.
In most code paths involving cgroup migration cgroup_threadgroup_rwsem is taken. There are two exceptions:
- remove_tasks_in_empty_cpuset calls cgroup_transfer_tasks
- vhost_attach_cgroups_work calls cgroup_attach_task_all
With cgroup_threadgroup_rwsem held it is guaranteed that cgroup_post_fork and copy_cgroup_ns will reference the same css_set from the process calling fork.
Without such an interlock there process after fork could reference one css_set from it's new cgroup namespace and another css_set from task->cgroups, which semantically is nonsensical.
--- kernel/cgroup.c | 5 +++++ 1 file changed, 5 insertions(+)
kernel/cgroup.c +5 -0
@@ -2962,6 +2962,7 @@ int cgroup_attach_task_all(struct task_sint retval =0 ;mutex_lock (&cgroup_mutex); +percpu_down_write (&cgroup_threadgroup_rwsem);for_each_root (root) {struct cgroup *from_cgrp;
@@ -2976,6 +2977,7 @@ int cgroup_attach_task_all(struct task_sif (retval)break ; } +percpu_up_write (&cgroup_threadgroup_rwsem);mutex_unlock (&cgroup_mutex);return retval;
@@ -4343,6 +4345,8 @@ int cgroup_transfer_tasks(struct cgroupmutex_lock (&cgroup_mutex); +percpu_down_write (&cgroup_threadgroup_rwsem); +/* all tasks in @from are being moved, all csets are source */ spin_lock_irq (&css_set_lock);list_for_each_entry (link, &from->cset_links, cset_link)
@@ -4371,6 +4375,7 @@ int cgroup_transfer_tasks(struct cgroup }while (task && !ret); out_err:cgroup_migrate_finish (&preloaded_csets); +percpu_up_write (&cgroup_threadgroup_rwsem);mutex_unlock (&cgroup_mutex);return ret; }
Greg Kroah-Hartman
maintainerPATCH 113/186 cgroupns: Only allow creation of hierarchies in the initial cgroup namespace
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
commit 726a4994b05ff5b6f83d64b5b43c3251217366ce upstream.
Unprivileged users can't use hierarchies if they create them as they do not have privilieges to the root directory.
Which means the only thing a hiearchy created by an unprivileged user is good for is expanding the number of cgroup links in every css_set, which is a DOS attack.
We could allow hierarchies to be created in namespaces in the initial user namespace. Unfortunately there is only a single namespace for the names of heirarchies, so that is likely to create more confusion than not.
So do the simple thing and restrict hiearchy creation to the initial cgroup namespace.
--- kernel/cgroup.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
kernel/cgroup.c +2 -6
@@ -2215,12 +2215,8 @@ static struct dentry *cgroup_mount(struc goto out_unlock; } -/* -* We know this subsystem has not yet been bound. Users in a non-init -* user namespace may only mount hierarchies with no bound subsystems, -* i.e. 'none,name=user1' -*/ -if (!opts.none && !capable (CAP_SYS_ADMIN )) { +/* Hierarchies may only be created in the initial cgroup namespace. */ +if (ns != &init_cgroup_ns) { ret = -EPERM ; goto out_unlock; }
Greg Kroah-Hartman
maintainerPATCH 114/186 tpm_crb: fix address space of the return pointer in crb_map_res()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Sakkinen <[email protected]>
commit f786b752098216fedb73ba2905c8cce12358534a upstream.
When running make C=2 M=drivers/char/tpm/
CHECK drivers/char/tpm//tpm_crb.c
drivers/char/tpm//tpm_crb.c:248:31: warning: incorrect type in return expression (different address spaces)
drivers/char/tpm//tpm_crb.c:248:31: expected void [noderef] <asn:2>*
drivers/char/tpm//tpm_crb.c:248:31: got void *
--- drivers/char/tpm/tpm_crb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/tpm/tpm_crb.c +1 -1
@@ -246,7 +246,7 @@ static void __iomem *crb_map_res(struct/* Detect a 64 bit address on a 32 bit system */ if (start != new_res.start) -return ERR_PTR (-EINVAL ); +return (void __iomem *)ERR_PTR (-EINVAL );if (!resource_contains (&priv->res, &new_res))return devm_ioremap_resource (dev, &new_res);
Greg Kroah-Hartman
maintainerPATCH 115/186 clk: rockchip: fix incorrect rk3399 spdif-DPTX divider bits
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xing Zheng <[email protected]>
commit 3770821fa360525e6c726cd562a2438a0aa5d566 upstream.
The CLKSEL_CON32 bit_0 is controlled for spdif_8ch, not spdif_rec_dptx, it should be bit_8, let's fix it.
--- drivers/clk/rockchip/clk-rk3399.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/rockchip/clk-rk3399.c +1 -1
@@ -586,7 +586,7 @@ static struct rockchip_clk_branch rk3399 RK3399_CLKGATE_CON(8), 15, GFLAGS),COMPOSITE (SCLK_SPDIF_REC_DPTX ,"clk_spdif_rec_dptx" , mux_pll_src_cpll_gpll_p,0 , -RK3399_CLKSEL_CON (32 ),15 ,1 ,MFLAGS ,0 ,5 ,DFLAGS , +RK3399_CLKSEL_CON (32 ),15 ,1 ,MFLAGS ,8 ,5 ,DFLAGS ,RK3399_CLKGATE_CON (10 ),6 ,GFLAGS ),/* i2s */ COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
Greg Kroah-Hartman
maintainerPATCH 116/186 soc: qcom: smp2p: Correct addressing of outgoing value
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjorn Andersson <[email protected]>
commit 63af8e44eaa56ffe613628742a2642c4c2f1a029 upstream.
The valid_entries index should not be incremented until after we have acquired the pointer to the value, or we will read and write data one item off.
--- drivers/soc/qcom/smp2p.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/soc/qcom/smp2p.c +2 -1
@@ -344,11 +344,12 @@ static int qcom_smp2p_outbound_entry(str/* Allocate an entry from the smem item */ strlcpy (buf, entry->name,SMP2P_MAX_ENTRY_NAME );memcpy_toio (out->entries[out->valid_entries].name, buf,SMP2P_MAX_ENTRY_NAME ); - out->valid_entries++;/* Make the logical entry reference the physical value */ entry->value = &out->entries[out->valid_entries].value; + out->valid_entries++; + entry->state =qcom_smem_state_register (node, &smp2p_state_ops, entry);if (IS_ERR (entry->state)) {dev_err (smp2p->dev,"failed to register qcom_smem_state\n" );
Greg Kroah-Hartman
maintainerPATCH 117/186 netlabel: add address family checks to netlbl_{sock,req}_delattr()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Moore <[email protected]>
commit 0e0e36774081534783aa8eeb9f6fbddf98d3c061 upstream.
It seems risky to always rely on the caller to ensure the socket's address family is correct before passing it to the NetLabel kAPI, especially since we see at least one LSM which didn't. Add address family checks to the *_delattr() functions to help prevent future problems.
--- net/netlabel/netlabel_kapi.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
net/netlabel/netlabel_kapi.c +10 -2
@@ -824,7 +824,11 @@ socket_setattr_return:*/ void netlbl_sock_delattr (struct sock *sk) { -cipso_v4_sock_delattr (sk); +switch (sk->sk_family) { +case AF_INET : +cipso_v4_sock_delattr (sk); +break ; + } }/**
@@ -987,7 +991,11 @@ req_setattr_return:*/ void netlbl_req_delattr (struct request_sock *req) { -cipso_v4_req_delattr (req); +switch (req->rsk_ops->family) { +case AF_INET : +cipso_v4_req_delattr (req); +break ; + } }/**
Greg Kroah-Hartman
maintainerPATCH 118/186 w1:omap_hdq: fix regression
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: H. Nikolaus Schaller <[email protected]>
commit ecfaf0c42fc4306b5ec4bf6be01b66f8fe9a9733 upstream.
Commit e93762bbf681 ("w1: masters: omap_hdq: add support for 1-wire mode") added a statement to clear the hdq_irqstatus flags in hdq_read_byte().
If the hdq reading process is scheduled slowly or interrupts are disabled for a while the hardware read activity might already be finished on entry of hdq_read_byte(). And hdq_isr() already has set the hdq_irqstatus to 0x6 (can be seen in debug mode) denoting that both, the TXCOMPLETE and RXCOMPLETE interrupts occurred in parallel.
This means there is no need to wait and the hdq_read_byte() can just read the byte from the hdq controller.
By resetting hdq_irqstatus to 0 the read process is forced to be always waiting again (because the if statement always succeeds) but the hardware will not issue another RXCOMPLETE interrupt. This results in a false timeout.
After such a situation the hdq bus hangs.
--- drivers/w1/masters/omap_hdq.c | 2 -- 1 file changed, 2 deletions(-)
drivers/w1/masters/omap_hdq.c +0 -2
@@ -390,8 +390,6 @@ static int hdq_read_byte(struct hdq_data goto out; } - hdq_data->hdq_irqstatus =0 ; -if (!(hdq_data->hdq_irqstatus &OMAP_HDQ_INT_STATUS_RXCOMPLETE )) { hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO,
Greg Kroah-Hartman
maintainerPATCH 120/186 drm/amdgpu: Poll for both connect/disconnect on analog connectors
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lyude <[email protected]>
commit b636a1b3d624b49b23cc1be2f9f6bcbb89aca855 upstream.
DRM_CONNECTOR_POLL_CONNECT only enables polling for connections, not disconnections. Because of this, we end up losing hotplug polling for analog connectors once they get connected.
Easy way to reproduce:
- Grab a machine with an AMD GPU and a VGA port
- Plug a monitor into the VGA port, wait for it to update the connector from disconnected to connected
- Disconnect the monitor on VGA, a hotplug event is never sent for the removal of the connector.
Originally, only using DRM_CONNECTOR_POLL_CONNECT might have been a good idea since doing VGA polling can sometimes result in having to mess with the DAC voltages to figure out whether or not there's actually something there since VGA doesn't have HPD. Doing this would have the potential of showing visible artifacts on the screen every time we ran a poll while a VGA display was connected. Luckily, amdgpu_vga_detect() only resorts to this sort of polling if the poll is forced, and DRM's polling helper doesn't force it's polls.
Additionally, this removes some assignments to connector->polled that weren't actually doing anything.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +4 -3
@@ -1690,7 +1690,6 @@ amdgpu_connector_add(struct amdgpu_devic DRM_MODE_SCALE_NONE);/* no HPD on analog connectors */ amdgpu_connector->hpd.hpd =AMDGPU_HPD_NONE ; - connector->polled =DRM_CONNECTOR_POLL_CONNECT ; connector->interlace_allowed = true; connector->doublescan_allowed = true;break ;
@@ -1893,8 +1892,10 @@ amdgpu_connector_add(struct amdgpu_devic }if (amdgpu_connector->hpd.hpd ==AMDGPU_HPD_NONE ) { -if (i2c_bus->valid) - connector->polled =DRM_CONNECTOR_POLL_CONNECT ; +if (i2c_bus->valid) { + connector->polled =DRM_CONNECTOR_POLL_CONNECT | +DRM_CONNECTOR_POLL_DISCONNECT ; + } }else connector->polled =DRM_CONNECTOR_POLL_HPD ;
Greg Kroah-Hartman
maintainerPATCH 121/186 drm/amdgpu: support backlight control for UNIPHY3
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit dba6c4fa26ccf47661be5b68dba87e746fa137d8 upstream.
Same interface as other UNIPHY blocks
--- drivers/gpu/drm/amd/amdgpu/atombios_encoders.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +1 -0
@@ -98,6 +98,7 @@ amdgpu_atombios_encoder_set_backlight_lecase ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA :case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 :case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 : +case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 :if (dig->backlight_level ==0 )amdgpu_atombios_encoder_setup_dig_transmitter (encoder,ATOM_TRANSMITTER_ACTION_LCD_BLOFF ,0 ,0 );
Greg Kroah-Hartman
maintainerPATCH 122/186 drm/amdgpu: Disable RPM helpers while reprobing connectors on resume
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lyude <[email protected]>
commit 23a1a9e54e71593fe5657e883662995d181d2d6b upstream.
Just about all of amdgpu's connector probing functions try to acquire runtime PM refs. If we try to do this in the context of amdgpu_resume_kms by calling drm_helper_hpd_irq_event(), we end up deadlocking the system.
Since we're guaranteed to be holding the spinlock for RPM in amdgpu_resume_kms, and we already know the GPU is in working order, we need to prevent the RPM helpers from trying to run during the initial connector reprobe on resume.
There's a couple of solutions I've explored for fixing this, but this one by far seems to be the simplest and most reliable (plus I'm pretty sure that's what disable_depth is there for anyway).
Reproduction recipe:
- Get any laptop dual GPUs using PRIME
- Make sure runtime PM is enabled for amdgpu
- Boot the machine
- If the machine managed to boot without hanging, switch out of X to another VT. This should definitely cause X to hang infinitely.
Changes since v1:
- add appropriate #ifdef checks for CONFIG_PM. This is not very useful, but it appears some kernel test suites test compiling amdgpu with CONFIG_PM disabled, which results in this patch breaking the builds if we don't include this #ifdef
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +16 -0
@@ -1841,7 +1841,23 @@ int amdgpu_resume_kms(struct drm_device }drm_kms_helper_poll_enable (dev); + +/* +* Most of the connector probing functions try to acquire runtime pm +* refs to ensure that the GPU is powered on when connector polling is +* performed. Since we're calling this from a runtime PM callback, +* trying to acquire rpm refs will cause us to deadlock. +* +* Since we're guaranteed to be holding the rpm lock, it's safe to +* temporarily disable the rpm helpers so this doesn't deadlock us. +*/ +#ifdef CONFIG_PM + dev->dev->power.disable_depth++; +#endif drm_helper_hpd_irq_event (dev); +#ifdef CONFIG_PM + dev->dev->power.disable_depth--; +#endif if (fbcon) {amdgpu_fbdev_set_suspend (adev,0 );
Greg Kroah-Hartman
maintainerPATCH 123/186 drm/amdgpu: fix firmware info version checks
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit a8a04c994d41a489eb0f2899893209e04e030153 upstream.
Some of the checks didn't handle frev 2 tables properly. amdgpu doesn't support any tables pre-frev 2, so drop the checks.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +8 -17
@@ -551,28 +551,19 @@ int amdgpu_atombios_get_clock_info(strucle16_to_cpu (firmware_info->info.usReferenceClock); ppll->reference_div =0 ; -if (crev <2 ) - ppll->pll_out_min = -le16_to_cpu (firmware_info->info.usMinPixelClockPLL_Output); -else - ppll->pll_out_min = -le32_to_cpu (firmware_info->info_12.ulMinPixelClockPLL_Output); + ppll->pll_out_min = +le32_to_cpu (firmware_info->info_12.ulMinPixelClockPLL_Output); ppll->pll_out_max =le32_to_cpu (firmware_info->info.ulMaxPixelClockPLL_Output); -if (crev >=4 ) { - ppll->lcd_pll_out_min = -le16_to_cpu (firmware_info->info_14.usLcdMinPixelClockPLL_Output) *100 ; -if (ppll->lcd_pll_out_min ==0 ) - ppll->lcd_pll_out_min = ppll->pll_out_min; - ppll->lcd_pll_out_max = -le16_to_cpu (firmware_info->info_14.usLcdMaxPixelClockPLL_Output) *100 ; -if (ppll->lcd_pll_out_max ==0 ) - ppll->lcd_pll_out_max = ppll->pll_out_max; - }else { + ppll->lcd_pll_out_min = +le16_to_cpu (firmware_info->info_14.usLcdMinPixelClockPLL_Output) *100 ; +if (ppll->lcd_pll_out_min ==0 ) ppll->lcd_pll_out_min = ppll->pll_out_min; + ppll->lcd_pll_out_max = +le16_to_cpu (firmware_info->info_14.usLcdMaxPixelClockPLL_Output) *100 ; +if (ppll->lcd_pll_out_max ==0 ) ppll->lcd_pll_out_max = ppll->pll_out_max; - }if (ppll->pll_out_min ==0 ) ppll->pll_out_min =64800 ;
Greg Kroah-Hartman
maintainerPATCH 124/186 drm/amdgpu/gmc7: add missing mullins case
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 7f555c8e5a84b348c2b76f4ca78eae7222354c03 upstream.
Looks like this got missed when we ported the code from radeon.
--- drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +1 -0
@@ -167,6 +167,7 @@ static int gmc_v7_0_init_microcode(strucbreak ;case CHIP_KAVERI :case CHIP_KABINI : +case CHIP_MULLINS :return 0 ;default :BUG (); }
Greg Kroah-Hartman
maintainerPATCH 126/186 drm/radeon: Poll for both connect/disconnect on analog connectors
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lyude <[email protected]>
commit 14ff8d48f2235295dfb3117693008e367b49cdb5 upstream.
DRM_CONNECTOR_POLL_CONNECT only enables polling for connections, not disconnections. Because of this, we end up losing hotplug polling for analog connectors once they get connected.
Easy way to reproduce:
- Grab a machine with a radeon GPU and a VGA port
- Plug a monitor into the VGA port, wait for it to update the connector from disconnected to connected
- Disconnect the monitor on VGA, a hotplug event is never sent for the removal of the connector.
Originally, only using DRM_CONNECTOR_POLL_CONNECT might have been a good idea since doing VGA polling can sometimes result in having to mess with the DAC voltages to figure out whether or not there's actually something there since VGA doesn't have HPD. Doing this would have the potential of showing visible artifacts on the screen every time we ran a poll while a VGA display was connected. Luckily, radeon_vga_detect() only resorts to this sort of polling if the poll is forced, and DRM's polling helper doesn't force it's polls.
Additionally, this removes some assignments to connector->polled that weren't actually doing anything.
--- drivers/gpu/drm/radeon/radeon_connectors.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/gpu/drm/radeon/radeon_connectors.c +9 -6
@@ -2064,7 +2064,6 @@ radeon_add_atom_connector(struct drm_dev RADEON_OUTPUT_CSC_BYPASS);/* no HPD on analog connectors */ radeon_connector->hpd.hpd =RADEON_HPD_NONE ; - connector->polled =DRM_CONNECTOR_POLL_CONNECT ; connector->interlace_allowed = true; connector->doublescan_allowed = true;break ;
@@ -2314,8 +2313,10 @@ radeon_add_atom_connector(struct drm_dev }if (radeon_connector->hpd.hpd ==RADEON_HPD_NONE ) { -if (i2c_bus->valid) - connector->polled =DRM_CONNECTOR_POLL_CONNECT ; +if (i2c_bus->valid) { + connector->polled =DRM_CONNECTOR_POLL_CONNECT | +DRM_CONNECTOR_POLL_DISCONNECT ; + } }else connector->polled =DRM_CONNECTOR_POLL_HPD ;
@@ -2391,7 +2392,6 @@ radeon_add_legacy_connector(struct drm_d 1);/* no HPD on analog connectors */ radeon_connector->hpd.hpd =RADEON_HPD_NONE ; - connector->polled =DRM_CONNECTOR_POLL_CONNECT ; connector->interlace_allowed = true; connector->doublescan_allowed = true;break ;
@@ -2476,10 +2476,13 @@ radeon_add_legacy_connector(struct drm_d }if (radeon_connector->hpd.hpd ==RADEON_HPD_NONE ) { -if (i2c_bus->valid) - connector->polled =DRM_CONNECTOR_POLL_CONNECT ; +if (i2c_bus->valid) { + connector->polled =DRM_CONNECTOR_POLL_CONNECT | +DRM_CONNECTOR_POLL_DISCONNECT ; + } }else connector->polled =DRM_CONNECTOR_POLL_HPD ; + connector->display_info.subpixel_order = subpixel_order;drm_connector_register (connector); }
Greg Kroah-Hartman
maintainerPATCH 127/186 drm/radeon: fix firmware info version checks
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 3edc38a0facef45ee22af8afdce3737f421f36ab upstream.
Some of the checks didn't handle frev 2 tables properly.
--- drivers/gpu/drm/radeon/radeon_atombios.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/radeon_atombios.c +2 -2
@@ -1155,7 +1155,7 @@ bool radeon_atom_get_clock_info(struct dle16_to_cpu (firmware_info->info.usReferenceClock); p1pll->reference_div =0 ; -if (crev <2 ) +if ((frev <2 ) && (crev <2 )) p1pll->pll_out_min =le16_to_cpu (firmware_info->info.usMinPixelClockPLL_Output);else
@@ -1164,7 +1164,7 @@ bool radeon_atom_get_clock_info(struct d p1pll->pll_out_max =le32_to_cpu (firmware_info->info.ulMaxPixelClockPLL_Output); -if (crev >=4 ) { +if (((frev <2 ) && (crev >=4 )) || (frev >=2 )) { p1pll->lcd_pll_out_min =le16_to_cpu (firmware_info->info_14.usLcdMinPixelClockPLL_Output) *100 ;if (p1pll->lcd_pll_out_min ==0 )
Greg Kroah-Hartman
maintainerPATCH 128/186 drm/radeon: support backlight control for UNIPHY3
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit d3200be6c423afa1c34f7e39e9f6d04dd5b0af9d upstream.
Same interface as other UNIPHY blocks
--- drivers/gpu/drm/radeon/atombios_encoders.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/radeon/atombios_encoders.c +1 -0
@@ -120,6 +120,7 @@ atombios_set_backlight_level(struct radecase ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA :case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 :case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 : +case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 :if (dig->backlight_level ==0 )atombios_dig_transmitter_setup (encoder,ATOM_TRANSMITTER_ACTION_LCD_BLOFF ,0 ,0 );else {
Greg Kroah-Hartman
maintainerPATCH 129/186 drm/nouveau: check for supported chipset before booting fbdev off the hw
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Skeggs <[email protected]>
commit 0e67bed2c765ff0fdaec62c963881f5416fe3692 upstream.
--- drivers/gpu/drm/nouveau/nouveau_drm.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nouveau_drm.c +10 -1
@@ -324,7 +324,16 @@ static int nouveau_drm_probe(struct pci_ !vga_switcheroo_handler_flags())return -EPROBE_DEFER ; -/* remove conflicting drivers (vesafb, efifb etc) */ +/* We need to check that the chipset is supported before booting +* fbdev off the hardware, as there's no way to put it back. +*/ + ret =nvkm_device_pci_new (pdev,NULL ,"error" , true, false,0 , &device); +if (ret) +return ret; + +nvkm_device_del (&device); + +/* Remove conflicting drivers (vesafb, efifb etc). */ aper =alloc_apertures (3 );if (!aper)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 130/186 drm/nouveau/gr/nv3x: fix instobj write offsets in gr setup
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Mirkin <[email protected]>
commit d0e62ef6ed257715a88d0e5d7cd850a1695429e2 upstream.
This should fix some unaligned access warnings. This is also likely to fix non-descript issues on nv30/nv34 as a result of incorrect channel setup.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96836
--- drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c +2 -2
@@ -76,8 +76,8 @@ nv30_gr_chan_new(struct nvkm_gr *base, snvkm_wo32 (chan->inst, i,0x00040004 );for (i =0x1f18 ; i <=0x3088 ; i +=16 ) {nvkm_wo32 (chan->inst, i +0 ,0x10700ff9 ); -nvkm_wo32 (chan->inst, i +1 ,0x0436086c ); -nvkm_wo32 (chan->inst, i +2 ,0x000c001b ); +nvkm_wo32 (chan->inst, i +4 ,0x0436086c ); +nvkm_wo32 (chan->inst, i +8 ,0x000c001b ); }for (i =0x30b8 ; i <0x30c8 ; i +=4 )nvkm_wo32 (chan->inst, i,0x0000ffff );
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c +2 -2
@@ -75,8 +75,8 @@ nv34_gr_chan_new(struct nvkm_gr *base, snvkm_wo32 (chan->inst, i,0x00040004 );for (i =0x15ac ; i <=0x271c ; i +=16 ) {nvkm_wo32 (chan->inst, i +0 ,0x10700ff9 ); -nvkm_wo32 (chan->inst, i +1 ,0x0436086c ); -nvkm_wo32 (chan->inst, i +2 ,0x000c001b ); +nvkm_wo32 (chan->inst, i +4 ,0x0436086c ); +nvkm_wo32 (chan->inst, i +8 ,0x000c001b ); }for (i =0x274c ; i <0x275c ; i +=4 )nvkm_wo32 (chan->inst, i,0x0000ffff );
Greg Kroah-Hartman
maintainerPATCH 131/186 drm/nouveau/fbcon: fix font width not divisible by 8
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit 28668f43b8e421634e1623f72a879812288dd06b upstream.
The patch f045f459d925 ("drm/nouveau/fbcon: fix out-of-bounds memory accesses") tries to fix some out of memory accesses. Unfortunatelly, the patch breaks the display when using fonts with width that is not divisiable by 8.
The monochrome bitmap for each character is stored in memory by lines from top to bottom. Each line is padded to a full byte.
For example, for 22x11 font, each line is padded to 16 bits, so each character is consuming 44 bytes total, that is 11 32-bit words. The patch f045f459d925 changed the logic to "dsize = ALIGN(image->width * image->height, 32) >> 5", that is just 8 words - this is incorrect and it causes display corruption.
This patch adds the necesary padding of lines to 8 bytes.
This patch should be backported to stable kernels where f045f459d925 was backported.
--- drivers/gpu/drm/nouveau/nv04_fbcon.c | 4 ++-- drivers/gpu/drm/nouveau/nv50_fbcon.c | 2 +- drivers/gpu/drm/nouveau/nvc0_fbcon.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/nouveau/nv04_fbcon.c +2 -2
@@ -107,11 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *inf ((image->dx + image->width) & 0xffff));OUT_RING (chan, bg);OUT_RING (chan, fg); -OUT_RING (chan, (image->height <<16 ) | image->width); +OUT_RING (chan, (image->height <<16 ) |ALIGN (image->width,8 ));OUT_RING (chan, (image->height <<16 ) | image->width);OUT_RING (chan, (image->dy <<16 ) | (image->dx &0xffff )); - dsize =ALIGN (image->width * image->height,32 ) >>5 ; + dsize =ALIGN (ALIGN (image->width,8 ) * image->height,32 ) >>5 ;while (dsize) {int iter_len = dsize >128 ?128 : dsize;
drivers/gpu/drm/nouveau/nv50_fbcon.c +1 -1
@@ -125,7 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *infOUT_RING (chan,0 );OUT_RING (chan, image->dy); - dwords =ALIGN (image->width * image->height,32 ) >>5 ; + dwords =ALIGN (ALIGN (image->width,8 ) * image->height,32 ) >>5 ;while (dwords) {int push = dwords >2047 ?2047 : dwords;
drivers/gpu/drm/nouveau/nvc0_fbcon.c +1 -1
@@ -125,7 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *infOUT_RING (chan,0 );OUT_RING (chan, image->dy); - dwords =ALIGN (image->width * image->height,32 ) >>5 ; + dwords =ALIGN (ALIGN (image->width,8 ) * image->height,32 ) >>5 ;while (dwords) {int push = dwords >2047 ?2047 : dwords;
Greg Kroah-Hartman
maintainerPATCH 132/186 drm: Restore double clflush on the last partial cacheline
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Wilson <[email protected]>
commit 396f5d62d1a5fd99421855a08ffdef8edb43c76e upstream.
This effectively reverts
commit afcd950cafea6e27b739fe7772cbbeed37d05b8b
Author: Chris Wilson <[email protected]> Date: Wed Jun 10 15:58:01 2015 +0100
drm: Avoid the double clflush on the last cache line in drm_clflush_virt_range()
as we have observed issues with serialisation of the clflush operations on Baytrail+ Atoms with partial updates. Applying the double flush on the last cacheline forces that clflush to be ordered with respect to the previous clflush, and the mfence then protects against prefetches crossing the clflush boundary.
The same issue can be demonstrated in userspace with igt/gem_exec_flush.
Testcase: igt/gem_concurrent_blit
Testcase: igt/gem_partial_pread_pwrite
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92845
--- drivers/gpu/drm/drm_cache.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/drm_cache.c +1 -0
@@ -136,6 +136,7 @@ drm_clflush_virt_range(void *addr, unsigmb ();for (; addr < end; addr += size)clflushopt (addr); +clflushopt (end -1 );/* force serialisation */ mb ();return ; }
Greg Kroah-Hartman
maintainerPATCH 134/186 drm/amd/powerplay: fix the incorrect return value
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huang Rui <[email protected]>
commit bec5f70dad45f7ad63f97aa0988821532ebeade7 upstream.
The return value 0 (false) means fail to find GPIO in atomctrl_get_pp_assign_pin. "-1" returns true as bool actually.
--- drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c +2 -2
@@ -592,12 +592,12 @@ bool atomctrl_get_pp_assign_pin(const uint32_t pinId, pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment) { - bool bRet = 0; + bool bRet = false;ATOM_GPIO_PIN_LUT *gpio_lookup_table =get_gpio_lookup_table (hwmgr->device);PP_ASSERT_WITH_CODE ((NULL != gpio_lookup_table), -"Could not find GPIO lookup Table in BIOS." , return -1 ); + "Could not find GPIO lookup Table in BIOS.", return false); bRet =atomctrl_lookup_gpio_pin (gpio_lookup_table, pinId, gpio_pin_assignment);
Greg Kroah-Hartman
maintainerPATCH 135/186 drm/rockchip: allocate correct crtc state structure on reset
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Keeping <[email protected]>
commit dc0b408f5a87cce3ea3f81a6800244fb7d395435 upstream.
Because we are using a custom crtc_state structure, we must override the reset helper to allocate the correct amount of memory.
--- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/gpu/drm/rockchip/rockchip_drm_vop.c +12 -1
@@ -1048,6 +1048,17 @@ static void vop_crtc_destroy(struct drm_drm_crtc_cleanup (crtc); } +static void vop_crtc_reset (struct drm_crtc *crtc) +{ +if (crtc->state) +__drm_atomic_helper_crtc_destroy_state (crtc->state); +kfree (crtc->state); + + crtc->state =kzalloc (sizeof (struct rockchip_crtc_state ),GFP_KERNEL ); +if (crtc->state) + crtc->state->crtc = crtc; +} +static struct drm_crtc_state *vop_crtc_duplicate_state (struct drm_crtc *crtc) {struct rockchip_crtc_state *rockchip_state;
@@ -1073,7 +1084,7 @@ static const struct drm_crtc_funcs vop_c .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, .destroy = vop_crtc_destroy, - .reset = drm_atomic_helper_crtc_reset, + .reset = vop_crtc_reset, .atomic_duplicate_state = vop_crtc_duplicate_state, .atomic_destroy_state = vop_crtc_destroy_state, };
Greg Kroah-Hartman
maintainerPATCH 136/186 drm/i915/gen9: Add WaInPlaceDecompressionHang
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Kuoppala <[email protected]>
commit f15f6ca1e706e11fd07611bd4c7f903625349b33 upstream.
Add this workaround to prevent hang when in place compression is used.
References: HSD#2135774
--- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_ringbuffer.c | 14 ++++++++++++++ 3 files changed, 19 insertions(+)
drivers/gpu/drm/i915/i915_drv.h +2 -0
@@ -2591,6 +2591,8 @@ struct drm_i915_cmd_table {#define SKL_REVID_D0 0x3#define SKL_REVID_E0 0x4#define SKL_REVID_F0 0x5 +#define SKL_REVID_G0 0x6 +#define SKL_REVID_H0 0x7#define IS_SKL_REVID (p, since, until) (IS_SKYLAKE(p) && IS_REVID(p, since, until))
drivers/gpu/drm/i915/i915_reg.h +3 -0
@@ -1672,6 +1672,9 @@ enum skl_disp_power_wells {#define GEN7_TLB_RD_ADDR _MMIO(0x4700) +#define GEN9_GAMT_ECO_REG_RW_IA _MMIO(0x4ab0) +#define GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS (1<<18) +#define GAMT_CHKN_BIT_REG _MMIO(0x4ab8)#define GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING (1<<28)
drivers/gpu/drm/i915/intel_ringbuffer.c +14 -0
@@ -1135,6 +1135,11 @@ static int skl_init_workarounds(struct i/* WaDisableGafsUnitClkGating:skl */ WA_SET_BIT (GEN7_UCGCTL4 ,GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE ); +/* WaInPlaceDecompressionHang:skl */ +if (IS_SKL_REVID (dev_priv,SKL_REVID_H0 ,REVID_FOREVER )) +WA_SET_BIT (GEN9_GAMT_ECO_REG_RW_IA , +GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS ); +/* WaDisableLSQCROPERFforOCL:skl */ ret =wa_ring_whitelist_reg (engine,GEN8_L3SQCREG4 );if (ret)
@@ -1194,6 +1199,11 @@ static int bxt_init_workarounds(struct iWA_SET_BIT_MASKED (COMMON_SLICE_CHICKEN2 ,GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION ); +/* WaInPlaceDecompressionHang:bxt */ +if (IS_BXT_REVID (dev_priv,BXT_REVID_C0 ,REVID_FOREVER )) +WA_SET_BIT (GEN9_GAMT_ECO_REG_RW_IA , +GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS ); +return 0 ; }
@@ -1241,6 +1251,10 @@ static int kbl_init_workarounds(struct iGEN7_HALF_SLICE_CHICKEN1 , GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); +/* WaInPlaceDecompressionHang:kbl */ +WA_SET_BIT (GEN9_GAMT_ECO_REG_RW_IA , +GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS ); +/* WaDisableLSQCROPERFforOCL:kbl */ ret =wa_ring_whitelist_reg (engine,GEN8_L3SQCREG4 );if (ret)
Greg Kroah-Hartman
maintainerPATCH 141/186 balloon: check the number of available pages in leak balloon
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Neumoin <[email protected]>
commit 37cf99e08c6fb4dcea0f9ad2b13b6daa8c76a711 upstream.
The balloon has a special mechanism that is subscribed to the oom notification which leads to deflation for a fixed number of pages. The number is always fixed even when the balloon is fully deflated. But leak_balloon did not expect that the pages to deflate will be more than taken, and raise a "BUG" in balloon_page_dequeue when page list will be empty.
So, the simplest solution would be to check that the number of releases pages is less or equal to the number taken pages.
--- drivers/virtio/virtio_balloon.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/virtio/virtio_balloon.c +2 -0
@@ -202,6 +202,8 @@ static unsigned leak_balloon(struct virt num =min (num,ARRAY_SIZE (vb->pfns));mutex_lock (&vb->balloon_lock); +/* We can't release more pages than taken */ + num =min (num, (size_t )vb->num_pages);for (vb->num_pfns =0 ; vb->num_pfns < num; vb->num_pfns +=VIRTIO_BALLOON_PAGES_PER_PAGE ) { page =balloon_page_dequeue (vb_dev_info);
Greg Kroah-Hartman
maintainerPATCH 142/186 ftrace/recordmcount: Work around for addition of metag magic but not relocations
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laura Abbott <[email protected]>
commit b2e1c26f0b62531636509fbcb6dab65617ed8331 upstream.
glibc recently did a sync up (94e73c95d9b5 "elf.h: Sync with the gabi webpage") that added a #define for EM_METAG but did not add relocations
This triggers build errors:
scripts/recordmcount.c: In function 'do_file':scripts/recordmcount.c:466:28: error: 'R_METAG_ADDR32' undeclared (first use in this function)
case EM_METAG: reltype = R_METAG_ADDR32;
^~~~~~~~~~~~~~
scripts/recordmcount.c:466:28: note: each undeclared identifier is reported only once for each function it appears in
scripts/recordmcount.c:468:20: error: 'R_METAG_NONE' undeclared (first use in this function)
rel_type_nop = R_METAG_NONE;
^~~~~~~~~~~~Work around this change with some more #ifdefery for the relocations.
Fedora Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1354034
--- scripts/recordmcount.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
scripts/recordmcount.c +8 -1
@@ -33,10 +33,17 @@#include <string.h> #include <unistd.h> +/* +* glibc synced up and added the metag number but didn't add the relocations. +* Work around this in a crude manner for now. +*/ #ifndef EM_METAG -/* Remove this when these make it to the standard system elf.h. */ #define EM_METAG 174 +#endif +#ifndef R_METAG_ADDR32 #define R_METAG_ADDR32 2 +#endif +#ifndef R_METAG_NONE #define R_METAG_NONE 3#endif
Greg Kroah-Hartman
maintainerPATCH 143/186 metag: Fix __cmpxchg_u32 asm constraint for CMP
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <[email protected]>
commit 6154c187b97ee7513046bb4eb317a89f738f13ef upstream.
The LNKGET based atomic sequence in __cmpxchg_u32 has slightly incorrect constraints for the return value which under certain circumstances can allow an address unit register to be used as the first operand of a CMP instruction. This isn't a valid instruction however as the encodings only allow a data unit to be specified. This would result in an assembler error like the following:
Error: failed to assemble instruction: "CMP A0.2,D0Ar6"
Fix by changing the constraint from "=&da" (assigned, early clobbered, data or address unit register) to "=&d" (data unit register only).
The constraint for the second operand, "bd" (an op2 register where op1 is a data unit register and the instruction supports O2R) is already correct assuming the first operand is a data unit register.
Other cases of CMP in inline asm have had their constraints checked, and appear to all be fine.
--- arch/metag/include/asm/cmpxchg_lnkget.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/metag/include/asm/cmpxchg_lnkget.h +1 -1
@@ -73,7 +73,7 @@ static inline unsigned long __cmpxchg_u3 " DCACHE [%2], %0\n" #endif "2:\n" - : "=&d" (temp), "=&da" (retval) + : "=&d" (temp), "=&d" (retval) : "da" (m), "bd" (old), "da" (new) : "cc" );
Greg Kroah-Hartman
maintainerPATCH 144/186 block: add missing group association in bio-cloning functions
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Valente <[email protected]>
commit 20bd723ec6a3261df5e02250cd3a1fbb09a343f2 upstream.
When a bio is cloned, the newly created bio must be associated with the same blkcg as the original bio (if BLK_CGROUP is enabled). If this operation is not performed, then the new bio is not associated with any group, and the group of the current task is returned when the group of the bio is requested.
Depending on the cloning frequency, this may cause a large percentage of the bios belonging to a given group to be treated as if belonging to other groups (in most cases as if belonging to the root group). The expected group isolation may thereby be broken.
This commit adds the missing association in bio-cloning functions.
--- block/bio.c | 15 +++++++++++++++ fs/btrfs/extent_io.c | 6 ------ include/linux/bio.h | 3 +++ 3 files changed, 18 insertions(+), 6 deletions(-)
block/bio.c +15 -0
@@ -579,6 +579,8 @@ void __bio_clone_fast(struct bio *bio, s bio->bi_rw = bio_src->bi_rw; bio->bi_iter = bio_src->bi_iter; bio->bi_io_vec = bio_src->bi_io_vec; + +bio_clone_blkcg_association (bio, bio_src); }EXPORT_SYMBOL (__bio_clone_fast);
@@ -684,6 +686,8 @@ integrity_clone: } } +bio_clone_blkcg_association (bio, bio_src); +return bio; }EXPORT_SYMBOL (bio_clone_bioset);
@@ -2005,6 +2009,17 @@ void bio_disassociate_task(struct bio *b } } +/** +* bio_clone_blkcg_association - clone blkcg association from src to dst bio +* @dst: destination bio +* @src: source bio +*/ +void bio_clone_blkcg_association (struct bio *dst,struct bio *src) +{ +if (src->bi_css) +WARN_ON (bio_associate_blkcg (dst, src->bi_css)); +} +#endif /* CONFIG_BLK_CGROUP */ static void __init biovec_init_slabs (void )
fs/btrfs/extent_io.c +0 -6
@@ -2696,12 +2696,6 @@ struct bio *btrfs_bio_clone(struct bio * btrfs_bio->csum =NULL ; btrfs_bio->csum_allocated =NULL ; btrfs_bio->end_io =NULL ; - -#ifdef CONFIG_BLK_CGROUP -/* FIXME, put this into bio_clone_bioset */ -if (bio->bi_css) -bio_associate_blkcg (new, bio->bi_css); -#endif }return new; }
include/linux/bio.h +3 -0
@@ -527,11 +527,14 @@ extern unsigned int bvec_nr_vecs(unsigneint bio_associate_blkcg (struct bio *bio,struct cgroup_subsys_state *blkcg_css);int bio_associate_current (struct bio *bio);void bio_disassociate_task (struct bio *bio); +void bio_clone_blkcg_association (struct bio *dst,struct bio *src);#else /* CONFIG_BLK_CGROUP */ static inline int bio_associate_blkcg (struct bio *bio,struct cgroup_subsys_state *blkcg_css) {return 0 ; }static inline int bio_associate_current (struct bio *bio) {return -ENOENT ; }static inline void bio_disassociate_task (struct bio *bio) { } +static inline void bio_clone_blkcg_association (struct bio *dst, +struct bio *src) { }#endif /* CONFIG_BLK_CGROUP */ #ifdef CONFIG_HIGHMEM
Greg Kroah-Hartman
maintainerPATCH 145/186 block: fix bdi vs gendisk lifetime mismatch
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit df08c32ce3be5be138c1dbfcba203314a3a7cd6f upstream.
The name for a bdi of a gendisk is derived from the gendisk's devt. However, since the gendisk is destroyed before the bdi it leaves a window where a new gendisk could dynamically reuse the same devt while a bdi with the same name is still live. Arrange for the bdi to hold a reference against its "owner" disk device while it is registered. Otherwise we can hit sysfs duplicate name collisions like the following:
WARNING: CPU: 10 PID: 2078 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x64/0x80 sysfs: cannot create duplicate filename '/devices/virtual/bdi/259:1' Hardware name: HP ProLiant DL580 Gen8, BIOS P79 05/06/2015 0000000000000286 0000000002c04ad5 ffff88006f24f970 ffffffff8134caec ffff88006f24f9c0 0000000000000000 ffff88006f24f9b0 ffffffff8108c351 0000001f0000000c ffff88105d236000 ffff88105d1031e0 ffff8800357427f8 Call Trace: [<ffffffff8134caec>] dump_stack+0x63/0x87 [<ffffffff8108c351>] __warn+0xd1/0xf0 [<ffffffff8108c3cf>] warn_slowpath_fmt+0x5f/0x80 [<ffffffff812a0d34>] sysfs_warn_dup+0x64/0x80 [<ffffffff812a0e1e>] sysfs_create_dir_ns+0x7e/0x90 [<ffffffff8134faaa>] kobject_add_internal+0xaa/0x320 [<ffffffff81358d4e>] ? vsnprintf+0x34e/0x4d0 [<ffffffff8134ff55>] kobject_add+0x75/0xd0 [<ffffffff816e66b2>] ? mutex_lock+0x12/0x2f [<ffffffff8148b0a5>] device_add+0x125/0x610 [<ffffffff8148b788>] device_create_groups_vargs+0xd8/0x100 [<ffffffff8148b7cc>] device_create_vargs+0x1c/0x20 [<ffffffff811b775c>] bdi_register+0x8c/0x180 [<ffffffff811b7877>] bdi_register_dev+0x27/0x30 [<ffffffff813317f5>] add_disk+0x175/0x4a0
Fixed up missing 0 return in bdi_register_owner().
--- block/genhd.c | 2 +- include/linux/backing-dev-defs.h | 1 + include/linux/backing-dev.h | 1 + mm/backing-dev.c | 19 +++++++++++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-)
block/genhd.c +1 -1
@@ -613,7 +613,7 @@ void add_disk(struct gendisk *disk)/* Register BDI before referencing it from bdev */ bdi = &disk->queue->backing_dev_info; -bdi_register_dev (bdi,disk_devt (disk)); +bdi_register_owner (bdi,disk_to_dev (disk));blk_register_region (disk_devt (disk), disk->minors,NULL , exact_match, exact_lock, disk);
include/linux/backing-dev-defs.h +1 -0
@@ -163,6 +163,7 @@ struct backing_dev_info {wait_queue_head_t wb_waitq;struct device *dev; +struct device *owner;struct timer_list laptop_mode_wb_timer;
include/linux/backing-dev.h +1 -0
@@ -24,6 +24,7 @@ __printf(3, 4)int bdi_register (struct backing_dev_info *bdi,struct device *parent,const char *fmt, ...);int bdi_register_dev (struct backing_dev_info *bdi,dev_t dev); +int bdi_register_owner (struct backing_dev_info *bdi,struct device *owner);void bdi_unregister (struct backing_dev_info *bdi);int __must_check bdi_setup_and_register (struct backing_dev_info *,char *);
mm/backing-dev.c +19 -0
@@ -825,6 +825,20 @@ int bdi_register_dev(struct backing_dev_ }EXPORT_SYMBOL (bdi_register_dev); +int bdi_register_owner (struct backing_dev_info *bdi,struct device *owner) +{ +int rc; + + rc =bdi_register (bdi,NULL ,"%u:%u" ,MAJOR (owner->devt), +MINOR (owner->devt)); +if (rc) +return rc; + bdi->owner = owner; +get_device (owner); +return 0 ; +} +EXPORT_SYMBOL (bdi_register_owner); +/* * Remove bdi from bdi_list, and ensure that it is no longer visible */
@@ -849,6 +863,11 @@ void bdi_unregister(struct backing_dev_idevice_unregister (bdi->dev); bdi->dev =NULL ; } + +if (bdi->owner) { +put_device (bdi->owner); + bdi->owner =NULL ; + } }void bdi_exit (struct backing_dev_info *bdi)
Greg Kroah-Hartman
maintainerPATCH 146/186 floppy: fix open(O_ACCMODE) for ioctl-only open
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Kosina <[email protected]>
commit ff06db1efb2ad6db06eb5b99b88a0c15a9cc9b0e upstream.
Commit 09954bad4 ("floppy: refactor open() flags handling"), as a side-effect, causes open(/dev/fdX, O_ACCMODE) to fail. It turns out that this is being used setfdprm userspace for ioctl-only open().
Reintroduce back the original behavior wrt !(FMODE_READ|FMODE_WRITE) modes, while still keeping the original O_NDELAY bug fixed.
--- drivers/block/floppy.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)
drivers/block/floppy.c +9 -12
@@ -3663,11 +3663,6 @@ static int floppy_open(struct block_devi opened_bdev[drive] = bdev; -if (!(mode & (FMODE_READ |FMODE_WRITE ))) { - res = -EINVAL ; - goto out; - } - res = -ENXIO ;if (!floppy_track_buffer) {
@@ -3711,13 +3706,15 @@ static int floppy_open(struct block_deviif (UFDCS ->rawcmd ==1 )UFDCS ->rawcmd =2 ; -UDRS ->last_checked =0 ; -clear_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags); -check_disk_change (bdev); -if (test_bit (FD_DISK_CHANGED_BIT , &UDRS ->flags)) - goto out; -if (test_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags)) - goto out; +if (mode & (FMODE_READ |FMODE_WRITE )) { +UDRS ->last_checked =0 ; +clear_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags); +check_disk_change (bdev); +if (test_bit (FD_DISK_CHANGED_BIT , &UDRS ->flags)) + goto out; +if (test_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags)) + goto out; + } res = -EROFS ;
Re: [PATCH 4.7 146/186] floppy: fix open(O_ACCMODE) for ioctl-only open
Quoted 55 lines · Greg Kroah-Hartman
4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Kosina <[email protected]>
commit
ff06db1efb2ad6db06eb5b99b88a0c15a9cc9b0eupstream.Commit
09954bad4("floppy: refactoropen()flags handling"), as a side-effect, causesopen(/dev/fdX, O_ACCMODE)to fail. It turns out that this is being used setfdprm userspace for ioctl-onlyopen().Reintroduce back the original behavior wrt !(FMODE_READ|FMODE_WRITE) modes, while still keeping the original
O_NDELAYbug fixed.Reported-by Wim Osterholt <[email protected]>Tested-by Wim Osterholt <[email protected]>Signed-off-by Jiri Kosina <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/block/floppy.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)drivers/block/floppy.c +2
-12@@ -3663,11 +3663,6 @@ static int floppy_open(struct block_devi opened_bdev[drive] = bdev; -if (!(mode & (FMODE_READ |FMODE_WRITE ))) { - res = -EINVAL ; - goto out; - } - res = -ENXIO ;if (!floppy_track_buffer) {@@ -3711,13 +3706,15 @@ static int floppy_open(struct block_deviif (UFDCS ->rawcmd ==1 )UFDCS ->rawcmd =2 ; -UDRS ->last_checked =0 ; -clear_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags); -check_disk_change (bdev); -if (test_bit (FD_DISK_CHANGED_BIT , &UDRS ->flags)) - goto out; -if (test_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags)) - goto out; +if (mode & (FMODE_READ |FMODE_WRITE )) { +UDRS ->last_checked =0 ;
drivers/block/floppy.c static int floppy_open(struct block_devi · line 3720
Quoted 10 lines
drivers/block/floppy.c +7
-0+clear_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags); +check_disk_change (bdev); +if (test_bit (FD_DISK_CHANGED_BIT , &UDRS ->flags)) + goto out; +if (test_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags)) + goto out; + } res = -EROFS ;
I have a problem with this patch. It only fixes one of the regressions caused by the original change to the floppy driver. It does not address the user land breakage of removing the NODELAY flag checks.
Thanks
Mark
Greg Kroah-Hartman
maintainerRe: [PATCH 4.7 146/186] floppy: fix open(O_ACCMODE) for ioctl-only open
Quoted 61 lines · Mark Hounschell
Quoted 60 lines · Greg Kroah-Hartman
4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Kosina <[email protected]>
commit
ff06db1efb2ad6db06eb5b99b88a0c15a9cc9b0eupstream.Commit
09954bad4("floppy: refactoropen()flags handling"), as a side-effect, causesopen(/dev/fdX, O_ACCMODE)to fail. It turns out that this is being used setfdprm userspace for ioctl-onlyopen().Reintroduce back the original behavior wrt !(FMODE_READ|FMODE_WRITE) modes, while still keeping the original
O_NDELAYbug fixed.Reported-by Wim Osterholt <[email protected]>Tested-by Wim Osterholt <[email protected]>Signed-off-by Jiri Kosina <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/block/floppy.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)drivers/block/floppy.c +9
-12@@ -3663,11 +3663,6 @@ static int floppy_open(struct block_devi opened_bdev[drive] = bdev; -if (!(mode & (FMODE_READ |FMODE_WRITE ))) { - res = -EINVAL ; - goto out; - } - res = -ENXIO ;if (!floppy_track_buffer) {@@ -3711,13 +3706,15 @@ static int floppy_open(struct block_deviif (UFDCS ->rawcmd ==1 )UFDCS ->rawcmd =2 ; -UDRS ->last_checked =0 ; -clear_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags); -check_disk_change (bdev); -if (test_bit (FD_DISK_CHANGED_BIT , &UDRS ->flags)) - goto out; -if (test_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags)) - goto out; +if (mode & (FMODE_READ |FMODE_WRITE )) { +UDRS ->last_checked =0 ; +clear_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags); +check_disk_change (bdev); +if (test_bit (FD_DISK_CHANGED_BIT , &UDRS ->flags)) + goto out; +if (test_bit (FD_OPEN_SHOULD_FAIL_BIT , &UDRS ->flags)) + goto out; + }
Quoted 9 lines
drivers/block/floppy.c static int floppy_open(struct block_devi · line 3720
Quoted 5 lines
drivers/block/floppy.c +0
-0res = -EROFS ;I have a problem with this patch. It only fixes one of the regressions caused by the original change to the floppy driver. It does not address the user land breakage of removing the NODELAY flag checks.
Does the same problem also happen in Linus's tree? If not, any hints on the patch that might have fixed it there?
thanks,
greg k-h
Re: [PATCH 4.7 146/186] floppy: fix open(O_ACCMODE) for ioctl-only open
Quoted 6 lines · Greg Kroah-Hartman
Quoted 3 lines
I have a problem with this patch. It only fixes one of the regressions caused by the original change to the floppy driver. It does not address the user land breakage of removing the NODELAY flag checks.
Does the same problem also happen in Linus's tree? If not, any hints on the patch that might have fixed it there?
That's still an unresolved issue, and it's on my list to things to look into.
This particular patch though fixes a different issue, and should be applied to -stable.
Thanks,
Signature · 2 lines
Jiri Kosina SUSE Labs
Re: [PATCH 4.7 146/186] floppy: fix open(O_ACCMODE) for ioctl-only open
Quoted 9 lines · Jiri Kosina
Quoted 6 lines · Greg Kroah-Hartman
Quoted 3 lines
I have a problem with this patch. It only fixes one of the regressions caused by the original change to the floppy driver. It does not address the user land breakage of removing the NODELAY flag checks.
Does the same problem also happen in Linus's tree? If not, any hints on the patch that might have fixed it there?
Yes, it does. IMHO the entire patch (between 4.4 and 4.5 that broke user land multiple ways) should be reverted and a fix for what ever obscure BUG was supposed to be fixed should be "retried".
Quoted 6 lines
That's still an unresolved issue, and it's on my list to things to look into.
This particular patch though fixes a different issue, and should be applied to -stable.
This patch fixes a bug that was introduced to fix "some other obscure BUG" that has nothing to do whatever with the "physical floppy" device. And it broke user land in at least 2 ways. All this patch does is revert part of the original patch so that it is only broke in 1 way to user land. It should revert the whole thing IMHO.
Regards
Mark
Quoted 2 lines
Thanks,
Re: [PATCH 4.7 146/186] floppy: fix open(O_ACCMODE) for ioctl-only open
Quoted 23 lines · Mark Hounschell
Quoted 10 lines · Jiri Kosina
Quoted 7 lines · Greg Kroah-Hartman
Quoted 4 lines
I have a problem with this patch. It only fixes one of the regressions caused by the original change to the floppy driver. It does not address the
user land breakage of removing the NODELAY flag checks.Does the same problem also happen in Linus's tree? If not, any hints on the patch that might have fixed it there?
Yes, it does. IMHO the entire patch (between 4.4 and 4.5 that broke user land multiple ways) should be reverted and a fix for what ever obscure BUG was supposed to be fixed should be "retried".
Quoted 6 lines
That's still an unresolved issue, and it's on my list to things to look into.
This particular patch though fixes a different issue, and should be applied to -stable.
Quoted 5 lines
This patch fixes a bug that was introduced to fix "some other obscure BUG" that has nothing to do whatever with the "physical floppy" device. And it broke user land in at least 2 ways. All this patch does is revert part of the original patch so that it is only broke in 1 way to user land. It should revert the whole thing IMHO.
Which patch is this? If that is truly the case, it should be reverted asap.
Signature · 1 line
Jens Axboe
Re: [PATCH 4.7 146/186] floppy: fix open(O_ACCMODE) for ioctl-only open
Quoted 25 lines · Jens Axboe
Quoted 24 lines · Mark Hounschell
Quoted 11 lines · Jiri Kosina
Quoted 8 lines · Greg Kroah-Hartman
Quoted 4 lines
I have a problem with this patch. It only fixes one of the regressions caused by the original change to the floppy driver. It does not address the
user land breakage of removing the NODELAY flag checks.Does the same problem also happen in Linus's tree? If not, any hints on
the patch that might have fixed it there?Yes, it does. IMHO the entire patch (between 4.4 and 4.5 that broke user land multiple ways) should be reverted and a fix for what ever obscure BUG was supposed to be fixed should be "retried".
Quoted 6 lines
That's still an unresolved issue, and it's on my list to things to look into.
This particular patch though fixes a different issue, and should be applied to -stable.
Quoted 9 lines
Quoted 5 lines
This patch fixes a bug that was introduced to fix "some other obscure BUG" that has nothing to do whatever with the "physical floppy" device. And it broke user land in at least 2 ways. All this patch does is revert part of the original patch so that it is only broke in 1 way to user land. It should revert the whole thing IMHO.
Which patch is this? If that is truly the case, it should be reverted asap.
commit 09954bad448791ef01202351d437abdd9497a804 seems to be the one.
Mark
Re: [PATCH 4.7 146/186] floppy: fix open(O_ACCMODE) for ioctl-only open
In reply to Jens AxboeQuoted 2 lines · Jens Axboe
Which patch is this? If that is truly the case, it should be reverted asap.
I've been looking into this for the past few days, and unfortunately I am not able to come up with a simple fix, so revert seems like the way to go.
Unfortunately, by reverting the patch, we'll get back into the original situation, where the bug found by syzkaller would be present.
If going down the revert path, we'd have to bring the driver to the state it was before, i.e. reverting it and the followup fix, i.e.
ff06db1efb2ad6db06eb5b99b88a0c15a9cc9b0e 09954bad448791ef01202351d437abdd9497a804
And then go back to the drawing board to fix the corruption reported by syzkaller.
Signature · 2 lines
Jiri Kosina SUSE Labs
Re: [PATCH 4.7 146/186] floppy: fix open(O_ACCMODE) for ioctl-only open
Quoted 11 lines · Jiri Kosina
Quoted 2 lines · Jens Axboe
Which patch is this? If that is truly the case, it should be reverted asap.
I've been looking into this for the past few days, and unfortunately I am not able to come up with a simple fix, so revert seems like the way to go.
Unfortunately, by reverting the patch, we'll get back into the original situation, where the bug found by syzkaller would be present.
Quoted 8 lines
If going down the revert path, we'd have to bring the driver to the state it was before, i.e. reverting it and the followup fix, i.e.
ff06db1efb2ad6db06eb5b99b88a0c15a9cc9b0e 09954bad448791ef01202351d437abdd9497a804And then go back to the drawing board to fix the corruption reported by syzkaller.
I'll revert these two.
Signature · 1 line
Jens Axboe
Greg Kroah-Hartman
maintainerPATCH 147/186 mtd: nand: fix bug writing 1 byte less than page size
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hector Palacios <[email protected]>
commit 144f4c98399e2c0ca60eb414c15a2c68125c18b8 upstream.
nand_do_write_ops() determines if it is writing a partial page with the formula:
part_pagewr = (column || writelen < (mtd->writesize - 1))
When 'writelen' is exactly 1 byte less than the NAND page size the formula equates to zero, so the code doesn't process it as a partial write, although it should.
As a consequence the function remains in the while(1) loop with 'writelen' becoming 0xffffffff and iterating endlessly.
The bug may not be easy to reproduce in Linux since user space tools usually force the padding or round-up the write size to a page-size multiple.
This was discovered in U-Boot where the issue can be reproduced by writing any size that is 1 byte less than a page-size multiple. For example, on a NAND with 2K page (0x800):
=> nand erase.part <partition>
=> nand write $loadaddr <partition> 7ff
[Editor's note: the bug was added in commit 29072b96078f, but moved around in commit 66507c7bc8895 ("mtd: nand: Add support to use nand_base poi databuf as bounce buffer")]
--- drivers/mtd/nand/nand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/nand/nand_base.c +1 -1
@@ -2610,7 +2610,7 @@ static int nand_do_write_ops(struct mtd_int cached = writelen > bytes && page != blockmask;uint8_t *wbuf = buf;int use_bufpoi; -int part_pagewr = (column || writelen < (mtd->writesize -1 )); +int part_pagewr = (column || writelen < mtd->writesize);if (part_pagewr) use_bufpoi =1 ;
Greg Kroah-Hartman
maintainerPATCH 148/186 mm/hugetlb: avoid soft lockup in set_max_huge_pages()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jia He <[email protected]>
commit 649920c6ab93429b94bc7c1aa7c0e8395351be32 upstream.
In powerpc servers with large memory(32TB), we watched several soft lockups for hugepage under stress tests.
The call traces are as follows:
1.
get_page_from_freelist+0x2d8/0xd50 __alloc_pages_nodemask+0x180/0xc20 alloc_fresh_huge_page+0xb0/0x190 set_max_huge_pages+0x164/0x3b0
2.
prep_new_huge_page+0x5c/0x100 alloc_fresh_huge_page+0xc8/0x190 set_max_huge_pages+0x164/0x3b0
This patch fixes such soft lockups. It is safe to call cond_resched() there because it is out of spin_lock/unlock section.
--- mm/hugetlb.c | 4 ++++ 1 file changed, 4 insertions(+)
mm/hugetlb.c +4 -0
@@ -2214,6 +2214,10 @@ static unsigned long set_max_huge_pages(* and reducing the surplus. */ spin_unlock (&hugetlb_lock); + +/* yield cpu to avoid soft lockup */ +cond_resched (); +if (hstate_is_gigantic (h)) ret =alloc_fresh_gigantic_page (h, nodes_allowed);else
Greg Kroah-Hartman
maintainerPATCH 149/186 ALSA: hda: Fix krealloc() with __GFP_ZERO usage
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 33baefe5e72f17a6df378e48196cd8cada11deec upstream.
krealloc() doesn't work always properly with __GFP_ZERO flag as expected. For clearing the reallocated area, we need to clear explicitly instead.
--- sound/hda/array.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/hda/array.c +3 -1
@@ -21,13 +21,15 @@ void *snd_array_new(struct snd_array *arreturn NULL ;if (array->used >= array->alloced) {int num = array->alloced + array->alloc_align; +int oldsize = array->alloced * array->elem_size;int size = (num +1 ) * array->elem_size;void *nlist;if (snd_BUG_ON (num >=4096 ))return NULL ; - nlist =krealloc (array->list, size,GFP_KERNEL | __GFP_ZERO); + nlist =krealloc (array->list, size,GFP_KERNEL );if (!nlist)return NULL ; +memset (nlist + oldsize,0 , size - oldsize); array->list = nlist; array->alloced = num; }
Greg Kroah-Hartman
maintainerPATCH 150/186 ALSA: hda/realtek - Cant adjust speakers volume on a Dell AIO
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Wang <[email protected]>
commit dd9aa335c88003d131ac874e7f6809902de0b847 upstream.
We have a Dell AIO on which we can't adjust its speaker's volume. The problem is it is connected to a Audio Output node without Amp-out capability. To fix it, we change it to be connnected to a node with Amp-out capability.
--- sound/pci/hda/patch_realtek.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
sound/pci/hda/patch_realtek.c +22 -0
@@ -4674,6 +4674,22 @@ static void alc290_fixup_mono_speakers(s } } +static void alc298_fixup_speaker_volume (struct hda_codec *codec, +const struct hda_fixup *fix,int action) +{ +if (action ==HDA_FIXUP_ACT_PRE_PROBE ) { +/* The speaker is routed to the Node 0x06 by a mistake, as a result +we can't adjust the speaker's volume since this node does not has +Amp-out capability. we change the speaker's route to: +Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 ( +Pin Complex), since Node 0x02 has Amp-out caps, we can adjust +speaker's volume now. */ + +hda_nid_t conn1[1 ] = {0x0c }; +snd_hda_override_conn_list (codec,0x17 ,1 , conn1); + } +} +/* Hook to update amp GPIO4 for automute */ static void alc280_hp_gpio4_automute_hook (struct hda_codec *codec,struct hda_jack_callback *jack)
@@ -4823,6 +4839,7 @@ enum {ALC280_FIXUP_HP_HEADSET_MIC ,ALC221_FIXUP_HP_FRONT_MIC ,ALC292_FIXUP_TPT460 , + ALC298_FIXUP_SPK_VOLUME, }; static const struct hda_fixup alc269_fixups[] = {
@@ -5478,6 +5495,10 @@ static const struct hda_fixup alc269_fix .chained = true, .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE, }, + [ALC298_FIXUP_SPK_VOLUME] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc298_fixup_speaker_volume, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5524,6 +5545,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1028 ,0x0704 ,"Dell XPS 13 9350" ,ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE ),SND_PCI_QUIRK (0x1028 ,0x0725 ,"Dell Inspiron 3162" ,ALC255_FIXUP_DELL_SPK_NOISE ),SND_PCI_QUIRK (0x1028 ,0x075b ,"Dell XPS 13 9360" ,ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE ), +SND_PCI_QUIRK (0x1028 ,0x075d ,"Dell AIO" ,ALC298_FIXUP_SPK_VOLUME ),SND_PCI_QUIRK (0x1028 ,0x164a ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1028 ,0x164b ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Greg Kroah-Hartman
maintainerPATCH 151/186 ALSA: hda: add AMD Bonaire AZ PCI ID with proper driver caps
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maruthi Srinivas Bayyavarapu <[email protected]>
commit fd48331f9b71d2add941adaee3619f5b8527182d upstream.
This commit fixes garbled audio on Bonaire HDMI
--- sound/pci/hda/hda_intel.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/hda_intel.c +2 -0
@@ -2265,6 +2265,8 @@ static const struct pci_device_id azx_id { PCI_DEVICE(0x1022, 0x780d), .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, /* ATI HDMI */ + { PCI_DEVICE(0x1002, 0x0002), + .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, { PCI_DEVICE(0x1002, 0x1308), .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, { PCI_DEVICE(0x1002, 0x157a),
Greg Kroah-Hartman
maintainerPATCH 152/186 ALSA: hda - Fix headset mic detection problem for two dell machines
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Wang <[email protected]>
commit 59ec4b57bcaede46546d54d037a21004b9aa5cef upstream.
One of the machines has ALC255 on it, another one has ALC298 on it.
On the machine with the codec ALC298, it also has the speaker volume problem, so we add the fixup chained to ALC298_FIXUP_SPK_VOLUME rather than adding a group of pin definition in the pin quirk table, since the speak volume problem does not happen on other machines yet.
--- sound/pci/hda/patch_realtek.c | 6 ++++++ 1 file changed, 6 insertions(+)
sound/pci/hda/patch_realtek.c +6 -0
@@ -5498,6 +5498,8 @@ static const struct hda_fixup alc269_fix [ALC298_FIXUP_SPK_VOLUME ] = { .type =HDA_FIXUP_FUNC , .v.func = alc298_fixup_speaker_volume, + .chained = true, + .chain_id =ALC298_FIXUP_DELL1_MIC_NO_PRESENCE , }, };
@@ -5821,6 +5823,10 @@ static const struct snd_hda_pin_quirk al {0x1b, 0x01014020}, {0x21, 0x0221103f}),SND_HDA_PIN_QUIRK (0x10ec0255 ,0x1028 ,"Dell" ,ALC255_FIXUP_DELL1_MIC_NO_PRESENCE , + {0x14, 0x90170130}, + {0x1b, 0x02011020}, + {0x21, 0x0221103f}), +SND_HDA_PIN_QUIRK (0x10ec0255 ,0x1028 ,"Dell" ,ALC255_FIXUP_DELL1_MIC_NO_PRESENCE , {0x14, 0x90170150}, {0x1b, 0x02011020}, {0x21, 0x0221105f}),
Greg Kroah-Hartman
maintainerPATCH 153/186 IB/mlx5: Fix iteration overrun in GSI qps
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Slava Shwartsman <[email protected]>
commit b0ffeb537f3a726931d962ab6d03e34a2f070ea4 upstream.
Number of outstanding_pi may overflow and as a result may indicate that there are no elements in the queue. The effect of doing this is that the MAD layer will get stuck waiting for completions. The MAD layer will think that the QP is full - because it didn't receive these completions.
This fix changes it so the outstanding_pi number is increased with 32-bit wraparound and is not limited to max_send_wr so that the difference between outstanding_pi and outstanding_ci will really indicate the number of outstanding completions.
--- drivers/infiniband/hw/mlx5/gsi.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-)
drivers/infiniband/hw/mlx5/gsi.c +6 -13
@@ -69,15 +69,6 @@ static bool mlx5_ib_deth_sqpn_cap(structreturn MLX5_CAP_GEN (dev->mdev, set_deth_sqpn); } -static u32 next_outstanding (struct mlx5_ib_gsi_qp *gsi,u32 index) -{ -return ++index % gsi->cap.max_send_wr; -} - -#define for_each_outstanding_wr (gsi, index) \ - for (index = gsi->outstanding_ci; index != gsi->outstanding_pi; \ - index = next_outstanding(gsi, index)) -/* Call with gsi->lock locked */ static void generate_completions (struct mlx5_ib_gsi_qp *gsi) {
@@ -85,8 +76,9 @@ static void generate_completions(structstruct mlx5_ib_gsi_wr *wr;u32 index; -for_each_outstanding_wr (gsi, index) { - wr = &gsi->outstanding_wrs[index]; +for (index = gsi->outstanding_ci; index != gsi->outstanding_pi; + index++) { + wr = &gsi->outstanding_wrs[index % gsi->cap.max_send_wr];if (!wr->completed)break ;
@@ -430,8 +422,9 @@ static int mlx5_ib_add_outstanding_wr(streturn -ENOMEM ; } - gsi_wr = &gsi->outstanding_wrs[gsi->outstanding_pi]; - gsi->outstanding_pi =next_outstanding (gsi, gsi->outstanding_pi); + gsi_wr = &gsi->outstanding_wrs[gsi->outstanding_pi % + gsi->cap.max_send_wr]; + gsi->outstanding_pi++;if (!wc) {memset (&gsi_wr->wc,0 ,sizeof (gsi_wr->wc));
Greg Kroah-Hartman
maintainerPATCH 154/186 IB/mlx5: Fix MODIFY_QP command input structure
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artemy Kovalyov <[email protected]>
commit e3353c268b06236d6c40fa1714c114f21f44451c upstream.
Make MODIFY_QP command input structure compliant to specification
--- include/linux/mlx5/qp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/mlx5/qp.h +2 -2
@@ -556,9 +556,9 @@ struct mlx5_destroy_qp_mbox_out {struct mlx5_modify_qp_mbox_in {struct mlx5_inbox_hdr hdr;__be32 qpn; -u8 rsvd1[4 ]; -__be32 optparam;u8 rsvd0[4 ]; +__be32 optparam; +u8 rsvd1[4 ];struct mlx5_qp_context ctx;u8 rsvd2[16 ]; };
Greg Kroah-Hartman
maintainerPATCH 155/186 IB/rdmavt: Disable by default
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 378fc3201eae07ab0fa7fb4133da141c3072f995 upstream.
There is a strict policy in the Linux kernel that new drivers must be disabled by default. Hence leave out the "default m" line from Kconfig.
--- drivers/infiniband/sw/rdmavt/Kconfig | 1 - 1 file changed, 1 deletion(-)
drivers/infiniband/sw/rdmavt/Kconfig +0 -1
@@ -1,6 +1,5 @@ config INFINIBAND_RDMAVT tristate "RDMA verbs transport library" depends on 64BIT - default m ---help--- This is a common software verbs provider for RDMA networks.
Greg Kroah-Hartman
maintainerPATCH 156/186 IB/rdmavt: Add missing spin_lock_init call for rdi->n_cqs_lock
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianxin Xiong <[email protected]>
commit a6580f4310ded039fc9f682cbf027fbba217652b upstream.
This fixes the following warning with PROV_LOCKING enabled kernel:
INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
CPU: 15 PID: 12286 Comm: modprobe Not tainted 4.7.0-rc5.prove_rcu+ #1 Hardware name: Intel Corporation S2600WT2R/S2600WT2R, ...... Call Trace: [<ffffffff8139ec0d>] dump_stack+0x85/0xc8 [<ffffffff810eb765>] register_lock_class+0x415/0x4b0 [<ffffffff810ede1c>] ? __lock_acquire+0x40c/0x1960 [<ffffffff810edaa9>] __lock_acquire+0x99/0x1960 [<ffffffff8120ab62>] ? find_vmap_area+0x42/0x60 [<ffffffff8120ab39>] ? find_vmap_area+0x19/0x60 [<ffffffff810ef9d3>] lock_acquire+0xd3/0x200 [<ffffffffa049d598>] ? rvt_create_cq+0xc8/0x250 [rdmavt] [<ffffffff81763391>] _raw_spin_lock+0x31/0x40 [<ffffffffa049d598>] ? rvt_create_cq+0xc8/0x250 [rdmavt] [<ffffffffa049d598>] rvt_create_cq+0xc8/0x250 [rdmavt] [<ffffffff810ead46>] ? static_obj+0x36/0x50 [<ffffffffa0469e39>] ib_alloc_cq+0x49/0x180 [ib_core] [<ffffffffa047bed4>] ib_mad_init_device+0x204/0x6d0 [ib_core] [<ffffffff810e968f>] ? up_write+0x1f/0x40 [<ffffffffa046e2c0>] ib_register_device+0x3d0/0x510 [ib_core] [<ffffffffa0752410>] ? read_cc_setting_bin+0x200/0x200 [hfi1] [<ffffffff810ead46>] ? static_obj+0x36/0x50 [<ffffffff810eb888>] ? lockdep_init_map+0x88/0x200 [<ffffffffa049cbff>] rvt_register_device+0x17f/0x320 [rdmavt] [<ffffffffa0766caa>] hfi1_register_ib_device+0x6ca/0x7c0 [hfi1] [<ffffffffa0733de4>] init_one+0x2b4/0x430 [hfi1] [<ffffffff813e40a5>] local_pci_probe+0x45/0xa0 [<ffffffff813e5110>] ? pci_match_device+0xe0/0x110 [<ffffffff813e550c>] pci_device_probe+0xfc/0x140 [<ffffffff814daee9>] driver_probe_device+0x239/0x460 [<ffffffff814db1dd>] __driver_attach+0xcd/0xf0 [<ffffffff814db110>] ? driver_probe_device+0x460/0x460 [<ffffffff814d89b3>] bus_for_each_dev+0x73/0xc0 [<ffffffff814da74e>] driver_attach+0x1e/0x20 [<ffffffff814da1b3>] bus_add_driver+0x1d3/0x290 [<ffffffffa04cc114>] ? dev_init+0x114/0x114 [hfi1] [<ffffffff814dbf60>] driver_register+0x60/0xe0 [<ffffffffa04cc114>] ? dev_init+0x114/0x114 [hfi1] [<ffffffff813e39d0>] __pci_register_driver+0x60/0x70 [<ffffffffa04cc2aa>] hfi1_mod_init+0x196/0x1fe [hfi1] [<ffffffff81002190>] do_one_initcall+0x50/0x190 [<ffffffff8110be72>] ? rcu_read_lock_sched_held+0x62/0x70 [<ffffffff8122d4aa>] ? kmem_cache_alloc_trace+0x23a/0x2a0 [<ffffffff811c1881>] ? do_init_module+0x27/0x1dc [<ffffffff811c18ba>] do_init_module+0x60/0x1dc [<ffffffff811360cc>] load_module+0x132c/0x1ac0 [<ffffffff81132c40>] ? __symbol_put+0x60/0x60 [<ffffffff8133e50d>] ? ima_post_read_file+0x3d/0x80
--- drivers/infiniband/sw/rdmavt/cq.c | 1 + 1 file changed, 1 insertion(+)
drivers/infiniband/sw/rdmavt/cq.c +1 -0
@@ -510,6 +510,7 @@ int rvt_driver_cq_init(struct rvt_dev_inif (rdi->worker)return 0 ; +spin_lock_init (&rdi->n_cqs_lock); rdi->worker =kzalloc (sizeof (*rdi->worker),GFP_KERNEL );if (!rdi->worker)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 157/186 IB/srpt: Limit the number of SG elements per work request
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 30c6d8773de06878f920666d8c945f81cb2081b3 upstream.
Limit the number of SG elements per work request to what the HCA and the queue pair support.
--- drivers/infiniband/ulp/srpt/ib_srpt.c | 3 ++- drivers/infiniband/ulp/srpt/ib_srpt.h | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-)
drivers/infiniband/ulp/srpt/ib_srpt.c +2 -1
@@ -1601,6 +1601,7 @@ static int srpt_create_ch_ib(struct srptstruct ib_qp_init_attr *qp_init;struct srpt_port *sport = ch->sport;struct srpt_device *sdev = sport->sdev; +const struct ib_device_attr *attrs = &sdev->device->attrs;u32 srp_sq_size = sport->port_attrib.srp_sq_size;int ret;
@@ -1638,7 +1639,7 @@ retry:*/ qp_init->cap.max_send_wr = srp_sq_size /2 ; qp_init->cap.max_rdma_ctxs = srp_sq_size /2 ; - qp_init->cap.max_send_sge =SRPT_DEF_SG_PER_WQE ; + qp_init->cap.max_send_sge =min (attrs->max_sge,SRPT_MAX_SG_PER_WQE ); qp_init->port_num = ch->sport->port; ch->qp =ib_create_qp (sdev->pd, qp_init);
drivers/infiniband/ulp/srpt/ib_srpt.h +5 -1
@@ -106,7 +106,11 @@ enum {SRP_LOGIN_RSP_MULTICHAN_MAINTAINED =0x2 ,SRPT_DEF_SG_TABLESIZE =128 , -SRPT_DEF_SG_PER_WQE =16 , +/* +* An experimentally determined value that avoids that QP creation +* fails due to "swiotlb buffer is full" on systems using the swiotlb. +*/ +SRPT_MAX_SG_PER_WQE =16 ,MIN_SRPT_SQ_SIZE =16 , DEF_SRPT_SQ_SIZE = 4096,
Greg Kroah-Hartman
maintainerPATCH 158/186 IB/core: Make rdma_rw_ctx_init() initialize all used fields
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit eaa74ec7329a48a4b724d8de440b3a2cbaabf7c8 upstream.
Some but not all callers of rdma_rw_ctx_init() zero-initialize struct rdma_rw_ctx. Hence make rdma_rw_ctx_init() initialize all work request fields that will be read by ib_post_send().
--- drivers/infiniband/core/rw.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/infiniband/core/rw.c +9 -5
@@ -71,6 +71,7 @@ static inline u32 rdma_rw_fr_page_list_lreturn min_t (u32, dev->attrs.max_fast_reg_page_list_len,256 ); } +/* Caller must have zero-initialized *reg. */ static int rdma_rw_init_one_mr (struct ib_qp *qp,u8 port_num,struct rdma_rw_reg_ctx *reg,struct scatterlist *sg,u32 sg_cnt,u32 offset)
@@ -114,6 +115,7 @@ static int rdma_rw_init_mr_wrs(struct rd u8 port_num, struct scatterlist *sg, u32 sg_cnt, u32 offset, u64 remote_addr, u32 rkey, enum dma_data_direction dir) { + struct rdma_rw_reg_ctx *prev = NULL;u32 pages_per_mr =rdma_rw_fr_page_list_len (qp->pd->device);int i, j, ret =0 , count =0 ;
@@ -125,7 +127,6 @@ static int rdma_rw_init_mr_wrs(struct rd }for (i =0 ; i < ctx->nr_ops; i++) { -struct rdma_rw_reg_ctx *prev = i ? &ctx->reg[i -1 ] :NULL ;struct rdma_rw_reg_ctx *reg = &ctx->reg[i];u32 nents =min (sg_cnt, pages_per_mr);
@@ -162,9 +163,13 @@ static int rdma_rw_init_mr_wrs(struct rd sg_cnt -= nents;for (j =0 ; j < nents; j++) sg =sg_next (sg); + prev = reg; offset =0 ; } +if (prev) + prev->wr.wr.next =NULL ; + ctx->type =RDMA_RW_MR ;return count;
@@ -205,11 +210,10 @@ static int rdma_rw_init_map_wrs(struct r rdma_wr->wr.opcode =IB_WR_RDMA_READ ; rdma_wr->remote_addr = remote_addr + total_len; rdma_wr->rkey = rkey; + rdma_wr->wr.num_sge = nr_sge; rdma_wr->wr.sg_list = sge;for (j =0 ; j < nr_sge; j++, sg =sg_next (sg)) { - rdma_wr->wr.num_sge++; - sge->addr =ib_sg_dma_address (dev, sg) + offset; sge->length =ib_sg_dma_len (dev, sg) - offset; sge->lkey = qp->pd->local_dma_lkey;
@@ -220,8 +224,8 @@ static int rdma_rw_init_map_wrs(struct r offset =0 ; } -if (i +1 < ctx->nr_ops) - rdma_wr->wr.next = &ctx->map.wrs[i +1 ].wr; + rdma_wr->wr.next = i +1 < ctx->nr_ops ? + &ctx->map.wrs[i +1 ].wr :NULL ; } ctx->type =RDMA_RW_MULTI_WR ;
Greg Kroah-Hartman
maintainerPATCH 159/186 IB/core, RDMA RW API: Do not exceed QP SGE send limit
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 632bc3f65081dd1e2e5394a9161580a0f78e8839 upstream.
Compute the SGE limit for RDMA READ and WRITE requests in ib_create_qp(). Use that limit in the RDMA RW API implementation.
--- drivers/infiniband/core/rw.c | 10 ++-------- drivers/infiniband/core/verbs.c | 9 +++++++++ include/rdma/ib_verbs.h | 6 ++++++ 3 files changed, 17 insertions(+), 8 deletions(-)
drivers/infiniband/core/rw.c +2 -8
@@ -58,13 +58,6 @@ static inline bool rdma_rw_io_needs_mr(sreturn false; } -static inline u32 rdma_rw_max_sge (struct ib_device *dev, -enum dma_data_direction dir) -{ -return dir ==DMA_TO_DEVICE ? - dev->attrs.max_sge : dev->attrs.max_sge_rd; -} -static inline u32 rdma_rw_fr_page_list_len (struct ib_device *dev) {/* arbitrary limit to avoid allocating gigantic resources */
@@ -186,7 +179,8 @@ static int rdma_rw_init_map_wrs(struct r u64 remote_addr, u32 rkey, enum dma_data_direction dir) { struct ib_device *dev = qp->pd->device; -u32 max_sge =rdma_rw_max_sge (dev, dir); +u32 max_sge = dir ==DMA_TO_DEVICE ? qp->max_write_sge : + qp->max_read_sge;struct ib_sge *sge;u32 total_len =0 , i, j;
drivers/infiniband/core/verbs.c +9 -0
@@ -814,6 +814,15 @@ struct ib_qp *ib_create_qp(struct ib_pd } } +/* +* Note: all hw drivers guarantee that max_send_sge is lower than +* the device RDMA WRITE SGE limit but not all hw drivers ensure that +* max_send_sge <= max_sge_rd. +*/ + qp->max_write_sge = qp_init_attr->cap.max_send_sge; + qp->max_read_sge =min_t (u32, qp_init_attr->cap.max_send_sge, + device->attrs.max_sge_rd); +return qp; }EXPORT_SYMBOL (ib_create_qp);
include/rdma/ib_verbs.h +6 -0
@@ -1428,6 +1428,10 @@ struct ib_srq { } ext; }; +/* +* @max_write_sge: Maximum SGE elements per RDMA WRITE request. +* @max_read_sge: Maximum SGE elements per RDMA READ request. +*/ struct ib_qp {struct ib_device *device;struct ib_pd *pd;
@@ -1449,6 +1453,8 @@ struct ib_qp {void (*event_handler)(struct ib_event *,void *);void *qp_context;u32 qp_num; +u32 max_write_sge; +u32 max_read_sge;enum ib_qp_type qp_type; };
Greg Kroah-Hartman
maintainerPATCH 160/186 of: fix memory leak related to safe_name()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Rowand <[email protected]>
commit d9fc880723321dbf16b2981e3f3e916b73942210 upstream.
Fix a memory leak resulting from memory allocation in safe_name(). This patch fixes all call sites of safe_name().
Mathieu Malaterre reported the memory leak on boot:
On my PowerMac device-tree would generate a duplicate name:
[ 0.023043] device-tree: Duplicate name in PowerPC,G4@0, renamed to "l2-cache#1"
in this case a newly allocated name is generated by safe_name. However in this case it is never deallocated.
The bug was found using kmemleak reported as:
unreferenced object 0xdf532e60 (size 32):
comm "swapper", pid 1, jiffies 4294892300 (age 1993.532s) hex dump (first 32 bytes):
6c 32 2d 63 61 63 68 65 23 31 00 dd e4 dd 1e c2 l2-cache#1......
ec d4 ba ce 04 ec cc de 8e 85 e9 ca c4 ec cc 9e ................
backtrace:
[<c02d3350>] kvasprintf+0x64/0xc8
[<c02d3400>] kasprintf+0x4c/0x5c
[<c0453814>] safe_name.isra.1+0x80/0xc4
[<c04545d8>] __of_attach_node_sysfs+0x6c/0x11c
[<c075f21c>] of_core_init+0x8c/0xf8
[<c0729594>] kernel_init_freeable+0xd4/0x208
[<c00047e8>] kernel_init+0x24/0x11c
[<c00158ec>] ret_from_kernel_thread+0x5c/0x64--- drivers/of/base.c | 30 +++++++++++++++++++++--------- drivers/of/dynamic.c | 2 +- drivers/of/of_private.h | 3 +++ 3 files changed, 25 insertions(+), 10 deletions(-)
drivers/of/base.c +21 -9
@@ -112,6 +112,7 @@ static ssize_t of_node_property_read(strreturn memory_read_from_buffer (buf, count, &offset, pp->value, pp->length); } +/* always return newly allocated name, caller must free after use */ static const char *safe_name (struct kobject *kobj,const char *orig_name) {const char *name = orig_name;
@@ -126,9 +127,12 @@ static const char *safe_name(struct kobj name =kasprintf (GFP_KERNEL ,"%s#%i" , orig_name, ++i); } -if (name != orig_name) +if (name == orig_name) { + name =kstrdup (orig_name,GFP_KERNEL ); + }else {pr_warn ("device-tree: Duplicate name in %s, renamed to \"%s\"\n" ,kobject_name (kobj), name); + }return name; }
@@ -159,6 +163,7 @@ int __of_add_property_sysfs(struct devicint __of_attach_node_sysfs (struct device_node *np) {const char *name; +struct kobject *parent;struct property *pp;int rc;
@@ -171,15 +176,16 @@ int __of_attach_node_sysfs(struct device np->kobj.kset = of_kset;if (!np->parent) {/* Nodes without parents are new top level trees */ - rc =kobject_add (&np->kobj,NULL ,"%s" , -safe_name (&of_kset->kobj,"base" )); + name =safe_name (&of_kset->kobj,"base" ); + parent =NULL ; }else { name =safe_name (&np->parent->kobj,kbasename (np->full_name)); -if (!name || !name[0 ]) -return -EINVAL ; - - rc =kobject_add (&np->kobj, &np->parent->kobj,"%s" , name); + parent = &np->parent->kobj; } +if (!name) +return -ENOMEM ; + rc =kobject_add (&np->kobj, parent,"%s" , name); +kfree (name);if (rc)return rc;
@@ -1815,6 +1821,12 @@ int __of_remove_property(struct device_nreturn 0 ; } +void __of_sysfs_remove_bin_file (struct device_node *np,struct property *prop) +{ +sysfs_remove_bin_file (&np->kobj, &prop->attr); +kfree (prop->attr.attr.name); +} +void __of_remove_property_sysfs (struct device_node *np,struct property *prop) {if (!IS_ENABLED (CONFIG_SYSFS ))
@@ -1822,7 +1834,7 @@ void __of_remove_property_sysfs(struct d/* at early boot, bail here and defer setup to of_init() */ if (of_kset &&of_node_is_attached (np)) -sysfs_remove_bin_file (&np->kobj, &prop->attr); +__of_sysfs_remove_bin_file (np, prop); }/**
@@ -1895,7 +1907,7 @@ void __of_update_property_sysfs(struct dreturn ;if (oldprop) -sysfs_remove_bin_file (&np->kobj, &oldprop->attr); +__of_sysfs_remove_bin_file (np, oldprop);__of_add_property_sysfs (np, newprop); }
drivers/of/dynamic.c +1 -1
@@ -55,7 +55,7 @@ void __of_detach_node_sysfs(struct devic/* only remove properties if on sysfs */ if (of_node_is_attached (np)) {for_each_property_of_node (np, pp) -sysfs_remove_bin_file (&np->kobj, &pp->attr); +__of_sysfs_remove_bin_file (np, pp);kobject_del (&np->kobj); }
drivers/of/of_private.h +3 -0
@@ -83,6 +83,9 @@ extern int __of_attach_node_sysfs(structextern void __of_detach_node (struct device_node *np);extern void __of_detach_node_sysfs (struct device_node *np); +extern void __of_sysfs_remove_bin_file (struct device_node *np, +struct property *prop); +/* iterators for transactions, used for overlays */ /* forward iterator */ #define for_each_transaction_entry (_oft, _te) \
Greg Kroah-Hartman
maintainerPATCH 161/186 ubi: Make volume resize power cut aware
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <[email protected]>
commit 4946784bd3924b1374f05eebff2fd68660bae866 upstream.
When the volume resize operation shrinks a volume, LEBs will be unmapped. Since unmapping will not erase these LEBs immediately we have to wait for that operation to finish. Otherwise in case of a power cut right after writing the new volume table the UBI attach process can find more LEBs than the volume table knows. This will render the UBI image unattachable.
Fix this issue by waiting for erase to complete and write the new volume table afterward.
--- drivers/mtd/ubi/vmt.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
drivers/mtd/ubi/vmt.c +18 -7
@@ -488,13 +488,6 @@ int ubi_resize_volume(struct ubi_volume_spin_unlock (&ubi->volumes_lock); } -/* Change volume table record */ - vtbl_rec = ubi->vtbl[vol_id]; - vtbl_rec.reserved_pebs =cpu_to_be32 (reserved_pebs); - err =ubi_change_vtbl_record (ubi, vol_id, &vtbl_rec); -if (err) - goto out_acc; -if (pebs <0 ) {for (i =0 ; i < -pebs; i++) { err =ubi_eba_unmap_leb (ubi, vol, reserved_pebs + i);
@@ -512,6 +505,24 @@ int ubi_resize_volume(struct ubi_volume_spin_unlock (&ubi->volumes_lock); } +/* +* When we shrink a volume we have to flush all pending (erase) work. +* Otherwise it can happen that upon next attach UBI finds a LEB with +* lnum > highest_lnum and refuses to attach. +*/ +if (pebs <0 ) { + err =ubi_wl_flush (ubi, vol_id,UBI_ALL ); +if (err) + goto out_acc; + } + +/* Change volume table record */ + vtbl_rec = ubi->vtbl[vol_id]; + vtbl_rec.reserved_pebs =cpu_to_be32 (reserved_pebs); + err =ubi_change_vtbl_record (ubi, vol_id, &vtbl_rec); +if (err) + goto out_acc; + vol->reserved_pebs = reserved_pebs;if (vol->vol_type ==UBI_DYNAMIC_VOLUME ) { vol->used_ebs = reserved_pebs;
Greg Kroah-Hartman
maintainerPATCH 162/186 ubi: Fix early logging
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <[email protected]>
commit bc743f34dfa011e62edd0ea4ae8455be06c083b5 upstream.
We cannot use ubi_* logging functions before the UBI object is initialized.
--- drivers/mtd/ubi/build.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mtd/ubi/build.c +4 -4
@@ -874,7 +874,7 @@ int ubi_attach_mtd_dev(struct mtd_info *for (i =0 ; i <UBI_MAX_DEVICES ; i++) { ubi = ubi_devices[i];if (ubi && mtd->index == ubi->mtd->index) { -ubi_err (ubi,"mtd%d is already attached to ubi%d" , +pr_err ("ubi: mtd%d is already attached to ubi%d" , mtd->index, i);return -EEXIST ; }
@@ -889,7 +889,7 @@ int ubi_attach_mtd_dev(struct mtd_info ** no sense to attach emulated MTD devices, so we prohibit this. */ if (mtd->type ==MTD_UBIVOLUME ) { -ubi_err (ubi,"refuse attaching mtd%d - it is already emulated on top of UBI" , +pr_err ("ubi: refuse attaching mtd%d - it is already emulated on top of UBI" , mtd->index);return -EINVAL ; }
@@ -900,7 +900,7 @@ int ubi_attach_mtd_dev(struct mtd_info *if (!ubi_devices[ubi_num])break ;if (ubi_num ==UBI_MAX_DEVICES ) { -ubi_err (ubi,"only %d UBI devices may be created" , +pr_err ("ubi: only %d UBI devices may be created" ,UBI_MAX_DEVICES );return -ENFILE ; }
@@ -910,7 +910,7 @@ int ubi_attach_mtd_dev(struct mtd_info */* Make sure ubi_num is not busy */ if (ubi_devices[ubi_num]) { -ubi_err (ubi,"already exists" ); +pr_err ("ubi: ubi%i already exists" , ubi_num);return -EEXIST ; } }
Greg Kroah-Hartman
maintainerPATCH 163/186 ubi: Fix race condition between ubi device creation and udev
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Iosif Harutyunov <[email protected]>
commit 714fb87e8bc05ff78255afc0dca981e8c5242785 upstream.
Install the UBI device object before we arm sysfs. Otherwise udev tries to read sysfs attributes before UBI is ready and udev rules will not match.
--- drivers/mtd/ubi/build.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mtd/ubi/build.c +4 -1
@@ -992,6 +992,9 @@ int ubi_attach_mtd_dev(struct mtd_info * goto out_detach; } +/* Make device "available" before it becomes accessible via sysfs */ + ubi_devices[ubi_num] = ubi; + err =uif_init (ubi, &ref);if (err) goto out_detach;
@@ -1036,7 +1039,6 @@ int ubi_attach_mtd_dev(struct mtd_info *wake_up_process (ubi->bgt_thread);spin_unlock (&ubi->wl_lock); - ubi_devices[ubi_num] = ubi;ubi_notify_all (ubi,UBI_VOLUME_ADDED ,NULL );return ubi_num;
@@ -1047,6 +1049,7 @@ out_uif:ubi_assert (ref);uif_close (ubi); out_detach: + ubi_devices[ubi_num] =NULL ;ubi_wl_close (ubi);ubi_free_internal_volumes (ubi);vfree (ubi->vtbl);
Greg Kroah-Hartman
maintainerPATCH 164/186 iscsi-target: Fix panic when adding second TCP connection to iSCSI session
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Feng Li <[email protected]>
commit 8abc718de6e9e52d8a6bfdb735060554aeae25e4 upstream.
In MC/S scenario, the conn->sess has been set NULL in iscsi_login_non_zero_tsih_s1 when the second connection comes here, then kernel panic.
The conn->sess will be assigned in iscsi_login_non_zero_tsih_s2. So we should check whether it's NULL before calling.
--- drivers/target/iscsi/iscsi_target_login.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/target/iscsi/iscsi_target_login.c +3 -2
@@ -1371,8 +1371,9 @@ static int __iscsi_target_login_thread(s } login->zero_tsih = zero_tsih; - conn->sess->se_sess->sup_prot_ops = - conn->conn_transport->iscsit_get_sup_prot_ops (conn); +if (conn->sess) + conn->sess->se_sess->sup_prot_ops = + conn->conn_transport->iscsit_get_sup_prot_ops (conn); tpg = conn->tpg;if (!tpg) {
Greg Kroah-Hartman
maintainerPATCH 165/186 target: Fix ordered task target_setup_cmd_from_cdb exception hang
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger <[email protected]>
commit dff0ca9ea7dc8be2181a62df4a722c32ce68ff4a upstream.
If a command with a Simple task attribute is failed due to a Unit Attention, then a subsequent command with an Ordered task attribute will hang forever. The reason for this is that the Unit Attention status is checked for in target_setup_cmd_from_cdb, before the call to target_execute_cmd, which calls target_handle_task_attr, which in turn increments dev->simple_cmds.
However, transport_generic_request_failure still calls transport_complete_task_attr, which will decrement dev->simple_cmds. In this case, simple_cmds is now -1. So when a command with the Ordered task attribute is sent, target_handle_task_attr sees that dev->simple_cmds is not 0, so it decides it can't execute the command until all the (nonexistent) Simple commands have completed.
--- drivers/target/target_core_internal.h | 1 drivers/target/target_core_sbc.c | 2 - drivers/target/target_core_transport.c | 62 ++++++++++++++++++--------------- include/target/target_core_fabric.h | 1 4 files changed, 37 insertions(+), 29 deletions(-)
drivers/target/target_core_internal.h +1 -0
@@ -146,6 +146,7 @@ sense_reason_t target_cmd_size_check(strvoid target_qf_do_work (struct work_struct *work);bool target_check_wce (struct se_device *dev);bool target_check_fua (struct se_device *dev); +void __target_execute_cmd (struct se_cmd *,bool );/* target_core_stat.c */ void target_stat_setup_dev_default_groups (struct se_device *);
drivers/target/target_core_sbc.c +1 -1
@@ -602,7 +602,7 @@ static sense_reason_t compare_and_write_ cmd->transport_state |=CMD_T_ACTIVE |CMD_T_BUSY |CMD_T_SENT ;spin_unlock_irq (&cmd->t_state_lock); -__target_execute_cmd (cmd); +__target_execute_cmd (cmd, false);kfree (buf);return ret;
drivers/target/target_core_transport.c +35 -27
92 lines not on this page · raw message
include/target/target_core_fabric.h +0 -1
@@ -163,7 +163,6 @@ int core_tmr_alloc_req(struct se_cmd *,void core_tmr_release_req (struct se_tmr_req *);int transport_generic_handle_tmr (struct se_cmd *);void transport_generic_request_failure (struct se_cmd *,sense_reason_t ); -void __target_execute_cmd (struct se_cmd *);int transport_lookup_tmr_lun (struct se_cmd *,u64 );void core_allocate_nexus_loss_ua (struct se_node_acl *acl);
Greg Kroah-Hartman
maintainerPATCH 166/186 target: Fix missing complete during ABORT_TASK + CMD_T_FABRIC_STOP
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger <[email protected]>
commit 5e2c956b8aa24d4f33ff7afef92d409eed164746 upstream.
During transport_generic_free_cmd() with a concurrent TMR ABORT_TASK and shutdown CMD_T_FABRIC_STOP bit set, the caller will be blocked on se_cmd->cmd_wait_stop completion until the final kref_put() -> target_release_cmd_kref() has been invoked to call complete().
However, when ABORT_TASK is completed with FUNCTION_COMPLETE in core_tmr_abort_task(), the aborted se_cmd will have already been removed from se_sess->sess_cmd_list via list_del_init().
This results in target_release_cmd_kref() hitting the legacy list_empty() == true check, invoking ->release_cmd() but skipping complete() to wakeup se_cmd->cmd_wait_stop blocked earlier in transport_generic_free_cmd() code.
To address this bug, it's safe to go ahead and drop the original list_empty() check so that fabric_stop invokes the complete() as expected, since list_del_init() can safely be used on a empty list.
--- drivers/target/target_core_transport.c | 6 ------ 1 file changed, 6 deletions(-)
drivers/target/target_core_transport.c +0 -6
@@ -2565,12 +2565,6 @@ static void target_release_cmd_kref(strubool fabric_stop;spin_lock_irqsave (&se_sess->sess_cmd_lock, flags); -if (list_empty (&se_cmd->se_cmd_list)) { -spin_unlock_irqrestore (&se_sess->sess_cmd_lock, flags); -target_free_cmd_mem (se_cmd); - se_cmd->se_tfo->release_cmd (se_cmd); -return ; - }spin_lock (&se_cmd->t_state_lock); fabric_stop = (se_cmd->transport_state &CMD_T_FABRIC_STOP );
Greg Kroah-Hartman
maintainerPATCH 167/186 target: Fix race between iscsi-target connection shutdown + ABORT_TASK
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger <[email protected]>
commit 064cdd2d91c2805d788876082f31cc63506f22c3 upstream.
This patch fixes a race in iscsit_release_commands_from_conn() -> iscsit_free_cmd() -> transport_generic_free_cmd() + wait_for_tasks=1, where CMD_T_FABRIC_STOP could end up being set after the final kref_put() is called from core_tmr_abort_task() context.
This results in transport_generic_free_cmd() blocking indefinately on se_cmd->cmd_wait_comp, because the target_release_cmd_kref() check for CMD_T_FABRIC_STOP returns false.
To address this bug, make iscsit_release_commands_from_conn() do list_splice and set CMD_T_FABRIC_STOP early while holding iscsi_conn->cmd_lock. Also make iscsit_aborted_task() only remove iscsi_cmd_t if CMD_T_FABRIC_STOP has not already been set.
Finally in target_release_cmd_kref(), only honor fabric_stop if CMD_T_ABORTED has been set.
--- drivers/target/iscsi/iscsi_target.c | 22 ++++++++++++++++------ drivers/target/target_core_transport.c | 3 ++- 2 files changed, 18 insertions(+), 7 deletions(-)
drivers/target/iscsi/iscsi_target.c +16 -6
@@ -492,7 +492,8 @@ void iscsit_aborted_task(struct iscsi_cobool scsi_cmd = (cmd->iscsi_opcode ==ISCSI_OP_SCSI_CMD );spin_lock_bh (&conn->cmd_lock); -if (!list_empty (&cmd->i_conn_node)) +if (!list_empty (&cmd->i_conn_node) && + !(cmd->se_cmd.transport_state &CMD_T_FABRIC_STOP ))list_del_init (&cmd->i_conn_node);spin_unlock_bh (&conn->cmd_lock);
@@ -4034,6 +4035,7 @@ int iscsi_target_rx_thread(void *arg)static void iscsit_release_commands_from_conn (struct iscsi_conn *conn) { +LIST_HEAD (tmp_list);struct iscsi_cmd *cmd =NULL , *cmd_tmp =NULL ;struct iscsi_session *sess = conn->sess;/*
@@ -4042,18 +4044,26 @@ static void iscsit_release_commands_from* has been reset -> returned sleeping pre-handler state. */ spin_lock_bh (&conn->cmd_lock); -list_for_each_entry_safe (cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { +list_splice_init (&conn->conn_cmd_list, &tmp_list); +list_for_each_entry (cmd, &tmp_list, i_conn_node) { +struct se_cmd *se_cmd = &cmd->se_cmd; + +if (se_cmd->se_tfo !=NULL ) { +spin_lock (&se_cmd->t_state_lock); + se_cmd->transport_state |=CMD_T_FABRIC_STOP ; +spin_unlock (&se_cmd->t_state_lock); + } + } +spin_unlock_bh (&conn->cmd_lock); + +list_for_each_entry_safe (cmd, cmd_tmp, &tmp_list, i_conn_node) {list_del_init (&cmd->i_conn_node); -spin_unlock_bh (&conn->cmd_lock);iscsit_increment_maxcmdsn (cmd, sess); -iscsit_free_cmd (cmd, true); -spin_lock_bh (&conn->cmd_lock); } -spin_unlock_bh (&conn->cmd_lock); } static void iscsit_stop_timers_for_cmds(
drivers/target/target_core_transport.c +2 -1
@@ -2567,7 +2567,8 @@ static void target_release_cmd_kref(struspin_lock_irqsave (&se_sess->sess_cmd_lock, flags);spin_lock (&se_cmd->t_state_lock); - fabric_stop = (se_cmd->transport_state &CMD_T_FABRIC_STOP ); + fabric_stop = (se_cmd->transport_state &CMD_T_FABRIC_STOP ) && + (se_cmd->transport_state &CMD_T_ABORTED );spin_unlock (&se_cmd->t_state_lock);if (se_cmd->cmd_wait_set || fabric_stop) {
Greg Kroah-Hartman
maintainerPATCH 168/186 target: Fix max_unmap_lba_count calc overflow
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Christie <[email protected]>
commit ea263c7fada4af8ec7fe5fcfd6e7d7705a89351b upstream.
max_discard_sectors only 32bits, and some non scsi backend devices will set this to the max 0xffffffff, so we can end up overflowing during the max_unmap_lba_count calculation.
This fixes a regression caused by my patch:
commit 8a9ebe717a133ba7bc90b06047f43cc6b8bcb8b3
Author: Mike Christie <[email protected]> Date: Mon Jan 18 14:09:27 2016 -0600
target: Fix WRITE_SAME/DISCARD conversion to linux 512b sectors
which can result in extra discards being sent to due the overflow causing max_unmap_lba_count to be smaller than what the backing device can actually support.
--- drivers/target/target_core_device.c | 8 +++++--- drivers/target/target_core_file.c | 3 +-- drivers/target/target_core_iblock.c | 3 +-- include/target/target_core_backend.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-)
drivers/target/target_core_device.c +5 -3
@@ -821,13 +821,15 @@ struct se_device *target_alloc_device(st* in ATA and we need to set TPE=1 */ bool target_configure_unmap_from_queue (struct se_dev_attrib *attrib, -struct request_queue *q,int block_size) +struct request_queue *q) { +int block_size =queue_logical_block_size (q); +if (!blk_queue_discard (q))return false; - attrib->max_unmap_lba_count = (q->limits.max_discard_sectors <<9 ) / - block_size; + attrib->max_unmap_lba_count = + q->limits.max_discard_sectors >> (ilog2 (block_size) -9 );/* * Currently hardcoded to 1 in Linux/SCSI code.. */
drivers/target/target_core_file.c +1 -2
@@ -161,8 +161,7 @@ static int fd_configure_device(struct se dev_size,div_u64 (dev_size, fd_dev->fd_block_size), fd_dev->fd_block_size); -if (target_configure_unmap_from_queue (&dev->dev_attrib, q, - fd_dev->fd_block_size)) +if (target_configure_unmap_from_queue (&dev->dev_attrib, q))pr_debug ("IFILE: BLOCK Discard support available," " disabled by default\n" );/*
drivers/target/target_core_iblock.c +1 -2
@@ -121,8 +121,7 @@ static int iblock_configure_device(struc dev->dev_attrib.hw_max_sectors =queue_max_hw_sectors (q); dev->dev_attrib.hw_queue_depth = q->nr_requests; -if (target_configure_unmap_from_queue (&dev->dev_attrib, q, - dev->dev_attrib.hw_block_size)) +if (target_configure_unmap_from_queue (&dev->dev_attrib, q))pr_debug ("IBLOCK: BLOCK Discard support available," " disabled by default\n" );
include/target/target_core_backend.h +1 -1
@@ -95,6 +95,6 @@ sense_reason_t passthrough_parse_cdb(strbool target_sense_desc_format (struct se_device *dev);sector_t target_to_linux_sector (struct se_device *dev,sector_t lb);bool target_configure_unmap_from_queue (struct se_dev_attrib *attrib, -struct request_queue *q,int block_size); +struct request_queue *q);#endif /* TARGET_CORE_BACKEND_H */
Greg Kroah-Hartman
maintainerPATCH 169/186 target: Fix ordered task CHECK_CONDITION early exception handling
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger <[email protected]>
commit 410c29dfbfdf73d0d0b5d14a21868ab038eca703 upstream.
If a Simple command is sent with a failure, target_setup_cmd_from_cdb returns with TCM_UNSUPPORTED_SCSI_OPCODE or TCM_INVALID_CDB_FIELD.
So in the cases where target_setup_cmd_from_cdb returns an error, we never get far enough to call target_execute_cmd to increment simple_cmds. Since simple_cmds isn't incremented, the result of the failure from target_setup_cmd_from_cdb causes transport_generic_request_failure to decrement simple_cmds, due to call to transport_complete_task_attr.
With this dev->simple_cmds or dev->dev_ordered_sync is now -1, not 0. So when a subsequent command with an Ordered Task is sent, it causes a hang, since dev->simple_cmds is at -1.
--- drivers/target/target_core_transport.c | 7 ++++++- include/target/target_core_base.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-)
drivers/target/target_core_transport.c +6 -1
@@ -1827,6 +1827,8 @@ static bool target_handle_task_attr(struif (dev->transport->transport_flags &TRANSPORT_FLAG_PASSTHROUGH )return false; + cmd->se_cmd_flags |=SCF_TASK_ATTR_SET ; +/* * Check for the existence of HEAD_OF_QUEUE, and if true return 1 * to allow the passed struct se_cmd list of tasks to the front of the list.
@@ -1949,6 +1951,9 @@ static void transport_complete_task_attrif (dev->transport->transport_flags &TRANSPORT_FLAG_PASSTHROUGH )return ; +if (!(cmd->se_cmd_flags &SCF_TASK_ATTR_SET )) + goto restart; +if (cmd->sam_task_attr ==TCM_SIMPLE_TAG ) {atomic_dec_mb (&dev->simple_cmds); dev->dev_cur_ordered_id++;
@@ -1965,7 +1970,7 @@ static void transport_complete_task_attrpr_debug ("Incremented dev_cur_ordered_id: %u for ORDERED\n" , dev->dev_cur_ordered_id); } - +restart:target_restart_delayed_cmds (dev); }
include/target/target_core_base.h +1 -0
@@ -142,6 +142,7 @@ enum se_cmd_flags_table {SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC =0x00200000 ,SCF_ACK_KREF =0x00400000 ,SCF_USE_CPUID =0x00800000 , + SCF_TASK_ATTR_SET = 0x01000000, };/*
Greg Kroah-Hartman
maintainerPATCH 170/186 um: Fix possible deadlock in sig_handler_common()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <[email protected]>
commit 57a05d83b16710aff30510c33768df7ab17e0b4a upstream.
We are in atomic context and must not sleep.
Sleeping here is possible since malloc() maps
to kmalloc() with GFP_KERNEL.
--- arch/um/os-Linux/signal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/um/os-Linux/signal.c +3 -2
@@ -15,6 +15,7 @@#include <kern_util.h> #include <os.h> #include <sysdep/mcontext.h> +#include <um_malloc.h> void (*sig_info[NSIG ])(int ,struct siginfo *,struct uml_pt_regs *) = { [SIGTRAP ] = relay_signal,
@@ -32,7 +33,7 @@ static void sig_handler_common(int sig,struct uml_pt_regs *r;int save_errno = errno; - r =malloc (sizeof (struct uml_pt_regs )); + r =uml_kmalloc (sizeof (struct uml_pt_regs ),UM_GFP_ATOMIC );if (!r)panic ("out of memory" );
@@ -91,7 +92,7 @@ static void timer_real_alarm_handler(mco {struct uml_pt_regs *regs; - regs =malloc (sizeof (struct uml_pt_regs )); + regs =uml_kmalloc (sizeof (struct uml_pt_regs ),UM_GFP_ATOMIC );if (!regs)panic ("out of memory" );
Greg Kroah-Hartman
maintainerPATCH 171/186 Input: elan_i2c - properly wake up touchpad on ASUS laptops
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: KT Liao <[email protected]>
commit 2de4fcc64685def3e586856a2dc636df44532395 upstream.
Some ASUS laptops were shipped with touchpads that require to be woken up first, before trying to switch them into absolute reporting mode, otherwise touchpad would fail to work while flooding the logs with:
elan_i2c i2c-ELAN1000:00: invalid report id data (1)
Among affected devices are Asus E202SA, N552VW, X456UF, UX305CA, and others. We detect such devices by checking the IC type and product ID numbers and adjusting order of operations accordingly.
--- drivers/input/mouse/elan_i2c_core.c | 79 ++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 16 deletions(-)
drivers/input/mouse/elan_i2c_core.c +63 -16
@@ -4,7 +4,8 @@* Copyright (c) 2013 ELAN Microelectronics Corp. * * Author: 林政維 (Duson Lin) <[email protected]> -* Version: 1.6.0 +* Author: KT Liao <[email protected]> +* Version: 1.6.2 * * Based on cyapa driver: * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +41,7 @@#include "elan_i2c.h" #define DRIVER_NAME "elan_i2c" -#define ELAN_DRIVER_VERSION "1.6.1" +#define ELAN_DRIVER_VERSION "1.6.2"#define ELAN_VENDOR_ID 0x04f3#define ETP_MAX_PRESSURE 255#define ETP_FWIDTH_REDUCE 90
@@ -199,9 +200,41 @@ static int elan_sleep(struct elan_tp_datreturn error; } +static int elan_query_product (struct elan_tp_data *data) +{ +int error; + + error = data->ops->get_product_id (data->client, &data->product_id); +if (error) +return error; + + error = data->ops->get_sm_version (data->client, &data->ic_type, + &data->sm_version); +if (error) +return error; + +return 0 ; +} + +static int elan_check_ASUS_special_fw (struct elan_tp_data *data) +{ +if (data->ic_type !=0x0E ) +return false; + +switch (data->product_id) { + case 0x05 ... 0x07: +case 0x09 : +case 0x13 : +return true; +default : +return false; + } +} +static int __elan_initialize (struct elan_tp_data *data) {struct i2c_client *client = data->client; +bool woken_up = false;int error; error = data->ops->initialize (client);
@@ -210,6 +243,27 @@ static int __elan_initialize(struct elanreturn error; } + error =elan_query_product (data); +if (error) +return error; + +/* +* Some ASUS devices were shipped with firmware that requires +* touchpads to be woken up first, before attempting to switch +* them into absolute reporting mode. +*/ +if (elan_check_ASUS_special_fw (data)) { + error = data->ops->sleep_control (client, false); +if (error) { +dev_err (&client->dev, +"failed to wake device up: %d\n" , error); +return error; + } + +msleep (200 ); + woken_up = true; + } + data->mode |=ETP_ENABLE_ABS ; error = data->ops->set_mode (client, data->mode);if (error) {
@@ -218,11 +272,13 @@ static int __elan_initialize(struct elanreturn error; } - error = data->ops->sleep_control (client, false); -if (error) { -dev_err (&client->dev, -"failed to wake device up: %d\n" , error); -return error; +if (!woken_up) { + error = data->ops->sleep_control (client, false); +if (error) { +dev_err (&client->dev, +"failed to wake device up: %d\n" , error); +return error; + } }return 0 ;
@@ -248,10 +304,6 @@ static int elan_query_device_info(struct {int error; - error = data->ops->get_product_id (data->client, &data->product_id); -if (error) -return error; - error = data->ops->get_version (data->client, false, &data->fw_version);if (error)return error;
@@ -261,11 +313,6 @@ static int elan_query_device_info(structif (error)return error; - error = data->ops->get_sm_version (data->client, &data->ic_type, - &data->sm_version); -if (error) -return error; - error = data->ops->get_version (data->client, true, &data->iap_version);if (error)return error;
Greg Kroah-Hartman
maintainerPATCH 172/186 Input: i8042 - break load dependency between atkbd/psmouse and i8042
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit 4097461897df91041382ff6fcd2bfa7ee6b2448c upstream.
As explained in [email protected] we have a hard load dependency between i8042 and atkbd which prevents keyboard from working on Gen2 Hyper-V VMs.
Quoted 6 lines
hyperv_keyboardinvokesserio_interrupt(), which needs a valid serio driver likeatkbd.c.atkbd.cdepends onlibps2.cbecause it invokesps2_command().libps2.cdepends oni8042.cbecause it invokesi8042_check_port_owner(). As a result,hyperv_keyboardactually depends oni8042.c.
Quoted 6 lines
For a Generation 2 Hyper-V VM (meaning no i8042 device emulated), if a Linux VM (like Arch Linux) happens to configure
CONFIG_SERIO_I8042=mrather than =y, atkbd.ko can't load because i8042.ko can't load(due to no i8042 device emulated) and finallyhyperv_keyboardcan't work and the user can't input: https://bugs.archlinux.org/task/39820
(Ubuntu/RHEL/SUSE aren't affected since they useCONFIG_SERIO_I8042=y)
To break the dependency we move away from using i8042_check_port_owner() and instead allow serio port owner specify a mutex that clients should use to serialize PS/2 command stream.
--- drivers/input/serio/i8042.c | 16 +--------------- drivers/input/serio/libps2.c | 10 ++++------ include/linux/i8042.h | 6 ------ include/linux/serio.h | 24 +++++++++++++++++++----- 4 files changed, 24 insertions(+), 32 deletions(-)
drivers/input/serio/i8042.c +1 -15
@@ -1277,6 +1277,7 @@ static int __init i8042_create_kbd_port( serio->start = i8042_start; serio->stop = i8042_stop; serio->close = i8042_port_close; + serio->ps2_cmd_mutex = &i8042_mutex; serio->port_data = port; serio->dev.parent = &i8042_platform_device->dev;strlcpy (serio->name,"i8042 KBD port" ,sizeof (serio->name));
@@ -1373,21 +1374,6 @@ static void i8042_unregister_ports(void) } } -/* -* Checks whether port belongs to i8042 controller. -*/ -bool i8042_check_port_owner (const struct serio *port) -{ -int i; - -for (i =0 ; i <I8042_NUM_PORTS ; i++) -if (i8042_ports[i].serio == port) -return true; - -return false; -} -EXPORT_SYMBOL (i8042_check_port_owner); -static void i8042_free_irqs (void ) {if (i8042_aux_irq_registered)
drivers/input/serio/libps2.c +4 -6
@@ -56,19 +56,17 @@ EXPORT_SYMBOL(ps2_sendbyte);void ps2_begin_command (struct ps2dev *ps2dev) { -mutex_lock (&ps2dev->cmd_mutex); +struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; -if (i8042_check_port_owner (ps2dev->serio)) -i8042_lock_chip (); +mutex_lock (m); }EXPORT_SYMBOL (ps2_begin_command);void ps2_end_command (struct ps2dev *ps2dev) { -if (i8042_check_port_owner (ps2dev->serio)) -i8042_unlock_chip (); +struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; -mutex_unlock (&ps2dev->cmd_mutex); +mutex_unlock (m); }EXPORT_SYMBOL (ps2_end_command);
include/linux/i8042.h +0 -6
@@ -62,7 +62,6 @@ struct serio;void i8042_lock_chip (void );void i8042_unlock_chip (void );int i8042_command (unsigned char *param,int command); -bool i8042_check_port_owner (const struct serio *);int i8042_install_filter (bool (*filter)(unsigned char data,unsigned char str,struct serio *serio)); int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
@@ -83,11 +82,6 @@ static inline int i8042_command(unsignedreturn -ENODEV ; } -static inline bool i8042_check_port_owner (const struct serio *serio) -{ -return false; -} -static inline int i8042_install_filter (bool (*filter)(unsigned char data,unsigned char str,struct serio *serio)) {
include/linux/serio.h +19 -5
@@ -31,7 +31,8 @@ struct serio {struct serio_device_id id; -spinlock_t lock;/* protects critical sections from port's interrupt handler */ +/* Protects critical sections from port's interrupt handler */ +spinlock_t lock;int (*write)(struct serio *,unsigned char );int (*open)(struct serio *);
@@ -40,16 +41,29 @@ struct serio {void (*stop)(struct serio *);struct serio *parent; -struct list_head child_node;/* Entry in parent->children list */ +/* Entry in parent->children list */ +struct list_head child_node;struct list_head children; -unsigned int depth;/* level of nesting in serio hierarchy */ +/* Level of nesting in serio hierarchy */ +unsigned int depth; -struct serio_driver *drv;/* accessed from interrupt, must be protected by serio->lock and serio->sem */ -struct mutex drv_mutex;/* protects serio->drv so attributes can pin driver */ +/* +* serio->drv is accessed from interrupt handlers; when modifying +* caller should acquire serio->drv_mutex and serio->lock. +*/ +struct serio_driver *drv; +/* Protects serio->drv so attributes can pin current driver */ +struct mutex drv_mutex;struct device dev;struct list_head node; + +/* +* For use by PS/2 layer when several ports share hardware and +* may get indigestion when exposed to concurrent access (i8042). +*/ +struct mutex *ps2_cmd_mutex; };#define to_serio_port (d) container_of(d, struct serio, dev)
Re: [PATCH 4.7 172/186] Input: i8042 - break load dependency between atkbd/psmouse and i8042
Quoted 1 line · Greg Kroah-Hartman
4.7-stable review patch. If anyone has any objections, please let me know.
Greg, please hold this patch off till your next cycle. I will be sending a fixup for it to Linus today or tomorrow.
Thanks!
Quoted 168 lines
------------------
From: Dmitry Torokhov <[email protected]>
commit
4097461897df91041382ff6fcd2bfa7ee6b2448cupstream.As explained in [email protected] we have a hard load dependency between i8042 and atkbd which prevents keyboard from working on Gen2 Hyper-V VMs.
Quoted 6 lines
hyperv_keyboardinvokesserio_interrupt(), which needs a valid serio driver likeatkbd.c.atkbd.cdepends onlibps2.cbecause it invokesps2_command().libps2.cdepends oni8042.cbecause it invokesi8042_check_port_owner(). As a result,hyperv_keyboardactually depends oni8042.c.Quoted 6 lines
For a Generation 2 Hyper-V VM (meaning no i8042 device emulated), if a Linux VM (like Arch Linux) happens to configure
CONFIG_SERIO_I8042=mrather than =y, atkbd.ko can't load because i8042.ko can't load(due to no i8042 device emulated) and finallyhyperv_keyboardcan't work and the user can't input: https://bugs.archlinux.org/task/39820
(Ubuntu/RHEL/SUSE aren't affected since they useCONFIG_SERIO_I8042=y)To break the dependency we move away from using
i8042_check_port_owner()and instead allow serio port owner specify a mutex that clients should use to serialize PS/2 command stream.Reported-by Mark Laws <[email protected]>Tested-by Mark Laws <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/input/serio/i8042.c | 16 +--------------- drivers/input/serio/libps2.c | 10 ++++------ include/linux/i8042.h | 6 ------ include/linux/serio.h | 24 +++++++++++++++++++----- 4 files changed, 24 insertions(+), 32 deletions(-)drivers/input/serio/i8042.c +1
-15@@ -1277,6 +1277,7 @@ static int __init i8042_create_kbd_port( serio->start = i8042_start; serio->stop = i8042_stop; serio->close = i8042_port_close; + serio->ps2_cmd_mutex = &i8042_mutex; serio->port_data = port; serio->dev.parent = &i8042_platform_device->dev;strlcpy (serio->name,"i8042 KBD port" ,sizeof (serio->name));@@ -1373,21 +1374,6 @@ static void i8042_unregister_ports(void) } } -/* -* Checks whether port belongs to i8042 controller. -*/ -bool i8042_check_port_owner (const struct serio *port) -{ -int i; - -for (i =0 ; i <I8042_NUM_PORTS ; i++) -if (i8042_ports[i].serio == port) -return true; - -return false; -} -EXPORT_SYMBOL (i8042_check_port_owner); -static void i8042_free_irqs (void ) {if (i8042_aux_irq_registered)drivers/input/serio/libps2.c +4
-6@@ -56,19 +56,17 @@ EXPORT_SYMBOL(ps2_sendbyte);void ps2_begin_command (struct ps2dev *ps2dev) { -mutex_lock (&ps2dev->cmd_mutex); +struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; -if (i8042_check_port_owner (ps2dev->serio)) -i8042_lock_chip (); +mutex_lock (m); }EXPORT_SYMBOL (ps2_begin_command);void ps2_end_command (struct ps2dev *ps2dev) { -if (i8042_check_port_owner (ps2dev->serio)) -i8042_unlock_chip (); +struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; -mutex_unlock (&ps2dev->cmd_mutex); +mutex_unlock (m); }EXPORT_SYMBOL (ps2_end_command);include/linux/i8042.h +0
-6@@ -62,7 +62,6 @@ struct serio;void i8042_lock_chip (void );void i8042_unlock_chip (void );int i8042_command (unsigned char *param,int command); -bool i8042_check_port_owner (const struct serio *);int i8042_install_filter (bool (*filter)(unsigned char data,unsigned char str,struct serio *serio)); int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,@@ -83,11 +82,6 @@ static inline int i8042_command(unsignedreturn -ENODEV ; } -static inline bool i8042_check_port_owner (const struct serio *serio) -{ -return false; -} -static inline int i8042_install_filter (bool (*filter)(unsigned char data,unsigned char str,struct serio *serio)) {include/linux/serio.h +19
-5@@ -31,7 +31,8 @@ struct serio {struct serio_device_id id; -spinlock_t lock;/* protects critical sections from port's interrupt handler */ +/* Protects critical sections from port's interrupt handler */ +spinlock_t lock;int (*write)(struct serio *,unsigned char );int (*open)(struct serio *);@@ -40,16 +41,29 @@ struct serio {void (*stop)(struct serio *);struct serio *parent; -struct list_head child_node;/* Entry in parent->children list */ +/* Entry in parent->children list */ +struct list_head child_node;struct list_head children; -unsigned int depth;/* level of nesting in serio hierarchy */ +/* Level of nesting in serio hierarchy */ +unsigned int depth; -struct serio_driver *drv;/* accessed from interrupt, must be protected by serio->lock and serio->sem */ -struct mutex drv_mutex;/* protects serio->drv so attributes can pin driver */ +/* +* serio->drv is accessed from interrupt handlers; when modifying +* caller should acquire serio->drv_mutex and serio->lock. +*/ +struct serio_driver *drv; +/* Protects serio->drv so attributes can pin current driver */ +struct mutex drv_mutex;struct device dev;struct list_head node; + +/* +* For use by PS/2 layer when several ports share hardware and +* may get indigestion when exposed to concurrent access (i8042). +*/ +struct mutex *ps2_cmd_mutex; };#define to_serio_port (d) container_of(d, struct serio, dev)
Signature · 1 line
Dmitry
Greg Kroah-Hartman
maintainerRe: [PATCH 4.7 172/186] Input: i8042 - break load dependency between atkbd/psmouse and i8042
Quoted 6 lines · Dmitry Torokhov
Quoted 1 line · Greg Kroah-Hartman
4.7-stable review patch. If anyone has any objections, please let me know.
Greg, please hold this patch off till your next cycle. I will be sending a fixup for it to Linus today or tomorrow.
I've now removed this from all of the queues, thanks. I'll add it to the next round of releases, hopefully you tagged the "fixup" for stable so I'll see it when it lands in Linus's tree. If not, can you send me the git commit id?
thanks,
greg k-h
Dmitry Torokhov
Tested-by Bruno Wolff IIIRe: [PATCH 4.7 172/186] Input: i8042 - break load dependency between atkbd/psmouse and i8042
Quoted 5 lines · Greg Kroah-Hartman
Quoted 4 lines · Dmitry Torokhov
Quoted 1 line · Greg Kroah-Hartman
4.7-stable review patch. If anyone has any objections, please let me know.
Quoted 7 lines
Quoted 2 lines
Greg, please hold this patch off till your next cycle. I will be sending a fixup for it to Linus today or tomorrow.
I've now removed this from all of the queues, thanks. I'll add it to the next round of releases, hopefully you tagged the "fixup" for stable so I'll see it when it lands in Linus's tree. If not, can you send me the git commit id?
It is here (in my tree ATM but the commit ID should be stable) and it is marked for stable:
commit 47af45d684b5f3ae000ad448db02ce4f13f73273
Author: Dmitry Torokhov <[email protected]> Date: Tue Aug 16 17:38:54 2016 -0700
Input: i8042 - set up shared ps2_cmd_mutex for AUX ports
The commit 4097461897df ("Input: i8042 - break load dependency ...") correctly set up ps2_cmd_mutex pointer for the KBD port but forgot to do the same for AUX port(s), which results in communication on KBD and AUX ports to clash with each other.
Thanks.
Signature · 1 line
Dmitry
Greg Kroah-Hartman
maintainerRe: [PATCH 4.7 172/186] Input: i8042 - break load dependency between atkbd/psmouse and i8042
Quoted 28 lines · Dmitry Torokhov
Quoted 5 lines · Greg Kroah-Hartman
Quoted 4 lines · Dmitry Torokhov
Quoted 1 line · Greg Kroah-Hartman
4.7-stable review patch. If anyone has any objections, please let me know.
Quoted 7 lines
Quoted 2 lines
Greg, please hold this patch off till your next cycle. I will be sending a fixup for it to Linus today or tomorrow.
I've now removed this from all of the queues, thanks. I'll add it to the next round of releases, hopefully you tagged the "fixup" for stable so I'll see it when it lands in Linus's tree. If not, can you send me the git commit id?
It is here (in my tree ATM but the commit ID should be stable) and it is marked for stable:
commit
47af45d684b5f3ae000ad448db02ce4f13f73273Author: Dmitry Torokhov <[email protected]> Date: Tue Aug 16 17:38:54 2016 -0700Input: i8042 - set up shared
ps2_cmd_mutexfor AUX portsThe commit
4097461897df("Input: i8042 - break load dependency ...") correctly set upps2_cmd_mutexpointer for the KBD port but forgot to do the same for AUX port(s), which results in communication on KBD and AUX ports to clash with each other.
Quoted 5 lines
Fixes 4097461897df ("Input: i8042 - break load dependency ...")Reported-by Bruno Wolff III <[email protected]>Tested-by Bruno Wolff III <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>
Thanks, I've applied this one and the original one now.
greg k-h
Greg Kroah-Hartman
maintainerPATCH 173/186 SUNRPC: Dont allocate a full sockaddr_storage for tracing
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit db1bb44c4c7e8d49ed674dc59e5222d99c698088 upstream.
We're always tracing IPv4 or IPv6 addresses, so we can save a lot of space on the ringbuffer by allocating the correct sockaddr size.
--- include/trace/events/sunrpc.h | 47 ++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-)
include/trace/events/sunrpc.h +34 -13
@@ -529,20 +529,27 @@ TRACE_EVENT(svc_xprt_do_enqueue,TP_STRUCT__entry (__field (struct svc_xprt *,xprt ) - __field_struct(struct sockaddr_storage, ss)__field (int, pid) __field(unsigned long, flags) + __dynamic_array(unsigned char, addr, xprt != NULL ? + xprt->xpt_remotelen : 0) ),TP_fast_assign ( __entry->xprt = xprt; - xprt ?memcpy (&__entry->ss, &xprt->xpt_remote,sizeof (__entry->ss)) :memset (&__entry->ss,0 ,sizeof (__entry->ss)); __entry->pid = rqst? rqst->rq_task->pid :0 ; - __entry->flags = xprt ? xprt->xpt_flags :0 ; +if (xprt) { +memcpy (__get_dynamic_array (addr), + &xprt->xpt_remote, + xprt->xpt_remotelen); + __entry->flags = xprt->xpt_flags; + }else + __entry->flags =0 ; ),TP_printk ("xprt=0x%p addr=%pIScp pid=%d flags=%s" , __entry->xprt, - (struct sockaddr *)&__entry->ss, +__get_dynamic_array_len (addr) !=0 ? + (struct sockaddr *)__get_dynamic_array (addr) :NULL , __entry->pid,show_svc_xprt_flags (__entry->flags)) );
@@ -553,18 +560,25 @@ TRACE_EVENT(svc_xprt_dequeue,TP_STRUCT__entry (__field (struct svc_xprt *,xprt ) - __field_struct(struct sockaddr_storage, ss) __field(unsigned long, flags) + __dynamic_array(unsigned char, addr, xprt != NULL ? + xprt->xpt_remotelen : 0) ),TP_fast_assign ( - __entry->xprt = xprt, - xprt ? memcpy(&__entry->ss, &xprt->xpt_remote, sizeof(__entry->ss)) : memset(&__entry->ss, 0, sizeof(__entry->ss)); - __entry->flags = xprt ? xprt->xpt_flags :0 ; + __entry->xprt = xprt; +if (xprt) { +memcpy (__get_dynamic_array (addr), + &xprt->xpt_remote, + xprt->xpt_remotelen); + __entry->flags = xprt->xpt_flags; + }else + __entry->flags =0 ; ),TP_printk ("xprt=0x%p addr=%pIScp flags=%s" , __entry->xprt, - (struct sockaddr *)&__entry->ss, +__get_dynamic_array_len (addr) !=0 ? + (struct sockaddr *)__get_dynamic_array (addr) :NULL ,show_svc_xprt_flags (__entry->flags)) );
@@ -592,19 +606,26 @@ TRACE_EVENT(svc_handle_xprt,TP_STRUCT__entry (__field (struct svc_xprt *,xprt )__field (int, len) - __field_struct(struct sockaddr_storage, ss) __field(unsigned long, flags) + __dynamic_array(unsigned char, addr, xprt != NULL ? + xprt->xpt_remotelen : 0) ),TP_fast_assign ( __entry->xprt = xprt; - xprt ?memcpy (&__entry->ss, &xprt->xpt_remote,sizeof (__entry->ss)) :memset (&__entry->ss,0 ,sizeof (__entry->ss)); __entry->len = len; - __entry->flags = xprt ? xprt->xpt_flags :0 ; +if (xprt) { +memcpy (__get_dynamic_array (addr), + &xprt->xpt_remote, + xprt->xpt_remotelen); + __entry->flags = xprt->xpt_flags; + }else + __entry->flags =0 ; ),TP_printk ("xprt=0x%p addr=%pIScp len=%d flags=%s" , __entry->xprt, - (struct sockaddr *)&__entry->ss, +__get_dynamic_array_len (addr) !=0 ? + (struct sockaddr *)__get_dynamic_array (addr) :NULL , __entry->len,show_svc_xprt_flags (__entry->flags)) );#endif /* _TRACE_SUNRPC_H */
Greg Kroah-Hartman
maintainerPATCH 174/186 MIPS: mm: Fix definition of R6 cache instruction
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Redfearn <[email protected]>
commit 4f53989b0652ffe2605221c81ca8ffcfc90aed2a upstream.
Commit a168b8f1cde6 ("MIPS: mm: Add MIPS R6 instruction encodings") added an incorrect definition of the redefined MIPSr6 cache instruction.
Executing any kernel code including this instuction results in a reserved instruction exception and kernel panic.
Fix the instruction definition.
Patchwork: https://patchwork.linux-mips.org/patch/13663/
--- arch/mips/mm/uasm-mips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/mm/uasm-mips.c +1 -1
@@ -65,7 +65,7 @@ static struct insn insn_table[] = { #ifndef CONFIG_CPU_MIPSR6 { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, #else - { insn_cache, M6(cache_op, 0, 0, 0, cache6_op), RS | RT | SIMM9 }, + { insn_cache, M6(spec3_op, 0, 0, 0, cache6_op), RS | RT | SIMM9 }, #endif { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
Greg Kroah-Hartman
maintainerPATCH 175/186 MIPS: Fix r4k clockevents registration
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
commit 6dabf2b7a597a9613f0b8a2fcbe01e2a0a05c896 upstream.
CPUFreq need min_delta_ticks/max_delta_ticks to be initialized, and this can be done by clockevents_config_and_register().
Patchwork: https://patchwork.linux-mips.org/patch/13817/
--- arch/mips/kernel/cevt-r4k.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
arch/mips/kernel/cevt-r4k.c +1 -6
@@ -276,12 +276,7 @@ int r4k_clockevent_init(void)CLOCK_EVT_FEAT_C3STOP |CLOCK_EVT_FEAT_PERCPU ; -clockevent_set_clock (cd, mips_hpt_frequency); - -/* Calculate the min / max delta */ - cd->max_delta_ns =clockevent_delta2ns (0x7fffffff , cd); min_delta =calculate_min_delta (); - cd->min_delta_ns =clockevent_delta2ns (min_delta, cd); cd->rating =300 ; cd->irq = irq;
@@ -289,7 +284,7 @@ int r4k_clockevent_init(void) cd->set_next_event = mips_next_event; cd->event_handler = mips_event_handler; -clockevents_register_device (cd); +clockevents_config_and_register (cd, mips_hpt_frequency, min_delta,0x7fffffff );if (cp0_timer_irq_installed)return 0 ;
Greg Kroah-Hartman
maintainerPATCH 176/186 MIPS: Dont register r4k sched clock when CPUFREQ enabled
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
commit 07d69579e7fec27e371296d8ca9d6076fc401b5c upstream.
Don't register r4k sched clock when CPUFREQ enabled because sched clock need a constant frequency.
Patchwork: https://patchwork.linux-mips.org/patch/13820/
--- arch/mips/kernel/csrc-r4k.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/mips/kernel/csrc-r4k.c +3 -1
@@ -23,7 +23,7 @@ static struct clocksource clocksource_mi .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static u64 notrace r4k_read_sched_clock(void) +static u64 __maybe_unused notrace r4k_read_sched_clock(void) {return read_c0_count (); }
@@ -82,7 +82,9 @@ int __init init_r4k_clocksource(void)clocksource_register_hz (&clocksource_mips, mips_hpt_frequency); +#ifndef CONFIG_CPU_FREQ sched_clock_register (r4k_read_sched_clock,32 , mips_hpt_frequency); +#endif return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 177/186 MIPS: hpet: Increase HPET_MIN_PROG_DELTA and decrease HPET_MIN_CYCLES
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
commit 3ef06653987d4c4536b408321edf0e5caa2a317f upstream.
At first, we prefer to use mips clockevent device, so we decrease the rating of hpet clockevent device.
For hpet, if HPET_MIN_PROG_DELTA (minimum delta of hpet programming) is too small and HPET_MIN_CYCLES (threshold of -ETIME checking) is too large, then hpet_next_event() can easily return -ETIME. After commit c6eb3f70d44828 ("hrtimer: Get rid of hrtimer softirq") this will cause a RCU stall.
So, HPET_MIN_PROG_DELTA must be sufficient that we don't re-trip the -ETIME check -- if we do, we will return -ETIME, forward the next event time, try to set it, return -ETIME again, and basically lock the system up. Meanwhile, HPET_MIN_CYCLES doesn't need to be too large, 16 cycles is enough.
This solution is similar to commit f9eccf24615672 ("clocksource/drivers /vt8500: Increase the minimum delta").
By the way, this patch ensures hpet count/compare to be 32-bit long.
Patchwork: https://patchwork.linux-mips.org/patch/13819/
--- arch/mips/loongson64/loongson-3/hpet.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
arch/mips/loongson64/loongson-3/hpet.c +7 -7
@@ -13,8 +13,8 @@#define SMBUS_PCI_REG64 0x64#define SMBUS_PCI_REGB4 0xb4 -#define HPET_MIN_CYCLES 64 -#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1)) +#define HPET_MIN_CYCLES 16 +#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES * 12)static DEFINE_SPINLOCK (hpet_lock); DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device);
@@ -157,14 +157,14 @@ static int hpet_tick_resume(struct clockstatic int hpet_next_event (unsigned long delta,struct clock_event_device *evt) { -unsigned int cnt; -int res; +u32 cnt; +s32 res; cnt =hpet_read (HPET_COUNTER ); - cnt += delta; + cnt += (u32 ) delta;hpet_write (HPET_T0_CMP , cnt); - res = (int )(cnt -hpet_read (HPET_COUNTER )); + res = (s32)(cnt -hpet_read (HPET_COUNTER ));return res <HPET_MIN_CYCLES ? -ETIME :0 ; }
@@ -230,7 +230,7 @@ void __init setup_hpet_timer(void) cd = &per_cpu (hpet_clockevent_device, cpu); cd->name ="hpet" ; - cd->rating =320 ; + cd->rating =100 ; cd->features =CLOCK_EVT_FEAT_PERIODIC |CLOCK_EVT_FEAT_ONESHOT ; cd->set_state_shutdown = hpet_set_state_shutdown; cd->set_state_periodic = hpet_set_state_periodic;
Greg Kroah-Hartman
maintainerPATCH 178/186 PCI: Mark Atheros AR9485 and QCA9882 to avoid bus reset
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Blake <[email protected]>
commit 9ac0108c2bac3f1d0255f64fb89fc27e71131b24 upstream.
Similar to the AR93xx series, the AR94xx and the Qualcomm QCA988x also have the same quirk for the Bus Reset.
--- drivers/pci/quirks.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/pci/quirks.c +6 -4
@@ -3189,13 +3189,15 @@ static void quirk_no_bus_reset(struct pc }/* -* Atheros AR93xx chips do not behave after a bus reset. The device will -* throw a Link Down error on AER-capable systems and regardless of AER, -* config space of the device is never accessible again and typically -* causes the system to hang or reset when access is attempted. +* Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset. +* The device will throw a Link Down error on AER-capable systems and +* regardless of AER, config space of the device is never accessible again +* and typically causes the system to hang or reset when access is attempted. * http://www.spinics.net/lists/linux-pci/msg34797.html */ DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_ATHEROS ,0x0030 , quirk_no_bus_reset); +DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_ATHEROS ,0x0032 , quirk_no_bus_reset); +DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_ATHEROS ,0x003c , quirk_no_bus_reset);static void quirk_no_pm_reset (struct pci_dev *dev) {
Greg Kroah-Hartman
maintainerPATCH 179/186 x86/platform/intel_mid_pci: Rework IRQ0 workaround
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit bb27570525a71f48347ed0e0c265063e7952bb61 upstream.
On Intel Merrifield platform several PCI devices have a bogus configuration, i.e. the IRQ0 had been assigned to few of them. These are PCI root bridge, eMMC0, HS UART common registers, PWM, and HDMI. The actual interrupt line can be allocated to one device exclusively, in our case to eMMC0, the rest should cope without it and basically known drivers for them are not using interrupt line at all.
Rework IRQ0 workaround, which was previously done to avoid conflict between eMMC0 and HS UART common registers, to behave differently based on the device in question, i.e. allocate interrupt line to eMMC0, but silently skip interrupt allocation for the rest except HS UART common registers which are not used anyway. With this rework IOSF MBI driver in particular would be used.
--- arch/x86/pci/intel_mid_pci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
arch/x86/pci/intel_mid_pci.c +10 -2
@@ -37,6 +37,7 @@/* Quirks for the listed devices */ #define PCI_DEVICE_ID_INTEL_MRFL_MMC 0x1190 +#define PCI_DEVICE_ID_INTEL_MRFL_HSU 0x1191/* Fixed BAR fields */ #define PCIE_VNDR_CAP_ID_FIXED_BAR 0x00/* Fixed BAR (TBD) */
@@ -225,13 +226,20 @@ static int intel_mid_pci_irq_enable(stru/* Special treatment for IRQ0 */ if (dev->irq ==0 ) {/* +* Skip HS UART common registers device since it has +* IRQ0 assigned and not used by the kernel. +*/ +if (dev->device ==PCI_DEVICE_ID_INTEL_MRFL_HSU ) +return -EBUSY ; +/* * TNG has IRQ0 assigned to eMMC controller. But there * are also other devices with bogus PCI configuration * that have IRQ0 assigned. This check ensures that -* eMMC gets it. +* eMMC gets it. The rest of devices still could be +* enabled without interrupt line being allocated. */ if (dev->device !=PCI_DEVICE_ID_INTEL_MRFL_MMC ) -return -EBUSY ; +return 0 ; }break ;default :
Greg Kroah-Hartman
maintainerPATCH 180/186 ACPI / EC: Work around method reentrancy limit in ACPICA for _Qxx
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lv Zheng <[email protected]>
commit e1191bd4f62d9086a1a47adc286e7fcffc1fa55c upstream.
A regression is caused by the following commit:
Commit: 02b771b64b73226052d6e731a0987db3b47281e9
Subject: ACPI / EC: Fix an issue caused by the serialized _Qxx evaluations
In this commit, using system workqueue causes that the maximum parallel executions of _Qxx can exceed 255. This violates the method reentrancy limit in ACPICA and generates the following error log:
ACPI Error: Method reached maximum reentrancy limit (255) (20150818/dsmethod-341)
This patch creates a seperate workqueue and limits the number of parallel _Qxx evaluations down to a configurable value (can be tuned against number of online CPUs).
Since EC events are handled after driver probe, we can create the workqueue in acpi_ec_init().
--- drivers/acpi/ec.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-)
drivers/acpi/ec.c +37 -4
@@ -101,6 +101,7 @@ enum ec_command {#define ACPI_EC_UDELAY_POLL 550/* Wait 1ms for EC transaction polling */ #define ACPI_EC_CLEAR_MAX 100/* Maximum number of events to query * when trying to clear the EC */ +#define ACPI_EC_MAX_QUERIES 16/* Maximum number of parallel queries */ enum {EC_FLAGS_QUERY_PENDING ,/* Query is pending */
@@ -121,6 +122,10 @@ static unsigned int ec_delay __read_mostmodule_param (ec_delay, uint,0644 );MODULE_PARM_DESC (ec_delay,"Timeout(ms) waited until an EC command completes" ); +static unsigned int ec_max_queries__read_mostly =ACPI_EC_MAX_QUERIES ; +module_param (ec_max_queries, uint,0644 ); +MODULE_PARM_DESC (ec_max_queries,"Maximum parallel _Qxx evaluations" ); +static bool ec_busy_polling__read_mostly ;module_param (ec_busy_polling, bool,0644 );MODULE_PARM_DESC (ec_busy_polling,"Use busy polling to advance EC transaction" );
@@ -174,6 +179,7 @@ static void acpi_ec_event_processor(strustruct acpi_ec *boot_ec, *first_ec;EXPORT_SYMBOL (first_ec); +static struct workqueue_struct *ec_query_wq;static int EC_FLAGS_CLEAR_ON_RESUME ;/* Needs acpi_ec_clear() on boot/resume */ static int EC_FLAGS_QUERY_HANDSHAKE ;/* Needs QR_EC issued when SCI_EVT set */
@@ -1098,7 +1104,7 @@ static int acpi_ec_query(struct acpi_ec* work queue execution. */ ec_dbg_evt ("Query(0x%02x) scheduled" , value); -if (!schedule_work (&q->work)) { +if (!queue_work (ec_query_wq, &q->work)) {ec_dbg_evt ("Query(0x%02x) overlapped" , value); result = -EBUSY ; }
@@ -1660,15 +1666,41 @@ static struct acpi_driver acpi_ec_driver }, }; +static inline int acpi_ec_query_init (void ) +{ +if (!ec_query_wq) { + ec_query_wq =alloc_workqueue ("kec_query" ,0 , + ec_max_queries); +if (!ec_query_wq) +return -ENODEV ; + } +return 0 ; +} + +static inline void acpi_ec_query_exit (void ) +{ +if (ec_query_wq) { +destroy_workqueue (ec_query_wq); + ec_query_wq =NULL ; + } +} +int __init acpi_ec_init (void ) { -int result =0 ; +int result; +/* register workqueue for _Qxx evaluations */ + result =acpi_ec_query_init (); +if (result) + goto err_exit;/* Now register the driver for the EC */ result =acpi_bus_register_driver (&acpi_ec_driver); -if (result <0 ) -return -ENODEV ; +if (result) + goto err_exit; +err_exit: +if (result) +acpi_ec_query_exit ();return result; }
@@ -1678,5 +1710,6 @@ static void __exit acpi_ec_exit(void) {acpi_bus_unregister_driver (&acpi_ec_driver); +acpi_ec_query_exit (); }#endif /* 0 */
Greg Kroah-Hartman
maintainerPATCH 181/186 lpfc: fix oops in lpfc_sli4_scmd_to_wqidx_distr() from lpfc_send_taskmgmt()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mauricio Faria de Oliveira <[email protected]>
commit 05a05872c8d4b4357c9d913e6d73ae64882bddf5 upstream.
The lpfc_sli4_scmd_to_wqidx_distr() function expects the scsi_cmnd 'lpfc_cmd->pCmd' not to be null, and point to the midlayer command.
That's not true in the .eh_(device|target|bus)_reset_handler path, because lpfc_send_taskmgmt() sends commands not from the midlayer, so does not set 'lpfc_cmd->pCmd'.
That is true in the .queuecommand path because lpfc_queuecommand() stores the scsi_cmnd from midlayer in lpfc_cmd->pCmd; and lpfc_cmd is stored by lpfc_scsi_prep_cmnd() in piocbq->context1 -- which is passed to lpfc_sli4_scmd_to_wqidx_distr() as lpfc_cmd parameter.
This problem can be hit on SCSI EH, and immediately with sg_reset. These 2 test-cases demonstrate the problem/fix with next-20160601.
Test-case 1) sg_reset
# strace sg_reset --device /dev/sdm
<...>
open("/dev/sdm", O_RDWR|O_NONBLOCK) = 3
ioctl(3, SG_SCSI_RESET, 0x3fffde6d0994 <unfinished ...>
+++ killed by SIGSEGV +++
Segmentation fault # dmesg
Unable to handle kernel paging request for data at address 0x00000000
Faulting instruction address: 0xd00000001c88442c
Oops: Kernel access of bad area, sig: 11 [#1]
<...>
CPU: 104 PID: 16333 Comm: sg_reset Tainted: G W 4.7.0-rc1-next-20160601-00004-g95b89dc #6
<...>
NIP [d00000001c88442c] lpfc_sli4_scmd_to_wqidx_distr+0xc/0xd0 [lpfc]
LR [d00000001c826fe8] lpfc_sli_calc_ring.part.27+0x98/0xd0 [lpfc]
Call Trace:
[c000003c9ec876f0] [c000003c9ec87770] 0xc000003c9ec87770 (unreliable)
[c000003c9ec87720] [d00000001c82e004] lpfc_sli_issue_iocb+0xd4/0x260 [lpfc]
[c000003c9ec87780] [d00000001c831a3c] lpfc_sli_issue_iocb_wait+0x15c/0x5b0 [lpfc]
[c000003c9ec87880] [d00000001c87f27c] lpfc_send_taskmgmt+0x24c/0x650 [lpfc]
[c000003c9ec87950] [d00000001c87fd7c] lpfc_device_reset_handler+0x10c/0x200 [lpfc]
[c000003c9ec87a10] [c000000000610694] scsi_try_bus_device_reset+0x44/0xc0
[c000003c9ec87a40] [c0000000006113e8] scsi_ioctl_reset+0x198/0x2c0
[c000003c9ec87bf0] [c00000000060fe5c] scsi_ioctl+0x13c/0x4b0
[c000003c9ec87c80] [c0000000006629b0] sd_ioctl+0xf0/0x120
[c000003c9ec87cd0] [c00000000046e4f8] blkdev_ioctl+0x248/0xb70
[c000003c9ec87d30] [c0000000002a1f60] block_ioctl+0x70/0x90
[c000003c9ec87d50] [c00000000026d334] do_vfs_ioctl+0xc4/0x890
[c000003c9ec87de0] [c00000000026db60] SyS_ioctl+0x60/0xc0
[c000003c9ec87e30] [c000000000009120] system_call+0x38/0x108
Instruction dump:
<...> With fix:
# strace sg_reset --device /dev/sdm
<...>
open("/dev/sdm", O_RDWR|O_NONBLOCK) = 3
ioctl(3, SG_SCSI_RESET, 0x3fffe103c554) = 0
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
# dmesg
[ 424.658649] lpfc 0006:01:00.4: 4:(0):0713 SCSI layer issued Device Reset (1, 0) return x2002Test-case 2) SCSI EH
Using this debug patch to wire an SCSI EH trigger, for lpfc_scsi_cmd_iocb_cmpl():
- cmd->scsi_done(cmd);
+ if ((phba->pport ? phba->pport->cfg_log_verbose : phba->cfg_log_verbose) == 0x32100000)
+ printk(KERN_ALERT "lpfc: skip scsi_done()\n");
+ else
+ cmd->scsi_done(cmd);
# echo 0x32100000 > /sys/class/scsi_host/host11/lpfc_log_verbose
# dd if=/dev/sdm of=/dev/null iflag=direct &
<...>
After a while:
# dmesg
lpfc 0006:01:00.4: 4:(0):3053 lpfc_log_verbose changed from 0 (x0) to 839909376 (x32100000)
lpfc: skip scsi_done()
<...>
Unable to handle kernel paging request for data at address 0x00000000
Faulting instruction address: 0xd0000000199e448c
Oops: Kernel access of bad area, sig: 11 [#1]
<...>
CPU: 96 PID: 28556 Comm: scsi_eh_11 Tainted: G W 4.7.0-rc1-next-20160601-00004-g95b89dc #6
<...>
NIP [d0000000199e448c] lpfc_sli4_scmd_to_wqidx_distr+0xc/0xd0 [lpfc]
LR [d000000019986fe8] lpfc_sli_calc_ring.part.27+0x98/0xd0 [lpfc]
Call Trace:
[c000000ff0d0b890] [c000000ff0d0b900] 0xc000000ff0d0b900 (unreliable)
[c000000ff0d0b8c0] [d00000001998e004] lpfc_sli_issue_iocb+0xd4/0x260 [lpfc]
[c000000ff0d0b920] [d000000019991a3c] lpfc_sli_issue_iocb_wait+0x15c/0x5b0 [lpfc]
[c000000ff0d0ba20] [d0000000199df27c] lpfc_send_taskmgmt+0x24c/0x650 [lpfc]
[c000000ff0d0baf0] [d0000000199dfd7c] lpfc_device_reset_handler+0x10c/0x200 [lpfc]
[c000000ff0d0bbb0] [c000000000610694] scsi_try_bus_device_reset+0x44/0xc0
[c000000ff0d0bbe0] [c0000000006126cc] scsi_eh_ready_devs+0x49c/0x9c0
[c000000ff0d0bcb0] [c000000000614160] scsi_error_handler+0x580/0x680
[c000000ff0d0bd80] [c0000000000ae848] kthread+0x108/0x130
[c000000ff0d0be30] [c0000000000094a8] ret_from_kernel_thread+0x5c/0xb4
Instruction dump:
<...>
With fix:
# dmesg
lpfc 0006:01:00.4: 4:(0):3053 lpfc_log_verbose changed from 0 (x0) to 839909376 (x32100000)
lpfc: skip scsi_done()
<...>
lpfc 0006:01:00.4: 4:(0):0713 SCSI layer issued Device Reset (0, 0) return x2002
<...>
lpfc 0006:01:00.4: 4:(0):0723 SCSI layer issued Target Reset (1, 0) return x2002
<...>
lpfc 0006:01:00.4: 4:(0):0714 SCSI layer issued Bus Reset Data: x2002
<...>
lpfc 0006:01:00.4: 4:(0):3172 SCSI layer issued Host Reset Data:
<...>--- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_scsi.c +1 -1
@@ -3874,7 +3874,7 @@ int lpfc_sli4_scmd_to_wqidx_distr(structuint32_t tag;uint16_t hwq; -if (shost_use_blk_mq (cmnd->device->host)) { +if (cmnd &&shost_use_blk_mq (cmnd->device->host)) { tag =blk_mq_unique_tag (cmnd->request); hwq =blk_mq_unique_tag_to_hwq (tag);
Greg Kroah-Hartman
maintainerPATCH 182/186 rtc: s3c: Add s3c_rtc_{enable/disable}_clk in s3c_rtc_setfreq()
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alim Akhtar <[email protected]>
commit 70c96dfac0e231424e17743bd52f6cd2ff1f2439 upstream.
As per code flow s3c_rtc_setfreq() will get called with rtc clock disabled and in set_freq we perform h/w registers read/write, which results in a kernel crash on exynos7 platform while probing rtc driver.
Below is code flow:s3c_rtc_probe()
clk_prepare_enable(info->rtc_clk) // rtc clock enabled s3c_rtc_gettime() // will enable clk if not done, and disable it upon exit s3c_rtc_setfreq() //then this will be called with clk disabled
This patch take cares of such issue by adding s3c_rtc_{enable/disable}_clk in s3c_rtc_setfreq().
--- drivers/rtc/rtc-s3c.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/rtc/rtc-s3c.c +2 -0
@@ -149,12 +149,14 @@ static int s3c_rtc_setfreq(struct s3c_rtif (!is_power_of_2 (freq))return -EINVAL ; +s3c_rtc_enable_clk (info);spin_lock_irq (&info->pie_lock);if (info->data->set_freq) info->data->set_freq (info, freq);spin_unlock_irq (&info->pie_lock); +s3c_rtc_disable_clk (info);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 183/186 dm flakey: error READ bios during the down_interval
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Snitzer <[email protected]>
commit 99f3c90d0d85708e7401a81ce3314e50bf7f2819 upstream.
When the corrupt_bio_byte feature was introduced it caused READ bios to no longer be errored with -EIO during the down_interval. This had to do with the complexity of needing to submit READs if the corrupt_bio_byte feature was used.
Fix it so READ bios are properly errored with -EIO; doing so early in flakey_map() as long as there isn't a match for the corrupt_bio_byte feature.
--- drivers/md/dm-flakey.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
drivers/md/dm-flakey.c +15 -8
@@ -289,10 +289,16 @@ static int flakey_map(struct dm_target * pb->bio_submitted = true;/* -* Map reads as normal. +* Map reads as normal only if corrupt_bio_byte set. */ -if (bio_data_dir (bio) ==READ ) - goto map_bio; +if (bio_data_dir (bio) ==READ ) { +/* If flags were specified, only corrupt those that match. */ +if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw ==READ ) && +all_corrupt_bio_flags_match (bio, fc)) + goto map_bio; +else +return -EIO ; + }/* * Drop writes?
@@ -330,12 +336,13 @@ static int flakey_end_io(struct dm_targe/* * Corrupt successful READs while in down state. -* If flags were specified, only corrupt those that match. */ -if (fc->corrupt_bio_byte && !error && pb->bio_submitted && - (bio_data_dir (bio) ==READ ) && (fc->corrupt_bio_rw ==READ ) && -all_corrupt_bio_flags_match (bio, fc)) -corrupt_bio_data (bio, fc); +if (!error && pb->bio_submitted && (bio_data_dir (bio) ==READ )) { +if (fc->corrupt_bio_byte) +corrupt_bio_data (bio, fc); +else +return -EIO ; + }return error; }
Greg Kroah-Hartman
maintainerPATCH 184/186 module: Invalidate signatures on force-loaded modules
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <[email protected]>
commit bca014caaa6130e57f69b5bf527967aa8ee70fdd upstream.
Signing a module should only make it trusted by the specific kernel it was built for, not anything else. Loading a signed module meant for a kernel with a different ABI could have interesting effects. Therefore, treat all signatures as invalid when a module is force-loaded.
--- kernel/module.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
kernel/module.c +9 -4
@@ -2687,13 +2687,18 @@ static inline void kmemleak_load_module(#endif #ifdef CONFIG_MODULE_SIG -static int module_sig_check (struct load_info *info) +static int module_sig_check (struct load_info *info,int flags) {int err = -ENOKEY ;const unsigned long markerlen =sizeof (MODULE_SIG_STRING ) -1 ;const void *mod = info->hdr; -if (info->len > markerlen && +/* +* Require flags == 0, as a module with version information +* removed is no longer the module that was signed +*/ +if (flags ==0 && + info->len > markerlen &&memcmp (mod + info->len - markerlen,MODULE_SIG_STRING , markerlen) ==0 ) {/* We truncate the module to discard the signature */ info->len -= markerlen;
@@ -2712,7 +2717,7 @@ static int module_sig_check(struct load_ return err; }#else /* !CONFIG_MODULE_SIG */ -static int module_sig_check (struct load_info *info) +static int module_sig_check (struct load_info *info,int flags) {return 0 ; }
@@ -3498,7 +3503,7 @@ static int load_module(struct load_infolong err;char *after_dashes; - err =module_sig_check (info); + err =module_sig_check (info, flags);if (err) goto free_copy;
Greg Kroah-Hartman
maintainerPATCH 185/186 Documentation/module-signing.txt: Note need for version info if reusing a key
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <[email protected]>
commit b8612e517c3c9809e1200b72c474dbfd969e5a83 upstream.
Signing a module should only make it trusted by the specific kernel it was built for, not anything else. If a module signing key is used for multiple ABI-incompatible kernels, the modules need to include enough version information to distinguish them.
--- Documentation/module-signing.txt | 6 ++++++ 1 file changed, 6 insertions(+)
Documentation/module-signing.txt +6 -0
@@ -271,3 +271,9 @@ Since the private key is used to sign mo the private key to sign modules and compromise the operating system. The private key must be either destroyed or moved to a secure location and not kept in the root node of the kernel source tree. + +If you use the same private key to sign modules for multiple kernel +configurations, you must ensure that the module version information is +sufficient to prevent loading a module into a different kernel. Either +set CONFIG_MODVERSIONS=y or ensure that each configuration has a different +kernel release string by changing EXTRAVERSION or CONFIG_LOCALVERSION.
Greg Kroah-Hartman
maintainerPATCH 186/186 phy: rcar-gen3-usb2: fix mutex_lock calling in interrupt
In reply to a message not in the archive4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yoshihiro Shimoda <[email protected]>
commit c14f8a4032efa73d9c4e155add47c19252b3bdf4 upstream.
This patch fixes an issue that the extcon_set_cable_state_() is possible to cause "BUG: scheduling while atomic" because this driver calls extcon_set_cable_state_() in the interrupt handler and mutex_lock() is possible to be called by like the following call trace. So, this patch adds a workqueue function to resolve this issue.
[ 9.706504] BUG: scheduling while atomic: systemd-journal/25893/0x00010303 [ 9.714569] Modules linked in: [ 9.717629] CPU: 0 PID: 25893 Comm: systemd-journal Not tainted 4.7.0-rc4+ #86 [ 9.724844] Hardware name: Renesas Salvator-X board based on r8a7795 (DT) [ 9.731624] Call trace: [ 9.734077] [<ffff0000080889f0>] dump_backtrace+0x0/0x1a8 [ 9.739470] [<ffff000008088bac>] show_stack+0x14/0x20 [ 9.744520] [<ffff000008348ab4>] dump_stack+0x94/0xb8 [ 9.749568] [<ffff0000080da18c>] __schedule_bug+0x44/0x58 [ 9.754966] [<ffff0000087c6394>] __schedule+0x4e4/0x598 [ 9.760185] [<ffff0000087c6484>] schedule+0x3c/0xa8 [ 9.765057] [<ffff0000087c6928>] schedule_preempt_disabled+0x20/0x38 [ 9.771408] [<ffff0000080f20dc>] mutex_optimistic_spin+0x18c/0x1d0 [ 9.777583] [<ffff0000087c7ef0>] __mutex_lock_slowpath+0x38/0x140 [ 9.783669] [<ffff0000087c803c>] mutex_lock+0x44/0x60 [ 9.788717] [<ffff00000834ca48>] kobject_uevent_env+0x250/0x500 [ 9.794634] [<ffff0000086ae8c0>] extcon_update_state+0x220/0x298 [ 9.800634] [<ffff0000086ae9d8>] extcon_set_cable_state_+0x78/0x88 [ 9.806812] [<ffff000008376004>] rcar_gen3_device_recognition+0x5c/0xe0 [ 9.813420] [<ffff0000083761bc>] rcar_gen3_phy_usb2_irq+0x3c/0x48 [ 9.819509] [<ffff0000080fae94>] handle_irq_event_percpu+0x94/0x140 [ 9.825769] [<ffff0000080faf88>] handle_irq_event+0x48/0x78 [ 9.831334] [<ffff0000080fe620>] handle_fasteoi_irq+0xb8/0x1b0 [ 9.837162] [<ffff0000080fa3c4>] generic_handle_irq+0x24/0x38 [ 9.842900] [<ffff0000080fa6fc>] __handle_domain_irq+0x5c/0xb8 [ 9.848727] [<ffff000008081520>] gic_handle_irq+0x58/0xb0
--- drivers/phy/phy-rcar-gen3-usb2.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-)
drivers/phy/phy-rcar-gen3-usb2.c +22 -4
@@ -21,6 +21,7 @@#include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> +#include <linux/workqueue.h> /******* USB2.0 Host registers (original offset is +0x200) *******/ #define USB2_INT_ENABLE 0x000
@@ -81,9 +82,25 @@ struct rcar_gen3_chan {struct extcon_dev *extcon;struct phy *phy;struct regulator *vbus; +struct work_struct work; +bool extcon_host;bool has_otg; }; +static void rcar_gen3_phy_usb2_work (struct work_struct *work) +{ + struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan, + work); + +if (ch->extcon_host) { +extcon_set_cable_state_ (ch->extcon,EXTCON_USB_HOST , true); +extcon_set_cable_state_ (ch->extcon,EXTCON_USB , false); + }else { +extcon_set_cable_state_ (ch->extcon,EXTCON_USB_HOST , false); +extcon_set_cable_state_ (ch->extcon,EXTCON_USB , true); + } +} +static void rcar_gen3_set_host_mode (struct rcar_gen3_chan *ch,int host) {void __iomem *usb2_base = ch->base;
@@ -130,8 +147,8 @@ static void rcar_gen3_init_for_host(strurcar_gen3_set_host_mode (ch,1 );rcar_gen3_enable_vbus_ctrl (ch,1 ); -extcon_set_cable_state_ (ch->extcon,EXTCON_USB_HOST , true); -extcon_set_cable_state_ (ch->extcon,EXTCON_USB , false); + ch->extcon_host = true; +schedule_work (&ch->work); }static void rcar_gen3_init_for_peri (struct rcar_gen3_chan *ch)
@@ -140,8 +157,8 @@ static void rcar_gen3_init_for_peri(strurcar_gen3_set_host_mode (ch,0 );rcar_gen3_enable_vbus_ctrl (ch,0 ); -extcon_set_cable_state_ (ch->extcon,EXTCON_USB_HOST , false); -extcon_set_cable_state_ (ch->extcon,EXTCON_USB , true); + ch->extcon_host = false; +schedule_work (&ch->work); }static bool rcar_gen3_check_id (struct rcar_gen3_chan *ch)
@@ -301,6 +318,7 @@ static int rcar_gen3_phy_usb2_probe(struif (irq >=0 ) {int ret; +INIT_WORK (&channel->work, rcar_gen3_phy_usb2_work); irq =devm_request_irq (dev, irq, rcar_gen3_phy_usb2_irq,IRQF_SHARED ,dev_name (dev), channel);if (irq <0 )
Re: [PATCH 4.7 000/186] 4.7.2-stable review
In reply to a message not in the archiveQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.7.2 release. There are 186 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 Sat Aug 20 13:59:06 UTC 2016. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.7.2-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.7.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Signature · 5 lines
Shuah Khan Sr. Linux Kernel Developer Open Source Innovation Group Samsung Research America(Silicon Valley) [email protected]
Greg Kroah-Hartman
maintainerRe: [PATCH 4.7 000/186] 4.7.2-stable review
Quoted 15 lines · Shuah Khan
Quoted 14 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.7.2 release. There are 186 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 Sat Aug 20 13:59:06 UTC 2016. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.7.2-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.7.y
and the diffstat can be found below.
Quoted 6 lines
Quoted 4 lines
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Thanks for testing all of these and letting me know.
greg k-h
Re: [PATCH 4.7 000/186] 4.7.2-stable review
In reply to a message not in the archiveQuoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.7.2 release. There are 186 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 Sat Aug 20 13:59:06 UTC 2016. Anything received after that time might be too late.
Build results:
total: 148 pass: 148 fail: 0 Qemu test results: total: 107 pass: 107 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter
Greg Kroah-Hartman
maintainerRe: [PATCH 4.7 000/186] 4.7.2-stable review
Quoted 6 lines · Guenter Roeck
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.7.2 release. There are 186 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.
Quoted 7 lines
Quoted 3 lines
Responses should be made by Sat Aug 20 13:59:06 UTC 2016. Anything received after that time might be too late.
Build results:
total: 148 pass: 148 fail: 0 Qemu test results: total: 107 pass: 107 fail: 0
Yes, we finally did it! :)
thanks for the reports, much appreciated.
greg k-h
A message that is not in the archive (sent off-list or not yet received): [email protected]
Greg Kroah-Hartman
maintainerRe: [PATCH 4.7 000/186] 4.7.2-stable review
Quoted 4 lines · kernelci.org bot
stable-rc boot: 146 boots: 0 failed, 139 passed with 7 offline (v4.7.1-186-ge94b177018fe)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/kernel/v4.7.1-186-ge94b177018fe/
Full Build Summary: https://kernelci.org/build/stable-rc/kernel/v4.7.1-186-ge94b177018fe/
Great, thanks for this, and the 2 other reports, much appreciated.
greg k-h