From: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
To: linux-kernel@vger.kernel.org
Cc: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>,
"Brijesh Singh" <brijesh.singh@amd.com>,
"Tom Lendacky" <thomas.lendacky@amd.com>,
"Kalra, Ashish" <ashish.kalra@amd.com>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Ingo Molnar" <mingo@redhat.com>,
"Borislav Petkov" <bp@alien8.de>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
x86@kernel.org
Subject: [PATCH v3 4/8] x86/psp: Add IRQ support
Date: Mon, 20 Mar 2023 19:19:52 +0000 [thread overview]
Message-ID: <20230320191956.1354602-5-jpiotrowski@linux.microsoft.com> (raw)
In-Reply-To: <20230320191956.1354602-1-jpiotrowski@linux.microsoft.com>
The ACPI PSP device provides a mailbox irq that needs to be configured
through the ACPI mailbox register first. This requires passing a CPU
vector and physical CPU id and then enabling interrupt delivery.
Allocate the irq directly from the default irq domain
(x86_vector_domain) to get access to the required information. By
passing a cpumask through irq_alloc_info the vector is immediately
allocated (and not later during activation) and can be retrieved.
Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
---
arch/x86/kernel/psp.c | 185 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 181 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/psp.c b/arch/x86/kernel/psp.c
index 64f3bfc5c9ff..fc059cf3b25c 100644
--- a/arch/x86/kernel/psp.c
+++ b/arch/x86/kernel/psp.c
@@ -1,8 +1,182 @@
// SPDX-License-Identifier: GPL-2.0-only
-
+#define pr_fmt(fmt) "psp: " fmt
#include <linux/platform_data/psp.h>
#include <linux/platform_device.h>
+#include <linux/iopoll.h>
+#include <linux/irq.h>
#include <asm/hypervisor.h>
+#include <asm/irqdomain.h>
+
+#define PSP_ACPI_CMDID_SHIFT 16
+#define PSP_ACPI_STATUS_SHIFT 26
+#define PSP_ACPI_STATUS_MASK GENMASK(30, 26)
+#define PSP_ACPI_RESPONSE_BIT BIT(31)
+#define PSP_ACPI_VECTOR_MASK GENMASK(7, 0)
+#define PSP_ACPI_MBOX_IRQID_SHIFT 10
+#define PSP_ACPI_IRQ_EN_BIT BIT(0)
+#define PSP_ACPI_IRQ_EN_MBOX_IRQID_SHIFT 10
+
+#define PSP_CMD_DELAY_US 2
+#define PSP_CMD_TIMEOUT_US 10000
+
+enum ASP_CMDID {
+ ASP_CMDID_PART1 = 0x82,
+ ASP_CMDID_PART2 = 0x83,
+ ASP_CMDID_PART3 = 0x84,
+ ASP_CMDID_IRQ_EN = 0x85,
+};
+
+enum ASP_CMD_STATUS {
+ ASP_CMD_STATUS_SUCCESS = 0x0,
+ ASP_CMD_STATUS_INVALID_CMD = 0x1,
+ ASP_CMD_STATUS_INVALID_PARAM = 0x2,
+ ASP_CMD_STATUS_INVALID_FW_STATE = 0x3,
+ ASP_CMD_STATUS_FAILURE = 0x1F,
+};
+
+struct psp_irq_data {
+ void __iomem *base;
+ u8 mbox_irq_id;
+ int acpi_cmd_resp_reg;
+};
+
+static int psp_sync_cmd(void __iomem *reg, u8 cmd, u16 data)
+{
+ u32 val;
+ int err;
+
+ val = data;
+ val |= cmd << PSP_ACPI_CMDID_SHIFT;
+ writel(val, reg);
+ err = readl_poll_timeout_atomic(reg, val, val & PSP_ACPI_RESPONSE_BIT, PSP_CMD_DELAY_US,
+ PSP_CMD_TIMEOUT_US);
+ if (err)
+ return err;
+
+ return (val & PSP_ACPI_STATUS_MASK) >> PSP_ACPI_STATUS_SHIFT;
+}
+
+static int psp_set_irq_enable(struct psp_irq_data *data, bool irq_en)
+{
+ void __iomem *reg = data->base + data->acpi_cmd_resp_reg;
+ u16 val = 0;
+ int err;
+
+ if (data->mbox_irq_id > 63)
+ return -EINVAL;
+
+ val = irq_en ? PSP_ACPI_IRQ_EN_BIT : 0;
+ val |= data->mbox_irq_id << PSP_ACPI_IRQ_EN_MBOX_IRQID_SHIFT;
+ err = psp_sync_cmd(reg, ASP_CMDID_IRQ_EN, val);
+ if (err != ASP_CMD_STATUS_SUCCESS) {
+ pr_err("ASP_CMDID_IRQ_EN failed: %d\n", err);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int psp_configure_irq(struct psp_irq_data *data, unsigned int vector, unsigned int cpu)
+{
+ void __iomem *reg = data->base + data->acpi_cmd_resp_reg;
+ unsigned int dest_cpu = cpu_physical_id(cpu);
+ u16 part1, part2, part3;
+ int err;
+
+ if (data->mbox_irq_id > 63)
+ return -EINVAL;
+
+ part1 = dest_cpu;
+ part2 = dest_cpu >> 16;
+ part3 = vector & PSP_ACPI_VECTOR_MASK;
+ part3 |= data->mbox_irq_id << PSP_ACPI_MBOX_IRQID_SHIFT;
+
+ err = psp_sync_cmd(reg, ASP_CMDID_PART1, part1);
+ if (err != ASP_CMD_STATUS_SUCCESS) {
+ pr_err("ASP_CMDID_PART1 failed: %d\n", err);
+ return -EIO;
+ }
+ err = psp_sync_cmd(reg, ASP_CMDID_PART2, part2);
+ if (err != ASP_CMD_STATUS_SUCCESS) {
+ pr_err("ASP_CMDID_PART2 failed: %d\n", err);
+ return -EIO;
+ }
+ err = psp_sync_cmd(reg, ASP_CMDID_PART3, part3);
+ if (err != ASP_CMD_STATUS_SUCCESS) {
+ pr_err("ASP_CMDID_PART3 failed: %d\n", err);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int psp_init_irq(const struct psp_platform_data *pdata, const struct resource *reg,
+ struct resource *irq)
+{
+ struct psp_irq_data pspirqd;
+ struct irq_alloc_info info;
+ struct irq_data *data;
+ struct irq_cfg *cfg;
+ void __iomem *base;
+ int virq;
+ int err;
+
+ base = ioremap(reg->start, resource_size(reg));
+ if (!base)
+ return -ENOMEM;
+
+ pspirqd.mbox_irq_id = pdata->mbox_irq_id;
+ pspirqd.acpi_cmd_resp_reg = pdata->acpi_cmd_resp_reg;
+ pspirqd.base = base;
+ init_irq_alloc_info(&info, cpumask_of(0));
+ virq = irq_domain_alloc_irqs(NULL, 1, NUMA_NO_NODE, &info);
+ if (virq <= 0) {
+ pr_err("failed to allocate vector: %d\n", virq);
+ err = -ENOMEM;
+ goto unmap;
+ }
+ irq_set_handler(virq, handle_edge_irq);
+
+ data = irq_get_irq_data(virq);
+ if (!data) {
+ pr_err("no irq data\n");
+ err = -ENODEV;
+ goto freeirq;
+ }
+
+ cfg = irqd_cfg(data);
+ if (!cfg) {
+ pr_err("no irq cfg\n");
+ err = -ENODEV;
+ goto freeirq;
+ }
+
+ err = psp_configure_irq(&pspirqd, cfg->vector, 0);
+ if (err) {
+ pr_err("failed to configure irq: %d\n", err);
+ goto freeirq;
+ }
+
+ err = psp_set_irq_enable(&pspirqd, true);
+ if (err) {
+ pr_err("failed to enable irq: %d\n", err);
+ goto freeirq;
+ }
+
+ *irq = (struct resource)DEFINE_RES_IRQ(virq);
+
+ iounmap(base);
+
+ return 0;
+
+freeirq:
+ irq_domain_free_irqs(virq, 1);
+
+unmap:
+ iounmap(base);
+
+ return err;
+}
static struct platform_device psp_device = {
.name = "psp",
@@ -12,7 +186,7 @@ static struct platform_device psp_device = {
static int __init psp_init_platform_device(void)
{
struct psp_platform_data pdata = {};
- struct resource res[1];
+ struct resource res[2];
int err;
/*
@@ -24,10 +198,13 @@ static int __init psp_init_platform_device(void)
if (!hypervisor_is_type(X86_HYPER_MS_HYPERV))
return -ENODEV;
- err = acpi_parse_aspt(res, &pdata);
+ err = acpi_parse_aspt(&res[0], &pdata);
+ if (err)
+ return err;
+ err = psp_init_irq(&pdata, &res[0], &res[1]);
if (err)
return err;
- err = platform_device_add_resources(&psp_device, res, 1);
+ err = platform_device_add_resources(&psp_device, res, 2);
if (err)
return err;
err = platform_device_add_data(&psp_device, &pdata, sizeof(pdata));
--
2.34.1
next prev parent reply other threads:[~2023-03-20 19:29 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-20 19:19 [PATCH v3 0/8] Support ACPI PSP on Hyper-V Jeremi Piotrowski
2023-03-20 19:19 ` [PATCH v3 1/8] include/acpi: add definition of ASPT table Jeremi Piotrowski
2023-03-20 19:19 ` [PATCH v3 2/8] ACPI: ASPT: Add helper to parse table Jeremi Piotrowski
2023-03-20 19:19 ` [PATCH v3 3/8] x86/psp: Register PSP platform device when ASP table is present Jeremi Piotrowski
2023-03-20 19:25 ` Borislav Petkov
2023-03-20 19:37 ` Jeremi Piotrowski
2023-03-20 20:03 ` Borislav Petkov
2023-03-20 20:18 ` Jeremi Piotrowski
2023-03-20 21:03 ` Borislav Petkov
2023-03-21 14:15 ` Jeremi Piotrowski
2023-03-20 19:19 ` Jeremi Piotrowski [this message]
2023-03-21 10:31 ` [PATCH v3 4/8] x86/psp: Add IRQ support Thomas Gleixner
2023-03-21 19:16 ` Jeremi Piotrowski
2023-03-22 10:07 ` Thomas Gleixner
2023-03-28 18:29 ` Jeremi Piotrowski
2023-03-20 19:19 ` [PATCH v3 5/8] crypto: cpp - Bind to psp platform device on x86 Jeremi Piotrowski
2023-03-20 19:19 ` [PATCH v3 6/8] crypto: ccp - Add vdata for platform device Jeremi Piotrowski
2023-03-20 19:19 ` [PATCH v3 7/8] crypto: ccp - Skip DMA coherency check for platform psp Jeremi Piotrowski
2023-03-20 19:19 ` [PATCH v3 8/8] crypto: ccp - Allow platform device to be psp master device Jeremi Piotrowski
2023-03-22 15:46 ` [PATCH v3 0/8] Support ACPI PSP on Hyper-V Borislav Petkov
2023-03-22 17:33 ` Jeremi Piotrowski
2023-03-22 18:15 ` Borislav Petkov
2023-03-23 14:46 ` Jeremi Piotrowski
2023-03-23 15:23 ` Borislav Petkov
2023-03-23 16:11 ` Jeremi Piotrowski
2023-03-23 16:34 ` Borislav Petkov
2023-03-24 17:10 ` Jeremi Piotrowski
2023-04-02 15:44 ` Borislav Petkov
2023-04-03 6:20 ` Thomas Gleixner
2023-04-05 7:56 ` Jeremi Piotrowski
2023-04-11 15:10 ` Jeremi Piotrowski
2023-04-13 21:53 ` Thomas Gleixner
2023-04-05 8:10 ` Jeremi Piotrowski
2023-04-05 8:50 ` Jeremi Piotrowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230320191956.1354602-5-jpiotrowski@linux.microsoft.com \
--to=jpiotrowski@linux.microsoft.com \
--cc=ashish.kalra@amd.com \
--cc=bp@alien8.de \
--cc=brijesh.singh@amd.com \
--cc=dave.hansen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=thomas.lendacky@amd.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).