aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBin Meng <bmeng.cn@gmail.com>2021-07-31 16:45:26 +0800
committerBin Meng <bmeng.cn@gmail.com>2021-08-02 15:11:41 +0800
commit9a7c6fde07d04e392dadfd406b7837c04aed0d72 (patch)
tree02e024f7f95da9b256d73d384a98942e14c07707
parent3bcd6cf89efee5c8088dce2f770bdd5592186efb (diff)
downloadu-boot-9a7c6fde07d04e392dadfd406b7837c04aed0d72.zip
u-boot-9a7c6fde07d04e392dadfd406b7837c04aed0d72.tar.gz
u-boot-9a7c6fde07d04e392dadfd406b7837c04aed0d72.tar.bz2
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 <bmeng.cn@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org> Tested on chromebook_coral, chromebook_samus, chromebook_link, minnowmax Tested-by: Simon Glass <sjg@chromium.org>
-rw-r--r--arch/x86/cpu/mtrr.c7
-rw-r--r--arch/x86/include/asm/mtrr.h7
2 files changed, 11 insertions, 3 deletions
diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 14c644e..260a008 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -26,6 +26,7 @@
#include <asm/mp.h>
#include <asm/msr.h>
#include <asm/mtrr.h>
+#include <linux/log2.h>
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 384672e..d1aa86b 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);