Commit 5dee19b6 authored by Tom Lendacky's avatar Tom Lendacky Committed by Borislav Petkov (AMD)

x86/sev: Fix calculation of end address based on number of pages

When calculating an end address based on an unsigned int number of pages,
any value greater than or equal to 0x100000 that is shift PAGE_SHIFT bits
results in a 0 value, resulting in an invalid end address. Change the
number of pages variable in various routines from an unsigned int to an
unsigned long to calculate the end address correctly.

Fixes: 5e5ccff6 ("x86/sev: Add helper for validating pages in early enc attribute changes")
Fixes: dc3f3d24 ("x86/mm: Validate memory when changing the C-bit")
Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/6a6e4eea0e1414402bac747744984fa4e9c01bb6.1686063086.git.thomas.lendacky@amd.com
parent 75d090fd
...@@ -192,12 +192,12 @@ struct snp_guest_request_ioctl; ...@@ -192,12 +192,12 @@ struct snp_guest_request_ioctl;
void setup_ghcb(void); void setup_ghcb(void);
void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
unsigned int npages); unsigned long npages);
void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr,
unsigned int npages); unsigned long npages);
void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op); void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op);
void snp_set_memory_shared(unsigned long vaddr, unsigned int npages); void snp_set_memory_shared(unsigned long vaddr, unsigned long npages);
void snp_set_memory_private(unsigned long vaddr, unsigned int npages); void snp_set_memory_private(unsigned long vaddr, unsigned long npages);
void snp_set_wakeup_secondary_cpu(void); void snp_set_wakeup_secondary_cpu(void);
bool snp_init(struct boot_params *bp); bool snp_init(struct boot_params *bp);
void __init __noreturn snp_abort(void); void __init __noreturn snp_abort(void);
...@@ -212,12 +212,12 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) ...@@ -212,12 +212,12 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate)
static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { return 0; } static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { return 0; }
static inline void setup_ghcb(void) { } static inline void setup_ghcb(void) { }
static inline void __init static inline void __init
early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned int npages) { } early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
static inline void __init static inline void __init
early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned int npages) { } early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { } static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { }
static inline void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) { } static inline void snp_set_memory_shared(unsigned long vaddr, unsigned long npages) { }
static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npages) { } static inline void snp_set_memory_private(unsigned long vaddr, unsigned long npages) { }
static inline void snp_set_wakeup_secondary_cpu(void) { } static inline void snp_set_wakeup_secondary_cpu(void) { }
static inline bool snp_init(struct boot_params *bp) { return false; } static inline bool snp_init(struct boot_params *bp) { return false; }
static inline void snp_abort(void) { } static inline void snp_abort(void) { }
......
...@@ -645,7 +645,7 @@ static u64 __init get_jump_table_addr(void) ...@@ -645,7 +645,7 @@ static u64 __init get_jump_table_addr(void)
return ret; return ret;
} }
static void pvalidate_pages(unsigned long vaddr, unsigned int npages, bool validate) static void pvalidate_pages(unsigned long vaddr, unsigned long npages, bool validate)
{ {
unsigned long vaddr_end; unsigned long vaddr_end;
int rc; int rc;
...@@ -662,7 +662,7 @@ static void pvalidate_pages(unsigned long vaddr, unsigned int npages, bool valid ...@@ -662,7 +662,7 @@ static void pvalidate_pages(unsigned long vaddr, unsigned int npages, bool valid
} }
} }
static void __init early_set_pages_state(unsigned long paddr, unsigned int npages, enum psc_op op) static void __init early_set_pages_state(unsigned long paddr, unsigned long npages, enum psc_op op)
{ {
unsigned long paddr_end; unsigned long paddr_end;
u64 val; u64 val;
...@@ -701,7 +701,7 @@ static void __init early_set_pages_state(unsigned long paddr, unsigned int npage ...@@ -701,7 +701,7 @@ static void __init early_set_pages_state(unsigned long paddr, unsigned int npage
} }
void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
unsigned int npages) unsigned long npages)
{ {
/* /*
* This can be invoked in early boot while running identity mapped, so * This can be invoked in early boot while running identity mapped, so
...@@ -723,7 +723,7 @@ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long padd ...@@ -723,7 +723,7 @@ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long padd
} }
void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr,
unsigned int npages) unsigned long npages)
{ {
/* /*
* This can be invoked in early boot while running identity mapped, so * This can be invoked in early boot while running identity mapped, so
...@@ -879,7 +879,7 @@ static void __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr, ...@@ -879,7 +879,7 @@ static void __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr,
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
} }
static void set_pages_state(unsigned long vaddr, unsigned int npages, int op) static void set_pages_state(unsigned long vaddr, unsigned long npages, int op)
{ {
unsigned long vaddr_end, next_vaddr; unsigned long vaddr_end, next_vaddr;
struct snp_psc_desc *desc; struct snp_psc_desc *desc;
...@@ -904,7 +904,7 @@ static void set_pages_state(unsigned long vaddr, unsigned int npages, int op) ...@@ -904,7 +904,7 @@ static void set_pages_state(unsigned long vaddr, unsigned int npages, int op)
kfree(desc); kfree(desc);
} }
void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) void snp_set_memory_shared(unsigned long vaddr, unsigned long npages)
{ {
if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
return; return;
...@@ -914,7 +914,7 @@ void snp_set_memory_shared(unsigned long vaddr, unsigned int npages) ...@@ -914,7 +914,7 @@ void snp_set_memory_shared(unsigned long vaddr, unsigned int npages)
set_pages_state(vaddr, npages, SNP_PAGE_STATE_SHARED); set_pages_state(vaddr, npages, SNP_PAGE_STATE_SHARED);
} }
void snp_set_memory_private(unsigned long vaddr, unsigned int npages) void snp_set_memory_private(unsigned long vaddr, unsigned long npages)
{ {
if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment