Skip to content

Commit ac3f9c9

Browse files
stevenrutherfordIngo Molnar
authored andcommitted
x86/sev: Make enc_dec_hypercall() accept a size instead of npages
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]
1 parent e221804 commit ac3f9c9

File tree

3 files changed

+10
-13
lines changed

3 files changed

+10
-13
lines changed

arch/x86/include/asm/mem_encrypt.h

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

5151
int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size);
5252
int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size);
53-
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages,
54-
bool enc);
53+
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr,
54+
unsigned long size, bool enc);
5555

5656
void __init mem_encrypt_free_decrypted_mem(void);
5757

@@ -85,7 +85,7 @@ early_set_memory_decrypted(unsigned long vaddr, unsigned long size) { return 0;
8585
static inline int __init
8686
early_set_memory_encrypted(unsigned long vaddr, unsigned long size) { return 0; }
8787
static inline void __init
88-
early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) {}
88+
early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc) {}
8989

9090
static inline void mem_encrypt_free_decrypted_mem(void) { }
9191

arch/x86/kernel/kvm.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -966,10 +966,8 @@ static void __init kvm_init_platform(void)
966966
* Ensure that _bss_decrypted section is marked as decrypted in the
967967
* shared pages list.
968968
*/
969-
nr_pages = DIV_ROUND_UP(__end_bss_decrypted - __start_bss_decrypted,
970-
PAGE_SIZE);
971969
early_set_mem_enc_dec_hypercall((unsigned long)__start_bss_decrypted,
972-
nr_pages, 0);
970+
__end_bss_decrypted - __start_bss_decrypted, 0);
973971

974972
/*
975973
* 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
@@ -288,11 +288,10 @@ static bool amd_enc_cache_flush_required(void)
288288
return !cpu_feature_enabled(X86_FEATURE_SME_COHERENT);
289289
}
290290

291-
static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
291+
static void enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc)
292292
{
293293
#ifdef CONFIG_PARAVIRT
294-
unsigned long sz = npages << PAGE_SHIFT;
295-
unsigned long vaddr_end = vaddr + sz;
294+
unsigned long vaddr_end = vaddr + size;
296295

297296
while (vaddr < vaddr_end) {
298297
int psize, pmask, level;
@@ -342,7 +341,7 @@ static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool e
342341
snp_set_memory_private(vaddr, npages);
343342

344343
if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
345-
enc_dec_hypercall(vaddr, npages, enc);
344+
enc_dec_hypercall(vaddr, npages << PAGE_SHIFT, enc);
346345

347346
return true;
348347
}
@@ -466,7 +465,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr,
466465

467466
ret = 0;
468467

469-
early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
468+
early_set_mem_enc_dec_hypercall(start, size, enc);
470469
out:
471470
__flush_tlb_all();
472471
return ret;
@@ -482,9 +481,9 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)
482481
return early_set_memory_enc_dec(vaddr, size, true);
483482
}
484483

485-
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
484+
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc)
486485
{
487-
enc_dec_hypercall(vaddr, npages, enc);
486+
enc_dec_hypercall(vaddr, size, enc);
488487
}
489488

490489
void __init sme_early_init(void)

0 commit comments

Comments
 (0)