diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/xen/enlighten.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index e9df942aa14..0a1700a2be9 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -658,10 +658,26 @@ static void xen_clts(void) | |||
658 | xen_mc_issue(PARAVIRT_LAZY_CPU); | 658 | xen_mc_issue(PARAVIRT_LAZY_CPU); |
659 | } | 659 | } |
660 | 660 | ||
661 | static DEFINE_PER_CPU(unsigned long, xen_cr0_value); | ||
662 | |||
663 | static unsigned long xen_read_cr0(void) | ||
664 | { | ||
665 | unsigned long cr0 = percpu_read(xen_cr0_value); | ||
666 | |||
667 | if (unlikely(cr0 == 0)) { | ||
668 | cr0 = native_read_cr0(); | ||
669 | percpu_write(xen_cr0_value, cr0); | ||
670 | } | ||
671 | |||
672 | return cr0; | ||
673 | } | ||
674 | |||
661 | static void xen_write_cr0(unsigned long cr0) | 675 | static void xen_write_cr0(unsigned long cr0) |
662 | { | 676 | { |
663 | struct multicall_space mcs; | 677 | struct multicall_space mcs; |
664 | 678 | ||
679 | percpu_write(xen_cr0_value, cr0); | ||
680 | |||
665 | /* Only pay attention to cr0.TS; everything else is | 681 | /* Only pay attention to cr0.TS; everything else is |
666 | ignored. */ | 682 | ignored. */ |
667 | mcs = xen_mc_entry(0); | 683 | mcs = xen_mc_entry(0); |
@@ -847,7 +863,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = { | |||
847 | 863 | ||
848 | .clts = xen_clts, | 864 | .clts = xen_clts, |
849 | 865 | ||
850 | .read_cr0 = native_read_cr0, | 866 | .read_cr0 = xen_read_cr0, |
851 | .write_cr0 = xen_write_cr0, | 867 | .write_cr0 = xen_write_cr0, |
852 | 868 | ||
853 | .read_cr4 = native_read_cr4, | 869 | .read_cr4 = native_read_cr4, |