mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-11-22 02:17:17 +00:00
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: 064ce6c550 ("mm: x86: Invoke hypercall when page encryption status is changed")
Signed-off-by: Steve Rutherford <srutherford@google.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Tested-by: Ben Hillier <bhillier@google.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20230824223731.2055016-1-srutherford@google.com
117 lines
3.4 KiB
C
117 lines
3.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* AMD Memory Encryption Support
|
|
*
|
|
* Copyright (C) 2016 Advanced Micro Devices, Inc.
|
|
*
|
|
* Author: Tom Lendacky <thomas.lendacky@amd.com>
|
|
*/
|
|
|
|
#ifndef __X86_MEM_ENCRYPT_H__
|
|
#define __X86_MEM_ENCRYPT_H__
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/cc_platform.h>
|
|
|
|
#include <asm/bootparam.h>
|
|
|
|
#ifdef CONFIG_X86_MEM_ENCRYPT
|
|
void __init mem_encrypt_init(void);
|
|
#else
|
|
static inline void mem_encrypt_init(void) { }
|
|
#endif
|
|
|
|
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
|
|
|
extern u64 sme_me_mask;
|
|
extern u64 sev_status;
|
|
|
|
void sme_encrypt_execute(unsigned long encrypted_kernel_vaddr,
|
|
unsigned long decrypted_kernel_vaddr,
|
|
unsigned long kernel_len,
|
|
unsigned long encryption_wa,
|
|
unsigned long encryption_pgd);
|
|
|
|
void __init sme_early_encrypt(resource_size_t paddr,
|
|
unsigned long size);
|
|
void __init sme_early_decrypt(resource_size_t paddr,
|
|
unsigned long size);
|
|
|
|
void __init sme_map_bootdata(char *real_mode_data);
|
|
void __init sme_unmap_bootdata(char *real_mode_data);
|
|
|
|
void __init sme_early_init(void);
|
|
void __init sev_setup_arch(void);
|
|
|
|
void __init sme_encrypt_kernel(struct boot_params *bp);
|
|
void __init sme_enable(struct boot_params *bp);
|
|
|
|
int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size);
|
|
int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size);
|
|
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr,
|
|
unsigned long size, bool enc);
|
|
|
|
void __init mem_encrypt_free_decrypted_mem(void);
|
|
|
|
void __init sev_es_init_vc_handling(void);
|
|
|
|
#define __bss_decrypted __section(".bss..decrypted")
|
|
|
|
#else /* !CONFIG_AMD_MEM_ENCRYPT */
|
|
|
|
#define sme_me_mask 0ULL
|
|
#define sev_status 0ULL
|
|
|
|
static inline void __init sme_early_encrypt(resource_size_t paddr,
|
|
unsigned long size) { }
|
|
static inline void __init sme_early_decrypt(resource_size_t paddr,
|
|
unsigned long size) { }
|
|
|
|
static inline void __init sme_map_bootdata(char *real_mode_data) { }
|
|
static inline void __init sme_unmap_bootdata(char *real_mode_data) { }
|
|
|
|
static inline void __init sme_early_init(void) { }
|
|
static inline void __init sev_setup_arch(void) { }
|
|
|
|
static inline void __init sme_encrypt_kernel(struct boot_params *bp) { }
|
|
static inline void __init sme_enable(struct boot_params *bp) { }
|
|
|
|
static inline void sev_es_init_vc_handling(void) { }
|
|
|
|
static inline int __init
|
|
early_set_memory_decrypted(unsigned long vaddr, unsigned long size) { return 0; }
|
|
static inline int __init
|
|
early_set_memory_encrypted(unsigned long vaddr, unsigned long size) { return 0; }
|
|
static inline void __init
|
|
early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc) {}
|
|
|
|
static inline void mem_encrypt_free_decrypted_mem(void) { }
|
|
|
|
#define __bss_decrypted
|
|
|
|
#endif /* CONFIG_AMD_MEM_ENCRYPT */
|
|
|
|
void add_encrypt_protection_map(void);
|
|
|
|
/*
|
|
* The __sme_pa() and __sme_pa_nodebug() macros are meant for use when
|
|
* writing to or comparing values from the cr3 register. Having the
|
|
* encryption mask set in cr3 enables the PGD entry to be encrypted and
|
|
* avoid special case handling of PGD allocations.
|
|
*/
|
|
#define __sme_pa(x) (__pa(x) | sme_me_mask)
|
|
#define __sme_pa_nodebug(x) (__pa_nodebug(x) | sme_me_mask)
|
|
|
|
extern char __start_bss_decrypted[], __end_bss_decrypted[], __start_bss_decrypted_unused[];
|
|
|
|
static inline u64 sme_get_me_mask(void)
|
|
{
|
|
return sme_me_mask;
|
|
}
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif /* __X86_MEM_ENCRYPT_H__ */
|