1// SPDX-License-Identifier: GPL-2.0 2/* 3 * SCLP Store Data support and sysfs interface 4 * 5 * Copyright IBM Corp. 2017 6 */ 7 8#define KMSG_COMPONENT "sclp_sd" 9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 11#include <linux/completion.h> 12#include <linux/kobject.h> 13#include <linux/list.h> 14#include <linux/printk.h> 15#include <linux/slab.h> 16#include <linux/vmalloc.h> 17#include <linux/async.h> 18#include <linux/export.h> 19#include <linux/mutex.h> 20 21#include <asm/pgalloc.h> 22 23#include "sclp.h" 24 25#define SD_EQ_STORE_DATA 0 26#define SD_EQ_HALT 1 27#define SD_EQ_SIZE 2 28 29#define SD_DI_CONFIG 3 30 31struct sclp_sd_evbuf { 32 struct evbuf_header hdr; 33 u8 eq; 34 u8 di; 35 u8 rflags; 36 u64 :56; 37 u32 id; 38 u16 :16; 39 u8 fmt; 40 u8 status; 41 u64 sat; 42 u64 sa; 43 u32 esize; 44 u32 dsize; 45} __packed; 46 47struct sclp_sd_sccb { 48 struct sccb_header hdr; 49 struct sclp_sd_evbuf evbuf; 50} __packed __aligned(PAGE_SIZE); 51 52/** 53 * struct sclp_sd_data - Result of a Store Data request 54 * @esize_bytes: Resulting esize in bytes 55 * @dsize_bytes: Resulting dsize in bytes 56 * @data: Pointer to data - must be released using vfree() 57 */ 58struct sclp_sd_data { 59 size_t esize_bytes; 60 size_t dsize_bytes; 61 void *data; 62}; 63 64/** 65 * struct sclp_sd_listener - Listener for asynchronous Store Data response 66 * @list: For enqueueing this struct 67 * @id: Event ID of response to listen for 68 * @completion: Can be used to wait for response 69 * @evbuf: Contains the resulting Store Data response after completion 70 */ 71struct sclp_sd_listener { 72 struct list_head list; 73 u32 id; 74 struct completion completion; 75 struct sclp_sd_evbuf evbuf; 76}; 77 78/** 79 * struct sclp_sd_file - Sysfs representation of a Store Data entity 80 * @kobj: Kobject 81 * @data_attr: Attribute for accessing data contents 82 * @data_mutex: Mutex to serialize access and updates to @data 83 * @data: Data associated with this entity 84 * @di: DI value associated with this entity 85 */ 86struct sclp_sd_file { 87 struct kobject kobj; 88 struct bin_attribute data_attr; 89 struct mutex data_mutex; 90 struct sclp_sd_data data; 91 u8 di; 92}; 93#define to_sd_file(x) container_of(x, struct sclp_sd_file, kobj) 94 95static struct kset *sclp_sd_kset; 96static struct sclp_sd_file *config_file; 97 98static LIST_HEAD(sclp_sd_queue); 99static DEFINE_SPINLOCK(sclp_sd_queue_lock); 100 101/** 102 * sclp_sd_listener_add() - Add listener for Store Data responses 103 * @listener: Listener to add 104 */ 105static void sclp_sd_listener_add(struct sclp_sd_listener *listener) 106{ 107 spin_lock_irq(&sclp_sd_queue_lock); 108 list_add_tail(&listener->list, &sclp_sd_queue); 109 spin_unlock_irq(&sclp_sd_queue_lock); 110} 111 112/** 113 * sclp_sd_listener_remove() - Remove listener for Store Data responses 114 * @listener: Listener to remove 115 */ 116static void sclp_sd_listener_remove(struct sclp_sd_listener *listener) 117{ 118 spin_lock_irq(&sclp_sd_queue_lock); 119 list_del(&listener->list); 120 spin_unlock_irq(&sclp_sd_queue_lock); 121} 122 123/** 124 * sclp_sd_listener_init() - Initialize a Store Data response listener 125 * @id: Event ID to listen for 126 * 127 * Initialize a listener for asynchronous Store Data responses. This listener 128 * can afterwards be used to wait for a specific response and to retrieve 129 * the associated response data. 130 */ 131static void sclp_sd_listener_init(struct sclp_sd_listener *listener, u32 id) 132{ 133 memset(listener, 0, sizeof(*listener)); 134 listener->id = id; 135 init_completion(&listener->completion); 136} 137 138/** 139 * sclp_sd_receiver() - Receiver for Store Data events 140 * @evbuf_hdr: Header of received events 141 * 142 * Process Store Data events and complete listeners with matching event IDs. 143 */ 144static void sclp_sd_receiver(struct evbuf_header *evbuf_hdr) 145{ 146 struct sclp_sd_evbuf *evbuf = (struct sclp_sd_evbuf *) evbuf_hdr; 147 struct sclp_sd_listener *listener; 148 int found = 0; 149 150 pr_debug("received event (id=0x%08x)\n", evbuf->id); 151 spin_lock(&sclp_sd_queue_lock); 152 list_for_each_entry(listener, &sclp_sd_queue, list) { 153 if (listener->id != evbuf->id) 154 continue; 155 156 listener->evbuf = *evbuf; 157 complete(&listener->completion); 158 found = 1; 159 break; 160 } 161 spin_unlock(&sclp_sd_queue_lock); 162 163 if (!found) 164 pr_debug("unsolicited event (id=0x%08x)\n", evbuf->id); 165} 166 167static struct sclp_register sclp_sd_register = { 168 .send_mask = EVTYP_STORE_DATA_MASK, 169 .receive_mask = EVTYP_STORE_DATA_MASK, 170 .receiver_fn = sclp_sd_receiver, 171}; 172 173/** 174 * sclp_sd_sync() - Perform Store Data request synchronously 175 * @page: Address of work page - must be below 2GB 176 * @eq: Input EQ value 177 * @di: Input DI value 178 * @sat: Input SAT value 179 * @sa: Input SA value used to specify the address of the target buffer 180 * @dsize_ptr: Optional pointer to input and output DSIZE value 181 * @esize_ptr: Optional pointer to output ESIZE value 182 * 183 * Perform Store Data request with specified parameters and wait for completion. 184 * 185 * Return %0 on success and store resulting DSIZE and ESIZE values in 186 * @dsize_ptr and @esize_ptr (if provided). Return non-zero on error. 187 */ 188static int sclp_sd_sync(unsigned long page, u8 eq, u8 di, u64 sat, u64 sa, 189 u32 *dsize_ptr, u32 *esize_ptr) 190{ 191 struct sclp_sd_sccb *sccb = (void *) page; 192 struct sclp_sd_listener listener; 193 struct sclp_sd_evbuf *evbuf; 194 int rc; 195 196 sclp_sd_listener_init(&listener, (u32) (addr_t) sccb); 197 sclp_sd_listener_add(&listener); 198 199 /* Prepare SCCB */ 200 memset(sccb, 0, PAGE_SIZE); 201 sccb->hdr.length = sizeof(sccb->hdr) + sizeof(sccb->evbuf); 202 evbuf = &sccb->evbuf; 203 evbuf->hdr.length = sizeof(*evbuf); 204 evbuf->hdr.type = EVTYP_STORE_DATA; 205 evbuf->eq = eq; 206 evbuf->di = di; 207 evbuf->id = listener.id; 208 evbuf->fmt = 1; 209 evbuf->sat = sat; 210 evbuf->sa = sa; 211 if (dsize_ptr) 212 evbuf->dsize = *dsize_ptr; 213 214 /* Perform command */ 215 pr_debug("request (eq=%d, di=%d, id=0x%08x)\n", eq, di, listener.id); 216 rc = sclp_sync_request(SCLP_CMDW_WRITE_EVENT_DATA, sccb); 217 pr_debug("request done (rc=%d)\n", rc); 218 if (rc) 219 goto out; 220 221 /* Evaluate response */ 222 if (sccb->hdr.response_code == 0x73f0) { 223 pr_debug("event not supported\n"); 224 rc = -EIO; 225 goto out_remove; 226 } 227 if (sccb->hdr.response_code != 0x0020 || !(evbuf->hdr.flags & 0x80)) { 228 rc = -EIO; 229 goto out; 230 } 231 if (!(evbuf->rflags & 0x80)) { 232 rc = wait_for_completion_interruptible(&listener.completion); 233 if (rc) 234 goto out; 235 evbuf = &listener.evbuf; 236 } 237 switch (evbuf->status) { 238 case 0: 239 if (dsize_ptr) 240 *dsize_ptr = evbuf->dsize; 241 if (esize_ptr) 242 *esize_ptr = evbuf->esize; 243 pr_debug("success (dsize=%u, esize=%u)\n", evbuf->dsize, 244 evbuf->esize); 245 break; 246 case 3: 247 rc = -ENOENT; 248 break; 249 default: 250 rc = -EIO; 251 break; 252 253 } 254 255out: 256 if (rc && rc != -ENOENT) { 257 /* Provide some information about what went wrong */ 258 pr_warn("Store Data request failed (eq=%d, di=%d, " 259 "response=0x%04x, flags=0x%02x, status=%d, rc=%d)\n", 260 eq, di, sccb->hdr.response_code, evbuf->hdr.flags, 261 evbuf->status, rc); 262 } 263 264out_remove: 265 sclp_sd_listener_remove(&listener); 266 267 return rc; 268} 269 270/** 271 * sclp_sd_store_data() - Obtain data for specified Store Data entity 272 * @result: Resulting data 273 * @di: DI value associated with this entity 274 * 275 * Perform a series of Store Data requests to obtain the size and contents of 276 * the specified Store Data entity. 277 * 278 * Return: 279 * %0: Success - result is stored in @result. @result->data must be 280 * released using vfree() after use. 281 * %-ENOENT: No data available for this entity 282 * %<0: Other error 283 */ 284static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di) 285{ 286 u32 dsize = 0, esize = 0; 287 unsigned long page, asce = 0; 288 void *data = NULL; 289 int rc; 290 291 page = __get_free_page(GFP_KERNEL | GFP_DMA); 292 if (!page) 293 return -ENOMEM; 294 295 /* Get size */ 296 rc = sclp_sd_sync(page, SD_EQ_SIZE, di, 0, 0, &dsize, &esize); 297 if (rc) 298 goto out; 299 if (dsize == 0) 300 goto out_result; 301 302 /* Allocate memory */ 303 data = vzalloc(array_size((size_t)dsize, PAGE_SIZE)); 304 if (!data) { 305 rc = -ENOMEM; 306 goto out; 307 } 308 309 /* Get translation table for buffer */ 310 asce = base_asce_alloc((unsigned long) data, dsize); 311 if (!asce) { 312 vfree(data); 313 rc = -ENOMEM; 314 goto out; 315 } 316 317 /* Get data */ 318 rc = sclp_sd_sync(page, SD_EQ_STORE_DATA, di, asce, (u64) data, &dsize, 319 &esize); 320 if (rc) { 321 /* Cancel running request if interrupted */ 322 if (rc == -ERESTARTSYS) { 323 if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) { 324 pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n", 325 (size_t)dsize * PAGE_SIZE); 326 data = NULL; 327 asce = 0; 328 } 329 } 330 vfree(data); 331 goto out; 332 } 333 334out_result: 335 result->esize_bytes = (size_t) esize * PAGE_SIZE; 336 result->dsize_bytes = (size_t) dsize * PAGE_SIZE; 337 result->data = data; 338 339out: 340 base_asce_free(asce); 341 free_page(page); 342 343 return rc; 344} 345 346/** 347 * sclp_sd_data_reset() - Reset Store Data result buffer 348 * @data: Data buffer to reset 349 * 350 * Reset @data to initial state and release associated memory. 351 */ 352static void sclp_sd_data_reset(struct sclp_sd_data *data) 353{ 354 vfree(data->data); 355 data->data = NULL; 356 data->dsize_bytes = 0; 357 data->esize_bytes = 0; 358} 359 360/** 361 * sclp_sd_file_release() - Release function for sclp_sd_file object 362 * @kobj: Kobject embedded in sclp_sd_file object 363 */ 364static void sclp_sd_file_release(struct kobject *kobj) 365{ 366 struct sclp_sd_file *sd_file = to_sd_file(kobj); 367 368 sclp_sd_data_reset(&sd_file->data); 369 kfree(sd_file); 370} 371 372/** 373 * sclp_sd_file_update() - Update contents of sclp_sd_file object 374 * @sd_file: Object to update 375 * 376 * Obtain the current version of data associated with the Store Data entity 377 * @sd_file. 378 * 379 * On success, return %0 and generate a KOBJ_CHANGE event to indicate that the 380 * data may have changed. Return non-zero otherwise. 381 */ 382static int sclp_sd_file_update(struct sclp_sd_file *sd_file) 383{ 384 const char *name = kobject_name(&sd_file->kobj); 385 struct sclp_sd_data data; 386 int rc; 387 388 rc = sclp_sd_store_data(&data, sd_file->di); 389 if (rc) { 390 if (rc == -ENOENT) { 391 pr_info("No data is available for the %s data entity\n", 392 name); 393 } 394 return rc; 395 } 396 397 mutex_lock(&sd_file->data_mutex); 398 sclp_sd_data_reset(&sd_file->data); 399 sd_file->data = data; 400 mutex_unlock(&sd_file->data_mutex); 401 402 pr_info("A %zu-byte %s data entity was retrieved\n", data.dsize_bytes, 403 name); 404 kobject_uevent(&sd_file->kobj, KOBJ_CHANGE); 405 406 return 0; 407} 408 409/** 410 * sclp_sd_file_update_async() - Wrapper for asynchronous update call 411 * @data: Object to update 412 */ 413static void sclp_sd_file_update_async(void *data, async_cookie_t cookie) 414{ 415 struct sclp_sd_file *sd_file = data; 416 417 sclp_sd_file_update(sd_file); 418} 419 420/** 421 * reload_store() - Store function for "reload" sysfs attribute 422 * @kobj: Kobject of sclp_sd_file object 423 * 424 * Initiate a reload of the data associated with an sclp_sd_file object. 425 */ 426static ssize_t reload_store(struct kobject *kobj, struct kobj_attribute *attr, 427 const char *buf, size_t count) 428{ 429 struct sclp_sd_file *sd_file = to_sd_file(kobj); 430 431 sclp_sd_file_update(sd_file); 432 433 return count; 434} 435 436static struct kobj_attribute reload_attr = __ATTR_WO(reload); 437 438static struct attribute *sclp_sd_file_default_attrs[] = { 439 &reload_attr.attr, 440 NULL, 441}; 442 443static struct kobj_type sclp_sd_file_ktype = { 444 .sysfs_ops = &kobj_sysfs_ops, 445 .release = sclp_sd_file_release, 446 .default_attrs = sclp_sd_file_default_attrs, 447}; 448 449/** 450 * data_read() - Read function for "read" sysfs attribute 451 * @kobj: Kobject of sclp_sd_file object 452 * @buffer: Target buffer 453 * @off: Requested file offset 454 * @size: Requested number of bytes 455 * 456 * Store the requested portion of the Store Data entity contents into the 457 * specified buffer. Return the number of bytes stored on success, or %0 458 * on EOF. 459 */ 460static ssize_t data_read(struct file *file, struct kobject *kobj, 461 struct bin_attribute *attr, char *buffer, 462 loff_t off, size_t size) 463{ 464 struct sclp_sd_file *sd_file = to_sd_file(kobj); 465 size_t data_size; 466 char *data; 467 468 mutex_lock(&sd_file->data_mutex); 469 470 data = sd_file->data.data; 471 data_size = sd_file->data.dsize_bytes; 472 if (!data || off >= data_size) { 473 size = 0; 474 } else { 475 if (off + size > data_size) 476 size = data_size - off; 477 memcpy(buffer, data + off, size); 478 } 479 480 mutex_unlock(&sd_file->data_mutex); 481 482 return size; 483} 484 485/** 486 * sclp_sd_file_create() - Add a sysfs file representing a Store Data entity 487 * @name: Name of file 488 * @di: DI value associated with this entity 489 * 490 * Create a sysfs directory with the given @name located under 491 * 492 * /sys/firmware/sclp_sd/ 493 * 494 * The files in this directory can be used to access the contents of the Store 495 * Data entity associated with @DI. 496 * 497 * Return pointer to resulting sclp_sd_file object on success, %NULL otherwise. 498 * The object must be freed by calling kobject_put() on the embedded kobject 499 * pointer after use. 500 */ 501static __init struct sclp_sd_file *sclp_sd_file_create(const char *name, u8 di) 502{ 503 struct sclp_sd_file *sd_file; 504 int rc; 505 506 sd_file = kzalloc(sizeof(*sd_file), GFP_KERNEL); 507 if (!sd_file) 508 return NULL; 509 sd_file->di = di; 510 mutex_init(&sd_file->data_mutex); 511 512 /* Create kobject located under /sys/firmware/sclp_sd/ */ 513 sd_file->kobj.kset = sclp_sd_kset; 514 rc = kobject_init_and_add(&sd_file->kobj, &sclp_sd_file_ktype, NULL, 515 "%s", name); 516 if (rc) { 517 kobject_put(&sd_file->kobj); 518 return NULL; 519 } 520 521 sysfs_bin_attr_init(&sd_file->data_attr); 522 sd_file->data_attr.attr.name = "data"; 523 sd_file->data_attr.attr.mode = 0444; 524 sd_file->data_attr.read = data_read; 525 526 rc = sysfs_create_bin_file(&sd_file->kobj, &sd_file->data_attr); 527 if (rc) { 528 kobject_put(&sd_file->kobj); 529 return NULL; 530 } 531 532 /* 533 * For completeness only - users interested in entity data should listen 534 * for KOBJ_CHANGE instead. 535 */ 536 kobject_uevent(&sd_file->kobj, KOBJ_ADD); 537 538 /* Don't let a slow Store Data request delay further initialization */ 539 async_schedule(sclp_sd_file_update_async, sd_file); 540 541 return sd_file; 542} 543 544/** 545 * sclp_sd_init() - Initialize sclp_sd support and register sysfs files 546 */ 547static __init int sclp_sd_init(void) 548{ 549 int rc; 550 551 rc = sclp_register(&sclp_sd_register); 552 if (rc) 553 return rc; 554 555 /* Create kset named "sclp_sd" located under /sys/firmware/ */ 556 rc = -ENOMEM; 557 sclp_sd_kset = kset_create_and_add("sclp_sd", NULL, firmware_kobj); 558 if (!sclp_sd_kset) 559 goto err_kset; 560 561 rc = -EINVAL; 562 config_file = sclp_sd_file_create("config", SD_DI_CONFIG); 563 if (!config_file) 564 goto err_config; 565 566 return 0; 567 568err_config: 569 kset_unregister(sclp_sd_kset); 570err_kset: 571 sclp_unregister(&sclp_sd_register); 572 573 return rc; 574} 575device_initcall(sclp_sd_init); 576