
[PATCH openEuler-22.03-LTS-SP2] dma-debug: don't call __dma_entry_alloc_check_leak() under free_entries_lock
by Jinjiang Tu 15 Apr '24
by Jinjiang Tu 15 Apr '24
15 Apr '24
From: Sergey Senozhatsky <senozhatsky(a)chromium.org>
stable inclusion
from stable-v5.10.198
commit c79300599923daaa30f417c75555d5566b3d31ae
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I987V5
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit fb5a4315591dae307a65fc246ca80b5159d296e1 ]
__dma_entry_alloc_check_leak() calls into printk -> serial console
output (qcom geni) and grabs port->lock under free_entries_lock
spin lock, which is a reverse locking dependency chain as qcom_geni
IRQ handler can call into dma-debug code and grab free_entries_lock
under port->lock.
Move __dma_entry_alloc_check_leak() call out of free_entries_lock
scope so that we don't acquire serial console's port->lock under it.
Trimmed-down lockdep splat:
The existing dependency chain (in reverse order) is:
-> #2 (free_entries_lock){-.-.}-{2:2}:
_raw_spin_lock_irqsave+0x60/0x80
dma_entry_alloc+0x38/0x110
debug_dma_map_page+0x60/0xf8
dma_map_page_attrs+0x1e0/0x230
dma_map_single_attrs.constprop.0+0x6c/0xc8
geni_se_rx_dma_prep+0x40/0xcc
qcom_geni_serial_isr+0x310/0x510
__handle_irq_event_percpu+0x110/0x244
handle_irq_event_percpu+0x20/0x54
handle_irq_event+0x50/0x88
handle_fasteoi_irq+0xa4/0xcc
handle_irq_desc+0x28/0x40
generic_handle_domain_irq+0x24/0x30
gic_handle_irq+0xc4/0x148
do_interrupt_handler+0xa4/0xb0
el1_interrupt+0x34/0x64
el1h_64_irq_handler+0x18/0x24
el1h_64_irq+0x64/0x68
arch_local_irq_enable+0x4/0x8
____do_softirq+0x18/0x24
...
-> #1 (&port_lock_key){-.-.}-{2:2}:
_raw_spin_lock_irqsave+0x60/0x80
qcom_geni_serial_console_write+0x184/0x1dc
console_flush_all+0x344/0x454
console_unlock+0x94/0xf0
vprintk_emit+0x238/0x24c
vprintk_default+0x3c/0x48
vprintk+0xb4/0xbc
_printk+0x68/0x90
register_console+0x230/0x38c
uart_add_one_port+0x338/0x494
qcom_geni_serial_probe+0x390/0x424
platform_probe+0x70/0xc0
really_probe+0x148/0x280
__driver_probe_device+0xfc/0x114
driver_probe_device+0x44/0x100
__device_attach_driver+0x64/0xdc
bus_for_each_drv+0xb0/0xd8
__device_attach+0xe4/0x140
device_initial_probe+0x1c/0x28
bus_probe_device+0x44/0xb0
device_add+0x538/0x668
of_device_add+0x44/0x50
of_platform_device_create_pdata+0x94/0xc8
of_platform_bus_create+0x270/0x304
of_platform_populate+0xac/0xc4
devm_of_platform_populate+0x60/0xac
geni_se_probe+0x154/0x160
platform_probe+0x70/0xc0
...
-> #0 (console_owner){-...}-{0:0}:
__lock_acquire+0xdf8/0x109c
lock_acquire+0x234/0x284
console_flush_all+0x330/0x454
console_unlock+0x94/0xf0
vprintk_emit+0x238/0x24c
vprintk_default+0x3c/0x48
vprintk+0xb4/0xbc
_printk+0x68/0x90
dma_entry_alloc+0xb4/0x110
debug_dma_map_sg+0xdc/0x2f8
__dma_map_sg_attrs+0xac/0xe4
dma_map_sgtable+0x30/0x4c
get_pages+0x1d4/0x1e4 [msm]
msm_gem_pin_pages_locked+0x38/0xac [msm]
msm_gem_pin_vma_locked+0x58/0x88 [msm]
msm_ioctl_gem_submit+0xde4/0x13ac [msm]
drm_ioctl_kernel+0xe0/0x15c
drm_ioctl+0x2e8/0x3f4
vfs_ioctl+0x30/0x50
...
Chain exists of:
console_owner --> &port_lock_key --> free_entries_lock
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(free_entries_lock);
lock(&port_lock_key);
lock(free_entries_lock);
lock(console_owner);
*** DEADLOCK ***
Call trace:
dump_backtrace+0xb4/0xf0
show_stack+0x20/0x30
dump_stack_lvl+0x60/0x84
dump_stack+0x18/0x24
print_circular_bug+0x1cc/0x234
check_noncircular+0x78/0xac
__lock_acquire+0xdf8/0x109c
lock_acquire+0x234/0x284
console_flush_all+0x330/0x454
console_unlock+0x94/0xf0
vprintk_emit+0x238/0x24c
vprintk_default+0x3c/0x48
vprintk+0xb4/0xbc
_printk+0x68/0x90
dma_entry_alloc+0xb4/0x110
debug_dma_map_sg+0xdc/0x2f8
__dma_map_sg_attrs+0xac/0xe4
dma_map_sgtable+0x30/0x4c
get_pages+0x1d4/0x1e4 [msm]
msm_gem_pin_pages_locked+0x38/0xac [msm]
msm_gem_pin_vma_locked+0x58/0x88 [msm]
msm_ioctl_gem_submit+0xde4/0x13ac [msm]
drm_ioctl_kernel+0xe0/0x15c
drm_ioctl+0x2e8/0x3f4
vfs_ioctl+0x30/0x50
...
Reported-by: Rob Clark <robdclark(a)chromium.org>
Signed-off-by: Sergey Senozhatsky <senozhatsky(a)chromium.org>
Acked-by: Robin Murphy <robin.murphy(a)arm.com>
Signed-off-by: Christoph Hellwig <hch(a)lst.de>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: sanglipeng <sanglipeng1(a)jd.com>
---
kernel/dma/debug.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c
index ae9fc1ee6d20..026398308909 100644
--- a/kernel/dma/debug.c
+++ b/kernel/dma/debug.c
@@ -606,15 +606,19 @@ static struct dma_debug_entry *__dma_entry_alloc(void)
return entry;
}
-static void __dma_entry_alloc_check_leak(void)
+/*
+ * This should be called outside of free_entries_lock scope to avoid potential
+ * deadlocks with serial consoles that use DMA.
+ */
+static void __dma_entry_alloc_check_leak(u32 nr_entries)
{
- u32 tmp = nr_total_entries % nr_prealloc_entries;
+ u32 tmp = nr_entries % nr_prealloc_entries;
/* Shout each time we tick over some multiple of the initial pool */
if (tmp < DMA_DEBUG_DYNAMIC_ENTRIES) {
pr_info("dma_debug_entry pool grown to %u (%u00%%)\n",
- nr_total_entries,
- (nr_total_entries / nr_prealloc_entries));
+ nr_entries,
+ (nr_entries / nr_prealloc_entries));
}
}
@@ -625,8 +629,10 @@ static void __dma_entry_alloc_check_leak(void)
*/
static struct dma_debug_entry *dma_entry_alloc(void)
{
+ bool alloc_check_leak = false;
struct dma_debug_entry *entry;
unsigned long flags;
+ u32 nr_entries;
spin_lock_irqsave(&free_entries_lock, flags);
if (num_free_entries == 0) {
@@ -636,13 +642,17 @@ static struct dma_debug_entry *dma_entry_alloc(void)
pr_err("debugging out of memory - disabling\n");
return NULL;
}
- __dma_entry_alloc_check_leak();
+ alloc_check_leak = true;
+ nr_entries = nr_total_entries;
}
entry = __dma_entry_alloc();
spin_unlock_irqrestore(&free_entries_lock, flags);
+ if (alloc_check_leak)
+ __dma_entry_alloc_check_leak(nr_entries);
+
#ifdef CONFIG_STACKTRACE
entry->stack_len = stack_trace_save(entry->stack_entries,
ARRAY_SIZE(entry->stack_entries),
--
2.25.1
2
1

[PATCH OLK-6.6] mm, fs: Add BPF_READAHEAD_OPTIMIZATION option for bpf readhead
by ZhaoLong Wang 15 Apr '24
by ZhaoLong Wang 15 Apr '24
15 Apr '24
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I7Y9JD
CVE: NA
---------------------------
This patch introduces a new configuration option called
BPF_READAHEAD_OPTIMIZATION, which is designed to optimize the read
performance in Spark SQL scenarios using eBPF to implement a
programmable kernel.
The changes include:
- Add CONFIG_BPF_READAHEAD_OPTIMIZATION to mm/Kconfig, which depends
on CONFIG_TRACEPOINTS.
- Add conditional compilation directives to fs/ext4/file.c, fs/read_write.c,
fs/xfs/xfs_file.c, and include/linux/fs.h to include tracepoint-related
headers and functions only when BPF_READAHEAD_OPTIMIZATION is enabled.
- Miodify page_cache_sync_ra() in mm/readahead.c to disable forced readahead
when BPF_READAHEAD_OPTIMIZATION is not enabled.
V2:
Explicitly set CONFIG_ in openeuler_defconfig.
Do not add redundant macros to mm/readahead.
V3:
Place all macro isolation switches in the .h header file.
Signed-off-by: ZhaoLong Wang <wangzhaolong1(a)huawei.com>
---
arch/arm64/configs/openeuler_defconfig | 1 +
arch/powerpc/configs/openeuler_defconfig | 1 +
arch/riscv/configs/openeuler_defconfig | 1 +
arch/x86/configs/openeuler_defconfig | 1 +
fs/read_write.c | 4 ++--
include/linux/fs.h | 18 +++++++++++++-----
include/trace/events/fs.h | 7 +++++++
mm/Kconfig | 9 +++++++++
8 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
index ba4a04309879..a40a3daa3aa1 100644
--- a/arch/arm64/configs/openeuler_defconfig
+++ b/arch/arm64/configs/openeuler_defconfig
@@ -1192,6 +1192,7 @@ CONFIG_DYNAMIC_POOL=y
CONFIG_ETMEM_SCAN=m
CONFIG_ETMEM_SWAP=m
CONFIG_ETMEM=y
+# CONFIG_BPF_READAHEAD_OPTIMIZATION is not set
#
# Data Access Monitoring
diff --git a/arch/powerpc/configs/openeuler_defconfig b/arch/powerpc/configs/openeuler_defconfig
index 152b941da1d5..793cca85862c 100644
--- a/arch/powerpc/configs/openeuler_defconfig
+++ b/arch/powerpc/configs/openeuler_defconfig
@@ -860,6 +860,7 @@ CONFIG_ARCH_HAS_HUGEPD=y
CONFIG_USERFAULTFD=y
# CONFIG_LRU_GEN is not set
CONFIG_LOCK_MM_AND_FIND_VMA=y
+# CONFIG_BPF_READAHEAD_OPTIMIZATION is not set
#
# Data Access Monitoring
diff --git a/arch/riscv/configs/openeuler_defconfig b/arch/riscv/configs/openeuler_defconfig
index cb132f4576da..06caed7e855a 100644
--- a/arch/riscv/configs/openeuler_defconfig
+++ b/arch/riscv/configs/openeuler_defconfig
@@ -825,6 +825,7 @@ CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y
CONFIG_PER_VMA_LOCK=y
CONFIG_LOCK_MM_AND_FIND_VMA=y
# CONFIG_PAGE_CACHE_LIMIT is not set
+# CONFIG_BPF_READAHEAD_OPTIMIZATION is not set
#
# Data Access Monitoring
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
index f15f089419e6..e4298be905ff 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -1179,6 +1179,7 @@ CONFIG_DYNAMIC_POOL=y
CONFIG_ETMEM_SCAN=m
CONFIG_ETMEM_SWAP=m
CONFIG_ETMEM=y
+# CONFIG_BPF_READAHEAD_OPTIMIZATION is not set
#
# Data Access Monitoring
diff --git a/fs/read_write.c b/fs/read_write.c
index 3d69fb284d10..265e40589be8 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1721,7 +1721,7 @@ int generic_file_rw_checks(struct file *file_in, struct file *file_out)
return 0;
}
-#ifdef CONFIG_TRACEPOINTS
+#ifdef CONFIG_BPF_READAHEAD_OPTIMIZATION
static void fs_file_read_ctx_init(struct fs_file_read_ctx *ctx,
struct file *filp, loff_t pos)
{
@@ -1752,7 +1752,7 @@ void fs_file_read_update_args_by_trace(struct kiocb *iocb)
filp->f_ctl_mode &= ~(ctx.clr_f_mode & FS_FILE_READ_MODE_MASK);
}
EXPORT_SYMBOL_GPL(fs_file_read_update_args_by_trace);
-#endif
EXPORT_TRACEPOINT_SYMBOL_GPL(fs_file_read);
EXPORT_TRACEPOINT_SYMBOL_GPL(fs_file_release);
+#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d74314a8fa94..2702d38b57ab 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -43,7 +43,9 @@
#include <linux/cred.h>
#include <linux/mnt_idmapping.h>
#include <linux/slab.h>
+#ifdef CONFIG_BPF_READAHEAD_OPTIMIZATION
#include <linux/tracepoint-defs.h>
+#endif
#include <linux/kabi.h>
#include <asm/byteorder.h>
@@ -190,11 +192,16 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
/* File supports async nowait buffered writes */
#define FMODE_BUF_WASYNC ((__force fmode_t)0x80000000)
+#ifdef CONFIG_BPF_READAHEAD_OPTIMIZATION
/* File mode control flag, expect random access pattern */
#define FMODE_CTL_RANDOM ((__force fmode_t)0x1000)
/* File mode control flag, will try to read head of the file into pagecache */
#define FMODE_CTL_WILLNEED ((__force fmode_t)0x400000)
+#else
+#define FMODE_CTL_RANDOM 0
+#define FMODE_CTL_WILLNEED 0
+#endif
/*
* Attribute flags. These should be or-ed together to figure out what
@@ -3524,16 +3531,17 @@ struct fs_file_read_ctx {
long long index;
};
-#ifdef CONFIG_TRACEPOINTS
+#ifdef CONFIG_BPF_READAHEAD_OPTIMIZATION
DECLARE_TRACEPOINT(fs_file_read);
extern void fs_file_read_update_args_by_trace(struct kiocb *iocb);
-#else
-static inline void fs_file_read_update_args_by_trace(struct kiocb *iocb) {}
-#endif
-
static inline void fs_file_read_do_trace(struct kiocb *iocb)
{
if (tracepoint_enabled(fs_file_read))
fs_file_read_update_args_by_trace(iocb);
}
+#else
+static inline void fs_file_read_update_args_by_trace(struct kiocb *iocb) {}
+static inline void fs_file_read_do_trace(struct kiocb *iocb) {}
+#endif
+
#endif /* _LINUX_FS_H */
diff --git a/include/trace/events/fs.h b/include/trace/events/fs.h
index ee82dad9d9da..5695967d4cea 100644
--- a/include/trace/events/fs.h
+++ b/include/trace/events/fs.h
@@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
+#ifdef CONFIG_BPF_READAHEAD_OPTIMIZATION
+
#undef TRACE_SYSTEM
#define TRACE_SYSTEM fs
@@ -31,3 +33,8 @@ DECLARE_TRACE(fs_file_release,
/* This part must be outside protection */
#include <trace/define_trace.h>
+#else
+#define trace_fs_file_release(...)
+#define trace_fs_file_read(...)
+#endif /* CONFIG_BPF_READAHEAD_OPTIMIZATION */
+
diff --git a/mm/Kconfig b/mm/Kconfig
index cdbb1ceaa554..0c22baa52542 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1424,6 +1424,15 @@ config ETMEM
high-performance storage media to release memory space and reduce
memory costs.
+config BPF_READAHEAD_OPTIMIZATION
+ bool "Enable bpf readahead optimization"
+ select TRACEPOINTS
+ default n
+ help
+ EBPF is used to implement a programmable kernel. The readahead behavior
+ of the kernel is adjusted based on the application read mode to optimize
+ the read performance in the Spark SQL scenario,
+
source "mm/damon/Kconfig"
endmenu
--
2.39.2
2
1
hisiraid inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9F23X
CVE: NA
------------------------------------------
This commit is to support sg_raw command feature
Signed-off-by: zhanglei <zhanglei48(a)huawei.com>
---
drivers/scsi/hisi_raid/hiraid.h | 4 ++
drivers/scsi/hisi_raid/hiraid_main.c | 59 +++++++++++++++++++++++-----
2 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/hisi_raid/hiraid.h b/drivers/scsi/hisi_raid/hiraid.h
index 1ebc3dd3f2ec..04b2e25b3b38 100644
--- a/drivers/scsi/hisi_raid/hiraid.h
+++ b/drivers/scsi/hisi_raid/hiraid.h
@@ -72,7 +72,10 @@
#define PCI_VENDOR_ID_HUAWEI_LOGIC 0x19E5
#define HIRAID_SERVER_DEVICE_HBA_DID 0x3858
+#define HIRAID_SERVER_DEVICE_HBAS_DID 0x3918
#define HIRAID_SERVER_DEVICE_RAID_DID 0x3758
+#define HIRAID_SERVER_DEVICE_RAIDS_DID 0x38D8
+
enum {
HIRAID_SC_SUCCESS = 0x0,
@@ -694,6 +697,7 @@ struct hiraid_mapmange {
u32 sge_cnt;
u32 len;
bool use_sgl;
+ u32 cdb_data_len;
dma_addr_t first_dma;
void *sense_buffer_virt;
dma_addr_t sense_buffer_phy;
diff --git a/drivers/scsi/hisi_raid/hiraid_main.c b/drivers/scsi/hisi_raid/hiraid_main.c
index b9ffa642479c..2f333393824f 100644
--- a/drivers/scsi/hisi_raid/hiraid_main.c
+++ b/drivers/scsi/hisi_raid/hiraid_main.c
@@ -152,7 +152,7 @@ static struct workqueue_struct *work_queue;
__func__, ##__VA_ARGS__); \
} while (0)
-#define HIRAID_DRV_VERSION "1.1.0.0"
+#define HIRAID_DRV_VERSION "1.1.0.1"
#define ADMIN_TIMEOUT (admin_tmout * HZ)
#define USRCMD_TIMEOUT (180 * HZ)
@@ -750,14 +750,19 @@ static int hiraid_build_sgl(struct hiraid_dev *hdev, struct hiraid_scsi_io_cmd *
}
#define HIRAID_RW_FUA BIT(14)
+#define RW_LENGTH_ZERO (67)
static int hiraid_setup_rw_cmd(struct hiraid_dev *hdev,
struct hiraid_scsi_rw_cmd *io_cmd,
- struct scsi_cmnd *scmd)
+ struct scsi_cmnd *scmd,
+ struct hiraid_mapmange *mapbuf)
{
+ u32 ret = 0;
u32 start_lba_lo, start_lba_hi;
u32 datalength = 0;
u16 control = 0;
+ struct scsi_device *sdev = scmd->device;
+ u32 buf_len = cpu_to_le32(scsi_bufflen(scmd));
start_lba_lo = 0;
start_lba_hi = 0;
@@ -766,6 +771,8 @@ static int hiraid_setup_rw_cmd(struct hiraid_dev *hdev,
io_cmd->opcode = HIRAID_CMD_WRITE;
} else if (scmd->sc_data_direction == DMA_FROM_DEVICE) {
io_cmd->opcode = HIRAID_CMD_READ;
+ } else if (scmd->sc_data_direction == DMA_NONE) {
+ ret = RW_LENGTH_ZERO;
} else {
dev_err(hdev->dev, "invalid RW_IO for unsupported data direction[%d]\n",
scmd->sc_data_direction);
@@ -773,6 +780,9 @@ static int hiraid_setup_rw_cmd(struct hiraid_dev *hdev,
return -EINVAL;
}
+ if (ret == RW_LENGTH_ZERO)
+ return ret;
+
/* 6-byte READ(0x08) or WRITE(0x0A) cdb */
if (scmd->cmd_len == 6) {
datalength = (u32)(scmd->cmnd[4] == 0 ?
@@ -809,17 +819,30 @@ static int hiraid_setup_rw_cmd(struct hiraid_dev *hdev,
control |= HIRAID_RW_FUA;
}
- if (unlikely(datalength > U16_MAX || datalength == 0)) {
+ if (unlikely(datalength > U16_MAX)) {
dev_err(hdev->dev, "invalid IO for illegal transfer data length[%u]\n", datalength);
WARN_ON(1);
return -EINVAL;
}
+ if (unlikely(datalength == 0))
+ return RW_LENGTH_ZERO;
+
io_cmd->slba = cpu_to_le64(((u64)start_lba_hi << 32) | start_lba_lo);
/* 0base for nlb */
io_cmd->nlb = cpu_to_le16((u16)(datalength - 1));
io_cmd->control = cpu_to_le16(control);
+ mapbuf->cdb_data_len = (u32)((io_cmd->nlb + 1) * sdev->sector_size);
+ if (mapbuf->cdb_data_len > buf_len) {
+ /* return DID_ERROR */
+ dev_err(hdev->dev, "error: buf len[0x%x] is smaller than actual length[0x%x] sectorsize[0x%x]\n",
+ buf_len, mapbuf->cdb_data_len, sdev->sector_size);
+ return -EINVAL;
+ } else if (mapbuf->cdb_data_len < buf_len) {
+ dev_warn(hdev->dev, "warn: buf_len[0x%x] cdb_data_len[0x%x] nlb[0x%x] sectorsize[0x%x]\n",
+ buf_len, mapbuf->cdb_data_len, io_cmd->nlb, sdev->sector_size);
+ }
return 0;
}
@@ -849,13 +872,17 @@ static int hiraid_setup_nonrw_cmd(struct hiraid_dev *hdev,
}
static int hiraid_setup_io_cmd(struct hiraid_dev *hdev,
- struct hiraid_scsi_io_cmd *io_cmd, struct scsi_cmnd *scmd)
+ struct hiraid_scsi_io_cmd *io_cmd, struct scsi_cmnd *scmd,
+ struct hiraid_mapmange *mapbuf)
{
memcpy(io_cmd->common.cdb, scmd->cmnd, scmd->cmd_len);
io_cmd->common.cdb_len = scmd->cmd_len;
+ /* init cdb_data_len */
+ mapbuf->cdb_data_len = cpu_to_le32(scsi_bufflen(scmd));
+
if (hiraid_is_rw_scmd(scmd))
- return hiraid_setup_rw_cmd(hdev, &io_cmd->rw, scmd);
+ return hiraid_setup_rw_cmd(hdev, &io_cmd->rw, scmd, mapbuf);
else
return hiraid_setup_nonrw_cmd(hdev, &io_cmd->nonrw, scmd);
}
@@ -938,7 +965,12 @@ static int hiraid_io_map_data(struct hiraid_dev *hdev, struct hiraid_mapmange *m
static void hiraid_check_status(struct hiraid_mapmange *mapbuf, struct scsi_cmnd *scmd,
struct hiraid_completion *cqe)
{
- scsi_set_resid(scmd, 0);
+ u32 datalength = cpu_to_le32(scsi_bufflen(scmd));
+
+ if (datalength > mapbuf->cdb_data_len)
+ scsi_set_resid(scmd, datalength - mapbuf->cdb_data_len);
+ else
+ scsi_set_resid(scmd, 0);
switch ((le16_to_cpu(cqe->status) >> 1) & 0x7f) {
case SENSE_STATE_OK:
@@ -1022,9 +1054,14 @@ static int hiraid_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
io_cmd.rw.hdid = cpu_to_le32(hostdata->hdid);
io_cmd.rw.cmd_id = cpu_to_le16(cid);
- ret = hiraid_setup_io_cmd(hdev, &io_cmd, scmd);
+ ret = hiraid_setup_io_cmd(hdev, &io_cmd, scmd, mapbuf);
if (unlikely(ret)) {
- set_host_byte(scmd, DID_ERROR);
+ if (ret == RW_LENGTH_ZERO) {
+ scsi_set_resid(scmd, scsi_bufflen(scmd));
+ set_host_byte(scmd, DID_OK);
+ } else {
+ set_host_byte(scmd, DID_ERROR);
+ }
scmd->scsi_done(scmd);
atomic_dec(&ioq->inflight);
return 0;
@@ -2541,12 +2578,12 @@ static int hiraid_bsg_buf_map(struct hiraid_dev *hdev, struct bsg_job *job,
if (unlikely(mapbuf->sge_cnt == 0))
goto out;
- mapbuf->use_sgl = !hiraid_is_prp(hdev, mapbuf->sgl, mapbuf->sge_cnt);
-
ret = dma_map_sg_attrs(hdev->dev, mapbuf->sgl, mapbuf->sge_cnt, dma_dir, DMA_ATTR_NO_WARN);
if (!ret)
goto out;
+ mapbuf->use_sgl = !hiraid_is_prp(hdev, mapbuf->sgl, mapbuf->sge_cnt);
+
if ((mapbuf->use_sgl == (bool)true) && (bsg_req->msgcode == HIRAID_BSG_IOPTHRU) &&
(hdev->ctrl_info->pt_use_sgl != (bool)false)) {
ret = hiraid_build_passthru_sgl(hdev, cmd, mapbuf);
@@ -3925,7 +3962,9 @@ static void hiraid_remove(struct pci_dev *pdev)
static const struct pci_device_id hiraid_hw_card_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI_LOGIC, HIRAID_SERVER_DEVICE_HBA_DID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI_LOGIC, HIRAID_SERVER_DEVICE_HBAS_DID) },
{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI_LOGIC, HIRAID_SERVER_DEVICE_RAID_DID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI_LOGIC, HIRAID_SERVER_DEVICE_RAIDS_DID) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, hiraid_hw_card_ids);
--
2.22.0.windows.1
2
1

15 Apr '24
The following optimization are made for feature "arm64: add machine
check safe support":
1. Optimize do_sea() processing logic.
2. Add new fixup type of the copy_to/from_user() memory error.
3. Optimize repeated assembly codes in copy_mc_page.S and memcpy_mc.S.
4. The below mailist patch hardening feature is incorporated:
https://lore.kernel.org/lkml/20240204080144.7977-1-xueshuai@linux.alibaba.c…
Marc Zyngier (1):
arm64: Get rid of ARM64_HAS_NO_HW_PREFETCH
Shuai Xue (3):
ACPI: APEI: send SIGBUS to current task if synchronous memory error
not recovered
mm: memory-failure: move return value documentation to function
declaration
ACPI: APEI: handle synchronous exceptions in task work to send correct
SIGBUS si_code
Tong Tiangen (12):
Revert "kasan: fix the compilation error for memcpy_mcs()"
Revert "arm64: add machine check safe sysctl interface"
Revert "arm64: introduce copy_mc_to_kernel() implementation"
Revert "arm64: support copy_mc_[user]_highpage()"
Revert "mm/hwpoison: return -EFAULT when copy fail in
copy_mc_[user]_highpage()"
Revert "arm64: add uaccess to machine check safe"
Revert "arm64: add support for machine check error safe"
arm64: add support for ARCH_HAS_COPY_MC
mm/hwpoison: return -EFAULT when copy fail in
copy_mc_[user]_highpage()
arm64: support copy_mc_[user]_highpage()
arm64: introduce copy_mc_to_kernel() implementation
arm64: add machine check safe sysctl interface
arch/arm64/include/asm/asm-extable.h | 34 +--
arch/arm64/include/asm/asm-uaccess.h | 4 +
arch/arm64/include/asm/assembler.h | 4 -
arch/arm64/include/asm/extable.h | 2 +-
arch/arm64/include/asm/mte.h | 4 +
arch/arm64/include/asm/string.h | 6 +-
arch/arm64/include/asm/uaccess.h | 13 +-
arch/arm64/kernel/cpufeature.c | 16 --
arch/arm64/lib/Makefile | 4 +-
arch/arm64/lib/copy_from_user.S | 10 +-
arch/arm64/lib/copy_mc_page.S | 63 +-----
arch/arm64/lib/copy_page.S | 61 +-----
arch/arm64/lib/copy_page_template.S | 56 +++++
arch/arm64/lib/copy_to_user.S | 10 +-
arch/arm64/lib/memcpy_mc.S | 304 ++++++---------------------
arch/arm64/lib/mte.S | 6 +-
arch/arm64/mm/copypage.c | 39 ++--
arch/arm64/mm/extable.c | 12 +-
arch/arm64/mm/fault.c | 53 ++---
arch/arm64/tools/cpucaps | 1 -
arch/x86/kernel/cpu/mce/core.c | 7 -
drivers/acpi/apei/ghes.c | 84 +++++---
include/acpi/ghes.h | 3 -
mm/kasan/shadow.c | 6 +-
mm/memory-failure.c | 22 +-
25 files changed, 282 insertions(+), 542 deletions(-)
create mode 100644 arch/arm64/lib/copy_page_template.S
--
2.25.1
2
17

15 Apr '24
From: Nicholas Kazlauskas <nicholas.kazlauskas(a)amd.com>
stable inclusion
from stable-v6.7.3
commit 2ef98c6d753a744e333b7e34b9cf687040fba57d
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9BV4C
CVE: CVE-2023-52624
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
[ Upstream commit e5ffd1263dd5b44929c676171802e7b6af483f21 ]
[Why]
DMCUB can be in idle when we attempt to interface with the HW through
the GPINT mailbox resulting in a system hang.
[How]
Add dc_wake_and_execute_gpint() to wrap the wake, execute, sleep
sequence.
If the GPINT executes successfully then DMCUB will be put back into
sleep after the optional response is returned.
It functions similar to the inbox command interface.
Cc: Mario Limonciello <mario.limonciello(a)amd.com>
Cc: Alex Deucher <alexander.deucher(a)amd.com>
Cc: stable(a)vger.kernel.org
Reviewed-by: Hansen Dsouza <hansen.dsouza(a)amd.com>
Acked-by: Wayne Lin <wayne.lin(a)amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas(a)amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler(a)amd.com>
Signed-off-by: Alex Deucher <alexander.deucher(a)amd.com>
This fix requires:
115c7e7f0501 ("drm/amd/display: Add psr get_state call")
0825d9658b5e ("drm/amd/display: implement notify stream mask")
1d496907f1c5 ("drm/amd/display: Engage PSR synchronously")
34ba432c946d ("drm/amd/display: [FW Promotion] Release 0.0.44")
672251b223c1 ("drm/amd/display: [FW Promotion] Release 0.0.40")
04f3c88f0955 ("drm/amd/display: Retry getting PSR state if command times out")
b30eda8d416c ("drm/amd/display: Add ETW log to dmub_psr_get_state")
f59a66c1915e ("drm/amd/display: use do-while-0 for DC_TRACE_LEVEL_MESSAGE()")
e97cc04fe0fb ("drm/amd/display: refactor dmub commands into single function")
522b9a5d5852 ("drm/amd/display: drain dmub inbox if queue is full")
9dce8c2a5f1b ("drm/amd/display: [FW Promotion] Release 0.0.161.0")
276641775848 ("drm/amd/display: [FW Promotion] Release 0.0.162.0")
65138eb72e1f ("drm/amd/display: Add DCN35 DMUB")
dc01c4b79bfe ("drm/amd/display: Update driver and IPS interop")
5b7954272ae9 ("drm/amd/display: [FW Promotion] Release 0.0.183.0")
da2d16fcdda3 ("drm/amd/display: Fix IPS handshake for idle optimizations")
5e8a0d3598b4 ("drm/amd/display: Negate IPS allow and commit bits")
820c3870c491 ("drm/amd/display: Refactor DMCUB enter/exit idle interface")
2ef98c6d753a ("drm/amd/display: Wake DMCUB before executing GPINT commands")
Signed-off-by: Zhu Wang <wangzhu9(a)huawei.com>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 16 +-
.../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 6 +-
.../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 5 +-
drivers/gpu/drm/amd/display/dc/core/dc.c | 4 +-
drivers/gpu/drm/amd/display/dc/core/dc_link.c | 19 +-
.../gpu/drm/amd/display/dc/core/dc_link_dp.c | 4 +-
drivers/gpu/drm/amd/display/dc/dc.h | 4 +-
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 265 +++++++++++++++++-
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 31 ++
drivers/gpu/drm/amd/display/dc/dc_link.h | 5 +-
drivers/gpu/drm/amd/display/dc/dc_types.h | 20 ++
drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 24 +-
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 140 +++++----
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h | 3 +-
drivers/gpu/drm/amd/display/dc/dm_services.h | 9 +
.../drm/amd/display/dc/dm_services_types.h | 6 +
.../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 1 +
drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h | 2 +-
.../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 +-
drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 20 ++
.../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 100 ++++++-
.../gpu/drm/amd/display/dmub/src/dmub_srv.c | 27 ++
22 files changed, 615 insertions(+), 99 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 652ddec18838..924d643a37ae 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9308,7 +9308,7 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
&stream, 1,
¶ms);
- return dc_link_set_psr_allow_active(link, true, false);
+ return dc_link_set_psr_allow_active(link, true, false, false);
}
/*
@@ -9322,7 +9322,7 @@ static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
DRM_DEBUG_DRIVER("Disabling psr...\n");
- return dc_link_set_psr_allow_active(stream->link, false, true);
+ return dc_link_set_psr_allow_active(stream->link, false, true, false);
}
/*
@@ -9355,3 +9355,15 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev)
}
mutex_unlock(&adev->dm.dc_lock);
}
+
+bool dm_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd,
+ enum dm_dmub_wait_type wait_type)
+{
+ return dc_dmub_srv_cmd_run(ctx->dmub_srv, cmd, wait_type);
+}
+
+bool dm_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned int count,
+ union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type)
+{
+ return dc_dmub_srv_cmd_run_list(ctx->dmub_srv, count, cmd, wait_type);
+}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index e43f82bcb231..9dee30fc4d1c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -2210,11 +2210,11 @@ static int psr_get(void *data, u64 *val)
{
struct amdgpu_dm_connector *connector = data;
struct dc_link *link = connector->dc_link;
- uint32_t psr_state = 0;
+ enum dc_psr_state state = PSR_STATE0;
- dc_link_get_psr_state(link, &psr_state);
+ dc_link_get_psr_state(link, &state);
- *val = psr_state;
+ *val = state;
return 0;
}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
index 857f156e4985..4a408cbb9363 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
@@ -95,7 +95,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
if (edp_link) {
clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
- dc_link_set_psr_allow_active(edp_link, false, false);
+ dc_link_set_psr_allow_active(edp_link, false, false, false);
}
}
@@ -105,7 +105,8 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
struct dc_link *edp_link = get_edp_link(dc);
if (edp_link)
- dc_link_set_psr_allow_active(edp_link, clk_mgr->psr_allow_active_cache, false);
+ dc_link_set_psr_allow_active(edp_link,
+ clk_mgr->psr_allow_active_cache, false, false);
if (dc->hwss.optimize_pwr_state)
dc->hwss.optimize_pwr_state(dc, dc->current_state);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 099542dd3154..384c077e15fc 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3052,9 +3052,9 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable)
if (link->psr_settings.psr_feature_enabled) {
if (enable && !link->psr_settings.psr_allow_active)
- return dc_link_set_psr_allow_active(link, true, false);
+ return dc_link_set_psr_allow_active(link, true, false, false);
else if (!enable && link->psr_settings.psr_allow_active)
- return dc_link_set_psr_allow_active(link, false, true);
+ return dc_link_set_psr_allow_active(link, false, true, false);
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 62778ccea055..0292a21ac365 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2584,17 +2584,23 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
return true;
}
-bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait)
+bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active,
+ bool wait, bool force_static)
{
struct dc *dc = link->ctx->dc;
struct dmcu *dmcu = dc->res_pool->dmcu;
struct dmub_psr *psr = dc->res_pool->psr;
+ if (psr == NULL && force_static)
+ return false;
+
link->psr_settings.psr_allow_active = allow_active;
- if (psr != NULL && link->psr_settings.psr_feature_enabled)
+ if (psr != NULL && link->psr_settings.psr_feature_enabled) {
+ if (force_static && psr->funcs->psr_force_static)
+ psr->funcs->psr_force_static(psr);
psr->funcs->psr_enable(psr, allow_active, wait);
- else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled)
+ } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled)
dmcu->funcs->set_psr_enable(dmcu, allow_active, wait);
else
return false;
@@ -2602,16 +2608,16 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool
return true;
}
-bool dc_link_get_psr_state(const struct dc_link *link, uint32_t *psr_state)
+bool dc_link_get_psr_state(const struct dc_link *link, enum dc_psr_state *state)
{
struct dc *dc = link->ctx->dc;
struct dmcu *dmcu = dc->res_pool->dmcu;
struct dmub_psr *psr = dc->res_pool->psr;
if (psr != NULL && link->psr_settings.psr_feature_enabled)
- psr->funcs->psr_get_state(psr, psr_state);
+ psr->funcs->psr_get_state(psr, state);
else if (dmcu != NULL && link->psr_settings.psr_feature_enabled)
- dmcu->funcs->get_psr_state(dmcu, psr_state);
+ dmcu->funcs->get_psr_state(dmcu, state);
return true;
}
@@ -2674,7 +2680,6 @@ bool dc_link_setup_psr(struct dc_link *link,
if (!dmcu && !psr)
return false;
-
memset(&psr_configuration, 0, sizeof(psr_configuration));
psr_configuration.bits.ENABLE = 1;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 3f4403e77814..4bb052142fc3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2570,8 +2570,8 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link)
sizeof(psr_error_status.raw));
/* PSR error, disable and re-enable PSR */
- dc_link_set_psr_allow_active(link, false, true);
- dc_link_set_psr_allow_active(link, true, true);
+ dc_link_set_psr_allow_active(link, false, true, false);
+ dc_link_set_psr_allow_active(link, true, true, false);
return true;
} else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 82fe0ab56e3a..4434498363bc 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -504,6 +504,8 @@ struct dc_debug_options {
bool disable_dsc;
bool enable_dram_clock_change_one_display_vactive;
bool force_ignore_link_settings;
+ unsigned int ips2_eval_delay_us;
+ unsigned int ips2_entry_delay_us;
};
struct dc_debug_data {
@@ -599,9 +601,7 @@ struct dc {
/* Require to optimize clocks and bandwidth for added/removed planes */
bool optimized_required;
bool wm_optimized_required;
-#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
bool idle_optimizations_allowed;
-#endif
/* Require to maintain clocks and bandwidth for UEFI enabled HW */
int optimize_seamless_boot_streams;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index b98754811977..2cbd5c6d9518 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -26,6 +26,7 @@
#include "dc.h"
#include "dc_dmub_srv.h"
#include "../dmub/dmub_srv.h"
+#include "clk_mgr.h"
static void dc_dmub_srv_construct(struct dc_dmub_srv *dc_srv, struct dc *dc,
struct dmub_srv *dmub)
@@ -84,6 +85,66 @@ void dc_dmub_srv_cmd_queue(struct dc_dmub_srv *dc_dmub_srv,
DC_ERROR("Error queuing DMUB command: status=%d\n", status);
}
+bool dc_dmub_srv_cmd_run(struct dc_dmub_srv *dc_dmub_srv, union dmub_rb_cmd *cmd,
+ enum dm_dmub_wait_type wait_type)
+{
+ return dc_dmub_srv_cmd_run_list(dc_dmub_srv, 1, cmd, wait_type);
+}
+
+bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int count,
+ union dmub_rb_cmd *cmd_list, enum dm_dmub_wait_type wait_type)
+{
+ struct dc_context *dc_ctx;
+ struct dmub_srv *dmub;
+ enum dmub_status status;
+ int i;
+
+ if (!dc_dmub_srv || !dc_dmub_srv->dmub)
+ return false;
+
+ dc_ctx = dc_dmub_srv->ctx;
+ dmub = dc_dmub_srv->dmub;
+
+ for (i = 0 ; i < count; i++) {
+ // Queue command
+ status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);
+ if (status == DMUB_STATUS_QUEUE_FULL) {
+ /* Execute and wait for queue to become empty again. */
+ dmub_srv_cmd_execute(dmub);
+ dmub_srv_wait_for_idle(dmub, 100000);
+
+ /* Requeue the command. */
+ status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);
+ }
+
+ if (status != DMUB_STATUS_OK) {
+ DC_ERROR("Error queueing DMUB command: status=%d\n", status);
+ return false;
+ }
+ }
+
+ status = dmub_srv_cmd_execute(dmub);
+ if (status != DMUB_STATUS_OK) {
+ DC_ERROR("Error starting DMUB execution: status=%d\n", status);
+ return false;
+ }
+
+ // Wait for DMUB to process command
+ if (wait_type != DM_DMUB_WAIT_TYPE_NO_WAIT) {
+ status = dmub_srv_wait_for_idle(dmub, 100000);
+ if (status != DMUB_STATUS_OK) {
+ DC_LOG_DEBUG("No reply for DMUB command: status=%d\n", status);
+ return false;
+ }
+
+ // Copy data back from ring buffer into command
+ if (wait_type == DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)
+ dmub_rb_get_return_data(&dmub->inbox1_rb, cmd_list);
+ }
+
+ return true;
+}
+
void dc_dmub_srv_cmd_execute(struct dc_dmub_srv *dc_dmub_srv)
{
struct dmub_srv *dmub = dc_dmub_srv->dmub;
@@ -136,15 +197,207 @@ void dc_dmub_srv_wait_phy_init(struct dc_dmub_srv *dc_dmub_srv)
bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
unsigned int stream_mask)
{
- struct dmub_srv *dmub;
- const uint32_t timeout = 30;
+ if (!dc_dmub_srv || !dc_dmub_srv->dmub)
+ return false;
+
+ return dc_wake_and_execute_gpint(dc_dmub_srv->ctx, DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK,
+ stream_mask, NULL, DM_DMUB_WAIT_TYPE_WAIT);
+}
+
+bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait)
+{
+ struct dc_context *dc_ctx;
+ enum dmub_status status;
+
+ if (!dc_dmub_srv || !dc_dmub_srv->dmub)
+ return true;
+
+ if (dc_dmub_srv->ctx->dc->debug.dmcub_emulation)
+ return true;
+
+ dc_ctx = dc_dmub_srv->ctx;
+
+ if (wait) {
+ status = dmub_srv_wait_for_hw_pwr_up(dc_dmub_srv->dmub, 500000);
+ if (status != DMUB_STATUS_OK) {
+ DC_ERROR("Error querying DMUB hw power up status: error=%d\n", status);
+ return false;
+ }
+ } else {
+ return dmub_srv_is_hw_pwr_up(dc_dmub_srv->dmub);
+ }
+
+ return true;
+}
+
+static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
+{
+ union dmub_rb_cmd cmd = {0};
+
+ if (dc->debug.dmcub_emulation)
+ return;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.idle_opt_notify_idle.header.type = DMUB_CMD__IDLE_OPT;
+ cmd.idle_opt_notify_idle.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE;
+ cmd.idle_opt_notify_idle.header.payload_bytes =
+ sizeof(cmd.idle_opt_notify_idle) -
+ sizeof(cmd.idle_opt_notify_idle.header);
+
+ cmd.idle_opt_notify_idle.cntl_data.driver_idle = allow_idle;
+
+ if (allow_idle) {
+ if (dc->hwss.set_idle_state)
+ dc->hwss.set_idle_state(dc, true);
+ }
+
+ /* NOTE: This does not use the "wake" interface since this is part of the wake path. */
+ dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+}
+
+static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
+{
+ const uint32_t max_num_polls = 10000;
+ uint32_t allow_state = 0;
+ uint32_t commit_state = 0;
+ uint32_t i;
+
+ if (dc->debug.dmcub_emulation)
+ return;
+
+ if (!dc->idle_optimizations_allowed)
+ return;
+
+ if (!dc->ctx->dmub_srv || !dc->ctx->dmub_srv->dmub)
+ return;
+
+ if (dc->hwss.get_idle_state &&
+ dc->hwss.set_idle_state &&
+ dc->clk_mgr->funcs->exit_low_power_state) {
+ allow_state = dc->hwss.get_idle_state(dc);
+ dc->hwss.set_idle_state(dc, false);
+
+ if (!(allow_state & DMUB_IPS2_ALLOW_MASK)) {
+ // Wait for evaluation time
+ udelay(dc->debug.ips2_eval_delay_us);
+ commit_state = dc->hwss.get_idle_state(dc);
+ if (!(commit_state & DMUB_IPS2_COMMIT_MASK)) {
+ // Tell PMFW to exit low power state
+ dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr);
+
+ // Wait for IPS2 entry upper bound
+ udelay(dc->debug.ips2_entry_delay_us);
+ dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr);
+
+ for (i = 0; i < max_num_polls; ++i) {
+ commit_state = dc->hwss.get_idle_state(dc);
+ if (commit_state & DMUB_IPS2_COMMIT_MASK)
+ break;
+
+ udelay(1);
+ }
+ ASSERT(i < max_num_polls);
+
+ if (!dc_dmub_srv_is_hw_pwr_up(dc->ctx->dmub_srv, true))
+ ASSERT(0);
+
+ /* TODO: See if we can return early here - IPS2 should go
+ * back directly to IPS0 and clear the flags, but it will
+ * be safer to directly notify DMCUB of this.
+ */
+ allow_state = dc->hwss.get_idle_state(dc);
+ }
+ }
+
+ dc_dmub_srv_notify_idle(dc, false);
+ if (!(allow_state & DMUB_IPS1_ALLOW_MASK)) {
+ for (i = 0; i < max_num_polls; ++i) {
+ commit_state = dc->hwss.get_idle_state(dc);
+ if (commit_state & DMUB_IPS1_COMMIT_MASK)
+ break;
+
+ udelay(1);
+ }
+ ASSERT(i < max_num_polls);
+ }
+ }
+
+ if (!dc_dmub_srv_is_hw_pwr_up(dc->ctx->dmub_srv, true))
+ ASSERT(0);
+}
+
+void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_idle)
+{
+ struct dc_dmub_srv *dc_dmub_srv = dc->ctx->dmub_srv;
+
+ if (!dc_dmub_srv || !dc_dmub_srv->dmub)
+ return;
+
+ if (dc_dmub_srv->idle_allowed == allow_idle)
+ return;
+
+ /*
+ * Entering a low power state requires a driver notification.
+ * Powering up the hardware requires notifying PMFW and DMCUB.
+ * Clearing the driver idle allow requires a DMCUB command.
+ * DMCUB commands requires the DMCUB to be powered up and restored.
+ *
+ * Exit out early to prevent an infinite loop of DMCUB commands
+ * triggering exit low power - use software state to track this.
+ */
+ dc_dmub_srv->idle_allowed = allow_idle;
+
+ if (!allow_idle)
+ dc_dmub_srv_exit_low_power_state(dc);
+ else
+ dc_dmub_srv_notify_idle(dc, allow_idle);
+}
+
+static bool dc_dmub_execute_gpint(const struct dc_context *ctx,
+ enum dmub_gpint_command command_code, uint16_t param,
+ uint32_t *response, enum dm_dmub_wait_type wait_type)
+{
+ struct dc_dmub_srv *dc_dmub_srv = ctx->dmub_srv;
+ const uint32_t wait_us = wait_type == DM_DMUB_WAIT_TYPE_NO_WAIT ? 0 : 30;
+ enum dmub_status status;
+
+ if (response)
+ *response = 0;
if (!dc_dmub_srv || !dc_dmub_srv->dmub)
return false;
- dmub = dc_dmub_srv->dmub;
+ status = dmub_srv_send_gpint_command(dc_dmub_srv->dmub, command_code, param, wait_us);
+ if (status != DMUB_STATUS_OK) {
+ if (status == DMUB_STATUS_TIMEOUT && wait_type == DM_DMUB_WAIT_TYPE_NO_WAIT)
+ return true;
+
+ return false;
+ }
+
+ if (response && wait_type == DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)
+ dmub_srv_get_gpint_response(dc_dmub_srv->dmub, response);
+
+ return true;
+}
+
+bool dc_wake_and_execute_gpint(const struct dc_context *ctx, enum dmub_gpint_command command_code,
+ uint16_t param, uint32_t *response, enum dm_dmub_wait_type wait_type)
+{
+ struct dc_dmub_srv *dc_dmub_srv = ctx->dmub_srv;
+ bool result = false, reallow_idle = false;
+
+ if (!dc_dmub_srv || !dc_dmub_srv->dmub)
+ return false;
+
+ if (dc_dmub_srv->idle_allowed) {
+ dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, false);
+ reallow_idle = true;
+ }
+
+ result = dc_dmub_execute_gpint(ctx, command_code, param, response, wait_type);
+ if (result && reallow_idle)
+ dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, true);
- return dmub_srv_send_gpint_command(
- dmub, DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK,
- stream_mask, timeout) == DMUB_STATUS_OK;
+ return result;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
index bb4ab61887e4..d8d4b02c5ace 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
@@ -27,6 +27,7 @@
#define _DMUB_DC_SRV_H_
#include "os_types.h"
+#include "dm_services_types.h"
#include "dmub/dmub_srv.h"
struct dmub_srv;
@@ -45,6 +46,8 @@ struct dc_dmub_srv {
struct dc_context *ctx;
void *dm;
+
+ bool idle_allowed;
};
void dc_dmub_srv_cmd_queue(struct dc_dmub_srv *dc_dmub_srv,
@@ -56,6 +59,34 @@ void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv);
void dc_dmub_srv_wait_phy_init(struct dc_dmub_srv *dc_dmub_srv);
+bool dc_dmub_srv_cmd_run(struct dc_dmub_srv *dc_dmub_srv, union dmub_rb_cmd *cmd,
+ enum dm_dmub_wait_type wait_type);
+
+bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int count,
+ union dmub_rb_cmd *cmd_list, enum dm_dmub_wait_type wait_type);
+
bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
unsigned int stream_mask);
+
+bool dc_wake_and_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd,
+ enum dm_dmub_wait_type wait_type);
+
+bool dc_wake_and_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned int count,
+ union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type);
+
+void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_idle);
+
+/**
+ * dc_wake_and_execute_gpint()
+ *
+ * @ctx: DC context
+ * @command_code: The command ID to send to DMCUB
+ * @param: The parameter to message DMCUB
+ * @response: Optional response out value - may be NULL.
+ * @wait_type: The wait behavior for the execution
+ */
+bool dc_wake_and_execute_gpint(const struct dc_context *ctx, enum dmub_gpint_command command_code,
+ uint16_t param, uint32_t *response,
+ enum dm_dmub_wait_type wait_type);
+
#endif /* _DMUB_DC_SRV_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 266b93a705d5..39277aaa3e62 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -219,9 +219,10 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link);
int dc_link_get_target_backlight_pwm(const struct dc_link *link);
-bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, bool wait);
+bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable,
+ bool wait, bool force_static);
-bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
+bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state);
bool dc_link_setup_psr(struct dc_link *dc_link,
const struct dc_stream_state *stream, struct psr_config *psr_config,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index c47a19719de2..bf8283ce7527 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -674,6 +674,26 @@ struct dc_plane_flip_time {
unsigned int prev_update_time_in_us;
};
+enum dc_psr_state {
+ PSR_STATE0 = 0x0,
+ PSR_STATE1,
+ PSR_STATE1a,
+ PSR_STATE2,
+ PSR_STATE2a,
+ PSR_STATE3,
+ PSR_STATE3Init,
+ PSR_STATE4,
+ PSR_STATE4a,
+ PSR_STATE4b,
+ PSR_STATE4c,
+ PSR_STATE4d,
+ PSR_STATE5,
+ PSR_STATE5a,
+ PSR_STATE5b,
+ PSR_STATE5c,
+ PSR_STATE_INVALID = 0xFF
+};
+
struct psr_config {
unsigned char psr_version;
unsigned int psr_rfb_setup_time;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
index 4216419503af..4c397a099e07 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -99,7 +99,7 @@ bool dce_dmcu_load_iram(struct dmcu *dmcu,
return true;
}
-static void dce_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
+static void dce_get_dmcu_psr_state(struct dmcu *dmcu, enum dc_psr_state *state)
{
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
@@ -114,7 +114,7 @@ static void dce_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);
/* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
- *psr_state = REG_READ(DMCU_IRAM_RD_DATA);
+ *state = (enum dc_psr_state)REG_READ(DMCU_IRAM_RD_DATA);
/* Disable write access to IRAM after finished using IRAM
* in order to allow dynamic sleep state
@@ -129,7 +129,7 @@ static void dce_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
unsigned int dmcu_wait_reg_ready_interval = 100;
unsigned int retryCount;
- uint32_t psr_state = 0;
+ enum dc_psr_state state = PSR_STATE0;
/* waitDMCUReadyForCmd */
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
@@ -148,12 +148,12 @@ static void dce_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
if (wait == true) {
for (retryCount = 0; retryCount <= 100; retryCount++) {
- dce_get_dmcu_psr_state(dmcu, &psr_state);
+ dce_get_dmcu_psr_state(dmcu, &state);
if (enable) {
- if (psr_state != 0)
+ if (state != PSR_STATE0)
break;
} else {
- if (psr_state == 0)
+ if (state == PSR_STATE0)
break;
}
udelay(10);
@@ -513,7 +513,7 @@ static bool dcn10_dmcu_load_iram(struct dmcu *dmcu,
return true;
}
-static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
+static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, enum dc_psr_state *state)
{
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
@@ -532,7 +532,7 @@ static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);
/* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
- *psr_state = REG_READ(DMCU_IRAM_RD_DATA);
+ *state = (enum dc_psr_state)REG_READ(DMCU_IRAM_RD_DATA);
/* Disable write access to IRAM after finished using IRAM
* in order to allow dynamic sleep state
@@ -547,7 +547,7 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
unsigned int dmcu_wait_reg_ready_interval = 100;
unsigned int retryCount;
- uint32_t psr_state = 0;
+ enum dc_psr_state state = PSR_STATE0;
/* If microcontroller is not running, do nothing */
if (dmcu->dmcu_state != DMCU_RUNNING)
@@ -575,12 +575,12 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
*/
if (wait == true) {
for (retryCount = 0; retryCount <= 1000; retryCount++) {
- dcn10_get_dmcu_psr_state(dmcu, &psr_state);
+ dcn10_get_dmcu_psr_state(dmcu, &state);
if (enable) {
- if (psr_state != 0)
+ if (state != PSR_STATE0)
break;
} else {
- if (psr_state == 0)
+ if (state == PSR_STATE0)
break;
}
udelay(500);
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
index 67af67ef2865..f93be6477538 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
@@ -29,60 +29,83 @@
#include "dmub/dmub_srv.h"
#include "core_types.h"
+#define DC_TRACE_LEVEL_MESSAGE(...) do {} while (0) /* do nothing */
+
#define MAX_PIPES 6
/**
* Convert dmcub psr state to dmcu psr state.
*/
-static void convert_psr_state(uint32_t *psr_state)
+static enum dc_psr_state convert_psr_state(uint32_t raw_state)
{
- if (*psr_state == 0)
- *psr_state = 0;
- else if (*psr_state == 0x10)
- *psr_state = 1;
- else if (*psr_state == 0x11)
- *psr_state = 2;
- else if (*psr_state == 0x20)
- *psr_state = 3;
- else if (*psr_state == 0x21)
- *psr_state = 4;
- else if (*psr_state == 0x30)
- *psr_state = 5;
- else if (*psr_state == 0x31)
- *psr_state = 6;
- else if (*psr_state == 0x40)
- *psr_state = 7;
- else if (*psr_state == 0x41)
- *psr_state = 8;
- else if (*psr_state == 0x42)
- *psr_state = 9;
- else if (*psr_state == 0x43)
- *psr_state = 10;
- else if (*psr_state == 0x44)
- *psr_state = 11;
- else if (*psr_state == 0x50)
- *psr_state = 12;
- else if (*psr_state == 0x51)
- *psr_state = 13;
- else if (*psr_state == 0x52)
- *psr_state = 14;
- else if (*psr_state == 0x53)
- *psr_state = 15;
+ enum dc_psr_state state = PSR_STATE0;
+
+ if (raw_state == 0)
+ state = PSR_STATE0;
+ else if (raw_state == 0x10)
+ state = PSR_STATE1;
+ else if (raw_state == 0x11)
+ state = PSR_STATE1a;
+ else if (raw_state == 0x20)
+ state = PSR_STATE2;
+ else if (raw_state == 0x21)
+ state = PSR_STATE2a;
+ else if (raw_state == 0x30)
+ state = PSR_STATE3;
+ else if (raw_state == 0x31)
+ state = PSR_STATE3Init;
+ else if (raw_state == 0x40)
+ state = PSR_STATE4;
+ else if (raw_state == 0x41)
+ state = PSR_STATE4a;
+ else if (raw_state == 0x42)
+ state = PSR_STATE4b;
+ else if (raw_state == 0x43)
+ state = PSR_STATE4c;
+ else if (raw_state == 0x44)
+ state = PSR_STATE4d;
+ else if (raw_state == 0x50)
+ state = PSR_STATE5;
+ else if (raw_state == 0x51)
+ state = PSR_STATE5a;
+ else if (raw_state == 0x52)
+ state = PSR_STATE5b;
+ else if (raw_state == 0x53)
+ state = PSR_STATE5c;
+
+ return state;
}
/**
* Get PSR state from firmware.
*/
-static void dmub_psr_get_state(struct dmub_psr *dmub, uint32_t *psr_state)
+static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state)
{
- struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
-
- // Send gpint command and wait for ack
- dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
-
- dmub_srv_get_gpint_response(srv, psr_state);
-
- convert_psr_state(psr_state);
+ uint32_t raw_state = 0;
+ uint32_t retry_count = 0;
+
+ do {
+ // Send gpint command and wait for ack
+ if (dc_wake_and_execute_gpint(dmub->ctx, DMUB_GPINT__GET_PSR_STATE, 0,
+ &raw_state, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) {
+ *state = convert_psr_state(raw_state);
+ } else {
+ // Return invalid state when GPINT times out
+ *state = PSR_STATE_INVALID;
+ }
+ } while (++retry_count <= 1000 && *state == PSR_STATE_INVALID);
+
+ // Assert if max retry hit
+ if (retry_count >= 1000 && *state == PSR_STATE_INVALID) {
+ ASSERT(0);
+ DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
+ WPP_BIT_FLAG_Firmware_PsrState,
+ "Unable to get PSR state from FW.");
+ } else
+ DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE,
+ WPP_BIT_FLAG_Firmware_PsrState,
+ "Got PSR state from FW. PSR state: %d, Retry count: %d",
+ *state, retry_count);
}
/**
@@ -123,7 +146,8 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait)
{
union dmub_rb_cmd cmd;
struct dc_context *dc = dmub->ctx;
- uint32_t retry_count, psr_state = 0;
+ uint32_t retry_count;
+ enum dc_psr_state state = PSR_STATE0;
cmd.psr_enable.header.type = DMUB_CMD__PSR;
@@ -144,13 +168,13 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait)
*/
if (wait) {
for (retry_count = 0; retry_count <= 1000; retry_count++) {
- dmub_psr_get_state(dmub, &psr_state);
+ dmub_psr_get_state(dmub, &state);
if (enable) {
- if (psr_state != 0)
+ if (state != PSR_STATE0)
break;
} else {
- if (psr_state == 0)
+ if (state == PSR_STATE0)
break;
}
@@ -169,12 +193,12 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait)
static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level)
{
union dmub_rb_cmd cmd;
- uint32_t psr_state = 0;
+ enum dc_psr_state state = PSR_STATE0;
struct dc_context *dc = dmub->ctx;
- dmub_psr_get_state(dmub, &psr_state);
+ dmub_psr_get_state(dmub, &state);
- if (psr_state == 0)
+ if (state == PSR_STATE0)
return;
cmd.psr_set_level.header.type = DMUB_CMD__PSR;
@@ -269,11 +293,29 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
return true;
}
+/**
+ * Send command to PSR to force static ENTER and ignore all state changes until exit
+ */
+static void dmub_psr_force_static(struct dmub_psr *dmub)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc = dmub->ctx;
+
+ cmd.psr_force_static.header.type = DMUB_CMD__PSR;
+ cmd.psr_force_static.header.sub_type = DMUB_CMD__PSR_FORCE_STATIC;
+ cmd.psr_enable.header.payload_bytes = 0;
+
+ dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->dmub_srv);
+}
+
static const struct dmub_psr_funcs psr_funcs = {
.psr_copy_settings = dmub_psr_copy_settings,
.psr_enable = dmub_psr_enable,
.psr_get_state = dmub_psr_get_state,
.psr_set_level = dmub_psr_set_level,
+ .psr_force_static = dmub_psr_force_static,
};
/**
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
index dc121ed92d2e..4e113ac5a56b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
@@ -37,8 +37,9 @@ struct dmub_psr {
struct dmub_psr_funcs {
bool (*psr_copy_settings)(struct dmub_psr *dmub, struct dc_link *link, struct psr_context *psr_context);
void (*psr_enable)(struct dmub_psr *dmub, bool enable, bool wait);
- void (*psr_get_state)(struct dmub_psr *dmub, uint32_t *psr_state);
+ void (*psr_get_state)(struct dmub_psr *dmub, enum dc_psr_state *dc_psr_state);
void (*psr_set_level)(struct dmub_psr *dmub, uint16_t psr_level);
+ void (*psr_force_static)(struct dmub_psr *dmub);
};
struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h b/drivers/gpu/drm/amd/display/dc/dm_services.h
index fdd1943c828d..569cdbdc4746 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_services.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_services.h
@@ -42,6 +42,7 @@
struct dmub_srv;
struct dc_dmub_srv;
+union dmub_rb_cmd;
irq_handler_idx dm_register_interrupt(
struct dc_context *ctx,
@@ -294,6 +295,14 @@ unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx,
__CTX->perf_trace->write_count, &__CTX->perf_trace->last_entry_read,\
&__CTX->perf_trace->last_entry_write, __func__, __LINE__)
+/*
+ * DMUB Interfaces
+ */
+bool dm_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd,
+ enum dm_dmub_wait_type wait_type);
+
+bool dm_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned int count,
+ union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type);
/*
* Debug and verification hooks
diff --git a/drivers/gpu/drm/amd/display/dc/dm_services_types.h b/drivers/gpu/drm/amd/display/dc/dm_services_types.h
index b52ba6ffabe1..facf269c4326 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_services_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_services_types.h
@@ -269,4 +269,10 @@ struct dtn_min_clk_info {
uint32_t min_memory_clock_khz;
};
+enum dm_dmub_wait_type {
+ DM_DMUB_WAIT_TYPE_NO_WAIT,
+ DM_DMUB_WAIT_TYPE_WAIT,
+ DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY,
+};
+
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
index 947d6106f341..c22d6dd9dfec 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
@@ -231,6 +231,7 @@ struct clk_mgr_funcs {
int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr);
void (*set_low_power_state)(struct clk_mgr *clk_mgr);
+ void (*exit_low_power_state)(struct clk_mgr *clk_mgr);
void (*init_clocks)(struct clk_mgr *clk_mgr);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
index 5315f1f86b21..69d9fbfb4bec 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
@@ -66,7 +66,7 @@ struct dmcu_funcs {
bool (*setup_psr)(struct dmcu *dmcu,
struct dc_link *link,
struct psr_context *psr_context);
- void (*get_psr_state)(struct dmcu *dmcu, uint32_t *psr_state);
+ void (*get_psr_state)(struct dmcu *dmcu, enum dc_psr_state *dc_psr_state);
void (*set_psr_wait_loop)(struct dmcu *dmcu,
unsigned int wait_loop_number);
void (*get_psr_wait_loop)(struct dmcu *dmcu,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index 3165a66c5362..03c075ea5fc1 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -213,7 +213,8 @@ struct hw_sequencer_funcs {
/* Idle Optimization Related */
bool (*apply_idle_power_optimizations)(struct dc *dc, bool enable);
#endif
-
+ void (*set_idle_state)(const struct dc *dc, bool allow_idle);
+ uint32_t (*get_idle_state)(const struct dc *dc);
};
void color_space_to_black_color(
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index 882b4e2816b5..9ff364c6353d 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -264,6 +264,8 @@ struct dmub_srv_hw_funcs {
bool (*is_hw_init)(struct dmub_srv *dmub);
+ bool (*is_hw_powered_up)(struct dmub_srv *dmub);
+
bool (*is_phy_init)(struct dmub_srv *dmub);
bool (*is_auto_load_done)(struct dmub_srv *dmub);
@@ -486,6 +488,24 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
*/
enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub);
+/**
+ * dmub_srv_wait_for_hw_pwr_up() - Waits for firmware hardware power up is completed
+ * @dmub: the dmub service
+ * @timeout_us: the maximum number of microseconds to wait
+ *
+ * Waits until firmware hardware is powered up. The maximum
+ * wait time is given in microseconds to prevent spinning forever.
+ *
+ * Return:
+ * DMUB_STATUS_OK - success
+ * DMUB_STATUS_TIMEOUT - timed out
+ * DMUB_STATUS_INVALID - unspecified error
+ */
+enum dmub_status dmub_srv_wait_for_hw_pwr_up(struct dmub_srv *dmub,
+ uint32_t timeout_us);
+
+bool dmub_srv_is_hw_pwr_up(struct dmub_srv *dmub);
+
/**
* dmub_srv_wait_for_auto_load() - Waits for firmware auto load to complete
* @dmub: the dmub service
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index d103ec1eaa73..c741aaa7cd34 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -104,6 +104,11 @@ union dmub_psr_debug_flags {
uint32_t u32All;
};
+struct dmub_feature_caps {
+ uint8_t psr;
+ uint8_t reserved[7];
+};
+
#if defined(__cplusplus)
}
#endif
@@ -123,6 +128,17 @@ union dmub_psr_debug_flags {
/* Offset from the end of the file to the dmub_fw_meta_info */
#define DMUB_FW_META_OFFSET 0x24
+/**
+ *
+ * PSR control version legacy
+ */
+#define DMUB_CMD_PSR_CONTROL_VERSION_UNKNOWN 0x0
+/**
+ * PSR control version with multi edp support
+ */
+#define DMUB_CMD_PSR_CONTROL_VERSION_1 0x1
+
+
/**
* struct dmub_fw_meta_info - metadata associated with fw binary
*
@@ -183,6 +199,11 @@ enum dmub_fw_boot_status_bit {
DMUB_FW_BOOT_STATUS_BIT_RESTORE_REQUIRED = (1 << 3),
};
+#define DMUB_IPS1_ALLOW_MASK 0x00000001
+#define DMUB_IPS2_ALLOW_MASK 0x00000002
+#define DMUB_IPS1_COMMIT_MASK 0x00000004
+#define DMUB_IPS2_COMMIT_MASK 0x00000008
+
/* Register bit definition for SCRATCH15 */
union dmub_fw_boot_options {
struct {
@@ -272,6 +293,7 @@ enum dmub_gpint_command {
* ARGS: Stream mask, 1 bit per active stream index.
*/
DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK = 8,
+ DMUB_GPINT__PSR_RESIDENCY = 9,
};
//==============================================================================
@@ -297,11 +319,13 @@ enum dmub_cmd_type {
DMUB_CMD__REG_SEQ_BURST_WRITE = 3,
DMUB_CMD__REG_REG_WAIT = 4,
DMUB_CMD__PLAT_54186_WA = 5,
+ DMUB_CMD__QUERY_FEATURE_CAPS = 6,
DMUB_CMD__PSR = 64,
DMUB_CMD__ABM = 66,
DMUB_CMD__HW_LOCK = 69,
DMUB_CMD__DP_AUX_ACCESS = 70,
DMUB_CMD__OUTBOX1_ENABLE = 71,
+ DMUB_CMD__IDLE_OPT = 72,
DMUB_CMD__VBIOS = 128,
};
@@ -316,7 +340,8 @@ enum dmub_out_cmd_type {
struct dmub_cmd_header {
unsigned int type : 8;
unsigned int sub_type : 8;
- unsigned int reserved0 : 8;
+ unsigned int ret_status : 1;
+ unsigned int reserved0 : 7;
unsigned int payload_bytes : 6; /* up to 60 bytes */
unsigned int reserved1 : 2;
};
@@ -549,6 +574,7 @@ enum dmub_cmd_psr_type {
DMUB_CMD__PSR_ENABLE = 2,
DMUB_CMD__PSR_DISABLE = 3,
DMUB_CMD__PSR_SET_LEVEL = 4,
+ DMUB_CMD__PSR_FORCE_STATIC = 5,
};
enum psr_version {
@@ -560,6 +586,9 @@ struct dmub_cmd_psr_copy_settings_data {
union dmub_psr_debug_flags debug;
uint16_t psr_level;
uint8_t dpp_inst;
+ /* opp_inst and mpcc_inst will not be used in dmub fw,
+ * dmub fw will get active opp by reading odm registers.
+ */
uint8_t mpcc_inst;
uint8_t opp_inst;
uint8_t otg_inst;
@@ -603,6 +632,10 @@ struct dmub_rb_cmd_psr_set_version {
struct dmub_cmd_psr_set_version_data psr_set_version_data;
};
+struct dmub_rb_cmd_psr_force_static {
+ struct dmub_cmd_header header;
+};
+
union dmub_hw_lock_flags {
struct {
uint8_t lock_pipe : 1;
@@ -744,6 +777,45 @@ struct dmub_rb_cmd_abm_init_config {
struct dmub_cmd_abm_init_config_data abm_init_config_data;
};
+/**
+ * enum dmub_cmd_idle_opt_type - Idle optimization command type.
+ */
+enum dmub_cmd_idle_opt_type {
+ /**
+ * DCN hardware restore.
+ */
+ DMUB_CMD__IDLE_OPT_DCN_RESTORE = 0,
+
+ /**
+ * DCN hardware save.
+ */
+ DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT = 1,
+
+ /**
+ * DCN hardware notify idle.
+ */
+ DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE = 2
+};
+
+struct dmub_dcn_notify_idle_cntl_data {
+ uint8_t driver_idle;
+ uint8_t pad[1];
+};
+
+struct dmub_rb_cmd_idle_opt_dcn_notify_idle {
+ struct dmub_cmd_header header; /**< header */
+ struct dmub_dcn_notify_idle_cntl_data cntl_data;
+};
+
+struct dmub_cmd_query_feature_caps_data {
+ struct dmub_feature_caps feature_caps;
+};
+
+struct dmub_rb_cmd_query_feature_caps {
+ struct dmub_cmd_header header;
+ struct dmub_cmd_query_feature_caps_data query_feature_caps_data;
+};
+
union dmub_rb_cmd {
struct dmub_rb_cmd_lock_hw lock_hw;
struct dmub_rb_cmd_read_modify_write read_modify_write;
@@ -760,6 +832,7 @@ union dmub_rb_cmd {
struct dmub_rb_cmd_psr_copy_settings psr_copy_settings;
struct dmub_rb_cmd_psr_enable psr_enable;
struct dmub_rb_cmd_psr_set_level psr_set_level;
+ struct dmub_rb_cmd_psr_force_static psr_force_static;
struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa;
struct dmub_rb_cmd_abm_set_pipe abm_set_pipe;
struct dmub_rb_cmd_abm_set_backlight abm_set_backlight;
@@ -769,6 +842,8 @@ union dmub_rb_cmd {
struct dmub_rb_cmd_abm_init_config abm_init_config;
struct dmub_rb_cmd_dp_aux_access dp_aux_access;
struct dmub_rb_cmd_outbox1_enable outbox1_enable;
+ struct dmub_rb_cmd_query_feature_caps query_feature_caps;
+ struct dmub_rb_cmd_idle_opt_dcn_notify_idle idle_opt_notify_idle;
};
union dmub_rb_out_cmd {
@@ -831,7 +906,7 @@ static inline bool dmub_rb_push_front(struct dmub_rb *rb,
{
uint64_t volatile *dst = (uint64_t volatile *)(rb->base_address) + rb->wrpt / sizeof(uint64_t);
const uint64_t *src = (const uint64_t *)cmd;
- int i;
+ uint8_t i;
if (dmub_rb_full(rb))
return false;
@@ -868,14 +943,14 @@ static inline bool dmub_rb_out_push_front(struct dmub_rb *rb,
}
static inline bool dmub_rb_front(struct dmub_rb *rb,
- union dmub_rb_cmd *cmd)
+ union dmub_rb_cmd **cmd)
{
- uint8_t *rd_ptr = (uint8_t *)rb->base_address + rb->rptr;
+ uint8_t *rb_cmd = (uint8_t *)(rb->base_address) + rb->rptr;
if (dmub_rb_empty(rb))
return false;
- dmub_memcpy(cmd, rd_ptr, DMUB_RB_CMD_SIZE);
+ *cmd = (union dmub_rb_cmd *)rb_cmd;
return true;
}
@@ -885,7 +960,7 @@ static inline bool dmub_rb_out_front(struct dmub_rb *rb,
{
const uint64_t volatile *src = (const uint64_t volatile *)(rb->base_address) + rb->rptr / sizeof(uint64_t);
uint64_t *dst = (uint64_t *)cmd;
- int i;
+ uint8_t i;
if (dmub_rb_empty(rb))
return false;
@@ -917,7 +992,7 @@ static inline void dmub_rb_flush_pending(const struct dmub_rb *rb)
while (rptr != wptr) {
uint64_t volatile *data = (uint64_t volatile *)rb->base_address + rptr / sizeof(uint64_t);
- int i;
+ uint8_t i;
for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++)
*data++;
@@ -937,6 +1012,17 @@ static inline void dmub_rb_init(struct dmub_rb *rb,
rb->wrpt = init_params->write_ptr;
}
+static inline void dmub_rb_get_return_data(struct dmub_rb *rb,
+ union dmub_rb_cmd *cmd)
+{
+ // Copy rb entry back into command
+ uint8_t *rd_ptr = (rb->rptr == 0) ?
+ (uint8_t *)rb->base_address + rb->capacity - DMUB_RB_CMD_SIZE :
+ (uint8_t *)rb->base_address + rb->rptr - DMUB_RB_CMD_SIZE;
+
+ dmub_memcpy(cmd, rd_ptr, DMUB_RB_CMD_SIZE);
+}
+
#if defined(__cplusplus)
}
#endif
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
index 08da423b24a1..b2f909d58a05 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -516,6 +516,33 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)
return DMUB_STATUS_OK;
}
+bool dmub_srv_is_hw_pwr_up(struct dmub_srv *dmub)
+{
+ if (!dmub->hw_funcs.is_hw_powered_up)
+ return true;
+
+ return dmub->hw_funcs.is_hw_powered_up(dmub) &&
+ dmub->hw_funcs.is_hw_init(dmub);
+}
+
+enum dmub_status dmub_srv_wait_for_hw_pwr_up(struct dmub_srv *dmub,
+ uint32_t timeout_us)
+{
+ uint32_t i;
+
+ if (!dmub->hw_init)
+ return DMUB_STATUS_INVALID;
+
+ for (i = 0; i <= timeout_us; i += 100) {
+ if (dmub_srv_is_hw_pwr_up(dmub))
+ return DMUB_STATUS_OK;
+
+ udelay(100);
+ }
+
+ return DMUB_STATUS_TIMEOUT;
+}
+
enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub,
uint32_t timeout_us)
{
--
2.34.1
2
1

15 Apr '24
From: Dimitris Vlachos <dvlachos(a)ics.forth.gr>
stable inclusion
from stable-v5.10.212
commit 8af1c121b0102041809bc137ec600d1865eaeedd
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9E466
CVE: CVE-2024-26795
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit a11dd49dcb9376776193e15641f84fcc1e5980c9 ]
Offset vmemmap so that the first page of vmemmap will be mapped
to the first page of physical memory in order to ensure that
vmemmap’s bounds will be respected during
pfn_to_page()/page_to_pfn() operations.
The conversion macros will produce correct SV39/48/57 addresses
for every possible/valid DRAM_BASE inside the physical memory limits.
v2:Address Alex's comments
Suggested-by: Alexandre Ghiti <alexghiti(a)rivosinc.com>
Signed-off-by: Dimitris Vlachos <dvlachos(a)ics.forth.gr>
Reported-by: Dimitris Vlachos <dvlachos(a)ics.forth.gr>
Closes: https://lore.kernel.org/linux-riscv/20240202135030.42265-1-csd4492@csd.uoc.…
Fixes: d95f1a542c3d ("RISC-V: Implement sparsemem")
Reviewed-by: Alexandre Ghiti <alexghiti(a)rivosinc.com>
Link: https://lore.kernel.org/r/20240229191723.32779-1-dvlachos@ics.forth.gr
Signed-off-by: Palmer Dabbelt <palmer(a)rivosinc.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Zheng Zucheng <zhengzucheng(a)huawei.com>
---
arch/riscv/include/asm/pgtable.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index b16304fdf448..5ab13570daa5 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -44,7 +44,7 @@
* Define vmemmap for pfn_to_page & page_to_pfn calls. Needed if kernel
* is configured with CONFIG_SPARSEMEM_VMEMMAP enabled.
*/
-#define vmemmap ((struct page *)VMEMMAP_START)
+#define vmemmap ((struct page *)VMEMMAP_START - (phys_ram_base >> PAGE_SHIFT))
#define PCI_IO_SIZE SZ_16M
#define PCI_IO_END VMEMMAP_START
--
2.34.1
2
1

[openeuler:OLK-5.10 19114/30000] drivers/scsi/sssraid/sssraid_os.c:1568:2: error: implicit declaration of function 'for_each_pci_msi_entry'
by kernel test robot 15 Apr '24
by kernel test robot 15 Apr '24
15 Apr '24
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 9a6863f4e4a4271bdb5b3a1e955bcd851d81c27a
commit: bbae0ca11850da2793282896206974656859a73e [19114/30000] SCSI: SSSRAID: Introduce map_queue in sssraid module
config: x86_64-randconfig-122-20240413 (https://download.01.org/0day-ci/archive/20240415/202404151411.qh3ixZhW-lkp@…)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240415/202404151411.qh3ixZhW-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202404151411.qh3ixZhW-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/scsi/sssraid/sssraid_os.c:1568:2: error: implicit declaration of function 'for_each_pci_msi_entry' [-Werror,-Wimplicit-function-declaration]
1568 | for_each_pci_msi_entry(entry, pdev) {
| ^
>> drivers/scsi/sssraid/sssraid_os.c:1568:37: error: expected ';' after expression
1568 | for_each_pci_msi_entry(entry, pdev) {
| ^
| ;
>> drivers/scsi/sssraid/sssraid_os.c:1569:43: error: no member named 'msi_list' in 'struct device'
1569 | struct list_head *msi_list = &pdev->dev.msi_list;
| ~~~~~~~~~ ^
>> drivers/scsi/sssraid/sssraid_os.c:1581:5: error: 'continue' statement not in loop statement
1581 | continue;
| ^
drivers/scsi/sssraid/sssraid_os.c:1591:3: error: 'continue' statement not in loop statement
1591 | continue;
| ^
5 errors generated.
vim +/for_each_pci_msi_entry +1568 drivers/scsi/sssraid/sssraid_os.c
1550
1551 static int sssraid_map_queues(struct Scsi_Host *shost)
1552 {
1553 struct sssraid_ioc *sdioc = shost_priv(shost);
1554 struct pci_dev *pdev = sdioc->pdev;
1555 struct msi_desc *entry = NULL;
1556 struct irq_affinity_desc *affinity = NULL;
1557 struct blk_mq_tag_set *tag_set = &shost->tag_set;
1558 struct blk_mq_queue_map *queue_map = &tag_set->map[HCTX_TYPE_DEFAULT];
1559 const struct cpumask *node_mask = NULL;
1560 unsigned int queue_offset = queue_map->queue_offset;
1561 unsigned int *map = queue_map->mq_map;
1562 unsigned int nr_queues = queue_map->nr_queues;
1563 unsigned int node_id, node_id_last = 0xFFFFFFFF;
1564 int cpu, first_sibling, cpu_index = 0;
1565 u8 node_count = 0, i;
1566 unsigned int node_id_array[100];
1567
> 1568 for_each_pci_msi_entry(entry, pdev) {
> 1569 struct list_head *msi_list = &pdev->dev.msi_list;
1570
1571 if (list_is_last(msi_list, &entry->list))
1572 goto get_next_numa_node;
1573
1574 if (entry->irq) {
1575 affinity = entry->affinity;
1576 node_mask = &affinity->mask;
1577
1578 cpu = cpumask_first(node_mask);
1579 node_id = cpu_to_node(cpu);
1580 if (node_id_last == node_id)
> 1581 continue;
1582
1583 for (i = 0; i < node_count; i++) {
1584 if (node_id == node_id_array[i])
1585 goto get_next_numa_node;
1586 }
1587 node_id_array[node_count++] = node_id;
1588 node_id_last = node_id;
1589 }
1590 get_next_numa_node:
1591 continue;
1592 }
1593
1594 for (i = 0; i < node_count; i++) {
1595 node_mask = cpumask_of_node(node_id_array[i]);
1596 dbgprint(sdioc, "NUMA_node = %d\n", node_id_array[i]);
1597 for_each_cpu(cpu, node_mask) {
1598 if (cpu_index < nr_queues) {
1599 map[cpu_index++] = queue_offset + (cpu % nr_queues);
1600 } else {
1601 first_sibling = sssraid_get_first_sibling(cpu);
1602 if (first_sibling == cpu)
1603 map[cpu_index++] = queue_offset + (cpu % nr_queues);
1604 else
1605 map[cpu_index++] = map[first_sibling];
1606 }
1607 dbgprint(sdioc, "map[%d] = %d\n", cpu_index - 1, map[cpu_index - 1]);
1608 }
1609 }
1610
1611 return 0;
1612 }
1613
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
CVE-2024-27437
Alex Williamson (1):
vfio/pci: Disable auto-enable of exclusive INTx IRQ
Barry Song (1):
genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
drivers/vfio/pci/vfio_pci_intrs.c | 17 ++++++++++-------
include/linux/interrupt.h | 4 ++++
kernel/irq/manage.c | 11 +++++++++--
3 files changed, 23 insertions(+), 9 deletions(-)
--
2.34.1
2
3

[openeuler:openEuler-1.0-LTS 17814/22098] drivers/edac/.tmp_skx_common.o: warning: objtool: missing symbol for section .text
by kernel test robot 15 Apr '24
by kernel test robot 15 Apr '24
15 Apr '24
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: ff773a407598b9c693c9dc10e0dc587828127aa6
commit: e34047f6dc606c123911c6db8fa424bb4a035262 [17814/22098] EDAC, skx_edac: Delete duplicated code
config: x86_64-buildonly-randconfig-005-20240415 (https://download.01.org/0day-ci/archive/20240415/202404151440.syDdJhZl-lkp@…)
compiler: gcc-13 (Ubuntu 13.2.0-4ubuntu3) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240415/202404151440.syDdJhZl-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202404151440.syDdJhZl-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/edac/skx_common.c: In function 'skx_mce_output_error':
drivers/edac/skx_common.c:470:15: warning: variable 'type' set but not used [-Wunused-but-set-variable]
470 | char *type, *optype;
| ^~~~
drivers/edac/skx_common.c: In function 'skx_get_dimm_info':
drivers/edac/skx_common.c:309:79: warning: '_DIMM#' directive output may be truncated writing 6 bytes into a region of size between 0 and 9 [-Wformat-truncation=]
309 | snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
| ^~~~~~
drivers/edac/skx_common.c:309:52: note: using the range [0, 4294967295] for directive argument
309 | snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/edac/skx_common.c:309:9: note: 'snprintf' output between 31 and 53 bytes into a destination of size 32
309 | snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
310 | imc->src_id, imc->lmc, chan, dimmno);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/edac/skx_common.c: In function 'skx_get_nvdimm_info':
drivers/edac/skx_common.c:357:79: warning: '_DIMM#' directive output may be truncated writing 6 bytes into a region of size between 0 and 9 [-Wformat-truncation=]
357 | snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
| ^~~~~~
drivers/edac/skx_common.c:357:52: note: using the range [0, 4294967295] for directive argument
357 | snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/edac/skx_common.c:357:9: note: 'snprintf' output between 31 and 53 bytes into a destination of size 32
357 | snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
358 | imc->src_id, imc->lmc, chan, dimmno);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/edac/.tmp_skx_common.o: warning: objtool: missing symbol for section .text
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:openEuler-1.0-LTS 5421/22098] include/linux/uaccess.h:112:17: warning: 'uf' may be used uninitialized
by kernel test robot 15 Apr '24
by kernel test robot 15 Apr '24
15 Apr '24
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: ff773a407598b9c693c9dc10e0dc587828127aa6
commit: 71e217e85c3dff8a9151707ed3afc7b4b054a2d4 [5421/22098] selinux: use kernel linux/socket.h for genheaders and mdp
config: arm64-randconfig-002-20240415 (https://download.01.org/0day-ci/archive/20240415/202404151325.D66sRhzh-lkp@…)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240415/202404151325.D66sRhzh-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202404151325.D66sRhzh-lkp@intel.com/
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
In file included from drivers/net/tun.c:53:
In function '__skb_queue_splice',
inlined from 'skb_queue_splice_tail_init' at include/linux/skbuff.h:1801:3,
inlined from 'tun_napi_receive' at drivers/net/tun.c:287:2:
include/linux/skbuff.h:1741:20: warning: array subscript 'struct sk_buff[0]' is partly outside array bounds of 'struct sk_buff_head[1]' [-Warray-bounds=]
1741 | next->prev = last;
| ~~~~~~~~~~~^~~~~~
drivers/net/tun.c: In function 'tun_napi_receive':
drivers/net/tun.c:280:29: note: object 'process_queue' of size 24
280 | struct sk_buff_head process_queue;
| ^~~~~~~~~~~~~
In file included from include/linux/poll.h:12,
from drivers/net/tun.c:50:
In function '_copy_from_user',
inlined from 'copy_from_user' at include/linux/uaccess.h:144:7,
inlined from 'update_filter' at drivers/net/tun.c:923:6:
>> include/linux/uaccess.h:112:17: warning: 'uf' may be used uninitialized [-Wmaybe-uninitialized]
112 | kasan_check_write(to, n);
| ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from include/linux/compiler.h:251,
from include/linux/kernel.h:10,
from include/linux/list.h:9,
from include/linux/module.h:10,
from drivers/net/tun.c:44:
include/linux/kasan-checks.h: In function 'update_filter':
include/linux/kasan-checks.h:7:6: note: by argument 1 of type 'const volatile void *' to 'kasan_check_write' declared here
7 | void kasan_check_write(const volatile void *p, unsigned int size);
| ^~~~~~~~~~~~~~~~~
drivers/net/tun.c:920:27: note: 'uf' declared here
920 | struct tun_filter uf;
| ^~
In function '_copy_from_user',
inlined from 'copy_from_user' at include/linux/uaccess.h:144:7,
inlined from 'tun_set_ebpf' at drivers/net/tun.c:2825:6:
include/linux/uaccess.h:112:17: warning: 'fd' may be used uninitialized [-Wmaybe-uninitialized]
112 | kasan_check_write(to, n);
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/kasan-checks.h: In function 'tun_set_ebpf':
include/linux/kasan-checks.h:7:6: note: by argument 1 of type 'const volatile void *' to 'kasan_check_write' declared here
7 | void kasan_check_write(const volatile void *p, unsigned int size);
| ^~~~~~~~~~~~~~~~~
drivers/net/tun.c:2823:13: note: 'fd' declared here
2823 | int fd;
| ^~
In function '__skb_queue_splice',
inlined from 'skb_queue_splice_tail_init' at include/linux/skbuff.h:1801:3,
inlined from 'tun_rx_batched.isra' at drivers/net/tun.c:1538:3:
include/linux/skbuff.h:1738:20: warning: array subscript 'struct sk_buff[0]' is partly outside array bounds of 'struct sk_buff_head[1]' [-Warray-bounds=]
1738 | prev->next = first;
| ~~~~~~~~~~~^~~~~~~
drivers/net/tun.c: In function 'tun_rx_batched.isra':
drivers/net/tun.c:1523:29: note: object 'process_queue' of size 24
1523 | struct sk_buff_head process_queue;
| ^~~~~~~~~~~~~
In function '__skb_queue_splice',
inlined from 'skb_queue_splice_tail_init' at include/linux/skbuff.h:1801:3,
inlined from 'tun_rx_batched.isra' at drivers/net/tun.c:1538:3:
include/linux/skbuff.h:1741:20: warning: array subscript 'struct sk_buff[0]' is partly outside array bounds of 'struct sk_buff_head[1]' [-Warray-bounds=]
1741 | next->prev = last;
| ~~~~~~~~~~~^~~~~~
drivers/net/tun.c: In function 'tun_rx_batched.isra':
drivers/net/tun.c:1523:29: note: object 'process_queue' of size 24
1523 | struct sk_buff_head process_queue;
| ^~~~~~~~~~~~~
In file included from drivers/net/tun.c:54:
In function 'rps_record_sock_flow',
inlined from 'sock_rps_record_flow_hash' at include/net/sock.h:977:2,
inlined from 'tun_flow_update' at drivers/net/tun.c:540:3:
include/linux/netdevice.h:717:32: warning: array subscript index is outside array bounds of 'u32[0]' {aka 'unsigned int[]'} [-Warray-bounds=]
717 | if (table->ents[index] != val)
| ~~~~~~~~~~~^~~~~~~
include/linux/netdevice.h: In function 'tun_flow_update':
include/linux/netdevice.h:698:17: note: while referencing 'ents'
698 | u32 ents[0] ____cacheline_aligned_in_smp;
| ^~~~
In function 'rps_record_sock_flow',
inlined from 'sock_rps_record_flow_hash' at include/net/sock.h:977:2,
inlined from 'tun_flow_update' at drivers/net/tun.c:540:3:
include/linux/netdevice.h:718:36: warning: array subscript index is outside array bounds of 'u32[0]' {aka 'unsigned int[]'} [-Warray-bounds=]
718 | table->ents[index] = val;
| ~~~~~~~~~~~^~~~~~~
include/linux/netdevice.h: In function 'tun_flow_update':
include/linux/netdevice.h:698:17: note: while referencing 'ents'
698 | u32 ents[0] ____cacheline_aligned_in_smp;
| ^~~~
In file included from include/asm-generic/preempt.h:5,
from ./arch/arm64/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:81,
from include/linux/rcupdate.h:40,
from include/linux/rculist.h:11,
from include/linux/pid.h:5,
from include/linux/sched.h:14,
from arch/arm64/include/asm/compat.h:25,
from arch/arm64/include/asm/stat.h:24,
from include/linux/stat.h:6,
from include/linux/module.h:11:
In function 'check_object_size',
inlined from 'check_copy_size' at include/linux/thread_info.h:150:2,
inlined from 'copy_from_user' at include/linux/uaccess.h:143:6,
inlined from '__tun_chr_ioctl' at drivers/net/tun.c:2858:7:
include/linux/thread_info.h:119:17: warning: 'ifr' may be used uninitialized [-Wmaybe-uninitialized]
119 | __check_object_size(ptr, n, to_user);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/thread_info.h: In function '__tun_chr_ioctl':
include/linux/thread_info.h:112:13: note: by argument 1 of type 'const void *' to '__check_object_size' declared here
112 | extern void __check_object_size(const void *ptr, unsigned long n,
| ^~~~~~~~~~~~~~~~~~~
drivers/net/tun.c:2846:22: note: 'ifr' declared here
2846 | struct ifreq ifr;
| ^~~
drivers/net/tun.c:561: warning: Function parameter or member 'e' not described in 'tun_flow_save_rps_rxhash'
drivers/net/tun.c:561: warning: Function parameter or member 'hash' not described in 'tun_flow_save_rps_rxhash'
--
from net/bridge/netfilter/ebtables.c:21:
In function '_copy_from_user',
inlined from 'copy_from_user' at include/linux/uaccess.h:144:7,
inlined from 'compat_copy_ebt_replace_from_user' at net/bridge/netfilter/ebtables.c:2175:6:
include/linux/uaccess.h:112:17: warning: 'tmp' may be used uninitialized [-Wmaybe-uninitialized]
112 | kasan_check_write(to, n);
| ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from include/linux/compiler.h:251,
from include/asm-generic/bug.h:5,
from arch/arm64/include/asm/bug.h:37,
from include/linux/bug.h:5,
from include/linux/mmdebug.h:5,
from include/linux/gfp.h:5,
from include/linux/umh.h:4,
from include/linux/kmod.h:22,
from net/bridge/netfilter/ebtables.c:18:
include/linux/kasan-checks.h: In function 'compat_copy_ebt_replace_from_user':
include/linux/kasan-checks.h:7:6: note: by argument 1 of type 'const volatile void *' to 'kasan_check_write' declared here
7 | void kasan_check_write(const volatile void *p, unsigned int size);
| ^~~~~~~~~~~~~~~~~
net/bridge/netfilter/ebtables.c:2169:35: note: 'tmp' declared here
2169 | struct compat_ebt_replace tmp;
| ^~~
In function '_copy_from_user',
inlined from 'copy_from_user' at include/linux/uaccess.h:144:7,
inlined from 'copy_everything_to_user' at net/bridge/netfilter/ebtables.c:1444:6:
include/linux/uaccess.h:112:17: warning: 'tmp' may be used uninitialized [-Wmaybe-uninitialized]
112 | kasan_check_write(to, n);
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/kasan-checks.h: In function 'copy_everything_to_user':
include/linux/kasan-checks.h:7:6: note: by argument 1 of type 'const volatile void *' to 'kasan_check_write' declared here
7 | void kasan_check_write(const volatile void *p, unsigned int size);
| ^~~~~~~~~~~~~~~~~
net/bridge/netfilter/ebtables.c:1426:28: note: 'tmp' declared here
1426 | struct ebt_replace tmp;
| ^~~
In function '_copy_from_user',
inlined from 'copy_from_user' at include/linux/uaccess.h:144:7,
inlined from 'do_replace' at net/bridge/netfilter/ebtables.c:1083:6:
include/linux/uaccess.h:112:17: warning: 'tmp' may be used uninitialized [-Wmaybe-uninitialized]
112 | kasan_check_write(to, n);
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/kasan-checks.h: In function 'do_replace':
include/linux/kasan-checks.h:7:6: note: by argument 1 of type 'const volatile void *' to 'kasan_check_write' declared here
7 | void kasan_check_write(const volatile void *p, unsigned int size);
| ^~~~~~~~~~~~~~~~~
net/bridge/netfilter/ebtables.c:1081:28: note: 'tmp' declared here
1081 | struct ebt_replace tmp;
| ^~~
In function '_copy_from_user',
inlined from 'copy_from_user' at include/linux/uaccess.h:144:7,
inlined from 'compat_copy_everything_to_user' at net/bridge/netfilter/ebtables.c:1824:6:
include/linux/uaccess.h:112:17: warning: 'tmp' may be used uninitialized [-Wmaybe-uninitialized]
112 | kasan_check_write(to, n);
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/kasan-checks.h: In function 'compat_copy_everything_to_user':
include/linux/kasan-checks.h:7:6: note: by argument 1 of type 'const volatile void *' to 'kasan_check_write' declared here
7 | void kasan_check_write(const volatile void *p, unsigned int size);
| ^~~~~~~~~~~~~~~~~
net/bridge/netfilter/ebtables.c:1804:41: note: 'tmp' declared here
1804 | struct compat_ebt_replace repl, tmp;
| ^~~
In file included from include/linux/netfilter/x_tables.h:9:
net/bridge/netfilter/ebtables.c: In function 'do_update_counters.isra':
net/bridge/netfilter/ebtables.c:1292:49: warning: array subscript i is outside array bounds of 'struct ebt_counter[0]' [-Warray-bounds=]
1292 | ADD_COUNTER(t->private->counters[i], tmp[i].pcnt, tmp[i].bcnt);
include/uapi/linux/netfilter/x_tables.h:108:34: note: in definition of macro 'ADD_COUNTER'
108 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
| ^
In file included from net/bridge/netfilter/ebtables.c:22:
include/linux/netfilter_bridge/ebtables.h:88:28: note: while referencing 'counters'
88 | struct ebt_counter counters[0] ____cacheline_aligned;
| ^~~~~~~~
net/bridge/netfilter/ebtables.c:1292:49: warning: array subscript i is outside array bounds of 'struct ebt_counter[0]' [-Warray-bounds=]
1292 | ADD_COUNTER(t->private->counters[i], tmp[i].pcnt, tmp[i].bcnt);
include/uapi/linux/netfilter/x_tables.h:108:34: note: in definition of macro 'ADD_COUNTER'
108 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
| ^
include/linux/netfilter_bridge/ebtables.h:88:28: note: while referencing 'counters'
88 | struct ebt_counter counters[0] ____cacheline_aligned;
| ^~~~~~~~
net/bridge/netfilter/ebtables.c:1292:49: warning: array subscript i is outside array bounds of 'struct ebt_counter[0]' [-Warray-bounds=]
1292 | ADD_COUNTER(t->private->counters[i], tmp[i].pcnt, tmp[i].bcnt);
include/uapi/linux/netfilter/x_tables.h:108:51: note: in definition of macro 'ADD_COUNTER'
108 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
| ^
include/linux/netfilter_bridge/ebtables.h:88:28: note: while referencing 'counters'
88 | struct ebt_counter counters[0] ____cacheline_aligned;
| ^~~~~~~~
net/bridge/netfilter/ebtables.c:1292:49: warning: array subscript i is outside array bounds of 'struct ebt_counter[0]' [-Warray-bounds=]
1292 | ADD_COUNTER(t->private->counters[i], tmp[i].pcnt, tmp[i].bcnt);
include/uapi/linux/netfilter/x_tables.h:108:51: note: in definition of macro 'ADD_COUNTER'
108 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
| ^
include/linux/netfilter_bridge/ebtables.h:88:28: note: while referencing 'counters'
88 | struct ebt_counter counters[0] ____cacheline_aligned;
| ^~~~~~~~
In function '_copy_from_user',
inlined from 'copy_from_user' at include/linux/uaccess.h:144:7,
inlined from 'update_counters' at net/bridge/netfilter/ebtables.c:1308:6:
>> include/linux/uaccess.h:112:17: warning: 'hlp' may be used uninitialized [-Wmaybe-uninitialized]
112 | kasan_check_write(to, n);
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/kasan-checks.h: In function 'update_counters':
include/linux/kasan-checks.h:7:6: note: by argument 1 of type 'const volatile void *' to 'kasan_check_write' declared here
7 | void kasan_check_write(const volatile void *p, unsigned int size);
| ^~~~~~~~~~~~~~~~~
net/bridge/netfilter/ebtables.c:1306:28: note: 'hlp' declared here
1306 | struct ebt_replace hlp;
| ^~~
vim +/uf +112 include/linux/uaccess.h
d597580d373774 Al Viro 2017-03-20 104
d597580d373774 Al Viro 2017-03-20 105 #ifdef INLINE_COPY_FROM_USER
d597580d373774 Al Viro 2017-03-20 106 static inline unsigned long
d597580d373774 Al Viro 2017-03-20 107 _copy_from_user(void *to, const void __user *from, unsigned long n)
d597580d373774 Al Viro 2017-03-20 108 {
d597580d373774 Al Viro 2017-03-20 109 unsigned long res = n;
9c5f6908de03a4 Al Viro 2017-06-29 110 might_fault();
4983cb67a383a7 Linus Torvalds 2019-02-14 111 if (likely(access_ok(from, n))) {
9c5f6908de03a4 Al Viro 2017-06-29 @112 kasan_check_write(to, n);
d597580d373774 Al Viro 2017-03-20 113 res = raw_copy_from_user(to, from, n);
9c5f6908de03a4 Al Viro 2017-06-29 114 }
d597580d373774 Al Viro 2017-03-20 115 if (unlikely(res))
d597580d373774 Al Viro 2017-03-20 116 memset(to + (n - res), 0, res);
d597580d373774 Al Viro 2017-03-20 117 return res;
d597580d373774 Al Viro 2017-03-20 118 }
d597580d373774 Al Viro 2017-03-20 119 #else
d597580d373774 Al Viro 2017-03-20 120 extern unsigned long
d597580d373774 Al Viro 2017-03-20 121 _copy_from_user(void *, const void __user *, unsigned long);
d597580d373774 Al Viro 2017-03-20 122 #endif
d597580d373774 Al Viro 2017-03-20 123
:::::: The code at line 112 was first introduced by commit
:::::: 9c5f6908de03a4f52ba7364b11fcd6116225480c copy_{from,to}_user(): move kasan checks and might_fault() out-of-line
:::::: TO: Al Viro <viro(a)zeniv.linux.org.uk>
:::::: CC: Al Viro <viro(a)zeniv.linux.org.uk>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0