Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

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
...

+235 -121
-1
arch/powerpc/configs/amigaone_defconfig
··· 76 76 # CONFIG_HW_RANDOM is not set 77 77 # CONFIG_HWMON is not set 78 78 CONFIG_FB=y 79 - CONFIG_FIRMWARE_EDID=y 80 79 CONFIG_FB_TILEBLITTING=y 81 80 CONFIG_FB_RADEON=y 82 81 CONFIG_FB_3DFX=y
-1
arch/powerpc/configs/chrp32_defconfig
··· 76 76 CONFIG_NVRAM=y 77 77 # CONFIG_HWMON is not set 78 78 CONFIG_FB=y 79 - CONFIG_FIRMWARE_EDID=y 80 79 CONFIG_FB_OF=y 81 80 CONFIG_FB_MATROX=y 82 81 CONFIG_FB_MATROX_MILLENIUM=y
-1
arch/powerpc/configs/g5_defconfig
··· 121 121 CONFIG_AGP=m 122 122 CONFIG_AGP_UNINORTH=m 123 123 CONFIG_FB=y 124 - CONFIG_FIRMWARE_EDID=y 125 124 CONFIG_FB_TILEBLITTING=y 126 125 CONFIG_FB_OF=y 127 126 CONFIG_FB_NVIDIA=y
-1
arch/powerpc/configs/pasemi_defconfig
··· 98 98 CONFIG_SENSORS_LM90=y 99 99 CONFIG_DRM=y 100 100 CONFIG_DRM_RADEON=y 101 - CONFIG_FIRMWARE_EDID=y 102 101 CONFIG_FB_TILEBLITTING=y 103 102 CONFIG_FB_VGA16=y 104 103 CONFIG_FB_NVIDIA=y
-1
arch/powerpc/configs/powernv_defconfig
··· 196 196 # CONFIG_PTP_1588_CLOCK is not set 197 197 CONFIG_DRM=y 198 198 CONFIG_DRM_AST=y 199 - CONFIG_FIRMWARE_EDID=y 200 199 CONFIG_FB_OF=y 201 200 CONFIG_FB_MATROX=m 202 201 CONFIG_FB_MATROX_MILLENIUM=y
-1
arch/powerpc/configs/ppc64_defconfig
··· 249 249 CONFIG_I2C_AMD8111=y 250 250 CONFIG_I2C_PASEMI=y 251 251 CONFIG_FB=y 252 - CONFIG_FIRMWARE_EDID=y 253 252 CONFIG_FB_OF=y 254 253 CONFIG_FB_MATROX=y 255 254 CONFIG_FB_MATROX_MILLENIUM=y
-1
arch/powerpc/configs/ppc64e_defconfig
··· 118 118 CONFIG_I2C_CHARDEV=y 119 119 CONFIG_I2C_AMD8111=y 120 120 CONFIG_FB=y 121 - CONFIG_FIRMWARE_EDID=y 122 121 CONFIG_FB_OF=y 123 122 CONFIG_FB_MATROX=y 124 123 CONFIG_FB_MATROX_MILLENIUM=y
-1
arch/powerpc/configs/skiroot_defconfig
··· 214 214 CONFIG_DRM=m 215 215 CONFIG_DRM_AST=m 216 216 CONFIG_FB=y 217 - CONFIG_FIRMWARE_EDID=y 218 217 # CONFIG_VGA_CONSOLE is not set 219 218 CONFIG_FRAMEBUFFER_CONSOLE=y 220 219 CONFIG_LOGO=y
+6
arch/powerpc/kernel/vdso/Makefile
··· 62 62 # 32-bit one. clang validates the values passed to these arguments during 63 63 # parsing, even when -fno-stack-protector is passed afterwards. 64 64 CC32FLAGSREMOVE += -mstack-protector-guard% 65 + # ftrace is disabled for the vdso but arch/powerpc/Makefile adds this define to 66 + # KBUILD_CPPFLAGS, which enables use of the 'patchable_function_entry' 67 + # attribute in the 'inline' define via 'notrace'. This attribute is not 68 + # supported for the powerpcle target, resulting in many instances of 69 + # -Wunknown-attributes. 70 + CC32FLAGSREMOVE += -DCC_USING_PATCHABLE_FUNCTION_ENTRY 65 71 endif 66 72 LD32FLAGS := -Wl,-soname=linux-vdso32.so.1 67 73 AS32FLAGS := -D__VDSO32__
+1 -1
arch/powerpc/kexec/Makefile
··· 16 16 KCOV_INSTRUMENT_core_$(BITS).o := n 17 17 UBSAN_SANITIZE_core_$(BITS).o := n 18 18 KASAN_SANITIZE_core.o := n 19 - KASAN_SANITIZE_core_$(BITS) := n 19 + KASAN_SANITIZE_core_$(BITS).o := n
+8 -1
arch/powerpc/lib/vmx-helper.c
··· 52 52 } 53 53 EXPORT_SYMBOL(exit_vmx_usercopy); 54 54 55 - int enter_vmx_ops(void) 55 + /* 56 + * Can be called from kexec copy_page() path with MMU off. The kexec 57 + * code sets preempt_count to HARDIRQ_OFFSET so we return early here. 58 + * Since in_interrupt() is always inline, __no_sanitize_address on this 59 + * function is sufficient to avoid KASAN shadow memory accesses in real 60 + * mode. 61 + */ 62 + int __no_sanitize_address enter_vmx_ops(void) 56 63 { 57 64 if (in_interrupt()) 58 65 return 0;
+3 -2
arch/powerpc/perf/core-book3s.c
··· 2242 2242 const u64 last_period = event->hw.last_period; 2243 2243 s64 prev, delta, left; 2244 2244 int record = 0; 2245 + int mark_event = regs->dsisr & MMCRA_SAMPLE_ENABLE; 2245 2246 2246 2247 if (event->hw.state & PERF_HES_STOPPED) { 2247 2248 write_pmc(event->hw.idx, 0); ··· 2305 2304 * In ISA v3.0 and before values "0" and "7" are considered reserved. 2306 2305 * In ISA v3.1, value "7" has been used to indicate "larx/stcx". 2307 2306 * Drop the sample if "type" has reserved values for this field with a 2308 - * ISA version check. 2307 + * ISA version check for marked events. 2309 2308 */ 2310 - if (event->attr.sample_type & PERF_SAMPLE_DATA_SRC && 2309 + if (mark_event && event->attr.sample_type & PERF_SAMPLE_DATA_SRC && 2311 2310 ppmu->get_mem_data_src) { 2312 2311 val = (regs->dar & SIER_TYPE_MASK) >> SIER_TYPE_SHIFT; 2313 2312 if (val == 0 || (val == 7 && !cpu_has_feature(CPU_FTR_ARCH_31))) {
+2 -2
arch/powerpc/platforms/8xx/cpm1.c
··· 477 477 struct device_node *np = dev->of_node; 478 478 struct cpm1_gpio16_chip *cpm1_gc; 479 479 struct gpio_chip *gc; 480 - u16 mask; 480 + u32 mask; 481 481 482 482 cpm1_gc = devm_kzalloc(dev, sizeof(*cpm1_gc), GFP_KERNEL); 483 483 if (!cpm1_gc) ··· 485 485 486 486 spin_lock_init(&cpm1_gc->lock); 487 487 488 - if (!of_property_read_u16(np, "fsl,cpm1-gpio-irq-mask", &mask)) { 488 + if (!of_property_read_u32(np, "fsl,cpm1-gpio-irq-mask", &mask)) { 489 489 int i, j; 490 490 491 491 for (i = 0, j = 0; i < 16; i++)
+1 -2
arch/powerpc/platforms/pasemi/pci.c
··· 272 272 { 273 273 struct device_node *root = of_find_node_by_path("/"); 274 274 struct device_node *np; 275 - int res; 276 275 277 276 pci_set_flags(PCI_SCAN_ALL_PCIE_DEVS); 278 277 279 278 np = of_find_compatible_node(root, NULL, "pasemi,rootbus"); 280 279 if (np) { 281 - res = pas_add_bridge(np); 280 + pas_add_bridge(np); 282 281 of_node_put(np); 283 282 } 284 283 of_node_put(root);
+1 -3
arch/powerpc/platforms/ps3/device-init.c
··· 950 950 951 951 static int __init ps3_register_devices(void) 952 952 { 953 - int result; 954 - 955 953 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 956 954 return -ENODEV; 957 955 ··· 957 959 958 960 /* ps3_repository_dump_bus_info(); */ 959 961 960 - result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE); 962 + ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE); 961 963 962 964 ps3_register_vuart_devices(); 963 965
+116 -17
arch/powerpc/platforms/pseries/htmdump.c
··· 16 16 static void *htm_status_buf; 17 17 static void *htm_info_buf; 18 18 static void *htm_caps_buf; 19 + static void *htm_mem_buf; 19 20 static u32 nodeindex; 20 21 static u32 nodalchipindex; 21 22 static u32 coreindexonchip; ··· 87 86 static ssize_t htmdump_read(struct file *filp, char __user *ubuf, 88 87 size_t count, loff_t *ppos) 89 88 { 90 - void *htm_buf = filp->private_data; 89 + void *htm_buf_data = filp->private_data; 91 90 unsigned long page, read_size, available; 92 91 loff_t offset; 93 92 long rc, ret; ··· 101 100 * - last three values are address, size and offset 102 101 */ 103 102 rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip, 104 - htmtype, H_HTM_OP_DUMP_DATA, virt_to_phys(htm_buf), 103 + htmtype, H_HTM_OP_DUMP_DATA, virt_to_phys(htm_buf_data), 105 104 PAGE_SIZE, page); 106 105 107 106 ret = htm_return_check(rc); ··· 113 112 available = PAGE_SIZE; 114 113 read_size = min(count, available); 115 114 *ppos += read_size; 116 - return simple_read_from_buffer(ubuf, count, &offset, htm_buf, available); 115 + return simple_read_from_buffer(ubuf, count, &offset, htm_buf_data, available); 116 + } 117 + 118 + static ssize_t htmsystem_mem_read(struct file *filp, char __user *ubuf, 119 + size_t count, loff_t *ppos) 120 + { 121 + void *htm_mem_data = filp->private_data; 122 + long rc, ret; 123 + u64 *num_entries; 124 + u64 to_copy = 0; 125 + loff_t offset = 0; 126 + u64 mem_offset = 0; 127 + 128 + /* 129 + * Invoke H_HTM call with: 130 + * - operation as htm status (H_HTM_OP_STATUS) 131 + * - last three values as addr, size and offset. "offset" 132 + * is value from output buffer header that points to next 133 + * entry to dump. 0 is the first entry to dump. next entry 134 + * is read from the output bufferbyte offset 0x8. 135 + * 136 + * When first time hcall is invoked, mem_offset should be 137 + * zero because zero is the first entry. 138 + * In the next hcall, offset of next entry to read from is 139 + * picked from output buffer header itself. So don't fill 140 + * mem_offset for first read. 141 + * 142 + * If there is no further data to read in next iteration, 143 + * offset value from output buffer header will point to -1. 144 + */ 145 + if (*ppos) { 146 + mem_offset = *(u64 *)(htm_mem_data + 0x8); 147 + if (mem_offset == -1) 148 + return 0; 149 + } 150 + rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip, 151 + htmtype, H_HTM_OP_DUMP_SYSMEM_CONF, virt_to_phys(htm_mem_data), 152 + PAGE_SIZE, be64_to_cpu(mem_offset)); 153 + ret = htm_return_check(rc); 154 + if (ret <= 0) { 155 + pr_debug("H_HTM hcall returned for op: H_HTM_OP_DUMP_SYSMEM_CONF with hcall returning %ld\n", ret); 156 + return ret; 157 + } 158 + 159 + /* 160 + * HTM system mem buffer, start of buffer + 0x10 gives the 161 + * number of HTM entries in the buffer. 162 + * So total count to copy is: 163 + * 32 bytes (for first 5 fields) + (number of HTM entries * entry size) 164 + */ 165 + num_entries = htm_mem_data + 0x10; 166 + to_copy = 32 + (be64_to_cpu(*num_entries) * 32); 167 + 168 + *ppos += to_copy; 169 + return simple_read_from_buffer(ubuf, count, &offset, htm_mem_data, to_copy); 117 170 } 118 171 119 172 static const struct file_operations htmdump_fops = { 120 173 .llseek = NULL, 121 174 .read = htmdump_read, 122 175 .open = simple_open, 176 + }; 177 + 178 + static const struct file_operations htmsystem_mem_fops = { 179 + .llseek = NULL, 180 + .read = htmsystem_mem_read, 181 + .open = simple_open, 123 182 }; 124 183 125 184 static int htmconfigure_set(void *data, u64 val) ··· 287 226 static ssize_t htmstatus_read(struct file *filp, char __user *ubuf, 288 227 size_t count, loff_t *ppos) 289 228 { 290 - void *htm_status_buf = filp->private_data; 229 + void *htm_status_data = filp->private_data; 291 230 long rc, ret; 292 231 u64 *num_entries; 293 232 u64 to_copy; 294 233 int htmstatus_flag; 234 + loff_t offset = 0; 235 + u64 status_offset = 0; 295 236 296 237 /* 297 238 * Invoke H_HTM call with: 298 239 * - operation as htm status (H_HTM_OP_STATUS) 299 - * - last three values as addr, size and offset 240 + * - last three values as addr, size and offset. 241 + * "offset" is value from output buffer header 242 + * that points to next entry to dump. 0 is the first 243 + * entry to dump. next entry is read from the output 244 + * bufferbyte offset 0x8. 300 245 */ 246 + if (*ppos) { 247 + status_offset = *(u64 *)(htm_status_data + 0x8); 248 + if (status_offset == -1) 249 + return 0; 250 + } 301 251 rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip, 302 - htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_buf), 303 - PAGE_SIZE, 0); 252 + htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_data), 253 + PAGE_SIZE, be64_to_cpu(status_offset)); 304 254 305 255 ret = htm_return_check(rc); 306 256 if (ret <= 0) { ··· 327 255 * So total count to copy is: 328 256 * 32 bytes (for first 7 fields) + (number of HTM entries * entry size) 329 257 */ 330 - num_entries = htm_status_buf + 0x10; 258 + num_entries = htm_status_data + 0x10; 331 259 if (htmtype == 0x2) 332 260 htmstatus_flag = 0x8; 333 261 else 334 262 htmstatus_flag = 0x6; 335 263 to_copy = 32 + (be64_to_cpu(*num_entries) * htmstatus_flag); 336 - return simple_read_from_buffer(ubuf, count, ppos, htm_status_buf, to_copy); 264 + *ppos += to_copy; 265 + 266 + return simple_read_from_buffer(ubuf, count, &offset, htm_status_data, to_copy); 337 267 } 338 268 339 269 static const struct file_operations htmstatus_fops = { ··· 347 273 static ssize_t htminfo_read(struct file *filp, char __user *ubuf, 348 274 size_t count, loff_t *ppos) 349 275 { 350 - void *htm_info_buf = filp->private_data; 276 + void *htm_info_data = filp->private_data; 351 277 long rc, ret; 352 278 u64 *num_entries; 353 279 u64 to_copy; 280 + loff_t offset = 0; 281 + u64 info_offset = 0; 354 282 355 283 /* 356 284 * Invoke H_HTM call with: 357 285 * - operation as htm status (H_HTM_OP_STATUS) 358 286 * - last three values as addr, size and offset 287 + * "offset" is value from output buffer header 288 + * that points to next entry to dump. 0 is the first 289 + * entry to dump. next entry is read from the output 290 + * bufferbyte offset 0x8. 359 291 */ 292 + if (*ppos) { 293 + info_offset = *(u64 *)(htm_info_data + 0x8); 294 + if (info_offset == -1) 295 + return 0; 296 + } 360 297 rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip, 361 - htmtype, H_HTM_OP_DUMP_SYSPROC_CONF, virt_to_phys(htm_info_buf), 362 - PAGE_SIZE, 0); 298 + htmtype, H_HTM_OP_DUMP_SYSPROC_CONF, virt_to_phys(htm_info_data), 299 + PAGE_SIZE, be64_to_cpu(info_offset)); 363 300 364 301 ret = htm_return_check(rc); 365 302 if (ret <= 0) { ··· 386 301 * So total count to copy is: 387 302 * 32 bytes (for first 5 fields) + (number of HTM entries * entry size) 388 303 */ 389 - num_entries = htm_info_buf + 0x10; 304 + num_entries = htm_info_data + 0x10; 390 305 to_copy = 32 + (be64_to_cpu(*num_entries) * 16); 391 - return simple_read_from_buffer(ubuf, count, ppos, htm_info_buf, to_copy); 306 + 307 + *ppos += to_copy; 308 + return simple_read_from_buffer(ubuf, count, &offset, htm_info_data, to_copy); 392 309 } 393 310 394 311 static ssize_t htmcaps_read(struct file *filp, char __user *ubuf, 395 312 size_t count, loff_t *ppos) 396 313 { 397 - void *htm_caps_buf = filp->private_data; 314 + void *htm_caps_data = filp->private_data; 398 315 long rc, ret; 399 316 400 317 /* ··· 406 319 * and zero 407 320 */ 408 321 rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip, 409 - htmtype, H_HTM_OP_CAPABILITIES, virt_to_phys(htm_caps_buf), 322 + htmtype, H_HTM_OP_CAPABILITIES, virt_to_phys(htm_caps_data), 410 323 0x80, 0); 411 324 412 325 ret = htm_return_check(rc); ··· 415 328 return ret; 416 329 } 417 330 418 - return simple_read_from_buffer(ubuf, count, ppos, htm_caps_buf, 0x80); 331 + return simple_read_from_buffer(ubuf, count, ppos, htm_caps_data, 0x80); 419 332 } 420 333 421 334 static const struct file_operations htminfo_fops = { ··· 544 457 return -ENOMEM; 545 458 } 546 459 460 + /* Memory to present HTM system memory configuration */ 461 + htm_mem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 462 + if (!htm_mem_buf) { 463 + pr_err("Failed to allocate htm mem buf\n"); 464 + return -ENOMEM; 465 + } 466 + 547 467 debugfs_create_file("htmstatus", 0400, htmdump_debugfs_dir, htm_status_buf, &htmstatus_fops); 548 468 debugfs_create_file("htminfo", 0400, htmdump_debugfs_dir, htm_info_buf, &htminfo_fops); 549 469 debugfs_create_file("htmcaps", 0400, htmdump_debugfs_dir, htm_caps_buf, &htmcaps_fops); 470 + debugfs_create_file("htmsystem_mem", 0400, htmdump_debugfs_dir, htm_mem_buf, &htmsystem_mem_fops); 550 471 551 472 return 0; 552 473 } ··· 577 482 { 578 483 debugfs_remove_recursive(htmdump_debugfs_dir); 579 484 kfree(htm_buf); 485 + kfree(htm_status_buf); 486 + kfree(htm_info_buf); 487 + kfree(htm_caps_buf); 488 + kfree(htm_mem_buf); 580 489 } 581 490 582 491 module_init(htmdump_init);
+97 -84
arch/powerpc/platforms/pseries/papr-hvpipe.c
··· 190 190 return -ENOMEM; 191 191 } 192 192 193 - ret = rtas_ibm_receive_hvpipe_msg(work_area, &srcID, 194 - &bytes_written); 195 - if (!ret) { 196 - /* 197 - * Recv HVPIPE RTAS is successful. 198 - * When releasing FD or no one is waiting on the 199 - * specific source, issue recv HVPIPE RTAS call 200 - * so that pipe is not blocked - this func is called 201 - * with NULL buf. 202 - */ 203 - if (buf) { 204 - if (size < bytes_written) { 205 - pr_err("Received the payload size = %d, but the buffer size = %d\n", 206 - bytes_written, size); 207 - bytes_written = size; 208 - } 209 - ret = copy_to_user(buf, 210 - rtas_work_area_raw_buf(work_area), 211 - bytes_written); 212 - if (!ret) 213 - ret = bytes_written; 214 - } 215 - } else { 216 - pr_err("ibm,receive-hvpipe-msg failed with %d\n", 217 - ret); 193 + /* 194 + * Recv HVPIPE RTAS is successful. 195 + * When releasing FD or no one is waiting on the 196 + * specific source, issue recv HVPIPE RTAS call 197 + * so that pipe is not blocked - this func is called 198 + * with NULL buf. 199 + */ 200 + ret = rtas_ibm_receive_hvpipe_msg(work_area, &srcID, &bytes_written); 201 + if (ret) { 202 + pr_err("ibm,receive-hvpipe-msg failed with %d\n", ret); 203 + goto out; 218 204 } 219 205 206 + if (!buf) 207 + goto out; 208 + 209 + if (size < bytes_written) { 210 + pr_err("Received the payload size = %d, but the buffer size = %d\n", 211 + bytes_written, size); 212 + bytes_written = size; 213 + } 214 + 215 + if (copy_to_user(buf, rtas_work_area_raw_buf(work_area), bytes_written)) 216 + ret = -EFAULT; 217 + else 218 + ret = bytes_written; 219 + 220 + out: 220 221 rtas_work_area_free(work_area); 221 222 return ret; 222 223 } ··· 328 327 { 329 328 330 329 struct hvpipe_source_info *src_info = file->private_data; 331 - struct papr_hvpipe_hdr hdr; 332 - long ret; 330 + struct papr_hvpipe_hdr hdr = {}; 331 + ssize_t ret = 0; 333 332 334 333 /* 335 334 * Return -ENXIO during migration ··· 377 376 378 377 ret = copy_to_user(buf, &hdr, HVPIPE_HDR_LEN); 379 378 if (ret) 380 - return ret; 379 + return -EFAULT; 381 380 382 381 /* 383 382 * Message event has payload, so get the payload with ··· 386 385 if (hdr.flags & HVPIPE_MSG_AVAILABLE) { 387 386 ret = hvpipe_rtas_recv_msg(buf + HVPIPE_HDR_LEN, 388 387 size - HVPIPE_HDR_LEN); 389 - if (ret > 0) { 388 + /* 389 + * Always clear MSG_AVAILABLE once the RTAS call has drained 390 + * the message, regardless of whether copy_to_user succeeded. 391 + */ 392 + if (ret >= 0 || ret == -EFAULT) 390 393 src_info->hvpipe_status &= ~HVPIPE_MSG_AVAILABLE; 391 - ret += HVPIPE_HDR_LEN; 392 - } 393 394 } else if (hdr.flags & HVPIPE_LOST_CONNECTION) { 394 395 /* 395 396 * Hypervisor is closing the pipe for the specific 396 397 * source. So notify user space. 397 398 */ 398 399 src_info->hvpipe_status &= ~HVPIPE_LOST_CONNECTION; 399 - ret = HVPIPE_HDR_LEN; 400 400 } 401 + 402 + if (ret >= 0) 403 + ret += HVPIPE_HDR_LEN; 401 404 402 405 return ret; 403 406 } ··· 449 444 struct file *file) 450 445 { 451 446 struct hvpipe_source_info *src_info; 447 + unsigned long flags; 452 448 453 449 /* 454 450 * Hold the lock, remove source from src_list, reset the 455 451 * hvpipe status and release the lock to prevent any race 456 452 * with message event IRQ. 457 453 */ 458 - spin_lock(&hvpipe_src_list_lock); 454 + spin_lock_irqsave(&hvpipe_src_list_lock, flags); 459 455 src_info = file->private_data; 460 456 list_del(&src_info->list); 461 457 file->private_data = NULL; 458 + spin_unlock_irqrestore(&hvpipe_src_list_lock, flags); 462 459 /* 463 460 * If the pipe for this specific source has any pending 464 461 * payload, issue recv HVPIPE RTAS so that pipe will not ··· 468 461 */ 469 462 if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE) { 470 463 src_info->hvpipe_status = 0; 471 - spin_unlock(&hvpipe_src_list_lock); 472 464 hvpipe_rtas_recv_msg(NULL, 0); 473 - } else 474 - spin_unlock(&hvpipe_src_list_lock); 465 + } 475 466 476 467 kfree(src_info); 477 468 return 0; ··· 484 479 485 480 static int papr_hvpipe_dev_create_handle(u32 srcID) 486 481 { 487 - struct hvpipe_source_info *src_info __free(kfree) = NULL; 488 - 489 - spin_lock(&hvpipe_src_list_lock); 490 - /* 491 - * Do not allow more than one process communicates with 492 - * each source. 493 - */ 494 - src_info = hvpipe_find_source(srcID); 495 - if (src_info) { 496 - spin_unlock(&hvpipe_src_list_lock); 497 - pr_err("pid(%d) is already using the source(%d)\n", 498 - src_info->tsk->pid, srcID); 499 - return -EALREADY; 500 - } 501 - spin_unlock(&hvpipe_src_list_lock); 482 + struct hvpipe_source_info *src_info; 483 + int fd; 484 + unsigned long flags; 502 485 503 486 src_info = kzalloc_obj(*src_info, GFP_KERNEL_ACCOUNT); 504 487 if (!src_info) 505 488 return -ENOMEM; 506 489 507 490 src_info->srcID = srcID; 508 - src_info->tsk = current; 509 491 init_waitqueue_head(&src_info->recv_wqh); 510 492 511 - FD_PREPARE(fdf, O_RDONLY | O_CLOEXEC, 512 - anon_inode_getfile("[papr-hvpipe]", &papr_hvpipe_handle_ops, 513 - (void *)src_info, O_RDWR)); 514 - if (fdf.err) 515 - return fdf.err; 516 - 517 - retain_and_null_ptr(src_info); 518 - spin_lock(&hvpipe_src_list_lock); 519 493 /* 520 - * If two processes are executing ioctl() for the same 521 - * source ID concurrently, prevent the second process to 522 - * acquire FD. 494 + * Do not allow more than one process communicates with 495 + * each source. 523 496 */ 497 + spin_lock_irqsave(&hvpipe_src_list_lock, flags); 524 498 if (hvpipe_find_source(srcID)) { 525 - spin_unlock(&hvpipe_src_list_lock); 499 + spin_unlock_irqrestore(&hvpipe_src_list_lock, flags); 500 + pr_err("pid(%s:%d) could not get the source(%d)\n", 501 + current->comm, task_pid_nr(current), srcID); 502 + kfree(src_info); 526 503 return -EALREADY; 527 504 } 528 505 list_add(&src_info->list, &hvpipe_src_list); 529 - spin_unlock(&hvpipe_src_list_lock); 530 - return fd_publish(fdf); 506 + spin_unlock_irqrestore(&hvpipe_src_list_lock, flags); 507 + 508 + fd = FD_ADD(O_RDONLY | O_CLOEXEC, 509 + anon_inode_getfile("[papr-hvpipe]", &papr_hvpipe_handle_ops, 510 + (void *)src_info, O_RDWR)); 511 + if (fd < 0) { 512 + spin_lock_irqsave(&hvpipe_src_list_lock, flags); 513 + list_del(&src_info->list); 514 + spin_unlock_irqrestore(&hvpipe_src_list_lock, flags); 515 + /* 516 + * if we fail to add FD, that means no userspace program is 517 + * polling. In that case if there is a msg pending because the 518 + * interrupt was fired after the src_info was added to the 519 + * global list, then let's consume it here, to unblock the 520 + * hvpipe 521 + */ 522 + if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE) 523 + hvpipe_rtas_recv_msg(NULL, 0); 524 + kfree(src_info); 525 + return fd; 526 + } 527 + 528 + return fd; 531 529 } 532 530 533 531 /* ··· 693 685 struct device_node *np; 694 686 695 687 hvpipe_check_exception_token = rtas_function_token(RTAS_FN_CHECK_EXCEPTION); 696 - if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE) 688 + if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE) 697 689 return -ENODEV; 698 690 699 691 /* hvpipe events */ 700 692 np = of_find_node_by_path("/event-sources/ibm,hvpipe-msg-events"); 701 - if (np != NULL) { 702 - request_event_sources_irqs(np, hvpipe_event_interrupt, 703 - "HPIPE_EVENT"); 704 - of_node_put(np); 705 - } else { 706 - pr_err("Can not enable hvpipe event IRQ\n"); 693 + if (!np) { 694 + pr_err("No device node found, could not enable hvpipe event IRQ\n"); 707 695 return -ENODEV; 708 696 } 697 + 698 + request_event_sources_irqs(np, hvpipe_event_interrupt, "HPIPE_EVENT"); 699 + of_node_put(np); 709 700 710 701 return 0; 711 702 } ··· 782 775 } 783 776 784 777 ret = enable_hvpipe_IRQ(); 785 - if (!ret) { 786 - ret = set_hvpipe_sys_param(1); 787 - if (!ret) 788 - ret = misc_register(&papr_hvpipe_dev); 789 - } 778 + if (ret) 779 + goto out_wq; 790 780 791 - if (!ret) { 792 - pr_info("hvpipe feature is enabled\n"); 793 - hvpipe_feature = true; 794 - return 0; 795 - } 781 + ret = misc_register(&papr_hvpipe_dev); 782 + if (ret) 783 + goto out_wq; 796 784 797 - pr_err("hvpipe feature is not enabled %d\n", ret); 785 + ret = set_hvpipe_sys_param(1); 786 + if (ret) 787 + goto out_misc; 788 + 789 + pr_info("hvpipe feature is enabled\n"); 790 + hvpipe_feature = true; 791 + return 0; 792 + 793 + out_misc: 794 + misc_deregister(&papr_hvpipe_dev); 795 + out_wq: 798 796 destroy_workqueue(papr_hvpipe_wq); 799 797 out: 800 798 kfree(papr_hvpipe_work); 801 799 papr_hvpipe_work = NULL; 800 + pr_err("hvpipe feature is not enabled %d\n", ret); 802 801 return ret; 803 802 } 804 803 machine_device_initcall(pseries, papr_hvpipe_init);
-1
arch/powerpc/platforms/pseries/papr-hvpipe.h
··· 21 21 u32 srcID; 22 22 u32 hvpipe_status; 23 23 wait_queue_head_t recv_wqh; /* wake up poll() waitq */ 24 - struct task_struct *tsk; 25 24 }; 26 25 27 26 /*