Andrew Cooper
2019-Jul-15 15:16 UTC
[PATCH v2] x86/paravirt: Drop {read,write}_cr8() hooks
There is a lot of infrastructure for functionality which is used exclusively in __{save,restore}_processor_state() on the suspend/resume path. cr8 is an alias of APIC_TASKPRI, and APIC_TASKPRI is saved/restored by lapic_{suspend,resume}(). Saving and restoring cr8 independently of the rest of the Local APIC state isn't a clever thing to be doing. Delete the suspend/resume cr8 handling, which shrinks the size of struct saved_context, and allows for the removal of both PVOPS. Signed-off-by: Andrew Cooper <andrew.cooper3 at citrix.com> --- CC: x86 at kernel.org CC: virtualization at lists.linux-foundation.org CC: Borislav Petkov <bp at alien8.de> CC: Peter Zijlstra <peterz at infradead.org> CC: Andy Lutomirski <luto at kernel.org> CC: Nadav Amit <namit at vmware.com> CC: Stephane Eranian <eranian at google.com> CC: Feng Tang <feng.tang at intel.com> CC: Juergen Gross <jgross at suse.com> CC: Boris Ostrovsky <boris.ostrovsky at oracle.com> CC: "Rafael J. Wysocki" <rjw at rjwysocki.net> CC: Pavel Machek <pavel at ucw.cz> Spotted while reviewing "x86/apic: Initialize TPR to block interrupts 16-31" https://lore.kernel.org/lkml/dc04a9f8b234d7b0956a8d2560b8945bcd9c4bf7.1563117760.git.luto at kernel.org/ v2: * Drop saved_context.cr8 as well (Juergen) * Remove akataria at vmware.com from the CC list due to bounces --- arch/x86/include/asm/paravirt.h | 12 ------------ arch/x86/include/asm/paravirt_types.h | 5 ----- arch/x86/include/asm/special_insns.h | 24 ------------------------ arch/x86/include/asm/suspend_64.h | 2 +- arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/paravirt.c | 4 ---- arch/x86/power/cpu.c | 4 ---- arch/x86/xen/enlighten_pv.c | 15 --------------- 8 files changed, 1 insertion(+), 66 deletions(-) diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index c25c38a05c1c..0e4a0539c353 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -139,18 +139,6 @@ static inline void __write_cr4(unsigned long x) PVOP_VCALL1(cpu.write_cr4, x); } -#ifdef CONFIG_X86_64 -static inline unsigned long read_cr8(void) -{ - return PVOP_CALL0(unsigned long, cpu.read_cr8); -} - -static inline void write_cr8(unsigned long x) -{ - PVOP_VCALL1(cpu.write_cr8, x); -} -#endif - static inline void arch_safe_halt(void) { PVOP_VCALL0(irq.safe_halt); diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 946f8f1f1efc..3c775fb5524b 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -119,11 +119,6 @@ struct pv_cpu_ops { void (*write_cr4)(unsigned long); -#ifdef CONFIG_X86_64 - unsigned long (*read_cr8)(void); - void (*write_cr8)(unsigned long); -#endif - /* Segment descriptor handling */ void (*load_tr_desc)(void); void (*load_gdt)(const struct desc_ptr *); diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 219be88a59d2..6d37b8fcfc77 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -73,20 +73,6 @@ static inline unsigned long native_read_cr4(void) void native_write_cr4(unsigned long val); -#ifdef CONFIG_X86_64 -static inline unsigned long native_read_cr8(void) -{ - unsigned long cr8; - asm volatile("movq %%cr8,%0" : "=r" (cr8)); - return cr8; -} - -static inline void native_write_cr8(unsigned long val) -{ - asm volatile("movq %0,%%cr8" :: "r" (val) : "memory"); -} -#endif - #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS static inline u32 rdpkru(void) { @@ -200,16 +186,6 @@ static inline void wbinvd(void) #ifdef CONFIG_X86_64 -static inline unsigned long read_cr8(void) -{ - return native_read_cr8(); -} - -static inline void write_cr8(unsigned long x) -{ - native_write_cr8(x); -} - static inline void load_gs_index(unsigned selector) { native_load_gs_index(selector); diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h index a7af9f53c0cb..35bb35d28733 100644 --- a/arch/x86/include/asm/suspend_64.h +++ b/arch/x86/include/asm/suspend_64.h @@ -34,7 +34,7 @@ struct saved_context { */ unsigned long kernelmode_gs_base, usermode_gs_base, fs_base; - unsigned long cr0, cr2, cr3, cr4, cr8; + unsigned long cr0, cr2, cr3, cr4; u64 misc_enable; bool misc_enable_saved; struct saved_msrs saved_msrs; diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index d3d075226c0a..8b54d8e3a561 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -62,7 +62,6 @@ int main(void) ENTRY(cr2); ENTRY(cr3); ENTRY(cr4); - ENTRY(cr8); ENTRY(gdt_desc); BLANK(); #undef ENTRY diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 98039d7fb998..de4d4e8a54c1 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -311,10 +311,6 @@ struct paravirt_patch_template pv_ops = { .cpu.read_cr0 = native_read_cr0, .cpu.write_cr0 = native_write_cr0, .cpu.write_cr4 = native_write_cr4, -#ifdef CONFIG_X86_64 - .cpu.read_cr8 = native_read_cr8, - .cpu.write_cr8 = native_write_cr8, -#endif .cpu.wbinvd = native_wbinvd, .cpu.read_msr = native_read_msr, .cpu.write_msr = native_write_msr, diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 24b079e94bc2..1c58d8982728 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -122,9 +122,6 @@ static void __save_processor_state(struct saved_context *ctxt) ctxt->cr2 = read_cr2(); ctxt->cr3 = __read_cr3(); ctxt->cr4 = __read_cr4(); -#ifdef CONFIG_X86_64 - ctxt->cr8 = read_cr8(); -#endif ctxt->misc_enable_saved = !rdmsrl_safe(MSR_IA32_MISC_ENABLE, &ctxt->misc_enable); msr_save_context(ctxt); @@ -207,7 +204,6 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) #else /* CONFIG X86_64 */ wrmsrl(MSR_EFER, ctxt->efer); - write_cr8(ctxt->cr8); __write_cr4(ctxt->cr4); #endif write_cr3(ctxt->cr3); diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 4722ba2966ac..27aba18f30e8 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -877,16 +877,6 @@ static void xen_write_cr4(unsigned long cr4) native_write_cr4(cr4); } -#ifdef CONFIG_X86_64 -static inline unsigned long xen_read_cr8(void) -{ - return 0; -} -static inline void xen_write_cr8(unsigned long val) -{ - BUG_ON(val); -} -#endif static u64 xen_read_msr_safe(unsigned int msr, int *err) { @@ -1022,11 +1012,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { .write_cr4 = xen_write_cr4, -#ifdef CONFIG_X86_64 - .read_cr8 = xen_read_cr8, - .write_cr8 = xen_write_cr8, -#endif - .wbinvd = native_wbinvd, .read_msr = xen_read_msr, -- 2.11.0
> On Jul 15, 2019, at 8:16 AM, Andrew Cooper <andrew.cooper3 at citrix.com> wrote: > > There is a lot of infrastructure for functionality which is used > exclusively in __{save,restore}_processor_state() on the suspend/resume > path. > > cr8 is an alias of APIC_TASKPRI, and APIC_TASKPRI is saved/restored by > lapic_{suspend,resume}(). Saving and restoring cr8 independently of the > rest of the Local APIC state isn't a clever thing to be doing. > > Delete the suspend/resume cr8 handling, which shrinks the size of struct > saved_context, and allows for the removal of both PVOPS.I think removing the interface for CR8 writes is also good to avoid potential correctness issues, as the SDM says (10.8.6.1 "Interaction of Task Priorities between CR8 and APIC?): "Operating software should implement either direct APIC TPR updates or CR8 style TPR updates but not mix them. Software can use a serializing instruction (for example, CPUID) to serialize updates between MOV CR8 and stores to the APIC.? And native_write_cr8() did not even issue a serializing instruction.
Andrew Cooper
2019-Jul-15 23:30 UTC
[PATCH v2] x86/paravirt: Drop {read,write}_cr8() hooks
On 15/07/2019 19:17, Nadav Amit wrote:>> On Jul 15, 2019, at 8:16 AM, Andrew Cooper <andrew.cooper3 at citrix.com> wrote: >> >> There is a lot of infrastructure for functionality which is used >> exclusively in __{save,restore}_processor_state() on the suspend/resume >> path. >> >> cr8 is an alias of APIC_TASKPRI, and APIC_TASKPRI is saved/restored by >> lapic_{suspend,resume}(). Saving and restoring cr8 independently of the >> rest of the Local APIC state isn't a clever thing to be doing. >> >> Delete the suspend/resume cr8 handling, which shrinks the size of struct >> saved_context, and allows for the removal of both PVOPS. > I think removing the interface for CR8 writes is also good to avoid > potential correctness issues, as the SDM says (10.8.6.1 "Interaction of Task > Priorities between CR8 and APIC?): > > "Operating software should implement either direct APIC TPR updates or CR8 > style TPR updates but not mix them. Software can use a serializing > instruction (for example, CPUID) to serialize updates between MOV CR8 and > stores to the APIC.? > > And native_write_cr8() did not even issue a serializing instruction. >Given its location, the one write_cr8() is bounded by two serialising operations, so is safe in practice. However, I agree with the statement in the manual.? I could submit a v3 with an updated commit message, or let it be fixed on commit.? Whichever is easiest. ~Andrew
Juergen Gross
2019-Jul-16 04:15 UTC
[PATCH v2] x86/paravirt: Drop {read,write}_cr8() hooks
On 15.07.19 17:16, Andrew Cooper wrote:> There is a lot of infrastructure for functionality which is used > exclusively in __{save,restore}_processor_state() on the suspend/resume > path. > > cr8 is an alias of APIC_TASKPRI, and APIC_TASKPRI is saved/restored by > lapic_{suspend,resume}(). Saving and restoring cr8 independently of the > rest of the Local APIC state isn't a clever thing to be doing. > > Delete the suspend/resume cr8 handling, which shrinks the size of struct > saved_context, and allows for the removal of both PVOPS. > > Signed-off-by: Andrew Cooper <andrew.cooper3 at citrix.com>Reviewed-by: Juergen Gross <jgross at suse.com> Juergen
Possibly Parallel Threads
- [PATCH v2] x86/paravirt: Drop {read,write}_cr8() hooks
- [PATCH] x86/paravirt: Drop {read,write}_cr8() hooks
- [PATCH] x86/paravirt: Drop {read,write}_cr8() hooks
- [PATCH v2] x86/paravirt: Drop {read,write}_cr8() hooks
- [PATCH v2] x86/paravirt: Drop {read,write}_cr8() hooks