1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Intel Software Defined Silicon driver
4 *
5 * Copyright (c) 2022, Intel Corporation.
6 * All Rights Reserved.
7 *
8 * Author: "David E. Box" <david.e.box@linux.intel.com>
9 */
10
11 #include <linux/auxiliary_bus.h>
12 #include <linux/bits.h>
13 #include <linux/bitfield.h>
14 #include <linux/device.h>
15 #include <linux/iopoll.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/pci.h>
19 #include <linux/slab.h>
20 #include <linux/sysfs.h>
21 #include <linux/types.h>
22 #include <linux/uaccess.h>
23
24 #include "vsec.h"
25
26 #define ACCESS_TYPE_BARID 2
27 #define ACCESS_TYPE_LOCAL 3
28
29 #define SDSI_MIN_SIZE_DWORDS 276
30 #define SDSI_SIZE_CONTROL 8
31 #define SDSI_SIZE_MAILBOX 1024
32 #define SDSI_SIZE_REGS 72
33 #define SDSI_SIZE_CMD sizeof(u64)
34
35 /*
36 * Write messages are currently up to the size of the mailbox
37 * while read messages are up to 4 times the size of the
38 * mailbox, sent in packets
39 */
40 #define SDSI_SIZE_WRITE_MSG SDSI_SIZE_MAILBOX
41 #define SDSI_SIZE_READ_MSG (SDSI_SIZE_MAILBOX * 4)
42
43 #define SDSI_ENABLED_FEATURES_OFFSET 16
44 #define SDSI_ENABLED BIT(3)
45 #define SDSI_SOCKET_ID_OFFSET 64
46 #define SDSI_SOCKET_ID GENMASK(3, 0)
47
48 #define SDSI_MBOX_CMD_SUCCESS 0x40
49 #define SDSI_MBOX_CMD_TIMEOUT 0x80
50
51 #define MBOX_TIMEOUT_US 2000
52 #define MBOX_TIMEOUT_ACQUIRE_US 1000
53 #define MBOX_POLLING_PERIOD_US 100
54 #define MBOX_ACQUIRE_NUM_RETRIES 5
55 #define MBOX_ACQUIRE_RETRY_DELAY_MS 500
56 #define MBOX_MAX_PACKETS 4
57
58 #define MBOX_OWNER_NONE 0x00
59 #define MBOX_OWNER_INBAND 0x01
60
61 #define CTRL_RUN_BUSY BIT(0)
62 #define CTRL_READ_WRITE BIT(1)
63 #define CTRL_SOM BIT(2)
64 #define CTRL_EOM BIT(3)
65 #define CTRL_OWNER GENMASK(5, 4)
66 #define CTRL_COMPLETE BIT(6)
67 #define CTRL_READY BIT(7)
68 #define CTRL_STATUS GENMASK(15, 8)
69 #define CTRL_PACKET_SIZE GENMASK(31, 16)
70 #define CTRL_MSG_SIZE GENMASK(63, 48)
71
72 #define DISC_TABLE_SIZE 12
73 #define DT_ACCESS_TYPE GENMASK(3, 0)
74 #define DT_SIZE GENMASK(27, 12)
75 #define DT_TBIR GENMASK(2, 0)
76 #define DT_OFFSET(v) ((v) & GENMASK(31, 3))
77
78 enum sdsi_command {
79 SDSI_CMD_PROVISION_AKC = 0x04,
80 SDSI_CMD_PROVISION_CAP = 0x08,
81 SDSI_CMD_READ_STATE = 0x10,
82 };
83
84 struct sdsi_mbox_info {
85 u64 *payload;
86 void *buffer;
87 int size;
88 };
89
90 struct disc_table {
91 u32 access_info;
92 u32 guid;
93 u32 offset;
94 };
95
96 struct sdsi_priv {
97 struct mutex mb_lock; /* Mailbox access lock */
98 struct device *dev;
99 void __iomem *control_addr;
100 void __iomem *mbox_addr;
101 void __iomem *regs_addr;
102 u32 guid;
103 bool sdsi_enabled;
104 };
105
106 /* SDSi mailbox operations must be performed using 64bit mov instructions */
107 static __always_inline void
sdsi_memcpy64_toio(u64 __iomem * to,const u64 * from,size_t count_bytes)108 sdsi_memcpy64_toio(u64 __iomem *to, const u64 *from, size_t count_bytes)
109 {
110 size_t count = count_bytes / sizeof(*to);
111 int i;
112
113 for (i = 0; i < count; i++)
114 writeq(from[i], &to[i]);
115 }
116
117 static __always_inline void
sdsi_memcpy64_fromio(u64 * to,const u64 __iomem * from,size_t count_bytes)118 sdsi_memcpy64_fromio(u64 *to, const u64 __iomem *from, size_t count_bytes)
119 {
120 size_t count = count_bytes / sizeof(*to);
121 int i;
122
123 for (i = 0; i < count; i++)
124 to[i] = readq(&from[i]);
125 }
126
sdsi_complete_transaction(struct sdsi_priv * priv)127 static inline void sdsi_complete_transaction(struct sdsi_priv *priv)
128 {
129 u64 control = FIELD_PREP(CTRL_COMPLETE, 1);
130
131 lockdep_assert_held(&priv->mb_lock);
132 writeq(control, priv->control_addr);
133 }
134
sdsi_status_to_errno(u32 status)135 static int sdsi_status_to_errno(u32 status)
136 {
137 switch (status) {
138 case SDSI_MBOX_CMD_SUCCESS:
139 return 0;
140 case SDSI_MBOX_CMD_TIMEOUT:
141 return -ETIMEDOUT;
142 default:
143 return -EIO;
144 }
145 }
146
sdsi_mbox_cmd_read(struct sdsi_priv * priv,struct sdsi_mbox_info * info,size_t * data_size)147 static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info,
148 size_t *data_size)
149 {
150 struct device *dev = priv->dev;
151 u32 total, loop, eom, status, message_size;
152 u64 control;
153 int ret;
154
155 lockdep_assert_held(&priv->mb_lock);
156
157 /* Format and send the read command */
158 control = FIELD_PREP(CTRL_EOM, 1) |
159 FIELD_PREP(CTRL_SOM, 1) |
160 FIELD_PREP(CTRL_RUN_BUSY, 1) |
161 FIELD_PREP(CTRL_PACKET_SIZE, info->size);
162 writeq(control, priv->control_addr);
163
164 /* For reads, data sizes that are larger than the mailbox size are read in packets. */
165 total = 0;
166 loop = 0;
167 do {
168 void *buf = info->buffer + (SDSI_SIZE_MAILBOX * loop);
169 u32 packet_size;
170
171 /* Poll on ready bit */
172 ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY,
173 MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US);
174 if (ret)
175 break;
176
177 eom = FIELD_GET(CTRL_EOM, control);
178 status = FIELD_GET(CTRL_STATUS, control);
179 packet_size = FIELD_GET(CTRL_PACKET_SIZE, control);
180 message_size = FIELD_GET(CTRL_MSG_SIZE, control);
181
182 ret = sdsi_status_to_errno(status);
183 if (ret)
184 break;
185
186 /* Only the last packet can be less than the mailbox size. */
187 if (!eom && packet_size != SDSI_SIZE_MAILBOX) {
188 dev_err(dev, "Invalid packet size\n");
189 ret = -EPROTO;
190 break;
191 }
192
193 if (packet_size > SDSI_SIZE_MAILBOX) {
194 dev_err(dev, "Packet size too large\n");
195 ret = -EPROTO;
196 break;
197 }
198
199 sdsi_memcpy64_fromio(buf, priv->mbox_addr, round_up(packet_size, SDSI_SIZE_CMD));
200
201 total += packet_size;
202
203 sdsi_complete_transaction(priv);
204 } while (!eom && ++loop < MBOX_MAX_PACKETS);
205
206 if (ret) {
207 sdsi_complete_transaction(priv);
208 return ret;
209 }
210
211 if (!eom) {
212 dev_err(dev, "Exceeded read attempts\n");
213 return -EPROTO;
214 }
215
216 /* Message size check is only valid for multi-packet transfers */
217 if (loop && total != message_size)
218 dev_warn(dev, "Read count %u differs from expected count %u\n",
219 total, message_size);
220
221 *data_size = total;
222
223 return 0;
224 }
225
sdsi_mbox_cmd_write(struct sdsi_priv * priv,struct sdsi_mbox_info * info)226 static int sdsi_mbox_cmd_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info)
227 {
228 u64 control;
229 u32 status;
230 int ret;
231
232 lockdep_assert_held(&priv->mb_lock);
233
234 /* Write rest of the payload */
235 sdsi_memcpy64_toio(priv->mbox_addr + SDSI_SIZE_CMD, info->payload + 1,
236 info->size - SDSI_SIZE_CMD);
237
238 /* Format and send the write command */
239 control = FIELD_PREP(CTRL_EOM, 1) |
240 FIELD_PREP(CTRL_SOM, 1) |
241 FIELD_PREP(CTRL_RUN_BUSY, 1) |
242 FIELD_PREP(CTRL_READ_WRITE, 1) |
243 FIELD_PREP(CTRL_PACKET_SIZE, info->size);
244 writeq(control, priv->control_addr);
245
246 /* Poll on ready bit */
247 ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY,
248 MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US);
249
250 if (ret)
251 goto release_mbox;
252
253 status = FIELD_GET(CTRL_STATUS, control);
254 ret = sdsi_status_to_errno(status);
255
256 release_mbox:
257 sdsi_complete_transaction(priv);
258
259 return ret;
260 }
261
sdsi_mbox_acquire(struct sdsi_priv * priv,struct sdsi_mbox_info * info)262 static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info)
263 {
264 u64 control;
265 u32 owner;
266 int ret, retries = 0;
267
268 lockdep_assert_held(&priv->mb_lock);
269
270 /* Check mailbox is available */
271 control = readq(priv->control_addr);
272 owner = FIELD_GET(CTRL_OWNER, control);
273 if (owner != MBOX_OWNER_NONE)
274 return -EBUSY;
275
276 /*
277 * If there has been no recent transaction and no one owns the mailbox,
278 * we should acquire it in under 1ms. However, if we've accessed it
279 * recently it may take up to 2.1 seconds to acquire it again.
280 */
281 do {
282 /* Write first qword of payload */
283 writeq(info->payload[0], priv->mbox_addr);
284
285 /* Check for ownership */
286 ret = readq_poll_timeout(priv->control_addr, control,
287 FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_INBAND,
288 MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US);
289
290 if (FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_NONE &&
291 retries++ < MBOX_ACQUIRE_NUM_RETRIES) {
292 msleep(MBOX_ACQUIRE_RETRY_DELAY_MS);
293 continue;
294 }
295
296 /* Either we got it or someone else did. */
297 break;
298 } while (true);
299
300 return ret;
301 }
302
sdsi_mbox_write(struct sdsi_priv * priv,struct sdsi_mbox_info * info)303 static int sdsi_mbox_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info)
304 {
305 int ret;
306
307 lockdep_assert_held(&priv->mb_lock);
308
309 ret = sdsi_mbox_acquire(priv, info);
310 if (ret)
311 return ret;
312
313 return sdsi_mbox_cmd_write(priv, info);
314 }
315
sdsi_mbox_read(struct sdsi_priv * priv,struct sdsi_mbox_info * info,size_t * data_size)316 static int sdsi_mbox_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info, size_t *data_size)
317 {
318 int ret;
319
320 lockdep_assert_held(&priv->mb_lock);
321
322 ret = sdsi_mbox_acquire(priv, info);
323 if (ret)
324 return ret;
325
326 return sdsi_mbox_cmd_read(priv, info, data_size);
327 }
328
sdsi_provision(struct sdsi_priv * priv,char * buf,size_t count,enum sdsi_command command)329 static ssize_t sdsi_provision(struct sdsi_priv *priv, char *buf, size_t count,
330 enum sdsi_command command)
331 {
332 struct sdsi_mbox_info info;
333 int ret;
334
335 if (!priv->sdsi_enabled)
336 return -EPERM;
337
338 if (count > (SDSI_SIZE_WRITE_MSG - SDSI_SIZE_CMD))
339 return -EOVERFLOW;
340
341 /* Qword aligned message + command qword */
342 info.size = round_up(count, SDSI_SIZE_CMD) + SDSI_SIZE_CMD;
343
344 info.payload = kzalloc(info.size, GFP_KERNEL);
345 if (!info.payload)
346 return -ENOMEM;
347
348 /* Copy message to payload buffer */
349 memcpy(info.payload, buf, count);
350
351 /* Command is last qword of payload buffer */
352 info.payload[(info.size - SDSI_SIZE_CMD) / SDSI_SIZE_CMD] = command;
353
354 ret = mutex_lock_interruptible(&priv->mb_lock);
355 if (ret)
356 goto free_payload;
357 ret = sdsi_mbox_write(priv, &info);
358 mutex_unlock(&priv->mb_lock);
359
360 free_payload:
361 kfree(info.payload);
362
363 if (ret)
364 return ret;
365
366 return count;
367 }
368
provision_akc_write(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t off,size_t count)369 static ssize_t provision_akc_write(struct file *filp, struct kobject *kobj,
370 struct bin_attribute *attr, char *buf, loff_t off,
371 size_t count)
372 {
373 struct device *dev = kobj_to_dev(kobj);
374 struct sdsi_priv *priv = dev_get_drvdata(dev);
375
376 if (off)
377 return -ESPIPE;
378
379 return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_AKC);
380 }
381 static BIN_ATTR_WO(provision_akc, SDSI_SIZE_WRITE_MSG);
382
provision_cap_write(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t off,size_t count)383 static ssize_t provision_cap_write(struct file *filp, struct kobject *kobj,
384 struct bin_attribute *attr, char *buf, loff_t off,
385 size_t count)
386 {
387 struct device *dev = kobj_to_dev(kobj);
388 struct sdsi_priv *priv = dev_get_drvdata(dev);
389
390 if (off)
391 return -ESPIPE;
392
393 return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_CAP);
394 }
395 static BIN_ATTR_WO(provision_cap, SDSI_SIZE_WRITE_MSG);
396
state_certificate_read(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t off,size_t count)397 static long state_certificate_read(struct file *filp, struct kobject *kobj,
398 struct bin_attribute *attr, char *buf, loff_t off,
399 size_t count)
400 {
401 struct device *dev = kobj_to_dev(kobj);
402 struct sdsi_priv *priv = dev_get_drvdata(dev);
403 u64 command = SDSI_CMD_READ_STATE;
404 struct sdsi_mbox_info info;
405 size_t size;
406 int ret;
407
408 if (!priv->sdsi_enabled)
409 return -EPERM;
410
411 if (off)
412 return 0;
413
414 /* Buffer for return data */
415 info.buffer = kmalloc(SDSI_SIZE_READ_MSG, GFP_KERNEL);
416 if (!info.buffer)
417 return -ENOMEM;
418
419 info.payload = &command;
420 info.size = sizeof(command);
421
422 ret = mutex_lock_interruptible(&priv->mb_lock);
423 if (ret)
424 goto free_buffer;
425 ret = sdsi_mbox_read(priv, &info, &size);
426 mutex_unlock(&priv->mb_lock);
427 if (ret < 0)
428 goto free_buffer;
429
430 if (size > count)
431 size = count;
432
433 memcpy(buf, info.buffer, size);
434
435 free_buffer:
436 kfree(info.buffer);
437
438 if (ret)
439 return ret;
440
441 return size;
442 }
443 static BIN_ATTR(state_certificate, 0400, state_certificate_read, NULL, SDSI_SIZE_READ_MSG);
444
registers_read(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t off,size_t count)445 static ssize_t registers_read(struct file *filp, struct kobject *kobj,
446 struct bin_attribute *attr, char *buf, loff_t off,
447 size_t count)
448 {
449 struct device *dev = kobj_to_dev(kobj);
450 struct sdsi_priv *priv = dev_get_drvdata(dev);
451 void __iomem *addr = priv->regs_addr;
452
453 memcpy_fromio(buf, addr + off, count);
454
455 return count;
456 }
457 static BIN_ATTR(registers, 0400, registers_read, NULL, SDSI_SIZE_REGS);
458
459 static struct bin_attribute *sdsi_bin_attrs[] = {
460 &bin_attr_registers,
461 &bin_attr_state_certificate,
462 &bin_attr_provision_akc,
463 &bin_attr_provision_cap,
464 NULL
465 };
466
guid_show(struct device * dev,struct device_attribute * attr,char * buf)467 static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf)
468 {
469 struct sdsi_priv *priv = dev_get_drvdata(dev);
470
471 return sysfs_emit(buf, "0x%x\n", priv->guid);
472 }
473 static DEVICE_ATTR_RO(guid);
474
475 static struct attribute *sdsi_attrs[] = {
476 &dev_attr_guid.attr,
477 NULL
478 };
479
480 static const struct attribute_group sdsi_group = {
481 .attrs = sdsi_attrs,
482 .bin_attrs = sdsi_bin_attrs,
483 };
484 __ATTRIBUTE_GROUPS(sdsi);
485
sdsi_map_mbox_registers(struct sdsi_priv * priv,struct pci_dev * parent,struct disc_table * disc_table,struct resource * disc_res)486 static int sdsi_map_mbox_registers(struct sdsi_priv *priv, struct pci_dev *parent,
487 struct disc_table *disc_table, struct resource *disc_res)
488 {
489 u32 access_type = FIELD_GET(DT_ACCESS_TYPE, disc_table->access_info);
490 u32 size = FIELD_GET(DT_SIZE, disc_table->access_info);
491 u32 tbir = FIELD_GET(DT_TBIR, disc_table->offset);
492 u32 offset = DT_OFFSET(disc_table->offset);
493 u32 features_offset;
494 struct resource res = {};
495
496 /* Starting location of SDSi MMIO region based on access type */
497 switch (access_type) {
498 case ACCESS_TYPE_LOCAL:
499 if (tbir) {
500 dev_err(priv->dev, "Unsupported BAR index %u for access type %u\n",
501 tbir, access_type);
502 return -EINVAL;
503 }
504
505 /*
506 * For access_type LOCAL, the base address is as follows:
507 * base address = end of discovery region + base offset + 1
508 */
509 res.start = disc_res->end + offset + 1;
510 break;
511
512 case ACCESS_TYPE_BARID:
513 res.start = pci_resource_start(parent, tbir) + offset;
514 break;
515
516 default:
517 dev_err(priv->dev, "Unrecognized access_type %u\n", access_type);
518 return -EINVAL;
519 }
520
521 res.end = res.start + size * sizeof(u32) - 1;
522 res.flags = IORESOURCE_MEM;
523
524 priv->control_addr = devm_ioremap_resource(priv->dev, &res);
525 if (IS_ERR(priv->control_addr))
526 return PTR_ERR(priv->control_addr);
527
528 priv->mbox_addr = priv->control_addr + SDSI_SIZE_CONTROL;
529 priv->regs_addr = priv->mbox_addr + SDSI_SIZE_MAILBOX;
530
531 features_offset = readq(priv->regs_addr + SDSI_ENABLED_FEATURES_OFFSET);
532 priv->sdsi_enabled = !!(features_offset & SDSI_ENABLED);
533
534 return 0;
535 }
536
sdsi_probe(struct auxiliary_device * auxdev,const struct auxiliary_device_id * id)537 static int sdsi_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id)
538 {
539 struct intel_vsec_device *intel_cap_dev = auxdev_to_ivdev(auxdev);
540 struct disc_table disc_table;
541 struct resource *disc_res;
542 void __iomem *disc_addr;
543 struct sdsi_priv *priv;
544 int ret;
545
546 priv = devm_kzalloc(&auxdev->dev, sizeof(*priv), GFP_KERNEL);
547 if (!priv)
548 return -ENOMEM;
549
550 priv->dev = &auxdev->dev;
551 mutex_init(&priv->mb_lock);
552 auxiliary_set_drvdata(auxdev, priv);
553
554 /* Get the SDSi discovery table */
555 disc_res = &intel_cap_dev->resource[0];
556 disc_addr = devm_ioremap_resource(&auxdev->dev, disc_res);
557 if (IS_ERR(disc_addr))
558 return PTR_ERR(disc_addr);
559
560 memcpy_fromio(&disc_table, disc_addr, DISC_TABLE_SIZE);
561
562 priv->guid = disc_table.guid;
563
564 /* Map the SDSi mailbox registers */
565 ret = sdsi_map_mbox_registers(priv, intel_cap_dev->pcidev, &disc_table, disc_res);
566 if (ret)
567 return ret;
568
569 return 0;
570 }
571
572 static const struct auxiliary_device_id sdsi_aux_id_table[] = {
573 { .name = "intel_vsec.sdsi" },
574 {}
575 };
576 MODULE_DEVICE_TABLE(auxiliary, sdsi_aux_id_table);
577
578 static struct auxiliary_driver sdsi_aux_driver = {
579 .driver = {
580 .dev_groups = sdsi_groups,
581 },
582 .id_table = sdsi_aux_id_table,
583 .probe = sdsi_probe,
584 /* No remove. All resources are handled under devm */
585 };
586 module_auxiliary_driver(sdsi_aux_driver);
587
588 MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
589 MODULE_DESCRIPTION("Intel Software Defined Silicon driver");
590 MODULE_LICENSE("GPL");
591