When the boot CPU MTRRs are updated, perform the same update on all other
CPUs so they are kept in sync.

This avoids kernel warnings about mismatched MTRRs.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 arch/x86/cpu/mtrr.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 11f3ef08172..a48c9d8232e 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -74,10 +74,61 @@ void mtrr_save_all(struct mtrr_info *info)
        }
 }
 
+void mtrr_load_all(struct mtrr_info *info)
+{
+       struct mtrr_state state;
+       int i;
+
+       for (i = 0; i < MTRR_COUNT; i++) {
+               mtrr_open(&state, true);
+               wrmsrl(MTRR_PHYS_BASE_MSR(i), info->mtrr[i].base);
+               wrmsrl(MTRR_PHYS_MASK_MSR(i), info->mtrr[i].mask);
+               mtrr_close(&state, true);
+       }
+}
+
+static void save_mtrrs(void *arg)
+{
+       struct mtrr_info *info = arg;
+
+       mtrr_save_all(info);
+}
+
+static void load_mtrrs(void *arg)
+{
+       struct mtrr_info *info = arg;
+
+       mtrr_load_all(info);
+}
+
+/**
+ * mtrr_copy_to_aps() - Copy the MTRRs from the boot CPU to other CPUs
+ *
+ * @return 0 on success, -ve on failure
+ */
+static int mtrr_copy_to_aps(void)
+{
+       struct mtrr_info info;
+       int ret;
+
+       ret = mp_run_on_cpus(MP_SELECT_BSP, save_mtrrs, &info);
+       if (ret == -ENXIO)
+               return 0;
+       else if (ret)
+               return log_msg_ret("bsp", ret);
+
+       ret = mp_run_on_cpus(MP_SELECT_APS, load_mtrrs, &info);
+       if (ret)
+               return log_msg_ret("bsp", ret);
+
+       return 0;
+}
+
 int mtrr_commit(bool do_caches)
 {
        struct mtrr_request *req = gd->arch.mtrr_req;
        struct mtrr_state state;
+       int ret;
        int i;
 
        debug("%s: enabled=%d, count=%d\n", __func__, gd->arch.has_mtrr,
@@ -99,6 +150,12 @@ int mtrr_commit(bool do_caches)
        mtrr_close(&state, do_caches);
        debug("mtrr done\n");
 
+       if (gd->flags & GD_FLG_RELOC) {
+               ret = mtrr_copy_to_aps();
+               if (ret)
+                       return log_msg_ret("copy", ret);
+       }
+
        return 0;
 }
 
-- 
2.27.0.rc0.183.gde8f92d652-goog

Reply via email to