From 9a7c6fde07d04e392dadfd406b7837c04aed0d72 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 31 Jul 2021 16:45:26 +0800 Subject: [PATCH] x86: mtrr: Abort if requested size is not power of 2 The size parameter of mtrr_add_request() and mtrr_set_next_var() shall be power of 2, otherwise the logic creates a mask that does not meet the requirement of IA32_MTRR_PHYSMASK register. Programming such a mask value to IA32_MTRR_PHYSMASK generates #GP. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Tested on chromebook_coral, chromebook_samus, chromebook_link, minnowmax Tested-by: Simon Glass --- arch/x86/cpu/mtrr.c | 7 +++++++ arch/x86/include/asm/mtrr.h | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c index 14c644eb56..260a008093 100644 --- a/arch/x86/cpu/mtrr.c +++ b/arch/x86/cpu/mtrr.c @@ -26,6 +26,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -179,6 +180,9 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size) if (!gd->arch.has_mtrr) return -ENOSYS; + if (!is_power_of_2(size)) + return -EINVAL; + if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS) return -ENOSPC; req = &gd->arch.mtrr_req[gd->arch.mtrr_req_count++]; @@ -223,6 +227,9 @@ int mtrr_set_next_var(uint type, uint64_t start, uint64_t size) { int mtrr; + if (!is_power_of_2(size)) + return -EINVAL; + mtrr = get_free_var_mtrr(); if (mtrr < 0) return mtrr; diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 384672e93f..d1aa86bf1d 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -119,7 +119,7 @@ void mtrr_close(struct mtrr_state *state, bool do_caches); * * @type: Requested type (MTRR_TYPE_) * @start: Start address - * @size: Size + * @size: Size, must be power of 2 * * @return: 0 on success, non-zero on failure */ @@ -144,8 +144,9 @@ int mtrr_commit(bool do_caches); * * @type: Requested type (MTRR_TYPE_) * @start: Start address - * @size: Size - * @return 0 on success, -ENOSPC if there are no more MTRRs + * @size: Size, must be power of 2 + * @return 0 on success, -EINVAL if size is not power of 2, + * -ENOSPC if there are no more MTRRs */ int mtrr_set_next_var(uint type, uint64_t base, uint64_t size);