Skip to content

Commit

Permalink
hw-mgmt: kernel: patches: 5.10: Add upstream bugfix patches
Browse files Browse the repository at this point in the history
Add upstream bugfix patches for crypto CCP driver

Bug #3896662

Signed-off-by: Felix Radensky <[email protected]>
  • Loading branch information
felixradensky committed Aug 25, 2024
1 parent f05174c commit 050edda
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 0 deletions.
2 changes: 2 additions & 0 deletions recipes-kernel/linux/Patch_Status_Table.txt
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ Kernel-5.10
|0334-platform-mellanox-mlx-platform-Fix-FAN-tacho-reading.patch | | Bugfix upstream | | MQM9700 |
|0335-platform-mellanox-Introduce-support-of-Nvidia-smart-.patch | | Downstream accepted | | SN4280 |
|0336-hwmon-pmbus-Add-support-for-MPS-Multi-phase-mp2855-c.patch | | Feature pending; os[sonic,opt,nvos,dvs] | | |
|0337-crypto-ccp-Reject-SEV-commands-with-mismatching-comm.patch | d5760dee127b | Bugfix upstream | 5.1.191 | |
|0338-crypto-ccp-Play-nice-with-vmalloc-d-memory-for-SEV-c.patch | 8347b99473a3 | Bugfix upstream | 5.1.191 | |
|7001-mctp-Add-MCTP-base.patch | | Downstream | | MCTP |
|7002-mctp-Add-base-socket-protocol-definitions.patch | | Downstream | | MCTP |
|7003-mctp-Add-base-packet-definitions.patch | | Downstream | | MCTP |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
From 1f988ce6e44f0f8222c366804144f9288fdc6552 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <[email protected]>
Date: Tue, 6 Apr 2021 15:49:47 -0700
Subject: [PATCH] crypto: ccp: Reject SEV commands with mismatching command
buffer

commit d5760dee127bf6f390b05e747369d7c37ae1a7b8 upstream.

WARN on and reject SEV commands that provide a valid data pointer, but do
not have a known, non-zero length. And conversely, reject commands that
take a command buffer but none is provided (data is null).

Aside from sanity checking input, disallowing a non-null pointer without
a non-zero size will allow a future patch to cleanly handle vmalloc'd
data by copying the data to an internal __pa() friendly buffer.

Note, this also effectively prevents callers from using commands that
have a non-zero length and are not known to the kernel. This is not an
explicit goal, but arguably the side effect is a good thing from the
kernel's perspective.

Cc: Brijesh Singh <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Tom Lendacky <[email protected]>
Signed-off-by: Sean Christopherson <[email protected]>
Message-Id: <[email protected]>
Reviewed-by: Brijesh Singh <[email protected]>
Acked-by: Tom Lendacky <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Cc: Ben Hutchings <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/crypto/ccp/sev-dev.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index 856d867f46eb..0286b6d5de17 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -156,6 +156,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
struct sev_device *sev;
unsigned int phys_lsb, phys_msb;
unsigned int reg, ret = 0;
+ int buf_len;

if (!psp || !psp->sev_data)
return -ENODEV;
@@ -165,6 +166,10 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)

sev = psp->sev_data;

+ buf_len = sev_cmd_buffer_len(cmd);
+ if (WARN_ON_ONCE(!data != !buf_len))
+ return -EINVAL;
+
if (data && WARN_ON_ONCE(!virt_addr_valid(data)))
return -EINVAL;

@@ -176,7 +181,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
cmd, phys_msb, phys_lsb, psp_timeout);

print_hex_dump_debug("(in): ", DUMP_PREFIX_OFFSET, 16, 2, data,
- sev_cmd_buffer_len(cmd), false);
+ buf_len, false);

iowrite32(phys_lsb, sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg);
iowrite32(phys_msb, sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg);
@@ -212,7 +217,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
}

print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
- sev_cmd_buffer_len(cmd), false);
+ buf_len, false);

return ret;
}
--
2.44.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
From 81df7153f011279ab2e6daad156776d234f9db0a Mon Sep 17 00:00:00 2001
From: Sean Christopherson <[email protected]>
Date: Tue, 6 Apr 2021 15:49:48 -0700
Subject: [PATCH] crypto: ccp: Play nice with vmalloc'd memory for SEV command
structs

commit 8347b99473a313be6549a5b940bc3c56a71be81c upstream.

Copy the incoming @data comman to an internal buffer so that callers can
put SEV command buffers on the stack without running afoul of
CONFIG_VMAP_STACK=y, i.e. without bombing on vmalloc'd pointers. As of
today, the largest supported command takes a 68 byte buffer, i.e. pretty
much every command can be put on the stack. Because sev_cmd_mutex is
held for the entirety of a transaction, only a single bounce buffer is
required.

Use the internal buffer unconditionally, as the majority of in-kernel
users will soon switch to using the stack. At that point, checking
virt_addr_valid() becomes (negligible) overhead in most cases, and
supporting both paths slightly increases complexity. Since the commands
are all quite small, the cost of the copies is insignificant compared to
the latency of communicating with the PSP.

Allocate a full page for the buffer as opportunistic preparation for
SEV-SNP, which requires the command buffer to be in firmware state for
commands that trigger memory writes from the PSP firmware. Using a full
page now will allow SEV-SNP support to simply transition the page as
needed.

Cc: Brijesh Singh <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Tom Lendacky <[email protected]>
Cc: Christophe Leroy <[email protected]>
Signed-off-by: Sean Christopherson <[email protected]>
Message-Id: <[email protected]>
Reviewed-by: Brijesh Singh <[email protected]>
Acked-by: Tom Lendacky <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Cc: Ben Hutchings <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/crypto/ccp/sev-dev.c | 28 +++++++++++++++++++++++-----
drivers/crypto/ccp/sev-dev.h | 2 ++
2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index 0286b6d5de17..8e2672ec6e03 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -170,12 +170,17 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
if (WARN_ON_ONCE(!data != !buf_len))
return -EINVAL;

- if (data && WARN_ON_ONCE(!virt_addr_valid(data)))
- return -EINVAL;
+ /*
+ * Copy the incoming data to driver's scratch buffer as __pa() will not
+ * work for some memory, e.g. vmalloc'd addresses, and @data may not be
+ * physically contiguous.
+ */
+ if (data)
+ memcpy(sev->cmd_buf, data, buf_len);

/* Get the physical address of the command buffer */
- phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0;
- phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0;
+ phys_lsb = data ? lower_32_bits(__psp_pa(sev->cmd_buf)) : 0;
+ phys_msb = data ? upper_32_bits(__psp_pa(sev->cmd_buf)) : 0;

dev_dbg(sev->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n",
cmd, phys_msb, phys_lsb, psp_timeout);
@@ -219,6 +224,13 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
buf_len, false);

+ /*
+ * Copy potential output from the PSP back to data. Do this even on
+ * failure in case the caller wants to glean something from the error.
+ */
+ if (data)
+ memcpy(data, sev->cmd_buf, buf_len);
+
return ret;
}

@@ -979,6 +991,10 @@ int sev_dev_init(struct psp_device *psp)
if (!sev)
goto e_err;

+ sev->cmd_buf = (void *)devm_get_free_pages(dev, GFP_KERNEL, 0);
+ if (!sev->cmd_buf)
+ goto e_sev;
+
psp->sev_data = sev;

sev->dev = dev;
@@ -990,7 +1006,7 @@ int sev_dev_init(struct psp_device *psp)
if (!sev->vdata) {
ret = -ENODEV;
dev_err(dev, "sev: missing driver data\n");
- goto e_sev;
+ goto e_buf;
}

psp_set_sev_irq_handler(psp, sev_irq_handler, sev);
@@ -1005,6 +1021,8 @@ int sev_dev_init(struct psp_device *psp)

e_irq:
psp_clear_sev_irq_handler(psp);
+e_buf:
+ devm_free_pages(dev, (unsigned long)sev->cmd_buf);
e_sev:
devm_kfree(dev, sev);
e_err:
diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h
index 3b0cd0f854df..0fd21433f627 100644
--- a/drivers/crypto/ccp/sev-dev.h
+++ b/drivers/crypto/ccp/sev-dev.h
@@ -51,6 +51,8 @@ struct sev_device {
u8 api_major;
u8 api_minor;
u8 build;
+
+ void *cmd_buf;
};

int sev_dev_init(struct psp_device *psp);
--
2.44.0

0 comments on commit 050edda

Please sign in to comment.