-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
hw-mgmt: kernel: patches: 5.10: Add upstream bugfix patches
Add upstream bugfix patches for crypto CCP driver Bug #3896662 Signed-off-by: Felix Radensky <[email protected]>
- Loading branch information
1 parent
f05174c
commit 050edda
Showing
3 changed files
with
211 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
...s-kernel/linux/linux-5.10/0337-crypto-ccp-Reject-SEV-commands-with-mismatching-comm.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
130 changes: 130 additions & 0 deletions
130
...s-kernel/linux/linux-5.10/0338-crypto-ccp-Play-nice-with-vmalloc-d-memory-for-SEV-c.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|