1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #define pr_fmt(fmt) "papr-platform-dump: " fmt 4 5 #include <linux/anon_inodes.h> 6 #include <linux/file.h> 7 #include <linux/fs.h> 8 #include <linux/init.h> 9 #include <linux/kernel.h> 10 #include <linux/miscdevice.h> 11 #include <asm/machdep.h> 12 #include <asm/rtas-work-area.h> 13 #include <asm/rtas.h> 14 #include <uapi/asm/papr-platform-dump.h> 15 16 /* 17 * Function-specific return values for ibm,platform-dump, derived from 18 * PAPR+ v2.13 7.3.3.4.1 "ibm,platform-dump RTAS Call". 19 */ 20 #define RTAS_IBM_PLATFORM_DUMP_COMPLETE 0 /* Complete dump retrieved. */ 21 #define RTAS_IBM_PLATFORM_DUMP_CONTINUE 1 /* Continue dump */ 22 #define RTAS_NOT_AUTHORIZED -9002 /* Not Authorized */ 23 24 #define RTAS_IBM_PLATFORM_DUMP_START 2 /* Linux status to start dump */ 25 26 /** 27 * struct ibm_platform_dump_params - Parameters (in and out) for 28 * ibm,platform-dump 29 * @work_area: In: work area buffer for results. 30 * @buf_length: In: work area buffer length in bytes 31 * @dump_tag_hi: In: Most-significant 32 bits of a Dump_Tag representing 32 * an id of the dump being processed. 33 * @dump_tag_lo: In: Least-significant 32 bits of a Dump_Tag representing 34 * an id of the dump being processed. 35 * @sequence_hi: In: Sequence number in most-significant 32 bits. 36 * Out: Next sequence number in most-significant 32 bits. 37 * @sequence_lo: In: Sequence number in Least-significant 32 bits 38 * Out: Next sequence number in Least-significant 32 bits. 39 * @bytes_ret_hi: Out: Bytes written in most-significant 32 bits. 40 * @bytes_ret_lo: Out: Bytes written in Least-significant 32 bits. 41 * @status: Out: RTAS call status. 42 * @list: Maintain the list of dumps are in progress. Can 43 * retrieve multiple dumps with different dump IDs at 44 * the same time but not with the same dump ID. This list 45 * is used to determine whether the dump for the same ID 46 * is in progress. 47 */ 48 struct ibm_platform_dump_params { 49 struct rtas_work_area *work_area; 50 u32 buf_length; 51 u32 dump_tag_hi; 52 u32 dump_tag_lo; 53 u32 sequence_hi; 54 u32 sequence_lo; 55 u32 bytes_ret_hi; 56 u32 bytes_ret_lo; 57 s32 status; 58 struct list_head list; 59 }; 60 61 /* 62 * Multiple dumps with different dump IDs can be retrieved at the same 63 * time, but not with dame dump ID. platform_dump_list_mutex and 64 * platform_dump_list are used to prevent this behavior. 65 */ 66 static DEFINE_MUTEX(platform_dump_list_mutex); 67 static LIST_HEAD(platform_dump_list); 68 69 /** 70 * rtas_ibm_platform_dump() - Call ibm,platform-dump to fill a work area 71 * buffer. 72 * @params: See &struct ibm_platform_dump_params. 73 * @buf_addr: Address of dump buffer (work_area) 74 * @buf_length: Length of the buffer in bytes (min. 1024) 75 * 76 * Calls ibm,platform-dump until it errors or successfully deposits data 77 * into the supplied work area. Handles RTAS retry statuses. Maps RTAS 78 * error statuses to reasonable errno values. 79 * 80 * Can request multiple dumps with different dump IDs at the same time, 81 * but not with the same dump ID which is prevented with the check in 82 * the ioctl code (papr_platform_dump_create_handle()). 83 * 84 * The caller should inspect @params.status to determine whether more 85 * calls are needed to complete the sequence. 86 * 87 * Context: May sleep. 88 * Return: -ve on error, 0 for dump complete and 1 for continue dump 89 */ 90 static int rtas_ibm_platform_dump(struct ibm_platform_dump_params *params, 91 phys_addr_t buf_addr, u32 buf_length) 92 { 93 u32 rets[4]; 94 s32 fwrc; 95 int ret = 0; 96 97 do { 98 fwrc = rtas_call(rtas_function_token(RTAS_FN_IBM_PLATFORM_DUMP), 99 6, 5, 100 rets, 101 params->dump_tag_hi, 102 params->dump_tag_lo, 103 params->sequence_hi, 104 params->sequence_lo, 105 buf_addr, 106 buf_length); 107 } while (rtas_busy_delay(fwrc)); 108 109 switch (fwrc) { 110 case RTAS_HARDWARE_ERROR: 111 ret = -EIO; 112 break; 113 case RTAS_NOT_AUTHORIZED: 114 ret = -EPERM; 115 break; 116 case RTAS_IBM_PLATFORM_DUMP_CONTINUE: 117 case RTAS_IBM_PLATFORM_DUMP_COMPLETE: 118 params->sequence_hi = rets[0]; 119 params->sequence_lo = rets[1]; 120 params->bytes_ret_hi = rets[2]; 121 params->bytes_ret_lo = rets[3]; 122 break; 123 default: 124 ret = -EIO; 125 pr_err_ratelimited("unexpected ibm,platform-dump status %d\n", 126 fwrc); 127 break; 128 } 129 130 params->status = fwrc; 131 return ret; 132 } 133 134 /* 135 * Platform dump is used with multiple RTAS calls to retrieve the 136 * complete dump for the provided dump ID. Once the complete dump is 137 * retrieved, the hypervisor returns dump complete status (0) for the 138 * last RTAS call and expects the caller issues one more call with 139 * NULL buffer to invalidate the dump so that the hypervisor can remove 140 * the dump. 141 * 142 * After the specific dump is invalidated in the hypervisor, expect the 143 * dump complete status for the new sequence - the user space initiates 144 * new request for the same dump ID. 145 */ 146 static ssize_t papr_platform_dump_handle_read(struct file *file, 147 char __user *buf, size_t size, loff_t *off) 148 { 149 struct ibm_platform_dump_params *params = file->private_data; 150 u64 total_bytes; 151 s32 fwrc; 152 153 /* 154 * Dump already completed with the previous read calls. 155 * In case if the user space issues further reads, returns 156 * -EINVAL. 157 */ 158 if (!params->buf_length) { 159 pr_warn_once("Platform dump completed for dump ID %llu\n", 160 (u64) (((u64)params->dump_tag_hi << 32) | 161 params->dump_tag_lo)); 162 return -EINVAL; 163 } 164 165 /* 166 * The hypervisor returns status 0 if no more data available to 167 * download. The dump will be invalidated with ioctl (see below). 168 */ 169 if (params->status == RTAS_IBM_PLATFORM_DUMP_COMPLETE) { 170 params->buf_length = 0; 171 /* 172 * Returns 0 to the user space so that user 173 * space read stops. 174 */ 175 return 0; 176 } 177 178 if (size < SZ_1K) { 179 pr_err_once("Buffer length should be minimum 1024 bytes\n"); 180 return -EINVAL; 181 } else if (size > params->buf_length) { 182 /* 183 * Allocate 4K work area. So if the user requests > 4K, 184 * resize the buffer length. 185 */ 186 size = params->buf_length; 187 } 188 189 fwrc = rtas_ibm_platform_dump(params, 190 rtas_work_area_phys(params->work_area), 191 size); 192 if (fwrc < 0) 193 return fwrc; 194 195 total_bytes = (u64) (((u64)params->bytes_ret_hi << 32) | 196 params->bytes_ret_lo); 197 198 /* 199 * Kernel or firmware bug, do not continue. 200 */ 201 if (WARN(total_bytes > size, "possible write beyond end of work area")) 202 return -EFAULT; 203 204 if (copy_to_user(buf, rtas_work_area_raw_buf(params->work_area), 205 total_bytes)) 206 return -EFAULT; 207 208 return total_bytes; 209 } 210 211 static int papr_platform_dump_handle_release(struct inode *inode, 212 struct file *file) 213 { 214 struct ibm_platform_dump_params *params = file->private_data; 215 216 if (params->work_area) 217 rtas_work_area_free(params->work_area); 218 219 mutex_lock(&platform_dump_list_mutex); 220 list_del(¶ms->list); 221 mutex_unlock(&platform_dump_list_mutex); 222 223 kfree(params); 224 file->private_data = NULL; 225 return 0; 226 } 227 228 /* 229 * This ioctl is used to invalidate the dump assuming the user space 230 * issue this ioctl after obtain the complete dump. 231 * Issue the last RTAS call with NULL buffer to invalidate the dump 232 * which means dump will be freed in the hypervisor. 233 */ 234 static long papr_platform_dump_invalidate_ioctl(struct file *file, 235 unsigned int ioctl, unsigned long arg) 236 { 237 struct ibm_platform_dump_params *params; 238 u64 __user *argp = (void __user *)arg; 239 u64 param_dump_tag, dump_tag; 240 241 if (ioctl != PAPR_PLATFORM_DUMP_IOC_INVALIDATE) 242 return -ENOIOCTLCMD; 243 244 if (get_user(dump_tag, argp)) 245 return -EFAULT; 246 247 /* 248 * private_data is freeded during release(), so should not 249 * happen. 250 */ 251 if (!file->private_data) { 252 pr_err("No valid FD to invalidate dump for the ID(%llu)\n", 253 dump_tag); 254 return -EINVAL; 255 } 256 257 params = file->private_data; 258 param_dump_tag = (u64) (((u64)params->dump_tag_hi << 32) | 259 params->dump_tag_lo); 260 if (dump_tag != param_dump_tag) { 261 pr_err("Invalid dump ID(%llu) to invalidate dump\n", 262 dump_tag); 263 return -EINVAL; 264 } 265 266 if (params->status != RTAS_IBM_PLATFORM_DUMP_COMPLETE) { 267 pr_err("Platform dump is not complete, but requested " 268 "to invalidate dump for ID(%llu)\n", 269 dump_tag); 270 return -EINPROGRESS; 271 } 272 273 return rtas_ibm_platform_dump(params, 0, 0); 274 } 275 276 static const struct file_operations papr_platform_dump_handle_ops = { 277 .read = papr_platform_dump_handle_read, 278 .release = papr_platform_dump_handle_release, 279 .unlocked_ioctl = papr_platform_dump_invalidate_ioctl, 280 }; 281 282 /** 283 * papr_platform_dump_create_handle() - Create a fd-based handle for 284 * reading platform dump 285 * 286 * Handler for PAPR_PLATFORM_DUMP_IOC_CREATE_HANDLE ioctl command 287 * Allocates RTAS parameter struct and work area and attached to the 288 * file descriptor for reading by user space with the multiple RTAS 289 * calls until the dump is completed. This memory allocation is freed 290 * when the file is released. 291 * 292 * Multiple dump requests with different IDs are allowed at the same 293 * time, but not with the same dump ID. So if the user space is 294 * already opened file descriptor for the specific dump ID, return 295 * -EALREADY for the next request. 296 * 297 * @dump_tag: Dump ID for the dump requested to retrieve from the 298 * hypervisor 299 * 300 * Return: The installed fd number if successful, -ve errno otherwise. 301 */ 302 static long papr_platform_dump_create_handle(u64 dump_tag) 303 { 304 struct ibm_platform_dump_params *params; 305 u64 param_dump_tag; 306 struct file *file; 307 long err; 308 int fd; 309 310 /* 311 * Return failure if the user space is already opened FD for 312 * the specific dump ID. This check will prevent multiple dump 313 * requests for the same dump ID at the same time. Generally 314 * should not expect this, but in case. 315 */ 316 list_for_each_entry(params, &platform_dump_list, list) { 317 param_dump_tag = (u64) (((u64)params->dump_tag_hi << 32) | 318 params->dump_tag_lo); 319 if (dump_tag == param_dump_tag) { 320 pr_err("Platform dump for ID(%llu) is already in progress\n", 321 dump_tag); 322 return -EALREADY; 323 } 324 } 325 326 params = kzalloc(sizeof(struct ibm_platform_dump_params), 327 GFP_KERNEL_ACCOUNT); 328 if (!params) 329 return -ENOMEM; 330 331 params->work_area = rtas_work_area_alloc(SZ_4K); 332 params->buf_length = SZ_4K; 333 params->dump_tag_hi = (u32)(dump_tag >> 32); 334 params->dump_tag_lo = (u32)(dump_tag & 0x00000000ffffffffULL); 335 params->status = RTAS_IBM_PLATFORM_DUMP_START; 336 337 fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC); 338 if (fd < 0) { 339 err = fd; 340 goto free_area; 341 } 342 343 file = anon_inode_getfile_fmode("[papr-platform-dump]", 344 &papr_platform_dump_handle_ops, 345 (void *)params, O_RDONLY, 346 FMODE_LSEEK | FMODE_PREAD); 347 if (IS_ERR(file)) { 348 err = PTR_ERR(file); 349 goto put_fd; 350 } 351 352 fd_install(fd, file); 353 354 list_add(¶ms->list, &platform_dump_list); 355 356 pr_info("%s (%d) initiated platform dump for dump tag %llu\n", 357 current->comm, current->pid, dump_tag); 358 return fd; 359 put_fd: 360 put_unused_fd(fd); 361 free_area: 362 rtas_work_area_free(params->work_area); 363 kfree(params); 364 return err; 365 } 366 367 /* 368 * Top-level ioctl handler for /dev/papr-platform-dump. 369 */ 370 static long papr_platform_dump_dev_ioctl(struct file *filp, 371 unsigned int ioctl, 372 unsigned long arg) 373 { 374 u64 __user *argp = (void __user *)arg; 375 u64 dump_tag; 376 long ret; 377 378 if (get_user(dump_tag, argp)) 379 return -EFAULT; 380 381 switch (ioctl) { 382 case PAPR_PLATFORM_DUMP_IOC_CREATE_HANDLE: 383 mutex_lock(&platform_dump_list_mutex); 384 ret = papr_platform_dump_create_handle(dump_tag); 385 mutex_unlock(&platform_dump_list_mutex); 386 break; 387 default: 388 ret = -ENOIOCTLCMD; 389 break; 390 } 391 return ret; 392 } 393 394 static const struct file_operations papr_platform_dump_ops = { 395 .unlocked_ioctl = papr_platform_dump_dev_ioctl, 396 }; 397 398 static struct miscdevice papr_platform_dump_dev = { 399 .minor = MISC_DYNAMIC_MINOR, 400 .name = "papr-platform-dump", 401 .fops = &papr_platform_dump_ops, 402 }; 403 404 static __init int papr_platform_dump_init(void) 405 { 406 if (!rtas_function_implemented(RTAS_FN_IBM_PLATFORM_DUMP)) 407 return -ENODEV; 408 409 return misc_register(&papr_platform_dump_dev); 410 } 411 machine_device_initcall(pseries, papr_platform_dump_init); 412