5.4.86-rc1 review
Subsystems (10)
Greg Kroah-Hartman
maintainerPATCH 349/453 s390/dasd: fix hanging device offline processing
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 658a337a606f48b7ebe451591f7681d383fa115e upstream.
For an LCU update a read unit address configuration IO is required. This is started using sleep_on(), which has early exit paths in case the device is not usable for IO. For example when it is in offline processing.
In those cases the LCU update should fail and not be retried. Therefore lcu_update_work checks if EOPNOTSUPP is returned or not.
Commit 41995342b40c ("s390/dasd: fix endless loop after read unit address configuration") accidentally removed the EOPNOTSUPP return code from read_unit_address_configuration(), which in turn might lead to an endless loop of the LCU update in offline processing.
Fix by returning EOPNOTSUPP again if the device is not able to perform the request.
--- drivers/s390/block/dasd_alias.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/s390/block/dasd_alias.c +9 -1
@@ -462,11 +462,19 @@ static int read_unit_address_configuratispin_unlock_irqrestore (&lcu->lock, flags); rc =dasd_sleep_on (cqr); -if (rc && !suborder_not_supported (cqr)) { +if (!rc) + goto out; + +if (suborder_not_supported (cqr)) { +/* suborder not supported or device unusable for IO */ + rc = -EOPNOTSUPP ; + }else { +/* IO failed but should be retried */ spin_lock_irqsave (&lcu->lock, flags); lcu->flags |=NEED_UAC_UPDATE ;spin_unlock_irqrestore (&lcu->lock, flags); } +out:dasd_sfree_request (cqr, cqr->memdev);return rc; }
Greg Kroah-Hartman
maintainerPATCH 350/453 s390/dasd: prevent inconsistent LCU device data
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit a29ea01653493b94ea12bb2b89d1564a265081b6 upstream.
Prevent _lcu_update from adding a device to a pavgroup if the LCU still requires an update. The data is not reliable any longer and in parallel devices might have been moved on the lists already.
This might lead to list corruptions or invalid PAV grouping. Only add devices to a pavgroup if the LCU is up to date. Additional steps are taken by the scheduled lcu update.
--- drivers/s390/block/dasd_alias.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/s390/block/dasd_alias.c +9 -0
@@ -511,6 +511,14 @@ static int _lcu_update(struct dasd_devicreturn rc;spin_lock_irqsave (&lcu->lock, flags); +/* +* there is another update needed skip the remaining handling +* the data might already be outdated +* but especially do not add the device to an LCU with pending +* update +*/ +if (lcu->flags &NEED_UAC_UPDATE ) + goto out; lcu->pav =NO_PAV ;for (i =0 ; i <MAX_DEVICES_PER_LCU ; ++i) {switch (lcu->uac->unit[i].ua_type) {
@@ -529,6 +537,7 @@ static int _lcu_update(struct dasd_devic alias_list) {_add_device_to_lcu (lcu, device, refdev); } +out:spin_unlock_irqrestore (&lcu->lock, flags);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 351/453 s390/dasd: fix list corruption of pavgroup group list
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 0ede91f83aa335da1c3ec68eb0f9e228f269f6d8 upstream.
dasd_alias_add_device() moves devices to the active_devices list in case of a scheduled LCU update regardless if they have previously been in a pavgroup or not.
Example: device A and B are in the same pavgroup.
Device A has already been in a pavgroup and the private->pavgroup pointer is set and points to a valid pavgroup. While going through dasd_add_device it is moved from the pavgroup to the active_devices list.
In parallel device B might be removed from the same pavgroup in remove_device_from_lcu() which in turn checks if the group is empty and deletes it accordingly because device A has already been removed from there.
When now device A enters remove_device_from_lcu() it is tried to remove it from the pavgroup again because the pavgroup pointer is still set and again the empty group will be cleaned up which leads to a list corruption.
Fix by setting private->pavgroup to NULL in dasd_add_device.
If the device has been the last device on the pavgroup an empty pavgroup remains but this will be cleaned up by the scheduled lcu_update which iterates over all existing pavgroups.
--- drivers/s390/block/dasd_alias.c | 1 + 1 file changed, 1 insertion(+)
drivers/s390/block/dasd_alias.c +1 -0
@@ -642,6 +642,7 @@ int dasd_alias_add_device(struct dasd_de }if (lcu->flags &UPDATE_PENDING ) {list_move (&device->alias_list, &lcu->active_devices); + private->pavgroup =NULL ;_schedule_lcu_update (lcu, device); }spin_unlock_irqrestore (&lcu->lock, flags);
Greg Kroah-Hartman
maintainerPATCH 352/453 s390/dasd: fix list corruption of lcu list
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 53a7f655834c7c335bf683f248208d4fbe4b47bc upstream.
In dasd_alias_disconnect_device_from_lcu the device is removed from any list on the LCU. Afterwards the LCU is removed from the lcu list if it does not contain devices any longer.
The lcu->lock protects the lcu from parallel updates. But to cancel all workers and wait for completion the lcu->lock has to be unlocked.
If two devices are removed in parallel and both are removed from the LCU the first device that takes the lcu->lock again will delete the LCU because it is already empty but the second device also tries to free the LCU which leads to a list corruption of the lcu list.
Fix by removing the device right before the lcu is checked without unlocking the lcu->lock in between.
--- drivers/s390/block/dasd_alias.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/block/dasd_alias.c +1 -1
@@ -256,7 +256,6 @@ void dasd_alias_disconnect_device_from_lreturn ; device->discipline->get_uid (device, &uid);spin_lock_irqsave (&lcu->lock, flags); -list_del_init (&device->alias_list);/* make sure that the workers don't use this device */ if (device == lcu->suc_data.device) {spin_unlock_irqrestore (&lcu->lock, flags);
@@ -283,6 +282,7 @@ void dasd_alias_disconnect_device_from_lspin_lock_irqsave (&aliastree.lock, flags);spin_lock (&lcu->lock); +list_del_init (&device->alias_list);if (list_empty (&lcu->grouplist) &&list_empty (&lcu->active_devices) &&list_empty (&lcu->inactive_devices)) {
Greg Kroah-Hartman
maintainerPATCH 353/453 binder: add flag to clear buffer on txn complete
In reply to Greg Kroah-HartmanFrom: Todd Kjos <[email protected]>
commit 0f966cba95c78029f491b433ea95ff38f414a761 upstream.
Add a per-transaction flag to indicate that the buffer must be cleared when the transaction is complete to prevent copies of sensitive data from being preserved in memory.
--- drivers/android/binder.c | 1 drivers/android/binder_alloc.c | 48 ++++++++++++++++++++++++++++++++++++ drivers/android/binder_alloc.h | 4 ++- include/uapi/linux/android/binder.h | 1 4 files changed, 53 insertions(+), 1 deletion(-)
drivers/android/binder.c +1 -0
@@ -3150,6 +3150,7 @@ static void binder_transaction(struct bi t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; t->buffer->target_node = target_node; + t->buffer->clear_on_free = !!(t->flags &TF_CLEAR_BUF );trace_binder_transaction_alloc_buf (t->buffer); if (binder_alloc_copy_user_to_buffer(
drivers/android/binder_alloc.c +48 -0
72 lines not on this page · raw message
drivers/android/binder_alloc.h +3 -1
@@ -23,6 +23,7 @@ struct binder_transaction;* @entry: entry alloc->buffers * @rb_node: node for allocated_buffers/free_buffers rb trees * @free: %true if buffer is free +* @clear_on_free: %true if buffer must be zeroed after use * @allow_user_free: %true if user is allowed to free buffer * @async_transaction: %true if buffer is in use for an async txn * @debug_id: unique ID for debugging
@@ -40,9 +41,10 @@ struct binder_buffer {struct rb_node rb_node;/* free entry by size or allocated entry */ /* by address */ unsigned free:1; + unsigned clear_on_free:1; unsigned allow_user_free:1; unsigned async_transaction:1; - unsigned debug_id:29; + unsigned debug_id:28;struct binder_transaction *transaction;
include/uapi/linux/android/binder.h +1 -0
@@ -248,6 +248,7 @@ enum transaction_flags {TF_ROOT_OBJECT =0x04 ,/* contents are the component's root object */ TF_STATUS_CODE =0x08 ,/* contents are a 32-bit status code */ TF_ACCEPT_FDS =0x10 ,/* allow replies with file descriptors */ + TF_CLEAR_BUF = 0x20, /* clear buffer on txn complete */ }; struct binder_transaction_data {
Greg Kroah-Hartman
maintainerPATCH 354/453 ASoC: cx2072x: Fix doubly definitions of Playback and Capture streams
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 0d024a8bec084205fdd9fa17479ba91f45f85db3 upstream.
The cx2072x codec driver defines multiple DAIs with the same stream name "Playback" and "Capture". Although the current code works more or less as is as the secondary streams are never used, it still leads the error message like:
debugfs: File 'Playback' in directory 'dapm' already present!
debugfs: File 'Capture' in directory 'dapm' already present!
Fix it by renaming the secondary streams to unique names.
--- sound/soc/codecs/cx2072x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/cx2072x.c +2 -2
@@ -1579,7 +1579,7 @@ static struct snd_soc_dai_driver soc_cod .id = CX2072X_DAI_DSP, .probe = cx2072x_dsp_dai_probe, .playback = { - .stream_name = "Playback", + .stream_name = "DSP Playback", .channels_min = 2, .channels_max = 2, .rates = CX2072X_RATES_DSP,
@@ -1591,7 +1591,7 @@ static struct snd_soc_dai_driver soc_cod .name = "cx2072x-aec", .id = 3, .capture = { - .stream_name = "Capture", + .stream_name = "AEC Capture", .channels_min = 2, .channels_max = 2, .rates = CX2072X_RATES_DSP,
Greg Kroah-Hartman
maintainerPATCH 355/453 staging: comedi: mf6x4: Fix AI end-of-conversion detection
In reply to Greg Kroah-HartmanFrom: Ian Abbott <[email protected]>
commit 56c90457ebfe9422496aac6ef3d3f0f0ea8b2ec2 upstream.
I have had reports from two different people that attempts to read the analog input channels of the MF624 board fail with an ETIMEDOUT error.
After triggering the conversion, the code calls comedi_timeout() with mf6x4_ai_eoc() as the callback function to check if the conversion is complete. The callback returns 0 if complete or -EBUSY if not yet complete. comedi_timeout() returns -ETIMEDOUT if it has not completed within a timeout period which is propagated as an error to the user application.
The existing code considers the conversion to be complete when the EOLC bit is high. However, according to the user manuals for the MF624 and MF634 boards, this test is incorrect because EOLC is an active low signal that goes high when the conversion is triggered, and goes low when the conversion is complete. Fix the problem by inverting the test of the EOLC bit state.
--- drivers/staging/comedi/drivers/mf6x4.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/staging/comedi/drivers/mf6x4.c +2 -1
@@ -112,8 +112,9 @@ static int mf6x4_ai_eoc(struct comedi_destruct mf6x4_private *devpriv = dev->private;unsigned int status; +/* EOLC goes low at end of conversion. */ status =ioread32 (devpriv->gpioc_reg); -if (status &MF6X4_GPIOC_EOLC ) +if ((status &MF6X4_GPIOC_EOLC ) ==0 )return 0 ;return -EBUSY ; }
Greg Kroah-Hartman
maintainerPATCH 356/453 perf/x86/intel: Add event constraint for CYCLE_ACTIVITY.STALLS_MEM_ANY
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
commit 306e3e91edf1c6739a55312edd110d298ff498dd upstream.
The event CYCLE_ACTIVITY.STALLS_MEM_ANY (0x14a3) should be available on all 8 GP counters on ICL, but it's only scheduled on the first four counters due to the current ICL constraint table.
Add a line for the CYCLE_ACTIVITY.STALLS_MEM_ANY event in the ICL constraint table.
Correct the comments for the CYCLE_ACTIVITY.CYCLES_MEM_ANY event.
--- arch/x86/events/intel/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/events/intel/core.c +2 -1
@@ -253,7 +253,8 @@ static struct event_constraint intel_iclINTEL_EVENT_CONSTRAINT_RANGE (0x48 ,0x54 ,0xf ),INTEL_EVENT_CONSTRAINT_RANGE (0x60 ,0x8b ,0xf ),INTEL_UEVENT_CONSTRAINT (0x04a3 ,0xff ),/* CYCLE_ACTIVITY.STALLS_TOTAL */ -INTEL_UEVENT_CONSTRAINT (0x10a3 ,0xff ),/* CYCLE_ACTIVITY.STALLS_MEM_ANY */ +INTEL_UEVENT_CONSTRAINT (0x10a3 ,0xff ),/* CYCLE_ACTIVITY.CYCLES_MEM_ANY */ +INTEL_UEVENT_CONSTRAINT (0x14a3 ,0xff ),/* CYCLE_ACTIVITY.STALLS_MEM_ANY */ INTEL_EVENT_CONSTRAINT (0xa3 ,0xf ),/* CYCLE_ACTIVITY.* */ INTEL_EVENT_CONSTRAINT_RANGE (0xa8 ,0xb0 ,0xf ), INTEL_EVENT_CONSTRAINT_RANGE(0xb7, 0xbd, 0xf),
Greg Kroah-Hartman
maintainerPATCH 357/453 perf/x86/intel: Fix rtm_abort_event encoding on Ice Lake
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
commit 46b72e1bf4fc571da0c29c6fb3e5b2a2107a4c26 upstream.
According to the event list from icelake_core_v1.09.json, the encoding of the RTM_RETIRED.ABORTED event on Ice Lake should be,
"EventCode": "0xc9",
"UMask": "0x04",
"EventName": "RTM_RETIRED.ABORTED",Correct the wrong encoding.
--- arch/x86/events/intel/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/events/intel/core.c +1 -1
@@ -5058,7 +5058,7 @@ __init int intel_pmu_init(void) extra_skl_attr = skl_format_attr; mem_attr = icl_events_attrs; tsx_attr = icl_tsx_events_attrs; - x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xca, .umask=0x02); + x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xc9, .umask=0x04); x86_pmu.lbr_pt_coexist = true;intel_pmu_pebs_data_source_skl (pmem);pr_cont ("Icelake events, " );
Greg Kroah-Hartman
maintainerPATCH 358/453 powerpc/perf: Exclude kernel samples while counting events in user space.
In reply to Greg Kroah-HartmanFrom: Athira Rajeev <[email protected]>
commit aa8e21c053d72b6639ea5a7f1d3a1d0209534c94 upstream.
Perf event attritube supports exclude_kernel flag to avoid sampling/profiling in supervisor state (kernel). Based on this event attr flag, Monitor Mode Control Register bit is set to freeze on supervisor state. But sometimes (due to hardware limitation), Sampled Instruction Address Register (SIAR) locks on to kernel address even when freeze on supervisor is set. Patch here adds a check to drop those samples.
--- arch/powerpc/perf/core-book3s.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/powerpc/perf/core-book3s.c +10 -0
@@ -2090,6 +2090,16 @@ static void record_and_restart(struct peperf_event_update_userpage (event);/* +* Due to hardware limitation, sometimes SIAR could sample a kernel +* address even when freeze on supervisor state (kernel) is set in +* MMCR2. Check attr.exclude_kernel and address to drop the sample in +* these cases. +*/ +if (event->attr.exclude_kernel && record) +if (is_kernel_addr (mfspr (SPRN_SIAR ))) + record =0 ; + +/* * Finally record data if requested. */ if (record) {
Greg Kroah-Hartman
maintainerPATCH 359/453 crypto: ecdh - avoid unaligned accesses in ecdh_set_secret()
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit 17858b140bf49961b71d4e73f1c3ea9bc8e7dda0 upstream.
ecdh_set_secret() casts a void* pointer to a const u64* in order to feed it into ecc_is_key_valid(). This is not generally permitted by the C standard, and leads to actual misalignment faults on ARMv6 cores. In some cases, these are fixed up in software, but this still leads to performance hits that are entirely avoidable.
So let's copy the key into the ctx buffer first, which we will do anyway in the common case, and which guarantees correct alignment.
--- crypto/ecdh.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
crypto/ecdh.c +5 -4
@@ -53,12 +53,13 @@ static int ecdh_set_secret(struct cryptoreturn ecc_gen_privkey (ctx->curve_id, ctx->ndigits, ctx->private_key); -if (ecc_is_key_valid (ctx->curve_id, ctx->ndigits, - (const u64 *)params.key, params.key_size) <0 ) -return -EINVAL ; -memcpy (ctx->private_key, params.key, params.key_size); +if (ecc_is_key_valid (ctx->curve_id, ctx->ndigits, + ctx->private_key, params.key_size) <0 ) { +memzero_explicit (ctx->private_key, params.key_size); +return -EINVAL ; + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 360/453 crypto: arm/aes-ce - work around Cortex-A57/A72 silion errata
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit f3456b9fd269c6d0c973b136c5449d46b2510f4b upstream.
ARM Cortex-A57 and Cortex-A72 cores running in 32-bit mode are affected by silicon errata #1742098 and #1655431, respectively, where the second instruction of a AES instruction pair may execute twice if an interrupt is taken right after the first instruction consumes an input register of which a single 32-bit lane has been updated the last time it was modified.
This is not such a rare occurrence as it may seem: in counter mode, only the least significant 32-bit word is incremented in the absence of a carry, which makes our counter mode implementation susceptible to these errata.
So let's shuffle the counter assignments around a bit so that the most recent updates when the AES instruction pair executes are 128-bit wide.
[0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice
[1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice
--- arch/arm/crypto/aes-ce-core.S | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-)
arch/arm/crypto/aes-ce-core.S +22 -10
@@ -386,20 +386,32 @@ ENTRY(ce_aes_ctr_encrypt) .Lctrloop4x: subs r4, r4, #4 bmi .Lctr1x - add r6, r6, #1 + + /* + * NOTE: the sequence below has been carefully tweaked to avoid + * a silicon erratum that exists in Cortex-A57 (#1742098) and + * Cortex-A72 (#1655431) cores, where AESE/AESMC instruction pairs + * may produce an incorrect result if they take their input from a + * register of which a single 32-bit lane has been updated the last + * time it was modified. To work around this, the lanes of registers + * q0-q3 below are not manipulated individually, and the different + * counter values are prepared by successive manipulations of q7. + */ + add ip, r6, #1 vmov q0, q7 + rev ip, ip + add lr, r6, #2 + vmov s31, ip @ set lane 3 of q1 via q7 + add ip, r6, #3 + rev lr, lr vmov q1, q7 - rev ip, r6 - add r6, r6, #1 + vmov s31, lr @ set lane 3 of q2 via q7 + rev ip, ip vmov q2, q7 - vmov s7, ip - rev ip, r6 - add r6, r6, #1 + vmov s31, ip @ set lane 3 of q3 via q7 + add r6, r6, #4 vmov q3, q7 - vmov s11, ip - rev ip, r6 - add r6, r6, #1 - vmov s15, ip + vld1.8 {q4-q5}, [r1]! vld1.8 {q6}, [r1]! vld1.8 {q15}, [r1]!
Greg Kroah-Hartman
maintainerPATCH 361/453 EDAC/i10nm: Use readl() to access MMIO registers
In reply to Greg Kroah-HartmanFrom: Qiuxu Zhuo <[email protected]>
commit 83ff51c4e3fecf6b8587ce4d46f6eac59f5d7c5a upstream.
Instead of raw access, use readl() to access MMIO registers of memory controller to avoid possible compiler re-ordering.
--- drivers/edac/i10nm_base.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/edac/i10nm_base.c +7 -4
@@ -6,6 +6,7 @@*/ #include <linux/kernel.h> +#include <linux/io.h> #include <asm/cpu_device_id.h> #include <asm/intel-family.h> #include <asm/mce.h>
@@ -19,14 +20,16 @@ #define i10nm_printk(level, fmt, arg...) \ edac_printk(level, "i10nm", fmt, ##arg) -#define I10NM_GET_SCK_BAR (d, reg) \ +#define I10NM_GET_SCK_BAR (d, reg) \ pci_read_config_dword((d)->uracu, 0xd0, &(reg))#define I10NM_GET_IMC_BAR (d, i, reg) \ pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))#define I10NM_GET_DIMMMTR (m, i, j) \ - (*(u32 *)((m)->mbase + 0x2080c + (i) * 0x4000 + (j) * 4)) + readl((m)->mbase + 0x2080c + (i) * 0x4000 + (j) * 4)#define I10NM_GET_MCDDRTCFG (m, i, j) \ - (*(u32 *)((m)->mbase + 0x20970 + (i) * 0x4000 + (j) * 4)) + readl((m)->mbase + 0x20970 + (i) * 0x4000 + (j) * 4) +#define I10NM_GET_MCMTR (m, i) \ + readl((m)->mbase + 0x20ef8 + (i) * 0x4000)#define I10NM_GET_SCK_MMIO_BASE (reg) (GET_BITFIELD(reg, 0, 28) << 23)#define I10NM_GET_IMC_MMIO_OFFSET (reg) (GET_BITFIELD(reg, 0, 10) << 12)
@@ -134,7 +137,7 @@ static bool i10nm_check_ecc(struct skx_i {u32 mcmtr; - mcmtr = *(u32 *)(imc->mbase +0x20ef8 + chan *0x4000 ); + mcmtr =I10NM_GET_MCMTR (imc, chan);edac_dbg (1 ,"ch%d mcmtr reg %x\n" , chan, mcmtr);return !!GET_BITFIELD (mcmtr,2 ,2 );
Greg Kroah-Hartman
maintainerPATCH 362/453 EDAC/amd64: Fix PCI component registration
In reply to Greg Kroah-HartmanFrom: Borislav Petkov <[email protected]>
commit 706657b1febf446a9ba37dc51b89f46604f57ee9 upstream.
In order to setup its PCI component, the driver needs any node private instance in order to get a reference to the PCI device and hand that into edac_pci_create_generic_ctl(). For convenience, it uses the 0th memory controller descriptor under the assumption that if any, the 0th will be always present.
However, this assumption goes wrong when the 0th node doesn't have memory and the driver doesn't initialize an instance for it:
EDAC amd64: F17h detected (node 0).
...
EDAC amd64: Node 0: No DIMMs detected.
But looking up node instances is not really needed - all one needs is the pointer to the proper device which gets discovered during instance init.
So stash that pointer into a variable and use it when setting up the EDAC PCI component.
Clear that variable when the driver needs to unwind due to some instances failing init to avoid any registration imbalance.
--- drivers/edac/amd64_edac.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
drivers/edac/amd64_edac.c +14 -12
@@ -22,6 +22,9 @@ static struct ecc_settings **ecc_stngs;/* Number of Unified Memory Controllers */ static u8 num_umcs; +/* Device for the PCI component */ +static struct device *pci_ctl_dev; +/* * Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing * bandwidth to a valid bit pattern. The 'set' operation finds the 'matching-
@@ -2672,6 +2675,9 @@ reserve_mc_sibling_devs(struct amd64_pvtreturn -ENODEV ; } +if (!pci_ctl_dev) + pci_ctl_dev = &pvt->F0->dev; +edac_dbg (1 ,"F0: %s\n" ,pci_name (pvt->F0));edac_dbg (1 ,"F3: %s\n" ,pci_name (pvt->F3));edac_dbg (1 ,"F6: %s\n" ,pci_name (pvt->F6));
@@ -2696,6 +2702,9 @@ reserve_mc_sibling_devs(struct amd64_pvtreturn -ENODEV ; } +if (!pci_ctl_dev) + pci_ctl_dev = &pvt->F2->dev; +edac_dbg (1 ,"F1: %s\n" ,pci_name (pvt->F1));edac_dbg (1 ,"F2: %s\n" ,pci_name (pvt->F2));edac_dbg (1 ,"F3: %s\n" ,pci_name (pvt->F3));
@@ -3626,21 +3635,10 @@ static void remove_one_instance(unsignedstatic void setup_pci_device (void ) { -struct mem_ctl_info *mci; -struct amd64_pvt *pvt; -if (pci_ctl)return ; - mci =edac_mc_find (0 ); -if (!mci) -return ; - - pvt = mci->pvt_info; -if (pvt->umc) - pci_ctl =edac_pci_create_generic_ctl (&pvt->F0->dev,EDAC_MOD_STR ); -else - pci_ctl =edac_pci_create_generic_ctl (&pvt->F2->dev,EDAC_MOD_STR ); + pci_ctl =edac_pci_create_generic_ctl (pci_ctl_dev,EDAC_MOD_STR );if (!pci_ctl) {pr_warn ("%s(): Unable to create PCI control\n" , __func__);pr_warn ("%s(): PCI error report via EDAC not set\n" , __func__);
@@ -3723,6 +3721,8 @@ static int __init amd64_edac_init(void)return 0 ; err_pci: + pci_ctl_dev =NULL ; +msrs_free (msrs); msrs =NULL ;
@@ -3754,6 +3754,8 @@ static void __exit amd64_edac_exit(void)kfree (ecc_stngs); ecc_stngs =NULL ; + pci_ctl_dev =NULL ; +msrs_free (msrs); msrs =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 363/453 cpuset: fix race between hotplug work and later CPU offline
In reply to Greg Kroah-HartmanFrom: Daniel Jordan <[email protected]>
commit 406100f3da08066c00105165db8520bbc7694a36 upstream.
One of our machines keeled over trying to rebuild the scheduler domains. Mainline produces the same splat:
BUG: unable to handle page fault for address: 0000607f820054db CPU: 2 PID: 149 Comm: kworker/1:1 Not tainted 5.10.0-rc1-master+ #6 Workqueue: events cpuset_hotplug_workfn RIP: build_sched_domains Call Trace: partition_sched_domains_locked rebuild_sched_domains_locked cpuset_hotplug_workfn
It happens with cgroup2 and exclusive cpusets only. This reproducer triggers it on an 8-cpu vm and works most effectively with no preexisting child cgroups:
cd $UNIFIED_ROOT
mkdir cg1
echo 4-7 > cg1/cpuset.cpus
echo root > cg1/cpuset.cpus.partition
# with smt/control reading 'on', echo off > /sys/devices/system/cpu/smt/control
RIP maps to
sd->shared = *per_cpu_ptr(sdd->sds, sd_id);
from sd_init(). sd_id is calculated earlier in the same function:
cpumask_and(sched_domain_span(sd), cpu_map, tl->mask(cpu)); sd_id = cpumask_first(sched_domain_span(sd));
tl->mask(cpu), which reads cpu_sibling_map on x86, returns an empty mask and so cpumask_first() returns >= nr_cpu_ids, which leads to the bogus value from per_cpu_ptr() above.
The problem is a race between cpuset_hotplug_workfn() and a later offline of CPU N. cpuset_hotplug_workfn() updates the effective masks when N is still online, the offline clears N from cpu_sibling_map, and then the worker uses the stale effective masks that still have N to generate the scheduling domains, leading the worker to read N's empty cpu_sibling_map in sd_init().
rebuild_sched_domains_locked() prevented the race during the cgroup2 cpuset series up until the Fixes commit changed its check. Make the check more robust so that it can detect an offline CPU in any exclusive cpuset's effective mask, not just the top one.
--- kernel/cgroup/cpuset.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-)
kernel/cgroup/cpuset.c +28 -5
@@ -981,25 +981,48 @@ partition_and_rebuild_sched_domains(int*/ static void rebuild_sched_domains_locked (void ) { +struct cgroup_subsys_state *pos_css;struct sched_domain_attr *attr;cpumask_var_t *doms; +struct cpuset *cs;int ndoms;lockdep_assert_cpus_held ();percpu_rwsem_assert_held (&cpuset_rwsem);/* -* We have raced with CPU hotplug. Don't do anything to avoid +* If we have raced with CPU hotplug, return early to avoid * passing doms with offlined cpu to partition_sched_domains(). -* Anyways, hotplug work item will rebuild sched domains. +* Anyways, cpuset_hotplug_workfn() will rebuild sched domains. +* +* With no CPUs in any subpartitions, top_cpuset's effective CPUs +* should be the same as the active CPUs, so checking only top_cpuset +* is enough to detect racing CPU offlines. */ if (!top_cpuset.nr_subparts_cpus && !cpumask_equal (top_cpuset.effective_cpus, cpu_active_mask))return ; -if (top_cpuset.nr_subparts_cpus && - !cpumask_subset (top_cpuset.effective_cpus, cpu_active_mask)) -return ; +/* +* With subpartition CPUs, however, the effective CPUs of a partition +* root should be only a subset of the active CPUs. Since a CPU in any +* partition root could be offlined, all must be checked. +*/ +if (top_cpuset.nr_subparts_cpus) { +rcu_read_lock (); +cpuset_for_each_descendant_pre (cs, pos_css, &top_cpuset) { +if (!is_partition_root (cs)) { + pos_css =css_rightmost_descendant (pos_css); +continue ; + } +if (!cpumask_subset (cs->effective_cpus, + cpu_active_mask)) { +rcu_read_unlock (); +return ; + } + } +rcu_read_unlock (); + }/* Generate domain masks and attrs */ ndoms =generate_sched_domains (&doms, &attr);
Greg Kroah-Hartman
maintainerPATCH 364/453 USB: serial: mos7720: fix parallel-port state restore
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 975323ab8f116667676c30ca3502a6757bd89e8d upstream.
The parallel-port restore operations is called when a driver claims the port and is supposed to restore the provided state (e.g. saved when releasing the port).
--- drivers/usb/serial/mos7720.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/mos7720.c +2 -0
@@ -638,6 +638,8 @@ static void parport_mos7715_restore_statspin_unlock (&release_lock);return ; } + mos_parport->shadowDCR = s->u.pc.ctr; + mos_parport->shadowECR = s->u.pc.ecr;write_parport_reg_nonblock (mos_parport,MOS7720_DCR , mos_parport->shadowDCR); write_parport_reg_nonblock(mos_parport, MOS7720_ECR,
Greg Kroah-Hartman
maintainerPATCH 365/453 USB: serial: digi_acceleport: fix write-wakeup deadlocks
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 5098e77962e7c8947f87bd8c5869c83e000a522a upstream.
The driver must not call tty_wakeup() while holding its private lock as line disciplines are allowed to call back into write() from write_wakeup(), leading to a deadlock.
Also remove the unneeded work struct that was used to defer wakeup in order to work around a possible race in ancient times (see comment about n_tty write_chan() in commit 14b54e39b412 ("USB: serial: remove changelogs and old todo entries")).
--- drivers/usb/serial/digi_acceleport.c | 45 ++++++++++------------------------- 1 file changed, 13 insertions(+), 32 deletions(-)
drivers/usb/serial/digi_acceleport.c +13 -32
@@ -19,7 +19,6 @@#include <linux/tty_flip.h> #include <linux/module.h> #include <linux/spinlock.h> -#include <linux/workqueue.h> #include <linux/uaccess.h> #include <linux/usb.h> #include <linux/wait.h>
@@ -198,14 +197,12 @@ struct digi_port {int dp_throttle_restart;wait_queue_head_t dp_flush_wait;wait_queue_head_t dp_close_wait;/* wait queue for close */ -struct work_struct dp_wakeup_work;struct usb_serial_port *dp_port; };/* Local Function Declarations */ -static void digi_wakeup_write_lock (struct work_struct *work);static int digi_write_oob_command (struct usb_serial_port *port,unsigned char *buf,int count,int interruptible); static int digi_write_inb_command(struct usb_serial_port *port,
@@ -356,26 +353,6 @@ __releases(lock)return timeout; } - -/* -* Digi Wakeup Write -* -* Wake up port, line discipline, and tty processes sleeping -* on writes. -*/ - -static void digi_wakeup_write_lock (struct work_struct *work) -{ -struct digi_port *priv = - container_of(work, struct digi_port, dp_wakeup_work); -struct usb_serial_port *port = priv->dp_port; -unsigned long flags; - -spin_lock_irqsave (&priv->dp_port_lock, flags); -tty_port_tty_wakeup (&port->port); -spin_unlock_irqrestore (&priv->dp_port_lock, flags); -} -/* * Digi Write OOB Command *
@@ -986,6 +963,7 @@ static void digi_write_bulk_callback(strunsigned long flags;int ret =0 ;int status = urb->status; +bool wakeup;/* port and serial sanity check */ if (port ==NULL || (priv =usb_get_serial_port_data (port)) ==NULL ) {
@@ -1012,6 +990,7 @@ static void digi_write_bulk_callback(str }/* try to send any buffered data on this port */ + wakeup = true;spin_lock_irqsave (&priv->dp_port_lock, flags); priv->dp_write_urb_in_use =0 ;if (priv->dp_out_buf_len >0 ) {
@@ -1027,19 +1006,18 @@ static void digi_write_bulk_callback(strif (ret ==0 ) { priv->dp_write_urb_in_use =1 ; priv->dp_out_buf_len =0 ; + wakeup = false; } } -/* wake up processes sleeping on writes immediately */ -tty_port_tty_wakeup (&port->port); -/* also queue up a wakeup at scheduler time, in case we */ -/* lost the race in write_chan(). */ -schedule_work (&priv->dp_wakeup_work); -spin_unlock_irqrestore (&priv->dp_port_lock, flags); +if (ret && ret != -EPERM )dev_err_console (port,"%s: usb_submit_urb failed, ret=%d, port=%d\n" , __func__, ret, priv->dp_port_num); + +if (wakeup) +tty_port_tty_wakeup (&port->port); }static int digi_write_room (struct tty_struct *tty)
@@ -1239,7 +1217,6 @@ static int digi_port_init(struct usb_serinit_waitqueue_head (&priv->dp_transmit_idle_wait);init_waitqueue_head (&priv->dp_flush_wait);init_waitqueue_head (&priv->dp_close_wait); -INIT_WORK (&priv->dp_wakeup_work, digi_wakeup_write_lock); priv->dp_port = port;init_waitqueue_head (&port->write_wait);
@@ -1508,13 +1485,14 @@ static int digi_read_oob_callback(struct rts =C_CRTSCTS (tty);if (tty && opcode ==DIGI_CMD_READ_INPUT_SIGNALS ) { +bool wakeup = false; +spin_lock_irqsave (&priv->dp_port_lock, flags);/* convert from digi flags to termiox flags */ if (val &DIGI_READ_INPUT_SIGNALS_CTS ) { priv->dp_modem_signals |=TIOCM_CTS ; -/* port must be open to use tty struct */ if (rts) -tty_port_tty_wakeup (&port->port); + wakeup = true; }else { priv->dp_modem_signals &= ~TIOCM_CTS ;/* port must be open to use tty struct */
@@ -1533,6 +1511,9 @@ static int digi_read_oob_callback(struct priv->dp_modem_signals &= ~TIOCM_CD ;spin_unlock_irqrestore (&priv->dp_port_lock, flags); + +if (wakeup) +tty_port_tty_wakeup (&port->port); }else if (opcode ==DIGI_CMD_TRANSMIT_IDLE ) {spin_lock_irqsave (&priv->dp_port_lock, flags); priv->dp_transmit_idle =1 ;
Greg Kroah-Hartman
maintainerPATCH 366/453 USB: serial: keyspan_pda: fix dropped unthrottle interrupts
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 696c541c8c6cfa05d65aa24ae2b9e720fc01766e upstream.
Commit c528fcb116e6 ("USB: serial: keyspan_pda: fix receive sanity checks") broke write-unthrottle handling by dropping well-formed unthrottle-interrupt packets which are precisely two bytes long. This could lead to blocked writers not being woken up when buffer space again becomes available.
Instead, stop unconditionally printing the third byte which is (presumably) only valid on modem-line changes.
--- drivers/usb/serial/keyspan_pda.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/serial/keyspan_pda.c +2 -2
@@ -172,11 +172,11 @@ static void keyspan_pda_rx_interrupt(strbreak ;case 1 :/* status interrupt */ -if (len <3 ) { +if (len <2 ) {dev_warn (&port->dev,"short interrupt message received\n" );break ; } -dev_dbg (&port->dev,"rx int, d1=%d, d2=%d\n" , data[1 ], data[2 ]); +dev_dbg (&port->dev,"rx int, d1=%d\n" , data[1 ]);switch (data[1 ]) {case 1 :/* modemline change */ break ;
Greg Kroah-Hartman
maintainerPATCH 367/453 USB: serial: keyspan_pda: fix write deadlock
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 7353cad7ee4deaefc16e94727e69285563e219f6 upstream.
The write() callback can be called in interrupt context (e.g. when used as a console) so interrupts must be disabled while holding the port lock to prevent a possible deadlock.
--- drivers/usb/serial/keyspan_pda.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/serial/keyspan_pda.c +4 -3
@@ -443,6 +443,7 @@ static int keyspan_pda_write(struct tty_int request_unthrottle =0 ;int rc =0 ;struct keyspan_pda_private *priv; +unsigned long flags; priv =usb_get_serial_port_data (port);/* guess how much room is left in the device's ring buffer, and if we
@@ -462,13 +463,13 @@ static int keyspan_pda_write(struct tty_the TX urb is in-flight (wait until it completes) the device is full (wait until it says there is room) */ -spin_lock_bh (&port->lock); +spin_lock_irqsave (&port->lock, flags);if (!test_bit (0 , &port->write_urbs_free) || priv->tx_throttled) { -spin_unlock_bh (&port->lock); +spin_unlock_irqrestore (&port->lock, flags);return 0 ; }clear_bit (0 , &port->write_urbs_free); -spin_unlock_bh (&port->lock); +spin_unlock_irqrestore (&port->lock, flags);/* At this point the URB is in our control, nobody else can submit it again (the only sudden transition was the one from EINPROGRESS to
Greg Kroah-Hartman
maintainerPATCH 368/453 USB: serial: keyspan_pda: fix stalled writes
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit c01d2c58698f710c9e13ba3e2d296328606f74fd upstream.
Make sure to clear the write-busy flag also in case no new data was submitted due to lack of device buffer space so that writing is resumed once space again becomes available.
--- drivers/usb/serial/keyspan_pda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/serial/keyspan_pda.c +1 -1
@@ -548,7 +548,7 @@ static int keyspan_pda_write(struct tty_ rc = count; exit: -if (rc <0 ) +if (rc <=0 )set_bit (0 , &port->write_urbs_free);return rc; }
Greg Kroah-Hartman
maintainerPATCH 369/453 USB: serial: keyspan_pda: fix write-wakeup use-after-free
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 37faf50615412947868c49aee62f68233307f4e4 upstream.
The driver's deferred write wakeup was never flushed on disconnect, something which could lead to the driver port data being freed while the wakeup work is still scheduled.
Fix this by using the usb-serial write wakeup which gets cancelled properly on disconnect.
--- drivers/usb/serial/keyspan_pda.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-)
drivers/usb/serial/keyspan_pda.c +3 -14
@@ -43,8 +43,7 @@struct keyspan_pda_private {int tx_room;int tx_throttled; -struct work_struct wakeup_work; -struct work_struct unthrottle_work; +struct work_struct unthrottle_work;struct usb_serial *serial;struct usb_serial_port *port; };
@@ -97,15 +96,6 @@ static const struct usb_device_id id_tab };#endif -static void keyspan_pda_wakeup_write (struct work_struct *work) -{ -struct keyspan_pda_private *priv = - container_of(work, struct keyspan_pda_private, wakeup_work); -struct usb_serial_port *port = priv->port; - -tty_port_tty_wakeup (&port->port); -} -static void keyspan_pda_request_unthrottle (struct work_struct *work) { struct keyspan_pda_private *priv =
@@ -183,7 +173,7 @@ static void keyspan_pda_rx_interrupt(strcase 2 :/* tx unthrottle interrupt */ priv->tx_throttled =0 ;/* queue up a wakeup at scheduler time */ -schedule_work (&priv->wakeup_work); +usb_serial_port_softint (port);break ;default :break ;
@@ -563,7 +553,7 @@ static void keyspan_pda_write_bulk_callb priv =usb_get_serial_port_data (port);/* queue up a wakeup at scheduler time */ -schedule_work (&priv->wakeup_work); +usb_serial_port_softint (port); }
@@ -716,7 +706,6 @@ static int keyspan_pda_port_probe(structif (!priv)return -ENOMEM ; -INIT_WORK (&priv->wakeup_work, keyspan_pda_wakeup_write);INIT_WORK (&priv->unthrottle_work, keyspan_pda_request_unthrottle); priv->serial = port->serial; priv->port = port;
Greg Kroah-Hartman
maintainerPATCH 370/453 USB: serial: keyspan_pda: fix tx-unthrottle use-after-free
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 49fbb8e37a961396a5b6c82937c70df91de45e9d upstream.
The driver's transmit-unthrottle work was never flushed on disconnect, something which could lead to the driver port data being freed while the unthrottle work is still scheduled.
Fix this by cancelling the unthrottle work when shutting down the port.
--- drivers/usb/serial/keyspan_pda.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/serial/keyspan_pda.c +4 -0
@@ -647,8 +647,12 @@ error: }static void keyspan_pda_close (struct usb_serial_port *port) { +struct keyspan_pda_private *priv =usb_get_serial_port_data (port); +usb_kill_urb (port->write_urb);usb_kill_urb (port->interrupt_in_urb); + +cancel_work_sync (&priv->unthrottle_work); }
Greg Kroah-Hartman
maintainerPATCH 371/453 USB: serial: keyspan_pda: fix write unthrottling
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 320f9028c7873c3c7710e8e93e5c979f4c857490 upstream.
The driver did not update its view of the available device buffer space until write() was called in task context. This meant that write_room() would return 0 even after the device had sent a write-unthrottle notification, something which could lead to blocked writers not being woken up (e.g. when using OPOST).
Note that we must also request an unthrottle notification is case a write() request fills the device buffer exactly.
--- drivers/usb/serial/keyspan_pda.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
drivers/usb/serial/keyspan_pda.c +20 -9
@@ -40,6 +40,8 @@#define DRIVER_AUTHOR "Brian Warner <[email protected]>"#define DRIVER_DESC "USB Keyspan PDA Converter driver" +#define KEYSPAN_TX_THRESHOLD 16 +struct keyspan_pda_private {int tx_room;int tx_throttled;
@@ -110,7 +112,7 @@ static void keyspan_pda_request_unthrott7 ,/* request_unthrottle */ USB_TYPE_VENDOR |USB_RECIP_INTERFACE |USB_DIR_OUT , -16 ,/* value: threshold */ +KEYSPAN_TX_THRESHOLD ,0 ,/* index */ NULL , 0,
@@ -129,6 +131,8 @@ static void keyspan_pda_rx_interrupt(strint retval;int status = urb->status;struct keyspan_pda_private *priv; +unsigned long flags; + priv =usb_get_serial_port_data (port);switch (status) {
@@ -171,7 +175,10 @@ static void keyspan_pda_rx_interrupt(strcase 1 :/* modemline change */ break ;case 2 :/* tx unthrottle interrupt */ +spin_lock_irqsave (&port->lock, flags); priv->tx_throttled =0 ; + priv->tx_room =max (priv->tx_room,KEYSPAN_TX_THRESHOLD ); +spin_unlock_irqrestore (&port->lock, flags);/* queue up a wakeup at scheduler time */ usb_serial_port_softint (port);break ;
@@ -505,7 +512,8 @@ static int keyspan_pda_write(struct tty_ goto exit; } } -if (count > priv->tx_room) { + +if (count >= priv->tx_room) {/* we're about to completely fill the Tx buffer, so we'll be throttled afterwards. */ count = priv->tx_room;
@@ -560,14 +568,17 @@ static void keyspan_pda_write_bulk_callbstatic int keyspan_pda_write_room (struct tty_struct *tty) {struct usb_serial_port *port = tty->driver_data; -struct keyspan_pda_private *priv; - priv =usb_get_serial_port_data (port); -/* used by n_tty.c for processing of tabs and such. Giving it our -conservative guess is probably good enough, but needs testing by -running a console through the device. */ -return priv->tx_room; -} +struct keyspan_pda_private *priv =usb_get_serial_port_data (port); +unsigned long flags; +int room =0 ; + +spin_lock_irqsave (&port->lock, flags); +if (test_bit (0 , &port->write_urbs_free) && !priv->tx_throttled) + room = priv->tx_room; +spin_unlock_irqrestore (&port->lock, flags); +return room; +}static int keyspan_pda_chars_in_buffer (struct tty_struct *tty) {
Greg Kroah-Hartman
maintainerPATCH 372/453 btrfs: do not shorten unpin len for caching block groups
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 9076dbd5ee837c3882fc42891c14cecd0354a849 upstream.
While fixing up our ->last_byte_to_unpin locking I noticed that we will shorten len based on ->last_byte_to_unpin if we're caching when we're adding back the free space. This is correct for the free space, as we cannot unpin more than ->last_byte_to_unpin, however we use len to adjust the ->bytes_pinned counters and such, which need to track the actual pinned usage. This could result in WARN_ON(space_info->bytes_pinned) triggering at unmount time.
Fix this by using a local variable for the amount to add to free space cache, and leave len untouched in this case.
--- fs/btrfs/extent-tree.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/btrfs/extent-tree.c +4 -4
@@ -2838,10 +2838,10 @@ static int unpin_extent_range(struct btr len = cache->key.objectid + cache->key.offset - start; len =min (len, end +1 - start); -if (start < cache->last_byte_to_unpin) { - len =min (len, cache->last_byte_to_unpin - start); -if (return_free_space) -btrfs_add_free_space (cache, start, len); +if (start < cache->last_byte_to_unpin && return_free_space) { +u64 add_len =min (len, cache->last_byte_to_unpin - start); + +btrfs_add_free_space (cache, start, add_len); } start += len;
Greg Kroah-Hartman
maintainerPATCH 373/453 btrfs: trim: fix underflow in trim length to prevent access beyond device boundary
In reply to Greg Kroah-HartmanFrom: Qu Wenruo <[email protected]>
commit c57dd1f2f6a7cd1bb61802344f59ccdc5278c983 upstream
[BUG]
The following script can lead to tons of beyond device boundary access:
mkfs.btrfs -f $dev -b 10G
mount $dev $mnt
trimfs $mnt
btrfs filesystem resize 1:-1G $mnt
trimfs $mnt
[CAUSE]
Since commit 929be17a9b49 ("btrfs: Switch btrfs_trim_free_extents to find_first_clear_extent_bit"), we try to avoid trimming ranges that's already trimmed.
So we check device->alloc_state by finding the first range which doesn't have CHUNK_TRIMMED and CHUNK_ALLOCATED not set.
But if we shrunk the device, that bits are not cleared, thus we could easily got a range starts beyond the shrunk device size.
This results the returned @start and @end are all beyond device size, then we call "end = min(end, device->total_bytes -1);" making @end smaller than device size.
Then finally we goes "len = end - start + 1", totally underflow the result, and lead to the beyond-device-boundary access.
[FIX]
This patch will fix the problem in two ways:
- Clear CHUNK_TRIMMED | CHUNK_ALLOCATED bits when shrinking device This is the root fix
- Add extra safety check when trimming free device extents We check and warn if the returned range is already beyond current device.
--- fs/btrfs/extent-tree.c | 14 ++++++++++++++ fs/btrfs/extent_io.h | 2 ++ fs/btrfs/volumes.c | 4 ++++ 3 files changed, 20 insertions(+)
fs/btrfs/extent-tree.c +14 -0
@@ -32,6 +32,7 @@#include "block-rsv.h" #include "delalloc-space.h" #include "block-group.h" +#include "rcu-string.h" #undef SCRAMBLE_DELAYED_REFS
@@ -5618,6 +5619,19 @@ static int btrfs_trim_free_extents(struc &start, &end, CHUNK_TRIMMED | CHUNK_ALLOCATED); +/* Check if there are any CHUNK_* bits left */ +if (start > device->total_bytes) { +WARN_ON (IS_ENABLED (CONFIG_BTRFS_DEBUG )); +btrfs_warn_in_rcu (fs_info, +"ignoring attempt to trim beyond device size: offset %llu length %llu device %s device size %llu" , + start, end - start +1 , +rcu_str_deref (device->name), + device->total_bytes); +mutex_unlock (&fs_info->chunk_mutex); + ret =0 ; +break ; + } +/* Ensure we skip the reserved area in the first 1M */ start =max_t (u64, start,SZ_1M );
fs/btrfs/extent_io.h +2 -0
@@ -35,6 +35,8 @@*/ #define CHUNK_ALLOCATED EXTENT_DIRTY#define CHUNK_TRIMMED EXTENT_DEFRAG +#define CHUNK_STATE_MASK (CHUNK_ALLOCATED | \ + CHUNK_TRIMMED)/* * flags for bio submission. The high bits indicate the compression
fs/btrfs/volumes.c +4 -0
@@ -4908,6 +4908,10 @@ again: }mutex_lock (&fs_info->chunk_mutex); +/* Clear all state bits beyond the shrunk device size */ +clear_extent_bits (&device->alloc_state, new_size, (u64)-1 , +CHUNK_STATE_MASK ); +btrfs_device_set_disk_total_bytes (device, new_size);if (list_empty (&device->post_commit_list)) list_add_tail(&device->post_commit_list,
Greg Kroah-Hartman
maintainerPATCH 374/453 ext4: fix a memory leak of ext4_free_data
In reply to Greg Kroah-HartmanFrom: Chunguang Xu <[email protected]>
commit cca415537244f6102cbb09b5b90db6ae2c953bdd upstream.
When freeing metadata, we will create an ext4_free_data and insert it into the pending free list. After the current transaction is committed, the object will be freed.
ext4_mb_free_metadata() will check whether the area to be freed overlaps with the pending free list. If true, return directly. At this time, ext4_free_data is leaked. Fortunately, the probability of this problem is small, since it only occurs if the file system is corrupted such that a block is claimed by more one inode and those inodes are deleted within a single jbd2 transaction.
--- fs/ext4/mballoc.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/mballoc.c +1 -0
@@ -4691,6 +4691,7 @@ ext4_mb_free_metadata(handle_t *handle,ext4_group_first_block_no (sb, group) +EXT4_C2B (sbi, cluster), "Block already on to-be-freed list"); +kmem_cache_free (ext4_free_data_cachep, new_entry);return 0 ; } }
Greg Kroah-Hartman
maintainerPATCH 375/453 ext4: fix deadlock with fs freezing and EA inodes
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
commit 46e294efc355c48d1dd4d58501aa56dac461792a upstream.
Xattr code using inodes with large xattr data can end up dropping last inode reference (and thus deleting the inode) from places like ext4_xattr_set_entry(). That function is called with transaction started and so ext4_evict_inode() can deadlock against fs freezing like:
CPU1 CPU2
removexattr() freeze_super()
vfs_removexattr()
ext4_xattr_set()
handle = ext4_journal_start()
...
ext4_xattr_set_entry()
iput(old_ea_inode)
ext4_evict_inode(old_ea_inode)
sb->s_writers.frozen = SB_FREEZE_FS;
sb_wait_write(sb, SB_FREEZE_FS);
ext4_freeze()
jbd2_journal_lock_updates()
-> blocks waiting for all
handles to stop
sb_start_intwrite()
-> blocks as sb is already in SB_FREEZE_FS stateGenerally it is advisable to delete inodes from a separate transaction as it can consume quite some credits however in this case it would be quite clumsy and furthermore the credits for inode deletion are quite limited and already accounted for. So just tweak ext4_evict_inode() to avoid freeze protection if we have transaction already started and thus it is not really needed anyway.
--- fs/ext4/inode.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
fs/ext4/inode.c +15 -6
@@ -203,6 +203,7 @@ void ext4_evict_inode(struct inode *inod*/ int extra_credits =6 ;struct ext4_xattr_inode_array *ea_inode_array =NULL ; +bool freeze_protected = false;trace_ext4_evict_inode (inode);
@@ -250,9 +251,14 @@ void ext4_evict_inode(struct inode *inod/* * Protect us against freezing - iput() caller didn't have to have any -* protection against it -*/ -sb_start_intwrite (inode->i_sb); +* protection against it. When we are in a running transaction though, +* we are already protected against freezing and we cannot grab further +* protection due to lock ordering constraints. +*/ +if (!ext4_journal_current_handle ()) { +sb_start_intwrite (inode->i_sb); + freeze_protected = true; + }if (!IS_NOQUOTA (inode)) extra_credits +=EXT4_MAXQUOTAS_DEL_BLOCKS (inode->i_sb);
@@ -271,7 +277,8 @@ void ext4_evict_inode(struct inode *inod* cleaned up. */ ext4_orphan_del (NULL , inode); -sb_end_intwrite (inode->i_sb); +if (freeze_protected) +sb_end_intwrite (inode->i_sb); goto no_delete; }
@@ -312,7 +319,8 @@ void ext4_evict_inode(struct inode *inod stop_handle:ext4_journal_stop (handle);ext4_orphan_del (NULL , inode); -sb_end_intwrite (inode->i_sb); +if (freeze_protected) +sb_end_intwrite (inode->i_sb);ext4_xattr_inode_array_free (ea_inode_array); goto no_delete; }
@@ -341,7 +349,8 @@ stop_handle:else ext4_free_inode (handle, inode);ext4_journal_stop (handle); -sb_end_intwrite (inode->i_sb); +if (freeze_protected) +sb_end_intwrite (inode->i_sb);ext4_xattr_inode_array_free (ea_inode_array);return ; no_delete:
Greg Kroah-Hartman
maintainerPATCH 376/453 KVM: arm64: Introduce handling of AArch32 TTBCR2 traps
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
commit ca4e514774930f30b66375a974b5edcbebaf0e7e upstream.
ARMv8.2 introduced TTBCR2, which shares TCR_EL1 with TTBCR. Gracefully handle traps to this register when HCR_EL2.TVM is set.
--- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/kvm/sys_regs.c | 1 + 2 files changed, 2 insertions(+)
arch/arm64/include/asm/kvm_host.h +1 -0
@@ -182,6 +182,7 @@ enum vcpu_sysreg {#define c2_TTBR1 (TTBR1_EL1 * 2)/* Translation Table Base Register 1 */ #define c2_TTBR1_high (c2_TTBR1 + 1)/* TTBR1 top 32 bits */ #define c2_TTBCR (TCR_EL1 * 2)/* Translation Table Base Control R. */ +#define c2_TTBCR2 (c2_TTBCR + 1)/* Translation Table Base Control R. 2 */ #define c3_DACR (DACR32_EL2 * 2)/* Domain Access Control Register */ #define c5_DFSR (ESR_EL1 * 2)/* Data Fault Status Register */ #define c5_IFSR (IFSR32_EL2 * 2)/* Instruction Fault Status Register */
arch/arm64/kvm/sys_regs.c +1 -0
@@ -1837,6 +1837,7 @@ static const struct sys_reg_desc cp15_re { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, { Op1( 0), CRn( 2), CRm( 0), Op2( 2), access_vm_reg, NULL, c2_TTBCR }, + { Op1( 0), CRn( 2), CRm( 0), Op2( 3), access_vm_reg, NULL, c2_TTBCR2 }, { Op1( 0), CRn( 3), CRm( 0), Op2( 0), access_vm_reg, NULL, c3_DACR }, { Op1( 0), CRn( 5), CRm( 0), Op2( 0), access_vm_reg, NULL, c5_DFSR }, { Op1( 0), CRn( 5), CRm( 0), Op2( 1), access_vm_reg, NULL, c5_IFSR },
Greg Kroah-Hartman
maintainerPATCH 377/453 ARM: dts: pandaboard: fix pinmux for gpio user button of Pandaboard ES
In reply to Greg Kroah-HartmanFrom: H. Nikolaus Schaller <[email protected]>
commit df9dbaf2c415cd94ad520067a1eccfee62f00a33 upstream.
The pinmux control register offset passed to OMAP4_IOPAD is odd.
--- arch/arm/boot/dts/omap4-panda-es.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/omap4-panda-es.dts +1 -1
@@ -46,7 +46,7 @@ button_pins: pinmux_button_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x11b, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ + OMAP4_IOPAD(0x0fc, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ >; }; };
Greg Kroah-Hartman
maintainerPATCH 378/453 ARM: dts: at91: sama5d2: fix CAN message ram offset and size
In reply to Greg Kroah-HartmanFrom: Nicolas Ferre <[email protected]>
commit 85b8350ae99d1300eb6dc072459246c2649a8e50 upstream.
CAN0 and CAN1 instances share the same message ram configured at 0x210000 on sama5d2 Linux systems.
According to current configuration of CAN0, we need 0x1c00 bytes so that the CAN1 don't overlap its message ram:
64 x RX FIFO0 elements => 64 x 72 bytes
32 x TXE (TX Event FIFO) elements => 32 x 8 bytes
32 x TXB (TX Buffer) elements => 32 x 72 bytes
So a total of 7168 bytes (0x1C00).
Fix offset to match this needed size.
Make the CAN0 message ram ioremap match exactly this size so that is easily understandable. Adapt CAN1 size accordingly.
--- arch/arm/boot/dts/sama5d2.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/boot/dts/sama5d2.dtsi +3 -3
@@ -717,7 +717,7 @@ can0: can@f8054000 { compatible = "bosch,m_can"; - reg = <0xf8054000 0x4000>, <0x210000 0x4000>; + reg = <0xf8054000 0x4000>, <0x210000 0x1c00>; reg-names = "m_can", "message_ram"; interrupts = <56 IRQ_TYPE_LEVEL_HIGH 7>, <64 IRQ_TYPE_LEVEL_HIGH 7>;
@@ -939,7 +939,7 @@ can1: can@fc050000 { compatible = "bosch,m_can"; - reg = <0xfc050000 0x4000>, <0x210000 0x4000>; + reg = <0xfc050000 0x4000>, <0x210000 0x3800>; reg-names = "m_can", "message_ram"; interrupts = <57 IRQ_TYPE_LEVEL_HIGH 7>, <65 IRQ_TYPE_LEVEL_HIGH 7>;
@@ -949,7 +949,7 @@ assigned-clocks = <&pmc PMC_TYPE_GCK 57>; assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_UTMI>; assigned-clock-rates = <40000000>; - bosch,mram-cfg = <0x1100 0 0 64 0 0 32 32>; + bosch,mram-cfg = <0x1c00 0 0 64 0 0 32 32>; status = "disabled"; };
Greg Kroah-Hartman
maintainerPATCH 379/453 xprtrdma: Fix XDRBUF_SPARSE_PAGES support
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
commit 15261b9126cd5bb2ad8521da49d8f5c042d904c7 upstream.
Olga K. observed that rpcrdma_marsh_req() allocates sparse pages only when it has determined that a Reply chunk is necessary. There are plenty of cases where no Reply chunk is needed, but the XDRBUF_SPARSE_PAGES flag is set. The result would be a crash in rpcrdma_inline_fixup() when it tries to copy parts of the received Reply into a missing page.
To avoid crashing, handle sparse page allocation up front.
Until XATTR support was added, this issue did not appear often because the only SPARSE_PAGES consumer always expected a reply large enough to always require a Reply chunk.
--- net/sunrpc/xprtrdma/rpc_rdma.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-)
net/sunrpc/xprtrdma/rpc_rdma.c +31 -9
@@ -183,6 +183,31 @@ rpcrdma_nonpayload_inline(const struct r r_xprt->rx_ep.rep_max_inline_recv; } +/* ACL likes to be lazy in allocating pages. For TCP, these +* pages can be allocated during receive processing. Not true +* for RDMA, which must always provision receive buffers +* up front. +*/ +static noinline int +rpcrdma_alloc_sparse_pages (struct xdr_buf *buf) +{ +struct page **ppages; +int len; + + len = buf->page_len; + ppages = buf->pages + (buf->page_base >>PAGE_SHIFT ); +while (len >0 ) { +if (!*ppages) + *ppages =alloc_page (GFP_NOWAIT | __GFP_NOWARN); +if (!*ppages) +return -ENOBUFS ; + ppages++; + len -=PAGE_SIZE ; + } + +return 0 ; +} +/* Split @vec on page boundaries into SGEs. FMR registers pages, not * a byte range. Other modes coalesce these SGEs into a single MR * when they can.
@@ -237,15 +262,6 @@ rpcrdma_convert_iovs(struct rpcrdma_xprt ppages = xdrbuf->pages + (xdrbuf->page_base >>PAGE_SHIFT ); page_base =offset_in_page (xdrbuf->page_base);while (len) { -/* ACL likes to be lazy in allocating pages - ACLs -* are small by default but can get huge. -*/ -if (unlikely (xdrbuf->flags &XDRBUF_SPARSE_PAGES )) { -if (!*ppages) - *ppages =alloc_page (GFP_NOWAIT | __GFP_NOWARN); -if (!*ppages) -return -ENOBUFS ; - } seg->mr_page = *ppages; seg->mr_offset = (char *)page_base; seg->mr_len =min_t (u32,PAGE_SIZE - page_base, len);
@@ -800,6 +816,12 @@ rpcrdma_marshal_req(struct rpcrdma_xprt__be32 *p;int ret; +if (unlikely (rqst->rq_rcv_buf.flags &XDRBUF_SPARSE_PAGES )) { + ret =rpcrdma_alloc_sparse_pages (&rqst->rq_rcv_buf); +if (ret) +return ret; + } +rpcrdma_set_xdrlen (&req->rl_hdrbuf,0 );xdr_init_encode (xdr, &req->rl_hdrbuf,rdmab_data (req->rl_rdmabuf), rqst);
Greg Kroah-Hartman
maintainerPATCH 380/453 powerpc: Fix incorrect stw{, ux, u, x} instructions in __set_pte_at
In reply to Greg Kroah-HartmanFrom: Mathieu Desnoyers <[email protected]>
commit d85be8a49e733dcd23674aa6202870d54bf5600d upstream.
The placeholder for instruction selection should use the second argument's operand, which is %1, not %0. This could generate incorrect assembly code if the memory addressing of operand %0 is a different form from that of operand %1.
Also remove the %Un placeholder because having %Un placeholders for two operands which are based on the same local var (ptep) doesn't make much sense. By the way, it doesn't change the current behaviour because "<>" constraint is missing for the associated "=m".
[chleroy: revised commit log iaw segher's comments and removed %U0]
--- arch/powerpc/include/asm/book3s/32/pgtable.h | 4 ++-- arch/powerpc/include/asm/nohash/pgtable.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
arch/powerpc/include/asm/book3s/32/pgtable.h +2 -2
@@ -557,9 +557,9 @@ static inline void __set_pte_at(struct mif (pte_val (*ptep) & _PAGE_HASHPTE)flush_hash_entry (mm, ptep, addr); __asm__ __volatile__("\ -stw%U0%X0 %2,%0\n\ +stw%X0 %2,%0\n\ eieio\n\ -stw%U0%X0 %L2,%1" +stw%X1 %L2,%1" :"=m" (*ptep),"=m" (*((unsigned char *)ptep+4 )) :"r" (pte) :"memory" );
arch/powerpc/include/asm/nohash/pgtable.h +2 -2
@@ -199,9 +199,9 @@ static inline void __set_pte_at(struct m*/ if (IS_ENABLED (CONFIG_PPC32 ) &&IS_ENABLED (CONFIG_PTE_64BIT ) && !percpu) { __asm__ __volatile__("\ -stw%U0%X0 %2,%0\n\ +stw%X0 %2,%0\n\ eieio\n\ -stw%U0%X0 %L2,%1" +stw%X1 %L2,%1" :"=m" (*ptep),"=m" (*((unsigned char *)ptep+4 )) :"r" (pte) :"memory" );return ;
Greg Kroah-Hartman
maintainerPATCH 381/453 powerpc/rtas: Fix typo of ibm,open-errinjct in RTAS filter
In reply to Greg Kroah-HartmanFrom: Tyrel Datwyler <[email protected]>
commit f10881a46f8914428110d110140a455c66bdf27b upstream.
Commit bd59380c5ba4 ("powerpc/rtas: Restrict RTAS requests from userspace") introduced the following error when invoking the errinjct userspace tool:
[root@ltcalpine2-lp5 librtas]# errinjct open
[327884.071171] sys_rtas: RTAS call blocked - exploit attempt? [327884.071186] sys_rtas: token=0x26, nargs=0 (called by errinjct) errinjct: Could not open RTAS error injection facility errinjct: librtas: open: Unexpected I/O error
The entry for ibm,open-errinjct in rtas_filter array has a typo where the "j" is omitted in the rtas call name. After fixing this typo the errinjct tool functions again as expected.
[root@ltcalpine2-lp5 linux]# errinjct open
RTAS error injection facility open, token = 1
--- arch/powerpc/kernel/rtas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/rtas.c +1 -1
@@ -978,7 +978,7 @@ static struct rtas_filter rtas_filters[] { "ibm,display-message", -1, 0, -1, -1, -1 }, { "ibm,errinjct", -1, 2, -1, -1, -1, 1024 }, { "ibm,close-errinjct", -1, -1, -1, -1, -1 }, - { "ibm,open-errinct", -1, -1, -1, -1, -1 }, + { "ibm,open-errinjct", -1, -1, -1, -1, -1 }, { "ibm,get-config-addr-info2", -1, -1, -1, -1, -1 }, { "ibm,get-dynamic-sensor-state", -1, 1, -1, -1, -1 }, { "ibm,get-indices", -1, 2, 3, -1, -1 },
Greg Kroah-Hartman
maintainerPATCH 382/453 powerpc/feature: Add CPU_FTR_NOEXECUTE to G2_LE
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 197493af414ee22427be3343637ac290a791925a upstream.
G2_LE has a 603 core, add CPU_FTR_NOEXECUTE.
--- arch/powerpc/include/asm/cputable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/include/asm/cputable.h +1 -1
@@ -367,7 +367,7 @@ static inline void cpu_feature_keys_init CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)#define CPU_FTRS_82XX (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_NOEXECUTE)#define CPU_FTRS_G2_LE (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \ - CPU_FTR_MAYBE_CAN_NAP) + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NOEXECUTE)#define CPU_FTRS_E300 (CPU_FTR_MAYBE_CAN_DOZE | \ CPU_FTR_MAYBE_CAN_NAP | \ CPU_FTR_COMMON | CPU_FTR_NOEXECUTE)
Greg Kroah-Hartman
maintainerPATCH 383/453 powerpc/xmon: Change printk() to pr_cont()
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 7c6c86b36a36dd4a13d30bba07718e767aa2e7a1 upstream.
Since some time now, printk() adds carriage return, leading to unusable xmon output if there is no udbg backend available:
[ 54.288722] sysrq: Entering xmon [ 54.292209] Vector: 0 at [cace3d2c] [ 54.292274] pc: [ 54.292331] c0023650 [ 54.292468] : xmon+0x28/0x58 [ 54.292519] [ 54.292574] lr: [ 54.292630] c0023724 [ 54.292749] : sysrq_handle_xmon+0xa4/0xfc [ 54.292801] [ 54.292867] sp: cace3de8 [ 54.292931] msr: 9032 [ 54.292999] current = 0xc28d0000 [ 54.293072] pid = 377, comm = sh [ 54.293157] Linux version 5.10.0-rc6-s3k-dev-01364-gedf13f0ccd76-dirty ([email protected]) (powerpc64-linux-gcc (GCC) 10.1.0, GNU ld (GNU Binutils) 2.34) #4211 PREEMPT Fri Dec 4 09:32:11 UTC 2020 [ 54.293287] enter ? for help [ 54.293470] [cace3de8] [ 54.293532] c0023724 [ 54.293654] sysrq_handle_xmon+0xa4/0xfc [ 54.293711] (unreliable) ... [ 54.296002] [ 54.296159] --- Exception: c01 (System Call) at [ 54.296217] 0fd4e784 [ 54.296303] [ 54.296375] SP (7fca6ff0) is in userspace [ 54.296431] mon> [ 54.296484] <no input ...>
Use pr_cont() instead.
--- arch/powerpc/xmon/nonstdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/xmon/nonstdio.c +1 -1
@@ -178,7 +178,7 @@ void xmon_printf(const char *format, ...if (n && rc ==0 ) {/* No udbg hooks, fallback to printk() - dangerous */ -printk ("%s" , xmon_outbuf); +pr_cont ("%s" , xmon_outbuf); } }
Greg Kroah-Hartman
maintainerPATCH 384/453 powerpc/8xx: Fix early debug when SMC1 is relocated
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 1e78f723d6a52966bfe3804209dbf404fdc9d3bb upstream.
When SMC1 is relocated and early debug is selected, the board hangs is ppc_md.setup_arch(). This is because ones the microcode has been loaded and SMC1 relocated, early debug writes in the weed.
To allow smooth continuation, the SMC1 parameter RAM set up by the bootloader have to be copied into the new location.
--- arch/powerpc/include/asm/cpm1.h | 1 + arch/powerpc/platforms/8xx/micropatch.c | 11 +++++++++++ 2 files changed, 12 insertions(+)
arch/powerpc/include/asm/cpm1.h +1 -0
@@ -68,6 +68,7 @@ extern void cpm_reset(void);#define PROFF_SPI ((uint)0x0180)#define PROFF_SCC3 ((uint)0x0200)#define PROFF_SMC1 ((uint)0x0280) +#define PROFF_DSP1 ((uint)0x02c0)#define PROFF_SCC4 ((uint)0x0300)#define PROFF_SMC2 ((uint)0x0380)
arch/powerpc/platforms/8xx/micropatch.c +11 -0
@@ -361,6 +361,17 @@ void __init cpm_load_patch(cpm8xx_t *cp)if (IS_ENABLED (CONFIG_SMC_UCODE_PATCH )) {smc_uart_t *smp; +if (IS_ENABLED (CONFIG_PPC_EARLY_DEBUG_CPM )) { +int i; + +for (i =0 ; i <sizeof (*smp); i +=4 ) { +u32 __iomem *src = (u32 __iomem *)&cp->cp_dparam[PROFF_SMC1 + i]; +u32 __iomem *dst = (u32 __iomem *)&cp->cp_dparam[PROFF_DSP1 + i]; + +out_be32 (dst,in_be32 (src)); + } + } + smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1 ];out_be16 (&smp->smc_rpbase,0x1ec0 ); smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2 ];
Greg Kroah-Hartman
maintainerPATCH 385/453 powerpc/mm: Fix verification of MMU_FTR_TYPE_44x
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 17179aeb9d34cc81e1a4ae3f85e5b12b13a1f8d0 upstream.
MMU_FTR_TYPE_44x cannot be checked by cpu_has_feature()
Use mmu_has_feature() instead
--- arch/powerpc/mm/mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/mm/mem.c +1 -1
@@ -530,7 +530,7 @@ void __flush_dcache_icache(void *p)* space occurs, before returning to user space. */ -if (cpu_has_feature (MMU_FTR_TYPE_44x)) +if (mmu_has_feature (MMU_FTR_TYPE_44x))return ;invalidate_icache_range (addr, addr +PAGE_SIZE );
Greg Kroah-Hartman
maintainerPATCH 386/453 powerpc/powernv/npu: Do not attempt NPU2 setup on POWER8NVL NPU
In reply to Greg Kroah-HartmanFrom: Alexey Kardashevskiy <[email protected]>
commit b1198a88230f2ce50c271e22b82a8b8610b2eea9 upstream.
We execute certain NPU2 setup code (such as mapping an LPID to a device in NPU2) unconditionally if an Nvlink bridge is detected. However this cannot succeed on POWER8NVL machines and errors appear in dmesg. This is harmless as skiboot returns an error and the only place we check it is vfio-pci but that code does not get called on P8+ either.
This adds a check if pnv_npu2_xxx helpers are called on a machine with NPU2 which initializes pnv_phb::npu in pnv_npu2_init(); pnv_phb::npu==NULL on POWER8/NVL (Naples).
While at this, fix NULL derefencing in pnv_npu_peers_take_ownership/ pnv_npu_peers_release_ownership which occurs when GPUs on mentioned P8s cause EEH which happens if "vfio-pci" disables devices using the D3 power state; the vfio-pci's disable_idle_d3 module parameter controls this and must be set on Naples. The EEH handling clears the entire pnv_ioda_pe struct in pnv_ioda_free_pe() hence the NULL derefencing. We cannot recover from that but at least we stop crashing.
Tested on
- POWER9 pvr=004e1201, Ubuntu 19.04 host, Ubuntu 18.04 vm, NVIDIA GV100 10de:1db1 driver 418.39
- POWER8 pvr=004c0100, RHEL 7.6 host, Ubuntu 16.10 vm, NVIDIA P100 10de:15f9 driver 396.47
--- arch/powerpc/platforms/powernv/npu-dma.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
arch/powerpc/platforms/powernv/npu-dma.c +14 -2
@@ -384,7 +384,8 @@ static void pnv_npu_peers_take_ownershipfor (i =0 ; i < npucomp->pe_num; ++i) {struct pnv_ioda_pe *pe = npucomp->pe[i]; -if (!pe->table_group.ops->take_ownership) +if (!pe->table_group.ops || + !pe->table_group.ops->take_ownership)continue ; pe->table_group.ops->take_ownership (&pe->table_group); }
@@ -400,7 +401,8 @@ static void pnv_npu_peers_release_ownersfor (i =0 ; i < npucomp->pe_num; ++i) {struct pnv_ioda_pe *pe = npucomp->pe[i]; -if (!pe->table_group.ops->release_ownership) +if (!pe->table_group.ops || + !pe->table_group.ops->release_ownership)continue ; pe->table_group.ops->release_ownership (&pe->table_group); }
@@ -560,6 +562,11 @@ int pnv_npu2_map_lpar_dev(struct pci_devreturn -ENODEV ; hose =pci_bus_to_host (npdev->bus); +if (hose->npu ==NULL ) { +dev_info_once (&npdev->dev,"Nvlink1 does not support contexts" ); +return 0 ; + } + nphb = hose->private_data; dev_dbg(&gpdev->dev, "Map LPAR opalid=%llu lparid=%u\n",
@@ -607,6 +614,11 @@ int pnv_npu2_unmap_lpar_dev(struct pci_dreturn -ENODEV ; hose =pci_bus_to_host (npdev->bus); +if (hose->npu ==NULL ) { +dev_info_once (&npdev->dev,"Nvlink1 does not support contexts" ); +return 0 ; + } + nphb = hose->private_data; dev_dbg(&gpdev->dev, "destroy context opalid=%llu\n",
Greg Kroah-Hartman
maintainerPATCH 387/453 powerpc/powernv/memtrace: Dont leak kernel memory to user space
In reply to Greg Kroah-HartmanFrom: David Hildenbrand <[email protected]>
commit c74cf7a3d59a21b290fe0468f5b470d0b8ee37df upstream.
We currently leak kernel memory to user space, because memory offlining doesn't do any implicit clearing of memory and we are missing explicit clearing of memory.
Let's keep it simple and clear pages before removing the linear mapping.
Reproduced in QEMU/TCG with 10 GiB of main memory:
[root@localhost ~]# dd obs=9G if=/dev/urandom of=/dev/null
[... wait until "free -m" used counter no longer changes and cancel] 19665802+0 records in
1+0 records out
9663676416 bytes (9.7 GB, 9.0 GiB) copied, 135.548 s, 71.3 MB/s [root@localhost ~]# cat /sys/devices/system/memory/block_size_bytes 40000000
[root@localhost ~]# echo 0x40000000 > /sys/kernel/debug/powerpc/memtrace/enable
[ 402.978663][ T1086] page:000000001bc4bc74 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x24900 [ 402.980063][ T1086] flags: 0x7ffff000001000(reserved) [ 402.980415][ T1086] raw: 007ffff000001000 c00c000000924008 c00c000000924008 0000000000000000 [ 402.980627][ T1086] raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000 [ 402.980845][ T1086] page dumped because: unmovable page [ 402.989608][ T1086] Offlined Pages 16384 [ 403.324155][ T1086] memtrace: Allocated trace memory on node 0 at 0x0000000200000000
Before this patch:
[root@localhost ~]# hexdump -C /sys/kernel/debug/powerpc/memtrace/00000000/trace | head
00000000 c8 25 72 51 4d 26 36 c5 5c c2 56 15 d5 1a cd 10 |.%rQM&6.\.V.....|
00000010 19 b9 50 b2 cb e3 60 b8 ec 0a f3 ec 4b 3c 39 f0 |..P...`.....K<9.|$
00000020 4e 5a 4c cf bd 26 19 ff 37 79 13 67 24 b7 b8 57 |NZL..&..7y.g$..W|$
00000030 98 3e f5 be 6f 14 6a bd a4 52 bc 6e e9 e0 c1 5d |.>..o.j..R.n...]|$
00000040 76 b3 ae b5 88 d7 da e3 64 23 85 2c 10 88 07 b6 |v.......d#.,....|$
00000050 9a d8 91 de f7 50 27 69 2e 64 9c 6f d3 19 45 79 |.....P'i.d.o..Ey|$
00000060 6a 6f 8a 61 71 19 1f c7 f1 df 28 26 ca 0f 84 55 |jo.aq.....(&...U|$
00000070 01 3f be e4 e2 e1 da ff 7b 8c 8e 32 37 b4 24 53 |.?......{..27.$S|$
00000080 1b 70 30 45 56 e6 8c c4 0e b5 4c fb 9f dd 88 06 |.p0EV.....L.....|$
00000090 ef c4 18 79 f1 60 b1 5c 79 59 4d f4 36 d7 4a 5c |...y.`.\yYM.6.J\|$After this patch:
[root@localhost ~]# hexdump -C /sys/kernel/debug/powerpc/memtrace/00000000/trace | head 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| *
40000000
--- arch/powerpc/platforms/powernv/memtrace.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
arch/powerpc/platforms/powernv/memtrace.c +22 -0
@@ -67,6 +67,23 @@ static int change_memblock_state(structreturn 0 ; } +static void memtrace_clear_range (unsigned long start_pfn, +unsigned long nr_pages) +{ +unsigned long pfn; + +/* +* As pages are offline, we cannot trust the memmap anymore. As HIGHMEM +* does not apply, avoid passing around "struct page" and use +* clear_page() instead directly. +*/ +for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { +if (IS_ALIGNED (pfn,PAGES_PER_SECTION )) +cond_resched (); +clear_page (__va (PFN_PHYS (pfn))); + } +} +/* called with device_hotplug_lock held */ static bool memtrace_offline_pages (u32 nid,u64 start_pfn,u64 nr_pages) {
@@ -112,6 +129,11 @@ static u64 memtrace_alloc_node(u32 nid,for (base_pfn = end_pfn; base_pfn > start_pfn; base_pfn -= nr_pages) {if (memtrace_offline_pages (nid, base_pfn, nr_pages) == true) {/* +* Clear the range while we still have a linear +* mapping. +*/ +memtrace_clear_range (base_pfn, nr_pages); +/* * Remove memory in memory block size chunks so that * iomem resources are always split to the same size and * we never try to remove memory that spans two iomem
Greg Kroah-Hartman
maintainerPATCH 388/453 powerpc/powernv/memtrace: Fix crashing the kernel when enabling concurrently
In reply to Greg Kroah-HartmanFrom: David Hildenbrand <[email protected]>
commit d6718941a2767fb383e105d257d2105fe4f15f0e upstream.
It's very easy to crash the kernel right now by simply trying to enable memtrace concurrently, hammering on the "enable" interface
loop.sh:
#!/bin/bash
dmesg --console-off
while true; do
echo 0x40000000 > /sys/kernel/debug/powerpc/memtrace/enable
done
[root@localhost ~]# loop.sh &
[root@localhost ~]# loop.sh &
Resulting quickly in a kernel crash. Let's properly protect using a mutex.
--- arch/powerpc/platforms/powernv/memtrace.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
arch/powerpc/platforms/powernv/memtrace.c +15 -7
@@ -30,6 +30,7 @@ struct memtrace_entry {char name[16 ]; }; +static DEFINE_MUTEX (memtrace_mutex);static u64 memtrace_size;static struct memtrace_entry *memtrace_array;
@@ -290,6 +291,7 @@ static int memtrace_online(void)static int memtrace_enable_set (void *data,u64 val) { +int rc = -EAGAIN ;u64 bytes;/*
@@ -302,25 +304,31 @@ static int memtrace_enable_set(void *datreturn -EINVAL ; } +mutex_lock (&memtrace_mutex); +/* Re-add/online previously removed/offlined memory */ if (memtrace_size) {if (memtrace_online ()) -return -EAGAIN ; + goto out_unlock; } -if (!val) -return 0 ; +if (!val) { + rc =0 ; + goto out_unlock; + }/* Offline and remove memory */ if (memtrace_init_regions_runtime (val)) -return -EINVAL ; + goto out_unlock;if (memtrace_init_debugfs ()) -return -EINVAL ; + goto out_unlock; memtrace_size = val; - -return 0 ; + rc =0 ; +out_unlock: +mutex_unlock (&memtrace_mutex); +return rc; }static int memtrace_enable_get (void *data,u64 *val)
Greg Kroah-Hartman
maintainerPATCH 389/453 ima: Dont modify file descriptor mode on the fly
In reply to Greg Kroah-HartmanFrom: Roberto Sassu <[email protected]>
commit 207cdd565dfc95a0a5185263a567817b7ebf5467 upstream.
Commit a408e4a86b36b ("ima: open a new file instance if no read permissions") already introduced a second open to measure a file when the original file descriptor does not allow it. However, it didn't remove the existing method of changing the mode of the original file descriptor, which is still necessary if the current process does not have enough privileges to open a new one.
Changing the mode isn't really an option, as the filesystem might need to do preliminary steps to make the read possible. Thus, this patch removes the code and keeps the second open as the only option to measure a file when it is unreadable with the original file descriptor.
--- security/integrity/ima/ima_crypto.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-)
security/integrity/ima/ima_crypto.c +5 -15
@@ -411,7 +411,7 @@ int ima_calc_file_hash(struct file *fileloff_t i_size;int rc;struct file *f = file; -bool new_file_instance = false, modified_mode = false; +bool new_file_instance = false;/* * For consistency, fail file's opened with the O_DIRECT flag on
@@ -429,18 +429,10 @@ int ima_calc_file_hash(struct file *file O_TRUNC | O_CREAT | O_NOCTTY | O_EXCL); flags |=O_RDONLY ; f =dentry_open (&file->f_path, flags, file->f_cred); -if (IS_ERR (f)) { -/* -* Cannot open the file again, lets modify f_mode -* of original and continue -*/ -pr_info_ratelimited ("Unable to reopen file for reading.\n" ); - f = file; - f->f_mode |=FMODE_READ ; - modified_mode = true; - }else { - new_file_instance = true; - } +if (IS_ERR (f)) +return PTR_ERR (f); + + new_file_instance = true; } i_size =i_size_read (file_inode (f));
@@ -455,8 +447,6 @@ int ima_calc_file_hash(struct file *file out:if (new_file_instance)fput (f); -else if (modified_mode) - f->f_mode &= ~FMODE_READ ;return rc; }
Greg Kroah-Hartman
maintainerPATCH 390/453 um: Remove use of asprinf in umid.c
In reply to Greg Kroah-HartmanFrom: Anton Ivanov <[email protected]>
commit 97be7ceaf7fea68104824b6aa874cff235333ac1 upstream.
asprintf is not compatible with the existing uml memory allocation mechanism. Its use on the "user" side of UML results in a corrupt slab state.
--- arch/um/os-Linux/umid.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-)
arch/um/os-Linux/umid.c +5 -12
@@ -137,20 +137,13 @@ static inline int is_umdir_used(char *di {char pid[sizeof ("nnnnn\0" )], *end, *file;int dead, fd, p, n, err; -size_t filelen; +size_t filelen =strlen (dir) +sizeof ("/pid" ) +1 ; - err =asprintf (&file,"%s/pid" , dir); -if (err <0 ) -return 0 ; + file =malloc (filelen); +if (!file) +return -ENOMEM ; - filelen =strlen (file); - - n =snprintf (file, filelen,"%s/pid" , dir); -if (n >= filelen) { -printk (UM_KERN_ERR "is_umdir_used - pid filename too long\n" ); - err = -E2BIG ; - goto out; - } +snprintf (file, filelen,"%s/pid" , dir); dead =0 ; fd =open (file,O_RDONLY );
Greg Kroah-Hartman
maintainerPATCH 391/453 ceph: fix race in concurrent __ceph_remove_cap invocations
In reply to Greg Kroah-HartmanFrom: Luis Henriques <[email protected]>
commit e5cafce3ad0f8652d6849314d951459c2bff7233 upstream.
A NULL pointer dereference may occur in __ceph_remove_cap with some of the callbacks used in ceph_iterate_session_caps, namely trim_caps_cb and remove_session_caps_cb. Those callers hold the session->s_mutex, so they are prevented from concurrent execution, but ceph_evict_inode does not.
Since the callers of this function hold the i_ceph_lock, the fix is simply a matter of returning immediately if caps->ci is NULL.
Cc: [email protected]
URL: https://tracker.ceph.com/issues/43272
--- fs/ceph/caps.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
fs/ceph/caps.c +9 -2
@@ -1052,12 +1052,19 @@ void __ceph_remove_cap(struct ceph_cap * {struct ceph_mds_session *session = cap->session;struct ceph_inode_info *ci = cap->ci; -struct ceph_mds_client *mdsc = -ceph_sb_to_client (ci->vfs_inode.i_sb)->mdsc; +struct ceph_mds_client *mdsc;int removed =0 ; +/* 'ci' being NULL means the remove have already occurred */ +if (!ci) { +dout ("%s: cap inode is NULL\n" , __func__); +return ; + } +dout ("__ceph_remove_cap %p from %p\n" , cap, &ci->vfs_inode); + mdsc =ceph_inode_to_client (&ci->vfs_inode)->mdsc; +/* remove from inode's cap rbtree, and clear auth cap */ rb_erase (&cap->ci_node, &ci->i_caps);if (ci->i_auth_cap == cap)
Greg Kroah-Hartman
maintainerPATCH 392/453 SMB3: avoid confusing warning message on mount to Azure
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit ebcd6de98754d9b6a5f89d7835864b1c365d432f upstream.
Mounts to Azure cause an unneeded warning message in dmesg
"CIFS: VFS: parse_server_interfaces: incomplete interface info"
Azure rounds up the size (by 8 additional bytes, to a 16 byte boundary) of the structure returned on the query of the server interfaces at mount time. This is permissible even though different than other servers so do not log a warning if query network interfaces response is only rounded up by 8 bytes or fewer.
--- fs/cifs/smb2ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/cifs/smb2ops.c +2 -1
@@ -478,7 +478,8 @@ parse_server_interfaces(struct network_i goto out; } -if (bytes_left || p->Next) +/* Azure rounds the buffer size up 8, to a 16 byte boundary */ +if ((bytes_left >8 ) || p->Next)cifs_dbg (VFS ,"%s: incomplete interface info\n" , __func__);
Greg Kroah-Hartman
maintainerPATCH 393/453 ubifs: wbuf: Dont leak kernel memory to flash
In reply to Greg Kroah-HartmanFrom: Richard Weinberger <[email protected]>
commit 20f1431160c6b590cdc269a846fc5a448abf5b98 upstream.
Write buffers use a kmalloc()'ed buffer, they can leak up to seven bytes of kernel memory to flash if writes are not aligned.
So use ubifs_pad() to fill these gaps with padding bytes. This was never a problem while scanning because the scanner logic manually aligns node lengths and skips over these gaps.
--- fs/ubifs/io.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
fs/ubifs/io.c +11 -2
@@ -319,7 +319,7 @@ void ubifs_pad(const struct ubifs_info * {uint32_t crc; -ubifs_assert (c, pad >=0 && !(pad &7 )); +ubifs_assert (c, pad >=0 );if (pad >=UBIFS_PAD_NODE_SZ ) {struct ubifs_ch *ch = buf;
@@ -764,6 +764,10 @@ int ubifs_wbuf_write_nolock(struct ubifs* write-buffer. */ memcpy (wbuf->buf + wbuf->used, buf, len); +if (aligned_len > len) { +ubifs_assert (c, aligned_len - len <8 ); +ubifs_pad (c, wbuf->buf + wbuf->used + len, aligned_len - len); + }if (aligned_len == wbuf->avail) { dbg_io("flush jhead %s wbuf to LEB %d:%d",
@@ -856,13 +860,18 @@ int ubifs_wbuf_write_nolock(struct ubifs }spin_lock (&wbuf->lock); -if (aligned_len) +if (aligned_len) {/* * And now we have what's left and what does not take whole * max. write unit, so write it to the write-buffer and we are * done. */ memcpy (wbuf->buf, buf + written, len); +if (aligned_len > len) { +ubifs_assert (c, aligned_len - len <8 ); +ubifs_pad (c, wbuf->buf + len, aligned_len - len); + } + }if (c->leb_size - wbuf->offs >= c->max_write_size) wbuf->size = c->max_write_size;
Greg Kroah-Hartman
maintainerPATCH 394/453 jffs2: Fix GC exit abnormally
In reply to Greg Kroah-HartmanFrom: Zhe Li <[email protected]>
commit 9afc9a8a4909fece0e911e72b1060614ba2f7969 upstream.
The log of this problem is:
jffs2: Error garbage collecting node at 0x***!
jffs2: No space for garbage collection. Aborting GC thread
This is because GC believe that it do nothing, so it abort.
After going over the image of jffs2, I find a scene that can trigger this problem stably.
The scene is: there is a normal dirent node at summary-area, but abnormal at corresponding not-summary-area with error name_crc.
The reason that GC exit abnormally is because it find that abnormal dirent node to GC, but when it goes to function jffs2_add_fd_to_list, it cannot meet the condition listed below:
if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name))
So no node is marked obsolete, statistical information of erase_block do not change, which cause GC exit abnormally.
The root cause of this problem is: we do not check the name_crc of the abnormal dirent node with summary is enabled.
Noticed that in function jffs2_scan_dirent_node, we use function jffs2_scan_dirty_space to deal with the dirent node with error name_crc. So this patch add a checking code in function read_direntry to ensure the correctness of dirent node. If checked failed, the dirent node will be marked obsolete so GC will pass this node and this problem will be fixed.
--- fs/jffs2/readinode.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
fs/jffs2/readinode.c +16 -0
@@ -672,6 +672,22 @@ static inline int read_direntry(struct jjffs2_free_full_dirent (fd);return -EIO ; } + +#ifdef CONFIG_JFFS2_SUMMARY +/* +* we use CONFIG_JFFS2_SUMMARY because without it, we +* have checked it while mounting +*/ + crc =crc32 (0 , fd->name, rd->nsize); +if (unlikely (crc !=je32_to_cpu (rd->name_crc))) { +JFFS2_NOTICE ("name CRC failed on dirent node at" +"%#08x: read %#08x,calculated %#08x\n" , +ref_offset (ref),je32_to_cpu (rd->node_crc), crc); +jffs2_mark_node_obsolete (c, ref); +jffs2_free_full_dirent (fd); +return 0 ; + } +#endif } fd->nhash =full_name_hash (NULL , fd->name, rd->nsize);
Greg Kroah-Hartman
maintainerPATCH 395/453 jffs2: Fix ignoring mounting options problem during remounting
In reply to Greg Kroah-HartmanFrom: lizhe <[email protected]>
commit 08cd274f9b8283a1da93e2ccab216a336da83525 upstream.
The jffs2 mount options will be ignored when remounting jffs2. It can be easily reproduced with the steps listed below.
1. mount -t jffs2 -o compr=none /dev/mtdblockx /mnt
2. mount -o remount compr=zlib /mnt
Since ec10a24f10c8, the option parsing happens before fill_super and then pass fc, which contains the options parsing results, to function jffs2_reconfigure during remounting. But function jffs2_reconfigure do not update c->mount_opts.
This patch add a function jffs2_update_mount_opts to fix this problem.
By the way, I notice that tmpfs use the same way to update remounting options. If it is necessary to unify them?
--- fs/jffs2/super.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
fs/jffs2/super.c +17 -0
@@ -221,11 +221,28 @@ static int jffs2_parse_param(struct fs_creturn 0 ; } +static inline void jffs2_update_mount_opts (struct fs_context *fc) +{ +struct jffs2_sb_info *new_c = fc->s_fs_info; +struct jffs2_sb_info *c =JFFS2_SB_INFO (fc->root->d_sb); + +mutex_lock (&c->alloc_sem); +if (new_c->mount_opts.override_compr) { + c->mount_opts.override_compr = new_c->mount_opts.override_compr; + c->mount_opts.compr = new_c->mount_opts.compr; + } +if (new_c->mount_opts.rp_size) + c->mount_opts.rp_size = new_c->mount_opts.rp_size; +mutex_unlock (&c->alloc_sem); +} +static int jffs2_reconfigure (struct fs_context *fc) {struct super_block *sb = fc->root->d_sb;sync_filesystem (sb); +jffs2_update_mount_opts (fc); +return jffs2_do_remount_fs (sb, fc); }
Greg Kroah-Hartman
maintainerPATCH 396/453 jfs: Fix array index bounds check in dbAdjTree
In reply to Greg Kroah-HartmanFrom: Dave Kleikamp <[email protected]>
commit c61b3e4839007668360ed8b87d7da96d2e59fc6c upstream.
Bounds checking tools can flag a bug in dbAdjTree() for an array index out of bounds in dmt_stree. Since dmt_stree can refer to the stree in both structures dmaptree and dmapctl, use the larger array to eliminate the false positive.
--- fs/jfs/jfs_dmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jfs/jfs_dmap.h +1 -1
@@ -183,7 +183,7 @@ typedef union dmtree {#define dmt_leafidx t1.leafidx#define dmt_height t1.height#define dmt_budmin t1.budmin -#define dmt_stree t1.stree +#define dmt_stree t2.stree/* * on-disk aggregate disk allocation map descriptor.
Greg Kroah-Hartman
maintainerPATCH 397/453 drm/amd/display: Honor the offset for plane 0.
In reply to Greg Kroah-HartmanFrom: Bas Nieuwenhuizen <[email protected]>
commit be7b9b327e79cd2db07b659af599867b629b2f66 upstream.
With modifiers I'd like to support non-dedicated buffers for images.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +9 -5
@@ -2720,6 +2720,7 @@ fill_plane_dcc_attributes(struct amdgpu_struct dc *dc = adev->dm.dc;struct dc_dcc_surface_param input;struct dc_surface_dcc_cap output; +uint64_t plane_address = afb->address + afb->base.offsets[0 ];uint32_t offset =AMDGPU_TILING_GET (info,DCC_OFFSET_256B );uint32_t i64b =AMDGPU_TILING_GET (info,DCC_INDEPENDENT_64B ) !=0 ;uint64_t dcc_address;
@@ -2763,7 +2764,7 @@ fill_plane_dcc_attributes(struct amdgpu_AMDGPU_TILING_GET (info,DCC_PITCH_MAX ) +1 ; dcc->independent_64b_blks = i64b; - dcc_address =get_dcc_address (afb->address, info); + dcc_address =get_dcc_address (plane_address, info); address->grph.meta_addr.low_part =lower_32_bits (dcc_address); address->grph.meta_addr.high_part =upper_32_bits (dcc_address);
@@ -2791,6 +2792,8 @@ fill_plane_buffer_attributes(struct amdgmemset (address,0 ,sizeof (*address));if (format <SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ) { +uint64_t addr = afb->address + fb->offsets[0 ]; + plane_size->surface_size.x =0 ; plane_size->surface_size.y =0 ; plane_size->surface_size.width = fb->width;
@@ -2799,9 +2802,10 @@ fill_plane_buffer_attributes(struct amdg fb->pitches[0 ] / fb->format->cpp[0 ]; address->type =PLN_ADDR_TYPE_GRAPHICS ; - address->grph.addr.low_part =lower_32_bits (afb->address); - address->grph.addr.high_part =upper_32_bits (afb->address); + address->grph.addr.low_part =lower_32_bits (addr); + address->grph.addr.high_part =upper_32_bits (addr); }else if (format <SURFACE_PIXEL_FORMAT_INVALID ) { +uint64_t luma_addr = afb->address + fb->offsets[0 ];uint64_t chroma_addr = afb->address + fb->offsets[1 ]; plane_size->surface_size.x =0 ;
@@ -2822,9 +2826,9 @@ fill_plane_buffer_attributes(struct amdg address->type =PLN_ADDR_TYPE_VIDEO_PROGRESSIVE ; address->video_progressive.luma_addr.low_part = -lower_32_bits (afb->address); +lower_32_bits (luma_addr); address->video_progressive.luma_addr.high_part = -upper_32_bits (afb->address); +upper_32_bits (luma_addr); address->video_progressive.chroma_addr.low_part =lower_32_bits (chroma_addr); address->video_progressive.chroma_addr.high_part =
Greg Kroah-Hartman
maintainerPATCH 398/453 drm/amd/display: Fix memory leaks in S3 resume
In reply to Greg Kroah-HartmanFrom: Stylon Wang <[email protected]>
commit a135a1b4c4db1f3b8cbed9676a40ede39feb3362 upstream.
EDID parsing in S3 resume pushes new display modes
to probed_modes list but doesn't consolidate to actual mode list. This creates a race condition when amdgpu_dm_connector_ddc_get_modes() re-initializes the list head without walking the list and results in memory leak.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 -1
@@ -1434,7 +1434,8 @@ amdgpu_dm_update_connector_after_detect(drm_connector_update_edid_property (connector, aconnector->edid); -drm_add_edid_modes (connector, aconnector->edid); + aconnector->num_modes =drm_add_edid_modes (connector, aconnector->edid); +drm_connector_list_update (connector);if (aconnector->dc_link->aux_mode) drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
Greg Kroah-Hartman
maintainerPATCH 399/453 drm/dp_aux_dev: check aux_dev before use in drm_dp_aux_dev_get_by_minor()
In reply to Greg Kroah-HartmanFrom: Zwane Mwaikambo <[email protected]>
commit 73b62cdb93b68d7e2c1d373c6a411bc00c53e702 upstream.
I observed this when unplugging a DP monitor whilst a computer is asleep and then waking it up. This left DP chardev nodes still being present on the filesystem and accessing these device nodes caused an oops because drm_dp_aux_dev_get_by_minor() assumes a device exists if it is opened. This can also be reproduced by creating a device node with mknod(1) and issuing an open(2)
[166164.933198] BUG: kernel NULL pointer dereference, address: 0000000000000018 [166164.933202] #PF: supervisor read access in kernel mode [166164.933204] #PF: error_code(0x0000) - not-present page [166164.933205] PGD 0 P4D 0 [166164.933208] Oops: 0000 [#1] PREEMPT SMP NOPTI [166164.933211] CPU: 4 PID: 99071 Comm: fwupd Tainted: G W 5.8.0-rc6+ #1 [166164.933213] Hardware name: LENOVO 20RD002VUS/20RD002VUS, BIOS R16ET25W (1.11 ) 04/21/2020 [166164.933232] RIP: 0010:drm_dp_aux_dev_get_by_minor+0x29/0x70 [drm_kms_helper] [166164.933234] Code: 00 0f 1f 44 00 00 55 48 89 e5 41 54 41 89 fc 48 c7 c7 60 01 a4 c0 e8 26 ab 30 d7 44 89 e6 48 c7 c7 80 01 a4 c0 e8 47 94 d6 d6 <8b> 50 18 49 89 c4 48 8d 78 18 85 d2 74 33 8d 4a 01 89 d0 f0 0f b1 [166164.933236] RSP: 0018:ffffb7d7c41cbbf0 EFLAGS: 00010246 [166164.933237] RAX: 0000000000000000 RBX: ffff8a90001fe900 RCX: 0000000000000000 [166164.933238] RDX: 0000000000000000 RSI: 0000000000000003 RDI: ffffffffc0a40180 [166164.933239] RBP: ffffb7d7c41cbbf8 R08: 0000000000000000 R09: ffff8a93e157d6d0 [166164.933240] R10: 0000000000000000 R11: ffffffffc0a40188 R12: 0000000000000003 [166164.933241] R13: ffff8a9402200e80 R14: ffff8a90001fe900 R15: 0000000000000000 [166164.933244] FS: 00007f7fb041eb00(0000) GS:ffff8a9411500000(0000) knlGS:0000000000000000 [166164.933245] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [166164.933246] CR2: 0000000000000018 CR3: 00000000352c2003 CR4: 00000000003606e0 [166164.933247] Call Trace: [166164.933264] auxdev_open+0x1b/0x40 [drm_kms_helper] [166164.933278] chrdev_open+0xa7/0x1c0 [166164.933282] ? cdev_put.part.0+0x20/0x20 [166164.933287] do_dentry_open+0x161/0x3c0 [166164.933291] vfs_open+0x2d/0x30 [166164.933297] path_openat+0xb27/0x10e0 [166164.933306] ? atime_needs_update+0x73/0xd0 [166164.933309] do_filp_open+0x91/0x100 [166164.933313] ? __alloc_fd+0xb2/0x150 [166164.933316] do_sys_openat2+0x210/0x2d0 [166164.933318] do_sys_open+0x46/0x80 [166164.933320] __x64_sys_openat+0x20/0x30 [166164.933328] do_syscall_64+0x52/0xc0 [166164.933336] entry_SYSCALL_64_after_hwframe+0x44/0xa9
(gdb) disassemble drm_dp_aux_dev_get_by_minor+0x29 Dump of assembler code for function drm_dp_aux_dev_get_by_minor:
0x0000000000017b10 <+0>: callq 0x17b15 <drm_dp_aux_dev_get_by_minor+5> 0x0000000000017b15 <+5>: push %rbp 0x0000000000017b16 <+6>: mov %rsp,%rbp 0x0000000000017b19 <+9>: push %r12 0x0000000000017b1b <+11>: mov %edi,%r12d 0x0000000000017b1e <+14>: mov $0x0,%rdi 0x0000000000017b25 <+21>: callq 0x17b2a <drm_dp_aux_dev_get_by_minor+26> 0x0000000000017b2a <+26>: mov %r12d,%esi 0x0000000000017b2d <+29>: mov $0x0,%rdi 0x0000000000017b34 <+36>: callq 0x17b39 <drm_dp_aux_dev_get_by_minor+41> 0x0000000000017b39 <+41>: mov 0x18(%rax),%edx <========= 0x0000000000017b3c <+44>: mov %rax,%r12 0x0000000000017b3f <+47>: lea 0x18(%rax),%rdi 0x0000000000017b43 <+51>: test %edx,%edx 0x0000000000017b45 <+53>: je 0x17b7a <drm_dp_aux_dev_get_by_minor+106> 0x0000000000017b47 <+55>: lea 0x1(%rdx),%ecx 0x0000000000017b4a <+58>: mov %edx,%eax 0x0000000000017b4c <+60>: lock cmpxchg %ecx,(%rdi) 0x0000000000017b50 <+64>: jne 0x17b76 <drm_dp_aux_dev_get_by_minor+102> 0x0000000000017b52 <+66>: test %edx,%edx 0x0000000000017b54 <+68>: js 0x17b6d <drm_dp_aux_dev_get_by_minor+93> 0x0000000000017b56 <+70>: test %ecx,%ecx 0x0000000000017b58 <+72>: js 0x17b6d <drm_dp_aux_dev_get_by_minor+93> 0x0000000000017b5a <+74>: mov $0x0,%rdi 0x0000000000017b61 <+81>: callq 0x17b66 <drm_dp_aux_dev_get_by_minor+86> 0x0000000000017b66 <+86>: mov %r12,%rax 0x0000000000017b69 <+89>: pop %r12 0x0000000000017b6b <+91>: pop %rbp 0x0000000000017b6c <+92>: retq 0x0000000000017b6d <+93>: xor %esi,%esi 0x0000000000017b6f <+95>: callq 0x17b74 <drm_dp_aux_dev_get_by_minor+100> 0x0000000000017b74 <+100>: jmp 0x17b5a <drm_dp_aux_dev_get_by_minor+74> 0x0000000000017b76 <+102>: mov %eax,%edx 0x0000000000017b78 <+104>: jmp 0x17b43 <drm_dp_aux_dev_get_by_minor+51> 0x0000000000017b7a <+106>: xor %r12d,%r12d 0x0000000000017b7d <+109>: jmp 0x17b5a <drm_dp_aux_dev_get_by_minor+74>
End of assembler dump.
(gdb) list *drm_dp_aux_dev_get_by_minor+0x290x17b39 is in drm_dp_aux_dev_get_by_minor (drivers/gpu/drm/drm_dp_aux_dev.c:65).
60 static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
61 {
62 struct drm_dp_aux_dev *aux_dev = NULL;
63
64 mutex_lock(&aux_idr_mutex); 65 aux_dev = idr_find(&aux_idr, index); 66 if (!kref_get_unless_zero(&aux_dev->refcount))
67 aux_dev = NULL;
68 mutex_unlock(&aux_idr_mutex);
69
(gdb) p/x &((struct drm_dp_aux_dev *)(0x0))->refcount $8 = 0x18
Looking at the caller, checks on the minor are pushed down to drm_dp_aux_dev_get_by_minor()
static int auxdev_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
struct drm_dp_aux_dev *aux_dev;
aux_dev = drm_dp_aux_dev_get_by_minor(minor); <====
if (!aux_dev)
return -ENODEV;
file->private_data = aux_dev;
return 0;
}--- drivers/gpu/drm/drm_dp_aux_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/drm_dp_aux_dev.c +1 -1
@@ -63,7 +63,7 @@ static struct drm_dp_aux_dev *drm_dp_auxmutex_lock (&aux_idr_mutex); aux_dev =idr_find (&aux_idr, index); -if (!kref_get_unless_zero (&aux_dev->refcount)) +if (aux_dev && !kref_get_unless_zero (&aux_dev->refcount)) aux_dev =NULL ;mutex_unlock (&aux_idr_mutex);
Greg Kroah-Hartman
maintainerPATCH 400/453 drm/i915: Fix mismatch between misplaced vma check and vma insert
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit 0e53656ad8abc99e0a80c3de611e593ebbf55829 upstream.
When inserting a VMA, we restrict the placement to the low 4G unless the caller opts into using the full range. This was done to allow usersapce the opportunity to transition slowly from a 32b address space, and to avoid breaking inherent 32b assumptions of some commands.
However, for insert we limited ourselves to 4G-4K, but on verification we allowed the full 4G. This causes some attempts to bind a new buffer to sporadically fail with -ENOSPC, but at other times be bound successfully.
commit 48ea1e32c39d ("drm/i915/gen9: Set PIN_ZONE_4G end to 4GB - 1 page") suggests that there is a genuine problem with stateless addressing that cannot utilize the last page in 4G and so we purposefully excluded it. This means that the quick pin pass may cause us to utilize a buggy placement.
Testcase: igt/gem_exec_params/larger-than-life-batch
--- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +1 -1
@@ -367,7 +367,7 @@ eb_vma_misplaced(const struct drm_i915_greturn true;if (!(flags &EXEC_OBJECT_SUPPORTS_48B_ADDRESS ) && - (vma->node.start + vma->node.size -1 ) >>32 ) + (vma->node.start + vma->node.size +4095 ) >>32 )return true; if (flags & __EXEC_OBJECT_NEEDS_MAP &&
Greg Kroah-Hartman
maintainerPATCH 401/453 spi: pxa2xx: Fix use-after-free on unbind
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 5626308bb94d9f930aa5f7c77327df4c6daa7759 upstream.
pxa2xx_spi_remove() accesses the driver's private data after calling spi_unregister_controller() even though that function releases the last reference on the spi_controller and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master/slave() helper which keeps the private data accessible until the driver has unbound.
--- drivers/spi/spi-pxa2xx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/spi/spi-pxa2xx.c +2 -3
@@ -1675,9 +1675,9 @@ static int pxa2xx_spi_probe(struct platf }if (platform_info->is_slave) - controller =spi_alloc_slave (dev,sizeof (struct driver_data )); + controller =devm_spi_alloc_slave (dev,sizeof (*drv_data));else - controller =spi_alloc_master (dev,sizeof (struct driver_data )); + controller =devm_spi_alloc_master (dev,sizeof (*drv_data));if (!controller) {dev_err (&pdev->dev,"cannot alloc spi_controller\n" );
@@ -1900,7 +1900,6 @@ out_error_dma_irq_alloc:free_irq (ssp->irq, drv_data); out_error_controller_alloc: -spi_controller_put (controller);pxa_ssp_free (ssp);return status; }
Greg Kroah-Hartman
maintainerPATCH 402/453 spi: spi-sh: Fix use-after-free on unbind
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit e77df3eca12be4b17f13cf9f215cff248c57d98f upstream.
spi_sh_remove() accesses the driver's private data after calling spi_unregister_master() even though that function releases the last reference on the spi_master and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
--- drivers/spi/spi-sh.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
drivers/spi/spi-sh.c +4 -9
@@ -440,7 +440,7 @@ static int spi_sh_probe(struct platform_if (irq <0 )return irq; - master =spi_alloc_master (&pdev->dev,sizeof (struct spi_sh_data )); + master =devm_spi_alloc_master (&pdev->dev,sizeof (struct spi_sh_data ));if (master ==NULL ) {dev_err (&pdev->dev,"spi_alloc_master error.\n" );return -ENOMEM ;
@@ -458,16 +458,14 @@ static int spi_sh_probe(struct platform_break ;default :dev_err (&pdev->dev,"No support width\n" ); - ret = -ENODEV ; - goto error1; +return -ENODEV ; } ss->irq = irq; ss->master = master; ss->addr =devm_ioremap (&pdev->dev, res->start,resource_size (res));if (ss->addr ==NULL ) {dev_err (&pdev->dev,"ioremap error.\n" ); - ret = -ENOMEM ; - goto error1; +return -ENOMEM ; }INIT_LIST_HEAD (&ss->queue);spin_lock_init (&ss->lock);
@@ -477,7 +475,7 @@ static int spi_sh_probe(struct platform_ ret =request_irq (irq, spi_sh_irq,0 ,"spi_sh" , ss);if (ret <0 ) {dev_err (&pdev->dev,"request_irq error\n" ); - goto error1; +return ret; } master->num_chipselect =2 ;
@@ -496,9 +494,6 @@ static int spi_sh_probe(struct platform_ error3:free_irq (irq, ss); - error1: -spi_master_put (master); -return ret; }
Greg Kroah-Hartman
maintainerPATCH 403/453 spi: atmel-quadspi: Fix use-after-free on unbind
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit c7b884561cb5b641f3dbba950094110794119a6d upstream.
atmel_qspi_remove() accesses the driver's private data after calling spi_unregister_controller() even though that function releases the last reference on the spi_controller and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
--- drivers/spi/atmel-quadspi.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
drivers/spi/atmel-quadspi.c +5 -10
@@ -454,7 +454,7 @@ static int atmel_qspi_probe(struct platfstruct resource *res;int irq, err =0 ; - ctrl =spi_alloc_master (&pdev->dev,sizeof (*aq)); + ctrl =devm_spi_alloc_master (&pdev->dev,sizeof (*aq));if (!ctrl)return -ENOMEM ;
@@ -476,8 +476,7 @@ static int atmel_qspi_probe(struct platf aq->regs =devm_ioremap_resource (&pdev->dev, res);if (IS_ERR (aq->regs)) {dev_err (&pdev->dev,"missing registers\n" ); - err =PTR_ERR (aq->regs); - goto exit; +return PTR_ERR (aq->regs); }/* Map the AHB memory */
@@ -485,8 +484,7 @@ static int atmel_qspi_probe(struct platf aq->mem =devm_ioremap_resource (&pdev->dev, res);if (IS_ERR (aq->mem)) {dev_err (&pdev->dev,"missing AHB memory\n" ); - err =PTR_ERR (aq->mem); - goto exit; +return PTR_ERR (aq->mem); } aq->mmap_size =resource_size (res);
@@ -498,15 +496,14 @@ static int atmel_qspi_probe(struct platfif (IS_ERR (aq->pclk)) {dev_err (&pdev->dev,"missing peripheral clock\n" ); - err =PTR_ERR (aq->pclk); - goto exit; +return PTR_ERR (aq->pclk); }/* Enable the peripheral clock */ err =clk_prepare_enable (aq->pclk);if (err) {dev_err (&pdev->dev,"failed to enable the peripheral clock\n" ); - goto exit; +return err; } aq->caps =of_device_get_match_data (&pdev->dev);
@@ -557,8 +554,6 @@ disable_qspick:clk_disable_unprepare (aq->qspick); disable_pclk:clk_disable_unprepare (aq->pclk); -exit: -spi_controller_put (ctrl);return err; }
Greg Kroah-Hartman
maintainerPATCH 404/453 spi: davinci: Fix use-after-free on unbind
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 373afef350a93519b4b8d636b0895da8650b714b upstream.
davinci_spi_remove() accesses the driver's private data after it's been freed with spi_master_put().
Fix by moving the spi_master_put() to the end of the function.
--- drivers/spi/spi-davinci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-davinci.c +1 -1
@@ -1040,13 +1040,13 @@ static int davinci_spi_remove(struct plaspi_bitbang_stop (&dspi->bitbang);clk_disable_unprepare (dspi->clk); -spi_master_put (master);if (dspi->dma_rx) {dma_release_channel (dspi->dma_rx);dma_release_channel (dspi->dma_tx); } +spi_master_put (master);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 405/453 spi: fsl: fix use of spisel_boot signal on MPC8309
In reply to Greg Kroah-HartmanFrom: Rasmus Villemoes <[email protected]>
commit 122541f2b10897b08f7f7e6db5f1eb693e51f0a1 upstream.
Commit 0f0581b24bd0 ("spi: fsl: Convert to use CS GPIO descriptors") broke the use of the SPISEL_BOOT signal as a chip select on the MPC8309.
pdata->max_chipselect, which becomes master->num_chipselect, must be initialized to take into account the possibility that there's one more chip select in use than the number of GPIO chip selects.
--- drivers/spi/spi-fsl-spi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/spi/spi-fsl-spi.c +8 -3
@@ -717,10 +717,11 @@ static int of_fsl_spi_probe(struct platf type =fsl_spi_get_type (&ofdev->dev);if (type ==TYPE_FSL ) {struct fsl_spi_platform_data *pdata =dev_get_platdata (dev); +bool spisel_boot = false;#if IS_ENABLED (CONFIG_FSL_SOC )struct mpc8xxx_spi_probe_info *pinfo =to_of_pinfo (pdata); -bool spisel_boot =of_property_read_bool (np,"fsl,spisel_boot" ); + spisel_boot =of_property_read_bool (np,"fsl,spisel_boot" );if (spisel_boot) { pinfo->immr_spi_cs =ioremap (get_immrbase () +IMMR_SPI_CS_OFFSET ,4 );if (!pinfo->immr_spi_cs) {
@@ -737,10 +738,14 @@ static int of_fsl_spi_probe(struct platf* supported on the GRLIB variant. */ ret =gpiod_count (dev,"cs" ); -if (ret <=0 ) +if (ret <0 ) + ret =0 ; +if (ret ==0 && !spisel_boot) { pdata->max_chipselect =1 ; -else + }else { + pdata->max_chipselect = ret + spisel_boot; pdata->cs_control = fsl_spi_cs_control; + } } ret =of_address_to_resource (np,0 , &mem);
Greg Kroah-Hartman
maintainerPATCH 406/453 spi: gpio: Dont leak SPI master in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 7174dc655ef0578877b0b4598e69619d2be28b4d upstream.
If the call to devm_spi_register_master() fails on probe of the GPIO SPI driver, the spi_master struct is erroneously not freed:
After allocating the spi_master, its reference count is 1. The driver unconditionally decrements the reference count on unbind using a devm action. Before calling devm_spi_register_master(), the driver unconditionally increments the reference count because on success, that function will decrement the reference count on unbind. However on failure, devm_spi_register_master() does *not* decrement the reference count, so the spi_master is leaked.
The issue was introduced by commits 8b797490b4db ("spi: gpio: Make sure spi_master_put() is called in every error path") and 79567c1a321e ("spi:
gpio: Use devm_spi_register_master()"), which sought to plug leaks introduced by 9b00bc7b901f ("spi: spi-gpio: Rewrite to use GPIO descriptors") but missed this remaining leak.
The situation was later aggravated by commit d3b0ffa1d75d ("spi: gpio:
prevent memory leak in spi_gpio_probe"), which introduced a use-after-free because it releases a reference on the spi_master if devm_add_action_or_reset() fails even though the function already does that.
Fix by switching over to the new devm_spi_alloc_master() helper.
--- drivers/spi/spi-gpio.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-)
drivers/spi/spi-gpio.c +2 -13
@@ -350,11 +350,6 @@ static int spi_gpio_probe_pdata(struct preturn 0 ; } -static void spi_gpio_put (void *data) -{ -spi_master_put (data); -} -static int spi_gpio_probe (struct platform_device *pdev) {int status;
@@ -366,16 +361,10 @@ static int spi_gpio_probe(struct platfor of_id =of_match_device (spi_gpio_dt_ids, &pdev->dev); - master =spi_alloc_master (dev,sizeof (*spi_gpio)); + master =devm_spi_alloc_master (dev,sizeof (*spi_gpio));if (!master)return -ENOMEM ; - status =devm_add_action_or_reset (&pdev->dev, spi_gpio_put, master); -if (status) { -spi_master_put (master); -return status; - } -if (of_id) status =spi_gpio_probe_dt (pdev, master);else
@@ -435,7 +424,7 @@ static int spi_gpio_probe(struct platforif (status)return status; -return devm_spi_register_master (&pdev->dev,spi_master_get (master)); +return devm_spi_register_master (&pdev->dev, master); }MODULE_ALIAS ("platform:" DRIVER_NAME );
Greg Kroah-Hartman
maintainerPATCH 407/453 spi: mxic: Dont leak SPI master in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit cc53711b2191cf3b3210283ae89bf0abb98c70a3 upstream.
If the calls to devm_clk_get() or devm_ioremap_resource() fail on probe of the Macronix SPI driver, the spi_master struct is erroneously not freed.
Fix by switching over to the new devm_spi_alloc_master() helper.
--- drivers/spi/spi-mxic.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/spi/spi-mxic.c +2 -8
@@ -528,7 +528,7 @@ static int mxic_spi_probe(struct platforstruct mxic_spi *mxic;int ret; - master =spi_alloc_master (&pdev->dev,sizeof (struct mxic_spi )); + master =devm_spi_alloc_master (&pdev->dev,sizeof (struct mxic_spi ));if (!master)return -ENOMEM ;
@@ -573,15 +573,9 @@ static int mxic_spi_probe(struct platfor ret =spi_register_master (master);if (ret) {dev_err (&pdev->dev,"spi_register_master failed\n" ); - goto err_put_master; +pm_runtime_disable (&pdev->dev); } -return 0 ; - -err_put_master: -spi_master_put (master); -pm_runtime_disable (&pdev->dev); -return ret; }
Greg Kroah-Hartman
maintainerPATCH 408/453 spi: pic32: Dont leak DMA channels in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit c575e9113bff5e024d75481613faed5ef9d465b2 upstream.
If the calls to devm_request_irq() or devm_spi_register_master() fail on probe of the PIC32 SPI driver, the DMA channels requested by pic32_spi_dma_prep() are erroneously not released. Plug the leak.
--- drivers/spi/spi-pic32.c | 1 + 1 file changed, 1 insertion(+)
drivers/spi/spi-pic32.c +1 -0
@@ -825,6 +825,7 @@ static int pic32_spi_probe(struct platforeturn 0 ; err_bailout: +pic32_spi_dma_unprep (pic32s);clk_disable_unprepare (pic32s->clk); err_master:spi_master_put (master);
Greg Kroah-Hartman
maintainerPATCH 409/453 spi: rb4xx: Dont leak SPI master in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit a4729c3506c3eb1a6ca5c0289f4e7cafa4115065 upstream.
If the calls to devm_clk_get(), devm_spi_register_master() or clk_prepare_enable() fail on probe of the Mikrotik RB4xx SPI driver, the spi_master struct is erroneously not freed.
Fix by switching over to the new devm_spi_alloc_master() helper.
--- drivers/spi/spi-rb4xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-rb4xx.c +1 -1
@@ -142,7 +142,7 @@ static int rb4xx_spi_probe(struct platfoif (IS_ERR (spi_base))return PTR_ERR (spi_base); - master =spi_alloc_master (&pdev->dev,sizeof (*rbspi)); + master =devm_spi_alloc_master (&pdev->dev,sizeof (*rbspi));if (!master)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 410/453 spi: sc18is602: Dont leak SPI master in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 5b8c88462d83331dacb48aeaec8388117fef82e0 upstream.
If the call to devm_gpiod_get_optional() fails on probe of the NXP SC18IS602/603 SPI driver, the spi_master struct is erroneously not freed.
Fix by switching over to the new devm_spi_alloc_master() helper.
--- drivers/spi/spi-sc18is602.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-)
drivers/spi/spi-sc18is602.c +2 -11
@@ -239,13 +239,12 @@ static int sc18is602_probe(struct i2c_clstruct sc18is602_platform_data *pdata =dev_get_platdata (dev);struct sc18is602 *hw;struct spi_master *master; -int error;if (!i2c_check_functionality (client->adapter,I2C_FUNC_I2C |I2C_FUNC_SMBUS_WRITE_BYTE_DATA ))return -EINVAL ; - master =spi_alloc_master (dev,sizeof (struct sc18is602 )); + master =devm_spi_alloc_master (dev,sizeof (struct sc18is602 ));if (!master)return -ENOMEM ;
@@ -299,15 +298,7 @@ static int sc18is602_probe(struct i2c_cl master->min_speed_hz = hw->freq /128 ; master->max_speed_hz = hw->freq /4 ; - error =devm_spi_register_master (dev, master); -if (error) - goto error_reg; - -return 0 ; - -error_reg: -spi_master_put (master); -return error; +return devm_spi_register_master (dev, master); }static const struct i2c_device_id sc18is602_id[] = {
Greg Kroah-Hartman
maintainerPATCH 411/453 spi: st-ssc4: Fix unbalanced pm_runtime_disable() in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 5ef76dac0f2c26aeae4ee79eb830280f16d5aceb upstream.
If the calls to devm_platform_ioremap_resource(), irq_of_parse_and_map() or devm_request_irq() fail on probe of the ST SSC4 SPI driver, the runtime PM disable depth is incremented even though it was not decremented before. Fix it.
--- drivers/spi/spi-st-ssc4.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/spi/spi-st-ssc4.c +3 -2
@@ -375,13 +375,14 @@ static int spi_st_probe(struct platform_ ret =devm_spi_register_master (&pdev->dev, master);if (ret) {dev_err (&pdev->dev,"Failed to register master\n" ); - goto clk_disable; + goto rpm_disable; }return 0 ; -clk_disable: +rpm_disable:pm_runtime_disable (&pdev->dev); +clk_disable:clk_disable_unprepare (spi_st->clk); put_master:spi_master_put (master);
Greg Kroah-Hartman
maintainerPATCH 412/453 spi: synquacer: Disable clock in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 8853b2503014aca5c793d2c7f0aabc990b32bdad upstream.
If the calls to platform_get_irq() or devm_request_irq() fail on probe of the SynQuacer SPI driver, the clock "sspi->clk" is erroneously not unprepared and disabled.
If the clock rate "master->max_speed_hz" cannot be determined, the same happens and in addition the spi_master struct is not freed.
Fix it.
--- drivers/spi/spi-synquacer.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/spi/spi-synquacer.c +8 -7
@@ -658,7 +658,8 @@ static int synquacer_spi_probe(struct plif (!master->max_speed_hz) {dev_err (&pdev->dev,"missing clock source\n" ); -return -EINVAL ; + ret = -EINVAL ; + goto disable_clk; } master->min_speed_hz = master->max_speed_hz /254 ;
@@ -671,7 +672,7 @@ static int synquacer_spi_probe(struct pl rx_irq =platform_get_irq (pdev,0 );if (rx_irq <=0 ) { ret = rx_irq; - goto put_spi; + goto disable_clk; }snprintf (sspi->rx_irq_name,SYNQUACER_HSSPI_IRQ_NAME_MAX ,"%s-rx" ,dev_name (&pdev->dev));
@@ -679,13 +680,13 @@ static int synquacer_spi_probe(struct pl 0, sspi->rx_irq_name, sspi);if (ret) {dev_err (&pdev->dev,"request rx_irq failed (%d)\n" , ret); - goto put_spi; + goto disable_clk; } tx_irq =platform_get_irq (pdev,1 );if (tx_irq <=0 ) { ret = tx_irq; - goto put_spi; + goto disable_clk; }snprintf (sspi->tx_irq_name,SYNQUACER_HSSPI_IRQ_NAME_MAX ,"%s-tx" ,dev_name (&pdev->dev));
@@ -693,7 +694,7 @@ static int synquacer_spi_probe(struct pl 0, sspi->tx_irq_name, sspi);if (ret) {dev_err (&pdev->dev,"request tx_irq failed (%d)\n" , ret); - goto put_spi; + goto disable_clk; } master->dev.of_node = np;
@@ -711,7 +712,7 @@ static int synquacer_spi_probe(struct pl ret =synquacer_spi_enable (master);if (ret) - goto fail_enable; + goto disable_clk;pm_runtime_set_active (sspi->dev);pm_runtime_enable (sspi->dev);
@@ -724,7 +725,7 @@ static int synquacer_spi_probe(struct pl disable_pm:pm_runtime_disable (sspi->dev); -fail_enable: +disable_clk:clk_disable_unprepare (sspi->clk); put_spi:spi_master_put (master);
Greg Kroah-Hartman
maintainerPATCH 413/453 spi: mt7621: Disable clock in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 24f7033405abe195224ec793dbc3d7a27dec0b98 upstream.
Commit 702b15cb9712 ("spi: mt7621: fix missing clk_disable_unprepare() on error in mt7621_spi_probe") sought to disable the SYS clock on probe errors, but only did so for 2 of 3 potentially failing calls: The clock needs to be disabled on failure of devm_spi_register_controller() as well.
Moreover, the commit purports to fix a bug in commit cbd66c626e16 ("spi:
mt7621: Move SPI driver out of staging") but in reality the bug has existed since the driver was first introduced.
--- drivers/spi/spi-mt7621.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/spi/spi-mt7621.c +5 -1
@@ -382,7 +382,11 @@ static int mt7621_spi_probe(struct platfreturn ret; } -return devm_spi_register_controller (&pdev->dev, master); + ret =devm_spi_register_controller (&pdev->dev, master); +if (ret) +clk_disable_unprepare (clk); + +return ret; }static int mt7621_spi_remove (struct platform_device *pdev)
Greg Kroah-Hartman
maintainerPATCH 414/453 spi: mt7621: Dont leak SPI master in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 46b5c4fb87ce8211e0f9b0383dbde72c3652d2ba upstream.
If the calls to device_reset() or devm_spi_register_controller() fail on probe of the MediaTek MT7621 SPI driver, the spi_controller struct is erroneously not freed. Fix by switching over to the new devm_spi_alloc_master() helper.
Additionally, there's an ordering issue in mt7621_spi_remove() wherein the spi_controller is unregistered after disabling the SYS clock. The correct order is to call spi_unregister_controller() *before* this teardown step because bus accesses may still be ongoing until that function returns.
All of these bugs have existed since the driver was first introduced, so it seems fair to fix them together in a single commit.
--- drivers/spi/spi-mt7621.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/spi/spi-mt7621.c +3 -2
@@ -350,7 +350,7 @@ static int mt7621_spi_probe(struct platfif (status)return status; - master =spi_alloc_master (&pdev->dev,sizeof (*rs)); + master =devm_spi_alloc_master (&pdev->dev,sizeof (*rs));if (!master) {dev_info (&pdev->dev,"master allocation failed\n" );clk_disable_unprepare (clk);
@@ -382,7 +382,7 @@ static int mt7621_spi_probe(struct platfreturn ret; } - ret =devm_spi_register_controller (&pdev->dev, master); + ret =spi_register_controller (master);if (ret)clk_disable_unprepare (clk);
@@ -397,6 +397,7 @@ static int mt7621_spi_remove(struct plat master =dev_get_drvdata (&pdev->dev); rs =spi_controller_get_devdata (master); +spi_unregister_controller (master);clk_disable_unprepare (rs->clk);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 415/453 spi: atmel-quadspi: Disable clock in probe error path
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 0e685017c7ba1a2fe9f6f1e7a9302890747d934c upstream.
If the call to of_device_get_match_data() fails on probe of the Atmel QuadSPI driver, the clock "aq->pclk" is erroneously not unprepared and disabled. Fix it.
--- drivers/spi/atmel-quadspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/atmel-quadspi.c +1 -1
@@ -510,7 +510,7 @@ static int atmel_qspi_probe(struct platfif (!aq->caps) {dev_err (&pdev->dev,"Could not retrieve QSPI caps\n" ); err = -EINVAL ; - goto exit; + goto disable_pclk; }if (aq->caps->has_qspick) {
Greg Kroah-Hartman
maintainerPATCH 416/453 spi: atmel-quadspi: Fix AHB memory accesses
In reply to Greg Kroah-HartmanFrom: Tudor Ambarus <[email protected]>
commit cac8c821059639b015586abf61623c62cc549a13 upstream.
Following error was seen when mounting a 16MByte ubifs:
UBIFS error (ubi0:0 pid 1893): check_lpt_type.constprop.6: invalid type (15) in LPT node type
QSPI_IFR.TFRTYP was not set correctly. When data transfer is enabled and one wants to access the serial memory through AHB in order to:
- read in the serial memory, but not a memory data, for example a JEDEC-ID, QSPI_IFR.TFRTYP must be written to '0' (both sama5d2 and sam9x60).
- read in the serial memory, and particularly a memory data, TFRTYP must be written to '1' (both sama5d2 and sam9x60).
- write in the serial memory, but not a memory data, for example writing the configuration or the QSPI_SR, TFRTYP must be written to '2' for sama5d2 and to '0' for sam9x60.
- write in the serial memory in particular to program a memory data, TFRTYP must be written to '3' for sama5d2 and to '1' for sam9x60.
Fix the setting of the QSPI_IFR.TFRTYP field.
--- drivers/spi/atmel-quadspi.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/spi/atmel-quadspi.c +7 -3
@@ -284,10 +284,14 @@ static int atmel_qspi_set_cfg(struct atmif (dummy_cycles) ifr |=QSPI_IFR_NBDUM (dummy_cycles); -/* Set data enable */ -if (op->data.nbytes) +/* Set data enable and data transfer type. */ +if (op->data.nbytes) { ifr |=QSPI_IFR_DATAEN ; +if (op->addr.nbytes) + ifr |=QSPI_IFR_TFRTYP_MEM ; + } +/* * If the QSPI controller is set in regular SPI mode, set it in * Serial Memory Mode (SMM).
@@ -312,7 +316,7 @@ static int atmel_qspi_set_cfg(struct atmwritel_relaxed (icr, aq->regs +QSPI_WICR );writel_relaxed (ifr, aq->regs +QSPI_IFR ); }else { -if (op->data.dir ==SPI_MEM_DATA_OUT ) +if (op->data.nbytes && op->data.dir ==SPI_MEM_DATA_OUT ) ifr |=QSPI_IFR_SAMA5D2_WRITE_TRSFR ;/* Set QSPI Instruction Frame registers */
Greg Kroah-Hartman
maintainerPATCH 417/453 soc: qcom: smp2p: Safely acquire spinlock without IRQs
In reply to Greg Kroah-HartmanFrom: Evan Green <[email protected]>
commit fc3e62e25c3896855b7c3d72df19ca6be3459c9f upstream.
smp2p_update_bits() should disable interrupts when it acquires its spinlock. This is important because without the _irqsave, a priority inversion can occur.
This function is called both with interrupts enabled in qcom_q6v5_request_stop(), and with interrupts disabled in ipa_smp2p_panic_notifier(). IRQ handling of spinlocks should be consistent to avoid the panic notifier deadlocking because it's sitting on the thread that's already got the lock via _request_stop().
Found via lockdep.
--- drivers/soc/qcom/smp2p.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/soc/qcom/smp2p.c +3 -2
@@ -318,15 +318,16 @@ static int qcom_smp2p_inbound_entry(strustatic int smp2p_update_bits (void *data,u32 mask,u32 value) {struct smp2p_entry *entry = data; +unsigned long flags;u32 orig;u32 val; -spin_lock (&entry->lock); +spin_lock_irqsave (&entry->lock, flags); val = orig =readl (entry->value); val &= ~mask; val |= value;writel (val, entry->value); -spin_unlock (&entry->lock); +spin_unlock_irqrestore (&entry->lock, flags);if (val != orig)qcom_smp2p_kick (entry->smp2p);
Greg Kroah-Hartman
maintainerPATCH 418/453 mtd: spinand: Fix OOB read
In reply to Greg Kroah-HartmanFrom: Miquel Raynal <[email protected]>
commit 868cbe2a6dcee451bd8f87cbbb2a73cf463b57e5 upstream.
So far OOB have never been used in SPI-NAND, add the missing memcpy to make it work properly.
--- drivers/mtd/nand/spi/core.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/mtd/nand/spi/core.c +4 -0
@@ -317,6 +317,10 @@ static int spinand_write_to_cache_op(str buf += ret; } +if (req->ooblen) +memcpy (req->oobbuf.in, spinand->oobbuf + req->ooboffs, + req->ooblen); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 419/453 mtd: parser: cmdline: Fix parsing of part-names with colons
In reply to Greg Kroah-HartmanFrom: Sven Eckelmann <[email protected]>
commit 639a82434f16a6df0ce0e7c8595976f1293940fd upstream.
Some devices (especially QCA ones) are already using hardcoded partition names with colons in it. The OpenMesh A62 for example provides following mtd relevant information via cmdline:
root=31:11 mtdparts=spi0.0:256k(0:SBL1),128k(0:MIBIB),384k(0:QSEE),64k(0:CDT),64k(0:DDRPARAMS),64k(0:APPSBLENV),512k(0:APPSBL),64k(0:ART),64k(custom),64k(0:KEYS),0x002b0000(kernel),0x00c80000(rootfs),15552k(inactive) rootfsname=rootfs rootwait
The change to split only on the last colon between mtd-id and partitions will cause newpart to see following string for the first partition:
KEYS),0x002b0000(kernel),0x00c80000(rootfs),15552k(inactive)
Such a partition list cannot be parsed and thus the device fails to boot.
Avoid this behavior by making sure that the start of the first part-name ("(") will also be the last byte the mtd-id split algorithm is using for its colon search.
--- drivers/mtd/parsers/cmdlinepart.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/mtd/parsers/cmdlinepart.c +13 -1
@@ -218,7 +218,7 @@ static int mtdpart_setup_real(char *s)struct cmdline_mtd_partition *this_mtd;struct mtd_partition *parts;int mtd_id_len, num_parts; -char *p, *mtd_id, *semicol; +char *p, *mtd_id, *semicol, *open_parenth;/* * Replace the first ';' by a NULL char so strrchr can work
@@ -228,6 +228,14 @@ static int mtdpart_setup_real(char *s)if (semicol) *semicol ='\0' ; +/* +* make sure that part-names with ":" will not be handled as +* part of the mtd-id with an ":" +*/ + open_parenth =strchr (s,'(' ); +if (open_parenth) + *open_parenth ='\0' ; + mtd_id = s;/*
@@ -237,6 +245,10 @@ static int mtdpart_setup_real(char *s)*/ p =strrchr (s,':' ); +/* Restore the '(' now. */ +if (open_parenth) + *open_parenth ='(' ; +/* Restore the ';' now. */ if (semicol) *semicol =';' ;
Greg Kroah-Hartman
maintainerPATCH 420/453 mtd: rawnand: qcom: Fix DMA sync on FLASH_STATUS register read
In reply to Greg Kroah-HartmanFrom: Praveenkumar I <[email protected]>
commit bc3686021122de953858a5be4cbf6e3f1d821e79 upstream.
After each codeword NAND_FLASH_STATUS is read for possible operational failures. But there is no DMA sync for CPU operation before reading it and this leads to incorrect or older copy of DMA buffer in reg_read_buf.
This patch adds the DMA sync on reg_read_buf for CPU before reading it.
--- drivers/mtd/nand/raw/qcom_nandc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mtd/nand/raw/qcom_nandc.c +2 -0
@@ -1570,6 +1570,8 @@ static int check_flash_errors(struct qcostruct qcom_nand_controller *nandc =get_qcom_nand_controller (chip);int i; +nandc_read_buffer_sync (nandc, true); +for (i =0 ; i < cw_cnt; i++) {u32 flash =le32_to_cpu (nandc->reg_read_buf[i]);
Greg Kroah-Hartman
maintainerPATCH 421/453 mtd: rawnand: meson: fix meson_nfc_dma_buffer_release() arguments
In reply to Greg Kroah-HartmanFrom: Sergei Antonov <[email protected]>
commit c13d845e9a69580424d40b7b101c37d4f71bcd63 upstream.
Arguments 'infolen' and 'datalen' to meson_nfc_dma_buffer_release() were mixed up.
--- drivers/mtd/nand/raw/meson_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/nand/raw/meson_nand.c +1 -1
@@ -510,7 +510,7 @@ static int meson_nfc_dma_buffer_setup(st }static void meson_nfc_dma_buffer_release (struct nand_chip *nand, -int infolen,int datalen, +int datalen,int infolen,enum dma_data_direction dir) {struct meson_nfc *nfc =nand_get_controller_data (nand);
Greg Kroah-Hartman
maintainerPATCH 422/453 scsi: qla2xxx: Fix crash during driver load on big endian machines
In reply to Greg Kroah-HartmanFrom: Arun Easi <[email protected]>
commit 8de309e7299a00b3045fb274f82b326f356404f0 upstream.
Crash stack:
[576544.715489] Unable to handle kernel paging request for data at address 0xd00000000f970000 [576544.715497] Faulting instruction address: 0xd00000000f880f64 [576544.715503] Oops: Kernel access of bad area, sig: 11 [#1] [576544.715506] SMP NR_CPUS=2048 NUMA pSeries : [576544.715703] NIP [d00000000f880f64] .qla27xx_fwdt_template_valid+0x94/0x100 [qla2xxx] [576544.715722] LR [d00000000f7952dc] .qla24xx_load_risc_flash+0x2fc/0x590 [qla2xxx] [576544.715726] Call Trace: [576544.715731] [c0000004d0ffb000] [c0000006fe02c350] 0xc0000006fe02c350 (unreliable) [576544.715750] [c0000004d0ffb080] [d00000000f7952dc] .qla24xx_load_risc_flash+0x2fc/0x590 [qla2xxx] [576544.715770] [c0000004d0ffb170] [d00000000f7aa034] .qla81xx_load_risc+0x84/0x1a0 [qla2xxx] [576544.715789] [c0000004d0ffb210] [d00000000f79f7c8] .qla2x00_setup_chip+0xc8/0x910 [qla2xxx] [576544.715808] [c0000004d0ffb300] [d00000000f7a631c] .qla2x00_initialize_adapter+0x4dc/0xb00 [qla2xxx] [576544.715826] [c0000004d0ffb3e0] [d00000000f78ce28] .qla2x00_probe_one+0xf08/0x2200 [qla2xxx]
--- drivers/scsi/qla2xxx/qla_tmpl.c | 9 +++++---- drivers/scsi/qla2xxx/qla_tmpl.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-)
drivers/scsi/qla2xxx/qla_tmpl.c +5 -4
@@ -910,7 +910,8 @@ qla27xx_template_checksum(void *p, ulongstatic inline int qla27xx_verify_template_checksum (struct qla27xx_fwdt_template *tmp) { -return qla27xx_template_checksum (tmp, tmp->template_size) ==0 ; +return qla27xx_template_checksum (tmp, +le32_to_cpu (tmp->template_size)) ==0 ; } static inline int
@@ -926,7 +927,7 @@ qla27xx_execute_fwdt_template(struct scsulong len =0 ;if (qla27xx_fwdt_template_valid (tmp)) { - len = tmp->template_size; + len =le32_to_cpu (tmp->template_size); tmp =memcpy (buf, tmp, len);ql27xx_edit_template (vha, tmp);qla27xx_walk_template (vha, tmp, buf, &len);
@@ -942,7 +943,7 @@ qla27xx_fwdt_calculate_dump_size(structulong len =0 ;if (qla27xx_fwdt_template_valid (tmp)) { - len = tmp->template_size; + len =le32_to_cpu (tmp->template_size);qla27xx_walk_template (vha, tmp,NULL , &len); }
@@ -954,7 +955,7 @@ qla27xx_fwdt_template_size(void *p) {struct qla27xx_fwdt_template *tmp = p; -return tmp->template_size; +return le32_to_cpu (tmp->template_size); }int
drivers/scsi/qla2xxx/qla_tmpl.h +1 -1
@@ -13,7 +13,7 @@struct __packed qla27xx_fwdt_template {__le32 template_type;__le32 entry_offset; -uint32_t template_size; +__le32 template_size;uint32_t count;/* borrow field for running/residual count */ __le32 entry_count;
Greg Kroah-Hartman
maintainerPATCH 423/453 scsi: lpfc: Fix invalid sleeping context in lpfc_sli4_nvmet_alloc()
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
commit 62e3a931db60daf94fdb3159d685a5bc6ad4d0cf upstream.
The following calltrace was seen:
BUG: sleeping function called from invalid context at mm/slab.h:494 ... Call Trace: dump_stack+0x9a/0xf0 ___might_sleep.cold.63+0x13d/0x178 slab_pre_alloc_hook+0x6a/0x90 kmem_cache_alloc_trace+0x3a/0x2d0 lpfc_sli4_nvmet_alloc+0x4c/0x280 [lpfc] lpfc_post_rq_buffer+0x2e7/0xa60 [lpfc] lpfc_sli4_hba_setup+0x6b4c/0xa4b0 [lpfc] lpfc_pci_probe_one_s4.isra.15+0x14f8/0x2280 [lpfc] lpfc_pci_probe_one+0x260/0x2880 [lpfc] local_pci_probe+0xd4/0x180 work_for_cpu_fn+0x51/0xa0 process_one_work+0x8f0/0x17b0 worker_thread+0x536/0xb50 kthread+0x30c/0x3d0 ret_from_fork+0x3a/0x50
A prior patch introduced a spin_lock_irqsave(hbalock) in the lpfc_post_rq_buffer() routine. Call trace is seen as the hbalock is held with interrupts disabled during a GFP_KERNEL allocation in lpfc_sli4_nvmet_alloc().
Fix by reordering locking so that hbalock not held when calling sli4_nvmet_alloc() (aka rqb_buf_list()).
--- drivers/scsi/lpfc/lpfc_mem.c | 4 +--- drivers/scsi/lpfc/lpfc_sli.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 5 deletions(-)
drivers/scsi/lpfc/lpfc_mem.c +1 -3
@@ -593,8 +593,6 @@ lpfc_sli4_rb_free(struct lpfc_hba *phba,* Description: Allocates a DMA-mapped receive buffer from the lpfc_hrb_pool PCI * pool along a non-DMA-mapped container for it. * -* Notes: Not interrupt-safe. Must be called with no locks held. -* * Returns: * pointer to HBQ on success * NULL on failure
@@ -604,7 +602,7 @@ lpfc_sli4_nvmet_alloc(struct lpfc_hba *p {struct rqb_dmabuf *dma_buf; - dma_buf =kzalloc (sizeof (struct rqb_dmabuf ),GFP_KERNEL ); + dma_buf =kzalloc (sizeof (*dma_buf),GFP_KERNEL );if (!dma_buf)return NULL ;
drivers/scsi/lpfc/lpfc_sli.c +8 -2
@@ -7102,12 +7102,16 @@ lpfc_post_rq_buffer(struct lpfc_hba *phbstruct rqb_dmabuf *rqb_buffer;LIST_HEAD (rqb_buf_list); -spin_lock_irqsave (&phba->hbalock, flags); rqbp = hrq->rqbp;for (i =0 ; i < count; i++) { +spin_lock_irqsave (&phba->hbalock, flags);/* IF RQ is already full, don't bother */ -if (rqbp->buffer_count + i >= rqbp->entry_count -1 ) +if (rqbp->buffer_count + i >= rqbp->entry_count -1 ) { +spin_unlock_irqrestore (&phba->hbalock, flags);break ; + } +spin_unlock_irqrestore (&phba->hbalock, flags); + rqb_buffer = rqbp->rqb_alloc_buffer (phba);if (!rqb_buffer)break ;
@@ -7116,6 +7120,8 @@ lpfc_post_rq_buffer(struct lpfc_hba *phb rqb_buffer->idx = idx;list_add_tail (&rqb_buffer->hbuf.list, &rqb_buf_list); } + +spin_lock_irqsave (&phba->hbalock, flags);while (!list_empty (&rqb_buf_list)) { list_remove_head(&rqb_buf_list, rqb_buffer, struct rqb_dmabuf, hbuf.list);
Greg Kroah-Hartman
maintainerPATCH 424/453 scsi: lpfc: Re-fix use after free in lpfc_rq_buf_free()
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
commit e5785d3ec32f5f44dd88cd7b398e496742630469 upstream.
Commit 9816ef6ecbc1 ("scsi: lpfc: Use after free in lpfc_rq_buf_free()") was made to correct a use after free condition in lpfc_rq_buf_free(). Unfortunately, a subsequent patch cut on a tree without the fix inadvertently reverted the fix.
Put the fix back: Move the freeing of the rqb_entry to after the print function that references it.
--- drivers/scsi/lpfc/lpfc_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_mem.c +1 -1
@@ -725,7 +725,6 @@ lpfc_rq_buf_free(struct lpfc_hba *phba, drqe.address_hi =putPaddrHigh (rqb_entry->dbuf.phys); rc =lpfc_sli4_rq_put (rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe);if (rc <0 ) { - (rqbp->rqb_free_buffer)(phba, rqb_entry); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "6409 Cannot post to HRQ %d: %x %x %x " "DRQ %x %x\n",
@@ -735,6 +734,7 @@ lpfc_rq_buf_free(struct lpfc_hba *phba, rqb_entry->hrq->entry_count, rqb_entry->drq->host_index, rqb_entry->drq->hba_index); + (rqbp->rqb_free_buffer)(phba, rqb_entry); }else {list_add_tail (&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list); rqbp->buffer_count++;
Greg Kroah-Hartman
maintainerPATCH 425/453 iio: buffer: Fix demux update
In reply to Greg Kroah-HartmanFrom: Nuno Sá <[email protected]>
commit 19ef7b70ca9487773c29b449adf0c70f540a0aab upstream.
When updating the buffer demux, we will skip a scan element from the device in the case in_ind != out_ind and we enter the while loop. in_ind should only be refreshed with find_next_bit() in the end of the loop.
Note, to cause problems we need a situation where we are skippig over an element (channel not enabled) that happens to not have the same size
as the next element. Whilst this is a possible situation we haven't
actually identified any cases in mainline where it happens as most drivers have consistent channel storage sizes with the exception of the timestamp which is the last element and hence never skipped over.
--- drivers/iio/industrialio-buffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iio/industrialio-buffer.c +3 -3
@@ -845,12 +845,12 @@ static int iio_buffer_update_demux(struc indio_dev->masklength, in_ind + 1);while (in_ind != out_ind) { - in_ind =find_next_bit (indio_dev->active_scan_mask, - indio_dev->masklength, - in_ind +1 ); length =iio_storage_bytes_for_si (indio_dev, in_ind);/* Make sure we are aligned */ in_loc =roundup (in_loc, length) + length; + in_ind =find_next_bit (indio_dev->active_scan_mask, + indio_dev->masklength, + in_ind +1 ); } length =iio_storage_bytes_for_si (indio_dev, in_ind); out_loc =roundup (out_loc, length);
Greg Kroah-Hartman
maintainerPATCH 426/453 iio: adc: rockchip_saradc: fix missing clk_disable_unprepare() on error in rockchip_saradc_resume
In reply to Greg Kroah-HartmanFrom: Qinglang Miao <[email protected]>
commit 560c6b914c6ec7d9d9a69fddbb5bf3bf71433e8b upstream.
Fix the missing clk_disable_unprepare() of info->pclk before return from rockchip_saradc_resume in the error handling case when fails to prepare and enable info->clk.
--- drivers/iio/adc/rockchip_saradc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/rockchip_saradc.c +1 -1
@@ -372,7 +372,7 @@ static int rockchip_saradc_resume(struct ret =clk_prepare_enable (info->clk);if (ret) -return ret; +clk_disable_unprepare (info->pclk);return ret; }
Greg Kroah-Hartman
maintainerPATCH 427/453 iio:light:rpr0521: Fix timestamp alignment and prevent data leak.
In reply to Greg Kroah-HartmanFrom: Jonathan Cameron <[email protected]>
commit a61817216bcc755eabbcb1cf281d84ccad267ed1 upstream.
One of a class of bugs pointed out by Lars in a recent review. iio_push_to_buffers_with_timestamp() assumes the buffer used is aligned to the size of the timestamp (8 bytes). This is not guaranteed in this driver which uses an array of smaller elements on the stack. As Lars also noted this anti pattern can involve a leak of data to userspace and that indeed can happen here. We close both issues by moving to a suitable structure in the iio_priv().
This data is allocated with kzalloc() so no data can leak apart from previous readings and in this case the status byte from the device.
The forced alignment of ts is not necessary in this case but it potentially makes the code less fragile.
Quoted 1 line
From personal communications with Mikko:
We could probably split the reading of the int register, but it would mean a significant performance cost of 20 i2c clock cycles.
--- drivers/iio/light/rpr0521.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/iio/light/rpr0521.c +13 -4
@@ -194,6 +194,17 @@ struct rpr0521_data {bool pxs_need_dis;struct regmap *regmap; + +/* +* Ensure correct naturally aligned timestamp. +* Note that the read will put garbage data into +* the padding but this should not be a problem +*/ +struct { +__le16 channels[3 ]; +u8 garbage; +s64 ts__aligned(8) ; + } scan; }; static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
@@ -449,8 +460,6 @@ static irqreturn_t rpr0521_trigger_consustruct rpr0521_data *data =iio_priv (indio_dev);int err; -u8 buffer[16 ];/* 3 16-bit channels + padding + ts */ -/* Use irq timestamp when reasonable. */ if (iio_trigger_using_own (indio_dev) && data->irq_timestamp) { pf->timestamp = data->irq_timestamp;
@@ -461,11 +470,11 @@ static irqreturn_t rpr0521_trigger_consu pf->timestamp =iio_get_time_ns (indio_dev); err =regmap_bulk_read (data->regmap,RPR0521_REG_PXS_DATA , - &buffer, + data->scan.channels, (3 *2 ) +1 );/* 3 * 16-bit + (discarded) int clear reg. */ if (!err)iio_push_to_buffers_with_timestamp (indio_dev, - buffer, pf->timestamp); + &data->scan, pf->timestamp);else dev_err (&data->client->dev,"Trigger consumer can't read from sensor.\n" );
Greg Kroah-Hartman
maintainerPATCH 428/453 iio:light:st_uvis25: Fix timestamp alignment and prevent data leak.
In reply to Greg Kroah-HartmanFrom: Jonathan Cameron <[email protected]>
commit d837a996f57c29a985177bc03b0e599082047f27 upstream.
One of a class of bugs pointed out by Lars in a recent review. iio_push_to_buffers_with_timestamp() assumes the buffer used is aligned to the size of the timestamp (8 bytes). This is not guaranteed in this driver which uses an array of smaller elements on the stack. As Lars also noted this anti pattern can involve a leak of data to userspace and that indeed can happen here. We close both issues by moving to a suitable structure in the iio_priv()
This data is allocated with kzalloc() so no data can leak apart from previous readings.
A local unsigned int variable is used for the regmap call so it is clear there is no potential issue with writing into the padding of the structure.
--- drivers/iio/light/st_uvis25.h | 5 +++++ drivers/iio/light/st_uvis25_core.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-)
drivers/iio/light/st_uvis25.h +5 -0
@@ -27,6 +27,11 @@ struct st_uvis25_hw {struct iio_trigger *trig;bool enabled;int irq; +/* Ensure timestamp is naturally aligned */ +struct { +u8 chan; +s64 ts__aligned(8) ; + } scan; };extern const struct dev_pm_ops st_uvis25_pm_ops;
drivers/iio/light/st_uvis25_core.c +5 -3
@@ -234,17 +234,19 @@ static const struct iio_buffer_setup_opsstatic irqreturn_t st_uvis25_buffer_handler_thread (int irq,void *p) { -u8 buffer[ALIGN (sizeof (u8),sizeof (s64)) +sizeof (s64)];struct iio_poll_func *pf = p;struct iio_dev *iio_dev = pf->indio_dev;struct st_uvis25_hw *hw =iio_priv (iio_dev); +unsigned int val;int err; - err =regmap_read (hw->regmap,ST_UVIS25_REG_OUT_ADDR , (int *)buffer); + err =regmap_read (hw->regmap,ST_UVIS25_REG_OUT_ADDR , &val);if (err <0 ) goto out; -iio_push_to_buffers_with_timestamp (iio_dev, buffer, + hw->scan.chan = val; + +iio_push_to_buffers_with_timestamp (iio_dev, &hw->scan,iio_get_time_ns (iio_dev)); out:
Greg Kroah-Hartman
maintainerPATCH 429/453 iio:magnetometer:mag3110: Fix alignment and data leak issues.
In reply to Greg Kroah-HartmanFrom: Jonathan Cameron <[email protected]>
commit 89deb1334252ea4a8491d47654811e28b0790364 upstream.
One of a class of bugs pointed out by Lars in a recent review. iio_push_to_buffers_with_timestamp() assumes the buffer used is aligned to the size of the timestamp (8 bytes). This is not guaranteed in this driver which uses an array of smaller elements on the stack. As Lars also noted this anti pattern can involve a leak of data to userspace and that indeed can happen here. We close both issues by moving to a suitable structure in the iio_priv() data.
This data is allocated with kzalloc() so no data can leak apart from previous readings.
The explicit alignment of ts is not necessary in this case but does make the code slightly less fragile so I have included it.
--- drivers/iio/magnetometer/mag3110.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/iio/magnetometer/mag3110.c +9 -4
@@ -56,6 +56,12 @@ struct mag3110_data {int sleep_val;struct regulator *vdd_reg;struct regulator *vddio_reg; +/* Ensure natural alignment of timestamp */ +struct { +__be16 channels[3 ]; +u8 temperature; +s64 ts__aligned(8) ; + } scan; };static int mag3110_request (struct mag3110_data *data)
@@ -387,10 +393,9 @@ static irqreturn_t mag3110_trigger_handlstruct iio_poll_func *pf = p;struct iio_dev *indio_dev = pf->indio_dev;struct mag3110_data *data =iio_priv (indio_dev); -u8 buffer[16 ];/* 3 16-bit channels + 1 byte temp + padding + ts */ int ret; - ret =mag3110_read (data, (__be16 *) buffer); + ret =mag3110_read (data, data->scan.channels);if (ret <0 ) goto done;
@@ -399,10 +404,10 @@ static irqreturn_t mag3110_trigger_handl MAG3110_DIE_TEMP);if (ret <0 ) goto done; - buffer[6 ] = ret; + data->scan.temperature = ret; } -iio_push_to_buffers_with_timestamp (indio_dev, buffer, +iio_push_to_buffers_with_timestamp (indio_dev, &data->scan,iio_get_time_ns (indio_dev)); done:
Greg Kroah-Hartman
maintainerPATCH 430/453 iio:pressure:mpl3115: Force alignment of buffer
In reply to Greg Kroah-HartmanFrom: Jonathan Cameron <[email protected]>
commit 198cf32f0503d2ad60d320b95ef6fb8243db857f upstream.
Whilst this is another case of the issue Lars reported with an array of elements of smaller than 8 bytes being passed to iio_push_to_buffers_with_timestamp(), the solution here is a bit different from the other cases and relies on __aligned working on the stack (true since 4.6?)
This one is unusual. We have to do an explicit memset() each time as we are reading 3 bytes into a potential 4 byte channel which may sometimes be a 2 byte channel depending on what is enabled. As such, moving the buffer to the heap in the iio_priv structure doesn't save us much. We can't use a nice explicit structure on the stack either as the data channels have different storage sizes and are all separately controlled.
--- drivers/iio/pressure/mpl3115.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/iio/pressure/mpl3115.c +8 -1
@@ -144,7 +144,14 @@ static irqreturn_t mpl3115_trigger_handlstruct iio_poll_func *pf = p;struct iio_dev *indio_dev = pf->indio_dev;struct mpl3115_data *data =iio_priv (indio_dev); -u8 buffer[16 ];/* 32-bit channel + 16-bit channel + padding + ts */ +/* +* 32-bit channel + 16-bit channel + padding + ts +* Note that it is possible for only one of the first 2 +* channels to be enabled. If that happens, the first element +* of the buffer may be either 16 or 32-bits. As such we cannot +* use a simple structure definition to express this data layout. +*/ +u8 buffer[16 ]__aligned(8) ;int ret, pos =0 ;mutex_lock (&data->lock);
Greg Kroah-Hartman
maintainerPATCH 431/453 iio:imu:bmi160: Fix too large a buffer.
In reply to Greg Kroah-HartmanFrom: Jonathan Cameron <[email protected]>
commit dc7de42d6b50a07b37feeba4c6b5136290fcee81 upstream.
The comment implies this device has 3 sensor types, but it only has an accelerometer and a gyroscope (both 3D). As such the buffer does not need to be as long as stated.
Note I've separated this from the following patch which fixes the alignment for passing to iio_push_to_buffers_with_timestamp() as they are different issues even if they affect the same line of code.
--- drivers/iio/imu/bmi160/bmi160_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/imu/bmi160/bmi160_core.c +2 -2
@@ -411,8 +411,8 @@ static irqreturn_t bmi160_trigger_handlestruct iio_poll_func *pf = p;struct iio_dev *indio_dev = pf->indio_dev;struct bmi160_data *data =iio_priv (indio_dev); -__le16 buf[16 ]; -/* 3 sens x 3 axis x __le16 + 3 x __le16 pad + 4 x __le16 tstamp */ +__le16 buf[12 ]; +/* 2 sens x 3 axis x __le16 + 2 x __le16 pad + 4 x __le16 tstamp */ int i, ret, j =0 , base =BMI160_REG_DATA_MAGN_XOUT_L ;__le16 sample;
Greg Kroah-Hartman
maintainerPATCH 432/453 iio:adc:ti-ads124s08: Fix buffer being too long.
In reply to Greg Kroah-HartmanFrom: Jonathan Cameron <[email protected]>
commit b0bd27f02d768e3a861c4e6c27f8e369720e6c25 upstream.
The buffer is expressed as a u32 array, yet the extra space for the s64 timestamp was expressed as sizeof(s64)/sizeof(u16). This will result in 2 extra u32 elements.
Fix by dividing by sizeof(u32).
--- drivers/iio/adc/ti-ads124s08.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ti-ads124s08.c +1 -1
@@ -270,7 +270,7 @@ static irqreturn_t ads124s_trigger_handlstruct iio_poll_func *pf = p;struct iio_dev *indio_dev = pf->indio_dev;struct ads124s_private *priv =iio_priv (indio_dev); -u32 buffer[ADS124S08_MAX_CHANNELS +sizeof (s64)/sizeof (u16)]; +u32 buffer[ADS124S08_MAX_CHANNELS +sizeof (s64)/sizeof (u32)];int scan_index, j =0 ;int ret;
Greg Kroah-Hartman
maintainerPATCH 433/453 iio:adc:ti-ads124s08: Fix alignment and data leak issues.
In reply to Greg Kroah-HartmanFrom: Jonathan Cameron <[email protected]>
commit 1e405bc2512f80a903ddd6ba8740cee885238d7f upstream.
One of a class of bugs pointed out by Lars in a recent review. iio_push_to_buffers_with_timestamp() assumes the buffer used is aligned to the size of the timestamp (8 bytes). This is not guaranteed in this driver which uses an array of smaller elements on the stack. As Lars also noted this anti pattern can involve a leak of data to userspace and that indeed can happen here. We close both issues by moving to a suitable structure in the iio_priv() data with alignment explicitly requested. This data is allocated with kzalloc() so no data can leak apart from previous readings.
In this driver the timestamp can end up in various different locations depending on what other channels are enabled. As a result, we don't use a structure to specify it's position as that would be misleading.
--- drivers/iio/adc/ti-ads124s08.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/iio/adc/ti-ads124s08.c +10 -3
@@ -97,6 +97,14 @@ struct ads124s_private {struct gpio_desc *reset_gpio;struct spi_device *spi;struct mutex lock; +/* +* Used to correctly align data. +* Ensure timestamp is naturally aligned. +* Note that the full buffer length may not be needed if not +* all channels are enabled, as long as the alignment of the +* timestamp is maintained. +*/ +u32 buffer[ADS124S08_MAX_CHANNELS +sizeof (s64)/sizeof (u32)]__aligned(8) ;u8 data[5 ]____cacheline_aligned ; };
@@ -270,7 +278,6 @@ static irqreturn_t ads124s_trigger_handlstruct iio_poll_func *pf = p;struct iio_dev *indio_dev = pf->indio_dev;struct ads124s_private *priv =iio_priv (indio_dev); -u32 buffer[ADS124S08_MAX_CHANNELS +sizeof (s64)/sizeof (u32)];int scan_index, j =0 ;int ret;
@@ -285,7 +292,7 @@ static irqreturn_t ads124s_trigger_handlif (ret)dev_err (&priv->spi->dev,"Start ADC conversions failed\n" ); - buffer[j] =ads124s_read (indio_dev, scan_index); + priv->buffer[j] =ads124s_read (indio_dev, scan_index); ret =ads124s_write_cmd (indio_dev,ADS124S08_STOP_CONV );if (ret)dev_err (&priv->spi->dev,"Stop ADC conversions failed\n" );
@@ -293,7 +300,7 @@ static irqreturn_t ads124s_trigger_handl j++; } -iio_push_to_buffers_with_timestamp (indio_dev, buffer, +iio_push_to_buffers_with_timestamp (indio_dev, priv->buffer, pf->timestamp);iio_trigger_notify_done (indio_dev->trig);
Greg Kroah-Hartman
maintainerPATCH 434/453 md/cluster: block reshape with remote resync job
In reply to Greg Kroah-HartmanFrom: Zhao Heming <[email protected]>
commit a8da01f79c89755fad55ed0ea96e8d2103242a72 upstream.
Reshape request should be blocked with ongoing resync job. In cluster env, a node can start resync job even if the resync cmd isn't executed on it, e.g., user executes "mdadm --grow" on node A, sometimes node B will start resync job. However, current update_raid_disks() only check local recovery status, which is incomplete. As a result, we see user will execute "mdadm --grow" successfully on local, while the remote node deny to do reshape job when it doing resync job. The inconsistent handling cause array enter unexpected status. If user doesn't observe this issue and continue executing mdadm cmd, the array doesn't work at last.
Fix this issue by blocking reshape request. When node executes "--grow" and detects ongoing resync, it should stop and report error to user.
The following script reproduces the issue with ~100% probability. (two nodes share 3 iSCSI luns: sdg/sdh/sdi. Each lun size is 1GB)
```
# on node1, node2 is the remote node.
ssh root@node2 "mdadm -S --scan"
mdadm -S --scan
for i in {g,h,i};do dd if=/dev/zero of=/dev/sd$i oflag=direct bs=1M \
count=20; done
mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sdg /dev/sdh
ssh root@node2 "mdadm -A /dev/md0 /dev/sdg /dev/sdh"
sleep 5
mdadm --manage --add /dev/md0 /dev/sdi
mdadm --wait /dev/md0
mdadm --grow --raid-devices=3 /dev/md0
mdadm /dev/md0 --fail /dev/sdg
mdadm /dev/md0 --remove /dev/sdg
mdadm --grow --raid-devices=2 /dev/md0
```--- drivers/md/md.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/md/md.c +6 -2
@@ -7052,6 +7052,7 @@ static int update_raid_disks(struct mddereturn -EINVAL ;if (mddev->sync_thread ||test_bit (MD_RECOVERY_RUNNING , &mddev->recovery) || +test_bit (MD_RESYNCING_REMOTE , &mddev->recovery) || mddev->reshape_position != MaxSector)return -EBUSY ;
@@ -9423,8 +9424,11 @@ static void check_sb_changes(struct mdde } } -if (mddev->raid_disks !=le32_to_cpu (sb->raid_disks)) -update_raid_disks (mddev,le32_to_cpu (sb->raid_disks)); +if (mddev->raid_disks !=le32_to_cpu (sb->raid_disks)) { + ret =update_raid_disks (mddev,le32_to_cpu (sb->raid_disks)); +if (ret) +pr_warn ("md: updating array disks failed. %d\n" , ret); + }/* * Since mddev->delta_disks has already updated in update_raid_disks,
Greg Kroah-Hartman
maintainerPATCH 435/453 md/cluster: fix deadlock when node is doing resync job
In reply to Greg Kroah-HartmanFrom: Zhao Heming <[email protected]>
commit bca5b0658020be90b6b504ca514fd80110204f71 upstream.
md-cluster uses MD_CLUSTER_SEND_LOCK to make node can exclusively send msg. During sending msg, node can concurrently receive msg from another node. When node does resync job, grab token_lockres:EX may trigger a deadlock:
```
nodeA nodeB
-------------------- --------------------
a.
send METADATA_UPDATED
held token_lockres:EX
b.
md_do_sync
resync_info_update
send RESYNCING
+ set MD_CLUSTER_SEND_LOCK
+ wait for holding token_lockres:EX
c.
mdadm /dev/md0 --remove /dev/sdg
+ held reconfig_mutex
+ send REMOVE
+ wait_event(MD_CLUSTER_SEND_LOCK)
d.
recv_daemon //METADATA_UPDATED from A
process_metadata_update
+ (mddev_trylock(mddev) ||
MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD)
//this time, both return false forever
```Explaination:
a. A send METADATA_UPDATED
This will block another node to send msg
b. B does sync jobs, which will send RESYNCING at intervals.
This will be block for holding token_lockres:EX lock.
c. B do "mdadm --remove", which will send REMOVE.
This will be blocked by step <b>: MD_CLUSTER_SEND_LOCK is 1.
d. B recv METADATA_UPDATED msg, which send from A in step <a>.
This will be blocked by step <c>: holding mddev lock, it makes wait_event can't hold mddev lock. (btw, MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD keep ZERO in this scenario.)
There is a similar deadlock in commit 0ba959774e93 ("md-cluster: use sync way to handle METADATA_UPDATED msg") In that commit, step c is "update sb". This patch step c is "mdadm --remove".
For fixing this issue, we can refer the solution of function:metadata_update_start. Which does the same grab lock_token action. lock_comm can use the same steps to avoid deadlock. By moving MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD from lock_token to lock_comm. It enlarge a little bit window of MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, but it is safe & can break deadlock.
Repro steps (I only triggered 3 times with hundreds tests):
two nodes share 3 iSCSI luns: sdg/sdh/sdi. Each lun size is 1GB.
```
ssh root@node2 "mdadm -S --scan"
mdadm -S --scan
for i in {g,h,i};do dd if=/dev/zero of=/dev/sd$i oflag=direct bs=1M \
count=20; done
mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sdg /dev/sdh \
--bitmap-chunk=1M
ssh root@node2 "mdadm -A /dev/md0 /dev/sdg /dev/sdh"
sleep 5
mkfs.xfs /dev/md0
mdadm --manage --add /dev/md0 /dev/sdi
mdadm --wait /dev/md0
mdadm --grow --raid-devices=3 /dev/md0
mdadm /dev/md0 --fail /dev/sdg
mdadm /dev/md0 --remove /dev/sdg
mdadm --grow --raid-devices=2 /dev/md0
```test script will hung when executing "mdadm --remove".
``` # dump stacks by "echo t > /proc/sysrq-trigger" md0_cluster_rec D 0 5329 2 0x80004000 Call Trace: __schedule+0x1f6/0x560 ? _cond_resched+0x2d/0x40 ? schedule+0x4a/0xb0 ? process_metadata_update.isra.0+0xdb/0x140 [md_cluster] ? wait_woken+0x80/0x80 ? process_recvd_msg+0x113/0x1d0 [md_cluster] ? recv_daemon+0x9e/0x120 [md_cluster] ? md_thread+0x94/0x160 [md_mod] ? wait_woken+0x80/0x80 ? md_congested+0x30/0x30 [md_mod] ? kthread+0x115/0x140 ? __kthread_bind_mask+0x60/0x60 ? ret_from_fork+0x1f/0x40 mdadm D 0 5423 1 0x00004004 Call Trace: __schedule+0x1f6/0x560 ? __schedule+0x1fe/0x560 ? schedule+0x4a/0xb0 ? lock_comm.isra.0+0x7b/0xb0 [md_cluster] ? wait_woken+0x80/0x80 ? remove_disk+0x4f/0x90 [md_cluster] ? hot_remove_disk+0xb1/0x1b0 [md_mod] ? md_ioctl+0x50c/0xba0 [md_mod] ? wait_woken+0x80/0x80 ? blkdev_ioctl+0xa2/0x2a0 ? block_ioctl+0x39/0x40 ? ksys_ioctl+0x82/0xc0 ? __x64_sys_ioctl+0x16/0x20 ? do_syscall_64+0x5f/0x150 ? entry_SYSCALL_64_after_hwframe+0x44/0xa9 md0_resync D 0 5425 2 0x80004000 Call Trace: __schedule+0x1f6/0x560 ? schedule+0x4a/0xb0 ? dlm_lock_sync+0xa1/0xd0 [md_cluster] ? wait_woken+0x80/0x80 ? lock_token+0x2d/0x90 [md_cluster] ? resync_info_update+0x95/0x100 [md_cluster] ? raid1_sync_request+0x7d3/0xa40 [raid1] ? md_do_sync.cold+0x737/0xc8f [md_mod] ? md_thread+0x94/0x160 [md_mod] ? md_congested+0x30/0x30 [md_mod] ? kthread+0x115/0x140 ? __kthread_bind_mask+0x60/0x60 ? ret_from_fork+0x1f/0x40 ```
At last, thanks for Xiao's solution.
--- drivers/md/md-cluster.c | 67 +++++++++++++++++++++++++++--------------------- drivers/md/md.c | 6 ++-- 2 files changed, 42 insertions(+), 31 deletions(-)
drivers/md/md-cluster.c +38 -29
@@ -664,9 +664,27 @@ out:* Takes the lock on the TOKEN lock resource so no other * node can communicate while the operation is underway. */ -static int lock_token (struct md_cluster_info *cinfo,bool mddev_locked) +static int lock_token (struct md_cluster_info *cinfo) { -int error, set_bit =0 ; +int error; + + error =dlm_lock_sync (cinfo->token_lockres,DLM_LOCK_EX ); +if (error) { +pr_err ("md-cluster(%s:%d): failed to get EX on TOKEN (%d)\n" , + __func__, __LINE__, error); + }else { +/* Lock the receive sequence */ +mutex_lock (&cinfo->recv_mutex); + } +return error; +} + +/* lock_comm() +* Sets the MD_CLUSTER_SEND_LOCK bit to lock the send channel. +*/ +static int lock_comm (struct md_cluster_info *cinfo,bool mddev_locked) +{ +int rv, set_bit =0 ;struct mddev *mddev = cinfo->mddev;/*
@@ -677,34 +695,19 @@ static int lock_token(struct md_cluster_*/ if (mddev_locked && !test_bit (MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD , &cinfo->state)) { - error =test_and_set_bit_lock (MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD , + rv =test_and_set_bit_lock (MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD , &cinfo->state); -WARN_ON_ONCE (error); +WARN_ON_ONCE (rv);md_wakeup_thread (mddev->thread); set_bit =1 ; } - error =dlm_lock_sync (cinfo->token_lockres,DLM_LOCK_EX ); -if (set_bit) -clear_bit_unlock (MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD , &cinfo->state); -if (error) -pr_err ("md-cluster(%s:%d): failed to get EX on TOKEN (%d)\n" , - __func__, __LINE__, error); - -/* Lock the receive sequence */ -mutex_lock (&cinfo->recv_mutex); -return error; -} - -/* lock_comm() -* Sets the MD_CLUSTER_SEND_LOCK bit to lock the send channel. -*/ -static int lock_comm (struct md_cluster_info *cinfo,bool mddev_locked) -{wait_event (cinfo->wait, !test_and_set_bit (MD_CLUSTER_SEND_LOCK , &cinfo->state)); - -return lock_token (cinfo, mddev_locked); + rv =lock_token (cinfo); +if (set_bit) +clear_bit_unlock (MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD , &cinfo->state); +return rv; }static void unlock_comm (struct md_cluster_info *cinfo)
@@ -784,9 +787,11 @@ static int sendmsg(struct md_cluster_inf {int ret; -lock_comm (cinfo, mddev_locked); - ret =__sendmsg (cinfo, cmsg); -unlock_comm (cinfo); + ret =lock_comm (cinfo, mddev_locked); +if (!ret) { + ret =__sendmsg (cinfo, cmsg); +unlock_comm (cinfo); + }return ret; }
@@ -1061,7 +1066,7 @@ static int metadata_update_start(structreturn 0 ; } - ret =lock_token (cinfo,1 ); + ret =lock_token (cinfo);clear_bit_unlock (MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD , &cinfo->state);return ret; }
@@ -1255,7 +1260,10 @@ static void update_size(struct mddev *mdint raid_slot =-1 ;md_update_sb (mddev,1 ); -lock_comm (cinfo,1 ); +if (lock_comm (cinfo,1 )) { +pr_err ("%s: lock_comm failed\n" , __func__); +return ; + }memset (&cmsg,0 ,sizeof (cmsg)); cmsg.type =cpu_to_le32 (METADATA_UPDATED );
@@ -1407,7 +1415,8 @@ static int add_new_disk(struct mddev *md cmsg.type =cpu_to_le32 (NEWDISK );memcpy (cmsg.uuid, uuid,16 ); cmsg.raid_slot =cpu_to_le32 (rdev->desc_nr); -lock_comm (cinfo,1 ); +if (lock_comm (cinfo,1 )) +return -EAGAIN ; ret =__sendmsg (cinfo, &cmsg);if (ret) {unlock_comm (cinfo);
drivers/md/md.c +4 -2
@@ -6721,8 +6721,10 @@ static int hot_remove_disk(struct mddev goto busy; kick_rdev: -if (mddev_is_clustered (mddev)) - md_cluster_ops->remove_disk (mddev, rdev); +if (mddev_is_clustered (mddev)) { +if (md_cluster_ops->remove_disk (mddev, rdev)) + goto busy; + }md_kick_rdev_from_array (rdev);set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags);
Greg Kroah-Hartman
maintainerPATCH 436/453 pinctrl: sunxi: Always call chained_irq_{enter, exit} in sunxi_pinctrl_irq_handler
In reply to Greg Kroah-HartmanFrom: Yangtao Li <[email protected]>
commit a1158e36f876f6269978a4176e3a1d48d27fe7a1 upstream.
It is found on many allwinner soc that there is a low probability that the interrupt status cannot be read in sunxi_pinctrl_irq_handler. This will cause the interrupt status of a gpio bank to always be active on gic, preventing gic from responding to other spi interrupts correctly.
So we should call the chained_irq_* each time enter sunxi_pinctrl_irq_handler().
--- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/pinctrl/sunxi/pinctrl-sunxi.c +4 -2
@@ -1130,20 +1130,22 @@ static void sunxi_pinctrl_irq_handler(stif (bank == pctl->desc->irq_banks)return ; +chained_irq_enter (chip, desc); + reg =sunxi_irq_status_reg_from_bank (pctl->desc, bank); val =readl (pctl->membase + reg);if (val) {int irqoffset; -chained_irq_enter (chip, desc);for_each_set_bit (irqoffset, &val,IRQ_PER_BANK ) {int pin_irq =irq_find_mapping (pctl->domain, bank *IRQ_PER_BANK + irqoffset);generic_handle_irq (pin_irq); } -chained_irq_exit (chip, desc); } + +chained_irq_exit (chip, desc); } static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl,
Greg Kroah-Hartman
maintainerPATCH 437/453 clk: ingenic: Fix divider calculation with div tables
In reply to Greg Kroah-HartmanFrom: Paul Cercueil <[email protected]>
commit 11a163f2c7d6a9f27ce144cd7e367a81c851621a upstream.
The previous code assumed that a higher hardware value always resulted in a bigger divider, which is correct for the regular clocks, but is an invalid assumption when a divider table is provided for the clock.
Perfect example of this is the PLL0_HALF clock, which applies a /2 divider with the hardware value 0, and a /1 divider otherwise.
--- drivers/clk/ingenic/cgu.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/clk/ingenic/cgu.c +10 -4
@@ -393,15 +393,21 @@ static unsigned int ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info, unsigned int div) { - unsigned int i; + unsigned int i, best_i = 0, best = (unsigned int)-1;for (i =0 ; i < (1 << clk_info->div.bits) && clk_info->div.div_table[i]; i++) { -if (clk_info->div.div_table[i] >= div) -return i; +if (clk_info->div.div_table[i] >= div && + clk_info->div.div_table[i] < best) { + best = clk_info->div.div_table[i]; + best_i = i; + +if (div == best) +break ; + } } -return i -1 ; +return best_i; } static unsigned
Greg Kroah-Hartman
maintainerPATCH 438/453 clk: mvebu: a3700: fix the XTAL MODE pin to MPP1_9
In reply to Greg Kroah-HartmanFrom: Terry Zhou <[email protected]>
commit 6f37689cf6b38fff96de52e7f0d3e78f22803ba0 upstream.
There is an error in the current code that the XTAL MODE pin was set to NB MPP1_31 which should be NB MPP1_9. The latch register of NB MPP1_9 has different offset of 0x8.
--- drivers/clk/mvebu/armada-37xx-xtal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/mvebu/armada-37xx-xtal.c +2 -2
@@ -13,8 +13,8 @@#include <linux/platform_device.h> #include <linux/regmap.h> -#define NB_GPIO1_LATCH 0xC -#define XTAL_MODE BIT(31) +#define NB_GPIO1_LATCH 0x8 +#define XTAL_MODE BIT(9)static int armada_3700_xtal_clock_probe (struct platform_device *pdev) {
Greg Kroah-Hartman
maintainerPATCH 439/453 clk: tegra: Do not return 0 on failure
In reply to Greg Kroah-HartmanFrom: Nicolin Chen <[email protected]>
commit 6160aca443148416994c022a35c77daeba948ea6 upstream.
Return values from read_dt_param() will be either TRUE (1) or FALSE (0), while dfll_fetch_pwm_params() returns 0 on success or an ERR code on failure.
So this patch fixes the bug of returning 0 on failure.
--- drivers/clk/tegra/clk-dfll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/tegra/clk-dfll.c +2 -2
@@ -1801,13 +1801,13 @@ static int dfll_fetch_pwm_params(struct &td->reg_init_uV);if (!ret) {dev_err (td->dev,"couldn't get initialized voltage\n" ); -return ret; +return -EINVAL ; } ret =read_dt_param (td,"nvidia,pwm-period-nanoseconds" , &pwm_period);if (!ret) {dev_err (td->dev,"couldn't get PWM period\n" ); -return ret; +return -EINVAL ; } td->pwm_rate = (NSEC_PER_SEC / pwm_period) * (MAX_DFLL_VOLTAGES -1 );
Greg Kroah-Hartman
maintainerPATCH 440/453 device-dax/core: Fix memory leak when rmmod dax.ko
In reply to Greg Kroah-HartmanFrom: Wang Hai <[email protected]>
commit 1aa574312518ef1d60d2dc62d58f7021db3b163a upstream.
When I repeatedly modprobe and rmmod dax.ko, kmemleak report a memory leak as follows:
unreferenced object 0xffff9a5588c05088 (size 8):
comm "modprobe", pid 261, jiffies 4294693644 (age 42.063s)
...
backtrace:
[<00000000e007ced0>] kstrdup+0x35/0x70
[<000000002ae73897>] kstrdup_const+0x3d/0x50
[<000000002b00c9c3>] kvasprintf_const+0xbc/0xf0
[<000000008023282f>] kobject_set_name_vargs+0x3b/0xd0
[<00000000d2cbaa4e>] kobject_set_name+0x62/0x90
[<00000000202e7a22>] bus_register+0x7f/0x2b0
[<000000000b77792c>] 0xffffffffc02840f7
[<000000002d5be5ac>] 0xffffffffc02840b4
[<00000000dcafb7cd>] do_one_initcall+0x58/0x240
[<00000000049fe480>] do_init_module+0x56/0x1e2
[<0000000022671491>] load_module+0x2517/0x2840
[<000000001a2201cb>] __do_sys_finit_module+0x9c/0xe0
[<000000003eb304e7>] do_syscall_64+0x33/0x40
[<0000000051c5fd06>] entry_SYSCALL_64_after_hwframe+0x44/0xa9When rmmod dax is executed, dax_bus_exit() is missing. This patch can fix this bug.
--- drivers/dax/super.c | 1 + 1 file changed, 1 insertion(+)
drivers/dax/super.c +1 -0
@@ -720,6 +720,7 @@ err_chrdev: static void __exit dax_core_exit(void) { +dax_bus_exit ();unregister_chrdev_region (dax_devt,MINORMASK +1 );ida_destroy (&dax_minor_ida);dax_fs_exit ();
Greg Kroah-Hartman
maintainerPATCH 441/453 dma-buf/dma-resv: Respect num_fences when initializing the shared fence list.
In reply to Greg Kroah-HartmanFrom: Maarten Lankhorst <[email protected]>
commit bf8975837dac156c33a4d15d46602700998cb6dd upstream.
We hardcode the maximum number of shared fences to 4, instead of respecting num_fences. Use a minimum of 4, but more if num_fences is higher.
This seems to have been an oversight when first implementing the api.
--- drivers/dma-buf/dma-resv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma-buf/dma-resv.c +1 -1
@@ -161,7 +161,7 @@ int dma_resv_reserve_shared(struct dma_r max =max (old->shared_count + num_fences, old->shared_max *2 ); }else { - max =4 ; + max =max (4ul ,roundup_pow_of_two (num_fences)); } new =dma_resv_list_alloc (max);
Greg Kroah-Hartman
maintainerPATCH 442/453 xen-blkback: set ring->xenblkd to NULL after kthread_stop()
In reply to Greg Kroah-HartmanFrom: Pawel Wieczorkiewicz <[email protected]>
commit 1c728719a4da6e654afb9cc047164755072ed7c9 upstream.
When xen_blkif_disconnect() is called, the kernel thread behind the block interface is stopped by calling kthread_stop(ring->xenblkd). The ring->xenblkd thread pointer being non-NULL determines if the thread has been already stopped.
Normally, the thread's function xen_blkif_schedule() sets the ring->xenblkd to NULL, when the thread's main loop ends.
However, when the thread has not been started yet (i.e. wake_up_process() has not been called on it), the xen_blkif_schedule() function would not be called yet.
In such case the kthread_stop() call returns -EINTR and the ring->xenblkd remains dangling.
When this happens, any consecutive call to xen_blkif_disconnect (for example in frontend_changed() callback) leads to a kernel crash in kthread_stop() (e.g. NULL pointer dereference in exit_creds()).
This is XSA-350.
--- drivers/block/xen-blkback/xenbus.c | 1 + 1 file changed, 1 insertion(+)
drivers/block/xen-blkback/xenbus.c +1 -0
@@ -256,6 +256,7 @@ static int xen_blkif_disconnect(struct xif (ring->xenblkd) {kthread_stop (ring->xenblkd); + ring->xenblkd =NULL ;wake_up (&ring->shutdown_wq); }
Greg Kroah-Hartman
maintainerPATCH 443/453 xen/xenbus: Allow watches discard events before queueing
In reply to Greg Kroah-HartmanFrom: SeongJae Park <[email protected]>
commit fed1755b118147721f2c87b37b9d66e62c39b668 upstream.
If handling logics of watch events are slower than the events enqueue logic and the events can be created from the guests, the guests could trigger memory pressure by intensively inducing the events, because it will create a huge number of pending events that exhausting the memory.
Fortunately, some watch events could be ignored, depending on its handler callback. For example, if the callback has interest in only one single path, the watch wouldn't want multiple pending events. Or, some watches could ignore events to same path.
To let such watches to volutarily help avoiding the memory pressure situation, this commit introduces new watch callback, 'will_handle'. If it is not NULL, it will be called for each new event just before enqueuing it. Then, if the callback returns false, the event will be discarded. No watch is using the callback for now, though.
This is part of XSA-349
--- drivers/net/xen-netback/xenbus.c | 4 ++++ drivers/xen/xenbus/xenbus_client.c | 1 + drivers/xen/xenbus/xenbus_xs.c | 5 ++++- include/xen/xenbus.h | 7 +++++++ 4 files changed, 16 insertions(+), 1 deletion(-)
drivers/net/xen-netback/xenbus.c +4 -0
@@ -713,12 +713,14 @@ static int xen_register_credit_watch(strreturn -ENOMEM ;snprintf (node, maxlen,"%s/rate" , dev->nodename); vif->credit_watch.node = node; + vif->credit_watch.will_handle =NULL ; vif->credit_watch.callback = xen_net_rate_changed; err =register_xenbus_watch (&vif->credit_watch);if (err) {pr_err ("Failed to set watcher %s\n" , vif->credit_watch.node);kfree (node); vif->credit_watch.node =NULL ; + vif->credit_watch.will_handle =NULL ; vif->credit_watch.callback =NULL ; }return err;
@@ -765,6 +767,7 @@ static int xen_register_mcast_ctrl_watchsnprintf (node, maxlen,"%s/request-multicast-control" , dev->otherend); vif->mcast_ctrl_watch.node = node; + vif->mcast_ctrl_watch.will_handle =NULL ; vif->mcast_ctrl_watch.callback = xen_mcast_ctrl_changed; err =register_xenbus_watch (&vif->mcast_ctrl_watch);if (err) {
@@ -772,6 +775,7 @@ static int xen_register_mcast_ctrl_watch vif->mcast_ctrl_watch.node);kfree (node); vif->mcast_ctrl_watch.node =NULL ; + vif->mcast_ctrl_watch.will_handle =NULL ; vif->mcast_ctrl_watch.callback =NULL ; }return err;
drivers/xen/xenbus/xenbus_client.c +1 -0
@@ -120,6 +120,7 @@ int xenbus_watch_path(struct xenbus_deviint err; watch->node = path; + watch->will_handle =NULL ; watch->callback = callback; err =register_xenbus_watch (watch);
drivers/xen/xenbus/xenbus_xs.c +4 -1
@@ -705,7 +705,10 @@ int xs_watch_msg(struct xs_watch_event *spin_lock (&watches_lock); event->handle =find_watch (event->token); -if (event->handle !=NULL ) { +if (event->handle !=NULL && + (!event->handle->will_handle || + event->handle->will_handle (event->handle, + event->path, event->token))) {spin_lock (&watch_events_lock);list_add_tail (&event->list, &watch_events);wake_up (&watch_events_waitq);
include/xen/xenbus.h +7 -0
@@ -59,6 +59,13 @@ struct xenbus_watch/* Path being watched. */ const char *node; +/* +* Called just before enqueing new event while a spinlock is held. +* The event will be discarded if this callback returns false. +*/ +bool (*will_handle)(struct xenbus_watch *, +const char *path,const char *token); +/* Callback (executed in a process context with no locks held). */ void (*callback)(struct xenbus_watch *,const char *path,const char *token);
Greg Kroah-Hartman
maintainerPATCH 444/453 xen/xenbus: Add will_handle callback support in xenbus_watch_path()
In reply to Greg Kroah-HartmanFrom: SeongJae Park <[email protected]>
commit 2e85d32b1c865bec703ce0c962221a5e955c52c2 upstream.
Some code does not directly make 'xenbus_watch' object and call 'register_xenbus_watch()' but use 'xenbus_watch_path()' instead. This commit adds support of 'will_handle' callback in the 'xenbus_watch_path()' and it's wrapper, 'xenbus_watch_pathfmt()'.
This is part of XSA-349
--- drivers/block/xen-blkback/xenbus.c | 3 ++- drivers/net/xen-netback/xenbus.c | 2 +- drivers/xen/xen-pciback/xenbus.c | 2 +- drivers/xen/xenbus/xenbus_client.c | 9 +++++++-- drivers/xen/xenbus/xenbus_probe.c | 2 +- include/xen/xenbus.h | 6 +++++- 6 files changed, 17 insertions(+), 7 deletions(-)
drivers/block/xen-blkback/xenbus.c +2 -1
@@ -644,7 +644,8 @@ static int xen_blkbk_probe(struct xenbus/* setup back pointer */ be->blkif->be = be; - err =xenbus_watch_pathfmt (dev, &be->backend_watch, backend_changed, + err =xenbus_watch_pathfmt (dev, &be->backend_watch,NULL , + backend_changed,"%s/%s" , dev->nodename,"physical-device" );if (err) goto fail;
drivers/net/xen-netback/xenbus.c +1 -1
@@ -979,7 +979,7 @@ static void connect(struct backend_infoxenvif_carrier_on (be->vif);unregister_hotplug_status_watch (be); - err =xenbus_watch_pathfmt (dev, &be->hotplug_status_watch, + err =xenbus_watch_pathfmt (dev, &be->hotplug_status_watch,NULL , hotplug_status_changed,"%s/%s" , dev->nodename,"hotplug-status" );if (!err)
drivers/xen/xen-pciback/xenbus.c +1 -1
@@ -688,7 +688,7 @@ static int xen_pcibk_xenbus_probe(struct/* watch the backend node for backend configuration information */ err =xenbus_watch_path (dev, dev->nodename, &pdev->be_watch, - xen_pcibk_be_watch); +NULL , xen_pcibk_be_watch);if (err) goto out;
drivers/xen/xenbus/xenbus_client.c +7 -2
@@ -114,19 +114,22 @@ EXPORT_SYMBOL_GPL(xenbus_strstate);*/ int xenbus_watch_path (struct xenbus_device *dev,const char *path,struct xenbus_watch *watch, +bool (*will_handle)(struct xenbus_watch *, +const char *,const char *),void (*callback)(struct xenbus_watch *,const char *,const char *)) {int err; watch->node = path; - watch->will_handle =NULL ; + watch->will_handle = will_handle; watch->callback = callback; err =register_xenbus_watch (watch);if (err) { watch->node =NULL ; + watch->will_handle =NULL ; watch->callback =NULL ;xenbus_dev_fatal (dev, err,"adding watch on %s" , path); }
@@ -153,6 +156,8 @@ EXPORT_SYMBOL_GPL(xenbus_watch_path);*/ int xenbus_watch_pathfmt (struct xenbus_device *dev,struct xenbus_watch *watch, +bool (*will_handle)(struct xenbus_watch *, +const char *,const char *),void (*callback)(struct xenbus_watch *,const char *,const char *),const char *pathfmt, ...)
@@ -169,7 +174,7 @@ int xenbus_watch_pathfmt(struct xenbus_dxenbus_dev_fatal (dev, -ENOMEM ,"allocating path for watch" );return -ENOMEM ; } - err =xenbus_watch_path (dev, path, watch, callback); + err =xenbus_watch_path (dev, path, watch, will_handle, callback);if (err)kfree (path);
drivers/xen/xenbus/xenbus_probe.c +1 -1
@@ -136,7 +136,7 @@ static int watch_otherend(struct xenbus_ container_of(dev->dev.bus, struct xen_bus_type, bus);return xenbus_watch_pathfmt (dev, &dev->otherend_watch, - bus->otherend_changed, +NULL , bus->otherend_changed,"%s/%s" , dev->otherend,"state" ); }
include/xen/xenbus.h +5 -1
@@ -199,10 +199,14 @@ void xenbus_probe(struct work_struct *);int xenbus_watch_path (struct xenbus_device *dev,const char *path,struct xenbus_watch *watch, +bool (*will_handle)(struct xenbus_watch *, +const char *,const char *),void (*callback)(struct xenbus_watch *,const char *,const char *)); -__printf(4, 5) +__printf(5, 6)int xenbus_watch_pathfmt (struct xenbus_device *dev,struct xenbus_watch *watch, +bool (*will_handle)(struct xenbus_watch *, +const char *,const char *),void (*callback)(struct xenbus_watch *,const char *,const char *),const char *pathfmt, ...);
Greg Kroah-Hartman
maintainerPATCH 445/453 xen/xenbus/xen_bus_type: Support will_handle watch callback
In reply to Greg Kroah-HartmanFrom: SeongJae Park <[email protected]>
commit be987200fbaceaef340872841d4f7af2c5ee8dc3 upstream.
This commit adds support of the 'will_handle' watch callback for 'xen_bus_type' users.
This is part of XSA-349
--- drivers/xen/xenbus/xenbus.h | 2 ++ drivers/xen/xenbus/xenbus_probe.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-)
drivers/xen/xenbus/xenbus.h +2 -0
@@ -44,6 +44,8 @@ struct xen_bus_type {int (*get_bus_id)(char bus_id[XEN_BUS_ID_SIZE ],const char *nodename);int (*probe)(struct xen_bus_type *bus,const char *type,const char *dir); +bool (*otherend_will_handle)(struct xenbus_watch *watch, +const char *path,const char *token);void (*otherend_changed)(struct xenbus_watch *watch,const char *path,const char *token);struct bus_type bus;
drivers/xen/xenbus/xenbus_probe.c +2 -1
@@ -136,7 +136,8 @@ static int watch_otherend(struct xenbus_ container_of(dev->dev.bus, struct xen_bus_type, bus);return xenbus_watch_pathfmt (dev, &dev->otherend_watch, -NULL , bus->otherend_changed, + bus->otherend_will_handle, + bus->otherend_changed,"%s/%s" , dev->otherend,"state" ); }
Greg Kroah-Hartman
maintainerPATCH 446/453 xen/xenbus: Count pending messages for each watch
In reply to Greg Kroah-HartmanFrom: SeongJae Park <[email protected]>
commit 3dc86ca6b4c8cfcba9da7996189d1b5a358a94fc upstream.
This commit adds a counter of pending messages for each watch in the struct. It is used to skip unnecessary pending messages lookup in 'unregister_xenbus_watch()'. It could also be used in 'will_handle' callback.
This is part of XSA-349
--- drivers/xen/xenbus/xenbus_xs.c | 29 ++++++++++++++++++----------- include/xen/xenbus.h | 2 ++ 2 files changed, 20 insertions(+), 11 deletions(-)
drivers/xen/xenbus/xenbus_xs.c +18 -11
@@ -711,6 +711,7 @@ int xs_watch_msg(struct xs_watch_event * event->path, event->token))) {spin_lock (&watch_events_lock);list_add_tail (&event->list, &watch_events); + event->handle->nr_pending++;wake_up (&watch_events_waitq);spin_unlock (&watch_events_lock); } else
@@ -768,6 +769,8 @@ int register_xenbus_watch(struct xenbus_sprintf (token,"%lX" , (long )watch); + watch->nr_pending =0 ; +down_read (&xs_watch_rwsem);spin_lock (&watches_lock);
@@ -817,11 +820,14 @@ void unregister_xenbus_watch(struct xenb/* Cancel pending watch events. */ spin_lock (&watch_events_lock); -list_for_each_entry_safe (event, tmp, &watch_events, list) { -if (event->handle != watch) -continue ; -list_del (&event->list); -kfree (event); +if (watch->nr_pending) { +list_for_each_entry_safe (event, tmp, &watch_events, list) { +if (event->handle != watch) +continue ; +list_del (&event->list); +kfree (event); + } + watch->nr_pending =0 ; }spin_unlock (&watch_events_lock);
@@ -868,7 +874,6 @@ void xs_suspend_cancel(void)static int xenwatch_thread (void *unused) { -struct list_head *ent;struct xs_watch_event *event; xenwatch_pid = current->pid;
@@ -883,13 +888,15 @@ static int xenwatch_thread(void *unused)mutex_lock (&xenwatch_mutex);spin_lock (&watch_events_lock); - ent = watch_events.next; -if (ent != &watch_events) -list_del (ent); + event =list_first_entry_or_null (&watch_events, + struct xs_watch_event, list); +if (event) { +list_del (&event->list); + event->handle->nr_pending--; + }spin_unlock (&watch_events_lock); -if (ent != &watch_events) { - event = list_entry(ent, struct xs_watch_event, list); +if (event) { event->handle->callback (event->handle, event->path, event->token);kfree (event);
include/xen/xenbus.h +2 -0
@@ -59,6 +59,8 @@ struct xenbus_watch/* Path being watched. */ const char *node; +unsigned int nr_pending; +/* * Called just before enqueing new event while a spinlock is held. * The event will be discarded if this callback returns false.
Greg Kroah-Hartman
maintainerPATCH 447/453 xenbus/xenbus_backend: Disallow pending watch messages
In reply to Greg Kroah-HartmanFrom: SeongJae Park <[email protected]>
commit 9996bd494794a2fe393e97e7a982388c6249aa76 upstream.
'xenbus_backend' watches 'state' of devices, which is writable by guests. Hence, if guests intensively updates it, dom0 will have lots of pending events that exhausting memory of dom0. In other words, guests can trigger dom0 memory pressure. This is known as XSA-349. However, the watch callback of it, 'frontend_changed()', reads only 'state', so doesn't need to have the pending events.
To avoid the problem, this commit disallows pending watch messages for 'xenbus_backend' using the 'will_handle()' watch callback.
This is part of XSA-349
--- drivers/xen/xenbus/xenbus_probe_backend.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/xen/xenbus/xenbus_probe_backend.c +7 -0
@@ -180,6 +180,12 @@ static int xenbus_probe_backend(struct xreturn err; } +static bool frontend_will_handle (struct xenbus_watch *watch, +const char *path,const char *token) +{ +return watch->nr_pending ==0 ; +} +static void frontend_changed (struct xenbus_watch *watch,const char *path,const char *token) {
@@ -191,6 +197,7 @@ static struct xen_bus_type xenbus_backen .levels = 3, /* backend/type/<frontend>/<id> */ .get_bus_id = backend_bus_id, .probe = xenbus_probe_backend, + .otherend_will_handle = frontend_will_handle, .otherend_changed = frontend_changed, .bus = { .name = "xen-backend",
Greg Kroah-Hartman
maintainerPATCH 448/453 libnvdimm/namespace: Fix reaping of invalidated block-window-namespace labels
In reply to Greg Kroah-HartmanFrom: Dan Williams <[email protected]>
commit 2dd2a1740ee19cd2636d247276cf27bfa434b0e2 upstream.
A recent change to ndctl to attempt to reconfigure namespaces in place uncovered a label accounting problem in block-window-type namespaces. The ndctl "create.sh" test is able to trigger this signature:
WARNING: CPU: 34 PID: 9167 at drivers/nvdimm/label.c:1100 __blk_label_update+0x9a3/0xbc0 [libnvdimm] [..] RIP: 0010:__blk_label_update+0x9a3/0xbc0 [libnvdimm] [..] Call Trace: uuid_store+0x21b/0x2f0 [libnvdimm] kernfs_fop_write+0xcf/0x1c0 vfs_write+0xcc/0x380 ksys_write+0x68/0xe0
When allocated capacity for a namespace is renamed (new UUID) the labels with the old UUID need to be deleted. The ndctl behavior to always destroy namespaces on reconfiguration hid this problem.
The immediate impact of this bug is limited since block-window-type namespaces only seem to exist in the specification and not in any shipping products. However, the label handling code is being reused for other technologies like CXL region labels, so there is a benefit to making sure both vertical labels sets (block-window) and horizontal label sets (pmem) have a functional reference implementation in libnvdimm.
--- drivers/nvdimm/label.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/nvdimm/label.c +9 -0
@@ -980,6 +980,15 @@ static int __blk_label_update(struct nd_ } } +/* release slots associated with any invalidated UUIDs */ +mutex_lock (&nd_mapping->lock); +list_for_each_entry_safe (label_ent, e, &nd_mapping->labels, list) +if (test_and_clear_bit (ND_LABEL_REAP , &label_ent->flags)) { +reap_victim (nd_mapping, label_ent); +list_move (&label_ent->list, &list); + } +mutex_unlock (&nd_mapping->lock); +/* * Find the resource associated with the first label in the set * per the v1.2 namespace specification.
Greg Kroah-Hartman
maintainerPATCH 449/453 platform/x86: intel-vbtn: Allow switch events on Acer Switch Alpha 12
In reply to Greg Kroah-HartmanFrom: Carlos Garnacho <[email protected]>
commit fe6000990394639ed374cb76c313be3640714f47 upstream.
This 2-in-1 model (Product name: Switch SA5-271) features a SW_TABLET_MODE that works as it would be expected, both when detaching the keyboard and when folding it behind the tablet body.
It used to work until the introduction of the allow list at commit 8169bd3e6e193 ("platform/x86: intel-vbtn: Switch to an allow-list for SW_TABLET_MODE reporting"). Add this model to it, so that the Virtual Buttons device announces the EV_SW features again.
--- drivers/platform/x86/intel-vbtn.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/platform/x86/intel-vbtn.c +6 -0
@@ -203,6 +203,12 @@ static const struct dmi_system_id dmi_sw DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion 13 x360 PC"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271"), + }, + }, {}/* Array terminator */ };
Greg Kroah-Hartman
maintainerPATCH 450/453 PCI: Fix pci_slot_release() NULL pointer dereference
In reply to Greg Kroah-HartmanFrom: Jubin Zhong <[email protected]>
commit 4684709bf81a2d98152ed6b610e3d5c403f9bced upstream.
If kobject_init_and_add() fails, pci_slot_release() is called to delete slot->list from parent->slots. But slot->list hasn't been initialized yet, so we dereference a NULL pointer:
Unable to handle kernel NULL pointer dereference at virtual address 00000000 ... CPU: 10 PID: 1 Comm: swapper/0 Not tainted 4.4.240 #197 task: ffffeb398a45ef10 task.stack: ffffeb398a470000 PC is at __list_del_entry_valid+0x5c/0xb0 LR is at pci_slot_release+0x84/0xe4 ... __list_del_entry_valid+0x5c/0xb0 pci_slot_release+0x84/0xe4 kobject_put+0x184/0x1c4 pci_create_slot+0x17c/0x1b4 __pci_hp_initialize+0x68/0xa4 pciehp_probe+0x1a4/0x2fc pcie_port_probe_service+0x58/0x84 driver_probe_device+0x320/0x470
Initialize slot->list before calling kobject_init_and_add() to avoid this.
--- drivers/pci/slot.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/pci/slot.c +3 -3
@@ -308,6 +308,9 @@ placeholder: goto err; } +INIT_LIST_HEAD (&slot->list); +list_add (&slot->list, &parent->slots); + err =kobject_init_and_add (&slot->kobj, &pci_slot_ktype,NULL ,"%s" , slot_name);if (err) {
@@ -315,9 +318,6 @@ placeholder: goto err; } -INIT_LIST_HEAD (&slot->list); -list_add (&slot->list, &parent->slots); -down_read (&pci_bus_sem);list_for_each_entry (dev, &parent->devices, bus_list)if (PCI_SLOT (dev->devfn) == slot_nr)
Greg Kroah-Hartman
maintainerPATCH 451/453 regulator: axp20x: Fix DLDO2 voltage control register mask for AXP22x
In reply to Greg Kroah-HartmanFrom: DingHua Ma <[email protected]>
commit 291de1d102fafef0798cdad9666cd4f8da7da7cc upstream.
When I use the axp20x chip to power my SDIO device on the 5.4 kernel, the output voltage of DLDO2 is wrong. After comparing the register manual and source code of the chip, I found that the mask bit of the driver register of the port was wrong. I fixed this error by modifying the mask register of the source code. This error seems to be a copy error of the macro when writing the code. Now the voltage output of the DLDO2 port of axp20x is correct. My development environment is Allwinner A40I of arm architecture, and the kernel version is 5.4.
--- drivers/regulator/axp20x-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/regulator/axp20x-regulator.c +1 -1
@@ -596,7 +596,7 @@ static const struct regulator_desc axp22 AXP22X_DLDO1_V_OUT, AXP22X_DLDO1_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO1_MASK),AXP_DESC (AXP22X ,DLDO2 ,"dldo2" ,"dldoin" ,700 ,3300 ,100 , -AXP22X_DLDO2_V_OUT ,AXP22X_PWR_OUT_DLDO2_MASK , +AXP22X_DLDO2_V_OUT ,AXP22X_DLDO2_V_OUT_MASK ,AXP22X_PWR_OUT_CTRL2 ,AXP22X_PWR_OUT_DLDO2_MASK ), AXP_DESC(AXP22X, DLDO3, "dldo3", "dldoin", 700, 3300, 100, AXP22X_DLDO3_V_OUT, AXP22X_DLDO3_V_OUT_MASK,
Greg Kroah-Hartman
maintainerPATCH 452/453 rtc: ep93xx: Fix NULL pointer dereference in ep93xx_rtc_read_time
In reply to Greg Kroah-HartmanFrom: Nikita Shubin <[email protected]>
commit 00c33482bb6110bce8110daa351f9b3baf4df7dc upstream.
Mismatch in probe platform_set_drvdata set's and method's that call dev_get_platdata will result in "Unable to handle kernel NULL pointer dereference", let's use according method for getting driver data after platform_set_drvdata.
8<--- cut here ---
Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = (ptrval) [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper Not tainted 5.9.10-00003-g723e101e0037-dirty #4 Hardware name: Technologic Systems TS-72xx SBC PC is at ep93xx_rtc_read_time+0xc/0x2c LR is at __rtc_read_time+0x4c/0x8c
[...]
[<c02b01c8>] (ep93xx_rtc_read_time) from [<c02ac38c>] (__rtc_read_time+0x4c/0x8c) [<c02ac38c>] (__rtc_read_time) from [<c02ac3f8>] (rtc_read_time+0x2c/0x4c) [<c02ac3f8>] (rtc_read_time) from [<c02acc54>] (__rtc_read_alarm+0x28/0x358) [<c02acc54>] (__rtc_read_alarm) from [<c02abd80>] (__rtc_register_device+0x124/0x2ec) [<c02abd80>] (__rtc_register_device) from [<c02b028c>] (ep93xx_rtc_probe+0xa4/0xac) [<c02b028c>] (ep93xx_rtc_probe) from [<c026424c>] (platform_drv_probe+0x24/0x5c) [<c026424c>] (platform_drv_probe) from [<c0262918>] (really_probe+0x218/0x374) [<c0262918>] (really_probe) from [<c0262da0>] (device_driver_attach+0x44/0x60) [<c0262da0>] (device_driver_attach) from [<c0262e70>] (__driver_attach+0xb4/0xc0) [<c0262e70>] (__driver_attach) from [<c0260d44>] (bus_for_each_dev+0x68/0xac) [<c0260d44>] (bus_for_each_dev) from [<c026223c>] (driver_attach+0x18/0x24) [<c026223c>] (driver_attach) from [<c0261dd8>] (bus_add_driver+0x150/0x1b4) [<c0261dd8>] (bus_add_driver) from [<c026342c>] (driver_register+0xb0/0xf4) [<c026342c>] (driver_register) from [<c0264210>] (__platform_driver_register+0x30/0x48) [<c0264210>] (__platform_driver_register) from [<c04cb9ac>] (ep93xx_rtc_driver_init+0x10/0x1c) [<c04cb9ac>] (ep93xx_rtc_driver_init) from [<c000973c>] (do_one_initcall+0x7c/0x1c0) [<c000973c>] (do_one_initcall) from [<c04b9ecc>] (kernel_init_freeable+0x168/0x1ac) [<c04b9ecc>] (kernel_init_freeable) from [<c03b2228>] (kernel_init+0x8/0xf4) [<c03b2228>] (kernel_init) from [<c00082c0>] (ret_from_fork+0x14/0x34)
Exception stack(0xc441dfb0 to 0xc441dff8) dfa0: 00000000 00000000 00000000 00000000 dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 Code: e12fff1e e92d4010 e590303c e1a02001 (e5933000) ---[ end trace c914d6030eaa95c8 ]---
--- drivers/rtc/rtc-ep93xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/rtc/rtc-ep93xx.c +3 -3
@@ -33,7 +33,7 @@ struct ep93xx_rtc {static int ep93xx_rtc_get_swcomp (struct device *dev,unsigned short *preload,unsigned short *delete) { -struct ep93xx_rtc *ep93xx_rtc =dev_get_platdata (dev); +struct ep93xx_rtc *ep93xx_rtc =dev_get_drvdata (dev);unsigned long comp; comp =readl (ep93xx_rtc->mmio_base +EP93XX_RTC_SWCOMP );
@@ -51,7 +51,7 @@ static int ep93xx_rtc_get_swcomp(structstatic int ep93xx_rtc_read_time (struct device *dev,struct rtc_time *tm) { -struct ep93xx_rtc *ep93xx_rtc =dev_get_platdata (dev); +struct ep93xx_rtc *ep93xx_rtc =dev_get_drvdata (dev);unsigned long time; time =readl (ep93xx_rtc->mmio_base +EP93XX_RTC_DATA );
@@ -62,7 +62,7 @@ static int ep93xx_rtc_read_time(struct dstatic int ep93xx_rtc_set_time (struct device *dev,struct rtc_time *tm) { -struct ep93xx_rtc *ep93xx_rtc =dev_get_platdata (dev); +struct ep93xx_rtc *ep93xx_rtc =dev_get_drvdata (dev);unsigned long secs =rtc_tm_to_time64 (tm);writel (secs +1 , ep93xx_rtc->mmio_base +EP93XX_RTC_LOAD );
Greg Kroah-Hartman
maintainerPATCH 453/453 Revert: "ring-buffer: Remove HAVE_64BIT_ALIGNED_ACCESS"
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (VMware) <[email protected]>
commit adab66b71abfe206a020f11e561f4df41f0b2aba upstream.
It was believed that metag was the only architecture that required the ring buffer to keep 8 byte words aligned on 8 byte architectures, and with its removal, it was assumed that the ring buffer code did not need to handle this case. It appears that sparc64 also requires this.
The following was reported on a sparc64 boot up:
kernel: futex hash table entries: 65536 (order: 9, 4194304 bytes, linear)
kernel: Running postponed tracer tests:
kernel: Testing tracer function:
kernel: Kernel unaligned access at TPC[552a20] trace_function+0x40/0x140
kernel: Kernel unaligned access at TPC[552a24] trace_function+0x44/0x140
kernel: Kernel unaligned access at TPC[552a20] trace_function+0x40/0x140
kernel: Kernel unaligned access at TPC[552a24] trace_function+0x44/0x140
kernel: Kernel unaligned access at TPC[552a20] trace_function+0x40/0x140
kernel: PASSED
Need to put back the 64BIT aligned code for the ring buffer.
--- arch/Kconfig | 16 ++++++++++++++++ kernel/trace/ring_buffer.c | 17 +++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-)
arch/Kconfig +16 -0
@@ -131,6 +131,22 @@ config UPROBES managed by the kernel and kept transparent to the probed application. ) +config HAVE_64BIT_ALIGNED_ACCESS + def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS + help + Some architectures require 64 bit accesses to be 64 bit + aligned, which also requires structs containing 64 bit values + to be 64 bit aligned too. This includes some 32 bit + architectures which can do 64 bit accesses, as well as 64 bit + architectures without unaligned access. + + This symbol should be selected by an architecture if 64 bit + accesses are required to be 64 bit aligned in this way even + though it is not a 64 bit architecture. + + See Documentation/unaligned-memory-access.txt for more + information on the topic of unaligned memory accesses. + config HAVE_EFFICIENT_UNALIGNED_ACCESS bool help
kernel/trace/ring_buffer.c +13 -4
@@ -129,7 +129,16 @@ int ring_buffer_print_entry_header(struc#define RB_ALIGNMENT 4U#define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX)#define RB_EVNT_MIN_SIZE 8U/* two 32bit words */ -#define RB_ALIGN_DATA __aligned(RB_ALIGNMENT) + +#ifndef CONFIG_HAVE_64BIT_ALIGNED_ACCESS +# define RB_FORCE_8BYTE_ALIGNMENT 0 +# define RB_ARCH_ALIGNMENT RB_ALIGNMENT +#else +# define RB_FORCE_8BYTE_ALIGNMENT 1 +# define RB_ARCH_ALIGNMENT 8U +#endif + +#define RB_ALIGN_DATA __aligned(RB_ARCH_ALIGNMENT)/* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */ #define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX
@@ -2367,7 +2376,7 @@ rb_update_event(struct ring_buffer_per_c event->time_delta = delta; length -=RB_EVNT_HDR_SIZE ; -if (length >RB_MAX_SMALL_DATA ) { +if (length >RB_MAX_SMALL_DATA ||RB_FORCE_8BYTE_ALIGNMENT ) { event->type_len =0 ; event->array[0 ] = length; }else
@@ -2382,11 +2391,11 @@ static unsigned rb_calculate_event_lengtif (!length) length++; -if (length >RB_MAX_SMALL_DATA ) +if (length >RB_MAX_SMALL_DATA ||RB_FORCE_8BYTE_ALIGNMENT ) length +=sizeof (event.array[0 ]); length +=RB_EVNT_HDR_SIZE ; - length =ALIGN (length,RB_ALIGNMENT ); + length =ALIGN (length,RB_ARCH_ALIGNMENT );/* * In case the time delta is larger than the 27 bits for it
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.86 release. There are 453 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 30 Dec 2020 12:48:23 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.86-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
Perf build failed on stable-rc 5.4 branch.
Quoted 2 lines
Andrii Nakryiko <[email protected]>
libbpf: Fix BTF data layout checks and allow empty BTF
In file included from btf.c:17:0:btf.c: In function 'btf_parse_hdr':
btf.c:104:48: error: 'struct btf' has no member named 'raw_size'; did you mean 'data_size'?
pr_debug("Invalid BTF total size:%u\n", btf->raw_size);
^
libbpf_internal.h:59:40: note: in definition of macro '__pr'
libbpf_print(level, "libbpf: " fmt, ##__VA_ARGS__); \
^~~~~~~~~~~btf.c:104:3: note: in expansion of macro 'pr_debug'
pr_debug("Invalid BTF total size:%u\n", btf->raw_size); ^~~~~~~~
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.86 release. There are 453 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 30 Dec 2020 12:48:23 +0000. Anything received after that time might be too late.
Building arm:multi_v5_defconfig ... failed
--------------
Error log:drivers/leds/leds-netxbig.c: In function 'netxbig_leds_get_of_pdata':drivers/leds/leds-netxbig.c:571:13: error: 'gpio_ext_dev' undeclared
Guenter
Greg Kroah-Hartman
maintainerQuoted 11 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.86 release. There are 453 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 30 Dec 2020 12:48:23 +0000. Anything received after that time might be too late.
Quoted 5 lines
Building arm:multi_v5_defconfig ... failed
--------------
Error log:drivers/leds/leds-netxbig.c: In function 'netxbig_leds_get_of_pdata':drivers/leds/leds-netxbig.c:571:13: error: 'gpio_ext_dev' undeclared
THanks for reporting this, I'll go delete the offending patch...
greg k-h
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.86 release. There are 453 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 30 Dec 2020 12:48:23 +0000. Anything received after that time might be too late.
Build results:
total: 157 pass: 154 fail: 3 Failed builds: arm:multi_v5_defconfig i386:tools/perf x86_64:tools/perf Qemu test results: total: 427 pass: 427 fail: 0
Failures as reported.
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.86 release. There are 453 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 30 Dec 2020 12:48:23 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.86-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.4:
12 builds: 12 pass, 0 fail
26 boots: 26 pass, 0 fail
56 tests: 56 pass, 0 failLinux version: 5.4.86-rc1-g11e71509ffb7
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon