projects/linux·commit bf0e0228

Merge tag 'powerpc-7.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

bf0e0228 · Linus Torvalds <[email protected]> · 2026-05-09 08:03:21 -07:00

Pull powerpc fixes from Madhavan Srinivasan:

 - Fix KASAN sanitization flag for core_$(BITS).o

 - Fixes for handling offset values in pseries htmdump

 - Fix interrupt mask in cpm1_gpiochip_add16()

 - ps3/pasemi fixes to drop redundant result assignment

 - Fixes in papr-hvpipe code path

 - powerpc/perf: Update check for PERF_SAMPLE_DATA_SRC marked events

Thanks to Aboorva Devarajan, Athira Rajeev, Christophe Leroy (CS GROUP),
Geert Uytterhoeven, Haren Myneni, Krzysztof Kozlowski, Mukesh Kumar
Chaurasiya (IBM), Nathan Chancellor, Ritesh Harjani (IBM), Shivani
Nittor, Sourabh Jain, Thomas Zimmermann, and Venkat Rao Bagalkote.

* tag 'powerpc-7.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (21 commits)
  powerpc/pasemi: Drop redundant res assignment
  powerpc/ps3: Drop redundant result assignment
  powerpc/vdso: Drop -DCC_USING_PATCHABLE_FUNCTION_ENTRY from 32-bit flags with clang
  arch/powerpc: Drop CONFIG_FIRMWARE_EDID from defconfig files
  powerpc/perf: Update check for PERF_SAMPLE_DATA_SRC marked events
  powerpc/8xx: Fix interrupt mask in cpm1_gpiochip_add16()
  powerpc/vmx: avoid KASAN instrumentation in enter_vmx_ops() for kexec
  powerpc/kdump: fix KASAN sanitization flag for core_$(BITS).o
  pseries/papr-hvpipe: Fix style and checkpatch issues in enable_hvpipe_IRQ()
  pseries/papr-hvpipe: Refactor and simplify hvpipe_rtas_recv_msg()
  pseries/papr-hvpipe: Kill task_struct pointer from struct hvpipe_source_info
  pseries/papr-hvpipe: Simplify spin unlock usage in papr_hvpipe_handle_release()
  pseries/papr-hvpipe: Fix the usage of copy_to_user()
  pseries/papr-hvpipe: Fix & simplify error handling in papr_hvpipe_init()
  pseries/papr-hvpipe: Fix null ptr deref in papr_hvpipe_dev_create_handle()
  pseries/papr-hvpipe: Prevent kernel stack memory leak to userspace
  pseries/papr-hvpipe: Fix race with interrupt handler
  powerpc/pseries/htmdump: Add memory configuration dump support to htmdump module
  powerpc/pseries/htmdump: Fix the offset value used in htm status dump
  powerpc/pseries/htmdump: Fix the offset value used in processor configuration dump
  ...
Commit
bf0e022821fa516cd6eb0292fcb4ccdd4e201c9f
Parents
70390501 · f583bd5f

Merge commit. Changes below are compared with the first parent: 70390501.

Changes

18 files changed · +235 −121

Only the first 600 diff lines are shown. Download the complete patch.

arch/powerpc/configs/amigaone_defconfig

View file
diff --git a/arch/powerpc/configs/amigaone_defconfig b/arch/powerpc/configs/amigaone_defconfig
index 69ef3dc..7a51539 100644
--- a/arch/powerpc/configs/amigaone_defconfig
+++ b/arch/powerpc/configs/amigaone_defconfig
@@ -76,7 +76,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_RADEON=y
CONFIG_FB_3DFX=y

arch/powerpc/configs/chrp32_defconfig

View file
diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig
index b799c95..66eae5b 100644
--- a/arch/powerpc/configs/chrp32_defconfig
+++ b/arch/powerpc/configs/chrp32_defconfig
@@ -76,7 +76,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_NVRAM=y
# CONFIG_HWMON is not set
CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
CONFIG_FB_OF=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y

arch/powerpc/configs/g5_defconfig

View file
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
index 04bbb37..e999671 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -121,7 +121,6 @@ CONFIG_I2C_CHARDEV=y
CONFIG_AGP=m
CONFIG_AGP_UNINORTH=m
CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_OF=y
CONFIG_FB_NVIDIA=y

arch/powerpc/configs/pasemi_defconfig

View file
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig
index 8bbf51b..89bcbeb 100644
--- a/arch/powerpc/configs/pasemi_defconfig
+++ b/arch/powerpc/configs/pasemi_defconfig
@@ -98,7 +98,6 @@ CONFIG_SENSORS_LM85=y
CONFIG_SENSORS_LM90=y
CONFIG_DRM=y
CONFIG_DRM_RADEON=y
-CONFIG_FIRMWARE_EDID=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_VGA16=y
CONFIG_FB_NVIDIA=y

arch/powerpc/configs/powernv_defconfig

View file
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
index cc98024..5d32c27 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -196,7 +196,6 @@ CONFIG_I2C_CHARDEV=y
# CONFIG_PTP_1588_CLOCK is not set
CONFIG_DRM=y
CONFIG_DRM_AST=y
-CONFIG_FIRMWARE_EDID=y
CONFIG_FB_OF=y
CONFIG_FB_MATROX=m
CONFIG_FB_MATROX_MILLENIUM=y

arch/powerpc/configs/ppc64_defconfig

View file
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 3bf518e..6316ca4 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -249,7 +249,6 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_AMD8111=y
CONFIG_I2C_PASEMI=y
CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
CONFIG_FB_OF=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y

arch/powerpc/configs/ppc64e_defconfig

View file
diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig
index 0fd49f6..20cc17d 100644
--- a/arch/powerpc/configs/ppc64e_defconfig
+++ b/arch/powerpc/configs/ppc64e_defconfig
@@ -118,7 +118,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_AMD8111=y
CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
CONFIG_FB_OF=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y

arch/powerpc/configs/skiroot_defconfig

View file
diff --git a/arch/powerpc/configs/skiroot_defconfig b/arch/powerpc/configs/skiroot_defconfig
index ff1bed4..005536e 100644
--- a/arch/powerpc/configs/skiroot_defconfig
+++ b/arch/powerpc/configs/skiroot_defconfig
@@ -214,7 +214,6 @@ CONFIG_SENSORS_IBMPOWERNV=m
CONFIG_DRM=m
CONFIG_DRM_AST=m
CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y

arch/powerpc/kernel/vdso/Makefile

View file
diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
index 8834dfe..368759f 100644
--- a/arch/powerpc/kernel/vdso/Makefile
+++ b/arch/powerpc/kernel/vdso/Makefile
@@ -62,6 +62,12 @@ CC32FLAGSREMOVE += -fno-stack-clash-protection
# 32-bit one. clang validates the values passed to these arguments during
# parsing, even when -fno-stack-protector is passed afterwards.
CC32FLAGSREMOVE += -mstack-protector-guard%
+# ftrace is disabled for the vdso but arch/powerpc/Makefile adds this define to
+# KBUILD_CPPFLAGS, which enables use of the 'patchable_function_entry'
+# attribute in the 'inline' define via 'notrace'. This attribute is not
+# supported for the powerpcle target, resulting in many instances of
+# -Wunknown-attributes.
+CC32FLAGSREMOVE += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
endif
LD32FLAGS := -Wl,-soname=linux-vdso32.so.1
AS32FLAGS := -D__VDSO32__

arch/powerpc/kexec/Makefile

View file
diff --git a/arch/powerpc/kexec/Makefile b/arch/powerpc/kexec/Makefile
index 470eb04..ec7a0ee 100644
--- a/arch/powerpc/kexec/Makefile
+++ b/arch/powerpc/kexec/Makefile
@@ -16,4 +16,4 @@ GCOV_PROFILE_core_$(BITS).o := n
KCOV_INSTRUMENT_core_$(BITS).o := n
UBSAN_SANITIZE_core_$(BITS).o := n
KASAN_SANITIZE_core.o := n
-KASAN_SANITIZE_core_$(BITS) := n
+KASAN_SANITIZE_core_$(BITS).o := n

arch/powerpc/lib/vmx-helper.c

View file
diff --git a/arch/powerpc/lib/vmx-helper.c b/arch/powerpc/lib/vmx-helper.c
index 554b248..57e897b 100644
--- a/arch/powerpc/lib/vmx-helper.c
+++ b/arch/powerpc/lib/vmx-helper.c
@@ -52,7 +52,14 @@ int exit_vmx_usercopy(void)
}
EXPORT_SYMBOL(exit_vmx_usercopy);
-int enter_vmx_ops(void)
+/*
+ * Can be called from kexec copy_page() path with MMU off. The kexec
+ * code sets preempt_count to HARDIRQ_OFFSET so we return early here.
+ * Since in_interrupt() is always inline, __no_sanitize_address on this
+ * function is sufficient to avoid KASAN shadow memory accesses in real
+ * mode.
+ */
+int __no_sanitize_address enter_vmx_ops(void)
{
if (in_interrupt())
return 0;

arch/powerpc/perf/core-book3s.c

View file
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 8b00814..2e6adf5 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -2242,6 +2242,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
const u64 last_period = event->hw.last_period;
s64 prev, delta, left;
int record = 0;
+ int mark_event = regs->dsisr & MMCRA_SAMPLE_ENABLE;
if (event->hw.state & PERF_HES_STOPPED) {
write_pmc(event->hw.idx, 0);
@@ -2304,9 +2305,9 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
* In ISA v3.0 and before values "0" and "7" are considered reserved.
* In ISA v3.1, value "7" has been used to indicate "larx/stcx".
* Drop the sample if "type" has reserved values for this field with a
- * ISA version check.
+ * ISA version check for marked events.
*/
- if (event->attr.sample_type & PERF_SAMPLE_DATA_SRC &&
+ if (mark_event && event->attr.sample_type & PERF_SAMPLE_DATA_SRC &&
ppmu->get_mem_data_src) {
val = (regs->dar & SIER_TYPE_MASK) >> SIER_TYPE_SHIFT;
if (val == 0 || (val == 7 && !cpu_has_feature(CPU_FTR_ARCH_31))) {

arch/powerpc/platforms/8xx/cpm1.c

View file
diff --git a/arch/powerpc/platforms/8xx/cpm1.c b/arch/powerpc/platforms/8xx/cpm1.c
index 7433be7..f00734f 100644
--- a/arch/powerpc/platforms/8xx/cpm1.c
+++ b/arch/powerpc/platforms/8xx/cpm1.c
@@ -477,7 +477,7 @@ int cpm1_gpiochip_add16(struct device *dev)
struct device_node *np = dev->of_node;
struct cpm1_gpio16_chip *cpm1_gc;
struct gpio_chip *gc;
- u16 mask;
+ u32 mask;
cpm1_gc = devm_kzalloc(dev, sizeof(*cpm1_gc), GFP_KERNEL);
if (!cpm1_gc)
@@ -485,7 +485,7 @@ int cpm1_gpiochip_add16(struct device *dev)
spin_lock_init(&cpm1_gc->lock);
- if (!of_property_read_u16(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
+ if (!of_property_read_u32(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
int i, j;
for (i = 0, j = 0; i < 16; i++)

arch/powerpc/platforms/pasemi/pci.c

View file
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
index 60f990a..2df9552 100644
--- a/arch/powerpc/platforms/pasemi/pci.c
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -272,13 +272,12 @@ void __init pas_pci_init(void)
{
struct device_node *root = of_find_node_by_path("/");
struct device_node *np;
- int res;
pci_set_flags(PCI_SCAN_ALL_PCIE_DEVS);
np = of_find_compatible_node(root, NULL, "pasemi,rootbus");
if (np) {
- res = pas_add_bridge(np);
+ pas_add_bridge(np);
of_node_put(np);
}
of_node_put(root);

arch/powerpc/platforms/ps3/device-init.c

View file
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index 12c4737..9109c21 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -950,8 +950,6 @@ static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
static int __init ps3_register_devices(void)
{
- int result;
-
if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
return -ENODEV;
@@ -959,7 +957,7 @@ static int __init ps3_register_devices(void)
/* ps3_repository_dump_bus_info(); */
- result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
+ ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
ps3_register_vuart_devices();

arch/powerpc/platforms/pseries/htmdump.c

View file
diff --git a/arch/powerpc/platforms/pseries/htmdump.c b/arch/powerpc/platforms/pseries/htmdump.c
index 742ec52..489a80e 100644
--- a/arch/powerpc/platforms/pseries/htmdump.c
+++ b/arch/powerpc/platforms/pseries/htmdump.c
@@ -16,6 +16,7 @@ static void *htm_buf;
static void *htm_status_buf;
static void *htm_info_buf;
static void *htm_caps_buf;
+static void *htm_mem_buf;
static u32 nodeindex;
static u32 nodalchipindex;
static u32 coreindexonchip;
@@ -86,7 +87,7 @@ static ssize_t htm_return_check(long rc)
static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
- void *htm_buf = filp->private_data;
+ void *htm_buf_data = filp->private_data;
unsigned long page, read_size, available;
loff_t offset;
long rc, ret;
@@ -100,7 +101,7 @@ static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
* - last three values are address, size and offset
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
- htmtype, H_HTM_OP_DUMP_DATA, virt_to_phys(htm_buf),
+ htmtype, H_HTM_OP_DUMP_DATA, virt_to_phys(htm_buf_data),
PAGE_SIZE, page);
ret = htm_return_check(rc);
@@ -112,7 +113,61 @@ static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
available = PAGE_SIZE;
read_size = min(count, available);
*ppos += read_size;
- return simple_read_from_buffer(ubuf, count, &offset, htm_buf, available);
+ return simple_read_from_buffer(ubuf, count, &offset, htm_buf_data, available);
+}
+
+static ssize_t htmsystem_mem_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ void *htm_mem_data = filp->private_data;
+ long rc, ret;
+ u64 *num_entries;
+ u64 to_copy = 0;
+ loff_t offset = 0;
+ u64 mem_offset = 0;
+
+ /*
+ * Invoke H_HTM call with:
+ * - operation as htm status (H_HTM_OP_STATUS)
+ * - last three values as addr, size and offset. "offset"
+ * is value from output buffer header that points to next
+ * entry to dump. 0 is the first entry to dump. next entry
+ * is read from the output bufferbyte offset 0x8.
+ *
+ * When first time hcall is invoked, mem_offset should be
+ * zero because zero is the first entry.
+ * In the next hcall, offset of next entry to read from is
+ * picked from output buffer header itself. So don't fill
+ * mem_offset for first read.
+ *
+ * If there is no further data to read in next iteration,
+ * offset value from output buffer header will point to -1.
+ */
+ if (*ppos) {
+ mem_offset = *(u64 *)(htm_mem_data + 0x8);
+ if (mem_offset == -1)
+ return 0;
+ }
+ rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
+ htmtype, H_HTM_OP_DUMP_SYSMEM_CONF, virt_to_phys(htm_mem_data),
+ PAGE_SIZE, be64_to_cpu(mem_offset));
+ ret = htm_return_check(rc);
+ if (ret <= 0) {
+ pr_debug("H_HTM hcall returned for op: H_HTM_OP_DUMP_SYSMEM_CONF with hcall returning %ld\n", ret);
+ return ret;
+ }
+
+ /*
+ * HTM system mem buffer, start of buffer + 0x10 gives the
+ * number of HTM entries in the buffer.
+ * So total count to copy is:
+ * 32 bytes (for first 5 fields) + (number of HTM entries * entry size)
+ */
+ num_entries = htm_mem_data + 0x10;
+ to_copy = 32 + (be64_to_cpu(*num_entries) * 32);
+
+ *ppos += to_copy;
+ return simple_read_from_buffer(ubuf, count, &offset, htm_mem_data, to_copy);
}
static const struct file_operations htmdump_fops = {
@@ -121,6 +176,12 @@ static const struct file_operations htmdump_fops = {
.open = simple_open,
};
+static const struct file_operations htmsystem_mem_fops = {
+ .llseek = NULL,
+ .read = htmsystem_mem_read,
+ .open = simple_open,
+};
+
static int htmconfigure_set(void *data, u64 val)
{
long rc, ret;
@@ -226,20 +287,31 @@ static int htmstart_get(void *data, u64 *val)
static ssize_t htmstatus_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
- void *htm_status_buf = filp->private_data;
+ void *htm_status_data = filp->private_data;
long rc, ret;
u64 *num_entries;
u64 to_copy;
int htmstatus_flag;
+ loff_t offset = 0;
+ u64 status_offset = 0;
/*
* Invoke H_HTM call with:
* - operation as htm status (H_HTM_OP_STATUS)
- * - last three values as addr, size and offset
+ * - last three values as addr, size and offset.
+ * "offset" is value from output buffer header
+ * that points to next entry to dump. 0 is the first
+ * entry to dump. next entry is read from the output
+ * bufferbyte offset 0x8.
*/
+ if (*ppos) {
+ status_offset = *(u64 *)(htm_status_data + 0x8);
+ if (status_offset == -1)
+ return 0;
+ }
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
- htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_buf),
- PAGE_SIZE, 0);
+ htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_data),
+ PAGE_SIZE, be64_to_cpu(status_offset));
ret = htm_return_check(rc);
if (ret <= 0) {
@@ -255,13 +327,15 @@ static ssize_t htmstatus_read(struct file *filp, char __user *ubuf,
* So total count to copy is:
* 32 bytes (for first 7 fields) + (number of HTM entries * entry size)
*/
- num_entries = htm_status_buf + 0x10;
+ num_entries = htm_status_data + 0x10;
if (htmtype == 0x2)
htmstatus_flag = 0x8;
else
htmstatus_flag = 0x6;
to_copy = 32 + (be64_to_cpu(*num_entries) * htmstatus_flag);
- return simple_read_from_buffer(ubuf, count, ppos, htm_status_buf, to_copy);
+ *ppos += to_copy;
+
+ return simple_read_from_buffer(ubuf, count, &offset, htm_status_data, to_copy);
}
static const struct file_operations htmstatus_fops = {
@@ -273,19 +347,30 @@ static const struct file_operations htmstatus_fops = {
static ssize_t htminfo_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
- void *htm_info_buf = filp->private_data;
+ void *htm_info_data = filp->private_data;
long rc, ret;
u64 *num_entries;
u64 to_copy;
+ loff_t offset = 0;
+ u64 info_offset = 0;
/*
* Invoke H_HTM call with:
* - operation as htm status (H_HTM_OP_STATUS)
* - last three values as addr, size and offset
+ * "offset" is value from output buffer header
+ * that points to next entry to dump. 0 is the first
+ * entry to dump. next entry is read from the output
+ * bufferbyte offset 0x8.
*/
+ if (*ppos) {
+ info_offset = *(u64 *)(htm_info_data + 0x8);
+ if (info_offset == -1)
+ return 0;
+ }
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
- htmtype, H_HTM_OP_DUMP_SYSPROC_CONF, virt_to_phys(htm_info_buf),
- PAGE_SIZE, 0);
+ htmtype, H_HTM_OP_DUMP_SYSPROC_CONF, virt_to_phys(htm_info_data),
+ PAGE_SIZE, be64_to_cpu(info_offset));
ret = htm_return_check(rc);
if (ret <= 0) {
@@ -301,15 +386,17 @@ static ssize_t htminfo_read(struct file *filp, char __user *ubuf,
* So total count to copy is:
* 32 bytes (for first 5 fields) + (number of HTM entries * entry size)
*/
- num_entries = htm_info_buf + 0x10;
+ num_entries = htm_info_data + 0x10;
to_copy = 32 + (be64_to_cpu(*num_entries) * 16);
- return simple_read_from_buffer(ubuf, count, ppos, htm_info_buf, to_copy);
+
+ *ppos += to_copy;
+ return simple_read_from_buffer(ubuf, count, &offset, htm_info_data, to_copy);
}
static ssize_t htmcaps_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
- void *htm_caps_buf = filp->private_data;
+ void *htm_caps_data = filp->private_data;
long rc, ret;
/*
@@ -319,7 +406,7 @@ static ssize_t htmcaps_read(struct file *filp, char __user *ubuf,
* and zero
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
- htmtype, H_HTM_OP_CAPABILITIES, virt_to_phys(htm_caps_buf),
+ htmtype, H_HTM_OP_CAPABILITIES, virt_to_phys(htm_caps_data),
0x80, 0);
ret = htm_return_check(rc);
@@ -328,7 +415,7 @@ static ssize_t htmcaps_read(struct file *filp, char __user *ubuf,
return ret;
}
- return simple_read_from_buffer(ubuf, count, ppos, htm_caps_buf, 0x80);
+ return simple_read_from_buffer(ubuf, count, ppos, htm_caps_data, 0x80);
}
static const struct file_operations htminfo_fops = {
@@ -457,9 +544,17 @@ static int htmdump_init_debugfs(void)
return -ENOMEM;
}
+ /* Memory to present HTM system memory configuration */
+ htm_mem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!htm_mem_buf) {
+ pr_err("Failed to allocate htm mem buf\n");
+ return -ENOMEM;
+ }
+
debugfs_create_file("htmstatus", 0400, htmdump_debugfs_dir, htm_status_buf, &htmstatus_fops);
debugfs_create_file("htminfo", 0400, htmdump_debugfs_dir, htm_info_buf, &htminfo_fops);
debugfs_create_file("htmcaps", 0400, htmdump_debugfs_dir, htm_caps_buf, &htmcaps_fops);
+ debugfs_create_file("htmsystem_mem", 0400, htmdump_debugfs_dir, htm_mem_buf, &htmsystem_mem_fops);
return 0;
}
@@ -482,6 +577,10 @@ static void __exit htmdump_exit(void)
{
debugfs_remove_recursive(htmdump_debugfs_dir);
kfree(htm_buf);
+ kfree(htm_status_buf);
+ kfree(htm_info_buf);
+ kfree(htm_caps_buf);
+ kfree(htm_mem_buf);
}
module_init(htmdump_init);

arch/powerpc/platforms/pseries/papr-hvpipe.c

View file
diff --git a/arch/powerpc/platforms/pseries/papr-hvpipe.c b/arch/powerpc/platforms/pseries/papr-hvpipe.c
index 14ae480..0c40bdd 100644
--- a/arch/powerpc/platforms/pseries/papr-hvpipe.c
+++ b/arch/powerpc/platforms/pseries/papr-hvpipe.c
@@ -190,33 +190,34 @@ static int hvpipe_rtas_recv_msg(char __user *buf, int size)
return -ENOMEM;
}
- ret = rtas_ibm_receive_hvpipe_msg(work_area, &srcID,
- &bytes_written);
- if (!ret) {
- /*
- * Recv HVPIPE RTAS is successful.
- * When releasing FD or no one is waiting on the
- * specific source, issue recv HVPIPE RTAS call
- * so that pipe is not blocked - this func is called
- * with NULL buf.
- */
- if (buf) {
- if (size < bytes_written) {
- pr_err("Received the payload size = %d, but the buffer size = %d\n",
- bytes_written, size);
- bytes_written = size;
- }
- ret = copy_to_user(buf,
- rtas_work_area_raw_buf(work_area),
- bytes_written);
- if (!ret)
- ret = bytes_written;
- }
- } else {
- pr_err("ibm,receive-hvpipe-msg failed with %d\n",
- ret);
+ /*
+ * Recv HVPIPE RTAS is successful.
+ * When releasing FD or no one is waiting on the
+ * specific source, issue recv HVPIPE RTAS call
+ * so that pipe is not blocked - this func is called
+ * with NULL buf.
+ */
+ ret = rtas_ibm_receive_hvpipe_msg(work_area, &srcID, &bytes_written);
+ if (ret) {
+ pr_err("ibm,receive-hvpipe-msg failed with %d\n", ret);
+ goto out;
}
+ if (!buf)
+ goto out;
+
+ if (size < bytes_written) {
+ pr_err("Received the payload size = %d, but the buffer size = %d\n",
+ bytes_written, size);
+ bytes_written = size;
+ }
+
+ if (copy_to_user(buf, rtas_work_area_raw_buf(work_area), bytes_written))
+ ret = -EFAULT;
+ else
+ ret = bytes_written;
+
+out:
rtas_work_area_free(work_area);
return ret;
}
@@ -327,8 +328,8 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
{
struct hvpipe_source_info *src_info = file->private_data;
- struct papr_hvpipe_hdr hdr;
- long ret;
+ struct papr_hvpipe_hdr hdr = {};
+ ssize_t ret = 0;
/*
* Return -ENXIO during migration
@@ -376,7 +377,7 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
ret = copy_to_user(buf, &hdr, HVPIPE_HDR_LEN);
if (ret)
- return ret;
+ return -EFAULT;
/*
* Message event has payload, so get the payload with
@@ -385,19 +386,23 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
if (hdr.flags & HVPIPE_MSG_AVAILABLE) {
ret = hvpipe_rtas_recv_msg(buf + HVPIPE_HDR_LEN,
size - HVPIPE_HDR_LEN);
- if (ret > 0) {
+ /*
+ * Always clear MSG_AVAILABLE once the RTAS call has drained
+ * the message, regardless of whether copy_to_user succeeded.
+ */
+ if (ret >= 0 || ret == -EFAULT)
src_info->hvpipe_status &= ~HVPIPE_MSG_AVAILABLE;
- ret += HVPIPE_HDR_LEN;
- }
} else if (hdr.flags & HVPIPE_LOST_CONNECTION) {
/*
* Hypervisor is closing the pipe for the specific
* source. So notify user space.
*/
src_info->hvpipe_status &= ~HVPIPE_LOST_CONNECTION;
- ret = HVPIPE_HDR_LEN;
}
+ if (ret >= 0)
+ ret += HVPIPE_HDR_LEN;

This diff is incomplete. Download the complete patch.

arch/powerpc/platforms/pseries/papr-hvpipe.h

View file

This diff is incomplete. Download the complete patch.