Skip to content

Commit 27ba8c7

Browse files
stevenrutherfordjohn-cabaj
authored andcommitted
x86/sev: Make enc_dec_hypercall() accept a size instead of npages
BugLink: https://bugs.launchpad.net/bugs/2034894 enc_dec_hypercall() accepted a page count instead of a size, which forced its callers to round up. As a result, non-page aligned vaddrs caused pages to be spuriously marked as decrypted via the encryption status hypercall, which in turn caused consistent corruption of pages during live migration. Live migration requires accurate encryption status information to avoid migrating pages from the wrong perspective. Fixes: 064ce6c ("mm: x86: Invoke hypercall when page encryption status is changed") Signed-off-by: Steve Rutherford <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Reviewed-by: Tom Lendacky <[email protected]> Reviewed-by: Pankaj Gupta <[email protected]> Tested-by: Ben Hillier <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Khalid Elmously <[email protected]> (backported from commit ac3f9c9) [ kmously: adjusted for different context in arch/x86/mm/mem_encrypt_amd.c ] Acked-by: Tim Gardner <[email protected]> Acked-by: John Cabaj <[email protected]> Signed-off-by: John Cabaj <[email protected]>
1 parent 62cd7c4 commit 27ba8c7

File tree

4 files changed

+11
-14
lines changed

4 files changed

+11
-14
lines changed

arch/x86/include/asm/mem_encrypt.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ void __init sme_enable(struct boot_params *bp);
4444

4545
int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size);
4646
int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size);
47-
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages,
48-
bool enc);
47+
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr,
48+
unsigned long size, bool enc);
4949

5050
void __init mem_encrypt_free_decrypted_mem(void);
5151

@@ -86,7 +86,7 @@ early_set_memory_decrypted(unsigned long vaddr, unsigned long size) { return 0;
8686
static inline int __init
8787
early_set_memory_encrypted(unsigned long vaddr, unsigned long size) { return 0; }
8888
static inline void __init
89-
early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) {}
89+
early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc) {}
9090

9191
static inline void mem_encrypt_free_decrypted_mem(void) { }
9292

arch/x86/include/asm/set_memory.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ int set_pages_rw(struct page *page, int numpages);
8383
int set_direct_map_invalid_noflush(struct page *page);
8484
int set_direct_map_default_noflush(struct page *page);
8585
bool kernel_page_present(struct page *page);
86-
void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);
86+
void notify_range_enc_status_changed(unsigned long vaddr, unsigned long size, bool enc);
8787

8888
extern int kernel_set_to_readonly;
8989

arch/x86/kernel/kvm.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -931,10 +931,8 @@ static void __init kvm_init_platform(void)
931931
* Ensure that _bss_decrypted section is marked as decrypted in the
932932
* shared pages list.
933933
*/
934-
nr_pages = DIV_ROUND_UP(__end_bss_decrypted - __start_bss_decrypted,
935-
PAGE_SIZE);
936934
early_set_mem_enc_dec_hypercall((unsigned long)__start_bss_decrypted,
937-
nr_pages, 0);
935+
__end_bss_decrypted - __start_bss_decrypted, 0);
938936

939937
/*
940938
* If not booted using EFI, enable Live migration support.

arch/x86/mm/mem_encrypt_amd.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,10 @@ static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
292292
return pfn;
293293
}
294294

295-
void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
295+
void notify_range_enc_status_changed(unsigned long vaddr, unsigned long size, bool enc)
296296
{
297297
#ifdef CONFIG_PARAVIRT
298-
unsigned long sz = npages << PAGE_SHIFT;
299-
unsigned long vaddr_end = vaddr + sz;
298+
unsigned long vaddr_end = vaddr + size;
300299

301300
while (vaddr < vaddr_end) {
302301
int psize, pmask, level;
@@ -316,7 +315,7 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
316315
psize = page_level_size(level);
317316
pmask = page_level_mask(level);
318317

319-
notify_page_enc_status_changed(pfn, psize >> PAGE_SHIFT, enc);
318+
notify_page_enc_status_changed(pfn, size, enc);
320319

321320
vaddr = (vaddr & pmask) + psize;
322321
}
@@ -442,7 +441,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr,
442441

443442
ret = 0;
444443

445-
notify_range_enc_status_changed(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
444+
notify_range_enc_status_changed(start, size, enc);
446445
out:
447446
__flush_tlb_all();
448447
return ret;
@@ -458,9 +457,9 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)
458457
return early_set_memory_enc_dec(vaddr, size, true);
459458
}
460459

461-
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
460+
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc)
462461
{
463-
notify_range_enc_status_changed(vaddr, npages, enc);
462+
notify_range_enc_status_changed(vaddr, size, enc);
464463
}
465464

466465
/*

0 commit comments

Comments
 (0)