1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * AMD HSMP Platform Driver
4 * Copyright (c) 2022, AMD.
5 * All Rights Reserved.
6 *
7 * This file provides a device implementation for HSMP interface
8 */
9
10 #include <asm/amd/hsmp.h>
11
12 #include <linux/acpi.h>
13 #include <linux/cleanup.h>
14 #include <linux/delay.h>
15 #include <linux/device.h>
16 #include <linux/io.h>
17 #include <linux/mutex.h>
18 #include <linux/nospec.h>
19 #include <linux/rwsem.h>
20 #include <linux/semaphore.h>
21 #include <linux/slab.h>
22 #include <linux/sysfs.h>
23 #include <linux/uaccess.h>
24
25 #include "hsmp.h"
26
27 /* HSMP Status / Error codes */
28 #define HSMP_STATUS_NOT_READY 0x00
29 #define HSMP_STATUS_OK 0x01
30 #define HSMP_ERR_INVALID_MSG 0xFE
31 #define HSMP_ERR_INVALID_INPUT 0xFF
32 #define HSMP_ERR_PREREQ_NOT_SATISFIED 0xFD
33 #define HSMP_ERR_SMU_BUSY 0xFC
34
35 /* Timeout in millsec */
36 #define HSMP_MSG_TIMEOUT 100
37 #define HSMP_SHORT_SLEEP 1
38
39 #define HSMP_WR true
40 #define HSMP_RD false
41
42 /*
43 * When same message numbers are used for both GET and SET operation,
44 * bit:31 indicates whether its SET or GET operation.
45 */
46 #define CHECK_GET_BIT BIT(31)
47
48 static struct hsmp_plat_device hsmp_pdev;
49
50 /*
51 * Gates the AMD HSMP data plane against socket bring-up and teardown.
52 *
53 * hsmp_send_message() takes it for read, so open /dev/hsmp fds and hwmon reads
54 * run concurrently. Probe and remove take it for write: probe brings sockets
55 * up (running the mailbox handshake via hsmp_send_message_locked()) and remove
56 * tears them down, both excluding and draining the data plane.
57 */
58 DECLARE_RWSEM(hsmp_sock_rwsem);
59 EXPORT_SYMBOL_NS_GPL(hsmp_sock_rwsem, "AMD_HSMP");
60
61 /*
62 * Send a message to the HSMP port via PCI-e config space registers
63 * or by writing to MMIO space.
64 *
65 * The caller is expected to zero out any unused arguments.
66 * If a response is expected, the number of response words should be greater than 0.
67 *
68 * Returns 0 for success and populates the requested number of arguments.
69 * Returns a negative error code for failure.
70 */
__hsmp_send_message(struct hsmp_socket * sock,struct hsmp_message * msg)71 static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *msg)
72 {
73 struct hsmp_mbaddr_info *mbinfo;
74 unsigned long timeout, short_sleep;
75 u32 mbox_status;
76 u32 index;
77 int ret;
78
79 mbinfo = &sock->mbinfo;
80
81 /* Clear the status register */
82 mbox_status = HSMP_STATUS_NOT_READY;
83 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR);
84 if (ret) {
85 dev_err(sock->dev, "Error %d clearing mailbox status register\n", ret);
86 return ret;
87 }
88
89 index = 0;
90 /* Write any message arguments */
91 while (index < msg->num_args) {
92 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
93 &msg->args[index], HSMP_WR);
94 if (ret) {
95 dev_err(sock->dev, "Error %d writing message argument %d\n", ret, index);
96 return ret;
97 }
98 index++;
99 }
100
101 /* Write the message ID which starts the operation */
102 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR);
103 if (ret) {
104 dev_err(sock->dev, "Error %d writing message ID %u\n", ret, msg->msg_id);
105 return ret;
106 }
107
108 /*
109 * Depending on when the trigger write completes relative to the SMU
110 * firmware 1 ms cycle, the operation may take from tens of us to 1 ms
111 * to complete. Some operations may take more. Therefore we will try
112 * a few short duration sleeps and switch to long sleeps if we don't
113 * succeed quickly.
114 */
115 short_sleep = jiffies + msecs_to_jiffies(HSMP_SHORT_SLEEP);
116 timeout = jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT);
117
118 while (true) {
119 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD);
120 if (ret) {
121 dev_err(sock->dev, "Error %d reading mailbox status\n", ret);
122 return ret;
123 }
124
125 if (mbox_status != HSMP_STATUS_NOT_READY)
126 break;
127
128 if (!time_before(jiffies, timeout))
129 break;
130
131 if (time_before(jiffies, short_sleep))
132 usleep_range(50, 100);
133 else
134 usleep_range(1000, 2000);
135 }
136
137 if (unlikely(mbox_status == HSMP_STATUS_NOT_READY)) {
138 dev_err(sock->dev, "Message ID 0x%X failure : SMU timeout (status = 0x%X)\n",
139 msg->msg_id, mbox_status);
140 return -ETIMEDOUT;
141 } else if (unlikely(mbox_status == HSMP_ERR_INVALID_MSG)) {
142 dev_err(sock->dev, "Message ID 0x%X failure : Invalid message (status = 0x%X)\n",
143 msg->msg_id, mbox_status);
144 return -ENOMSG;
145 } else if (unlikely(mbox_status == HSMP_ERR_INVALID_INPUT)) {
146 dev_err(sock->dev, "Message ID 0x%X failure : Invalid arguments (status = 0x%X)\n",
147 msg->msg_id, mbox_status);
148 return -EINVAL;
149 } else if (unlikely(mbox_status == HSMP_ERR_PREREQ_NOT_SATISFIED)) {
150 dev_err(sock->dev, "Message ID 0x%X failure : Prerequisite not satisfied (status = 0x%X)\n",
151 msg->msg_id, mbox_status);
152 return -EREMOTEIO;
153 } else if (unlikely(mbox_status == HSMP_ERR_SMU_BUSY)) {
154 dev_err(sock->dev, "Message ID 0x%X failure : SMU BUSY (status = 0x%X)\n",
155 msg->msg_id, mbox_status);
156 return -EBUSY;
157 } else if (unlikely(mbox_status != HSMP_STATUS_OK)) {
158 dev_err(sock->dev, "Message ID 0x%X unknown failure (status = 0x%X)\n",
159 msg->msg_id, mbox_status);
160 return -EIO;
161 }
162
163 /*
164 * SMU has responded OK. Read response data.
165 * SMU reads the input arguments from eight 32 bit registers starting
166 * from SMN_HSMP_MSG_DATA and writes the response data to the same
167 * SMN_HSMP_MSG_DATA address.
168 * We copy the response data if any, back to the args[].
169 */
170 index = 0;
171 while (index < msg->response_sz) {
172 ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
173 &msg->args[index], HSMP_RD);
174 if (ret) {
175 dev_err(sock->dev, "Error %d reading response %u for message ID:%u\n",
176 ret, index, msg->msg_id);
177 break;
178 }
179 index++;
180 }
181
182 return ret;
183 }
184
validate_message(struct hsmp_message * msg)185 static int validate_message(struct hsmp_message *msg)
186 {
187 /* msg_id against valid range of message IDs */
188 if (msg->msg_id < HSMP_TEST || msg->msg_id >= HSMP_MSG_ID_MAX)
189 return -ENOMSG;
190
191 /* msg_id is a reserved message ID */
192 if (hsmp_msg_desc_table[msg->msg_id].type == HSMP_RSVD)
193 return -ENOMSG;
194
195 /*
196 * num_args passed by user should match the num_args specified in
197 * message description table.
198 */
199 if (msg->num_args != hsmp_msg_desc_table[msg->msg_id].num_args)
200 return -EINVAL;
201
202 /*
203 * As the HSMP protocol evolves, newer platforms may define more
204 * response arguments for existing messages. Use an upper-bound
205 * check so that older userspace callers requesting fewer response
206 * words than what the current hsmp_msg_desc_table[] defines are
207 * still accepted, while rejecting requests that exceed the
208 * hardware capability.
209 */
210 if (msg->response_sz > hsmp_msg_desc_table[msg->msg_id].response_sz)
211 return -EINVAL;
212
213 return 0;
214 }
215
216 /*
217 * Core message send. The caller must hold hsmp_sock_rwsem: the data plane
218 * takes it for read so many messages run concurrently, while the probe-time
219 * senders run under the write lock taken by probe. Holding it here serializes
220 * every message against socket teardown, which also holds it for write.
221 */
hsmp_send_message_locked(struct hsmp_message * msg)222 static int hsmp_send_message_locked(struct hsmp_message *msg)
223 {
224 struct hsmp_socket *sock;
225 unsigned int sock_ind;
226 int ret;
227
228 lockdep_assert_held(&hsmp_sock_rwsem);
229
230 if (!msg)
231 return -EINVAL;
232 ret = validate_message(msg);
233 if (ret)
234 return ret;
235
236 if (!hsmp_pdev.sock || msg->sock_ind >= hsmp_pdev.num_sockets)
237 return -ENODEV;
238
239 /*
240 * Sanitize sock_ind after the bounds check. A mispredicted branch can
241 * still let the CPU speculatively use msg->sock_ind as an index into
242 * hsmp_pdev.sock[] (Spectre v1, CVE-2017-5753), including for callers
243 * other than hsmp_ioctl_msg() that pass a user-derived socket index.
244 */
245 sock_ind = array_index_nospec(msg->sock_ind, hsmp_pdev.num_sockets);
246 sock = &hsmp_pdev.sock[sock_ind];
247
248 /*
249 * A slot exists for every possible socket, but it is only usable once
250 * that socket has actually been probed. Reject messages aimed at a
251 * socket that was never brought up or is still in bring-up, so we never
252 * operate on a zero-initialized semaphore or an unmapped mailbox. A
253 * non-NULL dev also guarantees virt_base_addr, the mailbox offsets and
254 * the semaphore are visible.
255 *
256 * Held under hsmp_sock_rwsem; pairs with smp_store_release(&sock->dev)
257 * in hsmp_parse_acpi_table().
258 */
259 if (!smp_load_acquire(&sock->dev))
260 return -ENODEV;
261
262 ret = down_interruptible(&sock->hsmp_sem);
263 if (ret < 0)
264 return ret;
265
266 ret = __hsmp_send_message(sock, msg);
267
268 up(&sock->hsmp_sem);
269
270 return ret;
271 }
272
hsmp_send_message(struct hsmp_message * msg)273 int hsmp_send_message(struct hsmp_message *msg)
274 {
275 /*
276 * Data-plane entry point: open /dev/hsmp fds and hwmon sysfs reads issue
277 * messages from here. Take hsmp_sock_rwsem for read so messages run
278 * concurrently with each other but are drained and kept out while
279 * probe/remove hold it for write to tear a socket down.
280 */
281 guard(rwsem_read)(&hsmp_sock_rwsem);
282
283 return hsmp_send_message_locked(msg);
284 }
285 EXPORT_SYMBOL_NS_GPL(hsmp_send_message, "AMD_HSMP");
286
hsmp_msg_get_nargs(u16 sock_ind,u32 msg_id,u32 * data,u8 num_args)287 int hsmp_msg_get_nargs(u16 sock_ind, u32 msg_id, u32 *data, u8 num_args)
288 {
289 struct hsmp_message msg = {};
290 unsigned int i;
291 int ret;
292
293 if (!data)
294 return -EINVAL;
295 msg.msg_id = msg_id;
296 msg.sock_ind = sock_ind;
297 msg.response_sz = num_args;
298
299 ret = hsmp_send_message(&msg);
300 if (ret)
301 return ret;
302
303 for (i = 0; i < num_args; i++)
304 data[i] = msg.args[i];
305
306 return 0;
307 }
308 EXPORT_SYMBOL_NS_GPL(hsmp_msg_get_nargs, "AMD_HSMP");
309
hsmp_test(u16 sock_ind,u32 value)310 int hsmp_test(u16 sock_ind, u32 value)
311 {
312 struct hsmp_message msg = { 0 };
313 int ret;
314
315 /*
316 * Test the hsmp port by performing TEST command. The test message
317 * takes one argument and returns the value of that argument + 1.
318 */
319 msg.msg_id = HSMP_TEST;
320 msg.num_args = 1;
321 msg.response_sz = 1;
322 msg.args[0] = value;
323 msg.sock_ind = sock_ind;
324
325 ret = hsmp_send_message_locked(&msg);
326 if (ret)
327 return ret;
328
329 /* Check the response value */
330 if (msg.args[0] != (value + 1)) {
331 dev_err(hsmp_pdev.sock[sock_ind].dev,
332 "Socket %d test message failed, Expected 0x%08X, received 0x%08X\n",
333 sock_ind, (value + 1), msg.args[0]);
334 return -EBADE;
335 }
336
337 return ret;
338 }
339 EXPORT_SYMBOL_NS_GPL(hsmp_test, "AMD_HSMP");
340
is_get_msg(struct hsmp_message * msg)341 static bool is_get_msg(struct hsmp_message *msg)
342 {
343 if (hsmp_msg_desc_table[msg->msg_id].type == HSMP_GET)
344 return true;
345
346 if (hsmp_msg_desc_table[msg->msg_id].type == HSMP_SET_GET &&
347 (msg->args[0] & CHECK_GET_BIT))
348 return true;
349
350 return false;
351 }
352
hsmp_ioctl_msg(struct file * fp,unsigned long arg)353 static long hsmp_ioctl_msg(struct file *fp, unsigned long arg)
354 {
355 int __user *arguser = (int __user *)arg;
356 struct hsmp_message msg = { 0 };
357 int ret;
358
359 if (copy_struct_from_user(&msg, sizeof(msg), arguser, sizeof(struct hsmp_message)))
360 return -EFAULT;
361
362 /*
363 * Check msg_id is within the range of supported msg ids
364 * i.e within the array bounds of hsmp_msg_desc_table
365 */
366 if (msg.msg_id < HSMP_TEST || msg.msg_id >= HSMP_MSG_ID_MAX)
367 return -ENOMSG;
368
369 /*
370 * Sanitize the user-controlled msg_id against speculative
371 * execution. The bounds check above retires the out-of-range
372 * case with -ENOMSG, but a mispredicted branch can still let the
373 * CPU speculatively use msg_id as an index into
374 * hsmp_msg_desc_table[] (here and in validate_message() /
375 * is_get_msg() called downstream via hsmp_send_message()), and
376 * pull arbitrary kernel memory into the cache (Spectre v1,
377 * CVE-2017-5753). Clamp once into msg.msg_id so every downstream
378 * dereference sees the sanitized value.
379 */
380 msg.msg_id = array_index_nospec(msg.msg_id, HSMP_MSG_ID_MAX);
381
382 switch (fp->f_mode & (FMODE_WRITE | FMODE_READ)) {
383 case FMODE_WRITE:
384 /*
385 * Device is opened in O_WRONLY mode
386 * Execute only set/configure commands
387 */
388 if (is_get_msg(&msg))
389 return -EPERM;
390 break;
391 case FMODE_READ:
392 /*
393 * Device is opened in O_RDONLY mode
394 * Execute only get/monitor commands
395 */
396 if (!is_get_msg(&msg))
397 return -EPERM;
398 break;
399 case FMODE_READ | FMODE_WRITE:
400 /*
401 * Device is opened in O_RDWR mode
402 * Execute both get/monitor and set/configure commands
403 */
404 break;
405 default:
406 return -EPERM;
407 }
408
409 ret = hsmp_send_message(&msg);
410 if (ret)
411 return ret;
412
413 if (hsmp_msg_desc_table[msg.msg_id].response_sz > 0) {
414 /* Copy results back to user for get/monitor commands */
415 if (copy_to_user(arguser, &msg, sizeof(struct hsmp_message)))
416 return -EFAULT;
417 }
418
419 return 0;
420 }
421
422 static ssize_t hsmp_metric_tbl_read_locked(struct hsmp_socket *sock, char *buf,
423 size_t size);
424
425 /*
426 * Fetch the firmware metric (telemetry) table for the requested socket and
427 * copy it to the userspace buffer described by the request.
428 *
429 * The metric table size is variable across HSMP protocol versions and on
430 * Family 1Ah Model 50h-5Fh exceeds PAGE_SIZE. The request carries the buffer
431 * size, which may be anything up to the size firmware reported for this
432 * socket's table.
433 */
hsmp_ioctl_get_telemetry(struct file * fp,unsigned long arg)434 static long hsmp_ioctl_get_telemetry(struct file *fp, unsigned long arg)
435 {
436 void *kbuf __free(kvfree) = NULL;
437 void __user *arguser = (void __user *)arg;
438 struct hsmp_telemetry_data req;
439 struct hsmp_socket *sock;
440 void __user *user_buf;
441 size_t tbl_size;
442 unsigned int sock_ind;
443 int ret;
444
445 /* Telemetry data is read-only; require read access on the fd. */
446 if (!(fp->f_mode & FMODE_READ))
447 return -EPERM;
448
449 if (copy_from_user(&req, arguser, sizeof(req)))
450 return -EFAULT;
451
452 /*
453 * Reserved fields must be zero so future kernels can safely
454 * repurpose them without breaking already-deployed userspace.
455 */
456 if (req.reserved)
457 return -EINVAL;
458
459 user_buf = u64_to_user_ptr(req.buf);
460
461 /*
462 * /dev/hsmp is a singleton character device that outlives an individual
463 * socket unbind, so an ioctl on an already-open fd can run concurrently
464 * with socket teardown. Hold hsmp_sock_rwsem for read across the socket
465 * lookup, the checks on its metric-table state and the read itself:
466 * probe and remove take the same lock for write, so they cannot free the
467 * socket array, unmap the table or destroy the per-socket mutex while
468 * this runs.
469 *
470 * The lock is dropped before the copy_to_user() below. Faulting in the
471 * destination can block indefinitely on a userfaultfd-backed buffer,
472 * which would leave a socket unbind waiting for the write lock.
473 */
474 scoped_guard(rwsem_read, &hsmp_sock_rwsem) {
475 if (!hsmp_pdev.sock || req.sock_ind >= hsmp_pdev.num_sockets)
476 return -ENODEV;
477
478 /*
479 * Sanitize the user-controlled socket index against speculative
480 * execution. The bounds check above retires the out-of-range
481 * case with -ENODEV, but a mispredicted branch can still let the
482 * CPU speculatively use sock_ind as an index into
483 * hsmp_pdev.sock[] and pull arbitrary kernel memory into the
484 * cache (Spectre v1, CVE-2017-5753). array_index_nospec() turns
485 * the bounds check into a data-flow clamp so the speculative
486 * load is in-range too.
487 */
488 sock_ind = array_index_nospec(req.sock_ind, hsmp_pdev.num_sockets);
489 sock = &hsmp_pdev.sock[sock_ind];
490 if (!sock->metric_tbl_addr)
491 return -ENODEV;
492
493 tbl_size = sock->metric_tbl_size;
494 if (!tbl_size)
495 return -ENODEV;
496
497 /*
498 * A request shorter than the firmware table is served with the
499 * leading @size bytes of the snapshot, so userspace built
500 * against an older table layout keeps working on firmware that
501 * grew the table. Asking for more than firmware provides is
502 * rejected rather than short-written, so a caller can never
503 * mistake a partial copy for a full one.
504 */
505 if (!req.size || req.size > tbl_size)
506 return -EINVAL;
507
508 /*
509 * The bounce buffer is overwritten in full by memcpy_fromio()
510 * inside hsmp_metric_tbl_read_locked(); use kvmalloc() to avoid
511 * the zeroing cost of kvzalloc() on the ~13 KB allocation done
512 * on every ioctl call.
513 */
514 kbuf = kvmalloc(tbl_size, GFP_KERNEL);
515 if (!kbuf)
516 return -ENOMEM;
517
518 ret = hsmp_metric_tbl_read_locked(sock, kbuf, tbl_size);
519 }
520
521 if (ret < 0)
522 return ret;
523
524 if (copy_to_user(user_buf, kbuf, req.size))
525 return -EFAULT;
526
527 return 0;
528 }
529
hsmp_ioctl(struct file * fp,unsigned int cmd,unsigned long arg)530 long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
531 {
532 switch (cmd) {
533 case HSMP_IOCTL_CMD:
534 return hsmp_ioctl_msg(fp, arg);
535 case HSMP_IOCTL_GET_TELEMETRY_DATA:
536 return hsmp_ioctl_get_telemetry(fp, arg);
537 default:
538 return -ENOTTY;
539 }
540 }
541
542 /*
543 * Caller must hold hsmp_sock_rwsem. It keeps @sock, its metric-table mapping
544 * and its metric_read_lock alive: probe and remove take the same lock for
545 * write while they bring sockets up and tear them down.
546 */
hsmp_metric_tbl_read_locked(struct hsmp_socket * sock,char * buf,size_t size)547 static ssize_t hsmp_metric_tbl_read_locked(struct hsmp_socket *sock, char *buf,
548 size_t size)
549 {
550 struct hsmp_message msg = { 0 };
551 int ret;
552
553 lockdep_assert_held(&hsmp_sock_rwsem);
554
555 if (!sock || !buf)
556 return -EINVAL;
557
558 if (!sock->metric_tbl_addr) {
559 dev_err(sock->dev, "Metrics table address not available\n");
560 return -ENOMEM;
561 }
562
563 if (size != sock->metric_tbl_size) {
564 dev_err(sock->dev, "Wrong buffer size\n");
565 return -EINVAL;
566 }
567
568 msg.msg_id = HSMP_GET_METRIC_TABLE;
569 msg.sock_ind = sock->sock_ind;
570
571 /*
572 * HSMP_GET_METRIC_TABLE makes firmware refill this socket's shared
573 * metric DRAM region, which is then copied out below. Hold the
574 * per-socket lock across the fill-and-copy so concurrent readers of the
575 * same socket cannot return a torn snapshot.
576 */
577 guard(mutex)(&sock->metric_read_lock);
578
579 ret = hsmp_send_message_locked(&msg);
580 if (ret)
581 return ret;
582 memcpy_fromio(buf, sock->metric_tbl_addr, size);
583
584 return size;
585 }
586
hsmp_metric_tbl_read(struct hsmp_socket * sock,char * buf,size_t size)587 ssize_t hsmp_metric_tbl_read(struct hsmp_socket *sock, char *buf, size_t size)
588 {
589 guard(rwsem_read)(&hsmp_sock_rwsem);
590
591 return hsmp_metric_tbl_read_locked(sock, buf, size);
592 }
593 EXPORT_SYMBOL_NS_GPL(hsmp_metric_tbl_read, "AMD_HSMP");
594
hsmp_init_metric_read_locks(struct hsmp_plat_device * pdev)595 void hsmp_init_metric_read_locks(struct hsmp_plat_device *pdev)
596 {
597 u16 i;
598
599 for (i = 0; i < pdev->num_sockets; i++)
600 mutex_init(&pdev->sock[i].metric_read_lock);
601 }
602 EXPORT_SYMBOL_NS_GPL(hsmp_init_metric_read_locks, "AMD_HSMP");
603
hsmp_destroy_metric_read_locks(struct hsmp_plat_device * pdev)604 void hsmp_destroy_metric_read_locks(struct hsmp_plat_device *pdev)
605 {
606 u16 i;
607
608 for (i = 0; i < pdev->num_sockets; i++)
609 mutex_destroy(&pdev->sock[i].metric_read_lock);
610 }
611 EXPORT_SYMBOL_NS_GPL(hsmp_destroy_metric_read_locks, "AMD_HSMP");
612
hsmp_unmap_metric_tbls(struct hsmp_plat_device * pdev)613 void hsmp_unmap_metric_tbls(struct hsmp_plat_device *pdev)
614 {
615 struct hsmp_socket *sock;
616 u16 i;
617
618 for (i = 0; i < pdev->num_sockets; i++) {
619 sock = &pdev->sock[i];
620 if (sock->metric_tbl_addr) {
621 iounmap(sock->metric_tbl_addr);
622 sock->metric_tbl_addr = NULL;
623 }
624 sock->metric_tbl_size = 0;
625 }
626 }
627 EXPORT_SYMBOL_NS_GPL(hsmp_unmap_metric_tbls, "AMD_HSMP");
628
hsmp_get_tbl_dram_base(u16 sock_ind)629 int hsmp_get_tbl_dram_base(u16 sock_ind)
630 {
631 struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
632 struct hsmp_message msg = { 0 };
633 phys_addr_t dram_addr;
634 size_t tbl_size;
635 int ret;
636
637 msg.sock_ind = sock_ind;
638 msg.response_sz = hsmp_msg_desc_table[HSMP_GET_METRIC_TABLE_DRAM_ADDR].response_sz;
639 msg.msg_id = HSMP_GET_METRIC_TABLE_DRAM_ADDR;
640
641 ret = hsmp_send_message_locked(&msg);
642 if (ret)
643 return ret;
644
645 /*
646 * calculate the metric table DRAM address from lower and upper 32 bits
647 * sent from SMU and ioremap it to virtual address.
648 */
649 dram_addr = msg.args[0] | ((u64)(msg.args[1]) << 32);
650 if (!dram_addr) {
651 dev_err(sock->dev, "Invalid DRAM address for metric table\n");
652 return -ENOMEM;
653 }
654 /*
655 * The ACPI socket array is shared across sockets and outlives a
656 * per-socket unbind, so metric_tbl_addr may hold a mapping from an
657 * earlier bind of this socket. Unmap it before remapping so an
658 * unbind/rebind cycle does not leak a metric-table mapping. This runs
659 * during probe before the metric sysfs attribute is exposed, so no
660 * reader can be using it.
661 */
662 if (sock->metric_tbl_addr) {
663 iounmap(sock->metric_tbl_addr);
664 sock->metric_tbl_addr = NULL;
665 }
666 sock->metric_tbl_size = 0;
667
668 /* SMU returns table size from Family 1Ah Model 50h and forward */
669 if (msg.args[2])
670 tbl_size = msg.args[2];
671 else
672 tbl_size = sizeof(struct hsmp_metric_table);
673
674 sock->metric_tbl_addr = ioremap(dram_addr, tbl_size);
675 if (!sock->metric_tbl_addr) {
676 dev_err(sock->dev, "Failed to ioremap metric table addr\n");
677 return -ENOMEM;
678 }
679 sock->metric_tbl_size = tbl_size;
680
681 return 0;
682 }
683 EXPORT_SYMBOL_NS_GPL(hsmp_get_tbl_dram_base, "AMD_HSMP");
684
hsmp_cache_proto_ver(u16 sock_ind)685 int hsmp_cache_proto_ver(u16 sock_ind)
686 {
687 struct hsmp_message msg = { 0 };
688 int ret;
689
690 msg.msg_id = HSMP_GET_PROTO_VER;
691 msg.sock_ind = sock_ind;
692 msg.response_sz = hsmp_msg_desc_table[HSMP_GET_PROTO_VER].response_sz;
693
694 ret = hsmp_send_message_locked(&msg);
695 if (!ret)
696 hsmp_pdev.proto_ver = msg.args[0];
697
698 return ret;
699 }
700 EXPORT_SYMBOL_NS_GPL(hsmp_cache_proto_ver, "AMD_HSMP");
701
702 static const struct file_operations hsmp_fops = {
703 .owner = THIS_MODULE,
704 .unlocked_ioctl = hsmp_ioctl,
705 .compat_ioctl = hsmp_ioctl,
706 };
707
hsmp_misc_register(struct device * dev)708 int hsmp_misc_register(struct device *dev)
709 {
710 hsmp_pdev.mdev.name = HSMP_CDEV_NAME;
711 hsmp_pdev.mdev.minor = MISC_DYNAMIC_MINOR;
712 hsmp_pdev.mdev.fops = &hsmp_fops;
713 /*
714 * The caller chooses the parent. The platform driver has a single
715 * device whose lifetime matches /dev/hsmp and parents it there. The
716 * ACPI driver passes NULL: its /dev/hsmp is a singleton shared by
717 * per-socket devices that can be unbound individually and out of order,
718 * so parenting it to one would leave it attached to an already-removed
719 * device.
720 */
721 hsmp_pdev.mdev.parent = dev;
722 hsmp_pdev.mdev.nodename = HSMP_DEVNODE_NAME;
723 hsmp_pdev.mdev.mode = 0644;
724
725 return misc_register(&hsmp_pdev.mdev);
726 }
727 EXPORT_SYMBOL_NS_GPL(hsmp_misc_register, "AMD_HSMP");
728
hsmp_misc_deregister(void)729 void hsmp_misc_deregister(void)
730 {
731 misc_deregister(&hsmp_pdev.mdev);
732 hsmp_pdev.mdev.this_device = NULL;
733 }
734 EXPORT_SYMBOL_NS_GPL(hsmp_misc_deregister, "AMD_HSMP");
735
get_hsmp_pdev(void)736 struct hsmp_plat_device *get_hsmp_pdev(void)
737 {
738 return &hsmp_pdev;
739 }
740 EXPORT_SYMBOL_NS_GPL(get_hsmp_pdev, "AMD_HSMP");
741
742 MODULE_DESCRIPTION("AMD HSMP Common driver");
743 MODULE_VERSION(DRIVER_VERSION);
744 MODULE_LICENSE("GPL");
745