Skip to content

Commit 82b7f88

Browse files
ashkalrabp3tk0v
authored andcommitted
x86/sev: Make sure pages are not skipped during kdump
When shared pages are being converted to private during kdump, additional checks are performed. They include handling the case of a GHCB page being contained within a huge page. Currently, this check incorrectly skips a page just below the GHCB page from being transitioned back to private during kdump preparation. This skipped page causes a 0x404 #VC exception when it is accessed later while dumping guest memory for vmcore generation. Correct the range to be checked for GHCB contained in a huge page. Also, ensure that the skipped huge page containing the GHCB page is transitioned back to private by applying the correct address mask later when changing GHCBs to private at end of kdump preparation. [ bp: Massage commit message. ] Fixes: 3074152 ("x86/sev: Convert shared memory back to private on kexec") Signed-off-by: Ashish Kalra <ashish.kalra@amd.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Tested-by: Srikanth Aithal <sraithal@amd.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/20250506183529.289549-1-Ashish.Kalra@amd.com
1 parent d2062cc commit 82b7f88

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

arch/x86/coco/sev/core.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,8 @@ static void unshare_all_memory(void)
11011101
data = per_cpu(runtime_data, cpu);
11021102
ghcb = (unsigned long)&data->ghcb_page;
11031103

1104-
if (addr <= ghcb && ghcb <= addr + size) {
1104+
/* Handle the case of a huge page containing the GHCB page */
1105+
if (addr <= ghcb && ghcb < addr + size) {
11051106
skipped_addr = true;
11061107
break;
11071108
}
@@ -1213,8 +1214,8 @@ static void shutdown_all_aps(void)
12131214
void snp_kexec_finish(void)
12141215
{
12151216
struct sev_es_runtime_data *data;
1217+
unsigned long size, addr;
12161218
unsigned int level, cpu;
1217-
unsigned long size;
12181219
struct ghcb *ghcb;
12191220
pte_t *pte;
12201221

@@ -1242,8 +1243,10 @@ void snp_kexec_finish(void)
12421243
ghcb = &data->ghcb_page;
12431244
pte = lookup_address((unsigned long)ghcb, &level);
12441245
size = page_level_size(level);
1245-
set_pte_enc(pte, level, (void *)ghcb);
1246-
snp_set_memory_private((unsigned long)ghcb, (size / PAGE_SIZE));
1246+
/* Handle the case of a huge page containing the GHCB page */
1247+
addr = (unsigned long)ghcb & page_level_mask(level);
1248+
set_pte_enc(pte, level, (void *)addr);
1249+
snp_set_memory_private(addr, (size / PAGE_SIZE));
12471250
}
12481251
}
12491252

0 commit comments

Comments
 (0)