Skip to content

Commit 69dcb1e

Browse files
tlendackybp3tk0v
authored andcommitted
x86/sev: Put PSC struct on the stack in prep for unaccepted memory support
In advance of providing support for unaccepted memory, switch from using kmalloc() for allocating the Page State Change (PSC) structure to using a local variable that lives on the stack. This is needed to avoid a possible recursive call into set_pages_state() if the kmalloc() call requires (more) memory to be accepted, which would result in a hang. The current size of the PSC struct is 2,032 bytes. To make the struct more stack friendly, reduce the number of PSC entries from 253 down to 64, resulting in a size of 520 bytes. This is a nice compromise on struct size and total PSC requests while still allowing parallel PSC operations across vCPUs. If the reduction in PSC entries results in any kind of performance issue (that is not seen at the moment), use of a larger static PSC struct, with fallback to the smaller stack version, can be investigated. For more background info on this decision, see the subthread in the Link: tag below. Signed-off-by: Tom Lendacky <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Link: https://lore.kernel.org/lkml/658c455c40e8950cb046dd885dd19dc1c52d060a.1659103274.git.thomas.lendacky@amd.com
1 parent 5dee19b commit 69dcb1e

File tree

2 files changed

+9
-10
lines changed

2 files changed

+9
-10
lines changed

arch/x86/include/asm/sev-common.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,13 @@ enum psc_op {
106106
#define GHCB_HV_FT_SNP BIT_ULL(0)
107107
#define GHCB_HV_FT_SNP_AP_CREATION BIT_ULL(1)
108108

109-
/* SNP Page State Change NAE event */
110-
#define VMGEXIT_PSC_MAX_ENTRY 253
109+
/*
110+
* SNP Page State Change NAE event
111+
* The VMGEXIT_PSC_MAX_ENTRY determines the size of the PSC structure, which
112+
* is a local stack variable in set_pages_state(). Do not increase this value
113+
* without evaluating the impact to stack usage.
114+
*/
115+
#define VMGEXIT_PSC_MAX_ENTRY 64
111116

112117
struct psc_hdr {
113118
u16 cur_entry;

arch/x86/kernel/sev.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -882,11 +882,7 @@ static void __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr,
882882
static void set_pages_state(unsigned long vaddr, unsigned long npages, int op)
883883
{
884884
unsigned long vaddr_end, next_vaddr;
885-
struct snp_psc_desc *desc;
886-
887-
desc = kmalloc(sizeof(*desc), GFP_KERNEL_ACCOUNT);
888-
if (!desc)
889-
panic("SNP: failed to allocate memory for PSC descriptor\n");
885+
struct snp_psc_desc desc;
890886

891887
vaddr = vaddr & PAGE_MASK;
892888
vaddr_end = vaddr + (npages << PAGE_SHIFT);
@@ -896,12 +892,10 @@ static void set_pages_state(unsigned long vaddr, unsigned long npages, int op)
896892
next_vaddr = min_t(unsigned long, vaddr_end,
897893
(VMGEXIT_PSC_MAX_ENTRY * PAGE_SIZE) + vaddr);
898894

899-
__set_pages_state(desc, vaddr, next_vaddr, op);
895+
__set_pages_state(&desc, vaddr, next_vaddr, op);
900896

901897
vaddr = next_vaddr;
902898
}
903-
904-
kfree(desc);
905899
}
906900

907901
void snp_set_memory_shared(unsigned long vaddr, unsigned long npages)

0 commit comments

Comments
 (0)