5.4.33-rc1 review
Subsystems (2)
Greg Kroah-Hartman
maintainerPATCH 152/232 io_uring: honor original task RLIMIT_FSIZE
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 4ed734b0d0913e566a9d871e15d24eb240f269f7 upstream.
With the previous fixes for number of files open checking, I added some debug code to see if we had other spots where we're checking rlimit() against the async io-wq workers. The only one I found was file size checking, which we should also honor.
During write and fallocate prep, store the max file size and override that for the current ask if we're in io-wq worker context.
--- fs/io_uring.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
fs/io_uring.c +11 -0
@@ -331,6 +331,7 @@ struct io_kiocb {#define REQ_F_ISREG 2048/* regular file */ #define REQ_F_MUST_PUNT 4096/* must be punted even for NONBLOCK */ #define REQ_F_TIMEOUT_NOSEQ 8192/* no timeout sequence */ +unsigned long fsize;u64 user_data;u32 result;u32 sequence;
@@ -1085,6 +1086,9 @@ static int io_prep_rw(struct io_kiocb *rif (S_ISREG (file_inode (req->file)->i_mode)) req->flags |=REQ_F_ISREG ; +if (force_nonblock) + req->fsize =rlimit (RLIMIT_FSIZE ); +/* * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so * we know to async punt it even if it was opened O_NONBLOCK
@@ -1504,10 +1508,17 @@ static int io_write(struct io_kiocb *req } kiocb->ki_flags |=IOCB_WRITE ; +if (!force_nonblock) + current->signal->rlim[RLIMIT_FSIZE ].rlim_cur = req->fsize; +if (file->f_op->write_iter) ret2 =call_write_iter (file, kiocb, &iter);else ret2 =loop_rw_iter (WRITE , file, kiocb, &iter); + +if (!force_nonblock) + current->signal->rlim[RLIMIT_FSIZE ].rlim_cur =RLIM_INFINITY ; +if (!force_nonblock || ret2 != -EAGAIN ) {io_rw_done (kiocb, ret2); }else {
Greg Kroah-Hartman
maintainerPATCH 153/232 mmc: sdhci-of-esdhc: fix esdhc_reset() for different controller versions
In reply to Greg Kroah-HartmanFrom: Yangbo Lu <[email protected]>
commit 2aa3d826adb578b26629a79b775a552cfe3fedf7 upstream.
This patch is to fix operating in esdhc_reset() for different controller versions, and to add bus-width restoring after data reset for eSDHC (verdor version <= 2.2).
Also add annotation for understanding.
--- drivers/mmc/host/sdhci-of-esdhc.c | 43 ++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)
drivers/mmc/host/sdhci-of-esdhc.c +39 -4
@@ -734,23 +734,58 @@ static void esdhc_reset(struct sdhci_hos {struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host);struct sdhci_esdhc *esdhc =sdhci_pltfm_priv (pltfm_host); -u32 val; +u32 val, bus_width =0 ; +/* +* Add delay to make sure all the DMA transfers are finished +* for quirk. +*/ if (esdhc->quirk_delay_before_data_reset && (mask &SDHCI_RESET_DATA ) && (host->flags &SDHCI_REQ_USE_DMA ))mdelay (5 ); +/* +* Save bus-width for eSDHC whose vendor version is 2.2 +* or lower for data reset. +*/ +if ((mask &SDHCI_RESET_DATA ) && + (esdhc->vendor_ver <=VENDOR_V_22 )) { + val =sdhci_readl (host,ESDHC_PROCTL ); + bus_width = val &ESDHC_CTRL_BUSWIDTH_MASK ; + } +sdhci_reset (host, mask); -sdhci_writel (host, host->ier,SDHCI_INT_ENABLE ); -sdhci_writel (host, host->ier,SDHCI_SIGNAL_ENABLE ); +/* +* Restore bus-width setting and interrupt registers for eSDHC +* whose vendor version is 2.2 or lower for data reset. +*/ +if ((mask &SDHCI_RESET_DATA ) && + (esdhc->vendor_ver <=VENDOR_V_22 )) { + val =sdhci_readl (host,ESDHC_PROCTL ); + val &= ~ESDHC_CTRL_BUSWIDTH_MASK ; + val |= bus_width; +sdhci_writel (host, val,ESDHC_PROCTL ); + +sdhci_writel (host, host->ier,SDHCI_INT_ENABLE ); +sdhci_writel (host, host->ier,SDHCI_SIGNAL_ENABLE ); + } -if (mask &SDHCI_RESET_ALL ) { +/* +* Some bits have to be cleaned manually for eSDHC whose spec +* version is higher than 3.0 for all reset. +*/ +if ((mask &SDHCI_RESET_ALL ) && + (esdhc->spec_ver >=SDHCI_SPEC_300 )) { val =sdhci_readl (host,ESDHC_TBCTL ); val &= ~ESDHC_TB_EN ;sdhci_writel (host, val,ESDHC_TBCTL ); +/* +* Initialize eSDHC_DLLCFG1[DLL_PD_PULSE_STRETCH_SEL] to +* 0 for quirk. +*/ if (esdhc->quirk_unreliable_pulse_detection) { val =sdhci_readl (host,ESDHC_DLLCFG1 ); val &= ~ESDHC_DLL_PD_PULSE_STRETCH_SEL ;
Greg Kroah-Hartman
maintainerPATCH 154/232 powerpc/pseries: Drop pointless static qualifier in vpa_debugfs_init()
In reply to Greg Kroah-HartmanFrom: YueHaibing <[email protected]>
commit 11dd34f3eae5a468013bb161a1dcf1fecd2ca321 upstream.
There is no need to have the 'struct dentry *vpa_dir' variable static since new value always be assigned before use it.
--- arch/powerpc/platforms/pseries/lpar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/platforms/pseries/lpar.c +1 -1
@@ -1992,7 +1992,7 @@ static int __init vpa_debugfs_init(void) {char name[16 ];long i; -static struct dentry *vpa_dir; +struct dentry *vpa_dir;if (!firmware_has_feature (FW_FEATURE_SPLPAR ))return 0 ;
Greg Kroah-Hartman
maintainerPATCH 155/232 tools: gpio: Fix out-of-tree build regression
In reply to Greg Kroah-HartmanFrom: Anssi Hannula <[email protected]>
commit 82f04bfe2aff428b063eefd234679b2d693228ed upstream.
Commit 0161a94e2d1c7 ("tools: gpio: Correctly add make dependencies for gpio_utils") added a make rule for gpio-utils-in.o but used $(output) instead of the correct $(OUTPUT) for the output directory, breaking out-of-tree build (O=xx) with the following error:
No rule to make target 'out/tools/gpio/gpio-utils-in.o', needed by 'out/tools/gpio/lsgpio-in.o'. Stop.
Fix that.
--- tools/gpio/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/gpio/Makefile +1 -1
@@ -35,7 +35,7 @@ $(OUTPUT)include/linux/gpio.h: ../../inc prepare: $(OUTPUT)include/linux/gpio.h -GPIO_UTILS_IN := $(output)gpio-utils-in.o +GPIO_UTILS_IN := $(OUTPUT)gpio-utils-in.o $(GPIO_UTILS_IN): prepare FORCE $(Q)$(MAKE) $(build)=gpio-utils
Greg Kroah-Hartman
maintainerPATCH 156/232 net: qualcomm: rmnet: Allow configuration updates to existing devices
In reply to Greg Kroah-HartmanFrom: Subash Abhinov Kasiviswanathan <[email protected]>
commit 2abb5792387eb188b12051337d5dcd2cba615cb0 upstream.
This allows the changelink operation to succeed if the mux_id was specified as an argument. Note that the mux_id must match the existing mux_id of the rmnet device or should be an unused mux_id.
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 31 ++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +19 -12
@@ -279,7 +279,6 @@ static int rmnet_changelink(struct net_d {struct rmnet_priv *priv =netdev_priv (dev);struct net_device *real_dev; -struct rmnet_endpoint *ep;struct rmnet_port *port;u16 mux_id;
@@ -294,19 +293,27 @@ static int rmnet_changelink(struct net_dif (data[IFLA_RMNET_MUX_ID ]) { mux_id =nla_get_u16 (data[IFLA_RMNET_MUX_ID ]); -if (rmnet_get_endpoint (port, mux_id)) { -NL_SET_ERR_MSG_MOD (extack,"MUX ID already exists" ); -return -EINVAL ; - } - ep =rmnet_get_endpoint (port, priv->mux_id); -if (!ep) -return -ENODEV ; -hlist_del_init_rcu (&ep->hlnode); -hlist_add_head_rcu (&ep->hlnode, &port->muxed_ep[mux_id]); +if (mux_id != priv->mux_id) { +struct rmnet_endpoint *ep; + + ep =rmnet_get_endpoint (port, priv->mux_id); +if (!ep) +return -ENODEV ; + +if (rmnet_get_endpoint (port, mux_id)) { +NL_SET_ERR_MSG_MOD (extack, +"MUX ID already exists" ); +return -EINVAL ; + } + +hlist_del_init_rcu (&ep->hlnode); +hlist_add_head_rcu (&ep->hlnode, + &port->muxed_ep[mux_id]); - ep->mux_id = mux_id; - priv->mux_id = mux_id; + ep->mux_id = mux_id; + priv->mux_id = mux_id; + } }if (data[IFLA_RMNET_FLAGS ]) {
Greg Kroah-Hartman
maintainerPATCH 157/232 arm64: dts: allwinner: h6: Fix PMU compatible
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
commit 4c7eeb9af3e41ae7d840977119c58f3bbb3f4f59 upstream.
The commit 7aa9b9eb7d6a ("arm64: dts: allwinner: H6: Add PMU mode") introduced support for the PMU found on the Allwinner H6. However, the binding only allows for a single compatible, while the patch was adding two.
Make sure we follow the binding.
--- arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +1 -2
@@ -71,8 +71,7 @@ }; pmu { - compatible = "arm,cortex-a53-pmu", - "arm,armv8-pmuv3"; + compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
Greg Kroah-Hartman
maintainerPATCH 158/232 sched/core: Remove duplicate assignment in sched_tick_remote()
In reply to Greg Kroah-HartmanFrom: Scott Wood <[email protected]>
commit 82e0516ce3a147365a5dd2a9bedd5ba43a18663d upstream.
A redundant "curr = rq->curr" was added; remove it.
--- kernel/sched/core.c | 1 - 1 file changed, 1 deletion(-)
kernel/sched/core.c +0 -1
@@ -3676,7 +3676,6 @@ static void sched_tick_remote(struct worif (cpu_is_offline (cpu)) goto out_unlock; - curr = rq->curr;update_rq_clock (rq);if (!is_idle_task (curr)) {
Greg Kroah-Hartman
maintainerPATCH 159/232 arm64: dts: allwinner: h5: Fix PMU compatible
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
commit 4ae7a3c3d7d31260f690d8d658f0365f3eca67a2 upstream.
The commit c35a516a4618 ("arm64: dts: allwinner: H5: Add PMU node") introduced support for the PMU found on the Allwinner H5. However, the binding only allows for a single compatible, while the patch was adding two.
Make sure we follow the binding.
--- arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +1 -2
@@ -77,8 +77,7 @@ }; pmu { - compatible = "arm,cortex-a53-pmu", - "arm,armv8-pmuv3"; + compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
Greg Kroah-Hartman
maintainerPATCH 160/232 mm, memcg: do not high throttle allocators based on wraparound
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
commit 9b8b17541f13809d06f6f873325305ddbb760e3e upstream.
If a cgroup violates its memory.high constraints, we may end up unduly penalising it. For example, for the following hierarchy:
A: max high, 20 usage
A/B: 9 high, 10 usage
A/C: max high, 10 usage
We would end up doing the following calculation below when calculating high delay for A/B:
A/B: 10 - 9 = 1...
A: 20 - PAGE_COUNTER_MAX = 21, so set max_overage to 21.
This gets worse with higher disparities in usage in the parent.
I have no idea how this disappeared from the final version of the patch, but it is certainly Not Good(tm). This wasn't obvious in testing because, for a simple cgroup hierarchy with only one child, the result is usually roughly the same. It's only in more complex hierarchies that things go really awry (although still, the effects are limited to a maximum of 2 seconds in schedule_timeout_killable at a maximum).
--- mm/memcontrol.c | 3 +++ 1 file changed, 3 insertions(+)
mm/memcontrol.c +3 -0
@@ -2441,6 +2441,9 @@ static unsigned long calculate_high_dela usage =page_counter_read (&memcg->memory); high =READ_ONCE (memcg->high); +if (usage <= high) +continue ; +/* * Prevent division by 0 in overage calculation by acting as if * it was a threshold of 1 page
Greg Kroah-Hartman
maintainerPATCH 161/232 dm writecache: add cond_resched to avoid CPU hangs
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
commit 1edaa447d958bec24c6a79685a5790d98976fd16 upstream.
Initializing a dm-writecache device can take a long time when the persistent memory device is large. Add cond_resched() to a few loops to avoid warnings that the CPU is stuck.
--- drivers/md/dm-writecache.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/md/dm-writecache.c +5 -1
@@ -872,6 +872,7 @@ static int writecache_alloc_entries(strustruct wc_entry *e = &wc->entries[b]; e->index = b; e->write_in_progress = false; +cond_resched (); }return 0 ;
@@ -926,6 +927,7 @@ static void writecache_resume(struct dm_ e->original_sector =le64_to_cpu (wme.original_sector); e->seq_count = le64_to_cpu(wme.seq_count); } +cond_resched (); }#endif for (b =0 ; b < wc->n_blocks; b++) {
@@ -1770,8 +1772,10 @@ static int init_memory(struct dm_writecapmem_assign (sb (wc)->n_blocks,cpu_to_le64 (wc->n_blocks));pmem_assign (sb (wc)->seq_count,cpu_to_le64 (0 )); -for (b =0 ; b < wc->n_blocks; b++) +for (b =0 ; b < wc->n_blocks; b++) {write_original_sector_seq_count (wc, &wc->entries[b],-1 ,-1 ); +cond_resched (); + }writecache_flush_all_metadata (wc);writecache_commit_flushed (wc, false);
Greg Kroah-Hartman
maintainerPATCH 162/232 dm integrity: fix a crash with unusually large tag size
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
commit b93b6643e9b5a7f260b931e97f56ffa3fa65e26d upstream.
If the user specifies tag size larger than HASH_MAX_DIGESTSIZE, there's a crash in integrity_metadata().
--- drivers/md/dm-integrity.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/md/dm-integrity.c +2 -2
@@ -1514,7 +1514,7 @@ static void integrity_metadata(struct wostruct bio *bio =dm_bio_from_per_bio_data (dio,sizeof (struct dm_integrity_io ));char *checksums;unsigned extra_space =unlikely (digest_size > ic->tag_size) ? digest_size - ic->tag_size :0 ; -char checksums_onstack[HASH_MAX_DIGESTSIZE ]; +char checksums_onstack[max ((size_t )HASH_MAX_DIGESTSIZE ,MAX_TAG_SIZE )];unsigned sectors_to_process = dio->range.n_sectors;sector_t sector = dio->range.logical_sector;
@@ -1743,7 +1743,7 @@ retry_kmap: }while (++s < ic->sectors_per_block);#ifdef INTERNAL_VERIFY if (ic->internal_hash) { -char checksums_onstack[max (HASH_MAX_DIGESTSIZE ,MAX_TAG_SIZE )]; +char checksums_onstack[max ((size_t )HASH_MAX_DIGESTSIZE ,MAX_TAG_SIZE )];integrity_sector_checksum (ic, logical_sector, mem + bv.bv_offset, checksums_onstack);if (unlikely (memcmp (checksums_onstack,journal_entry_tag (ic, je), ic->tag_size))) {
Greg Kroah-Hartman
maintainerPATCH 163/232 dm verity fec: fix memory leak in verity_fec_dtr
In reply to Greg Kroah-HartmanFrom: Shetty, Harshini X (EXT-Sony Mobile) <[email protected]>
commit 75fa601934fda23d2f15bf44b09c2401942d8e15 upstream.
Fix below kmemleak detected in verity_fec_ctr. output_pool is allocated for each dm-verity-fec device. But it is not freed when dm-table for the verity target is removed. Hence free the output mempool in destructor function verity_fec_dtr.
unreferenced object 0xffffffffa574d000 (size 4096):
comm "init", pid 1667, jiffies 4294894890 (age 307.168s) hex dump (first 32 bytes):
8e 36 00 98 66 a8 0b 9b 00 00 00 00 00 00 00 00 .6..f...........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<0000000060e82407>] __kmalloc+0x2b4/0x340
[<00000000dd99488f>] mempool_kmalloc+0x18/0x20
[<000000002560172b>] mempool_init_node+0x98/0x118
[<000000006c3574d2>] mempool_init+0x14/0x20
[<0000000008cb266e>] verity_fec_ctr+0x388/0x3b0
[<000000000887261b>] verity_ctr+0x87c/0x8d0
[<000000002b1e1c62>] dm_table_add_target+0x174/0x348
[<000000002ad89eda>] table_load+0xe4/0x328
[<000000001f06f5e9>] dm_ctl_ioctl+0x3b4/0x5a0
[<00000000bee5fbb7>] do_vfs_ioctl+0x5dc/0x928
[<00000000b475b8f5>] __arm64_sys_ioctl+0x70/0x98
[<000000005361e2e8>] el0_svc_common+0xa0/0x158
[<000000001374818f>] el0_svc_handler+0x6c/0x88
[<000000003364e9f4>] el0_svc+0x8/0xc
[<000000009d84cec9>] 0xffffffffffffffffDepends-on: 6f1c819c219f7 ("dm: convert to bioset_init()/mempool_init()")
--- drivers/md/dm-verity-fec.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/dm-verity-fec.c +1 -0
@@ -551,6 +551,7 @@ void verity_fec_dtr(struct dm_verity *v)mempool_exit (&f->rs_pool);mempool_exit (&f->prealloc_pool);mempool_exit (&f->extra_pool); +mempool_exit (&f->output_pool);kmem_cache_destroy (f->cache);if (f->data_bufio)
Greg Kroah-Hartman
maintainerPATCH 164/232 dm clone: Add overflow check for number of regions
In reply to Greg Kroah-HartmanFrom: Nikos Tsironis <[email protected]>
commit cd481c12269b4d276f1a52eda0ebd419079bfe3a upstream.
Add overflow check for clone->nr_regions variable, which holds the number of regions of the target.
The overflow can occur with sufficiently large devices, if BITS_PER_LONG == 32. E.g., if the region size is 8 sectors (4K), the overflow would occur for device sizes > 34359738360 sectors (~16TB).
This could result in multiple device sectors wrongly mapping to the same region number, due to the truncation from 64 bits to 32 bits, which would lead to data corruption.
--- drivers/md/dm-clone-target.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/md/dm-clone-target.c +11 -1
@@ -1775,6 +1775,7 @@ error:static int clone_ctr (struct dm_target *ti,unsigned int argc,char **argv) {int r; +sector_t nr_regions;struct clone *clone;struct dm_arg_set as;
@@ -1816,7 +1817,16 @@ static int clone_ctr(struct dm_target *t goto out_with_source_dev; clone->region_shift =__ffs (clone->region_size); - clone->nr_regions =dm_sector_div_up (ti->len, clone->region_size); + nr_regions =dm_sector_div_up (ti->len, clone->region_size); + +/* Check for overflow */ +if (nr_regions != (unsigned long )nr_regions) { + ti->error ="Too many regions. Consider increasing the region size" ; + r = -EOVERFLOW ; + goto out_with_source_dev; + } + + clone->nr_regions = nr_regions; r =validate_nr_regions (clone->nr_regions, &ti->error);if (r)
Greg Kroah-Hartman
maintainerPATCH 165/232 dm clone metadata: Fix return type of dm_clone_nr_of_hydrated_regions()
In reply to Greg Kroah-HartmanFrom: Nikos Tsironis <[email protected]>
commit 81d5553d1288c2ec0390f02f84d71ca0f0f9f137 upstream.
dm_clone_nr_of_hydrated_regions() returns the number of regions that have been hydrated so far. In order to do so it employs bitmap_weight().
Until now, the return type of dm_clone_nr_of_hydrated_regions() was unsigned long.
Because bitmap_weight() returns an int, in case BITS_PER_LONG == 64 and the return value of bitmap_weight() is 2^31 (the maximum allowed number of regions for a device), the result is sign extended from 32 bits to 64 bits and an incorrect value is displayed, in the status output of dm-clone, as the number of hydrated regions.
Fix this by having dm_clone_nr_of_hydrated_regions() return an unsigned int.
--- drivers/md/dm-clone-metadata.c | 2 +- drivers/md/dm-clone-metadata.h | 2 +- drivers/md/dm-clone-target.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/md/dm-clone-metadata.c +1 -1
@@ -656,7 +656,7 @@ bool dm_clone_is_range_hydrated(struct dreturn (bit >= (start + nr_regions)); } -unsigned long dm_clone_nr_of_hydrated_regions (struct dm_clone_metadata *cmd) +unsigned int dm_clone_nr_of_hydrated_regions (struct dm_clone_metadata *cmd) {return bitmap_weight (cmd->region_map, cmd->nr_regions); }
drivers/md/dm-clone-metadata.h +1 -1
@@ -154,7 +154,7 @@ bool dm_clone_is_range_hydrated(struct d/* * Returns the number of hydrated regions. */ -unsigned long dm_clone_nr_of_hydrated_regions (struct dm_clone_metadata *cmd); +unsigned int dm_clone_nr_of_hydrated_regions (struct dm_clone_metadata *cmd);/* * Returns the first unhydrated region with region_nr >= @start
drivers/md/dm-clone-target.c +1 -1
@@ -1455,7 +1455,7 @@ static void clone_status(struct dm_targe goto error; } - DMEMIT("%u %llu/%llu %llu %lu/%lu %u ", + DMEMIT("%u %llu/%llu %llu %u/%lu %u ", DM_CLONE_METADATA_BLOCK_SIZE, (unsigned long long)(nr_metadata_blocks - nr_free_metadata_blocks), (unsigned long long)nr_metadata_blocks,
Greg Kroah-Hartman
maintainerPATCH 166/232 XArray: Fix xas_pause for large multi-index entries
In reply to Greg Kroah-HartmanFrom: Matthew Wilcox (Oracle) <[email protected]>
commit c36d451ad386b34f452fc3c8621ff14b9eaa31a6 upstream.
Inspired by the recent Coverity report, I looked for other places where the offset wasn't being converted to an unsigned long before being shifted, and I found one in xas_pause() when the entry being paused is of order >32.
--- lib/test_xarray.c | 37 +++++++++++++++++++++++++++++++++++++ lib/xarray.c | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-)
lib/test_xarray.c +37 -0
@@ -1156,6 +1156,42 @@ static noinline void check_find_entry(stXA_BUG_ON (xa, !xa_empty (xa)); } +static noinline void check_pause(struct xarray *xa) +{ +XA_STATE (xas, xa,0 ); +void *entry; +unsigned int order; +unsigned long index =1 ; +unsigned int count =0 ; + +for (order =0 ; order < order_limit; order++) { +XA_BUG_ON (xa,xa_store_order (xa, index, order, +xa_mk_index (index),GFP_KERNEL )); + index +=1UL << order; + } + +rcu_read_lock (); +xas_for_each (&xas, entry,ULONG_MAX ) { +XA_BUG_ON (xa, entry !=xa_mk_index (1UL << count)); + count++; + } +rcu_read_unlock (); +XA_BUG_ON (xa, count != order_limit); + + count =0 ; +xas_set (&xas,0 ); +rcu_read_lock (); +xas_for_each (&xas, entry,ULONG_MAX ) { +XA_BUG_ON (xa, entry !=xa_mk_index (1UL << count)); + count++; +xas_pause (&xas); + } +rcu_read_unlock (); +XA_BUG_ON (xa, count != order_limit); + +xa_destroy (xa); +} + static noinline void check_move_tiny(struct xarray *xa) {XA_STATE (xas, xa,0 );
@@ -1664,6 +1700,7 @@ static int xarray_checks(void)check_xa_alloc ();check_find (&array);check_find_entry (&array); +check_pause (&array);check_account (&array);check_destroy (&array);check_move (&array);
lib/xarray.c +1 -1
@@ -970,7 +970,7 @@ void xas_pause(struct xa_state *xas) xas->xa_node =XAS_RESTART ;if (node) { -unsigned int offset = xas->xa_offset; +unsigned long offset = xas->xa_offset;while (++offset <XA_CHUNK_SIZE ) {if (!xa_is_sibling (xa_entry (xas->xa, node, offset)))break ;
Greg Kroah-Hartman
maintainerPATCH 167/232 xarray: Fix early termination of xas_for_each_marked
In reply to Greg Kroah-HartmanFrom: Matthew Wilcox (Oracle) <[email protected]>
commit 7e934cf5ace1dceeb804f7493fa28bb697ed3c52 upstream.
xas_for_each_marked() is using entry == NULL as a termination condition of the iteration. When xas_for_each_marked() is used protected only by RCU, this can however race with xas_store(xas, NULL) in the following way:
TASK1 TASK2page_cache_delete() find_get_pages_range_tag()
xas_for_each_marked()
xas_find_marked()
off = xas_find_chunk()
xas_store(&xas, NULL)
xas_init_marks(&xas);
...
rcu_assign_pointer(*slot, NULL);
entry = xa_entry(off);And thus xas_for_each_marked() terminates prematurely possibly leading to missed entries in the iteration (translating to missing writeback of some pages or a similar problem).
If we find a NULL entry that has been marked, skip it (unless we're trying to allocate an entry).
--- include/linux/xarray.h | 6 + lib/xarray.c | 2 tools/testing/radix-tree/Makefile | 4 - tools/testing/radix-tree/iteration_check_2.c | 87 +++++++++++++++++++++++++++ tools/testing/radix-tree/main.c | 1 tools/testing/radix-tree/test.h | 1 6 files changed, 98 insertions(+), 3 deletions(-)
include/linux/xarray.h +5 -1
@@ -1613,6 +1613,7 @@ static inline void *xas_next_marked(stru xa_mark_t mark) {struct xa_node *node = xas->xa_node; +void *entry;unsigned int offset;if (unlikely (xas_not_node (node) || node->shift))
@@ -1624,7 +1625,10 @@ static inline void *xas_next_marked(strureturn NULL ;if (offset ==XA_CHUNK_SIZE )return xas_find_marked (xas, max, mark); -return xa_entry (xas->xa, node, offset); + entry =xa_entry (xas->xa, node, offset); +if (!entry) +return xas_find_marked (xas, max, mark); +return entry; }/*
lib/xarray.c +2 -0
@@ -1208,6 +1208,8 @@ void *xas_find_marked(struct xa_state *x } entry =xa_entry (xas->xa, xas->xa_node, xas->xa_offset); +if (!entry && !(xa_track_free (xas->xa) && mark ==XA_FREE_MARK )) +continue ;if (!xa_is_node (entry))return entry; xas->xa_node =xa_to_node (entry);
tools/testing/radix-tree/Makefile +2 -2
@@ -7,8 +7,8 @@ LDLIBS+= -lpthread -lurcu TARGETS = main idr-test multiorder xarray CORE_OFILES := xarray.o radix-tree.o idr.o linux.o test.o find_bit.o bitmap.o OFILES = main.o $(CORE_OFILES) regression1.o regression2.o regression3.o \ - regression4.o \ - tag_check.o multiorder.o idr-test.o iteration_check.o benchmark.o + regression4.o tag_check.o multiorder.o idr-test.o iteration_check.o \ + iteration_check_2.o benchmark.o ifndef SHIFT SHIFT=3
tools/testing/radix-tree/iteration_check_2.c new file +87 -0
87 lines not on this page · raw message
tools/testing/radix-tree/main.c +1 -0
@@ -311,6 +311,7 @@ int main(int argc, char **argv)regression4_test ();iteration_test (0 ,10 +90 * long_run);iteration_test (7 ,10 +90 * long_run); +iteration_test2 (10 +90 * long_run);single_thread_tests (long_run);/* Free any remaining preallocated nodes */
tools/testing/radix-tree/test.h +1 -0
@@ -34,6 +34,7 @@ void xarray_tests(void);void tag_check (void );void multiorder_checks (void );void iteration_test (unsigned order,unsigned duration); +void iteration_test2 (unsigned duration);void benchmark (void );void idr_checks (void );void ida_tests (void );
Greg Kroah-Hartman
maintainerPATCH 168/232 crypto: caam/qi2 - fix chacha20 data size error
In reply to Greg Kroah-HartmanFrom: Horia Geantă <[email protected]>
commit 3a5a9e1ef37b030b836d92df8264f840988f4a38 upstream.
HW generates a Data Size error for chacha20 requests that are not a multiple of 64B, since algorithm state (AS) does not have the FINAL bit set.
Since updating req->iv (for chaining) is not required, modify skcipher descriptors to set the FINAL bit for chacha20.
[Note that for skcipher decryption we know that ctx1_iv_off is 0, which allows for an optimization by not checking algorithm type, since append_dec_op1() sets FINAL bit for all algorithms except AES.]
Also drop the descriptor operations that save the IV. However, in order to keep code logic simple, things like S/G tables generation etc. are not touched.
--- drivers/crypto/caam/caamalg_desc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/crypto/caam/caamalg_desc.c +10 -4
@@ -1379,6 +1379,9 @@ void cnstr_shdsc_skcipher_encap(u32 * co const u32 ctx1_iv_off) {u32 *key_jump_cmd; +u32 options = cdata->algtype |OP_ALG_AS_INIT |OP_ALG_ENCRYPT ; +bool is_chacha20 = ((cdata->algtype &OP_ALG_ALGSEL_MASK ) == +OP_ALG_ALGSEL_CHACHA20 );init_sh_desc (desc,HDR_SHARE_SERIAL |HDR_SAVECTX );/* Skip if already shared */
@@ -1417,14 +1420,15 @@ void cnstr_shdsc_skcipher_encap(u32 * co LDST_OFFSET_SHIFT));/* Load operation */ -append_operation (desc, cdata->algtype |OP_ALG_AS_INIT | -OP_ALG_ENCRYPT ); +if (is_chacha20) + options |=OP_ALG_AS_FINALIZE ; +append_operation (desc, options);/* Perform operation */ skcipher_append_src_dst (desc);/* Store IV */ -if (ivsize) +if (!is_chacha20 && ivsize)append_seq_store (desc, ivsize,LDST_SRCDST_BYTE_CONTEXT |LDST_CLASS_1_CCB | (ctx1_iv_off <<LDST_OFFSET_SHIFT ));
@@ -1451,6 +1455,8 @@ void cnstr_shdsc_skcipher_decap(u32 * co const u32 ctx1_iv_off) {u32 *key_jump_cmd; +bool is_chacha20 = ((cdata->algtype &OP_ALG_ALGSEL_MASK ) == +OP_ALG_ALGSEL_CHACHA20 );init_sh_desc (desc,HDR_SHARE_SERIAL |HDR_SAVECTX );/* Skip if already shared */
@@ -1499,7 +1505,7 @@ void cnstr_shdsc_skcipher_decap(u32 * coskcipher_append_src_dst (desc);/* Store IV */ -if (ivsize) +if (!is_chacha20 && ivsize)append_seq_store (desc, ivsize,LDST_SRCDST_BYTE_CONTEXT |LDST_CLASS_1_CCB | (ctx1_iv_off <<LDST_OFFSET_SHIFT ));
Greg Kroah-Hartman
maintainerPATCH 169/232 crypto: caam - update xts sector size for large input length
In reply to Greg Kroah-HartmanFrom: Andrei Botila <[email protected]>
commit 3f142b6a7b573bde6cff926f246da05652c61eb4 upstream.
Since in the software implementation of XTS-AES there is no notion of sector every input length is processed the same way. CAAM implementation has the notion of sector which causes different results between the software implementation and the one in CAAM for input lengths bigger than 512 bytes.
Increase sector size to maximum value on 16 bits.
--- drivers/crypto/caam/caamalg_desc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
drivers/crypto/caam/caamalg_desc.c +14 -2
@@ -1524,7 +1524,13 @@ EXPORT_SYMBOL(cnstr_shdsc_skcipher_decap*/ void cnstr_shdsc_xts_skcipher_encap (u32 *const desc,struct alginfo *cdata) { -__be64 sector_size =cpu_to_be64 (512 ); +/* +* Set sector size to a big value, practically disabling +* sector size segmentation in xts implementation. We cannot +* take full advantage of this HW feature with existing +* crypto API / dm-crypt SW architecture. +*/ +__be64 sector_size =cpu_to_be64 (BIT (15 ));u32 *key_jump_cmd;init_sh_desc (desc,HDR_SHARE_SERIAL |HDR_SAVECTX );
@@ -1577,7 +1583,13 @@ EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_e*/ void cnstr_shdsc_xts_skcipher_decap (u32 *const desc,struct alginfo *cdata) { -__be64 sector_size =cpu_to_be64 (512 ); +/* +* Set sector size to a big value, practically disabling +* sector size segmentation in xts implementation. We cannot +* take full advantage of this HW feature with existing +* crypto API / dm-crypt SW architecture. +*/ +__be64 sector_size =cpu_to_be64 (BIT (15 ));u32 *key_jump_cmd;init_sh_desc (desc,HDR_SHARE_SERIAL |HDR_SAVECTX );
Greg Kroah-Hartman
maintainerPATCH 170/232 crypto: ccree - protect against empty or NULL scatterlists
In reply to Greg Kroah-HartmanFrom: Gilad Ben-Yossef <[email protected]>
commit ce0fc6db38decf0d2919bfe783de6d6b76e421a9 upstream.
Deal gracefully with a NULL or empty scatterlist which can happen if both cryptlen and assoclen are zero and we're doing in-place AEAD encryption.
This fixes a crash when this causes us to try and map a NULL page, at least with some platforms / DMA mapping configs.
--- drivers/crypto/ccree/cc_buffer_mgr.c | 62 +++++++++++++++-------------------- drivers/crypto/ccree/cc_buffer_mgr.h | 1 2 files changed, 28 insertions(+), 35 deletions(-)
drivers/crypto/ccree/cc_buffer_mgr.c +27 -35
@@ -87,6 +87,8 @@ static unsigned int cc_get_sgl_nents(str {unsigned int nents =0 ; + *lbytes =0 ; +while (nbytes && sg_list) { nents++;/* get the number of bytes in the last entry */
@@ -95,6 +97,7 @@ static unsigned int cc_get_sgl_nents(str nbytes : sg_list->length; sg_list =sg_next (sg_list); } +dev_dbg (dev,"nents %d last bytes %d\n" , nents, *lbytes);return nents; }
@@ -290,37 +293,25 @@ static int cc_map_sg(struct device *dev, unsigned int nbytes, int direction, u32 *nents, u32 max_sg_nents, u32 *lbytes, u32 *mapped_nents) { - if (sg_is_last(sg)) { - /* One entry only case -set to DLLI */ - if (dma_map_sg(dev, sg, 1, direction) != 1) { - dev_err(dev, "dma_map_sg() single buffer failed\n"); -return -ENOMEM ; - } -dev_dbg (dev,"Mapped sg: dma_address=%pad page=%p addr=%pK offset=%u length=%u\n" , - &sg_dma_address (sg),sg_page (sg),sg_virt (sg), - sg->offset, sg->length); - *lbytes = nbytes; - *nents =1 ; - *mapped_nents =1 ; - } else { /*sg_is_last*/ - *nents =cc_get_sgl_nents (dev, sg, nbytes, lbytes); -if (*nents > max_sg_nents) { - *nents =0 ; -dev_err (dev,"Too many fragments. current %d max %d\n" , - *nents, max_sg_nents); -return -ENOMEM ; - } -/* In case of mmu the number of mapped nents might -* be changed from the original sgl nents -*/ - *mapped_nents =dma_map_sg (dev, sg, *nents, direction); -if (*mapped_nents ==0 ) { - *nents =0 ; -dev_err (dev,"dma_map_sg() sg buffer failed\n" ); -return -ENOMEM ; - } + int ret = 0; + + *nents =cc_get_sgl_nents (dev, sg, nbytes, lbytes); +if (*nents > max_sg_nents) { + *nents =0 ; +dev_err (dev,"Too many fragments. current %d max %d\n" , + *nents, max_sg_nents); +return -ENOMEM ; } + ret =dma_map_sg (dev, sg, *nents, direction); +if (dma_mapping_error (dev, ret)) { + *nents =0 ; +dev_err (dev,"dma_map_sg() sg buffer failed %d\n" , ret); +return -ENOMEM ; + } + + *mapped_nents = ret; +return 0 ; }
@@ -555,11 +546,12 @@ void cc_unmap_aead_request(struct devicesg_virt (req->src), areq_ctx->src.nents, areq_ctx->assoc.nents, areq_ctx->assoclen, req->cryptlen); -dma_unmap_sg (dev, req->src,sg_nents (req->src),DMA_BIDIRECTIONAL ); +dma_unmap_sg (dev, req->src, areq_ctx->src.mapped_nents, +DMA_BIDIRECTIONAL );if (req->src != req->dst) {dev_dbg (dev,"Unmapping dst sgl: req->dst=%pK\n" ,sg_virt (req->dst)); -dma_unmap_sg (dev, req->dst,sg_nents (req->dst), +dma_unmap_sg (dev, req->dst, areq_ctx->dst.mapped_nents,DMA_BIDIRECTIONAL ); } if (drvdata->coherent &&
@@ -881,7 +873,7 @@ static int cc_aead_chain_data(struct cc_ &src_last_bytes); sg_index = areq_ctx->src_sgl->length;//check where the data starts -while (sg_index <= size_to_skip) { +while (src_mapped_nents && (sg_index <= size_to_skip)) { src_mapped_nents--; offset -= areq_ctx->src_sgl->length; sgl =sg_next (areq_ctx->src_sgl);
@@ -908,7 +900,7 @@ static int cc_aead_chain_data(struct cc_ size_for_map +=crypto_aead_ivsize (tfm); rc =cc_map_sg (dev, req->dst, size_for_map,DMA_BIDIRECTIONAL , - &areq_ctx->dst.nents, + &areq_ctx->dst.mapped_nents,LLI_MAX_NUM_OF_DATA_ENTRIES , &dst_last_bytes, &dst_mapped_nents);if (rc)
@@ -921,7 +913,7 @@ static int cc_aead_chain_data(struct cc_ offset = size_to_skip;//check where the data starts -while (sg_index <= size_to_skip) { +while (dst_mapped_nents && sg_index <= size_to_skip) { dst_mapped_nents--; offset -= areq_ctx->dst_sgl->length; sgl =sg_next (areq_ctx->dst_sgl);
@@ -1123,7 +1115,7 @@ int cc_map_aead_request(struct cc_drvdatif (is_gcm4543) size_to_map +=crypto_aead_ivsize (tfm); rc =cc_map_sg (dev, req->src, size_to_map,DMA_BIDIRECTIONAL , - &areq_ctx->src.nents, + &areq_ctx->src.mapped_nents, (LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES +LLI_MAX_NUM_OF_DATA_ENTRIES ), &dummy, &mapped_nents);
drivers/crypto/ccree/cc_buffer_mgr.h +1 -0
@@ -25,6 +25,7 @@ enum cc_sg_cpy_direct {struct cc_mlli {cc_sram_addr_t sram_addr; +unsigned int mapped_nents;unsigned int nents;//sg nents unsigned int mlli_nents;//mlli nents might be different than the above };
Greg Kroah-Hartman
maintainerPATCH 171/232 crypto: ccree - only try to map auth tag if needed
In reply to Greg Kroah-HartmanFrom: Gilad Ben-Yossef <[email protected]>
commit 504e84abec7a635b861afd8d7f92ecd13eaa2b09 upstream.
Make sure to only add the size of the auth tag to the source mapping for encryption if it is an in-place operation. Failing to do this previously caused us to try and map auth size len bytes from a NULL mapping and crashing if both the cryptlen and assoclen are zero.
--- drivers/crypto/ccree/cc_buffer_mgr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/crypto/ccree/cc_buffer_mgr.c +4 -2
@@ -1109,9 +1109,11 @@ int cc_map_aead_request(struct cc_drvdat } size_to_map = req->cryptlen + areq_ctx->assoclen; -if (areq_ctx->gen_ctx.op_type ==DRV_CRYPTO_DIRECTION_ENCRYPT ) +/* If we do in-place encryption, we also need the auth tag */ +if ((areq_ctx->gen_ctx.op_type ==DRV_CRYPTO_DIRECTION_ENCRYPT ) && + (req->src == req->dst)) { size_to_map += authsize; - + }if (is_gcm4543) size_to_map +=crypto_aead_ivsize (tfm); rc = cc_map_sg(dev, req->src, size_to_map, DMA_BIDIRECTIONAL,
Greg Kroah-Hartman
maintainerPATCH 172/232 crypto: ccree - dec auth tag size from cryptlen map
In reply to Greg Kroah-HartmanFrom: Gilad Ben-Yossef <[email protected]>
commit 8962c6d2c2b8ca51b0f188109015b15fc5f4da44 upstream.
Remove the auth tag size from cryptlen before mapping the destination in out-of-place AEAD decryption thus resolving a crash with extended testmgr tests.
--- drivers/crypto/ccree/cc_buffer_mgr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/crypto/ccree/cc_buffer_mgr.c +6 -2
@@ -894,8 +894,12 @@ static int cc_aead_chain_data(struct cc_if (req->src != req->dst) { size_for_map = areq_ctx->assoclen + req->cryptlen; - size_for_map += (direct ==DRV_CRYPTO_DIRECTION_ENCRYPT ) ? - authsize :0 ; + +if (direct ==DRV_CRYPTO_DIRECTION_ENCRYPT ) + size_for_map += authsize; +else + size_for_map -= authsize; +if (is_gcm4543) size_for_map +=crypto_aead_ivsize (tfm);
Greg Kroah-Hartman
maintainerPATCH 173/232 scsi: zfcp: fix missing erp_lock in port recovery trigger for point-to-point
In reply to Greg Kroah-HartmanFrom: Steffen Maier <[email protected]>
commit 819732be9fea728623e1ed84eba28def7384ad1f upstream.
v2.6.27 commit cc8c282963bd ("[SCSI] zfcp: Automatically attach remote ports") introduced zfcp automatic port scan.
Before that, the user had to use the sysfs attribute "port_add" of an FCP device (adapter) to add and open remote (target) ports, even for the remote peer port in point-to-point topology. That code path did a proper port open recovery trigger taking the erp_lock.
Since above commit, a new helper function zfcp_erp_open_ptp_port() performed an UNlocked port open recovery trigger. This can race with other parallel recovery triggers. In zfcp_erp_action_enqueue() this could corrupt e.g. adapter->erp_total_count or adapter->erp_ready_head.
As already found for fabric topology in v4.17 commit fa89adba1941 ("scsi:
zfcp: fix infinite iteration on ERP ready list"), there was an endless loop during tracing of rport (un)block. A subsequent v4.18 commit 9e156c54ace3 ("scsi: zfcp: assert that the ERP lock is held when tracing a recovery trigger") introduced a lockdep assertion for that case.
As a side effect, that lockdep assertion now uncovered the unlocked code path for PtP. It is from within an adapter ERP action:
zfcp_erp_strategy[1479] intentionally DROPs erp lock around
zfcp_erp_strategy_do_action()
zfcp_erp_strategy_do_action[1441] NO erp lock zfcp_erp_adapter_strategy[876] NO erp lock zfcp_erp_adapter_strategy_open[855] NO erp lock
zfcp_erp_adapter_strategy_open_fsf[806]NO erp lock zfcp_erp_adapter_strat_fsf_xconf[772] erp lock only around
zfcp_erp_action_to_running(), BUT *_not_* around zfcp_erp_enqueue_ptp_port()
zfcp_erp_enqueue_ptp_port[728] BUG: *_not_* taking erp lock _zfcp_erp_port_reopen[432] assumes to be called with erp lock zfcp_erp_action_enqueue[314] assumes to be called with erp lock zfcp_dbf_rec_trig[288] _checks_ to be called with erp lock: lockdep_assert_held(&adapter->erp_lock);
It causes the following lockdep warning:
WARNING: CPU: 2 PID: 775 at drivers/s390/scsi/zfcp_dbf.c:288
zfcp_dbf_rec_trig+0x16a/0x188
no locks held by zfcperp0.0.17c0/775.Fix this by using the proper locked recovery trigger helper function.
--- drivers/s390/scsi/zfcp_erp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/scsi/zfcp_erp.c +1 -1
@@ -725,7 +725,7 @@ static void zfcp_erp_enqueue_ptp_port(st adapter->peer_d_id);if (IS_ERR (port))/* error or port already attached */ return ; -_zfcp_erp_port_reopen (port,0 ,"ereptp1" ); +zfcp_erp_port_reopen (port,0 ,"ereptp1" ); } static enum zfcp_erp_act_result zfcp_erp_adapter_strat_fsf_xconf(
Greg Kroah-Hartman
maintainerPATCH 174/232 scsi: ufs: fix Auto-Hibern8 error detection
In reply to Greg Kroah-HartmanFrom: Stanley Chu <[email protected]>
commit 5a244e0ea67b293abb1d26c825db2ddde5f2862f upstream.
Auto-Hibern8 may be disabled by some vendors or sysfs in runtime even if Auto-Hibern8 capability is supported by host. If Auto-Hibern8 capability is supported by host but not actually enabled, Auto-Hibern8 error shall not happen.
To fix this, provide a way to detect if Auto-Hibern8 is actually enabled first, and bypass Auto-Hibern8 disabling case in ufshcd_is_auto_hibern8_error().
--- drivers/scsi/ufs/ufshcd.c | 3 ++- drivers/scsi/ufs/ufshcd.h | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/scsi/ufs/ufshcd.c +2 -1
@@ -5467,7 +5467,8 @@ static void ufshcd_update_uic_error(strustatic bool ufshcd_is_auto_hibern8_error (struct ufs_hba *hba,u32 intr_mask) { -if (!ufshcd_is_auto_hibern8_supported (hba)) +if (!ufshcd_is_auto_hibern8_supported (hba) || + !ufshcd_is_auto_hibern8_enabled (hba))return false;if (!(intr_mask &UFSHCD_UIC_HIBERN8_MASK ))
drivers/scsi/ufs/ufshcd.h +6 -0
@@ -55,6 +55,7 @@#include <linux/clk.h> #include <linux/completion.h> #include <linux/regulator/consumer.h> +#include <linux/bitfield.h> #include "unipro.h" #include <asm/irq.h>
@@ -771,6 +772,11 @@ static inline bool ufshcd_is_auto_hibernreturn (hba->capabilities &MASK_AUTO_HIBERN8_SUPPORT ); } +static inline bool ufshcd_is_auto_hibern8_enabled (struct ufs_hba *hba) +{ +return FIELD_GET (UFSHCI_AHIBERN8_TIMER_MASK , hba->ahit) ? true : false; +} +#define ufshcd_writel (hba, val, reg) \ writel((val), (hba)->mmio_base + (reg))#define ufshcd_readl (hba, reg) \
Greg Kroah-Hartman
maintainerPATCH 175/232 scsi: lpfc: Fix lpfc_io_buf resource leak in lpfc_get_scsi_buf_s4 error path
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
commit 0ab384a49c548baf132ccef249f78d9c6c506380 upstream.
If a call to lpfc_get_cmd_rsp_buf_per_hdwq returns NULL (memory allocation failure), a previously allocated lpfc_io_buf resource is leaked.
Fix by releasing the lpfc_io_buf resource in the failure path.
--- drivers/scsi/lpfc/lpfc_scsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_scsi.c +3 -1
@@ -671,8 +671,10 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *ph lpfc_cmd->prot_data_type =0 ;#endif tmp =lpfc_get_cmd_rsp_buf_per_hdwq (phba, lpfc_cmd); -if (!tmp) +if (!tmp) { +lpfc_release_io_buf (phba, lpfc_cmd, lpfc_cmd->hdwq);return NULL ; + } lpfc_cmd->fcp_cmnd = tmp->fcp_cmnd; lpfc_cmd->fcp_rsp = tmp->fcp_rsp;
Greg Kroah-Hartman
maintainerPATCH 176/232 ARM: dts: exynos: Fix polarity of the LCD SPI bus on UniversalC210 board
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
commit 32a1671ff8e84f0dfff3a50d4b2091d25e91f5e2 upstream.
Recent changes in the SPI core and the SPI-GPIO driver revealed that the GPIO lines for the LD9040 LCD controller on the UniversalC210 board are defined incorrectly. Fix the polarity for those lines to match the old behavior and hardware requirements to fix LCD panel operation with recent kernels.
--- arch/arm/boot/dts/exynos4210-universal_c210.dts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
arch/arm/boot/dts/exynos4210-universal_c210.dts +1 -3
@@ -115,7 +115,7 @@ gpio-sck = <&gpy3 1 GPIO_ACTIVE_HIGH>; gpio-mosi = <&gpy3 3 GPIO_ACTIVE_HIGH>; num-chipselects = <1>; - cs-gpios = <&gpy4 3 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpy4 3 GPIO_ACTIVE_LOW>; lcd@0 { compatible = "samsung,ld9040";
@@ -124,8 +124,6 @@ vci-supply = <&ldo17_reg>; reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>; spi-max-frequency = <1200000>; - spi-cpol; - spi-cpha; power-on-delay = <10>; reset-delay = <10>; panel-width-mm = <90>;
Greg Kroah-Hartman
maintainerPATCH 177/232 arm64: dts: ti: k3-am65: Add clocks to dwc3 nodes
In reply to Greg Kroah-HartmanFrom: Dave Gerlach <[email protected]>
commit a81e5442d796ccfa2cc97d205a5477053264d978 upstream.
The TI sci-clk driver can scan the DT for all clocks provided by system firmware and does this by checking the clocks property of all nodes, so we must add this to the dwc3 nodes so USB clocks are available.
Without this USB does not work with latest system firmware i.e.
[ 1.714662] clk: couldn't get parent clock 0 for /interconnect@100000/dwc3@4020000
--- arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/ti/k3-am65-main.dtsi +2 -0
@@ -307,6 +307,7 @@ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; dma-coherent; power-domains = <&k3_pds 151 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 151 2>, <&k3_clks 151 7>; assigned-clocks = <&k3_clks 151 2>, <&k3_clks 151 7>; assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */ <&k3_clks 151 9>; /* set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */
@@ -346,6 +347,7 @@ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; dma-coherent; power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 152 2>; assigned-clocks = <&k3_clks 152 2>; assigned-clock-parents = <&k3_clks 152 4>; /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
Greg Kroah-Hartman
maintainerPATCH 178/232 arm64: armv8_deprecated: Fix undef_hook mask for thumb setend
In reply to Greg Kroah-HartmanFrom: Fredrik Strupe <[email protected]>
commit fc2266011accd5aeb8ebc335c381991f20e26e33 upstream.
For thumb instructions, call_undef_hook() in traps.c first reads a u16, and if the u16 indicates a T32 instruction (u16 >= 0xe800), a second u16 is read, which then makes up the the lower half-word of a T32 instruction. For T16 instructions, the second u16 is not read, which makes the resulting u32 opcode always have the upper half set to 0.
However, having the upper half of instr_mask in the undef_hook set to 0 masks out the upper half of all thumb instructions - both T16 and T32. This results in trapped T32 instructions with the lower half-word equal to the T16 encoding of setend (b650) being matched, even though the upper half-word is not 0000 and thus indicates a T32 opcode.
An example of such a T32 instruction is eaa0b650, which should raise a SIGILL since T32 instructions with an eaa prefix are unallocated as per Arm ARM, but instead works as a SETEND because the second half-word is set to b650.
This patch fixes the issue by extending instr_mask to include the upper u32 half, which will still match T16 instructions where the upper half is 0, but not T32 instructions.
--- arch/arm64/kernel/armv8_deprecated.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/armv8_deprecated.c +1 -1
@@ -601,7 +601,7 @@ static struct undef_hook setend_hooks[] }, {/* Thumb mode */ - .instr_mask = 0x0000fff7, + .instr_mask = 0xfffffff7, .instr_val = 0x0000b650, .pstate_mask = (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK), .pstate_val = (PSR_AA32_T_BIT | PSR_AA32_MODE_USR),
Greg Kroah-Hartman
maintainerPATCH 179/232 selftests: vm: drop dependencies on page flags from mlock2 tests
In reply to Greg Kroah-HartmanFrom: Michal Hocko <[email protected]>
commit eea274d64e6ea8aff2224d33d0851133a84cc7b5 upstream.
It was noticed that mlock2 tests are failing after 9c4e6b1a7027f ("mm, mlock, vmscan: no more skipping pagevecs") because the patch has changed the timing on when the page is added to the unevictable LRU list and thus gains the unevictable page flag.
The test was just too dependent on the implementation details which were true at the time when it was introduced. Page flags and the timing when they are set is something no userspace should ever depend on. The test should be testing only for the user observable contract of the tested syscalls. Those are defined pretty well for the mlock and there are other means for testing them. In fact this is already done and testing for page flags can be safely dropped to achieve the aimed purpose. Present bits can be checked by /proc/<pid>/smaps RSS field and the locking state by VmFlags although I would argue that Locked: field would be more appropriate.
Drop all the page flag machinery and considerably simplify the test. This should be more robust for future kernel changes while checking the promised contract is still valid.
--- tools/testing/selftests/vm/mlock2-tests.c | 233 ++++-------------------------- 1 file changed, 37 insertions(+), 196 deletions(-)
tools/testing/selftests/vm/mlock2-tests.c +37 -196
@@ -67,59 +67,6 @@ out:return ret; } -static uint64_t get_pageflags (unsigned long addr) -{ -FILE *file; -uint64_t pfn; -unsigned long offset; - - file =fopen ("/proc/self/pagemap" ,"r" ); -if (!file) { -perror ("fopen pagemap" ); -_exit (1 ); - } - - offset = addr /getpagesize () *sizeof (pfn); - -if (fseek (file, offset,SEEK_SET )) { -perror ("fseek pagemap" ); -_exit (1 ); - } - -if (fread (&pfn,sizeof (pfn),1 , file) !=1 ) { -perror ("fread pagemap" ); -_exit (1 ); - } - -fclose (file); -return pfn; -} - -static uint64_t get_kpageflags (unsigned long pfn) -{ -uint64_t flags; -FILE *file; - - file =fopen ("/proc/kpageflags" ,"r" ); -if (!file) { -perror ("fopen kpageflags" ); -_exit (1 ); - } - -if (fseek (file, pfn *sizeof (flags),SEEK_SET )) { -perror ("fseek kpageflags" ); -_exit (1 ); - } - -if (fread (&flags,sizeof (flags),1 , file) !=1 ) { -perror ("fread kpageflags" ); -_exit (1 ); - } - -fclose (file); -return flags; -} -#define VMFLAGS "VmFlags:"static bool is_vmflag_set (unsigned long addr,const char *vmflag)
@@ -159,19 +106,13 @@ out:#define RSS "Rss:"#define LOCKED "lo" -static bool is_vma_lock_on_fault (unsigned long addr) +static unsigned long get_value_for_name (unsigned long addr,const char *name) { -bool ret = false; -bool locked; -FILE *smaps =NULL ; -unsigned long vma_size, vma_rss;char *line =NULL ; -char *value;size_t size =0 ; - - locked =is_vmflag_set (addr,LOCKED ); -if (!locked) - goto out; +char *value_ptr; +FILE *smaps =NULL ; +unsigned long value =-1UL ; smaps =seek_to_smaps_entry (addr);if (!smaps) {
@@ -180,112 +121,70 @@ static bool is_vma_lock_on_fault(unsigne }while (getline (&line, &size, smaps) >0 ) { -if (!strstr (line,SIZE )) { +if (!strstr (line, name)) {free (line); line =NULL ; size =0 ;continue ; } - value = line +strlen (SIZE ); -if (sscanf (value,"%lu kB" , &vma_size) <1 ) { + value_ptr = line +strlen (name); +if (sscanf (value_ptr,"%lu kB" , &value) <1 ) {printf ("Unable to parse smaps entry for Size\n" ); goto out; }break ; } -while (getline (&line, &size, smaps) >0 ) { -if (!strstr (line,RSS )) { -free (line); - line =NULL ; - size =0 ; -continue ; - } - - value = line +strlen (RSS ); -if (sscanf (value,"%lu kB" , &vma_rss) <1 ) { -printf ("Unable to parse smaps entry for Rss\n" ); - goto out; - } -break ; - } - - ret = locked && (vma_rss < vma_size); out: -free (line);if (smaps)fclose (smaps); -return ret; +free (line); +return value; } -#define PRESENT_BIT 0x8000000000000000ULL -#define PFN_MASK 0x007FFFFFFFFFFFFFULL -#define UNEVICTABLE_BIT (1UL << 18) - -static int lock_check (char *map) +static bool is_vma_lock_on_fault (unsigned long addr) { -unsigned long page_size =getpagesize (); -uint64_t page1_flags, page2_flags; +bool locked; +unsigned long vma_size, vma_rss; + + locked =is_vmflag_set (addr,LOCKED ); +if (!locked) +return false; - page1_flags =get_pageflags ((unsigned long )map); - page2_flags =get_pageflags ((unsigned long )map + page_size); + vma_size =get_value_for_name (addr,SIZE ); + vma_rss =get_value_for_name (addr,RSS ); -/* Both pages should be present */ -if (((page1_flags &PRESENT_BIT ) ==0 ) || - ((page2_flags &PRESENT_BIT ) ==0 )) { -printf ("Failed to make both pages present\n" ); -return 1 ; - } +/* only one page is faulted in */ +return (vma_rss < vma_size); +} - page1_flags =get_kpageflags (page1_flags &PFN_MASK ); - page2_flags =get_kpageflags (page2_flags &PFN_MASK ); +#define PRESENT_BIT 0x8000000000000000ULL +#define PFN_MASK 0x007FFFFFFFFFFFFFULL +#define UNEVICTABLE_BIT (1UL << 18) -/* Both pages should be unevictable */ -if (((page1_flags &UNEVICTABLE_BIT ) ==0 ) || - ((page2_flags &UNEVICTABLE_BIT ) ==0 )) { -printf ("Failed to make both pages unevictable\n" ); -return 1 ; - } +static int lock_check (unsigned long addr) +{ +bool locked; +unsigned long vma_size, vma_rss; -if (!is_vmflag_set ((unsigned long )map,LOCKED )) { -printf ("VMA flag %s is missing on page 1\n" ,LOCKED ); -return 1 ; - } + locked =is_vmflag_set (addr,LOCKED ); +if (!locked) +return false; -if (!is_vmflag_set ((unsigned long )map + page_size,LOCKED )) { -printf ("VMA flag %s is missing on page 2\n" ,LOCKED ); -return 1 ; - } + vma_size =get_value_for_name (addr,SIZE ); + vma_rss =get_value_for_name (addr,RSS ); -return 0 ; +return (vma_rss == vma_size); }static int unlock_lock_check (char *map) { -unsigned long page_size =getpagesize (); -uint64_t page1_flags, page2_flags; - - page1_flags =get_pageflags ((unsigned long )map); - page2_flags =get_pageflags ((unsigned long )map + page_size); - page1_flags =get_kpageflags (page1_flags &PFN_MASK ); - page2_flags =get_kpageflags (page2_flags &PFN_MASK ); - -if ((page1_flags &UNEVICTABLE_BIT ) || (page2_flags &UNEVICTABLE_BIT )) { -printf ("A page is still marked unevictable after unlock\n" ); -return 1 ; - } -if (is_vmflag_set ((unsigned long )map,LOCKED )) {printf ("VMA flag %s is present on page 1 after unlock\n" ,LOCKED );return 1 ; } -if (is_vmflag_set ((unsigned long )map + page_size,LOCKED )) { -printf ("VMA flag %s is present on page 2 after unlock\n" ,LOCKED ); -return 1 ; - } -return 0 ; }
@@ -311,7 +210,7 @@ static int test_mlock_lock() goto unmap; } -if (lock_check (map)) +if (!lock_check ((unsigned long )map)) goto unmap;/* Now unlock and recheck attributes */
@@ -330,64 +229,18 @@ out:static int onfault_check (char *map) { -unsigned long page_size =getpagesize (); -uint64_t page1_flags, page2_flags; - - page1_flags =get_pageflags ((unsigned long )map); - page2_flags =get_pageflags ((unsigned long )map + page_size); - -/* Neither page should be present */ -if ((page1_flags &PRESENT_BIT ) || (page2_flags &PRESENT_BIT )) { -printf ("Pages were made present by MLOCK_ONFAULT\n" ); -return 1 ; - } - *map ='a' ; - page1_flags =get_pageflags ((unsigned long )map); - page2_flags =get_pageflags ((unsigned long )map + page_size); - -/* Only page 1 should be present */ -if ((page1_flags &PRESENT_BIT ) ==0 ) { -printf ("Page 1 is not present after fault\n" ); -return 1 ; - }else if (page2_flags &PRESENT_BIT ) { -printf ("Page 2 was made present\n" ); -return 1 ; - } - - page1_flags =get_kpageflags (page1_flags &PFN_MASK ); - -/* Page 1 should be unevictable */ -if ((page1_flags &UNEVICTABLE_BIT ) ==0 ) { -printf ("Failed to make faulted page unevictable\n" ); -return 1 ; - } -if (!is_vma_lock_on_fault ((unsigned long )map)) {printf ("VMA is not marked for lock on fault\n" );return 1 ; } -if (!is_vma_lock_on_fault ((unsigned long )map + page_size)) { -printf ("VMA is not marked for lock on fault\n" ); -return 1 ; - } -return 0 ; }static int unlock_onfault_check (char *map) {unsigned long page_size =getpagesize (); -uint64_t page1_flags; - - page1_flags =get_pageflags ((unsigned long )map); - page1_flags =get_kpageflags (page1_flags &PFN_MASK ); - -if (page1_flags &UNEVICTABLE_BIT ) { -printf ("Page 1 is still marked unevictable after unlock\n" ); -return 1 ; - }if (is_vma_lock_on_fault ((unsigned long )map) ||is_vma_lock_on_fault ((unsigned long )map + page_size)) {
@@ -445,7 +298,6 @@ static int test_lock_onfault_of_present(char *map;int ret =1 ;unsigned long page_size =getpagesize (); -uint64_t page1_flags, page2_flags; map =mmap (NULL ,2 * page_size,PROT_READ |PROT_WRITE ,MAP_ANONYMOUS |MAP_PRIVATE ,-1 ,0 );
@@ -465,17 +317,6 @@ static int test_lock_onfault_of_present( goto unmap; } - page1_flags =get_pageflags ((unsigned long )map); - page2_flags =get_pageflags ((unsigned long )map + page_size); - page1_flags =get_kpageflags (page1_flags &PFN_MASK ); - page2_flags =get_kpageflags (page2_flags &PFN_MASK ); - -/* Page 1 should be unevictable */ -if ((page1_flags &UNEVICTABLE_BIT ) ==0 ) { -printf ("Failed to make present page unevictable\n" ); - goto unmap; - } -if (!is_vma_lock_on_fault ((unsigned long )map) || !is_vma_lock_on_fault ((unsigned long )map + page_size)) {printf ("VMA with present pages is not marked lock on fault\n" );
@@ -507,7 +348,7 @@ static int test_munlockall() goto out; } -if (lock_check (map)) +if (!lock_check ((unsigned long )map)) goto unmap;if (munlockall ()) {
@@ -549,7 +390,7 @@ static int test_munlockall() goto out; } -if (lock_check (map)) +if (!lock_check ((unsigned long )map)) goto unmap;if (munlockall ()) {
Greg Kroah-Hartman
maintainerPATCH 180/232 selftests/vm: fix map_hugetlb length used for testing read and write
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit cabc30da10e677c67ab9a136b1478175734715c5 upstream.
Commit fa7b9a805c79 ("tools/selftest/vm: allow choosing mem size and page size in map_hugetlb") added the possibility to change the size of memory mapped for the test, but left the read and write test using the default value. This is unnoticed when mapping a length greater than the default one, but segfaults otherwise.
Fix read_bytes() and write_bytes() by giving them the real length.
Also fix the call to munmap().
--- tools/testing/selftests/vm/map_hugetlb.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
tools/testing/selftests/vm/map_hugetlb.c +7 -7
@@ -45,20 +45,20 @@ static void check_bytes(char *addr)printf ("First hex is %x\n" , *((unsigned int *)addr)); } -static void write_bytes (char *addr) +static void write_bytes (char *addr,size_t length) {unsigned long i; -for (i =0 ; i <LENGTH ; i++) +for (i =0 ; i < length; i++) *(addr + i) = (char )i; } -static int read_bytes (char *addr) +static int read_bytes (char *addr,size_t length) {unsigned long i;check_bytes (addr); -for (i =0 ; i <LENGTH ; i++) +for (i =0 ; i < length; i++)if (*(addr + i) != (char )i) {printf ("Mismatch at %lu\n" , i);return 1 ;
@@ -96,11 +96,11 @@ int main(int argc, char **argv)printf ("Returned address is %p\n" , addr);check_bytes (addr); -write_bytes (addr); - ret =read_bytes (addr); +write_bytes (addr, length); + ret =read_bytes (addr, length);/* munmap() length of MAP_HUGETLB memory must be hugepage aligned */ -if (munmap (addr,LENGTH )) { +if (munmap (addr, length)) {perror ("munmap" );exit (1 ); }
Greg Kroah-Hartman
maintainerPATCH 181/232 selftests/powerpc: Add tlbie_test in .gitignore
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 47bf235f324c696395c30541fe4fcf99fcd24188 upstream.
The commit identified below added tlbie_test but forgot to add it in .gitignore.
--- tools/testing/selftests/powerpc/mm/.gitignore | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/powerpc/mm/.gitignore +1 -0
@@ -5,3 +5,4 @@ prot_sao segv_errors wild_bctr large_vm_fork_separation +tlbie_test
Greg Kroah-Hartman
maintainerPATCH 182/232 vfio: platform: Switch to platform_get_irq_optional()
In reply to Greg Kroah-HartmanFrom: Eric Auger <[email protected]>
commit 723fe298ad85ad1278bd2312469ad14738953cc6 upstream.
Since commit 7723f4c5ecdb ("driver core: platform: Add an error message to platform_get_irq*()"), platform_get_irq() calls dev_err() on an error. As we enumerate all interrupts until platform_get_irq() fails, we now systematically get a message such as:
"vfio-platform fff51000.ethernet: IRQ index 3 not found" which is a false positive.
Let's use platform_get_irq_optional() instead.
--- drivers/vfio/platform/vfio_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vfio/platform/vfio_platform.c +1 -1
@@ -44,7 +44,7 @@ static int get_platform_irq(struct vfio_ {struct platform_device *pdev = (struct platform_device *) vdev->opaque; -return platform_get_irq (pdev, i); +return platform_get_irq_optional (pdev, i); }static int vfio_platform_probe (struct platform_device *pdev)
Greg Kroah-Hartman
maintainerPATCH 183/232 drm/i915/gem: Flush all the reloc_gpu batch
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit 1aaea8476d9f014667d2cb24819f9bcaf3ebb7a4 upstream.
__i915_gem_object_flush_map() takes a byte range, so feed it the written bytes and do not mistake the u32 index as bytes!
--- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +5 -3
@@ -931,11 +931,13 @@ static inline struct i915_ggtt *cache_tostatic void reloc_gpu_flush (struct reloc_cache *cache) { -GEM_BUG_ON (cache->rq_size >= cache->rq->batch->obj->base.size /sizeof (u32)); +struct drm_i915_gem_object *obj = cache->rq->batch->obj; + +GEM_BUG_ON (cache->rq_size >= obj->base.size /sizeof (u32)); cache->rq_cmd[cache->rq_size] =MI_BATCH_BUFFER_END ; -__i915_gem_object_flush_map (cache->rq->batch->obj,0 , cache->rq_size); -i915_gem_object_unpin_map (cache->rq->batch->obj); +__i915_gem_object_flush_map (obj,0 ,sizeof (u32) * (cache->rq_size +1 )); +i915_gem_object_unpin_map (obj);intel_gt_chipset_flush (cache->rq->engine->gt);
Greg Kroah-Hartman
maintainerPATCH 184/232 drm/etnaviv: rework perfmon query infrastructure
In reply to Greg Kroah-HartmanFrom: Christian Gmeiner <[email protected]>
commit ed1dd899baa32d47d9a93d98336472da50564346 upstream.
Report the correct perfmon domains and signals depending on the supported feature flags.
--- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 59 ++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 7 deletions(-)
drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +52 -7
@@ -32,6 +32,7 @@ struct etnaviv_pm_domain { };struct etnaviv_pm_domain_meta { +unsigned int feature;const struct etnaviv_pm_domain *domains;u32 nr_domains; };
@@ -410,36 +411,78 @@ static const struct etnaviv_pm_domain dostatic const struct etnaviv_pm_domain_meta doms_meta[] = { { + .feature = chipFeatures_PIPE_3D, .nr_domains =ARRAY_SIZE (doms_3d), .domains = &doms_3d[0 ] }, { + .feature = chipFeatures_PIPE_2D, .nr_domains =ARRAY_SIZE (doms_2d), .domains = &doms_2d[0 ] }, { + .feature = chipFeatures_PIPE_VG, .nr_domains =ARRAY_SIZE (doms_vg), .domains = &doms_vg[0 ] } }; +static unsigned int num_pm_domains (const struct etnaviv_gpu *gpu) +{ +unsigned int num =0 , i; + +for (i =0 ; i <ARRAY_SIZE (doms_meta); i++) { +const struct etnaviv_pm_domain_meta *meta = &doms_meta[i]; + +if (gpu->identity.features & meta->feature) + num += meta->nr_domains; + } + +return num; +} + +static const struct etnaviv_pm_domain *pm_domain (const struct etnaviv_gpu *gpu, +unsigned int index) +{ +const struct etnaviv_pm_domain *domain =NULL ; +unsigned int offset =0 , i; + +for (i =0 ; i <ARRAY_SIZE (doms_meta); i++) { +const struct etnaviv_pm_domain_meta *meta = &doms_meta[i]; + +if (!(gpu->identity.features & meta->feature)) +continue ; + +if (meta->nr_domains < (index - offset)) { + offset += meta->nr_domains; +continue ; + } + + domain = meta->domains + (index - offset); + } + +return domain; +} +int etnaviv_pm_query_dom (struct etnaviv_gpu *gpu,struct drm_etnaviv_pm_domain *domain) { -const struct etnaviv_pm_domain_meta *meta = &doms_meta[domain->pipe]; +const unsigned int nr_domains =num_pm_domains (gpu);const struct etnaviv_pm_domain *dom; -if (domain->iter >= meta->nr_domains) +if (domain->iter >= nr_domains)return -EINVAL ; - dom = meta->domains + domain->iter; + dom =pm_domain (gpu, domain->iter); +if (!dom) +return -EINVAL ; domain->id = domain->iter; domain->nr_signals = dom->nr_signals;strncpy (domain->name, dom->name,sizeof (domain->name)); domain->iter++; -if (domain->iter == meta->nr_domains) +if (domain->iter == nr_domains) domain->iter =0xff ;return 0 ;
@@ -448,14 +491,16 @@ int etnaviv_pm_query_dom(struct etnaviv_int etnaviv_pm_query_sig (struct etnaviv_gpu *gpu,struct drm_etnaviv_pm_signal *signal) { -const struct etnaviv_pm_domain_meta *meta = &doms_meta[signal->pipe]; +const unsigned int nr_domains =num_pm_domains (gpu);const struct etnaviv_pm_domain *dom;const struct etnaviv_pm_signal *sig; -if (signal->domain >= meta->nr_domains) +if (signal->domain >= nr_domains)return -EINVAL ; - dom = meta->domains + signal->domain; + dom =pm_domain (gpu, signal->domain); +if (!dom) +return -EINVAL ;if (signal->iter >= dom->nr_signals)return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 185/232 drm: Remove PageReserved manipulation from drm_pci_alloc
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit ea36ec8623f56791c6ff6738d0509b7920f85220 upstream.
drm_pci_alloc/drm_pci_free are very thin wrappers around the core dma facilities, and we have no special reason within the drm layer to behave differently. In particular, since
commit de09d31dd38a50fdce106c15abd68432eebbd014
Author: Kirill A. Shutemov <[email protected]> Date: Fri Jan 15 16:51:42 2016 -0800
page-flags: define PG_reserved behavior on compound pages
As far as I can see there's no users of PG_reserved on compound pages. Let's use PF_NO_COMPOUND here.
it has been illegal to combine GFP_COMP with SetPageReserved, so lets stop doing both and leave the dma layer to its own devices.
--- drivers/gpu/drm/drm_pci.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-)
drivers/gpu/drm/drm_pci.c +2 -21
@@ -51,8 +51,6 @@drm_dma_handle_t *drm_pci_alloc (struct drm_device * dev,size_t size,size_t align) {drm_dma_handle_t *dmah; -unsigned long addr; -size_t sz;/* pci_alloc_consistent only guarantees alignment to the smallest * PAGE_SIZE order which is greater than or equal to the requested size.
@@ -68,20 +66,13 @@ drm_dma_handle_t *drm_pci_alloc(struct d dmah->size = size; dmah->vaddr =dma_alloc_coherent (&dev->pdev->dev, size, &dmah->busaddr, -GFP_KERNEL | __GFP_COMP); +GFP_KERNEL );if (dmah->vaddr ==NULL ) {kfree (dmah);return NULL ; } -/* XXX - Is virt_to_page() legal for consistent mem? */ -/* Reserve */ -for (addr = (unsigned long )dmah->vaddr, sz = size; - sz >0 ; addr +=PAGE_SIZE , sz -=PAGE_SIZE ) { -SetPageReserved (virt_to_page ((void *)addr)); - } -return dmah; }
@@ -94,19 +85,9 @@ EXPORT_SYMBOL(drm_pci_alloc);*/ void __drm_legacy_pci_free (struct drm_device * dev,drm_dma_handle_t * dmah) { -unsigned long addr; -size_t sz; - -if (dmah->vaddr) { -/* XXX - Is virt_to_page() legal for consistent mem? */ -/* Unreserve */ -for (addr = (unsigned long )dmah->vaddr, sz = dmah->size; - sz >0 ; addr +=PAGE_SIZE , sz -=PAGE_SIZE ) { -ClearPageReserved (virt_to_page ((void *)addr)); - } +if (dmah->vaddr)dma_free_coherent (&dev->pdev->dev, dmah->size, dmah->vaddr, dmah->busaddr); - } }/**
Greg Kroah-Hartman
maintainerPATCH 186/232 drm/amdgpu/powerplay: using the FCLK DPM table to set the MCLK
In reply to Greg Kroah-HartmanFrom: Yuxian Dai <[email protected]>
commit 022ac4c9c55be35a2d1f71019a931324c51b0dab upstream.
1.Using the FCLK DPM table to set the MCLK for DPM states consist of three entities:
FCLK
UCLK
MEMCLK
All these three clk change together, MEMCLK from FCLK, so use the fclk frequency.
2.we should show the current working clock freqency from clock table metric
--- drivers/gpu/drm/amd/powerplay/renoir_ppt.c | 6 ++++++ drivers/gpu/drm/amd/powerplay/renoir_ppt.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/powerplay/renoir_ppt.c +6 -0
@@ -184,6 +184,7 @@ static int renoir_print_clk_levels(strucuint32_t cur_value =0 , value =0 , count =0 , min =0 , max =0 ;DpmClocks_t *clk_table = smu->smu_table.clocks_table;SmuMetrics_t metrics; +bool cur_value_match_level = false;if (!clk_table || clk_type >=SMU_CLK_COUNT )return -EINVAL ;
@@ -243,8 +244,13 @@ static int renoir_print_clk_levels(strucGET_DPM_CUR_FREQ (clk_table, clk_type, i, value); size +=sprintf (buf + size,"%d: %uMhz %s\n" , i, value, cur_value == value ?"*" :"" ); +if (cur_value == value) + cur_value_match_level = true; } +if (!cur_value_match_level) + size +=sprintf (buf + size," %uMhz *\n" , cur_value); +return size; }
drivers/gpu/drm/amd/powerplay/renoir_ppt.h +1 -1
@@ -37,7 +37,7 @@ extern void renoir_set_ppt_funcs(struct freq = table->SocClocks[dpm_level].Freq; \break ; \case SMU_MCLK : \ - freq = table->MemClocks[dpm_level].Freq; \ + freq = table->FClocks[dpm_level].Freq; \break ; \case SMU_DCEFCLK : \ freq = table->DcfClocks[dpm_level].Freq; \
Greg Kroah-Hartman
maintainerPATCH 187/232 drm/amdgpu: unify fw_write_wait for new gfx9 asics
In reply to Greg Kroah-HartmanFrom: Aaron Liu <[email protected]>
commit 2960758cce2310774de60bbbd8d6841d436c54d9 upstream.
Make the fw_write_wait default case true since presumably all new gfx9 asics will have updated firmware. That is using unique WAIT_REG_MEM packet with opration=1.
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +2 -0
@@ -1026,6 +1026,8 @@ static void gfx_v9_0_check_fw_write_wait adev->gfx.mec_fw_write_wait = true;break ;default : + adev->gfx.me_fw_write_wait = true; + adev->gfx.mec_fw_write_wait = true;break ; } }
Greg Kroah-Hartman
maintainerPATCH 188/232 powerpc/pseries: Avoid NULL pointer dereference when drmem is unavailable
In reply to Greg Kroah-HartmanFrom: Libor Pechacek <[email protected]>
commit a83836dbc53e96f13fec248ecc201d18e1e3111d upstream.
In guests without hotplugagble memory drmem structure is only zero initialized. Trying to manipulate DLPAR parameters results in a crash.
$ echo "memory add count 1" > /sys/kernel/dlpar
Oops: Kernel access of bad area, sig: 11 [#1]
LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
...
NIP: c0000000000ff294 LR: c0000000000ff248 CTR: 0000000000000000
REGS: c0000000fb9d3880 TRAP: 0300 Tainted: G E (5.5.0-rc6-2-default)
MSR: 8000000000009033 <SF,EE,ME,IR,DR,RI,LE> CR: 28242428 XER: 20000000
CFAR: c0000000009a6c10 DAR: 0000000000000010 DSISR: 40000000 IRQMASK: 0
...
NIP dlpar_memory+0x6e4/0xd00
LR dlpar_memory+0x698/0xd00
Call Trace:
dlpar_memory+0x698/0xd00 (unreliable)
handle_dlpar_errorlog+0xc0/0x190
dlpar_store+0x198/0x4a0
kobj_attr_store+0x30/0x50
sysfs_kf_write+0x64/0x90
kernfs_fop_write+0x1b0/0x290
__vfs_write+0x3c/0x70
vfs_write+0xd0/0x260
ksys_write+0xdc/0x130
system_call+0x5c/0x68Taking closer look at the code, I can see that for_each_drmem_lmb is a macro expanding into for (lmb = &drmem_info->lmbs[0]; lmb <= &drmem_info->lmbs[drmem_info->n_lmbs - 1]; lmb++). When drmem_info->lmbs is NULL, the loop would iterate through the whole address range if it weren't stopped by the NULL pointer dereference on the next line.
This patch aligns for_each_drmem_lmb and for_each_drmem_lmb_in_range macro behavior with the common C semantics, where the end marker does not belong to the scanned range, and alters get_lmb_range() semantics. As a side effect, the wraparound observed in the crash is prevented.
--- arch/powerpc/include/asm/drmem.h | 4 ++-- arch/powerpc/platforms/pseries/hotplug-memory.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-)
arch/powerpc/include/asm/drmem.h +2 -2
@@ -27,12 +27,12 @@ struct drmem_lmb_info {extern struct drmem_lmb_info *drmem_info;#define for_each_drmem_lmb_in_range (lmb, start, end) \ - for ((lmb) = (start); (lmb) <= (end); (lmb)++) + for ((lmb) = (start); (lmb) < (end); (lmb)++)#define for_each_drmem_lmb (lmb) \ for_each_drmem_lmb_in_range((lmb), \ &drmem_info->lmbs[0], \ - &drmem_info->lmbs[drmem_info->n_lmbs - 1]) + &drmem_info->lmbs[drmem_info->n_lmbs])/* * The of_drconf_cell_v1 struct defines the layout of the LMB data
arch/powerpc/platforms/pseries/hotplug-memory.c +4 -4
@@ -223,7 +223,7 @@ static int get_lmb_range(u32 drc_index, struct drmem_lmb **end_lmb) {struct drmem_lmb *lmb, *start, *end; -struct drmem_lmb *last_lmb; +struct drmem_lmb *limit; start =NULL ;for_each_drmem_lmb (lmb) {
@@ -236,10 +236,10 @@ static int get_lmb_range(u32 drc_index,if (!start)return -EINVAL ; - end = &start[n_lmbs -1 ]; + end = &start[n_lmbs]; - last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs -1 ]; -if (end > last_lmb) + limit = &drmem_info->lmbs[drmem_info->n_lmbs]; +if (end > limit)return -EINVAL ; *start_lmb = start;
Greg Kroah-Hartman
maintainerPATCH 189/232 nfsd: fsnotify on rmdir under nfsd/clients/
In reply to Greg Kroah-HartmanFrom: J. Bruce Fields <[email protected]>
commit 69afd267982e733a555fede4e85fe30329ed0588 upstream.
Userspace should be able to monitor nfsd/clients/ to see when clients come and go, but we're failing to send fsnotify events.
--- fs/nfsd/nfsctl.c | 1 + 1 file changed, 1 insertion(+)
fs/nfsd/nfsctl.c +1 -0
@@ -1333,6 +1333,7 @@ void nfsd_client_rmdir(struct dentry *dedget (dentry); ret =simple_rmdir (dir, dentry);WARN_ON_ONCE (ret); +fsnotify_rmdir (dir, dentry);d_delete (dentry);inode_unlock (dir); }
Greg Kroah-Hartman
maintainerPATCH 190/232 NFS: Fix use-after-free issues in nfs_pageio_add_request()
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit dc9dc2febb17f72e9878eb540ad3996f7984239a upstream.
We need to ensure that we create the mirror requests before calling nfs_pageio_add_request_mirror() on the request we are adding. Otherwise, we can end up with a use-after-free if the call to nfs_pageio_add_request_mirror() triggers I/O.
--- fs/nfs/pagelist.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-)
fs/nfs/pagelist.c +24 -24
@@ -1177,38 +1177,38 @@ int nfs_pageio_add_request(struct nfs_paif (desc->pg_error <0 ) goto out_failed; -for (midx =0 ; midx < desc->pg_mirror_count; midx++) { -if (midx) { -nfs_page_group_lock (req); - -/* find the last request */ -for (lastreq = req->wb_head; - lastreq->wb_this_page != req->wb_head; - lastreq = lastreq->wb_this_page) - ; - - dupreq =nfs_create_subreq (req, lastreq, - pgbase, offset, bytes); - -nfs_page_group_unlock (req); -if (IS_ERR (dupreq)) { - desc->pg_error =PTR_ERR (dupreq); - goto out_failed; - } - }else - dupreq = req; +/* Create the mirror instances first, and fire them off */ +for (midx =1 ; midx < desc->pg_mirror_count; midx++) { +nfs_page_group_lock (req); + +/* find the last request */ +for (lastreq = req->wb_head; + lastreq->wb_this_page != req->wb_head; + lastreq = lastreq->wb_this_page) + ; + + dupreq =nfs_create_subreq (req, lastreq, + pgbase, offset, bytes); + +nfs_page_group_unlock (req); +if (IS_ERR (dupreq)) { + desc->pg_error =PTR_ERR (dupreq); + goto out_failed; + } -if (nfs_pgio_has_mirroring (desc)) - desc->pg_mirror_idx = midx; + desc->pg_mirror_idx = midx;if (!nfs_pageio_add_request_mirror (desc, dupreq)) goto out_cleanup_subreq; } + desc->pg_mirror_idx =0 ; +if (!nfs_pageio_add_request_mirror (desc, req)) + goto out_failed; +return 1 ; out_cleanup_subreq: -if (req != dupreq) -nfs_pageio_cleanup_request (desc, dupreq); +nfs_pageio_cleanup_request (desc, dupreq); out_failed:nfs_pageio_error_cleanup (desc);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 191/232 NFS: Fix a page leak in nfs_destroy_unlinked_subrequests()
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit add42de31721fa29ed77a7ce388674d69f9d31a4 upstream.
When we detach a subrequest from the list, we must also release the reference it holds to the parent.
--- fs/nfs/write.c | 1 + 1 file changed, 1 insertion(+)
fs/nfs/write.c +1 -0
@@ -441,6 +441,7 @@ nfs_destroy_unlinked_subrequests(struct } subreq->wb_head = subreq; +nfs_release_request (old_head);if (test_and_clear_bit (PG_INODE_REF , &subreq->wb_flags)) {nfs_release_request (subreq);
Greg Kroah-Hartman
maintainerPATCH 192/232 ext4: fix a data race at inode->i_blocks
In reply to Greg Kroah-HartmanFrom: Qian Cai <[email protected]>
commit 28936b62e71e41600bab319f262ea9f9b1027629 upstream.
inode->i_blocks could be accessed concurrently as noticed by KCSAN,
BUG: KCSAN: data-race in ext4_do_update_inode [ext4] / inode_add_bytes
write to 0xffff9a00d4b982d0 of 8 bytes by task 22100 on cpu 118:
inode_add_bytes+0x65/0xf0 __inode_add_bytes at fs/stat.c:689 (inlined by) inode_add_bytes at fs/stat.c:702 ext4_mb_new_blocks+0x418/0xca0 [ext4] ext4_ext_map_blocks+0x1a6b/0x27b0 [ext4] ext4_map_blocks+0x1a9/0x950 [ext4] _ext4_get_block+0xfc/0x270 [ext4] ext4_get_block_unwritten+0x33/0x50 [ext4] __block_write_begin_int+0x22e/0xae0 __block_write_begin+0x39/0x50 ext4_write_begin+0x388/0xb50 [ext4] ext4_da_write_begin+0x35f/0x8f0 [ext4] generic_perform_write+0x15d/0x290 ext4_buffered_write_iter+0x11f/0x210 [ext4] ext4_file_write_iter+0xce/0x9e0 [ext4] new_sync_write+0x29c/0x3b0 __vfs_write+0x92/0xa0 vfs_write+0x103/0x260 ksys_write+0x9d/0x130 __x64_sys_write+0x4c/0x60 do_syscall_64+0x91/0xb05 entry_SYSCALL_64_after_hwframe+0x49/0xbe
read to 0xffff9a00d4b982d0 of 8 bytes by task 8 on cpu 65:
ext4_do_update_inode+0x4a0/0xf60 [ext4] ext4_inode_blocks_set at fs/ext4/inode.c:4815 ext4_mark_iloc_dirty+0xaf/0x160 [ext4] ext4_mark_inode_dirty+0x129/0x3e0 [ext4] ext4_convert_unwritten_extents+0x253/0x2d0 [ext4] ext4_convert_unwritten_io_end_vec+0xc5/0x150 [ext4] ext4_end_io_rsv_work+0x22c/0x350 [ext4] process_one_work+0x54f/0xb90 worker_thread+0x80/0x5f0 kthread+0x1cd/0x1f0 ret_from_fork+0x27/0x50
4 locks held by kworker/u256:0/8:
#0: ffff9a025abc4328 ((wq_completion)ext4-rsv-conversion){+.+.}, at: process_one_work+0x443/0xb90 #1: ffffab5a862dbe20 ((work_completion)(&ei->i_rsv_conversion_work)){+.+.}, at: process_one_work+0x443/0xb90 #2: ffff9a025a9d0f58 (jbd2_handle){++++}, at: start_this_handle+0x1c1/0x9d0 [jbd2]
#3: ffff9a00d4b985d8 (&(&ei->i_raw_lock)->rlock){+.+.}, at: ext4_do_update_inode+0xaa/0xf60 [ext4]
irq event stamp: 3009267 hardirqs last enabled at (3009267): [<ffffffff980da9b7>] __find_get_block+0x107/0x790 hardirqs last disabled at (3009266): [<ffffffff980da8f9>] __find_get_block+0x49/0x790 softirqs last enabled at (3009230): [<ffffffff98a0034c>] __do_softirq+0x34c/0x57c softirqs last disabled at (3009223): [<ffffffff97cc67a2>] irq_exit+0xa2/0xc0
Reported by Kernel Concurrency Sanitizer on:
CPU: 65 PID: 8 Comm: kworker/u256:0 Tainted: G L 5.6.0-rc2-next-20200221+ #7 Hardware name: HPE ProLiant DL385 Gen10/ProLiant DL385 Gen10, BIOS A40 07/10/2019 Workqueue: ext4-rsv-conversion ext4_end_io_rsv_work [ext4]
The plain read is outside of inode->i_lock critical section which results in a data race. Fix it by adding READ_ONCE() there.
--- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/inode.c +1 -1
@@ -5140,7 +5140,7 @@ static int ext4_inode_blocks_set(handle_ struct ext4_inode_info *ei) {struct inode *inode = &(ei->vfs_inode); -u64 i_blocks = inode->i_blocks; +u64 i_blocks =READ_ONCE (inode->i_blocks);struct super_block *sb = inode->i_sb;if (i_blocks <= ~0U ) {
Greg Kroah-Hartman
maintainerPATCH 193/232 fs/filesystems.c: downgrade user-reachable WARN_ONCE() to pr_warn_once()
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 26c5d78c976ca298e59a56f6101a97b618ba3539 upstream.
After request_module(), nothing is stopping the module from being unloaded until someone takes a reference to it via try_get_module().
The WARN_ONCE() in get_fs_type() is thus user-reachable, via userspace running 'rmmod' concurrently.
Since WARN_ONCE() is for kernel bugs only, not for user-reachable situations, downgrade this warning to pr_warn_once().
Keep it printed once only, since the intent of this warning is to detect a bug in modprobe at boot time. Printing the warning more than once wouldn't really provide any useful extra information.
--- fs/filesystems.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/filesystems.c +3 -1
@@ -271,7 +271,9 @@ struct file_system_type *get_fs_type(con fs =__get_fs_type (name, len);if (!fs && (request_module ("fs-%.*s" , len, name) ==0 )) { fs =__get_fs_type (name, len); -WARN_ONCE (!fs,"request_module fs-%.*s succeeded, but still no fs?\n" , len, name); +if (!fs) +pr_warn_once ("request_module fs-%.*s succeeded, but still no fs?\n" , + len, name); }if (dot && fs && !(fs->fs_flags &FS_HAS_SUBTYPE )) {
Greg Kroah-Hartman
maintainerPATCH 194/232 ocfs2: no need try to truncate file beyond i_size
In reply to Greg Kroah-HartmanFrom: Changwei Ge <[email protected]>
commit 783fda856e1034dee90a873f7654c418212d12d7 upstream.
Linux fallocate(2) with FALLOC_FL_PUNCH_HOLE mode set, its offset can exceed the inode size. Ocfs2 now doesn't allow that offset beyond inode size. This restriction is not necessary and violates fallocate(2) semantics.
If fallocate(2) offset is beyond inode size, just return success and do nothing further.
Otherwise, ocfs2 will crash the kernel.
kernel BUG at fs/ocfs2//alloc.c:7264!
ocfs2_truncate_inline+0x20f/0x360 [ocfs2] ocfs2_remove_inode_range+0x23c/0xcb0 [ocfs2] __ocfs2_change_file_space+0x4a5/0x650 [ocfs2] ocfs2_fallocate+0x83/0xa0 [ocfs2] vfs_fallocate+0x148/0x230 SyS_fallocate+0x48/0x80 do_syscall_64+0x79/0x170
--- fs/ocfs2/alloc.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/ocfs2/alloc.c +4 -0
@@ -7403,6 +7403,10 @@ int ocfs2_truncate_inline(struct inode *struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;struct ocfs2_inline_data *idata = &di->id2.i_data; +/* No need to punch hole beyond i_size. */ +if (start >=i_size_read (inode)) +return 0 ; +if (end >i_size_read (inode)) end =i_size_read (inode);
Greg Kroah-Hartman
maintainerPATCH 195/232 perf tools: Support Python 3.8+ in Makefile
In reply to Greg Kroah-HartmanFrom: Sam Lunt <[email protected]>
commit b9c9ce4e598e012ca7c1813fae2f4d02395807de upstream.
Python 3.8 changed the output of 'python-config --ldflags' to no longer include the '-lpythonX.Y' flag (this apparently fixed an issue loading modules with a statically linked Python executable). The libpython feature check in linux/build/feature fails if the Python library is not included in FEATURE_CHECK_LDFLAGS-libpython variable.
This adds a check in the Makefile to determine if PYTHON_CONFIG accepts the '--embed' flag and passes that flag alongside '--ldflags' if so.
tools/perf is the only place the libpython feature check is used.
--- tools/perf/Makefile.config | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
tools/perf/Makefile.config +10 -1
@@ -228,8 +228,17 @@ strip-libs = $(filter-out -l%,$(1)) PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG)) +# Python 3.8 changed the output of `python-config --ldflags` to not include the +# '-lpythonX.Y' flag unless '--embed' is also passed. The feature check for +# libpython fails if that flag is not included in LDFLAGS +ifeq ($(shell $(PYTHON_CONFIG_SQ) --ldflags --embed 2>&1 1>/dev/null; echo $$?), 0) + PYTHON_CONFIG_LDFLAGS := --ldflags --embed +else + PYTHON_CONFIG_LDFLAGS := --ldflags +endif + ifdef PYTHON_CONFIG - PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) + PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) $(PYTHON_CONFIG_LDFLAGS) 2>/dev/null) PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --includes 2>/dev/null)
Greg Kroah-Hartman
maintainerPATCH 196/232 s390/diag: fix display of diagnose call statistics
In reply to Greg Kroah-HartmanFrom: Michael Mueller <[email protected]>
commit 6c7c851f1b666a8a455678a0b480b9162de86052 upstream.
Show the full diag statistic table and not just parts of it.
The issue surfaced in a KVM guest with a number of vcpus defined smaller than NR_DIAG_STAT.
--- arch/s390/kernel/diag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/kernel/diag.c +1 -1
@@ -84,7 +84,7 @@ static int show_diag_stat(struct seq_filstatic void *show_diag_stat_start (struct seq_file *m,loff_t *pos) { -return *pos <= nr_cpu_ids ? (void *)((unsigned long ) *pos +1 ) :NULL ; +return *pos <=NR_DIAG_STAT ? (void *)((unsigned long ) *pos +1 ) :NULL ; }static void *show_diag_stat_next (struct seq_file *m,void *v,loff_t *pos)
Greg Kroah-Hartman
maintainerPATCH 197/232 Input: i8042 - add Acer Aspire 5738z to nomux list
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit ebc68cedec4aead47d8d11623d013cca9bf8e825 upstream.
The Acer Aspire 5738z has a button to disable (and re-enable) the touchpad next to the touchpad.
When this button is pressed a LED underneath indicates that the touchpad is disabled (and an event is send to userspace and GNOME shows its touchpad enabled / disable OSD thingie).
So far so good, but after re-enabling the touchpad it no longer works.
The laptop does not have an external ps2 port, so mux mode is not needed and disabling mux mode fixes the touchpad no longer working after toggling it off and back on again, so lets add this laptop model to the nomux list.
--- drivers/input/serio/i8042-x86ia64io.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/input/serio/i8042-x86ia64io.h +11 -0
@@ -530,6 +530,17 @@ static const struct dmi_system_id __init DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"), }, }, + { + /* + * Acer Aspire 5738z + * Touchpad stops working in mux mode when dis- + re-enabled + * with the touchpad enable/disable toggle hotkey + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), + }, + }, { } };
Greg Kroah-Hartman
maintainerPATCH 198/232 ftrace/kprobe: Show the maxactive number on kprobe_events
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
commit 6a13a0d7b4d1171ef9b80ad69abc37e1daa941b3 upstream.
Show maxactive parameter on kprobe_events. This allows user to save the current configuration and restore it without losing maxactive parameter.
--- kernel/trace/trace_kprobe.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace_kprobe.c +2 -0
@@ -918,6 +918,8 @@ static int trace_kprobe_show(struct seq_int i;seq_putc (m,trace_kprobe_is_return (tk) ?'r' :'p' ); +if (trace_kprobe_is_return (tk) && tk->rp.maxactive) +seq_printf (m,"%d" , tk->rp.maxactive);seq_printf (m,":%s/%s" ,trace_probe_group_name (&tk->tp),trace_probe_name (&tk->tp));
Greg Kroah-Hartman
maintainerPATCH 199/232 clk: ingenic/jz4770: Exit with error if CGU init failed
In reply to Greg Kroah-HartmanFrom: Paul Cercueil <[email protected]>
commit c067b46d731a764fc46ecc466c2967088c97089e upstream.
Exit jz4770_cgu_init() if the 'cgu' pointer we get is NULL, since the pointer is passed as argument to functions later on.
--- drivers/clk/ingenic/jz4770-cgu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/clk/ingenic/jz4770-cgu.c +3 -1
@@ -432,8 +432,10 @@ static void __init jz4770_cgu_init(struc cgu =ingenic_cgu_new (jz4770_cgu_clocks,ARRAY_SIZE (jz4770_cgu_clocks), np); -if (!cgu) +if (!cgu) {pr_err ("%s: failed to initialise CGU\n" , __func__); +return ; + } retval =ingenic_cgu_register_clocks (cgu);if (retval)
Greg Kroah-Hartman
maintainerPATCH 200/232 clk: ingenic/TCU: Fix round_rate returning error
In reply to Greg Kroah-HartmanFrom: Paul Cercueil <[email protected]>
commit edcc42945dee85e9dec3737f3dbf59d917ae5418 upstream.
When requesting a rate superior to the parent's rate, it would return -EINVAL instead of simply returning the parent's rate like it should.
--- drivers/clk/ingenic/tcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/ingenic/tcu.c +1 -1
@@ -189,7 +189,7 @@ static long ingenic_tcu_round_rate(strucu8 prescale;if (req_rate > rate) -return -EINVAL ; +return rate; prescale =ingenic_tcu_get_prescale (rate, req_rate);
Greg Kroah-Hartman
maintainerPATCH 201/232 kmod: make request_module() return an error when autoloading is disabled
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit d7d27cfc5cf0766a26a8f56868c5ad5434735126 upstream.
Patch series "module autoloading fixes and cleanups", v5.
This series fixes a bug where request_module() was reporting success to kernel code when module autoloading had been completely disabled via 'echo > /proc/sys/kernel/modprobe'.
It also addresses the issues raised on the original thread
(https://lkml.kernel.org/lkml/[email protected]/T/#u)
bydocumenting the modprobe sysctl, adding a self-test for the empty path case, and downgrading a user-reachable WARN_ONCE().
This patch (of 4):
It's long been possible to disable kernel module autoloading completely (while still allowing manual module insertion) by setting /proc/sys/kernel/modprobe to the empty string.
This can be preferable to setting it to a nonexistent file since it avoids the overhead of an attempted execve(), avoids potential deadlocks, and avoids the call to security_kernel_module_request() and thus on SELinux-based systems eliminates the need to write SELinux rules to dontaudit module_request.
However, when module autoloading is disabled in this way, request_module() returns 0. This is broken because callers expect 0 to mean that the module was successfully loaded.
Apparently this was never noticed because this method of disabling module autoloading isn't used much, and also most callers don't use the return value of request_module() since it's always necessary to check whether the module registered its functionality or not anyway.
But improperly returning 0 can indeed confuse a few callers, for example get_fs_type() in fs/filesystems.c where it causes a WARNING to be hit:
if (!fs && (request_module("fs-%.*s", len, name) == 0)) {
fs = __get_fs_type(name, len);
WARN_ONCE(!fs, "request_module fs-%.*s succeeded, but still no fs?\n", len, name);
}This is easily reproduced with:
echo > /proc/sys/kernel/modprobe
mount -t NONEXISTENT none /
It causes:
request_module fs-NONEXISTENT succeeded, but still no fs? WARNING: CPU: 1 PID: 1106 at fs/filesystems.c:275 get_fs_type+0xd6/0xf0 [...]
This should actually use pr_warn_once() rather than WARN_ONCE(), since it's also user-reachable if userspace immediately unloads the module. Regardless, request_module() should correctly return an error when it fails. So let's make it return -ENOENT, which matches the error when the modprobe binary doesn't exist.
I've also sent patches to document and test this case.
--- kernel/kmod.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/kmod.c +2 -2
@@ -120,7 +120,7 @@ out:* invoke it. * * If module auto-loading support is disabled then this function -* becomes a no-operation. +* simply returns -ENOENT. */ int __request_module (bool wait,const char *fmt, ...) {
@@ -137,7 +137,7 @@ int __request_module(bool wait, const chWARN_ON_ONCE (wait &¤t_is_async ());if (!modprobe_path[0 ]) -return 0 ; +return -ENOENT ;va_start (args, fmt); ret =vsnprintf (module_name,MODULE_NAME_LEN , fmt, args);
Greg Kroah-Hartman
maintainerPATCH 202/232 cpufreq: powernv: Fix use-after-free
In reply to Greg Kroah-HartmanFrom: Oliver O'Halloran <[email protected]>
commit d0a72efac89d1c35ac55197895201b7b94c5e6ef upstream.
The cpufreq driver has a use-after-free that we can hit if:
a) There's an OCC message pending when the notifier is registered, and
b) The cpufreq driver fails to register with the core.
When a) occurs the notifier schedules a workqueue item to handle the message. The backing work_struct is located on chips[].throttle and when b) happens we clean up by freeing the array. Once we get to the (now free) queued item and the kernel crashes.
--- drivers/cpufreq/powernv-cpufreq.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/cpufreq/powernv-cpufreq.c +6 -0
@@ -1080,6 +1080,12 @@ free_and_return:static inline void clean_chip_info (void ) { +int i; + +/* flush any pending work items */ +if (chips) +for (i =0 ; i < nr_chips; i++) +cancel_work_sync (&chips[i].throttle);kfree (chips); }
Greg Kroah-Hartman
maintainerPATCH 203/232 hfsplus: fix crash and filesystem corruption when deleting files
In reply to Greg Kroah-HartmanFrom: Simon Gander <[email protected]>
commit 25efb2ffdf991177e740b2f63e92b4ec7d310a92 upstream.
When removing files containing extended attributes, the hfsplus driver may remove the wrong entries from the attributes b-tree, causing major filesystem damage and in some cases even kernel crashes.
To remove a file, all its extended attributes have to be removed as well. The driver does this by looking up all keys in the attributes b-tree with the cnid of the file. Each of these entries then gets deleted using the key used for searching, which doesn't contain the attribute's name when it should. Since the key doesn't contain the name, the deletion routine will not find the correct entry and instead remove the one in front of it. If parent nodes have to be modified, these become corrupt as well. This causes invalid links and unsorted entries that not even macOS's fsck_hfs is able to fix.
To fix this, modify the search key before an entry is deleted from the attributes b-tree by copying the found entry's key into the search key, therefore ensuring that the correct entry gets removed from the tree.
--- fs/hfsplus/attributes.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/hfsplus/attributes.c +4 -0
@@ -292,6 +292,10 @@ static int __hfsplus_delete_attr(structreturn -ENOENT ; } +/* Avoid btree corruption */ +hfs_bnode_read (fd->bnode, fd->search_key, + fd->keyoffset, fd->keylength); + err =hfs_brec_remove (fd);if (err)return err;
Greg Kroah-Hartman
maintainerPATCH 204/232 libata: Return correct status in sata_pmp_eh_recover_pm() when ATA_DFLAG_DETACH is set
In reply to Greg Kroah-HartmanFrom: Kai-Heng Feng <[email protected]>
commit 8305f72f952cff21ce8109dc1ea4b321c8efc5af upstream.
During system resume from suspend, this can be observed on ASM1062 PMP controller:
ata10.01: SATA link down (SStatus 0 SControl 330)
ata10.02: hard resetting link
ata10.02: SATA link down (SStatus 0 SControl 330)
ata10.00: configured for UDMA/133
Kernel panic - not syncing: stack-protector: Kernel in: sata_pmp_eh_recover+0xa2b/0xa40 CPU: 2 PID: 230 Comm: scsi_eh_9 Tainted: P OE #49-Ubuntu Hardware name: System manufacturer System Product 1001 12/10/2017 Call Trace: dump_stack+0x63/0x8b panic+0xe4/0x244 ? sata_pmp_eh_recover+0xa2b/0xa40 __stack_chk_fail+0x19/0x20 sata_pmp_eh_recover+0xa2b/0xa40 ? ahci_do_softreset+0x260/0x260 [libahci] ? ahci_do_hardreset+0x140/0x140 [libahci] ? ata_phys_link_offline+0x60/0x60 ? ahci_stop_engine+0xc0/0xc0 [libahci] sata_pmp_error_handler+0x22/0x30 ahci_error_handler+0x45/0x80 [libahci] ata_scsi_port_error_handler+0x29b/0x770 ? ata_scsi_cmd_error_handler+0x101/0x140 ata_scsi_error+0x95/0xd0 ? scsi_try_target_reset+0x90/0x90 scsi_error_handler+0xd0/0x5b0 kthread+0x121/0x140 ? scsi_eh_get_sense+0x200/0x200 ? kthread_create_worker_on_cpu+0x70/0x70 ret_from_fork+0x22/0x40
Kernel Offset: 0xcc00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
Since sata_pmp_eh_recover_pmp() doens't set rc when ATA_DFLAG_DETACH is set, sata_pmp_eh_recover() continues to run. During retry it triggers the stack protector.
Set correct rc in sata_pmp_eh_recover_pmp() to let sata_pmp_eh_recover() jump to pmp_fail directly.
--- drivers/ata/libata-pmp.c | 1 + 1 file changed, 1 insertion(+)
drivers/ata/libata-pmp.c +1 -0
@@ -763,6 +763,7 @@ static int sata_pmp_eh_recover_pmp(strucif (dev->flags &ATA_DFLAG_DETACH ) { detach =1 ; + rc = -ENODEV ; goto fail; }
Greg Kroah-Hartman
maintainerPATCH 205/232 ipmi: fix hung processes in __get_guid()
In reply to Greg Kroah-HartmanFrom: Wen Yang <[email protected]>
commit 32830a0534700f86366f371b150b17f0f0d140d7 upstream.
The wait_event() function is used to detect command completion. When send_guid_cmd() returns an error, smi_send() has not been called to send data. Therefore, wait_event() should not be used on the error path, otherwise it will cause the following warning:
[ 1361.588808] systemd-udevd D 0 1501 1436 0x00000004 [ 1361.588813] ffff883f4b1298c0 0000000000000000 ffff883f4b188000 ffff887f7e3d9f40 [ 1361.677952] ffff887f64bd4280 ffffc90037297a68 ffffffff8173ca3b ffffc90000000010 [ 1361.767077] 00ffc90037297ad0 ffff887f7e3d9f40 0000000000000286 ffff883f4b188000 [ 1361.856199] Call Trace: [ 1361.885578] [<ffffffff8173ca3b>] ? __schedule+0x23b/0x780 [ 1361.951406] [<ffffffff8173cfb6>] schedule+0x36/0x80 [ 1362.010979] [<ffffffffa071f178>] get_guid+0x118/0x150 [ipmi_msghandler] [ 1362.091281] [<ffffffff810d5350>] ? prepare_to_wait_event+0x100/0x100 [ 1362.168533] [<ffffffffa071f755>] ipmi_register_smi+0x405/0x940 [ipmi_msghandler] [ 1362.258337] [<ffffffffa0230ae9>] try_smi_init+0x529/0x950 [ipmi_si] [ 1362.334521] [<ffffffffa022f350>] ? std_irq_setup+0xd0/0xd0 [ipmi_si] [ 1362.411701] [<ffffffffa0232bd2>] init_ipmi_si+0x492/0x9e0 [ipmi_si] [ 1362.487917] [<ffffffffa0232740>] ? ipmi_pci_probe+0x280/0x280 [ipmi_si] [ 1362.568219] [<ffffffff810021a0>] do_one_initcall+0x50/0x180 [ 1362.636109] [<ffffffff812231b2>] ? kmem_cache_alloc_trace+0x142/0x190 [ 1362.714330] [<ffffffff811b2ae1>] do_init_module+0x5f/0x200 [ 1362.781208] [<ffffffff81123ca8>] load_module+0x1898/0x1de0 [ 1362.848069] [<ffffffff811202e0>] ? __symbol_put+0x60/0x60 [ 1362.913886] [<ffffffff8130696b>] ? security_kernel_post_read_file+0x6b/0x80 [ 1362.998514] [<ffffffff81124465>] SYSC_finit_module+0xe5/0x120 [ 1363.068463] [<ffffffff81124465>] ? SYSC_finit_module+0xe5/0x120 [ 1363.140513] [<ffffffff811244be>] SyS_finit_module+0xe/0x10 [ 1363.207364] [<ffffffff81003c04>] do_syscall_64+0x74/0x180
Message-Id: <[email protected]>
--- drivers/char/ipmi/ipmi_msghandler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/char/ipmi/ipmi_msghandler.c +2 -2
@@ -3207,8 +3207,8 @@ static void __get_guid(struct ipmi_smi *if (rv)/* Send failed, no GUID available. */ bmc->dyn_guid_set =0 ; - -wait_event (intf->waitq, bmc->dyn_guid_set !=2 ); +else +wait_event (intf->waitq, bmc->dyn_guid_set !=2 );/* dyn_guid_set makes the guid data available. */ smp_rmb ();
Greg Kroah-Hartman
maintainerPATCH 206/232 xen/blkfront: fix memory allocation flags in blkfront_setup_indirect()
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit 3a169c0be75b59dd85d159493634870cdec6d3c4 upstream.
Commit 1d5c76e664333 ("xen-blkfront: switch kcalloc to kvcalloc for large array allocation") didn't fix the issue it was meant to, as the flags for allocating the memory are GFP_NOIO, which will lead the memory allocation falling back to kmalloc().
So instead of GFP_NOIO use GFP_KERNEL and do all the memory allocation in blkfront_setup_indirect() in a memalloc_noio_{save,restore} section.
--- drivers/block/xen-blkfront.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/block/xen-blkfront.c +12 -5
@@ -47,6 +47,7 @@#include <linux/bitmap.h> #include <linux/list.h> #include <linux/workqueue.h> +#include <linux/sched/mm.h> #include <xen/xen.h> #include <xen/xenbus.h>
@@ -2188,10 +2189,12 @@ static void blkfront_setup_discard(strucstatic int blkfront_setup_indirect (struct blkfront_ring_info *rinfo) { -unsigned int psegs, grants; +unsigned int psegs, grants, memflags;int err, i;struct blkfront_info *info = rinfo->dev_info; + memflags =memalloc_noio_save (); +if (info->max_indirect_segments ==0 ) {if (!HAS_EXTRA_REQ ) grants =BLKIF_MAX_SEGMENTS_PER_REQUEST ;
@@ -2223,7 +2226,7 @@ static int blkfront_setup_indirect(strucBUG_ON (!list_empty (&rinfo->indirect_pages));for (i =0 ; i < num; i++) { -struct page *indirect_page =alloc_page (GFP_NOIO ); +struct page *indirect_page =alloc_page (GFP_KERNEL );if (!indirect_page) goto out_of_memory;list_add (&indirect_page->lru, &rinfo->indirect_pages);
@@ -2234,15 +2237,15 @@ static int blkfront_setup_indirect(struc rinfo->shadow[i].grants_used =kvcalloc (grants,sizeof (rinfo->shadow[i].grants_used[0 ]), -GFP_NOIO ); +GFP_KERNEL ); rinfo->shadow[i].sg =kvcalloc (psegs,sizeof (rinfo->shadow[i].sg[0 ]), -GFP_NOIO ); +GFP_KERNEL );if (info->max_indirect_segments) rinfo->shadow[i].indirect_grants =kvcalloc (INDIRECT_GREFS (grants),sizeof (rinfo->shadow[i].indirect_grants[0 ]), -GFP_NOIO ); +GFP_KERNEL ); if ((rinfo->shadow[i].grants_used == NULL) || (rinfo->shadow[i].sg == NULL) || (info->max_indirect_segments &&
@@ -2251,6 +2254,7 @@ static int blkfront_setup_indirect(strucsg_init_table (rinfo->shadow[i].sg, psegs); } +memalloc_noio_restore (memflags);return 0 ;
@@ -2270,6 +2274,9 @@ out_of_memory:__free_page (indirect_page); } } + +memalloc_noio_restore (memflags); +return -ENOMEM ; }
Greg Kroah-Hartman
maintainerPATCH 207/232 powerpc/64/tm: Dont let userspace set regs->trap via sigreturn
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
commit c7def7fbdeaa25feaa19caf4a27c5d10bd8789e4 upstream.
In restore_tm_sigcontexts() we take the trap value directly from the user sigcontext with no checking:
err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]);
This means we can be in the kernel with an arbitrary regs->trap value.
Although that's not immediately problematic, there is a risk we could trigger one of the uses of CHECK_FULL_REGS():
#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1)
It can also cause us to unnecessarily save non-volatile GPRs again in save_nvgprs(), which shouldn't be problematic but is still wrong.
It's also possible it could trick the syscall restart machinery, which relies on regs->trap not being == 0xc00 (see 9a81c16b5275 ("powerpc:
fix double syscall restarts")), though I haven't been able to make that happen.
Finally it doesn't match the behaviour of the non-TM case, in restore_sigcontext() which zeroes regs->trap.
So change restore_tm_sigcontexts() to zero regs->trap.
This was discovered while testing Nick's upcoming rewrite of the syscall entry path. In that series the call to save_nvgprs() prior to signal handling (do_notify_resume()) is removed, which leaves the low-bit of regs->trap uncleared which can then trigger the FULL_REGS() WARNs in setup_tm_sigcontexts().
--- arch/powerpc/kernel/signal_64.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/powerpc/kernel/signal_64.c +3 -1
@@ -473,8 +473,10 @@ static long restore_tm_sigcontexts(struc err |=__get_user (tsk->thread.ckpt_regs.ccr, &sc->gp_regs[PT_CCR ]); +/* Don't allow userspace to set the trap value */ + regs->trap =0 ; +/* These regs are not checkpointed; they can go in 'regs'. */ - err |=__get_user (regs->trap, &sc->gp_regs[PT_TRAP ]); err |=__get_user (regs->dar, &sc->gp_regs[PT_DAR ]); err |=__get_user (regs->dsisr, &sc->gp_regs[PT_DSISR ]); err |=__get_user (regs->result, &sc->gp_regs[PT_RESULT ]);
Greg Kroah-Hartman
maintainerPATCH 208/232 powerpc/fsl_booke: Avoid creating duplicate tlb1 entry
In reply to Greg Kroah-HartmanFrom: Laurentiu Tudor <[email protected]>
commit aa4113340ae6c2811e046f08c2bc21011d20a072 upstream.
In the current implementation, the call to loadcam_multi() is wrapped between switch_to_as1() and restore_to_as0() calls so, when it tries to create its own temporary AS=1 TLB1 entry, it ends up duplicating the existing one created by switch_to_as1(). Add a check to skip creating the temporary entry if already running in AS=1.
--- arch/powerpc/mm/nohash/tlb_low.S | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
arch/powerpc/mm/nohash/tlb_low.S +11 -1
@@ -397,7 +397,7 @@ _GLOBAL(set_context) * extern void loadcam_entry(unsigned int index) * * Load TLBCAM[index] entry in to the L2 CAM MMU - * Must preserve r7, r8, r9, and r10 + * Must preserve r7, r8, r9, r10 and r11 */ _GLOBAL(loadcam_entry) mflr r5
@@ -433,6 +433,10 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PH */ _GLOBAL(loadcam_multi) mflr r8 + /* Don't switch to AS=1 if already there */ + mfmsr r11 + andi. r11,r11,MSR_IS + bne 10f /* * Set up temporary TLB entry that is the same as what we're
@@ -458,6 +462,7 @@ _GLOBAL(loadcam_multi) mtmsr r6 isync +10: mr r9,r3 add r10,r3,r4 2: bl loadcam_entry
@@ -466,6 +471,10 @@ _GLOBAL(loadcam_multi) mr r3,r9 blt 2b + /* Don't return to AS=0 if we were in AS=1 at function start */ + andi. r11,r11,MSR_IS + bne 3f + /* Return to AS=0 and clear the temporary entry */ mfmsr r6 rlwinm. r6,r6,0,~(MSR_IS|MSR_DS)
@@ -481,6 +490,7 @@ _GLOBAL(loadcam_multi) tlbwe isync +3: mtlr r8 blr #endif
Greg Kroah-Hartman
maintainerPATCH 209/232 powerpc/hash64/devmap: Use H_PAGE_THP_HUGE when setting up huge devmap PTE entries
In reply to Greg Kroah-HartmanFrom: Aneesh Kumar K.V <[email protected]>
commit 36b78402d97a3b9aeab136feb9b00d8647ec2c20 upstream.
H_PAGE_THP_HUGE is used to differentiate between a THP hugepage and hugetlb hugepage entries. The difference is WRT how we handle hash fault on these address. THP address enables MPSS in segments. We want to manage devmap hugepage entries similar to THP pt entries. Hence use H_PAGE_THP_HUGE for devmap huge PTE entries.
With current code while handling hash PTE fault, we do set is_thp = true when finding devmap PTE huge PTE entries.
Current code also does the below sequence we setting up huge devmap entries.
entry = pmd_mkhuge(pfn_t_pmd(pfn, prot)); if (pfn_t_devmap(pfn)) entry = pmd_mkdevmap(entry);
In that case we would find both H_PAGE_THP_HUGE and PAGE_DEVMAP set for huge devmap PTE entries. This results in false positive error like below.
kernel BUG at /home/kvaneesh/src/linux/mm/memory.c:4321!
Oops: Exception in kernel mode, sig: 5 [#1]
LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
Modules linked in:
CPU: 56 PID: 67996 Comm: t_mmap_dio Not tainted 5.6.0-rc4-59640-g371c804dedbc #128
....
NIP [c00000000044c9e4] __follow_pte_pmd+0x264/0x900
LR [c0000000005d45f8] dax_writeback_one+0x1a8/0x740
Call Trace:
str_spec.74809+0x22ffb4/0x2d116c (unreliable)
dax_writeback_one+0x1a8/0x740
dax_writeback_mapping_range+0x26c/0x700
ext4_dax_writepages+0x150/0x5a0
do_writepages+0x68/0x180
__filemap_fdatawrite_range+0x138/0x180
file_write_and_wait_range+0xa4/0x110
ext4_sync_file+0x370/0x6e0
vfs_fsync_range+0x70/0xf0
sys_msync+0x220/0x2e0
system_call+0x5c/0x68This is because our pmd_trans_huge check doesn't exclude _PAGE_DEVMAP.
To make this all consistent, update pmd_mkdevmap to set H_PAGE_THP_HUGE and pmd_trans_huge check now excludes _PAGE_DEVMAP correctly.
--- arch/powerpc/include/asm/book3s/64/hash-4k.h | 6 ++++++ arch/powerpc/include/asm/book3s/64/hash-64k.h | 8 +++++++- arch/powerpc/include/asm/book3s/64/pgtable.h | 4 +++- arch/powerpc/include/asm/book3s/64/radix.h | 5 +++++ 4 files changed, 21 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/book3s/64/hash-4k.h +6 -0
@@ -156,6 +156,12 @@ extern pmd_t hash__pmdp_huge_get_and_cleextern int hash__has_transparent_hugepage (void );#endif +static inline pmd_t hash__pmd_mkdevmap (pmd_t pmd) +{ +BUG (); +return pmd; +} +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */
arch/powerpc/include/asm/book3s/64/hash-64k.h +7 -1
@@ -246,7 +246,7 @@ static inline void mark_hpte_slot_valid(*/ static inline int hash__pmd_trans_huge (pmd_t pmd) { -return !!((pmd_val (pmd) & (_PAGE_PTE |H_PAGE_THP_HUGE )) == +return !!((pmd_val (pmd) & (_PAGE_PTE |H_PAGE_THP_HUGE | _PAGE_DEVMAP)) == (_PAGE_PTE |H_PAGE_THP_HUGE )); }
@@ -272,6 +272,12 @@ extern pmd_t hash__pmdp_huge_get_and_cle unsigned long addr, pmd_t *pmdp);extern int hash__has_transparent_hugepage (void );#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + +static inline pmd_t hash__pmd_mkdevmap (pmd_t pmd) +{ +return __pmd (pmd_val (pmd) | (_PAGE_PTE |H_PAGE_THP_HUGE | _PAGE_DEVMAP)); +} +#endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
arch/powerpc/include/asm/book3s/64/pgtable.h +3 -1
@@ -1303,7 +1303,9 @@ extern void serialize_against_pte_lookupstatic inline pmd_t pmd_mkdevmap (pmd_t pmd) { -return __pmd (pmd_val (pmd) | (_PAGE_PTE | _PAGE_DEVMAP)); +if (radix_enabled ()) +return radix__pmd_mkdevmap (pmd); +return hash__pmd_mkdevmap (pmd); }static inline int pmd_devmap (pmd_t pmd)
arch/powerpc/include/asm/book3s/64/radix.h +5 -0
@@ -263,6 +263,11 @@ static inline int radix__has_transparent }#endif +static inline pmd_t radix__pmd_mkdevmap (pmd_t pmd) +{ +return __pmd (pmd_val (pmd) | (_PAGE_PTE | _PAGE_DEVMAP)); +} +extern int __meminit radix__vmemmap_create_mapping (unsigned long start,unsigned long page_size,unsigned long phys);
Greg Kroah-Hartman
maintainerPATCH 210/232 powerpc/xive: Use XIVE_BAD_IRQ instead of zero to catch non configured IPIs
In reply to Greg Kroah-HartmanFrom: Cédric Le Goater <[email protected]>
commit b1a504a6500df50e83b701b7946b34fce27ad8a3 upstream.
When a CPU is brought up, an IPI number is allocated and recorded under the XIVE CPU structure. Invalid IPI numbers are tracked with interrupt number 0x0.
On the PowerNV platform, the interrupt number space starts at 0x10 and this works fine. However, on the sPAPR platform, it is possible to allocate the interrupt number 0x0 and this raises an issue when CPU 0 is unplugged. The XIVE spapr driver tracks allocated interrupt numbers in a bitmask and it is not correctly updated when interrupt number 0x0 is freed. It stays allocated and it is then impossible to reallocate.
Fix by using the XIVE_BAD_IRQ value instead of zero on both platforms.
--- arch/powerpc/sysdev/xive/common.c | 12 +++--------- arch/powerpc/sysdev/xive/native.c | 4 ++-- arch/powerpc/sysdev/xive/spapr.c | 4 ++-- arch/powerpc/sysdev/xive/xive-internal.h | 7 +++++++ 4 files changed, 14 insertions(+), 13 deletions(-)
arch/powerpc/sysdev/xive/common.c +3 -9
@@ -68,13 +68,6 @@ static u32 xive_ipi_irq;/* Xive state for each CPU */ static DEFINE_PER_CPU(struct xive_cpu *, xive_cpu); -/* -* A "disabled" interrupt should never fire, to catch problems -* we set its logical number to this -*/ -#define XIVE_BAD_IRQ 0x7fffffff -#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1) -/* An invalid CPU target */ #define XIVE_INVALID_TARGET (-1)
@@ -1150,7 +1143,7 @@ static int xive_setup_cpu_ipi(unsigned i xc =per_cpu (xive_cpu, cpu);/* Check if we are already setup */ -if (xc->hw_ipi !=0 ) +if (xc->hw_ipi !=XIVE_BAD_IRQ )return 0 ;/* Grab an IPI from the backend, this will populate xc->hw_ipi */
@@ -1187,7 +1180,7 @@ static void xive_cleanup_cpu_ipi(unsigne/* Disable the IPI and free the IRQ data */ /* Already cleaned up ? */ -if (xc->hw_ipi ==0 ) +if (xc->hw_ipi ==XIVE_BAD_IRQ )return ;/* Mask the IPI */
@@ -1343,6 +1336,7 @@ static int xive_prepare_cpu(unsigned intif (np) xc->chip_id =of_get_ibm_chip_id (np);of_node_put (np); + xc->hw_ipi =XIVE_BAD_IRQ ;per_cpu (xive_cpu, cpu) = xc; }
arch/powerpc/sysdev/xive/native.c +2 -2
@@ -312,7 +312,7 @@ static void xive_native_put_ipi(unsigneds64 rc;/* Free the IPI */ -if (!xc->hw_ipi) +if (xc->hw_ipi ==XIVE_BAD_IRQ )return ;for (;;) { rc =opal_xive_free_irq (xc->hw_ipi);
@@ -320,7 +320,7 @@ static void xive_native_put_ipi(unsignedmsleep (OPAL_BUSY_DELAY_MS );continue ; } - xc->hw_ipi =0 ; + xc->hw_ipi =XIVE_BAD_IRQ ;break ; } }
arch/powerpc/sysdev/xive/spapr.c +2 -2
@@ -560,11 +560,11 @@ static int xive_spapr_get_ipi(unsigned istatic void xive_spapr_put_ipi (unsigned int cpu,struct xive_cpu *xc) { -if (!xc->hw_ipi) +if (xc->hw_ipi ==XIVE_BAD_IRQ )return ;xive_irq_bitmap_free (xc->hw_ipi); - xc->hw_ipi =0 ; + xc->hw_ipi =XIVE_BAD_IRQ ; }#endif /* CONFIG_SMP */
arch/powerpc/sysdev/xive/xive-internal.h +7 -0
@@ -5,6 +5,13 @@ #ifndef __XIVE_INTERNAL_H #define __XIVE_INTERNAL_H +/* + * A "disabled" interrupt should never fire, to catch problems + * we set its logical number to this + */ +#define XIVE_BAD_IRQ 0x7fffffff +#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1) + /* Each CPU carry one of these with various per-CPU state */ struct xive_cpu { #ifdef CONFIG_SMP
Greg Kroah-Hartman
maintainerPATCH 211/232 powerpc/64: Setup a paca before parsing device tree etc.
In reply to Greg Kroah-HartmanFrom: Daniel Axtens <[email protected]>
commit d4a8e98621543d5798421eed177978bf2b3cdd11 upstream.
Currently we set up the paca after parsing the device tree for CPU features. Prior to that, r13 contains random data, which means there is random data in r13 while we're running the generic dt parsing code.
This random data varies depending on whether we boot through a vmlinux or a zImage: for the vmlinux case it's usually around zero, but for zImages we see random values like 912a72603d420015.
This is poor practice, and can also lead to difficult-to-debug crashes. For example, when kcov is enabled, the kcov instrumentation attempts to read preempt_count out of the current task, which goes via the paca. This then crashes in the zImage case.
Similarly stack protector can cause crashes if r13 is bogus, by reading from the stack canary in the paca.
To resolve this:
- move the paca setup to before the CPU feature parsing.
- because we no longer have access to CPU feature flags in paca setup, change the HV feature test in the paca setup path to consider the actual value of the MSR rather than the CPU feature.
Translations get switched on once we leave early_setup, so I think we'd already catch any other cases where the paca or task aren't set up.
Boot tested on a P9 guest and host.
--- arch/powerpc/kernel/dt_cpu_ftrs.c | 1 - arch/powerpc/kernel/paca.c | 10 +++++++--- arch/powerpc/kernel/setup_64.c | 30 ++++++++++++++++++++++++------ 3 files changed, 31 insertions(+), 10 deletions(-)
arch/powerpc/kernel/dt_cpu_ftrs.c +0 -1
@@ -139,7 +139,6 @@ static void __init cpufeatures_setup_cpu/* Initialize the base environment -- clear FSCR/HFSCR. */ hv_mode = !!(mfmsr () &MSR_HV );if (hv_mode) { -/* CPU_FTR_HVMODE is used early in PACA setup */ cur_cpu_spec->cpu_features |=CPU_FTR_HVMODE ;mtspr (SPRN_HFSCR ,0 ); }
arch/powerpc/kernel/paca.c +7 -3
@@ -214,11 +214,15 @@ void setup_paca(struct paca_struct *new_/* On Book3E, initialize the TLB miss exception frames */ mtspr (SPRN_SPRG_TLB_EXFRAME , local_paca->extlb);#else -/* In HV mode, we setup both HPACA and PACA to avoid problems +/* +* In HV mode, we setup both HPACA and PACA to avoid problems * if we do a GET_PACA() before the feature fixups have been -* applied +* applied. +* +* Normally you should test against CPU_FTR_HVMODE, but CPU features +* are not yet set up when we first reach here. */ -if (early_cpu_has_feature (CPU_FTR_HVMODE )) +if (mfmsr () &MSR_HV )mtspr (SPRN_SPRG_HPACA , local_paca);#endif mtspr (SPRN_SPRG_PACA , local_paca);
arch/powerpc/kernel/setup_64.c +24 -6
@@ -290,18 +290,36 @@ void __init early_setup(unsigned long dt/* -------- printk is _NOT_ safe to use here ! ------- */ -/* Try new device tree based feature discovery ... */ -if (!dt_cpu_ftrs_init (__va (dt_ptr))) -/* Otherwise use the old style CPU table */ -identify_cpu (0 ,mfspr (SPRN_PVR )); - -/* Assume we're on cpu 0 for now. Don't write to the paca yet! */ +/* +* Assume we're on cpu 0 for now. +* +* We need to load a PACA very early for a few reasons. +* +* The stack protector canary is stored in the paca, so as soon as we +* call any stack protected code we need r13 pointing somewhere valid. +* +* If we are using kcov it will call in_task() in its instrumentation, +* which relies on the current task from the PACA. +* +* dt_cpu_ftrs_init() calls into generic OF/fdt code, as well as +* printk(), which can trigger both stack protector and kcov. +* +* percpu variables and spin locks also use the paca. +* +* So set up a temporary paca. It will be replaced below once we know +* what CPU we are on. +*/ initialise_paca (&boot_paca,0 );setup_paca (&boot_paca);fixup_boot_paca ();/* -------- printk is now safe to use ------- */ +/* Try new device tree based feature discovery ... */ +if (!dt_cpu_ftrs_init (__va (dt_ptr))) +/* Otherwise use the old style CPU table */ +identify_cpu (0 ,mfspr (SPRN_PVR )); +/* Enable early debugging if any specified (see udbg.h) */ udbg_early_init ();
Greg Kroah-Hartman
maintainerPATCH 212/232 powerpc/xive: Fix xmon support on the PowerNV platform
In reply to Greg Kroah-HartmanFrom: Cédric Le Goater <[email protected]>
commit 97ef275077932c65b1b8ec5022abd737a9fbf3e0 upstream.
The PowerNV platform has multiple IRQ chips and the xmon command dumping the state of the XIVE interrupt should only operate on the XIVE IRQ chip.
--- arch/powerpc/sysdev/xive/common.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/powerpc/sysdev/xive/common.c +4 -0
@@ -258,11 +258,15 @@ notrace void xmon_xive_do_dump(int cpu)int xmon_xive_get_irq_config (u32 hw_irq,struct irq_data *d) { +struct irq_chip *chip =irq_data_get_irq_chip (d);int rc;u32 target;u8 prio;u32 lirq; +if (!is_xive_irq (chip)) +return -EINVAL ; + rc = xive_ops->get_irq_config (hw_irq, &target, &prio, &lirq);if (rc) {xmon_printf ("IRQ 0x%08x : no config rc=%d\n" , hw_irq, rc);
Greg Kroah-Hartman
maintainerPATCH 213/232 powerpc/kprobes: Ignore traps that happened in real mode
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 21f8b2fa3ca5b01f7a2b51b89ce97a3705a15aa0 upstream.
When a program check exception happens while MMU translation is disabled, following Oops happens in kprobe_handler() in the following code:
} else if (*addr != BREAKPOINT_INSTRUCTION) {BUG: Unable to handle kernel data access on read at 0x0000e268 Faulting instruction address: 0xc000ec34 Oops: Kernel access of bad area, sig: 11 [#1] BE PAGE_SIZE=16K PREEMPT CMPC885 Modules linked in: CPU: 0 PID: 429 Comm: cat Not tainted 5.6.0-rc1-s3k-dev-00824-g84195dc6c58a #3267 NIP: c000ec34 LR: c000ecd8 CTR: c019cab8 REGS: ca4d3b58 TRAP: 0300 Not tainted (5.6.0-rc1-s3k-dev-00824-g84195dc6c58a) MSR: 00001032 <ME,IR,DR,RI> CR: 2a4d3c52 XER: 00000000 DAR: 0000e268 DSISR: c0000000 GPR00: c000b09c ca4d3c10 c66d0620 00000000 ca4d3c60 00000000 00009032 00000000 GPR08: 00020000 00000000 c087de44 c000afe0 c66d0ad0 100d3dd6 fffffff3 00000000 GPR16: 00000000 00000041 00000000 ca4d3d70 00000000 00000000 0000416d 00000000 GPR24: 00000004 c53b6128 00000000 0000e268 00000000 c07c0000 c07bb6fc ca4d3c60 NIP [c000ec34] kprobe_handler+0x128/0x290 LR [c000ecd8] kprobe_handler+0x1cc/0x290 Call Trace: [ca4d3c30] [c000b09c] program_check_exception+0xbc/0x6fc [ca4d3c50] [c000e43c] ret_from_except_full+0x0/0x4 --- interrupt: 700 at 0xe268 Instruction dump: 913e0008 81220000 38600001 3929ffff 91220000 80010024 bb410008 7c0803a6 38210020 4e800020 38600000 4e800020 <813b0000> 6d2a7fe0 2f8a0008 419e0154 ---[ end trace 5b9152d4cdadd06d ]---
kprobe is not prepared to handle events in real mode and functions running in real mode should have been blacklisted, so kprobe_handler() can safely bail out telling 'this trap is not mine' for any trap that happened while in real-mode.
If the trap happened with MSR_IR or MSR_DR cleared, return 0 immediately.
--- arch/powerpc/kernel/kprobes.c | 3 +++ 1 file changed, 3 insertions(+)
arch/powerpc/kernel/kprobes.c +3 -0
@@ -264,6 +264,9 @@ int kprobe_handler(struct pt_regs *regs)if (user_mode (regs))return 0 ; +if (!(regs->msr &MSR_IR ) || !(regs->msr &MSR_DR )) +return 0 ; +/* * We don't want to be preempted for the entire * duration of kprobe processing
Greg Kroah-Hartman
maintainerPATCH 214/232 powerpc/64: Prevent stack protection in early boot
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
commit 7053f80d96967d8e72e9f2a724bbfc3906ce2b07 upstream.
The previous commit reduced the amount of code that is run before we setup a paca. However there are still a few remaining functions that run with no paca, or worse, with an arbitrary value in r13 that will be used as a paca pointer.
In particular the stack protector canary is stored in the paca, so if stack protector is activated for any of these functions we will read the stack canary from wherever r13 points. If r13 happens to point outside of memory we will get a machine check / checkstop.
For example if we modify initialise_paca() to trigger stack protection, and then boot in the mambo simulator with r13 poisoned in skiboot before calling the kernel:
DEBUG: 19952232: (19952232): INSTRUCTION: PC=0xC0000000191FC1E8: [0x3C4C006D]: addis r2,r12,0x6D [fetch]
DEBUG: 19952236: (19952236): INSTRUCTION: PC=0xC00000001807EAD8: [0x7D8802A6]: mflr r12 [fetch]
FATAL ERROR: 19952276: (19952276): Check Stop for 0:0: Machine Check with ME bit of MSR off
DEBUG: 19952276: (19952276): INSTRUCTION: PC=0xC0000000191FCA7C: [0xE90D0CF8]: ld r8,0xCF8(r13) [Instruction Failed]
INFO: 19952276: (19952277): ** Execution stopped: Mambo Error, Machine Check Stop, ** systemsim % bt
pc: 0xC0000000191FCA7C initialise_paca+0x54 lr: 0xC0000000191FC22C early_setup+0x44 stack:0x00000000198CBED0 0x0 +0x0 stack:0x00000000198CBF00 0xC0000000191FC22C early_setup+0x44 stack:0x00000000198CBF90 0x1801C968 +0x1801C968
So annotate the relevant functions to ensure stack protection is never enabled for them.
--- arch/powerpc/kernel/paca.c | 4 ++-- arch/powerpc/kernel/setup.h | 6 ++++++ arch/powerpc/kernel/setup_64.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-)
arch/powerpc/kernel/paca.c +2 -2
@@ -176,7 +176,7 @@ static struct slb_shadow * __init new_slstruct paca_struct **paca_ptrs__read_mostly ;EXPORT_SYMBOL (paca_ptrs); -void __init initialise_paca (struct paca_struct *new_paca,int cpu) +void __init __nostackprotector initialise_paca(struct paca_struct *new_paca, int cpu) {#ifdef CONFIG_PPC_PSERIES new_paca->lppaca_ptr =NULL ;
@@ -205,7 +205,7 @@ void __init initialise_paca(struct paca_ }/* Put the paca pointer into r13 and SPRG_PACA */ -void setup_paca (struct paca_struct *new_paca) +void __nostackprotector setup_paca(struct paca_struct *new_paca) {/* Setup r13 */ local_paca = new_paca;
arch/powerpc/kernel/setup.h +6 -0
@@ -8,6 +8,12 @@#ifndef __ARCH_POWERPC_KERNEL_SETUP_H#define __ARCH_POWERPC_KERNEL_SETUP_H +#ifdef CONFIG_CC_IS_CLANG +#define __nostackprotector +#else +#define __nostackprotector __attribute__((__optimize__("no-stack-protector"))) +#endif +void initialize_cache_info (void );void irqstack_early_init (void );
arch/powerpc/kernel/setup_64.c +1 -1
@@ -284,7 +284,7 @@ void __init record_spr_defaults(void)* device-tree is not accessible via normal means at this point. */ -void __init early_setup (unsigned long dt_ptr) +void __init __nostackprotector early_setup(unsigned long dt_ptr) {static __initdata struct paca_struct boot_paca;
Greg Kroah-Hartman
maintainerPATCH 215/232 scsi: mpt3sas: Fix kernel panic observed on soft HBA unplug
In reply to Greg Kroah-HartmanFrom: Sreekanth Reddy <[email protected]>
commit cc41f11a21a51d6869d71e525a7264c748d7c0d7 upstream.
Generic protection fault type kernel panic is observed when user performs soft (ordered) HBA unplug operation while IOs are running on drives connected to HBA.
When user performs ordered HBA removal operation, the kernel calls PCI device's .remove() call back function where driver is flushing out all the outstanding SCSI IO commands with DID_NO_CONNECT host byte and also unmaps sg buffers allocated for these IO commands.
However, in the ordered HBA removal case (unlike of real HBA hot removal), HBA device is still alive and hence HBA hardware is performing the DMA operations to those buffers on the system memory which are already unmapped while flushing out the outstanding SCSI IO commands and this leads to kernel panic.
Don't flush out the outstanding IOs from .remove() path in case of ordered removal since HBA will be still alive in this case and it can complete the outstanding IOs. Flush out the outstanding IOs only in case of 'physical HBA hot unplug' where there won't be any communication with the HBA.
During shutdown also it is possible that HBA hardware can perform DMA operations on those outstanding IO buffers which are completed with DID_NO_CONNECT by the driver from .shutdown(). So same above fix is applied in shutdown path as well.
It is safe to drop the outstanding commands when HBA is inaccessible such as when permanent PCI failure happens, when HBA is in non-operational state, or when someone does a real HBA hot unplug operation. Since driver knows that HBA is inaccessible during these cases, it is safe to drop the outstanding commands instead of waiting for SCSI error recovery to kick in and clear these outstanding commands.
--- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/scsi/mpt3sas/mpt3sas_scsih.c +4 -4
@@ -9747,8 +9747,8 @@ static void scsih_remove(struct pci_dev ioc->remove_host =1 ; -mpt3sas_wait_for_commands_to_complete (ioc); -_scsih_flush_running_cmds (ioc); +if (!pci_device_is_present (pdev)) +_scsih_flush_running_cmds (ioc);_scsih_fw_event_cleanup_queue (ioc);
@@ -9831,8 +9831,8 @@ scsih_shutdown(struct pci_dev *pdev) ioc->remove_host =1 ; -mpt3sas_wait_for_commands_to_complete (ioc); -_scsih_flush_running_cmds (ioc); +if (!pci_device_is_present (pdev)) +_scsih_flush_running_cmds (ioc);_scsih_fw_event_cleanup_queue (ioc);
Greg Kroah-Hartman
maintainerPATCH 216/232 powerpc: Make setjmp/longjmp signature standard
In reply to Greg Kroah-HartmanFrom: Clement Courbet <[email protected]>
commit c17eb4dca5a353a9dbbb8ad6934fe57af7165e91 upstream.
Declaring setjmp()/longjmp() as taking longs makes the signature non-standard, and makes clang complain. In the past, this has been worked around by adding -ffreestanding to the compile flags.
The implementation looks like it only ever propagates the value (in longjmp) or sets it to 1 (in setjmp), and we only call longjmp with integer parameters.
This allows removing -ffreestanding from the compilation flags.
--- arch/powerpc/include/asm/setjmp.h | 6 ++++-- arch/powerpc/kernel/Makefile | 3 --- arch/powerpc/xmon/Makefile | 3 --- 3 files changed, 4 insertions(+), 8 deletions(-)
arch/powerpc/include/asm/setjmp.h +4 -2
@@ -7,7 +7,9 @@#define JMP_BUF_LEN 23 -extern long setjmp (long *) __attribute__((returns_twice)); -extern void longjmp (long *,long ) __attribute__((noreturn)); +typedef long jmp_buf [JMP_BUF_LEN ]; + +extern int setjmp (jmp_buf env) __attribute__((returns_twice)); +extern void longjmp (jmp_buf env,int val) __attribute__((noreturn));#endif /* _ASM_POWERPC_SETJMP_H */
arch/powerpc/kernel/Makefile +0 -3
@@ -5,9 +5,6 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' -# Avoid clang warnings around longjmp/setjmp declarations -CFLAGS_crash.o += -ffreestanding - ifdef CONFIG_PPC64 CFLAGS_prom_init.o += $(NO_MINIMAL_TOC) endif
arch/powerpc/xmon/Makefile +0 -3
@@ -1,9 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 # Makefile for xmon -# Avoid clang warnings around longjmp/setjmp declarations -subdir-ccflags-y := -ffreestanding - GCOV_PROFILE := n KCOV_INSTRUMENT := n UBSAN_SANITIZE := n
Greg Kroah-Hartman
maintainerPATCH 217/232 arm64: Always force a branch protection mode when the compiler has one
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
commit b8fdef311a0bd9223f10754f94fdcf1a594a3457 upstream.
Compilers with branch protection support can be configured to enable it by default, it is likely that distributions will do this as part of deploying branch protection system wide. As well as the slight overhead from having some extra NOPs for unused branch protection features this can cause more serious problems when the kernel is providing pointer authentication to userspace but not built for pointer authentication itself. In that case our switching of keys for userspace can affect the kernel unexpectedly, causing pointer authentication instructions in the kernel to corrupt addresses.
To ensure that we get consistent and reliable behaviour always explicitly initialise the branch protection mode, ensuring that the kernel is built the same way regardless of the compiler defaults.
[This is a reworked version of b8fdef311a0bd9223f1075 ("arm64: Always force a branch protection mode when the compiler has one") for backport. Kernels prior to 74afda4016a7 ("arm64: compile the kernel with ptrauth return address signing") don't have any Makefile machinery for forcing on pointer auth but still have issues if the compiler defaults it on so need this reworked version. -- broonie]
--- arch/arm64/Makefile | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm64/Makefile +4 -0
@@ -72,6 +72,10 @@ stack_protector_prepare: prepare0 include/generated/asm-offsets.h)) endif +# Ensure that if the compiler supports branch protection we default it +# off. +KBUILD_CFLAGS += $(call cc-option,-mbranch-protection=none) + ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) KBUILD_CPPFLAGS += -mbig-endian CHECKFLAGS += -D__AARCH64EB__
Greg Kroah-Hartman
maintainerPATCH 218/232 dm zoned: remove duplicate nr_rnd_zones increase in dmz_init_zone()
In reply to Greg Kroah-HartmanFrom: Bob Liu <[email protected]>
[ Upstream commit b8fdd090376a7a46d17db316638fe54b965c2fb0 ]
zmd->nr_rnd_zones was increased twice by mistake. The other place it is increased in dmz_init_zone() is the only one needed:
1131 zmd->nr_useable_zones++;
1132 if (dmz_is_rnd(zone)) {
1133 zmd->nr_rnd_zones++; ^^^
--- drivers/md/dm-zoned-metadata.c | 1 - 1 file changed, 1 deletion(-)
drivers/md/dm-zoned-metadata.c +0 -1
@@ -1107,7 +1107,6 @@ static int dmz_init_zone(struct dmz_metadata *zmd, struct dm_zone *zone,if (blkz->type ==BLK_ZONE_TYPE_CONVENTIONAL ) {set_bit (DMZ_RND , &zone->flags); - zmd->nr_rnd_zones++; }else if (blkz->type ==BLK_ZONE_TYPE_SEQWRITE_REQ || blkz->type ==BLK_ZONE_TYPE_SEQWRITE_PREF ) {set_bit (DMZ_SEQ , &zone->flags);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 219/232 dm clone: replace spin_lock_irqsave with spin_lock_irq
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
[ Upstream commit 6ca43ed8376a51afec790dd484a51804ade4352a ]
If we are in a place where it is known that interrupts are enabled, functions spin_lock_irq/spin_unlock_irq should be used instead of spin_lock_irqsave/spin_unlock_irqrestore.
spin_lock_irq and spin_unlock_irq are faster because they don't need to push and pop the flags register.
--- drivers/md/dm-clone-metadata.c | 29 ++++++++++++----------------- drivers/md/dm-clone-metadata.h | 4 +++- drivers/md/dm-clone-target.c | 28 ++++++++++++---------------- 3 files changed, 27 insertions(+), 34 deletions(-)
drivers/md/dm-clone-metadata.c +12 -17
@@ -748,7 +748,7 @@ static int __metadata_commit(struct dm_clone_metadata *cmd)static int __flush_dmap (struct dm_clone_metadata *cmd,struct dirty_map *dmap) {int r; -unsigned long word, flags; +unsigned long word; word =0 ; do {
@@ -772,9 +772,9 @@ static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap)return r;/* Update the changed flag */ -spin_lock_irqsave (&cmd->bitmap_lock, flags); +spin_lock_irq (&cmd->bitmap_lock); dmap->changed =0 ; -spin_unlock_irqrestore (&cmd->bitmap_lock, flags); +spin_unlock_irq (&cmd->bitmap_lock);return 0 ; }
@@ -782,7 +782,6 @@ static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap)int dm_clone_metadata_pre_commit (struct dm_clone_metadata *cmd) {int r =0 ; -unsigned long flags;struct dirty_map *dmap, *next_dmap;down_write (&cmd->lock);
@@ -808,9 +807,9 @@ int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd) }/* Swap dirty bitmaps */ -spin_lock_irqsave (&cmd->bitmap_lock, flags); +spin_lock_irq (&cmd->bitmap_lock); cmd->current_dmap = next_dmap; -spin_unlock_irqrestore (&cmd->bitmap_lock, flags); +spin_unlock_irq (&cmd->bitmap_lock);/* Set old dirty bitmap as currently committing */ cmd->committing_dmap = dmap;
@@ -878,9 +877,9 @@ int dm_clone_cond_set_range(struct dm_clone_metadata *cmd, unsigned long start, {int r =0 ;struct dirty_map *dmap; -unsigned long word, region_nr, flags; +unsigned long word, region_nr; -spin_lock_irqsave (&cmd->bitmap_lock, flags); +spin_lock_irq (&cmd->bitmap_lock);if (cmd->read_only) { r = -EPERM ;
@@ -898,7 +897,7 @@ int dm_clone_cond_set_range(struct dm_clone_metadata *cmd, unsigned long start, } } out: -spin_unlock_irqrestore (&cmd->bitmap_lock, flags); +spin_unlock_irq (&cmd->bitmap_lock);return r; }
@@ -965,13 +964,11 @@ int dm_clone_metadata_abort(struct dm_clone_metadata *cmd)void dm_clone_metadata_set_read_only (struct dm_clone_metadata *cmd) { -unsigned long flags; -down_write (&cmd->lock); -spin_lock_irqsave (&cmd->bitmap_lock, flags); +spin_lock_irq (&cmd->bitmap_lock); cmd->read_only =1 ; -spin_unlock_irqrestore (&cmd->bitmap_lock, flags); +spin_unlock_irq (&cmd->bitmap_lock);if (!cmd->fail_io)dm_bm_set_read_only (cmd->bm);
@@ -981,13 +978,11 @@ void dm_clone_metadata_set_read_only(struct dm_clone_metadata *cmd)void dm_clone_metadata_set_read_write (struct dm_clone_metadata *cmd) { -unsigned long flags; -down_write (&cmd->lock); -spin_lock_irqsave (&cmd->bitmap_lock, flags); +spin_lock_irq (&cmd->bitmap_lock); cmd->read_only =0 ; -spin_unlock_irqrestore (&cmd->bitmap_lock, flags); +spin_unlock_irq (&cmd->bitmap_lock);if (!cmd->fail_io)dm_bm_set_read_write (cmd->bm);
drivers/md/dm-clone-metadata.h +3 -1
@@ -44,7 +44,9 @@ int dm_clone_set_region_hydrated(struct dm_clone_metadata *cmd, unsigned long re* @start: Starting region number * @nr_regions: Number of regions in the range * -* This function doesn't block, so it's safe to call it from interrupt context. +* This function doesn't block, but since it uses spin_lock_irq()/spin_unlock_irq() +* it's NOT safe to call it from any context where interrupts are disabled, e.g., +* from interrupt context. */ int dm_clone_cond_set_range (struct dm_clone_metadata *cmd,unsigned long start,unsigned long nr_regions);
drivers/md/dm-clone-target.c +12 -16
@@ -338,8 +338,6 @@ static void submit_bios(struct bio_list *bios)*/ static void issue_bio (struct clone *clone,struct bio *bio) { -unsigned long flags; -if (!bio_triggers_commit (clone, bio)) {generic_make_request (bio);return ;
@@ -358,9 +356,9 @@ static void issue_bio(struct clone *clone, struct bio *bio)* Batch together any bios that trigger commits and then issue a single * commit for them in process_deferred_flush_bios(). */ -spin_lock_irqsave (&clone->lock, flags); +spin_lock_irq (&clone->lock);bio_list_add (&clone->deferred_flush_bios, bio); -spin_unlock_irqrestore (&clone->lock, flags); +spin_unlock_irq (&clone->lock);wake_worker (clone); }
@@ -475,7 +473,7 @@ static void complete_discard_bio(struct clone *clone, struct bio *bio, bool succstatic void process_discard_bio (struct clone *clone,struct bio *bio) { -unsigned long rs, re, flags; +unsigned long rs, re;bio_region_range (clone, bio, &rs, &re);BUG_ON (re > clone->nr_regions);
@@ -507,9 +505,9 @@ static void process_discard_bio(struct clone *clone, struct bio *bio)/* * Defer discard processing. */ -spin_lock_irqsave (&clone->lock, flags); +spin_lock_irq (&clone->lock);bio_list_add (&clone->deferred_discard_bios, bio); -spin_unlock_irqrestore (&clone->lock, flags); +spin_unlock_irq (&clone->lock);wake_worker (clone); }
@@ -1167,13 +1165,13 @@ static void process_deferred_discards(struct clone *clone)int r = -EPERM ;struct bio *bio;struct blk_plug plug; -unsigned long rs, re, flags; +unsigned long rs, re;struct bio_list discards =BIO_EMPTY_LIST ; -spin_lock_irqsave (&clone->lock, flags); +spin_lock_irq (&clone->lock);bio_list_merge (&discards, &clone->deferred_discard_bios);bio_list_init (&clone->deferred_discard_bios); -spin_unlock_irqrestore (&clone->lock, flags); +spin_unlock_irq (&clone->lock);if (bio_list_empty (&discards))return ;
@@ -1203,13 +1201,12 @@ static void process_deferred_discards(struct clone *clone)static void process_deferred_bios (struct clone *clone) { -unsigned long flags;struct bio_list bios =BIO_EMPTY_LIST ; -spin_lock_irqsave (&clone->lock, flags); +spin_lock_irq (&clone->lock);bio_list_merge (&bios, &clone->deferred_bios);bio_list_init (&clone->deferred_bios); -spin_unlock_irqrestore (&clone->lock, flags); +spin_unlock_irq (&clone->lock);if (bio_list_empty (&bios))return ;
@@ -1220,7 +1217,6 @@ static void process_deferred_bios(struct clone *clone)static void process_deferred_flush_bios (struct clone *clone) {struct bio *bio; -unsigned long flags;bool dest_dev_flushed;struct bio_list bios =BIO_EMPTY_LIST ;struct bio_list bio_completions =BIO_EMPTY_LIST ;
@@ -1229,13 +1225,13 @@ static void process_deferred_flush_bios(struct clone *clone)* If there are any deferred flush bios, we must commit the metadata * before issuing them or signaling their completion. */ -spin_lock_irqsave (&clone->lock, flags); +spin_lock_irq (&clone->lock);bio_list_merge (&bios, &clone->deferred_flush_bios);bio_list_init (&clone->deferred_flush_bios);bio_list_merge (&bio_completions, &clone->deferred_flush_completions);bio_list_init (&clone->deferred_flush_completions); -spin_unlock_irqrestore (&clone->lock, flags); +spin_unlock_irq (&clone->lock);if (bio_list_empty (&bios) &&bio_list_empty (&bio_completions) && !(dm_clone_changed_this_transaction (clone->cmd) &&need_commit_due_to_time (clone)))
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 220/232 dm clone: Fix handling of partial region discards
In reply to Greg Kroah-HartmanFrom: Nikos Tsironis <[email protected]>
[ Upstream commit 4b5142905d4ff58a4b93f7c8eaa7ba829c0a53c9 ]
There is a bug in the way dm-clone handles discards, which can lead to discarding the wrong blocks or trying to discard blocks beyond the end of the device.
This could lead to data corruption, if the destination device indeed discards the underlying blocks, i.e., if the discard operation results in the original contents of a block to be lost.
The root of the problem is the code that calculates the range of regions covered by a discard request and decides which regions to discard.
Since dm-clone handles the device in units of regions, we don't discard parts of a region, only whole regions.
The range is calculated as:
rs = dm_sector_div_up(bio->bi_iter.bi_sector, clone->region_size);
re = bio_end_sector(bio) >> clone->region_shift;, where 'rs' is the first region to discard and (re - rs) is the number of regions to discard.
The bug manifests when we try to discard part of a single region, i.e., when we try to discard a block with size < region_size, and the discard request both starts at an offset with respect to the beginning of that region and ends before the end of the region.
The root cause is the following comparison:
if (rs == re)
// skip discard and complete original bio immediately
, which doesn't take into account that 'rs' might be greater than 're'.
Thus, we then issue a discard request for the wrong blocks, instead of skipping the discard all together.
Fix the check to also take into account the above case, so we don't end up discarding the wrong blocks.
Also, add some range checks to dm_clone_set_region_hydrated() and dm_clone_cond_set_range(), which update dm-clone's region bitmap.
Note that the aforementioned bug doesn't cause invalid memory accesses, because dm_clone_is_range_hydrated() returns True for this case, so the checks are just precautionary.
--- drivers/md/dm-clone-metadata.c | 13 ++++++++++ drivers/md/dm-clone-target.c | 43 +++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 14 deletions(-)
drivers/md/dm-clone-metadata.c +13 -0
@@ -850,6 +850,12 @@ int dm_clone_set_region_hydrated(struct dm_clone_metadata *cmd, unsigned long restruct dirty_map *dmap;unsigned long word, flags; +if (unlikely (region_nr >= cmd->nr_regions)) { +DMERR ("Region %lu out of range (total number of regions %lu)" , + region_nr, cmd->nr_regions); +return -ERANGE ; + } + word = region_nr /BITS_PER_LONG ;spin_lock_irqsave (&cmd->bitmap_lock, flags);
@@ -879,6 +885,13 @@ int dm_clone_cond_set_range(struct dm_clone_metadata *cmd, unsigned long start,struct dirty_map *dmap;unsigned long word, region_nr; +if (unlikely (start >= cmd->nr_regions || (start + nr_regions) < start || + (start + nr_regions) > cmd->nr_regions)) { +DMERR ("Invalid region range: start %lu, nr_regions %lu (total number of regions %lu)" , + start, nr_regions, cmd->nr_regions); +return -ERANGE ; + } +spin_lock_irq (&cmd->bitmap_lock);if (cmd->read_only) {
drivers/md/dm-clone-target.c +29 -14
95 lines not on this page · raw message
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 221/232 dm clone: Add missing casts to prevent overflows and data corruption
In reply to Greg Kroah-HartmanFrom: Nikos Tsironis <[email protected]>
[ Upstream commit 9fc06ff56845cc5ccafec52f545fc2e08d22f849 ]
Add missing casts when converting from regions to sectors.
In case BITS_PER_LONG == 32, the lack of the appropriate casts can lead to overflows and miscalculation of the device sector.
As a result, we could end up discarding and/or copying the wrong parts of the device, thus corrupting the device's data.
--- drivers/md/dm-clone-target.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/md/dm-clone-target.c +6 -3
@@ -282,7 +282,7 @@ static bool bio_triggers_commit(struct clone *clone, struct bio *bio)/* Get the address of the region in sectors */ static inline sector_t region_to_sector (struct clone *clone,unsigned long region_nr) { -return (region_nr << clone->region_shift); +return ((sector_t )region_nr << clone->region_shift); }/* Get the region number of the bio */
@@ -471,7 +471,7 @@ static void complete_discard_bio(struct clone *clone, struct bio *bio, bool succif (test_bit (DM_CLONE_DISCARD_PASSDOWN , &clone->flags) && success) {remap_to_dest (clone, bio);bio_region_range (clone, bio, &rs, &nr_regions); -trim_bio (bio, rs << clone->region_shift, +trim_bio (bio,region_to_sector (clone, rs), nr_regions << clone->region_shift);generic_make_request (bio); }else
@@ -798,11 +798,14 @@ static void hydration_copy(struct dm_clone_region_hydration *hd, unsigned int nrstruct dm_io_region from, to;struct clone *clone = hd->clone; +if (WARN_ON (!nr_regions)) +return ; + region_size = clone->region_size; region_start = hd->region_nr; region_end = region_start + nr_regions -1 ; - total_size = (nr_regions -1 ) << clone->region_shift; + total_size =region_to_sector (clone, nr_regions -1 );if (region_end == clone->nr_regions -1 ) {/*
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 222/232 scsi: lpfc: Add registration for CPU Offline/Online events
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 93a4d6f40198dffcca35d9a928c409f9290f1fe0 ]
The recent affinitization didn't address cpu offlining/onlining. If an interrupt vector is shared and the low order cpu owning the vector is offlined, as interrupts are managed, the vector is taken offline. This causes the other CPUs sharing the vector will hang as they can't get io completions.
Correct by registering callbacks with the system for Offline/Online events. When a cpu is taken offline, its eq, which is tied to an interrupt vector is found. If the cpu is the "owner" of the vector and if the eq/vector is shared by other CPUs, the eq is placed into a polled mode. Additionally, code paths that perform io submission on the "sharing CPUs" will check the eq state and poll for completion after submission of new io to a wq that uses the eq.
Similarly, when a cpu comes back online and owns an offlined vector, the eq is taken out of polled mode and rearmed to start driving interrupts for eq.
--- drivers/scsi/lpfc/lpfc.h | 7 ++ drivers/scsi/lpfc/lpfc_crtn.h | 6 + drivers/scsi/lpfc/lpfc_init.c | 202 +++++++++++++++++++++++++++++++++- drivers/scsi/lpfc/lpfc_sli.c | 164 ++++++++++++++++++++++++++- drivers/scsi/lpfc/lpfc_sli4.h | 21 +++- 5 files changed, 388 insertions(+), 12 deletions(-)
drivers/scsi/lpfc/lpfc.h +7 -0
@@ -1209,6 +1209,13 @@ struct lpfc_hba {uint64_t ktime_seg10_min;uint64_t ktime_seg10_max;#endif + +struct hlist_node cpuhp;/* used for cpuhp per hba callback */ +struct timer_list cpuhp_poll_timer; +struct list_head poll_list;/* slowpath eq polling list */ +#define LPFC_POLL_HB 1/* slowpath heartbeat */ +#define LPFC_POLL_FASTPATH 0/* called from fastpath */ +#define LPFC_POLL_SLOWPATH 1/* called from slowpath */ }; static inline struct Scsi_Host *
drivers/scsi/lpfc/lpfc_crtn.h +6 -0
@@ -215,6 +215,12 @@ irqreturn_t lpfc_sli_fp_intr_handler(int, void *);irqreturn_t lpfc_sli4_intr_handler (int ,void *);irqreturn_t lpfc_sli4_hba_intr_handler (int ,void *); +inline void lpfc_sli4_cleanup_poll_list (struct lpfc_hba *phba); +int lpfc_sli4_poll_eq (struct lpfc_queue *q,uint8_t path); +void lpfc_sli4_poll_hbtimer (struct timer_list *t); +void lpfc_sli4_start_polling (struct lpfc_queue *q); +void lpfc_sli4_stop_polling (struct lpfc_queue *q); +void lpfc_read_rev (struct lpfc_hba *,LPFC_MBOXQ_t *);void lpfc_sli4_swap_str (struct lpfc_hba *,LPFC_MBOXQ_t *);void lpfc_config_ring (struct lpfc_hba *,int ,LPFC_MBOXQ_t *);
drivers/scsi/lpfc/lpfc_init.c +198 -4
266 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli.c +159 -5
234 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli4.h +18 -3
@@ -133,6 +133,23 @@ struct lpfc_rqb {struct lpfc_queue {struct list_head list;struct list_head wq_list; + +/* +* If interrupts are in effect on _all_ the eq's the footprint +* of polling code is zero (except mode). This memory is chec- +* ked for every io to see if the io needs to be polled and +* while completion to check if the eq's needs to be rearmed. +* Keep in same cacheline as the queue ptr to avoid cpu fetch +* stalls. Using 1B memory will leave us with 7B hole. Fill +* it with other frequently used members. +*/ +uint16_t last_cpu;/* most recent cpu */ +uint16_t hdwq; +uint8_t qe_valid; +uint8_t mode;/* interrupt or polling */ +#define LPFC_EQ_INTERRUPT 0 +#define LPFC_EQ_POLL 1 +struct list_head wqfull_list;enum lpfc_sli4_queue_type type;enum lpfc_sli4_queue_subtype subtype;
@@ -239,10 +256,8 @@ struct lpfc_queue {struct delayed_work sched_spwork;uint64_t isr_timestamp; -uint16_t hdwq; -uint16_t last_cpu;/* most recent cpu */ -uint8_t qe_valid;struct lpfc_queue *assoc_qp; +struct list_head _poll_list;void **q_pgs;/* array to index entries per page */ };
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 223/232 scsi: lpfc: Fix Fabric hostname registration if system hostname changes
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit e3ba04c9bad1d1c7f15df43da25e878045150777 ]
There are reports of multiple ports on the same system displaying different hostnames in fabric FDMI displays.
Currently, the driver registers the hostname at initialization and obtains the hostname via init_utsname()->nodename queried at the time the FC link comes up. Unfortunately, if the machine hostname is updated after initialization, such as via DHCP or admin command, the value registered initially will be incorrect.
Fix by having the driver save the hostname that was registered with FDMI. The driver then runs a heartbeat action that will check the hostname. If the name changes, reregister the FMDI data.
The hostname is used in RSNN_NN, FDMI RPA and FDMI RHBA.
--- drivers/scsi/lpfc/lpfc.h | 2 ++ drivers/scsi/lpfc/lpfc_crtn.h | 2 +- drivers/scsi/lpfc/lpfc_ct.c | 48 ++++++++++++++++++++++++-------- drivers/scsi/lpfc/lpfc_hbadisc.c | 5 ++++ drivers/scsi/lpfc/lpfc_init.c | 2 +- 5 files changed, 46 insertions(+), 13 deletions(-)
drivers/scsi/lpfc/lpfc.h +2 -0
@@ -1216,6 +1216,8 @@ struct lpfc_hba {#define LPFC_POLL_HB 1/* slowpath heartbeat */ #define LPFC_POLL_FASTPATH 0/* called from fastpath */ #define LPFC_POLL_SLOWPATH 1/* called from slowpath */ + +char os_host_name[MAXHOSTNAMELEN ]; }; static inline struct Scsi_Host *
drivers/scsi/lpfc/lpfc_crtn.h +1 -1
@@ -180,7 +180,7 @@ int lpfc_issue_gidft(struct lpfc_vport *vport);int lpfc_get_gidft_type (struct lpfc_vport *vport,struct lpfc_iocbq *iocbq);int lpfc_ns_cmd (struct lpfc_vport *,int ,uint8_t ,uint32_t );int lpfc_fdmi_cmd (struct lpfc_vport *,struct lpfc_nodelist *,int ,uint32_t ); -void lpfc_fdmi_num_disc_check (struct lpfc_vport *); +void lpfc_fdmi_change_check (struct lpfc_vport *vport);void lpfc_delayed_disc_tmo (struct timer_list *);void lpfc_delayed_disc_timeout_handler (struct lpfc_vport *);
drivers/scsi/lpfc/lpfc_ct.c +37 -11
83 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_hbadisc.c +5 -0
@@ -28,6 +28,7 @@#include <linux/kthread.h> #include <linux/interrupt.h> #include <linux/lockdep.h> +#include <linux/utsname.h> #include <scsi/scsi.h> #include <scsi/scsi_device.h>
@@ -3322,6 +3323,10 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)lpfc_sli4_clear_fcf_rr_bmask (phba); } +/* Prepare for LINK up registrations */ +memset (phba->os_host_name,0 ,sizeof (phba->os_host_name)); +scnprintf (phba->os_host_name,sizeof (phba->os_host_name),"%s" , +init_utsname ()->nodename);return ; out:lpfc_vport_set_state (vport,FC_VPORT_FAILED );
drivers/scsi/lpfc/lpfc_init.c +1 -1
@@ -1370,7 +1370,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)if (vports !=NULL )for (i =0 ; i <= phba->max_vports && vports[i] !=NULL ; i++) {lpfc_rcv_seq_check_edtov (vports[i]); -lpfc_fdmi_num_disc_check (vports[i]); +lpfc_fdmi_change_check (vports[i]); }lpfc_destroy_vport_work_array (phba, vports);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 224/232 scsi: lpfc: Fix configuration of BB credit recovery in service parameters
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 6bfb1620829825c01e1dcdd63b6a7700352babd9 ]
The driver today is reading service parameters from the firmware and then overwriting the firmware-provided values with values of its own. There are some switch features that require preliminary FLOGI's that are switch-specific and done prior to the actual fabric FLOGI for traffic. The fw will perform those FLOGIs and will revise the service parameters for the features configured. As the driver later overwrites those values with its own values, it misconfigures things like BBSCN use by doing so.
Correct by eliminating the driver-overwrite of firmware values. The driver correctly re-reads the service parameters after each link up to obtain the latest values from firmware.
--- drivers/scsi/lpfc/lpfc_hbadisc.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
drivers/scsi/lpfc/lpfc_hbadisc.c +3 -10
@@ -1139,7 +1139,6 @@ void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { struct lpfc_vport *vport = pmb->vport; -uint8_t bbscn =0 ;if (pmb->u.mb.mbxStatus) goto out;
@@ -1166,17 +1165,11 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)/* Start discovery by sending a FLOGI. port_state is identically * LPFC_FLOGI while waiting for FLOGI cmpl */ -if (vport->port_state !=LPFC_FLOGI ) { -if (phba->bbcredit_support && phba->cfg_enable_bbcr) { - bbscn =bf_get (lpfc_bbscn_def, - &phba->sli4_hba.bbscn_params); - vport->fc_sparam.cmn.bbRcvSizeMsb &=0xf ; - vport->fc_sparam.cmn.bbRcvSizeMsb |= (bbscn <<4 ); - } +if (vport->port_state !=LPFC_FLOGI )lpfc_initial_flogi (vport); - }else if (vport->fc_flag &FC_PT2PT ) { +else if (vport->fc_flag &FC_PT2PT )lpfc_disc_start (vport); - } +return ; out:
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 225/232 scsi: lpfc: Fix broken Credit Recovery after driver load
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 835214f5d5f516a38069bc077c879c7da00d6108 ]
When driver is set to enable bb credit recovery, the switch displayed the setting as inactive. If the link bounces, it switches to Active.
During link up processing, the driver currently does a MBX_READ_SPARAM followed by a MBX_CONFIG_LINK. These mbox commands are queued to be executed, one at a time and the completion is processed by the worker thread. Since the MBX_READ_SPARAM is done BEFORE the MBX_CONFIG_LINK, the BB_SC_N bit is never set the the returned values. BB Credit recovery status only gets set after the driver requests the feature in CONFIG_LINK, which is done after the link up. Thus the ordering of READ_SPARAM needs to follow the CONFIG_LINK.
Fix by reordering so that READ_SPARAM is done after CONFIG_LINK. Added a HBA_DEFER_FLOGI flag so that any FLOGI handling waits until after the READ_SPARAM is done so that the proper BB credit value is set in the FLOGI payload.
--- drivers/scsi/lpfc/lpfc.h | 1 + drivers/scsi/lpfc/lpfc_hbadisc.c | 59 +++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 20 deletions(-)
drivers/scsi/lpfc/lpfc.h +1 -0
@@ -742,6 +742,7 @@ struct lpfc_hba {* capability */ #define HBA_FLOGI_ISSUED 0x100000/* FLOGI was issued */ +#define HBA_DEFER_FLOGI 0x800000/* Defer FLOGI till read_sparm cmpl */ uint32_t fcp_ring_in_use;/* When polling test if intr-hndlr active*/ struct lpfc_dmabuf slim2p;
drivers/scsi/lpfc/lpfc_hbadisc.c +39 -20
90 lines not on this page · raw message
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 226/232 Revert "drm/dp_mst: Remove VCPI while disabling topology mgr"
In reply to Greg Kroah-Hartman[ Upstream commit a86675968e2300fb567994459da3dbc4cd1b322a ]
This reverts commit 64e62bdf04ab8529f45ed0a85122c703035dec3a.
This commit ends up causing some lockdep splats due to trying to grab the payload lock while holding the mgr's lock:
[ 54.010099]
[ 54.011765] ======================================================
[ 54.018670] WARNING: possible circular locking dependency detected
[ 54.025577] 5.5.0-rc6-02274-g77381c23ee63 #47 Not tainted
[ 54.031610] ------------------------------------------------------
[ 54.038516] kworker/1:6/1040 is trying to acquire lock:
[ 54.044354] ffff888272af3228 (&mgr->payload_lock){+.+.}, at:
drm_dp_mst_topology_mgr_set_mst+0x218/0x2e4
[ 54.054957]
[ 54.054957] but task is already holding lock:
[ 54.061473] ffff888272af3060 (&mgr->lock){+.+.}, at:
drm_dp_mst_topology_mgr_set_mst+0x3c/0x2e4
[ 54.071193]
[ 54.071193] which lock already depends on the new lock.
[ 54.071193]
[ 54.080334]
[ 54.080334] the existing dependency chain (in reverse order) is:
[ 54.088697]
[ 54.088697] -> #1 (&mgr->lock){+.+.}:
[ 54.094440] __mutex_lock+0xc3/0x498
[ 54.099015] drm_dp_mst_topology_get_port_validated+0x25/0x80
[ 54.106018] drm_dp_update_payload_part1+0xa2/0x2e2
[ 54.112051] intel_mst_pre_enable_dp+0x144/0x18f
[ 54.117791] intel_encoders_pre_enable+0x63/0x70
[ 54.123532] hsw_crtc_enable+0xa1/0x722
[ 54.128396] intel_update_crtc+0x50/0x194
[ 54.133455] skl_commit_modeset_enables+0x40c/0x540
[ 54.139485] intel_atomic_commit_tail+0x5f7/0x130d
[ 54.145418] intel_atomic_commit+0x2c8/0x2d8
[ 54.150770] drm_atomic_helper_set_config+0x5a/0x70
[ 54.156801] drm_mode_setcrtc+0x2ab/0x833
[ 54.161862] drm_ioctl+0x2e5/0x424
[ 54.166242] vfs_ioctl+0x21/0x2f
[ 54.170426] do_vfs_ioctl+0x5fb/0x61e
[ 54.175096] ksys_ioctl+0x55/0x75
[ 54.179377] __x64_sys_ioctl+0x1a/0x1e
[ 54.184146] do_syscall_64+0x5c/0x6d
[ 54.188721] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 54.194946]
[ 54.194946] -> #0 (&mgr->payload_lock){+.+.}:
[ 54.201463]
[ 54.201463] other info that might help us debug this:
[ 54.201463]
[ 54.210410] Possible unsafe locking scenario:
[ 54.210410]
[ 54.217025] CPU0 CPU1
[ 54.222082] ---- ----
[ 54.227138] lock(&mgr->lock);
[ 54.230643] lock(&mgr->payload_lock);
[ 54.237742] lock(&mgr->lock);
[ 54.244062] lock(&mgr->payload_lock);
[ 54.248346]
[ 54.248346] *** DEADLOCK ***
[ 54.248346]
[ 54.254959] 7 locks held by kworker/1:6/1040:
[ 54.259822] #0: ffff888275c4f528 ((wq_completion)events){+.+.},
at: worker_thread+0x455/0x6e2
[ 54.269451] #1: ffffc9000119beb0
((work_completion)(&(&dev_priv->hotplug.hotplug_work)->work)){+.+.},
at: worker_thread+0x455/0x6e2
[ 54.282768] #2: ffff888272a403f0 (&dev->mode_config.mutex){+.+.},
at: i915_hotplug_work_func+0x4b/0x2be
[ 54.293368] #3: ffffffff824fc6c0 (drm_connector_list_iter){.+.+},
at: i915_hotplug_work_func+0x17e/0x2be
[ 54.304061] #4: ffffc9000119bc58 (crtc_ww_class_acquire){+.+.},
at: drm_helper_probe_detect_ctx+0x40/0xfd
[ 54.314855] #5: ffff888272a40470 (crtc_ww_class_mutex){+.+.}, at:
drm_modeset_lock+0x74/0xe2
[ 54.324385] #6: ffff888272af3060 (&mgr->lock){+.+.}, at:
drm_dp_mst_topology_mgr_set_mst+0x3c/0x2e4
[ 54.334597]
[ 54.334597] stack backtrace:
[ 54.339464] CPU: 1 PID: 1040 Comm: kworker/1:6 Not tainted
5.5.0-rc6-02274-g77381c23ee63 #47
[ 54.348893] Hardware name: Google Fizz/Fizz, BIOS
Google_Fizz.10139.39.0 01/04/2018
[ 54.357451] Workqueue: events i915_hotplug_work_func
[ 54.362995] Call Trace:
[ 54.365724] dump_stack+0x71/0x9c
[ 54.369427] check_noncircular+0x91/0xbc
[ 54.373809] ? __lock_acquire+0xc9e/0xf66
[ 54.378286] ? __lock_acquire+0xc9e/0xf66
[ 54.382763] ? lock_acquire+0x175/0x1ac
[ 54.387048] ? drm_dp_mst_topology_mgr_set_mst+0x218/0x2e4
[ 54.393177] ? __mutex_lock+0xc3/0x498
[ 54.397362] ? drm_dp_mst_topology_mgr_set_mst+0x218/0x2e4
[ 54.403492] ? drm_dp_mst_topology_mgr_set_mst+0x218/0x2e4
[ 54.409620] ? drm_dp_dpcd_access+0xd9/0x101
[ 54.414390] ? drm_dp_mst_topology_mgr_set_mst+0x218/0x2e4
[ 54.420517] ? drm_dp_mst_topology_mgr_set_mst+0x218/0x2e4
[ 54.426645] ? intel_digital_port_connected+0x34d/0x35c
[ 54.432482] ? intel_dp_detect+0x227/0x44e
[ 54.437056] ? ww_mutex_lock+0x49/0x9a
[ 54.441242] ? drm_helper_probe_detect_ctx+0x75/0xfd
[ 54.446789] ? intel_encoder_hotplug+0x4b/0x97
[ 54.451752] ? intel_ddi_hotplug+0x61/0x2e0
[ 54.456423] ? mark_held_locks+0x53/0x68
[ 54.460803] ? _raw_spin_unlock_irqrestore+0x3a/0x51
[ 54.466347] ? lockdep_hardirqs_on+0x187/0x1a4
[ 54.471310] ? drm_connector_list_iter_next+0x89/0x9a
[ 54.476953] ? i915_hotplug_work_func+0x206/0x2be
[ 54.482208] ? worker_thread+0x4d5/0x6e2
[ 54.486587] ? worker_thread+0x455/0x6e2
[ 54.490966] ? queue_work_on+0x64/0x64
[ 54.495151] ? kthread+0x1e9/0x1f1
[ 54.498946] ? queue_work_on+0x64/0x64
[ 54.503130] ? kthread_unpark+0x5e/0x5e
[ 54.507413] ? ret_from_fork+0x3a/0x50The proper fix for this is probably cleanup the VCPI allocations when we're enabling the topology, or on the first payload allocation. For now though, let's just revert.
--- drivers/gpu/drm/drm_dp_mst_topology.c | 12 ------------ 1 file changed, 12 deletions(-)
drivers/gpu/drm/drm_dp_mst_topology.c +0 -12
@@ -2694,7 +2694,6 @@ static bool drm_dp_get_vc_payload_bw(int dp_link_bw,int drm_dp_mst_topology_mgr_set_mst (struct drm_dp_mst_topology_mgr *mgr,bool mst_state) {int ret =0 ; -int i =0 ;struct drm_dp_mst_branch *mstb =NULL ;mutex_lock (&mgr->lock);
@@ -2755,21 +2754,10 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms/* this can fail if the device is gone */ drm_dp_dpcd_writeb (mgr->aux,DP_MSTM_CTRL ,0 ); ret =0 ; -mutex_lock (&mgr->payload_lock);memset (mgr->payloads,0 , mgr->max_payloads *sizeof (struct drm_dp_payload )); mgr->payload_mask =0 ;set_bit (0 , &mgr->payload_mask); -for (i =0 ; i < mgr->max_payloads; i++) { -struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i]; - -if (vcpi) { - vcpi->vcpi =0 ; - vcpi->num_slots =0 ; - } - mgr->proposed_vcpis[i] =NULL ; - } mgr->vcpi_mask =0 ; -mutex_unlock (&mgr->payload_lock); } out_unlock:
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 227/232 drm/dp_mst: Fix clearing payload state on topology disable
In reply to Greg Kroah-HartmanFrom: Lyude Paul <[email protected]>
[ Upstream commit 8732fe46b20c951493bfc4dba0ad08efdf41de81 ]
The issues caused by:
commit 64e62bdf04ab ("drm/dp_mst: Remove VCPI while disabling topology mgr")
Prompted me to take a closer look at how we clear the payload state in general when disabling the topology, and it turns out there's actually two subtle issues here.
The first is that we're not grabbing &mgr.payload_lock when clearing the payloads in drm_dp_mst_topology_mgr_set_mst(). Seeing as the canonical lock order is &mgr.payload_lock -> &mgr.lock (because we always want &mgr.lock to be the inner-most lock so topology validation always works), this makes perfect sense. It also means that -technically- there could be racing between someone calling drm_dp_mst_topology_mgr_set_mst() to disable the topology, along with a modeset occurring that's modifying the payload state at the same time.
The second is the more obvious issue that Wayne Lin discovered, that we're not clearing proposed_payloads when disabling the topology.
I actually can't see any obvious places where the racing caused by the first issue would break something, and it could be that some of our higher-level locks already prevent this by happenstance, but better safe then sorry. So, let's make it so that drm_dp_mst_topology_mgr_set_mst() first grabs &mgr.payload_lock followed by &mgr.lock so that we never race when modifying the payload state. Then, we also clear proposed_payloads to fix the original issue of enabling a new topology with a dirty payload state. This doesn't clear any of the drm_dp_vcpi structures, but those are getting destroyed along with the ports anyway.
Changes since v1:
* Use sizeof(mgr->payloads[0])/sizeof(mgr->proposed_vcpis[0]) instead - vsyrjala
--- drivers/gpu/drm/drm_dp_mst_topology.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/drm_dp_mst_topology.c +6 -1
@@ -2696,6 +2696,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool msint ret =0 ;struct drm_dp_mst_branch *mstb =NULL ; +mutex_lock (&mgr->payload_lock);mutex_lock (&mgr->lock);if (mst_state == mgr->mst_state) goto out_unlock;
@@ -2754,7 +2755,10 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms/* this can fail if the device is gone */ drm_dp_dpcd_writeb (mgr->aux,DP_MSTM_CTRL ,0 ); ret =0 ; -memset (mgr->payloads,0 , mgr->max_payloads *sizeof (struct drm_dp_payload )); +memset (mgr->payloads,0 , + mgr->max_payloads *sizeof (mgr->payloads[0 ])); +memset (mgr->proposed_vcpis,0 , + mgr->max_payloads *sizeof (mgr->proposed_vcpis[0 ])); mgr->payload_mask =0 ;set_bit (0 , &mgr->payload_mask); mgr->vcpi_mask =0 ;
@@ -2762,6 +2766,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms out_unlock:mutex_unlock (&mgr->lock); +mutex_unlock (&mgr->payload_lock);if (mstb)drm_dp_mst_topology_put_mstb (mstb);return ret;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 228/232 drm/amdgpu: fix gfx hang during suspend with video playback (v2)
In reply to Greg Kroah-HartmanFrom: Prike Liang <[email protected]>
[ Upstream commit 487eca11a321ef33bcf4ca5adb3c0c4954db1b58 ]
The system will be hang up during S3 suspend because of SMU is pending for GC not respose the register CP_HQD_ACTIVE access request.This issue root cause of accessing the GC register under enter GFX CGGPG and can be fixed by disable GFX CGPG before perform suspend.
v2: Use disable the GFX CGPG instead of RLC safe mode guard.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +3 -2
@@ -2176,8 +2176,6 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev) {int i, r; -amdgpu_device_set_pg_state (adev,AMD_PG_STATE_UNGATE ); -amdgpu_device_set_cg_state (adev,AMD_CG_STATE_UNGATE );for (i = adev->num_ip_blocks -1 ; i >=0 ; i--) {if (!adev->ip_blocks[i].status.valid)
@@ -3070,6 +3068,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) } } +amdgpu_device_set_pg_state (adev,AMD_PG_STATE_UNGATE ); +amdgpu_device_set_cg_state (adev,AMD_CG_STATE_UNGATE ); +amdgpu_amdkfd_suspend (adev);amdgpu_ras_suspend (adev);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 229/232 drm/i915/icl+: Dont enable DDI IO power on a TypeC port in TBT mode
In reply to Greg Kroah-HartmanFrom: Imre Deak <[email protected]>
The DDI IO power well must not be enabled for a TypeC port in TBT mode, ensure this during driver loading/system resume.
This gets rid of error messages like
[drm] *ERROR* power well DDI E TC2 IO state mismatch (refcount 1/enabled 0)
and avoids leaking the power ref when disabling the output.
--- drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_ddi.c +5 -1
@@ -2124,7 +2124,11 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,return ; dig_port =enc_to_dig_port (&encoder->base); -intel_display_power_get (dev_priv, dig_port->ddi_io_power_domain); + +if (!intel_phy_is_tc (dev_priv, phy) || + dig_port->tc_mode !=TC_PORT_TBT_ALT ) +intel_display_power_get (dev_priv, + dig_port->ddi_io_power_domain);/* * AUX power is only needed for (e)DP mode, and for HDMI mode on TC
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 230/232 powerpc/kasan: Fix kasan_remap_early_shadow_ro()
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
[ Upstream commit af92bad615be75c6c0d1b1c5b48178360250a187 ]
At the moment kasan_remap_early_shadow_ro() does nothing, because k_end is 0 and k_cur < 0 is always true.
Change the test to k_cur != k_end, as done inkasan_init_shadow_page_tables()
--- arch/powerpc/mm/kasan/kasan_init_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/mm/kasan/kasan_init_32.c +1 -1
@@ -117,7 +117,7 @@ static void __init kasan_remap_early_shadow_ro(void)kasan_populate_pte (kasan_early_shadow_pte, prot); -for (k_cur = k_start &PAGE_MASK ; k_cur < k_end; k_cur +=PAGE_SIZE ) { +for (k_cur = k_start &PAGE_MASK ; k_cur != k_end; k_cur +=PAGE_SIZE ) {pmd_t *pmd =pmd_offset (pud_offset (pgd_offset_k (k_cur), k_cur), k_cur);pte_t *ptep =pte_offset_kernel (pmd, k_cur);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 231/232 mmc: sdhci: Convert sdhci_set_timeout_irq() to non-static
In reply to Greg Kroah-HartmanFrom: Faiz Abbas <[email protected]>
[ Upstream commit 7907ebe741a7f14ed12889ebe770438a4ff47613 ]
Export sdhci_set_timeout_irq() so that it is accessible from platform drivers.
--- drivers/mmc/host/sdhci.c | 3 ++- drivers/mmc/host/sdhci.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/mmc/host/sdhci.c +2 -1
@@ -981,7 +981,7 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)sdhci_writel (host, host->ier,SDHCI_SIGNAL_ENABLE ); } -static void sdhci_set_data_timeout_irq (struct sdhci_host *host,bool enable) +void sdhci_set_data_timeout_irq (struct sdhci_host *host,bool enable) {if (enable) host->ier |=SDHCI_INT_DATA_TIMEOUT ;
@@ -990,6 +990,7 @@ static void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable)sdhci_writel (host, host->ier,SDHCI_INT_ENABLE );sdhci_writel (host, host->ier,SDHCI_SIGNAL_ENABLE ); } +EXPORT_SYMBOL_GPL (sdhci_set_data_timeout_irq);static void sdhci_set_timeout (struct sdhci_host *host,struct mmc_command *cmd) {
drivers/mmc/host/sdhci.h +1 -0
@@ -795,5 +795,6 @@ void sdhci_end_tuning(struct sdhci_host *host);void sdhci_reset_tuning (struct sdhci_host *host);void sdhci_send_tuning (struct sdhci_host *host,u32 opcode);void sdhci_abort_tuning (struct sdhci_host *host,u32 opcode); +void sdhci_set_data_timeout_irq (struct sdhci_host *host,bool enable);#endif /* __SDHCI_HW_H */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 232/232 mmc: sdhci: Refactor sdhci_set_timeout()
In reply to Greg Kroah-HartmanFrom: Faiz Abbas <[email protected]>
[ Upstream commit 7d76ed77cfbd39468ae58d419f537d35ca892d83 ]
Refactor sdhci_set_timeout() such that platform drivers can do some functionality in a set_timeout() callback and then call __sdhci_set_timeout() to complete the operation.
--- drivers/mmc/host/sdhci.c | 38 ++++++++++++++++++++------------------ drivers/mmc/host/sdhci.h | 1 + 2 files changed, 21 insertions(+), 18 deletions(-)
drivers/mmc/host/sdhci.c +20 -18
@@ -992,27 +992,29 @@ void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable) }EXPORT_SYMBOL_GPL (sdhci_set_data_timeout_irq); -static void sdhci_set_timeout (struct sdhci_host *host,struct mmc_command *cmd) +void __sdhci_set_timeout (struct sdhci_host *host,struct mmc_command *cmd) { -u8 count; - -if (host->ops->set_timeout) { - host->ops->set_timeout (host, cmd); - }else { -bool too_big = false; - - count =sdhci_calc_timeout (host, cmd, &too_big); +bool too_big = false; +u8 count =sdhci_calc_timeout (host, cmd, &too_big); + +if (too_big && + host->quirks2 &SDHCI_QUIRK2_DISABLE_HW_TIMEOUT ) { +sdhci_calc_sw_timeout (host, cmd); +sdhci_set_data_timeout_irq (host, false); + }else if (!(host->ier &SDHCI_INT_DATA_TIMEOUT )) { +sdhci_set_data_timeout_irq (host, true); + } -if (too_big && - host->quirks2 &SDHCI_QUIRK2_DISABLE_HW_TIMEOUT ) { -sdhci_calc_sw_timeout (host, cmd); -sdhci_set_data_timeout_irq (host, false); - }else if (!(host->ier &SDHCI_INT_DATA_TIMEOUT )) { -sdhci_set_data_timeout_irq (host, true); - } +sdhci_writeb (host, count,SDHCI_TIMEOUT_CONTROL ); +} +EXPORT_SYMBOL_GPL (__sdhci_set_timeout); -sdhci_writeb (host, count,SDHCI_TIMEOUT_CONTROL ); - } +static void sdhci_set_timeout (struct sdhci_host *host,struct mmc_command *cmd) +{ +if (host->ops->set_timeout) + host->ops->set_timeout (host, cmd); +else +__sdhci_set_timeout (host, cmd); }static void sdhci_prepare_data (struct sdhci_host *host,struct mmc_command *cmd)
drivers/mmc/host/sdhci.h +1 -0
@@ -796,5 +796,6 @@ void sdhci_reset_tuning(struct sdhci_host *host);void sdhci_send_tuning (struct sdhci_host *host,u32 opcode);void sdhci_abort_tuning (struct sdhci_host *host,u32 opcode);void sdhci_set_data_timeout_irq (struct sdhci_host *host,bool enable); +void __sdhci_set_timeout (struct sdhci_host *host,struct mmc_command *cmd);#endif /* __SDHCI_HW_H */
Signature · 1 line
2.20.1
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.33 release. There are 232 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Apr 2020 13:11:20 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.33-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
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 5.4.33-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-5.4.y
git commit: ccba204bf567bf5349e9635ea1fb8cd18d23c123
git describe: v5.4.32-233-gccba204bf567
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/build/v5.4.32-233-gccba204bf567
No regressions (compared to build v5.4.31-42-gf163418797b9)
No fixes (compared to build v5.4.31-42-gf163418797b9)
Ran 34739 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c
- hi6220-hikey
- i386
- juno-r2
- juno-r2-compat
- juno-r2-kasan
- nxp-ls2088
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15
- x86
- x86-kasan
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* install-android-platform-tools-r2800
* libgpiod
* linux-log-parser
* ltp-cve-tests
* ltp-hugetlb-tests
* ltp-ipc-tests
* ltp-mm-tests
* ltp-sched-tests
* ltp-syscalls-tests
* kselftest
* kvm-unit-tests
* libhugetlbfs
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-io-tests
* ltp-math-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-securebits-tests
* network-basic-tests
* perf
* v4l2-compliance
* ltp-fs-tests
* ltp-open-posix-tests
* spectre-meltdown-checker-test
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
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.33 release. There are 232 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Apr 2020 13:11:20 +0000. Anything received after that time might be too late.
Build results:
total: 157 pass: 157 fail: 0 Qemu test results: total: 427 pass: 427 fail: 0
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.33 release. There are 232 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Apr 2020 13:11:20 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.33-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
Compiled and booted on my test system. No dmesg regressions. reboot and poweroff hang forever. The same problem I am seeing on Linux 5.7-rc1 and Linux 5.6.5-rc1 and now on 5.4.33-rc1.
I am starting bisect on 5.6.5.
thanks,
-- Shuah
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.33 release. There are 232 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 18 Apr 2020 13:11:20 +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.33-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 are passing for Tegra ...
Test results for stable-v5.4:
13 builds: 13 pass, 0 fail
24 boots: 24 pass, 0 fail
40 tests: 40 pass, 0 failLinux version: 5.4.33-rc1-gccba204bf567
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Cheers
Jon
Signature · 1 line
nvpublic