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 int fd; 307 308 /* 309 * Return failure if the user space is already opened FD for 310 * the specific dump ID. This check will prevent multiple dump 311 * requests for the same dump ID at the same time. Generally 312 * should not expect this, but in case. 313 */ 314 list_for_each_entry(params, &platform_dump_list, list) { 315 param_dump_tag = (u64) (((u64)params->dump_tag_hi << 32) | 316 params->dump_tag_lo); 317 if (dump_tag == param_dump_tag) { 318 pr_err("Platform dump for ID(%llu) is already in progress\n", 319 dump_tag); 320 return -EALREADY; 321 } 322 } 323 324 params = kzalloc(sizeof(struct ibm_platform_dump_params), 325 GFP_KERNEL_ACCOUNT); 326 if (!params) 327 return -ENOMEM; 328 329 params->work_area = rtas_work_area_alloc(SZ_4K); 330 params->buf_length = SZ_4K; 331 params->dump_tag_hi = (u32)(dump_tag >> 32); 332 params->dump_tag_lo = (u32)(dump_tag & 0x00000000ffffffffULL); 333 params->status = RTAS_IBM_PLATFORM_DUMP_START; 334 335 fd = FD_ADD(O_RDONLY | O_CLOEXEC, 336 anon_inode_getfile_fmode("[papr-platform-dump]", 337 &papr_platform_dump_handle_ops, 338 (void *)params, O_RDONLY, 339 FMODE_LSEEK | FMODE_PREAD)); 340 if (fd < 0) { 341 rtas_work_area_free(params->work_area); 342 kfree(params); 343 return fd; 344 } 345 346 list_add(¶ms->list, &platform_dump_list); 347 348 pr_info("%s (%d) initiated platform dump for dump tag %llu\n", 349 current->comm, current->pid, dump_tag); 350 return fd; 351 } 352 353 /* 354 * Top-level ioctl handler for /dev/papr-platform-dump. 355 */ 356 static long papr_platform_dump_dev_ioctl(struct file *filp, 357 unsigned int ioctl, 358 unsigned long arg) 359 { 360 u64 __user *argp = (void __user *)arg; 361 u64 dump_tag; 362 long ret; 363 364 if (get_user(dump_tag, argp)) 365 return -EFAULT; 366 367 switch (ioctl) { 368 case PAPR_PLATFORM_DUMP_IOC_CREATE_HANDLE: 369 mutex_lock(&platform_dump_list_mutex); 370 ret = papr_platform_dump_create_handle(dump_tag); 371 mutex_unlock(&platform_dump_list_mutex); 372 break; 373 default: 374 ret = -ENOIOCTLCMD; 375 break; 376 } 377 return ret; 378 } 379 380 static const struct file_operations papr_platform_dump_ops = { 381 .unlocked_ioctl = papr_platform_dump_dev_ioctl, 382 }; 383 384 static struct miscdevice papr_platform_dump_dev = { 385 .minor = MISC_DYNAMIC_MINOR, 386 .name = "papr-platform-dump", 387 .fops = &papr_platform_dump_ops, 388 }; 389 390 static __init int papr_platform_dump_init(void) 391 { 392 if (!rtas_function_implemented(RTAS_FN_IBM_PLATFORM_DUMP)) 393 return -ENODEV; 394 395 return misc_register(&papr_platform_dump_dev); 396 } 397 machine_device_initcall(pseries, papr_platform_dump_init); 398