x86/mtrr: Improvements to control register handling
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 9 May 2017 15:05:08 +0000 (15:05 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 30 May 2017 17:50:13 +0000 (18:50 +0100)
Use X86_CR0_CD rather than opencoding it (and its inversion).  Drop the
pointless cr0 variable.

Xen always uses CR4.PGE, and altering PGE is a full TLB flush.  There is no
need to call flush_tlb_local() (which itself, toggles CR4.PGE rather than
writing to CR3!) as well as clearing CR4.PGE.  The static cr4 variable isn't
needed either.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/cpu/mtrr/generic.c

index 104baf951aa83c7f8dd9014d665b39086a6195a2..e9c0e5e059555448d5f5599ed8d1b964488c5d21 100644 (file)
@@ -391,7 +391,6 @@ static unsigned long set_mtrr_state(void)
 }
 
 
-static unsigned long cr4 = 0;
 static DEFINE_SPINLOCK(set_atomicity_lock);
 
 /*
@@ -403,8 +402,6 @@ static DEFINE_SPINLOCK(set_atomicity_lock);
 
 static void prepare_set(void)
 {
-       unsigned long cr0;
-
        /*  Note that this is not ideal, since the cache is only flushed/disabled
           for this CPU while the MTRRs are changed, but changing this requires
           more invasive changes to the way the kernel boots  */
@@ -412,18 +409,12 @@ static void prepare_set(void)
        spin_lock(&set_atomicity_lock);
 
        /*  Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
-       cr0 = read_cr0() | 0x40000000;  /* set CD flag */
-       write_cr0(cr0);
+       write_cr0(read_cr0() | X86_CR0_CD);
        wbinvd();
 
-       /*  Save value of CR4 and clear Page Global Enable (bit 7)  */
-       if ( cpu_has_pge ) {
-               cr4 = read_cr4();
-               write_cr4(cr4 & ~X86_CR4_PGE);
-       }
-
-       /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */
-       flush_tlb_local();
+       /*  TLB flushing here relies on Xen always using CR4.PGE. */
+       BUILD_BUG_ON(!(XEN_MINIMAL_CR4 & X86_CR4_PGE));
+       write_cr4(read_cr4() & ~X86_CR4_PGE);
 
        /*  Save MTRR state */
        rdmsrl(MSR_MTRRdefType, deftype);
@@ -434,18 +425,15 @@ static void prepare_set(void)
 
 static void post_set(void)
 {
-       /*  Flush TLBs (no need to flush caches - they are disabled)  */
-       flush_tlb_local();
-
        /* Intel (P6) standard MTRRs */
        mtrr_wrmsr(MSR_MTRRdefType, deftype);
-               
+
        /*  Enable caches  */
-       write_cr0(read_cr0() & 0xbfffffff);
+       write_cr0(read_cr0() & ~X86_CR0_CD);
+
+       /*  Reenable CR4.PGE (also flushes the TLB) */
+       write_cr4(read_cr4() | X86_CR4_PGE);
 
-       /*  Restore value of CR4  */
-       if ( cpu_has_pge )
-               write_cr4(cr4);
        spin_unlock(&set_atomicity_lock);
 }