|
23 | 23 |
|
24 | 24 | /* Function and variable pointers for hooks */ |
25 | 25 | struct hygon_psp_hooks_table hygon_psp_hooks; |
| 26 | +static unsigned int psp_int_rcvd; |
| 27 | +wait_queue_head_t psp_int_queue; |
26 | 28 |
|
27 | 29 | static struct psp_misc_dev *psp_misc; |
28 | 30 | #define HYGON_PSP_IOC_TYPE 'H' |
@@ -533,65 +535,69 @@ int fixup_hygon_psp_caps(struct psp_device *psp) |
533 | 535 | return 0; |
534 | 536 | } |
535 | 537 |
|
| 538 | +static int psp_wait_cmd_ioc(struct psp_device *psp, |
| 539 | + unsigned int *reg, unsigned int timeout) |
| 540 | +{ |
| 541 | + int ret; |
| 542 | + |
| 543 | + ret = wait_event_timeout(psp_int_queue, |
| 544 | + psp_int_rcvd, timeout * HZ); |
| 545 | + if (!ret) |
| 546 | + return -ETIMEDOUT; |
| 547 | + |
| 548 | + *reg = ioread32(psp->io_regs + psp->vdata->sev->cmdresp_reg); |
| 549 | + |
| 550 | + return 0; |
| 551 | +} |
| 552 | + |
536 | 553 | static int __psp_do_cmd_locked(int cmd, void *data, int *psp_ret) |
537 | 554 | { |
538 | 555 | struct psp_device *psp = psp_master; |
539 | | - struct sev_device *sev; |
540 | 556 | unsigned int phys_lsb, phys_msb; |
541 | 557 | unsigned int reg, ret = 0; |
542 | 558 |
|
543 | | - if (!psp || !psp->sev_data || !hygon_psp_hooks.sev_dev_hooks_installed) |
| 559 | + if (!psp || !hygon_psp_hooks.sev_dev_hooks_installed) |
544 | 560 | return -ENODEV; |
545 | 561 |
|
546 | 562 | if (*hygon_psp_hooks.psp_dead) |
547 | 563 | return -EBUSY; |
548 | 564 |
|
549 | | - sev = psp->sev_data; |
550 | | - |
551 | 565 | /* Get the physical address of the command buffer */ |
552 | 566 | phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0; |
553 | 567 | phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0; |
554 | 568 |
|
555 | | - dev_dbg(sev->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n", |
556 | | - cmd, phys_msb, phys_lsb, *hygon_psp_hooks.psp_timeout); |
557 | | - |
558 | | - print_hex_dump_debug("(in): ", DUMP_PREFIX_OFFSET, 16, 2, data, |
559 | | - hygon_psp_hooks.sev_cmd_buffer_len(cmd), false); |
| 569 | + dev_dbg(psp->dev, "psp command id %#x buffer 0x%08x%08x timeout %us\n", |
| 570 | + cmd, phys_msb, phys_lsb, *hygon_psp_hooks.psp_cmd_timeout); |
560 | 571 |
|
561 | | - iowrite32(phys_lsb, sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg); |
562 | | - iowrite32(phys_msb, sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg); |
| 572 | + iowrite32(phys_lsb, psp->io_regs + psp->vdata->sev->cmdbuff_addr_lo_reg); |
| 573 | + iowrite32(phys_msb, psp->io_regs + psp->vdata->sev->cmdbuff_addr_hi_reg); |
563 | 574 |
|
564 | | - sev->int_rcvd = 0; |
| 575 | + psp_int_rcvd = 0; |
565 | 576 |
|
566 | 577 | reg = FIELD_PREP(SEV_CMDRESP_CMD, cmd) | SEV_CMDRESP_IOC; |
567 | | - iowrite32(reg, sev->io_regs + sev->vdata->cmdresp_reg); |
| 578 | + iowrite32(reg, psp->io_regs + psp->vdata->sev->cmdresp_reg); |
568 | 579 |
|
569 | 580 | /* wait for command completion */ |
570 | | - ret = hygon_psp_hooks.sev_wait_cmd_ioc(sev, ®, *hygon_psp_hooks.psp_timeout); |
| 581 | + ret = psp_wait_cmd_ioc(psp, ®, *hygon_psp_hooks.psp_cmd_timeout); |
571 | 582 | if (ret) { |
572 | 583 | if (psp_ret) |
573 | 584 | *psp_ret = 0; |
574 | 585 |
|
575 | | - dev_err(sev->dev, "sev command %#x timed out, disabling PSP\n", cmd); |
| 586 | + dev_err(psp->dev, "psp command %#x timed out, disabling PSP\n", cmd); |
576 | 587 | *hygon_psp_hooks.psp_dead = true; |
577 | 588 |
|
578 | 589 | return ret; |
579 | 590 | } |
580 | 591 |
|
581 | | - *hygon_psp_hooks.psp_timeout = *hygon_psp_hooks.psp_cmd_timeout; |
582 | | - |
583 | 592 | if (psp_ret) |
584 | 593 | *psp_ret = FIELD_GET(PSP_CMDRESP_STS, reg); |
585 | 594 |
|
586 | 595 | if (FIELD_GET(PSP_CMDRESP_STS, reg)) { |
587 | | - dev_dbg(sev->dev, "sev command %#x failed (%#010lx)\n", |
| 596 | + dev_dbg(psp->dev, "psp command %#x failed (%#010lx)\n", |
588 | 597 | cmd, FIELD_GET(PSP_CMDRESP_STS, reg)); |
589 | 598 | ret = -EIO; |
590 | 599 | } |
591 | 600 |
|
592 | | - print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data, |
593 | | - hygon_psp_hooks.sev_cmd_buffer_len(cmd), false); |
594 | | - |
595 | 601 | return ret; |
596 | 602 | } |
597 | 603 |
|
@@ -689,8 +695,12 @@ static irqreturn_t psp_irq_handler_hygon(int irq, void *data) |
689 | 695 | /* Check if it is SEV command completion: */ |
690 | 696 | reg = ioread32(psp->io_regs + psp->vdata->sev->cmdresp_reg); |
691 | 697 | if (reg & PSP_CMDRESP_RESP) { |
692 | | - sev->int_rcvd = 1; |
693 | | - wake_up(&sev->int_queue); |
| 698 | + psp_int_rcvd = 1; |
| 699 | + wake_up(&psp_int_queue); |
| 700 | + if (sev != NULL) { |
| 701 | + sev->int_rcvd = 1; |
| 702 | + wake_up(&sev->int_queue); |
| 703 | + } |
694 | 704 | } |
695 | 705 | } |
696 | 706 |
|
|
0 commit comments