diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-23 12:54:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-23 12:54:58 -0400 |
commit | f682a7920baf7b721d01dd317f3b532265357cbb (patch) | |
tree | 253e96be2249d704424b153c58ba58c974a9e61d | |
parent | 99792e0cea1ed733cdc8d0758677981e0cbebfed (diff) | |
parent | 3a025de64bf89c84a79909069e3c24ad9e710d27 (diff) |
Merge branch 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 paravirt updates from Ingo Molnar:
"Two main changes:
- Remove no longer used parts of the paravirt infrastructure and put
large quantities of paravirt ops under a new config option
PARAVIRT_XXL=y, which is selected by XEN_PV only. (Joergen Gross)
- Enable PV spinlocks on Hyperv (Yi Sun)"
* 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/hyperv: Enable PV qspinlock for Hyper-V
x86/hyperv: Add GUEST_IDLE_MSR support
x86/paravirt: Clean up native_patch()
x86/paravirt: Prevent redefinition of SAVE_FLAGS macro
x86/xen: Make xen_reservation_lock static
x86/paravirt: Remove unneeded mmu related paravirt ops bits
x86/paravirt: Move the Xen-only pv_mmu_ops under the PARAVIRT_XXL umbrella
x86/paravirt: Move the pv_irq_ops under the PARAVIRT_XXL umbrella
x86/paravirt: Move the Xen-only pv_cpu_ops under the PARAVIRT_XXL umbrella
x86/paravirt: Move items in pv_info under PARAVIRT_XXL umbrella
x86/paravirt: Introduce new config option PARAVIRT_XXL
x86/paravirt: Remove unused paravirt bits
x86/paravirt: Use a single ops structure
x86/paravirt: Remove clobbers from struct paravirt_patch_site
x86/paravirt: Remove clobbers parameter from paravirt patch functions
x86/paravirt: Make paravirt_patch_call() and paravirt_patch_jmp() static
x86/xen: Add SPDX identifier in arch/x86/xen files
x86/xen: Link platform-pci-unplug.o only if CONFIG_XEN_PVHVM
x86/xen: Move pv specific parts of arch/x86/xen/mmu.c to mmu_pv.c
x86/xen: Move pv irq related functions under CONFIG_XEN_PV umbrella
68 files changed, 1023 insertions, 1006 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 4c74a2f4ddfc..6d380890e075 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
@@ -1390,6 +1390,11 @@ | |||
1390 | hvc_iucv_allow= [S390] Comma-separated list of z/VM user IDs. | 1390 | hvc_iucv_allow= [S390] Comma-separated list of z/VM user IDs. |
1391 | If specified, z/VM IUCV HVC accepts connections | 1391 | If specified, z/VM IUCV HVC accepts connections |
1392 | from listed z/VM user IDs only. | 1392 | from listed z/VM user IDs only. |
1393 | |||
1394 | hv_nopvspin [X86,HYPER_V] Disables the paravirt spinlock optimizations | ||
1395 | which allow the hypervisor to 'idle' the | ||
1396 | guest on lock contention. | ||
1397 | |||
1393 | keep_bootcon [KNL] | 1398 | keep_bootcon [KNL] |
1394 | Do not unregister boot console at start. This is only | 1399 | Do not unregister boot console at start. This is only |
1395 | useful for debugging when something happens in the window | 1400 | useful for debugging when something happens in the window |
diff --git a/arch/arm/include/asm/paravirt.h b/arch/arm/include/asm/paravirt.h index d51e5cd31d01..cdbf02d9c1d4 100644 --- a/arch/arm/include/asm/paravirt.h +++ b/arch/arm/include/asm/paravirt.h | |||
@@ -10,11 +10,16 @@ extern struct static_key paravirt_steal_rq_enabled; | |||
10 | struct pv_time_ops { | 10 | struct pv_time_ops { |
11 | unsigned long long (*steal_clock)(int cpu); | 11 | unsigned long long (*steal_clock)(int cpu); |
12 | }; | 12 | }; |
13 | extern struct pv_time_ops pv_time_ops; | 13 | |
14 | struct paravirt_patch_template { | ||
15 | struct pv_time_ops time; | ||
16 | }; | ||
17 | |||
18 | extern struct paravirt_patch_template pv_ops; | ||
14 | 19 | ||
15 | static inline u64 paravirt_steal_clock(int cpu) | 20 | static inline u64 paravirt_steal_clock(int cpu) |
16 | { | 21 | { |
17 | return pv_time_ops.steal_clock(cpu); | 22 | return pv_ops.time.steal_clock(cpu); |
18 | } | 23 | } |
19 | #endif | 24 | #endif |
20 | 25 | ||
diff --git a/arch/arm/kernel/paravirt.c b/arch/arm/kernel/paravirt.c index 53f371ed4568..75c158b0353f 100644 --- a/arch/arm/kernel/paravirt.c +++ b/arch/arm/kernel/paravirt.c | |||
@@ -21,5 +21,5 @@ | |||
21 | struct static_key paravirt_steal_enabled; | 21 | struct static_key paravirt_steal_enabled; |
22 | struct static_key paravirt_steal_rq_enabled; | 22 | struct static_key paravirt_steal_rq_enabled; |
23 | 23 | ||
24 | struct pv_time_ops pv_time_ops; | 24 | struct paravirt_patch_template pv_ops; |
25 | EXPORT_SYMBOL_GPL(pv_time_ops); | 25 | EXPORT_SYMBOL_GPL(pv_ops); |
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 07060e5b5864..17e478928276 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c | |||
@@ -62,29 +62,6 @@ static __read_mostly unsigned int xen_events_irq; | |||
62 | uint32_t xen_start_flags; | 62 | uint32_t xen_start_flags; |
63 | EXPORT_SYMBOL(xen_start_flags); | 63 | EXPORT_SYMBOL(xen_start_flags); |
64 | 64 | ||
65 | int xen_remap_domain_gfn_array(struct vm_area_struct *vma, | ||
66 | unsigned long addr, | ||
67 | xen_pfn_t *gfn, int nr, | ||
68 | int *err_ptr, pgprot_t prot, | ||
69 | unsigned domid, | ||
70 | struct page **pages) | ||
71 | { | ||
72 | return xen_xlate_remap_gfn_array(vma, addr, gfn, nr, err_ptr, | ||
73 | prot, domid, pages); | ||
74 | } | ||
75 | EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_array); | ||
76 | |||
77 | /* Not used by XENFEAT_auto_translated guests. */ | ||
78 | int xen_remap_domain_gfn_range(struct vm_area_struct *vma, | ||
79 | unsigned long addr, | ||
80 | xen_pfn_t gfn, int nr, | ||
81 | pgprot_t prot, unsigned domid, | ||
82 | struct page **pages) | ||
83 | { | ||
84 | return -ENOSYS; | ||
85 | } | ||
86 | EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_range); | ||
87 | |||
88 | int xen_unmap_domain_gfn_range(struct vm_area_struct *vma, | 65 | int xen_unmap_domain_gfn_range(struct vm_area_struct *vma, |
89 | int nr, struct page **pages) | 66 | int nr, struct page **pages) |
90 | { | 67 | { |
@@ -92,17 +69,6 @@ int xen_unmap_domain_gfn_range(struct vm_area_struct *vma, | |||
92 | } | 69 | } |
93 | EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range); | 70 | EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range); |
94 | 71 | ||
95 | /* Not used by XENFEAT_auto_translated guests. */ | ||
96 | int xen_remap_domain_mfn_array(struct vm_area_struct *vma, | ||
97 | unsigned long addr, | ||
98 | xen_pfn_t *mfn, int nr, | ||
99 | int *err_ptr, pgprot_t prot, | ||
100 | unsigned int domid, struct page **pages) | ||
101 | { | ||
102 | return -ENOSYS; | ||
103 | } | ||
104 | EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_array); | ||
105 | |||
106 | static void xen_read_wallclock(struct timespec64 *ts) | 72 | static void xen_read_wallclock(struct timespec64 *ts) |
107 | { | 73 | { |
108 | u32 version; | 74 | u32 version; |
diff --git a/arch/arm64/include/asm/paravirt.h b/arch/arm64/include/asm/paravirt.h index bb5dcea42003..799d9dd6f7cc 100644 --- a/arch/arm64/include/asm/paravirt.h +++ b/arch/arm64/include/asm/paravirt.h | |||
@@ -10,11 +10,16 @@ extern struct static_key paravirt_steal_rq_enabled; | |||
10 | struct pv_time_ops { | 10 | struct pv_time_ops { |
11 | unsigned long long (*steal_clock)(int cpu); | 11 | unsigned long long (*steal_clock)(int cpu); |
12 | }; | 12 | }; |
13 | extern struct pv_time_ops pv_time_ops; | 13 | |
14 | struct paravirt_patch_template { | ||
15 | struct pv_time_ops time; | ||
16 | }; | ||
17 | |||
18 | extern struct paravirt_patch_template pv_ops; | ||
14 | 19 | ||
15 | static inline u64 paravirt_steal_clock(int cpu) | 20 | static inline u64 paravirt_steal_clock(int cpu) |
16 | { | 21 | { |
17 | return pv_time_ops.steal_clock(cpu); | 22 | return pv_ops.time.steal_clock(cpu); |
18 | } | 23 | } |
19 | #endif | 24 | #endif |
20 | 25 | ||
diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c index 53f371ed4568..75c158b0353f 100644 --- a/arch/arm64/kernel/paravirt.c +++ b/arch/arm64/kernel/paravirt.c | |||
@@ -21,5 +21,5 @@ | |||
21 | struct static_key paravirt_steal_enabled; | 21 | struct static_key paravirt_steal_enabled; |
22 | struct static_key paravirt_steal_rq_enabled; | 22 | struct static_key paravirt_steal_rq_enabled; |
23 | 23 | ||
24 | struct pv_time_ops pv_time_ops; | 24 | struct paravirt_patch_template pv_ops; |
25 | EXPORT_SYMBOL_GPL(pv_time_ops); | 25 | EXPORT_SYMBOL_GPL(pv_ops); |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ff425a2d286c..46d42af4501a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -523,6 +523,7 @@ config X86_VSMP | |||
523 | bool "ScaleMP vSMP" | 523 | bool "ScaleMP vSMP" |
524 | select HYPERVISOR_GUEST | 524 | select HYPERVISOR_GUEST |
525 | select PARAVIRT | 525 | select PARAVIRT |
526 | select PARAVIRT_XXL | ||
526 | depends on X86_64 && PCI | 527 | depends on X86_64 && PCI |
527 | depends on X86_EXTENDED_PLATFORM | 528 | depends on X86_EXTENDED_PLATFORM |
528 | depends on SMP | 529 | depends on SMP |
@@ -753,6 +754,9 @@ config PARAVIRT | |||
753 | over full virtualization. However, when run without a hypervisor | 754 | over full virtualization. However, when run without a hypervisor |
754 | the kernel is theoretically slower and slightly larger. | 755 | the kernel is theoretically slower and slightly larger. |
755 | 756 | ||
757 | config PARAVIRT_XXL | ||
758 | bool | ||
759 | |||
756 | config PARAVIRT_DEBUG | 760 | config PARAVIRT_DEBUG |
757 | bool "paravirt-ops debugging" | 761 | bool "paravirt-ops debugging" |
758 | depends on PARAVIRT && DEBUG_KERNEL | 762 | depends on PARAVIRT && DEBUG_KERNEL |
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index a423bdb42686..a1d5918765f3 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h | |||
@@ -9,6 +9,7 @@ | |||
9 | * paravirt and debugging variants are added.) | 9 | * paravirt and debugging variants are added.) |
10 | */ | 10 | */ |
11 | #undef CONFIG_PARAVIRT | 11 | #undef CONFIG_PARAVIRT |
12 | #undef CONFIG_PARAVIRT_XXL | ||
12 | #undef CONFIG_PARAVIRT_SPINLOCKS | 13 | #undef CONFIG_PARAVIRT_SPINLOCKS |
13 | #undef CONFIG_KASAN | 14 | #undef CONFIG_KASAN |
14 | 15 | ||
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index fbbf1ba57ec6..687e47f8a796 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S | |||
@@ -783,7 +783,7 @@ GLOBAL(__begin_SYSENTER_singlestep_region) | |||
783 | * will ignore all of the single-step traps generated in this range. | 783 | * will ignore all of the single-step traps generated in this range. |
784 | */ | 784 | */ |
785 | 785 | ||
786 | #ifdef CONFIG_XEN | 786 | #ifdef CONFIG_XEN_PV |
787 | /* | 787 | /* |
788 | * Xen doesn't set %esp to be precisely what the normal SYSENTER | 788 | * Xen doesn't set %esp to be precisely what the normal SYSENTER |
789 | * entry point expects, so fix it up before using the normal path. | 789 | * entry point expects, so fix it up before using the normal path. |
@@ -1241,7 +1241,7 @@ ENTRY(spurious_interrupt_bug) | |||
1241 | jmp common_exception | 1241 | jmp common_exception |
1242 | END(spurious_interrupt_bug) | 1242 | END(spurious_interrupt_bug) |
1243 | 1243 | ||
1244 | #ifdef CONFIG_XEN | 1244 | #ifdef CONFIG_XEN_PV |
1245 | ENTRY(xen_hypervisor_callback) | 1245 | ENTRY(xen_hypervisor_callback) |
1246 | pushl $-1 /* orig_ax = -1 => not a system call */ | 1246 | pushl $-1 /* orig_ax = -1 => not a system call */ |
1247 | SAVE_ALL | 1247 | SAVE_ALL |
@@ -1322,11 +1322,13 @@ ENTRY(xen_failsafe_callback) | |||
1322 | _ASM_EXTABLE(3b, 8b) | 1322 | _ASM_EXTABLE(3b, 8b) |
1323 | _ASM_EXTABLE(4b, 9b) | 1323 | _ASM_EXTABLE(4b, 9b) |
1324 | ENDPROC(xen_failsafe_callback) | 1324 | ENDPROC(xen_failsafe_callback) |
1325 | #endif /* CONFIG_XEN_PV */ | ||
1325 | 1326 | ||
1327 | #ifdef CONFIG_XEN_PVHVM | ||
1326 | BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, | 1328 | BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, |
1327 | xen_evtchn_do_upcall) | 1329 | xen_evtchn_do_upcall) |
1330 | #endif | ||
1328 | 1331 | ||
1329 | #endif /* CONFIG_XEN */ | ||
1330 | 1332 | ||
1331 | #if IS_ENABLED(CONFIG_HYPERV) | 1333 | #if IS_ENABLED(CONFIG_HYPERV) |
1332 | 1334 | ||
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index f95dcb209fdf..7c5ce0a6c4d2 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S | |||
@@ -1050,7 +1050,7 @@ ENTRY(do_softirq_own_stack) | |||
1050 | ret | 1050 | ret |
1051 | ENDPROC(do_softirq_own_stack) | 1051 | ENDPROC(do_softirq_own_stack) |
1052 | 1052 | ||
1053 | #ifdef CONFIG_XEN | 1053 | #ifdef CONFIG_XEN_PV |
1054 | idtentry hypervisor_callback xen_do_hypervisor_callback has_error_code=0 | 1054 | idtentry hypervisor_callback xen_do_hypervisor_callback has_error_code=0 |
1055 | 1055 | ||
1056 | /* | 1056 | /* |
@@ -1130,11 +1130,13 @@ ENTRY(xen_failsafe_callback) | |||
1130 | ENCODE_FRAME_POINTER | 1130 | ENCODE_FRAME_POINTER |
1131 | jmp error_exit | 1131 | jmp error_exit |
1132 | END(xen_failsafe_callback) | 1132 | END(xen_failsafe_callback) |
1133 | #endif /* CONFIG_XEN_PV */ | ||
1133 | 1134 | ||
1135 | #ifdef CONFIG_XEN_PVHVM | ||
1134 | apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ | 1136 | apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ |
1135 | xen_hvm_callback_vector xen_evtchn_do_upcall | 1137 | xen_hvm_callback_vector xen_evtchn_do_upcall |
1138 | #endif | ||
1136 | 1139 | ||
1137 | #endif /* CONFIG_XEN */ | ||
1138 | 1140 | ||
1139 | #if IS_ENABLED(CONFIG_HYPERV) | 1141 | #if IS_ENABLED(CONFIG_HYPERV) |
1140 | apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ | 1142 | apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ |
@@ -1151,7 +1153,7 @@ idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK | |||
1151 | idtentry int3 do_int3 has_error_code=0 | 1153 | idtentry int3 do_int3 has_error_code=0 |
1152 | idtentry stack_segment do_stack_segment has_error_code=1 | 1154 | idtentry stack_segment do_stack_segment has_error_code=1 |
1153 | 1155 | ||
1154 | #ifdef CONFIG_XEN | 1156 | #ifdef CONFIG_XEN_PV |
1155 | idtentry xennmi do_nmi has_error_code=0 | 1157 | idtentry xennmi do_nmi has_error_code=0 |
1156 | idtentry xendebug do_debug has_error_code=0 | 1158 | idtentry xendebug do_debug has_error_code=0 |
1157 | idtentry xenint3 do_int3 has_error_code=0 | 1159 | idtentry xenint3 do_int3 has_error_code=0 |
diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile index b21ee65c4101..1c11f9420a82 100644 --- a/arch/x86/hyperv/Makefile +++ b/arch/x86/hyperv/Makefile | |||
@@ -1,2 +1,6 @@ | |||
1 | obj-y := hv_init.o mmu.o nested.o | 1 | obj-y := hv_init.o mmu.o nested.o |
2 | obj-$(CONFIG_X86_64) += hv_apic.o | 2 | obj-$(CONFIG_X86_64) += hv_apic.o |
3 | |||
4 | ifdef CONFIG_X86_64 | ||
5 | obj-$(CONFIG_PARAVIRT_SPINLOCKS) += hv_spinlock.o | ||
6 | endif | ||
diff --git a/arch/x86/hyperv/hv_spinlock.c b/arch/x86/hyperv/hv_spinlock.c new file mode 100644 index 000000000000..a861b0456b1a --- /dev/null +++ b/arch/x86/hyperv/hv_spinlock.c | |||
@@ -0,0 +1,88 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | /* | ||
4 | * Hyper-V specific spinlock code. | ||
5 | * | ||
6 | * Copyright (C) 2018, Intel, Inc. | ||
7 | * | ||
8 | * Author : Yi Sun <yi.y.sun@intel.com> | ||
9 | */ | ||
10 | |||
11 | #define pr_fmt(fmt) "Hyper-V: " fmt | ||
12 | |||
13 | #include <linux/spinlock.h> | ||
14 | |||
15 | #include <asm/mshyperv.h> | ||
16 | #include <asm/paravirt.h> | ||
17 | #include <asm/apic.h> | ||
18 | |||
19 | static bool __initdata hv_pvspin = true; | ||
20 | |||
21 | static void hv_qlock_kick(int cpu) | ||
22 | { | ||
23 | apic->send_IPI(cpu, X86_PLATFORM_IPI_VECTOR); | ||
24 | } | ||
25 | |||
26 | static void hv_qlock_wait(u8 *byte, u8 val) | ||
27 | { | ||
28 | unsigned long msr_val; | ||
29 | unsigned long flags; | ||
30 | |||
31 | if (in_nmi()) | ||
32 | return; | ||
33 | |||
34 | /* | ||
35 | * Reading HV_X64_MSR_GUEST_IDLE MSR tells the hypervisor that the | ||
36 | * vCPU can be put into 'idle' state. This 'idle' state is | ||
37 | * terminated by an IPI, usually from hv_qlock_kick(), even if | ||
38 | * interrupts are disabled on the vCPU. | ||
39 | * | ||
40 | * To prevent a race against the unlock path it is required to | ||
41 | * disable interrupts before accessing the HV_X64_MSR_GUEST_IDLE | ||
42 | * MSR. Otherwise, if the IPI from hv_qlock_kick() arrives between | ||
43 | * the lock value check and the rdmsrl() then the vCPU might be put | ||
44 | * into 'idle' state by the hypervisor and kept in that state for | ||
45 | * an unspecified amount of time. | ||
46 | */ | ||
47 | local_irq_save(flags); | ||
48 | /* | ||
49 | * Only issue the rdmsrl() when the lock state has not changed. | ||
50 | */ | ||
51 | if (READ_ONCE(*byte) == val) | ||
52 | rdmsrl(HV_X64_MSR_GUEST_IDLE, msr_val); | ||
53 | local_irq_restore(flags); | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * Hyper-V does not support this so far. | ||
58 | */ | ||
59 | bool hv_vcpu_is_preempted(int vcpu) | ||
60 | { | ||
61 | return false; | ||
62 | } | ||
63 | PV_CALLEE_SAVE_REGS_THUNK(hv_vcpu_is_preempted); | ||
64 | |||
65 | void __init hv_init_spinlocks(void) | ||
66 | { | ||
67 | if (!hv_pvspin || !apic || | ||
68 | !(ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) || | ||
69 | !(ms_hyperv.features & HV_X64_MSR_GUEST_IDLE_AVAILABLE)) { | ||
70 | pr_info("PV spinlocks disabled\n"); | ||
71 | return; | ||
72 | } | ||
73 | pr_info("PV spinlocks enabled\n"); | ||
74 | |||
75 | __pv_init_lock_hash(); | ||
76 | pv_ops.lock.queued_spin_lock_slowpath = __pv_queued_spin_lock_slowpath; | ||
77 | pv_ops.lock.queued_spin_unlock = PV_CALLEE_SAVE(__pv_queued_spin_unlock); | ||
78 | pv_ops.lock.wait = hv_qlock_wait; | ||
79 | pv_ops.lock.kick = hv_qlock_kick; | ||
80 | pv_ops.lock.vcpu_is_preempted = PV_CALLEE_SAVE(hv_vcpu_is_preempted); | ||
81 | } | ||
82 | |||
83 | static __init int hv_parse_nopvspin(char *arg) | ||
84 | { | ||
85 | hv_pvspin = false; | ||
86 | return 0; | ||
87 | } | ||
88 | early_param("hv_nopvspin", hv_parse_nopvspin); | ||
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c index ef5f29f913d7..e65d7fe6489f 100644 --- a/arch/x86/hyperv/mmu.c +++ b/arch/x86/hyperv/mmu.c | |||
@@ -231,6 +231,6 @@ void hyperv_setup_mmu_ops(void) | |||
231 | return; | 231 | return; |
232 | 232 | ||
233 | pr_info("Using hypercall for remote TLB flush\n"); | 233 | pr_info("Using hypercall for remote TLB flush\n"); |
234 | pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others; | 234 | pv_ops.mmu.flush_tlb_others = hyperv_flush_tlb_others; |
235 | pv_mmu_ops.tlb_remove_table = tlb_remove_table; | 235 | pv_ops.mmu.tlb_remove_table = tlb_remove_table; |
236 | } | 236 | } |
diff --git a/arch/x86/include/asm/debugreg.h b/arch/x86/include/asm/debugreg.h index 4505ac2735ad..9e5ca30738e5 100644 --- a/arch/x86/include/asm/debugreg.h +++ b/arch/x86/include/asm/debugreg.h | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | DECLARE_PER_CPU(unsigned long, cpu_dr7); | 9 | DECLARE_PER_CPU(unsigned long, cpu_dr7); |
10 | 10 | ||
11 | #ifndef CONFIG_PARAVIRT | 11 | #ifndef CONFIG_PARAVIRT_XXL |
12 | /* | 12 | /* |
13 | * These special macros can be used to get or set a debugging register | 13 | * These special macros can be used to get or set a debugging register |
14 | */ | 14 | */ |
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 13c5ee878a47..68a99d2a5f33 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
@@ -108,7 +108,7 @@ static inline int desc_empty(const void *ptr) | |||
108 | return !(desc[0] | desc[1]); | 108 | return !(desc[0] | desc[1]); |
109 | } | 109 | } |
110 | 110 | ||
111 | #ifdef CONFIG_PARAVIRT | 111 | #ifdef CONFIG_PARAVIRT_XXL |
112 | #include <asm/paravirt.h> | 112 | #include <asm/paravirt.h> |
113 | #else | 113 | #else |
114 | #define load_TR_desc() native_load_tr_desc() | 114 | #define load_TR_desc() native_load_tr_desc() |
@@ -134,7 +134,7 @@ static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries) | |||
134 | static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries) | 134 | static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries) |
135 | { | 135 | { |
136 | } | 136 | } |
137 | #endif /* CONFIG_PARAVIRT */ | 137 | #endif /* CONFIG_PARAVIRT_XXL */ |
138 | 138 | ||
139 | #define store_ldt(ldt) asm("sldt %0" : "=m"(ldt)) | 139 | #define store_ldt(ldt) asm("sldt %0" : "=m"(ldt)) |
140 | 140 | ||
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index 6390bd8c141b..50ba74a34a37 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h | |||
@@ -162,7 +162,7 @@ void __native_set_fixmap(enum fixed_addresses idx, pte_t pte); | |||
162 | void native_set_fixmap(enum fixed_addresses idx, | 162 | void native_set_fixmap(enum fixed_addresses idx, |
163 | phys_addr_t phys, pgprot_t flags); | 163 | phys_addr_t phys, pgprot_t flags); |
164 | 164 | ||
165 | #ifndef CONFIG_PARAVIRT | 165 | #ifndef CONFIG_PARAVIRT_XXL |
166 | static inline void __set_fixmap(enum fixed_addresses idx, | 166 | static inline void __set_fixmap(enum fixed_addresses idx, |
167 | phys_addr_t phys, pgprot_t flags) | 167 | phys_addr_t phys, pgprot_t flags) |
168 | { | 168 | { |
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h index 00e01d215f74..4139f7650fe5 100644 --- a/arch/x86/include/asm/hyperv-tlfs.h +++ b/arch/x86/include/asm/hyperv-tlfs.h | |||
@@ -38,6 +38,8 @@ | |||
38 | #define HV_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) | 38 | #define HV_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) |
39 | /* Partition reference TSC MSR is available */ | 39 | /* Partition reference TSC MSR is available */ |
40 | #define HV_MSR_REFERENCE_TSC_AVAILABLE (1 << 9) | 40 | #define HV_MSR_REFERENCE_TSC_AVAILABLE (1 << 9) |
41 | /* Partition Guest IDLE MSR is available */ | ||
42 | #define HV_X64_MSR_GUEST_IDLE_AVAILABLE (1 << 10) | ||
41 | 43 | ||
42 | /* A partition's reference time stamp counter (TSC) page */ | 44 | /* A partition's reference time stamp counter (TSC) page */ |
43 | #define HV_X64_MSR_REFERENCE_TSC 0x40000021 | 45 | #define HV_X64_MSR_REFERENCE_TSC 0x40000021 |
@@ -246,6 +248,9 @@ | |||
246 | #define HV_X64_MSR_STIMER3_CONFIG 0x400000B6 | 248 | #define HV_X64_MSR_STIMER3_CONFIG 0x400000B6 |
247 | #define HV_X64_MSR_STIMER3_COUNT 0x400000B7 | 249 | #define HV_X64_MSR_STIMER3_COUNT 0x400000B7 |
248 | 250 | ||
251 | /* Hyper-V guest idle MSR */ | ||
252 | #define HV_X64_MSR_GUEST_IDLE 0x400000F0 | ||
253 | |||
249 | /* Hyper-V guest crash notification MSR's */ | 254 | /* Hyper-V guest crash notification MSR's */ |
250 | #define HV_X64_MSR_CRASH_P0 0x40000100 | 255 | #define HV_X64_MSR_CRASH_P0 0x40000100 |
251 | #define HV_X64_MSR_CRASH_P1 0x40000101 | 256 | #define HV_X64_MSR_CRASH_P1 0x40000101 |
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index 15450a675031..058e40fed167 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h | |||
@@ -64,7 +64,7 @@ static inline __cpuidle void native_halt(void) | |||
64 | 64 | ||
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | #ifdef CONFIG_PARAVIRT | 67 | #ifdef CONFIG_PARAVIRT_XXL |
68 | #include <asm/paravirt.h> | 68 | #include <asm/paravirt.h> |
69 | #else | 69 | #else |
70 | #ifndef __ASSEMBLY__ | 70 | #ifndef __ASSEMBLY__ |
@@ -123,6 +123,10 @@ static inline notrace unsigned long arch_local_irq_save(void) | |||
123 | #define DISABLE_INTERRUPTS(x) cli | 123 | #define DISABLE_INTERRUPTS(x) cli |
124 | 124 | ||
125 | #ifdef CONFIG_X86_64 | 125 | #ifdef CONFIG_X86_64 |
126 | #ifdef CONFIG_DEBUG_ENTRY | ||
127 | #define SAVE_FLAGS(x) pushfq; popq %rax | ||
128 | #endif | ||
129 | |||
126 | #define SWAPGS swapgs | 130 | #define SWAPGS swapgs |
127 | /* | 131 | /* |
128 | * Currently paravirt can't handle swapgs nicely when we | 132 | * Currently paravirt can't handle swapgs nicely when we |
@@ -135,8 +139,6 @@ static inline notrace unsigned long arch_local_irq_save(void) | |||
135 | */ | 139 | */ |
136 | #define SWAPGS_UNSAFE_STACK swapgs | 140 | #define SWAPGS_UNSAFE_STACK swapgs |
137 | 141 | ||
138 | #define PARAVIRT_ADJUST_EXCEPTION_FRAME /* */ | ||
139 | |||
140 | #define INTERRUPT_RETURN jmp native_iret | 142 | #define INTERRUPT_RETURN jmp native_iret |
141 | #define USERGS_SYSRET64 \ | 143 | #define USERGS_SYSRET64 \ |
142 | swapgs; \ | 144 | swapgs; \ |
@@ -145,18 +147,12 @@ static inline notrace unsigned long arch_local_irq_save(void) | |||
145 | swapgs; \ | 147 | swapgs; \ |
146 | sysretl | 148 | sysretl |
147 | 149 | ||
148 | #ifdef CONFIG_DEBUG_ENTRY | ||
149 | #define SAVE_FLAGS(x) pushfq; popq %rax | ||
150 | #endif | ||
151 | #else | 150 | #else |
152 | #define INTERRUPT_RETURN iret | 151 | #define INTERRUPT_RETURN iret |
153 | #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit | ||
154 | #define GET_CR0_INTO_EAX movl %cr0, %eax | ||
155 | #endif | 152 | #endif |
156 | 153 | ||
157 | |||
158 | #endif /* __ASSEMBLY__ */ | 154 | #endif /* __ASSEMBLY__ */ |
159 | #endif /* CONFIG_PARAVIRT */ | 155 | #endif /* CONFIG_PARAVIRT_XXL */ |
160 | 156 | ||
161 | #ifndef __ASSEMBLY__ | 157 | #ifndef __ASSEMBLY__ |
162 | static inline int arch_irqs_disabled_flags(unsigned long flags) | 158 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index eeeb9289c764..0ca50611e8ce 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h | |||
@@ -16,12 +16,12 @@ | |||
16 | 16 | ||
17 | extern atomic64_t last_mm_ctx_id; | 17 | extern atomic64_t last_mm_ctx_id; |
18 | 18 | ||
19 | #ifndef CONFIG_PARAVIRT | 19 | #ifndef CONFIG_PARAVIRT_XXL |
20 | static inline void paravirt_activate_mm(struct mm_struct *prev, | 20 | static inline void paravirt_activate_mm(struct mm_struct *prev, |
21 | struct mm_struct *next) | 21 | struct mm_struct *next) |
22 | { | 22 | { |
23 | } | 23 | } |
24 | #endif /* !CONFIG_PARAVIRT */ | 24 | #endif /* !CONFIG_PARAVIRT_XXL */ |
25 | 25 | ||
26 | #ifdef CONFIG_PERF_EVENTS | 26 | #ifdef CONFIG_PERF_EVENTS |
27 | 27 | ||
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index f37704497d8f..0d6271cce198 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h | |||
@@ -351,6 +351,8 @@ int hyperv_flush_guest_mapping(u64 as); | |||
351 | 351 | ||
352 | #ifdef CONFIG_X86_64 | 352 | #ifdef CONFIG_X86_64 |
353 | void hv_apic_init(void); | 353 | void hv_apic_init(void); |
354 | void __init hv_init_spinlocks(void); | ||
355 | bool hv_vcpu_is_preempted(int vcpu); | ||
354 | #else | 356 | #else |
355 | static inline void hv_apic_init(void) {} | 357 | static inline void hv_apic_init(void) {} |
356 | #endif | 358 | #endif |
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 04addd6e0a4a..91e4cf189914 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h | |||
@@ -242,7 +242,7 @@ static inline unsigned long long native_read_pmc(int counter) | |||
242 | return EAX_EDX_VAL(val, low, high); | 242 | return EAX_EDX_VAL(val, low, high); |
243 | } | 243 | } |
244 | 244 | ||
245 | #ifdef CONFIG_PARAVIRT | 245 | #ifdef CONFIG_PARAVIRT_XXL |
246 | #include <asm/paravirt.h> | 246 | #include <asm/paravirt.h> |
247 | #else | 247 | #else |
248 | #include <linux/errno.h> | 248 | #include <linux/errno.h> |
@@ -305,7 +305,7 @@ do { \ | |||
305 | 305 | ||
306 | #define rdpmcl(counter, val) ((val) = native_read_pmc(counter)) | 306 | #define rdpmcl(counter, val) ((val) = native_read_pmc(counter)) |
307 | 307 | ||
308 | #endif /* !CONFIG_PARAVIRT */ | 308 | #endif /* !CONFIG_PARAVIRT_XXL */ |
309 | 309 | ||
310 | /* | 310 | /* |
311 | * 64-bit version of wrmsr_safe(): | 311 | * 64-bit version of wrmsr_safe(): |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index e375d4266b53..4bf42f9e4eea 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -17,16 +17,73 @@ | |||
17 | #include <linux/cpumask.h> | 17 | #include <linux/cpumask.h> |
18 | #include <asm/frame.h> | 18 | #include <asm/frame.h> |
19 | 19 | ||
20 | static inline unsigned long long paravirt_sched_clock(void) | ||
21 | { | ||
22 | return PVOP_CALL0(unsigned long long, time.sched_clock); | ||
23 | } | ||
24 | |||
25 | struct static_key; | ||
26 | extern struct static_key paravirt_steal_enabled; | ||
27 | extern struct static_key paravirt_steal_rq_enabled; | ||
28 | |||
29 | static inline u64 paravirt_steal_clock(int cpu) | ||
30 | { | ||
31 | return PVOP_CALL1(u64, time.steal_clock, cpu); | ||
32 | } | ||
33 | |||
34 | /* The paravirtualized I/O functions */ | ||
35 | static inline void slow_down_io(void) | ||
36 | { | ||
37 | pv_ops.cpu.io_delay(); | ||
38 | #ifdef REALLY_SLOW_IO | ||
39 | pv_ops.cpu.io_delay(); | ||
40 | pv_ops.cpu.io_delay(); | ||
41 | pv_ops.cpu.io_delay(); | ||
42 | #endif | ||
43 | } | ||
44 | |||
45 | static inline void __flush_tlb(void) | ||
46 | { | ||
47 | PVOP_VCALL0(mmu.flush_tlb_user); | ||
48 | } | ||
49 | |||
50 | static inline void __flush_tlb_global(void) | ||
51 | { | ||
52 | PVOP_VCALL0(mmu.flush_tlb_kernel); | ||
53 | } | ||
54 | |||
55 | static inline void __flush_tlb_one_user(unsigned long addr) | ||
56 | { | ||
57 | PVOP_VCALL1(mmu.flush_tlb_one_user, addr); | ||
58 | } | ||
59 | |||
60 | static inline void flush_tlb_others(const struct cpumask *cpumask, | ||
61 | const struct flush_tlb_info *info) | ||
62 | { | ||
63 | PVOP_VCALL2(mmu.flush_tlb_others, cpumask, info); | ||
64 | } | ||
65 | |||
66 | static inline void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table) | ||
67 | { | ||
68 | PVOP_VCALL2(mmu.tlb_remove_table, tlb, table); | ||
69 | } | ||
70 | |||
71 | static inline void paravirt_arch_exit_mmap(struct mm_struct *mm) | ||
72 | { | ||
73 | PVOP_VCALL1(mmu.exit_mmap, mm); | ||
74 | } | ||
75 | |||
76 | #ifdef CONFIG_PARAVIRT_XXL | ||
20 | static inline void load_sp0(unsigned long sp0) | 77 | static inline void load_sp0(unsigned long sp0) |
21 | { | 78 | { |
22 | PVOP_VCALL1(pv_cpu_ops.load_sp0, sp0); | 79 | PVOP_VCALL1(cpu.load_sp0, sp0); |
23 | } | 80 | } |
24 | 81 | ||
25 | /* The paravirtualized CPUID instruction. */ | 82 | /* The paravirtualized CPUID instruction. */ |
26 | static inline void __cpuid(unsigned int *eax, unsigned int *ebx, | 83 | static inline void __cpuid(unsigned int *eax, unsigned int *ebx, |
27 | unsigned int *ecx, unsigned int *edx) | 84 | unsigned int *ecx, unsigned int *edx) |
28 | { | 85 | { |
29 | PVOP_VCALL4(pv_cpu_ops.cpuid, eax, ebx, ecx, edx); | 86 | PVOP_VCALL4(cpu.cpuid, eax, ebx, ecx, edx); |
30 | } | 87 | } |
31 | 88 | ||
32 | /* | 89 | /* |
@@ -34,98 +91,98 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx, | |||
34 | */ | 91 | */ |
35 | static inline unsigned long paravirt_get_debugreg(int reg) | 92 | static inline unsigned long paravirt_get_debugreg(int reg) |
36 | { | 93 | { |
37 | return PVOP_CALL1(unsigned long, pv_cpu_ops.get_debugreg, reg); | 94 | return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg); |
38 | } | 95 | } |
39 | #define get_debugreg(var, reg) var = paravirt_get_debugreg(reg) | 96 | #define get_debugreg(var, reg) var = paravirt_get_debugreg(reg) |
40 | static inline void set_debugreg(unsigned long val, int reg) | 97 | static inline void set_debugreg(unsigned long val, int reg) |
41 | { | 98 | { |
42 | PVOP_VCALL2(pv_cpu_ops.set_debugreg, reg, val); | 99 | PVOP_VCALL2(cpu.set_debugreg, reg, val); |
43 | } | 100 | } |
44 | 101 | ||
45 | static inline unsigned long read_cr0(void) | 102 | static inline unsigned long read_cr0(void) |
46 | { | 103 | { |
47 | return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr0); | 104 | return PVOP_CALL0(unsigned long, cpu.read_cr0); |
48 | } | 105 | } |
49 | 106 | ||
50 | static inline void write_cr0(unsigned long x) | 107 | static inline void write_cr0(unsigned long x) |
51 | { | 108 | { |
52 | PVOP_VCALL1(pv_cpu_ops.write_cr0, x); | 109 | PVOP_VCALL1(cpu.write_cr0, x); |
53 | } | 110 | } |
54 | 111 | ||
55 | static inline unsigned long read_cr2(void) | 112 | static inline unsigned long read_cr2(void) |
56 | { | 113 | { |
57 | return PVOP_CALL0(unsigned long, pv_mmu_ops.read_cr2); | 114 | return PVOP_CALL0(unsigned long, mmu.read_cr2); |
58 | } | 115 | } |
59 | 116 | ||
60 | static inline void write_cr2(unsigned long x) | 117 | static inline void write_cr2(unsigned long x) |
61 | { | 118 | { |
62 | PVOP_VCALL1(pv_mmu_ops.write_cr2, x); | 119 | PVOP_VCALL1(mmu.write_cr2, x); |
63 | } | 120 | } |
64 | 121 | ||
65 | static inline unsigned long __read_cr3(void) | 122 | static inline unsigned long __read_cr3(void) |
66 | { | 123 | { |
67 | return PVOP_CALL0(unsigned long, pv_mmu_ops.read_cr3); | 124 | return PVOP_CALL0(unsigned long, mmu.read_cr3); |
68 | } | 125 | } |
69 | 126 | ||
70 | static inline void write_cr3(unsigned long x) | 127 | static inline void write_cr3(unsigned long x) |
71 | { | 128 | { |
72 | PVOP_VCALL1(pv_mmu_ops.write_cr3, x); | 129 | PVOP_VCALL1(mmu.write_cr3, x); |
73 | } | 130 | } |
74 | 131 | ||
75 | static inline void __write_cr4(unsigned long x) | 132 | static inline void __write_cr4(unsigned long x) |
76 | { | 133 | { |
77 | PVOP_VCALL1(pv_cpu_ops.write_cr4, x); | 134 | PVOP_VCALL1(cpu.write_cr4, x); |
78 | } | 135 | } |
79 | 136 | ||
80 | #ifdef CONFIG_X86_64 | 137 | #ifdef CONFIG_X86_64 |
81 | static inline unsigned long read_cr8(void) | 138 | static inline unsigned long read_cr8(void) |
82 | { | 139 | { |
83 | return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr8); | 140 | return PVOP_CALL0(unsigned long, cpu.read_cr8); |
84 | } | 141 | } |
85 | 142 | ||
86 | static inline void write_cr8(unsigned long x) | 143 | static inline void write_cr8(unsigned long x) |
87 | { | 144 | { |
88 | PVOP_VCALL1(pv_cpu_ops.write_cr8, x); | 145 | PVOP_VCALL1(cpu.write_cr8, x); |
89 | } | 146 | } |
90 | #endif | 147 | #endif |
91 | 148 | ||
92 | static inline void arch_safe_halt(void) | 149 | static inline void arch_safe_halt(void) |
93 | { | 150 | { |
94 | PVOP_VCALL0(pv_irq_ops.safe_halt); | 151 | PVOP_VCALL0(irq.safe_halt); |
95 | } | 152 | } |
96 | 153 | ||
97 | static inline void halt(void) | 154 | static inline void halt(void) |
98 | { | 155 | { |
99 | PVOP_VCALL0(pv_irq_ops.halt); | 156 | PVOP_VCALL0(irq.halt); |
100 | } | 157 | } |
101 | 158 | ||
102 | static inline void wbinvd(void) | 159 | static inline void wbinvd(void) |
103 | { | 160 | { |
104 | PVOP_VCALL0(pv_cpu_ops.wbinvd); | 161 | PVOP_VCALL0(cpu.wbinvd); |
105 | } | 162 | } |
106 | 163 | ||
107 | #define get_kernel_rpl() (pv_info.kernel_rpl) | 164 | #define get_kernel_rpl() (pv_info.kernel_rpl) |
108 | 165 | ||
109 | static inline u64 paravirt_read_msr(unsigned msr) | 166 | static inline u64 paravirt_read_msr(unsigned msr) |
110 | { | 167 | { |
111 | return PVOP_CALL1(u64, pv_cpu_ops.read_msr, msr); | 168 | return PVOP_CALL1(u64, cpu.read_msr, msr); |
112 | } | 169 | } |
113 | 170 | ||
114 | static inline void paravirt_write_msr(unsigned msr, | 171 | static inline void paravirt_write_msr(unsigned msr, |
115 | unsigned low, unsigned high) | 172 | unsigned low, unsigned high) |
116 | { | 173 | { |
117 | PVOP_VCALL3(pv_cpu_ops.write_msr, msr, low, high); | 174 | PVOP_VCALL3(cpu.write_msr, msr, low, high); |
118 | } | 175 | } |
119 | 176 | ||
120 | static inline u64 paravirt_read_msr_safe(unsigned msr, int *err) | 177 | static inline u64 paravirt_read_msr_safe(unsigned msr, int *err) |
121 | { | 178 | { |
122 | return PVOP_CALL2(u64, pv_cpu_ops.read_msr_safe, msr, err); | 179 | return PVOP_CALL2(u64, cpu.read_msr_safe, msr, err); |
123 | } | 180 | } |
124 | 181 | ||
125 | static inline int paravirt_write_msr_safe(unsigned msr, | 182 | static inline int paravirt_write_msr_safe(unsigned msr, |
126 | unsigned low, unsigned high) | 183 | unsigned low, unsigned high) |
127 | { | 184 | { |
128 | return PVOP_CALL3(int, pv_cpu_ops.write_msr_safe, msr, low, high); | 185 | return PVOP_CALL3(int, cpu.write_msr_safe, msr, low, high); |
129 | } | 186 | } |
130 | 187 | ||
131 | #define rdmsr(msr, val1, val2) \ | 188 | #define rdmsr(msr, val1, val2) \ |
@@ -170,23 +227,9 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) | |||
170 | return err; | 227 | return err; |
171 | } | 228 | } |
172 | 229 | ||
173 | static inline unsigned long long paravirt_sched_clock(void) | ||
174 | { | ||
175 | return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock); | ||
176 | } | ||
177 | |||
178 | struct static_key; | ||
179 | extern struct static_key paravirt_steal_enabled; | ||
180 | extern struct static_key paravirt_steal_rq_enabled; | ||
181 | |||
182 | static inline u64 paravirt_steal_clock(int cpu) | ||
183 | { | ||
184 | return PVOP_CALL1(u64, pv_time_ops.steal_clock, cpu); | ||
185 | } | ||
186 | |||
187 | static inline unsigned long long paravirt_read_pmc(int counter) | 230 | static inline unsigned long long paravirt_read_pmc(int counter) |
188 | { | 231 | { |
189 | return PVOP_CALL1(u64, pv_cpu_ops.read_pmc, counter); | 232 | return PVOP_CALL1(u64, cpu.read_pmc, counter); |
190 | } | 233 | } |
191 | 234 | ||
192 | #define rdpmc(counter, low, high) \ | 235 | #define rdpmc(counter, low, high) \ |
@@ -200,166 +243,127 @@ do { \ | |||
200 | 243 | ||
201 | static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries) | 244 | static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries) |
202 | { | 245 | { |
203 | PVOP_VCALL2(pv_cpu_ops.alloc_ldt, ldt, entries); | 246 | PVOP_VCALL2(cpu.alloc_ldt, ldt, entries); |
204 | } | 247 | } |
205 | 248 | ||
206 | static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries) | 249 | static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries) |
207 | { | 250 | { |
208 | PVOP_VCALL2(pv_cpu_ops.free_ldt, ldt, entries); | 251 | PVOP_VCALL2(cpu.free_ldt, ldt, entries); |
209 | } | 252 | } |
210 | 253 | ||
211 | static inline void load_TR_desc(void) | 254 | static inline void load_TR_desc(void) |
212 | { | 255 | { |
213 | PVOP_VCALL0(pv_cpu_ops.load_tr_desc); | 256 | PVOP_VCALL0(cpu.load_tr_desc); |
214 | } | 257 | } |
215 | static inline void load_gdt(const struct desc_ptr *dtr) | 258 | static inline void load_gdt(const struct desc_ptr *dtr) |
216 | { | 259 | { |
217 | PVOP_VCALL1(pv_cpu_ops.load_gdt, dtr); | 260 | PVOP_VCALL1(cpu.load_gdt, dtr); |
218 | } | 261 | } |
219 | static inline void load_idt(const struct desc_ptr *dtr) | 262 | static inline void load_idt(const struct desc_ptr *dtr) |
220 | { | 263 | { |
221 | PVOP_VCALL1(pv_cpu_ops.load_idt, dtr); | 264 | PVOP_VCALL1(cpu.load_idt, dtr); |
222 | } | 265 | } |
223 | static inline void set_ldt(const void *addr, unsigned entries) | 266 | static inline void set_ldt(const void *addr, unsigned entries) |
224 | { | 267 | { |
225 | PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries); | 268 | PVOP_VCALL2(cpu.set_ldt, addr, entries); |
226 | } | 269 | } |
227 | static inline unsigned long paravirt_store_tr(void) | 270 | static inline unsigned long paravirt_store_tr(void) |
228 | { | 271 | { |
229 | return PVOP_CALL0(unsigned long, pv_cpu_ops.store_tr); | 272 | return PVOP_CALL0(unsigned long, cpu.store_tr); |
230 | } | 273 | } |
274 | |||
231 | #define store_tr(tr) ((tr) = paravirt_store_tr()) | 275 | #define store_tr(tr) ((tr) = paravirt_store_tr()) |
232 | static inline void load_TLS(struct thread_struct *t, unsigned cpu) | 276 | static inline void load_TLS(struct thread_struct *t, unsigned cpu) |
233 | { | 277 | { |
234 | PVOP_VCALL2(pv_cpu_ops.load_tls, t, cpu); | 278 | PVOP_VCALL2(cpu.load_tls, t, cpu); |
235 | } | 279 | } |
236 | 280 | ||
237 | #ifdef CONFIG_X86_64 | 281 | #ifdef CONFIG_X86_64 |
238 | static inline void load_gs_index(unsigned int gs) | 282 | static inline void load_gs_index(unsigned int gs) |
239 | { | 283 | { |
240 | PVOP_VCALL1(pv_cpu_ops.load_gs_index, gs); | 284 | PVOP_VCALL1(cpu.load_gs_index, gs); |
241 | } | 285 | } |
242 | #endif | 286 | #endif |
243 | 287 | ||
244 | static inline void write_ldt_entry(struct desc_struct *dt, int entry, | 288 | static inline void write_ldt_entry(struct desc_struct *dt, int entry, |
245 | const void *desc) | 289 | const void *desc) |
246 | { | 290 | { |
247 | PVOP_VCALL3(pv_cpu_ops.write_ldt_entry, dt, entry, desc); | 291 | PVOP_VCALL3(cpu.write_ldt_entry, dt, entry, desc); |
248 | } | 292 | } |
249 | 293 | ||
250 | static inline void write_gdt_entry(struct desc_struct *dt, int entry, | 294 | static inline void write_gdt_entry(struct desc_struct *dt, int entry, |
251 | void *desc, int type) | 295 | void *desc, int type) |
252 | { | 296 | { |
253 | PVOP_VCALL4(pv_cpu_ops.write_gdt_entry, dt, entry, desc, type); | 297 | PVOP_VCALL4(cpu.write_gdt_entry, dt, entry, desc, type); |
254 | } | 298 | } |
255 | 299 | ||
256 | static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) | 300 | static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) |
257 | { | 301 | { |
258 | PVOP_VCALL3(pv_cpu_ops.write_idt_entry, dt, entry, g); | 302 | PVOP_VCALL3(cpu.write_idt_entry, dt, entry, g); |
259 | } | 303 | } |
260 | static inline void set_iopl_mask(unsigned mask) | 304 | static inline void set_iopl_mask(unsigned mask) |
261 | { | 305 | { |
262 | PVOP_VCALL1(pv_cpu_ops.set_iopl_mask, mask); | 306 | PVOP_VCALL1(cpu.set_iopl_mask, mask); |
263 | } | ||
264 | |||
265 | /* The paravirtualized I/O functions */ | ||
266 | static inline void slow_down_io(void) | ||
267 | { | ||
268 | pv_cpu_ops.io_delay(); | ||
269 | #ifdef REALLY_SLOW_IO | ||
270 | pv_cpu_ops.io_delay(); | ||
271 | pv_cpu_ops.io_delay(); | ||
272 | pv_cpu_ops.io_delay(); | ||
273 | #endif | ||
274 | } | 307 | } |
275 | 308 | ||
276 | static inline void paravirt_activate_mm(struct mm_struct *prev, | 309 | static inline void paravirt_activate_mm(struct mm_struct *prev, |
277 | struct mm_struct *next) | 310 | struct mm_struct *next) |
278 | { | 311 | { |
279 | PVOP_VCALL2(pv_mmu_ops.activate_mm, prev, next); | 312 | PVOP_VCALL2(mmu.activate_mm, prev, next); |
280 | } | 313 | } |
281 | 314 | ||
282 | static inline void paravirt_arch_dup_mmap(struct mm_struct *oldmm, | 315 | static inline void paravirt_arch_dup_mmap(struct mm_struct *oldmm, |
283 | struct mm_struct *mm) | 316 | struct mm_struct *mm) |
284 | { | 317 | { |
285 | PVOP_VCALL2(pv_mmu_ops.dup_mmap, oldmm, mm); | 318 | PVOP_VCALL2(mmu.dup_mmap, oldmm, mm); |
286 | } | ||
287 | |||
288 | static inline void paravirt_arch_exit_mmap(struct mm_struct *mm) | ||
289 | { | ||
290 | PVOP_VCALL1(pv_mmu_ops.exit_mmap, mm); | ||
291 | } | ||
292 | |||
293 | static inline void __flush_tlb(void) | ||
294 | { | ||
295 | PVOP_VCALL0(pv_mmu_ops.flush_tlb_user); | ||
296 | } | ||
297 | static inline void __flush_tlb_global(void) | ||
298 | { | ||
299 | PVOP_VCALL0(pv_mmu_ops.flush_tlb_kernel); | ||
300 | } | ||
301 | static inline void __flush_tlb_one_user(unsigned long addr) | ||
302 | { | ||
303 | PVOP_VCALL1(pv_mmu_ops.flush_tlb_one_user, addr); | ||
304 | } | ||
305 | |||
306 | static inline void flush_tlb_others(const struct cpumask *cpumask, | ||
307 | const struct flush_tlb_info *info) | ||
308 | { | ||
309 | PVOP_VCALL2(pv_mmu_ops.flush_tlb_others, cpumask, info); | ||
310 | } | ||
311 | |||
312 | static inline void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table) | ||
313 | { | ||
314 | PVOP_VCALL2(pv_mmu_ops.tlb_remove_table, tlb, table); | ||
315 | } | 319 | } |
316 | 320 | ||
317 | static inline int paravirt_pgd_alloc(struct mm_struct *mm) | 321 | static inline int paravirt_pgd_alloc(struct mm_struct *mm) |
318 | { | 322 | { |
319 | return PVOP_CALL1(int, pv_mmu_ops.pgd_alloc, mm); | 323 | return PVOP_CALL1(int, mmu.pgd_alloc, mm); |
320 | } | 324 | } |
321 | 325 | ||
322 | static inline void paravirt_pgd_free(struct mm_struct *mm, pgd_t *pgd) | 326 | static inline void paravirt_pgd_free(struct mm_struct *mm, pgd_t *pgd) |
323 | { | 327 | { |
324 | PVOP_VCALL2(pv_mmu_ops.pgd_free, mm, pgd); | 328 | PVOP_VCALL2(mmu.pgd_free, mm, pgd); |
325 | } | 329 | } |
326 | 330 | ||
327 | static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned long pfn) | 331 | static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned long pfn) |
328 | { | 332 | { |
329 | PVOP_VCALL2(pv_mmu_ops.alloc_pte, mm, pfn); | 333 | PVOP_VCALL2(mmu.alloc_pte, mm, pfn); |
330 | } | 334 | } |
331 | static inline void paravirt_release_pte(unsigned long pfn) | 335 | static inline void paravirt_release_pte(unsigned long pfn) |
332 | { | 336 | { |
333 | PVOP_VCALL1(pv_mmu_ops.release_pte, pfn); | 337 | PVOP_VCALL1(mmu.release_pte, pfn); |
334 | } | 338 | } |
335 | 339 | ||
336 | static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn) | 340 | static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn) |
337 | { | 341 | { |
338 | PVOP_VCALL2(pv_mmu_ops.alloc_pmd, mm, pfn); | 342 | PVOP_VCALL2(mmu.alloc_pmd, mm, pfn); |
339 | } | 343 | } |
340 | 344 | ||
341 | static inline void paravirt_release_pmd(unsigned long pfn) | 345 | static inline void paravirt_release_pmd(unsigned long pfn) |
342 | { | 346 | { |
343 | PVOP_VCALL1(pv_mmu_ops.release_pmd, pfn); | 347 | PVOP_VCALL1(mmu.release_pmd, pfn); |
344 | } | 348 | } |
345 | 349 | ||
346 | static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned long pfn) | 350 | static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned long pfn) |
347 | { | 351 | { |
348 | PVOP_VCALL2(pv_mmu_ops.alloc_pud, mm, pfn); | 352 | PVOP_VCALL2(mmu.alloc_pud, mm, pfn); |
349 | } | 353 | } |
350 | static inline void paravirt_release_pud(unsigned long pfn) | 354 | static inline void paravirt_release_pud(unsigned long pfn) |
351 | { | 355 | { |
352 | PVOP_VCALL1(pv_mmu_ops.release_pud, pfn); | 356 | PVOP_VCALL1(mmu.release_pud, pfn); |
353 | } | 357 | } |
354 | 358 | ||
355 | static inline void paravirt_alloc_p4d(struct mm_struct *mm, unsigned long pfn) | 359 | static inline void paravirt_alloc_p4d(struct mm_struct *mm, unsigned long pfn) |
356 | { | 360 | { |
357 | PVOP_VCALL2(pv_mmu_ops.alloc_p4d, mm, pfn); | 361 | PVOP_VCALL2(mmu.alloc_p4d, mm, pfn); |
358 | } | 362 | } |
359 | 363 | ||
360 | static inline void paravirt_release_p4d(unsigned long pfn) | 364 | static inline void paravirt_release_p4d(unsigned long pfn) |
361 | { | 365 | { |
362 | PVOP_VCALL1(pv_mmu_ops.release_p4d, pfn); | 366 | PVOP_VCALL1(mmu.release_p4d, pfn); |
363 | } | 367 | } |
364 | 368 | ||
365 | static inline pte_t __pte(pteval_t val) | 369 | static inline pte_t __pte(pteval_t val) |
@@ -367,13 +371,9 @@ static inline pte_t __pte(pteval_t val) | |||
367 | pteval_t ret; | 371 | pteval_t ret; |
368 | 372 | ||
369 | if (sizeof(pteval_t) > sizeof(long)) | 373 | if (sizeof(pteval_t) > sizeof(long)) |
370 | ret = PVOP_CALLEE2(pteval_t, | 374 | ret = PVOP_CALLEE2(pteval_t, mmu.make_pte, val, (u64)val >> 32); |
371 | pv_mmu_ops.make_pte, | ||
372 | val, (u64)val >> 32); | ||
373 | else | 375 | else |
374 | ret = PVOP_CALLEE1(pteval_t, | 376 | ret = PVOP_CALLEE1(pteval_t, mmu.make_pte, val); |
375 | pv_mmu_ops.make_pte, | ||
376 | val); | ||
377 | 377 | ||
378 | return (pte_t) { .pte = ret }; | 378 | return (pte_t) { .pte = ret }; |
379 | } | 379 | } |
@@ -383,11 +383,10 @@ static inline pteval_t pte_val(pte_t pte) | |||
383 | pteval_t ret; | 383 | pteval_t ret; |
384 | 384 | ||
385 | if (sizeof(pteval_t) > sizeof(long)) | 385 | if (sizeof(pteval_t) > sizeof(long)) |
386 | ret = PVOP_CALLEE2(pteval_t, pv_mmu_ops.pte_val, | 386 | ret = PVOP_CALLEE2(pteval_t, mmu.pte_val, |
387 | pte.pte, (u64)pte.pte >> 32); | 387 | pte.pte, (u64)pte.pte >> 32); |
388 | else | 388 | else |
389 | ret = PVOP_CALLEE1(pteval_t, pv_mmu_ops.pte_val, | 389 | ret = PVOP_CALLEE1(pteval_t, mmu.pte_val, pte.pte); |
390 | pte.pte); | ||
391 | 390 | ||
392 | return ret; | 391 | return ret; |
393 | } | 392 | } |
@@ -397,11 +396,9 @@ static inline pgd_t __pgd(pgdval_t val) | |||
397 | pgdval_t ret; | 396 | pgdval_t ret; |
398 | 397 | ||
399 | if (sizeof(pgdval_t) > sizeof(long)) | 398 | if (sizeof(pgdval_t) > sizeof(long)) |
400 | ret = PVOP_CALLEE2(pgdval_t, pv_mmu_ops.make_pgd, | 399 | ret = PVOP_CALLEE2(pgdval_t, mmu.make_pgd, val, (u64)val >> 32); |
401 | val, (u64)val >> 32); | ||
402 | else | 400 | else |
403 | ret = PVOP_CALLEE1(pgdval_t, pv_mmu_ops.make_pgd, | 401 | ret = PVOP_CALLEE1(pgdval_t, mmu.make_pgd, val); |
404 | val); | ||
405 | 402 | ||
406 | return (pgd_t) { ret }; | 403 | return (pgd_t) { ret }; |
407 | } | 404 | } |
@@ -411,11 +408,10 @@ static inline pgdval_t pgd_val(pgd_t pgd) | |||
411 | pgdval_t ret; | 408 | pgdval_t ret; |
412 | 409 | ||
413 | if (sizeof(pgdval_t) > sizeof(long)) | 410 | if (sizeof(pgdval_t) > sizeof(long)) |
414 | ret = PVOP_CALLEE2(pgdval_t, pv_mmu_ops.pgd_val, | 411 | ret = PVOP_CALLEE2(pgdval_t, mmu.pgd_val, |
415 | pgd.pgd, (u64)pgd.pgd >> 32); | 412 | pgd.pgd, (u64)pgd.pgd >> 32); |
416 | else | 413 | else |
417 | ret = PVOP_CALLEE1(pgdval_t, pv_mmu_ops.pgd_val, | 414 | ret = PVOP_CALLEE1(pgdval_t, mmu.pgd_val, pgd.pgd); |
418 | pgd.pgd); | ||
419 | 415 | ||
420 | return ret; | 416 | return ret; |
421 | } | 417 | } |
@@ -426,8 +422,7 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long a | |||
426 | { | 422 | { |
427 | pteval_t ret; | 423 | pteval_t ret; |
428 | 424 | ||
429 | ret = PVOP_CALL3(pteval_t, pv_mmu_ops.ptep_modify_prot_start, | 425 | ret = PVOP_CALL3(pteval_t, mmu.ptep_modify_prot_start, mm, addr, ptep); |
430 | mm, addr, ptep); | ||
431 | 426 | ||
432 | return (pte_t) { .pte = ret }; | 427 | return (pte_t) { .pte = ret }; |
433 | } | 428 | } |
@@ -437,20 +432,18 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long a | |||
437 | { | 432 | { |
438 | if (sizeof(pteval_t) > sizeof(long)) | 433 | if (sizeof(pteval_t) > sizeof(long)) |
439 | /* 5 arg words */ | 434 | /* 5 arg words */ |
440 | pv_mmu_ops.ptep_modify_prot_commit(mm, addr, ptep, pte); | 435 | pv_ops.mmu.ptep_modify_prot_commit(mm, addr, ptep, pte); |
441 | else | 436 | else |
442 | PVOP_VCALL4(pv_mmu_ops.ptep_modify_prot_commit, | 437 | PVOP_VCALL4(mmu.ptep_modify_prot_commit, |
443 | mm, addr, ptep, pte.pte); | 438 | mm, addr, ptep, pte.pte); |
444 | } | 439 | } |
445 | 440 | ||
446 | static inline void set_pte(pte_t *ptep, pte_t pte) | 441 | static inline void set_pte(pte_t *ptep, pte_t pte) |
447 | { | 442 | { |
448 | if (sizeof(pteval_t) > sizeof(long)) | 443 | if (sizeof(pteval_t) > sizeof(long)) |
449 | PVOP_VCALL3(pv_mmu_ops.set_pte, ptep, | 444 | PVOP_VCALL3(mmu.set_pte, ptep, pte.pte, (u64)pte.pte >> 32); |
450 | pte.pte, (u64)pte.pte >> 32); | ||
451 | else | 445 | else |
452 | PVOP_VCALL2(pv_mmu_ops.set_pte, ptep, | 446 | PVOP_VCALL2(mmu.set_pte, ptep, pte.pte); |
453 | pte.pte); | ||
454 | } | 447 | } |
455 | 448 | ||
456 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | 449 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, |
@@ -458,9 +451,9 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
458 | { | 451 | { |
459 | if (sizeof(pteval_t) > sizeof(long)) | 452 | if (sizeof(pteval_t) > sizeof(long)) |
460 | /* 5 arg words */ | 453 | /* 5 arg words */ |
461 | pv_mmu_ops.set_pte_at(mm, addr, ptep, pte); | 454 | pv_ops.mmu.set_pte_at(mm, addr, ptep, pte); |
462 | else | 455 | else |
463 | PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pte.pte); | 456 | PVOP_VCALL4(mmu.set_pte_at, mm, addr, ptep, pte.pte); |
464 | } | 457 | } |
465 | 458 | ||
466 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) | 459 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) |
@@ -468,9 +461,9 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) | |||
468 | pmdval_t val = native_pmd_val(pmd); | 461 | pmdval_t val = native_pmd_val(pmd); |
469 | 462 | ||
470 | if (sizeof(pmdval_t) > sizeof(long)) | 463 | if (sizeof(pmdval_t) > sizeof(long)) |
471 | PVOP_VCALL3(pv_mmu_ops.set_pmd, pmdp, val, (u64)val >> 32); | 464 | PVOP_VCALL3(mmu.set_pmd, pmdp, val, (u64)val >> 32); |
472 | else | 465 | else |
473 | PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, val); | 466 | PVOP_VCALL2(mmu.set_pmd, pmdp, val); |
474 | } | 467 | } |
475 | 468 | ||
476 | #if CONFIG_PGTABLE_LEVELS >= 3 | 469 | #if CONFIG_PGTABLE_LEVELS >= 3 |
@@ -479,11 +472,9 @@ static inline pmd_t __pmd(pmdval_t val) | |||
479 | pmdval_t ret; | 472 | pmdval_t ret; |
480 | 473 | ||
481 | if (sizeof(pmdval_t) > sizeof(long)) | 474 | if (sizeof(pmdval_t) > sizeof(long)) |
482 | ret = PVOP_CALLEE2(pmdval_t, pv_mmu_ops.make_pmd, | 475 | ret = PVOP_CALLEE2(pmdval_t, mmu.make_pmd, val, (u64)val >> 32); |
483 | val, (u64)val >> 32); | ||
484 | else | 476 | else |
485 | ret = PVOP_CALLEE1(pmdval_t, pv_mmu_ops.make_pmd, | 477 | ret = PVOP_CALLEE1(pmdval_t, mmu.make_pmd, val); |
486 | val); | ||
487 | 478 | ||
488 | return (pmd_t) { ret }; | 479 | return (pmd_t) { ret }; |
489 | } | 480 | } |
@@ -493,11 +484,10 @@ static inline pmdval_t pmd_val(pmd_t pmd) | |||
493 | pmdval_t ret; | 484 | pmdval_t ret; |
494 | 485 | ||
495 | if (sizeof(pmdval_t) > sizeof(long)) | 486 | if (sizeof(pmdval_t) > sizeof(long)) |
496 | ret = PVOP_CALLEE2(pmdval_t, pv_mmu_ops.pmd_val, | 487 | ret = PVOP_CALLEE2(pmdval_t, mmu.pmd_val, |
497 | pmd.pmd, (u64)pmd.pmd >> 32); | 488 | pmd.pmd, (u64)pmd.pmd >> 32); |
498 | else | 489 | else |
499 | ret = PVOP_CALLEE1(pmdval_t, pv_mmu_ops.pmd_val, | 490 | ret = PVOP_CALLEE1(pmdval_t, mmu.pmd_val, pmd.pmd); |
500 | pmd.pmd); | ||
501 | 491 | ||
502 | return ret; | 492 | return ret; |
503 | } | 493 | } |
@@ -507,39 +497,23 @@ static inline void set_pud(pud_t *pudp, pud_t pud) | |||
507 | pudval_t val = native_pud_val(pud); | 497 | pudval_t val = native_pud_val(pud); |
508 | 498 | ||
509 | if (sizeof(pudval_t) > sizeof(long)) | 499 | if (sizeof(pudval_t) > sizeof(long)) |
510 | PVOP_VCALL3(pv_mmu_ops.set_pud, pudp, | 500 | PVOP_VCALL3(mmu.set_pud, pudp, val, (u64)val >> 32); |
511 | val, (u64)val >> 32); | ||
512 | else | 501 | else |
513 | PVOP_VCALL2(pv_mmu_ops.set_pud, pudp, | 502 | PVOP_VCALL2(mmu.set_pud, pudp, val); |
514 | val); | ||
515 | } | 503 | } |
516 | #if CONFIG_PGTABLE_LEVELS >= 4 | 504 | #if CONFIG_PGTABLE_LEVELS >= 4 |
517 | static inline pud_t __pud(pudval_t val) | 505 | static inline pud_t __pud(pudval_t val) |
518 | { | 506 | { |
519 | pudval_t ret; | 507 | pudval_t ret; |
520 | 508 | ||
521 | if (sizeof(pudval_t) > sizeof(long)) | 509 | ret = PVOP_CALLEE1(pudval_t, mmu.make_pud, val); |
522 | ret = PVOP_CALLEE2(pudval_t, pv_mmu_ops.make_pud, | ||
523 | val, (u64)val >> 32); | ||
524 | else | ||
525 | ret = PVOP_CALLEE1(pudval_t, pv_mmu_ops.make_pud, | ||
526 | val); | ||
527 | 510 | ||
528 | return (pud_t) { ret }; | 511 | return (pud_t) { ret }; |
529 | } | 512 | } |
530 | 513 | ||
531 | static inline pudval_t pud_val(pud_t pud) | 514 | static inline pudval_t pud_val(pud_t pud) |
532 | { | 515 | { |
533 | pudval_t ret; | 516 | return PVOP_CALLEE1(pudval_t, mmu.pud_val, pud.pud); |
534 | |||
535 | if (sizeof(pudval_t) > sizeof(long)) | ||
536 | ret = PVOP_CALLEE2(pudval_t, pv_mmu_ops.pud_val, | ||
537 | pud.pud, (u64)pud.pud >> 32); | ||
538 | else | ||
539 | ret = PVOP_CALLEE1(pudval_t, pv_mmu_ops.pud_val, | ||
540 | pud.pud); | ||
541 | |||
542 | return ret; | ||
543 | } | 517 | } |
544 | 518 | ||
545 | static inline void pud_clear(pud_t *pudp) | 519 | static inline void pud_clear(pud_t *pudp) |
@@ -551,31 +525,26 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d) | |||
551 | { | 525 | { |
552 | p4dval_t val = native_p4d_val(p4d); | 526 | p4dval_t val = native_p4d_val(p4d); |
553 | 527 | ||
554 | if (sizeof(p4dval_t) > sizeof(long)) | 528 | PVOP_VCALL2(mmu.set_p4d, p4dp, val); |
555 | PVOP_VCALL3(pv_mmu_ops.set_p4d, p4dp, | ||
556 | val, (u64)val >> 32); | ||
557 | else | ||
558 | PVOP_VCALL2(pv_mmu_ops.set_p4d, p4dp, | ||
559 | val); | ||
560 | } | 529 | } |
561 | 530 | ||
562 | #if CONFIG_PGTABLE_LEVELS >= 5 | 531 | #if CONFIG_PGTABLE_LEVELS >= 5 |
563 | 532 | ||
564 | static inline p4d_t __p4d(p4dval_t val) | 533 | static inline p4d_t __p4d(p4dval_t val) |
565 | { | 534 | { |
566 | p4dval_t ret = PVOP_CALLEE1(p4dval_t, pv_mmu_ops.make_p4d, val); | 535 | p4dval_t ret = PVOP_CALLEE1(p4dval_t, mmu.make_p4d, val); |
567 | 536 | ||
568 | return (p4d_t) { ret }; | 537 | return (p4d_t) { ret }; |
569 | } | 538 | } |
570 | 539 | ||
571 | static inline p4dval_t p4d_val(p4d_t p4d) | 540 | static inline p4dval_t p4d_val(p4d_t p4d) |
572 | { | 541 | { |
573 | return PVOP_CALLEE1(p4dval_t, pv_mmu_ops.p4d_val, p4d.p4d); | 542 | return PVOP_CALLEE1(p4dval_t, mmu.p4d_val, p4d.p4d); |
574 | } | 543 | } |
575 | 544 | ||
576 | static inline void __set_pgd(pgd_t *pgdp, pgd_t pgd) | 545 | static inline void __set_pgd(pgd_t *pgdp, pgd_t pgd) |
577 | { | 546 | { |
578 | PVOP_VCALL2(pv_mmu_ops.set_pgd, pgdp, native_pgd_val(pgd)); | 547 | PVOP_VCALL2(mmu.set_pgd, pgdp, native_pgd_val(pgd)); |
579 | } | 548 | } |
580 | 549 | ||
581 | #define set_pgd(pgdp, pgdval) do { \ | 550 | #define set_pgd(pgdp, pgdval) do { \ |
@@ -606,19 +575,18 @@ static inline void p4d_clear(p4d_t *p4dp) | |||
606 | 64-bit pte atomically */ | 575 | 64-bit pte atomically */ |
607 | static inline void set_pte_atomic(pte_t *ptep, pte_t pte) | 576 | static inline void set_pte_atomic(pte_t *ptep, pte_t pte) |
608 | { | 577 | { |
609 | PVOP_VCALL3(pv_mmu_ops.set_pte_atomic, ptep, | 578 | PVOP_VCALL3(mmu.set_pte_atomic, ptep, pte.pte, pte.pte >> 32); |
610 | pte.pte, pte.pte >> 32); | ||
611 | } | 579 | } |
612 | 580 | ||
613 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, | 581 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, |
614 | pte_t *ptep) | 582 | pte_t *ptep) |
615 | { | 583 | { |
616 | PVOP_VCALL3(pv_mmu_ops.pte_clear, mm, addr, ptep); | 584 | PVOP_VCALL3(mmu.pte_clear, mm, addr, ptep); |
617 | } | 585 | } |
618 | 586 | ||
619 | static inline void pmd_clear(pmd_t *pmdp) | 587 | static inline void pmd_clear(pmd_t *pmdp) |
620 | { | 588 | { |
621 | PVOP_VCALL1(pv_mmu_ops.pmd_clear, pmdp); | 589 | PVOP_VCALL1(mmu.pmd_clear, pmdp); |
622 | } | 590 | } |
623 | #else /* !CONFIG_X86_PAE */ | 591 | #else /* !CONFIG_X86_PAE */ |
624 | static inline void set_pte_atomic(pte_t *ptep, pte_t pte) | 592 | static inline void set_pte_atomic(pte_t *ptep, pte_t pte) |
@@ -641,64 +609,68 @@ static inline void pmd_clear(pmd_t *pmdp) | |||
641 | #define __HAVE_ARCH_START_CONTEXT_SWITCH | 609 | #define __HAVE_ARCH_START_CONTEXT_SWITCH |
642 | static inline void arch_start_context_switch(struct task_struct *prev) | 610 | static inline void arch_start_context_switch(struct task_struct *prev) |
643 | { | 611 | { |
644 | PVOP_VCALL1(pv_cpu_ops.start_context_switch, prev); | 612 | PVOP_VCALL1(cpu.start_context_switch, prev); |
645 | } | 613 | } |
646 | 614 | ||
647 | static inline void arch_end_context_switch(struct task_struct *next) | 615 | static inline void arch_end_context_switch(struct task_struct *next) |
648 | { | 616 | { |
649 | PVOP_VCALL1(pv_cpu_ops.end_context_switch, next); | 617 | PVOP_VCALL1(cpu.end_context_switch, next); |
650 | } | 618 | } |
651 | 619 | ||
652 | #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE | 620 | #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE |
653 | static inline void arch_enter_lazy_mmu_mode(void) | 621 | static inline void arch_enter_lazy_mmu_mode(void) |
654 | { | 622 | { |
655 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.enter); | 623 | PVOP_VCALL0(mmu.lazy_mode.enter); |
656 | } | 624 | } |
657 | 625 | ||
658 | static inline void arch_leave_lazy_mmu_mode(void) | 626 | static inline void arch_leave_lazy_mmu_mode(void) |
659 | { | 627 | { |
660 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); | 628 | PVOP_VCALL0(mmu.lazy_mode.leave); |
661 | } | 629 | } |
662 | 630 | ||
663 | static inline void arch_flush_lazy_mmu_mode(void) | 631 | static inline void arch_flush_lazy_mmu_mode(void) |
664 | { | 632 | { |
665 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.flush); | 633 | PVOP_VCALL0(mmu.lazy_mode.flush); |
666 | } | 634 | } |
667 | 635 | ||
668 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, | 636 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, |
669 | phys_addr_t phys, pgprot_t flags) | 637 | phys_addr_t phys, pgprot_t flags) |
670 | { | 638 | { |
671 | pv_mmu_ops.set_fixmap(idx, phys, flags); | 639 | pv_ops.mmu.set_fixmap(idx, phys, flags); |
672 | } | 640 | } |
641 | #endif | ||
673 | 642 | ||
674 | #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) | 643 | #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) |
675 | 644 | ||
676 | static __always_inline void pv_queued_spin_lock_slowpath(struct qspinlock *lock, | 645 | static __always_inline void pv_queued_spin_lock_slowpath(struct qspinlock *lock, |
677 | u32 val) | 646 | u32 val) |
678 | { | 647 | { |
679 | PVOP_VCALL2(pv_lock_ops.queued_spin_lock_slowpath, lock, val); | 648 | PVOP_VCALL2(lock.queued_spin_lock_slowpath, lock, val); |
680 | } | 649 | } |
681 | 650 | ||
682 | static __always_inline void pv_queued_spin_unlock(struct qspinlock *lock) | 651 | static __always_inline void pv_queued_spin_unlock(struct qspinlock *lock) |
683 | { | 652 | { |
684 | PVOP_VCALLEE1(pv_lock_ops.queued_spin_unlock, lock); | 653 | PVOP_VCALLEE1(lock.queued_spin_unlock, lock); |
685 | } | 654 | } |
686 | 655 | ||
687 | static __always_inline void pv_wait(u8 *ptr, u8 val) | 656 | static __always_inline void pv_wait(u8 *ptr, u8 val) |
688 | { | 657 | { |
689 | PVOP_VCALL2(pv_lock_ops.wait, ptr, val); | 658 | PVOP_VCALL2(lock.wait, ptr, val); |
690 | } | 659 | } |
691 | 660 | ||
692 | static __always_inline void pv_kick(int cpu) | 661 | static __always_inline void pv_kick(int cpu) |
693 | { | 662 | { |
694 | PVOP_VCALL1(pv_lock_ops.kick, cpu); | 663 | PVOP_VCALL1(lock.kick, cpu); |
695 | } | 664 | } |
696 | 665 | ||
697 | static __always_inline bool pv_vcpu_is_preempted(long cpu) | 666 | static __always_inline bool pv_vcpu_is_preempted(long cpu) |
698 | { | 667 | { |
699 | return PVOP_CALLEE1(bool, pv_lock_ops.vcpu_is_preempted, cpu); | 668 | return PVOP_CALLEE1(bool, lock.vcpu_is_preempted, cpu); |
700 | } | 669 | } |
701 | 670 | ||
671 | void __raw_callee_save___native_queued_spin_unlock(struct qspinlock *lock); | ||
672 | bool __raw_callee_save___native_vcpu_is_preempted(long cpu); | ||
673 | |||
702 | #endif /* SMP && PARAVIRT_SPINLOCKS */ | 674 | #endif /* SMP && PARAVIRT_SPINLOCKS */ |
703 | 675 | ||
704 | #ifdef CONFIG_X86_32 | 676 | #ifdef CONFIG_X86_32 |
@@ -778,24 +750,25 @@ static __always_inline bool pv_vcpu_is_preempted(long cpu) | |||
778 | #define __PV_IS_CALLEE_SAVE(func) \ | 750 | #define __PV_IS_CALLEE_SAVE(func) \ |
779 | ((struct paravirt_callee_save) { func }) | 751 | ((struct paravirt_callee_save) { func }) |
780 | 752 | ||
753 | #ifdef CONFIG_PARAVIRT_XXL | ||
781 | static inline notrace unsigned long arch_local_save_flags(void) | 754 | static inline notrace unsigned long arch_local_save_flags(void) |
782 | { | 755 | { |
783 | return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl); | 756 | return PVOP_CALLEE0(unsigned long, irq.save_fl); |
784 | } | 757 | } |
785 | 758 | ||
786 | static inline notrace void arch_local_irq_restore(unsigned long f) | 759 | static inline notrace void arch_local_irq_restore(unsigned long f) |
787 | { | 760 | { |
788 | PVOP_VCALLEE1(pv_irq_ops.restore_fl, f); | 761 | PVOP_VCALLEE1(irq.restore_fl, f); |
789 | } | 762 | } |
790 | 763 | ||
791 | static inline notrace void arch_local_irq_disable(void) | 764 | static inline notrace void arch_local_irq_disable(void) |
792 | { | 765 | { |
793 | PVOP_VCALLEE0(pv_irq_ops.irq_disable); | 766 | PVOP_VCALLEE0(irq.irq_disable); |
794 | } | 767 | } |
795 | 768 | ||
796 | static inline notrace void arch_local_irq_enable(void) | 769 | static inline notrace void arch_local_irq_enable(void) |
797 | { | 770 | { |
798 | PVOP_VCALLEE0(pv_irq_ops.irq_enable); | 771 | PVOP_VCALLEE0(irq.irq_enable); |
799 | } | 772 | } |
800 | 773 | ||
801 | static inline notrace unsigned long arch_local_irq_save(void) | 774 | static inline notrace unsigned long arch_local_irq_save(void) |
@@ -806,6 +779,7 @@ static inline notrace unsigned long arch_local_irq_save(void) | |||
806 | arch_local_irq_disable(); | 779 | arch_local_irq_disable(); |
807 | return f; | 780 | return f; |
808 | } | 781 | } |
782 | #endif | ||
809 | 783 | ||
810 | 784 | ||
811 | /* Make sure as little as possible of this mess escapes. */ | 785 | /* Make sure as little as possible of this mess escapes. */ |
@@ -827,7 +801,7 @@ extern void default_banner(void); | |||
827 | 801 | ||
828 | #else /* __ASSEMBLY__ */ | 802 | #else /* __ASSEMBLY__ */ |
829 | 803 | ||
830 | #define _PVSITE(ptype, clobbers, ops, word, algn) \ | 804 | #define _PVSITE(ptype, ops, word, algn) \ |
831 | 771:; \ | 805 | 771:; \ |
832 | ops; \ | 806 | ops; \ |
833 | 772:; \ | 807 | 772:; \ |
@@ -836,7 +810,6 @@ extern void default_banner(void); | |||
836 | word 771b; \ | 810 | word 771b; \ |
837 | .byte ptype; \ | 811 | .byte ptype; \ |
838 | .byte 772b-771b; \ | 812 | .byte 772b-771b; \ |
839 | .short clobbers; \ | ||
840 | .popsection | 813 | .popsection |
841 | 814 | ||
842 | 815 | ||
@@ -868,8 +841,8 @@ extern void default_banner(void); | |||
868 | COND_POP(set, CLBR_RCX, rcx); \ | 841 | COND_POP(set, CLBR_RCX, rcx); \ |
869 | COND_POP(set, CLBR_RAX, rax) | 842 | COND_POP(set, CLBR_RAX, rax) |
870 | 843 | ||
871 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 8) | 844 | #define PARA_PATCH(off) ((off) / 8) |
872 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8) | 845 | #define PARA_SITE(ptype, ops) _PVSITE(ptype, ops, .quad, 8) |
873 | #define PARA_INDIRECT(addr) *addr(%rip) | 846 | #define PARA_INDIRECT(addr) *addr(%rip) |
874 | #else | 847 | #else |
875 | #define PV_SAVE_REGS(set) \ | 848 | #define PV_SAVE_REGS(set) \ |
@@ -883,46 +856,41 @@ extern void default_banner(void); | |||
883 | COND_POP(set, CLBR_EDI, edi); \ | 856 | COND_POP(set, CLBR_EDI, edi); \ |
884 | COND_POP(set, CLBR_EAX, eax) | 857 | COND_POP(set, CLBR_EAX, eax) |
885 | 858 | ||
886 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) | 859 | #define PARA_PATCH(off) ((off) / 4) |
887 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) | 860 | #define PARA_SITE(ptype, ops) _PVSITE(ptype, ops, .long, 4) |
888 | #define PARA_INDIRECT(addr) *%cs:addr | 861 | #define PARA_INDIRECT(addr) *%cs:addr |
889 | #endif | 862 | #endif |
890 | 863 | ||
864 | #ifdef CONFIG_PARAVIRT_XXL | ||
891 | #define INTERRUPT_RETURN \ | 865 | #define INTERRUPT_RETURN \ |
892 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \ | 866 | PARA_SITE(PARA_PATCH(PV_CPU_iret), \ |
893 | ANNOTATE_RETPOLINE_SAFE; \ | 867 | ANNOTATE_RETPOLINE_SAFE; \ |
894 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret);) | 868 | jmp PARA_INDIRECT(pv_ops+PV_CPU_iret);) |
895 | 869 | ||
896 | #define DISABLE_INTERRUPTS(clobbers) \ | 870 | #define DISABLE_INTERRUPTS(clobbers) \ |
897 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ | 871 | PARA_SITE(PARA_PATCH(PV_IRQ_irq_disable), \ |
898 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ | 872 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ |
899 | ANNOTATE_RETPOLINE_SAFE; \ | 873 | ANNOTATE_RETPOLINE_SAFE; \ |
900 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable); \ | 874 | call PARA_INDIRECT(pv_ops+PV_IRQ_irq_disable); \ |
901 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) | 875 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) |
902 | 876 | ||
903 | #define ENABLE_INTERRUPTS(clobbers) \ | 877 | #define ENABLE_INTERRUPTS(clobbers) \ |
904 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ | 878 | PARA_SITE(PARA_PATCH(PV_IRQ_irq_enable), \ |
905 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ | 879 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ |
906 | ANNOTATE_RETPOLINE_SAFE; \ | 880 | ANNOTATE_RETPOLINE_SAFE; \ |
907 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \ | 881 | call PARA_INDIRECT(pv_ops+PV_IRQ_irq_enable); \ |
908 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) | 882 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) |
883 | #endif | ||
909 | 884 | ||
910 | #ifdef CONFIG_X86_32 | 885 | #ifdef CONFIG_X86_64 |
911 | #define GET_CR0_INTO_EAX \ | 886 | #ifdef CONFIG_PARAVIRT_XXL |
912 | push %ecx; push %edx; \ | ||
913 | ANNOTATE_RETPOLINE_SAFE; \ | ||
914 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \ | ||
915 | pop %edx; pop %ecx | ||
916 | #else /* !CONFIG_X86_32 */ | ||
917 | |||
918 | /* | 887 | /* |
919 | * If swapgs is used while the userspace stack is still current, | 888 | * If swapgs is used while the userspace stack is still current, |
920 | * there's no way to call a pvop. The PV replacement *must* be | 889 | * there's no way to call a pvop. The PV replacement *must* be |
921 | * inlined, or the swapgs instruction must be trapped and emulated. | 890 | * inlined, or the swapgs instruction must be trapped and emulated. |
922 | */ | 891 | */ |
923 | #define SWAPGS_UNSAFE_STACK \ | 892 | #define SWAPGS_UNSAFE_STACK \ |
924 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ | 893 | PARA_SITE(PARA_PATCH(PV_CPU_swapgs), swapgs) |
925 | swapgs) | ||
926 | 894 | ||
927 | /* | 895 | /* |
928 | * Note: swapgs is very special, and in practise is either going to be | 896 | * Note: swapgs is very special, and in practise is either going to be |
@@ -931,44 +899,51 @@ extern void default_banner(void); | |||
931 | * it. | 899 | * it. |
932 | */ | 900 | */ |
933 | #define SWAPGS \ | 901 | #define SWAPGS \ |
934 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ | 902 | PARA_SITE(PARA_PATCH(PV_CPU_swapgs), \ |
935 | ANNOTATE_RETPOLINE_SAFE; \ | 903 | ANNOTATE_RETPOLINE_SAFE; \ |
936 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs); \ | 904 | call PARA_INDIRECT(pv_ops+PV_CPU_swapgs); \ |
937 | ) | 905 | ) |
906 | #endif | ||
938 | 907 | ||
939 | #define GET_CR2_INTO_RAX \ | 908 | #define GET_CR2_INTO_RAX \ |
940 | ANNOTATE_RETPOLINE_SAFE; \ | 909 | ANNOTATE_RETPOLINE_SAFE; \ |
941 | call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2); | 910 | call PARA_INDIRECT(pv_ops+PV_MMU_read_cr2); |
942 | 911 | ||
912 | #ifdef CONFIG_PARAVIRT_XXL | ||
943 | #define USERGS_SYSRET64 \ | 913 | #define USERGS_SYSRET64 \ |
944 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \ | 914 | PARA_SITE(PARA_PATCH(PV_CPU_usergs_sysret64), \ |
945 | CLBR_NONE, \ | 915 | ANNOTATE_RETPOLINE_SAFE; \ |
946 | ANNOTATE_RETPOLINE_SAFE; \ | 916 | jmp PARA_INDIRECT(pv_ops+PV_CPU_usergs_sysret64);) |
947 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64);) | ||
948 | 917 | ||
949 | #ifdef CONFIG_DEBUG_ENTRY | 918 | #ifdef CONFIG_DEBUG_ENTRY |
950 | #define SAVE_FLAGS(clobbers) \ | 919 | #define SAVE_FLAGS(clobbers) \ |
951 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_save_fl), clobbers, \ | 920 | PARA_SITE(PARA_PATCH(PV_IRQ_save_fl), \ |
952 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ | 921 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \ |
953 | ANNOTATE_RETPOLINE_SAFE; \ | 922 | ANNOTATE_RETPOLINE_SAFE; \ |
954 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_save_fl); \ | 923 | call PARA_INDIRECT(pv_ops+PV_IRQ_save_fl); \ |
955 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) | 924 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) |
956 | #endif | 925 | #endif |
926 | #endif | ||
957 | 927 | ||
958 | #endif /* CONFIG_X86_32 */ | 928 | #endif /* CONFIG_X86_32 */ |
959 | 929 | ||
960 | #endif /* __ASSEMBLY__ */ | 930 | #endif /* __ASSEMBLY__ */ |
961 | #else /* CONFIG_PARAVIRT */ | 931 | #else /* CONFIG_PARAVIRT */ |
962 | # define default_banner x86_init_noop | 932 | # define default_banner x86_init_noop |
933 | #endif /* !CONFIG_PARAVIRT */ | ||
934 | |||
963 | #ifndef __ASSEMBLY__ | 935 | #ifndef __ASSEMBLY__ |
936 | #ifndef CONFIG_PARAVIRT_XXL | ||
964 | static inline void paravirt_arch_dup_mmap(struct mm_struct *oldmm, | 937 | static inline void paravirt_arch_dup_mmap(struct mm_struct *oldmm, |
965 | struct mm_struct *mm) | 938 | struct mm_struct *mm) |
966 | { | 939 | { |
967 | } | 940 | } |
941 | #endif | ||
968 | 942 | ||
943 | #ifndef CONFIG_PARAVIRT | ||
969 | static inline void paravirt_arch_exit_mmap(struct mm_struct *mm) | 944 | static inline void paravirt_arch_exit_mmap(struct mm_struct *mm) |
970 | { | 945 | { |
971 | } | 946 | } |
947 | #endif | ||
972 | #endif /* __ASSEMBLY__ */ | 948 | #endif /* __ASSEMBLY__ */ |
973 | #endif /* !CONFIG_PARAVIRT */ | ||
974 | #endif /* _ASM_X86_PARAVIRT_H */ | 949 | #endif /* _ASM_X86_PARAVIRT_H */ |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 83ce282eed0a..fba54ca23b2a 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
@@ -66,12 +66,14 @@ struct paravirt_callee_save { | |||
66 | 66 | ||
67 | /* general info */ | 67 | /* general info */ |
68 | struct pv_info { | 68 | struct pv_info { |
69 | #ifdef CONFIG_PARAVIRT_XXL | ||
69 | unsigned int kernel_rpl; | 70 | unsigned int kernel_rpl; |
70 | int shared_kernel_pmd; | 71 | int shared_kernel_pmd; |
71 | 72 | ||
72 | #ifdef CONFIG_X86_64 | 73 | #ifdef CONFIG_X86_64 |
73 | u16 extra_user_64bit_cs; /* __USER_CS if none */ | 74 | u16 extra_user_64bit_cs; /* __USER_CS if none */ |
74 | #endif | 75 | #endif |
76 | #endif | ||
75 | 77 | ||
76 | const char *name; | 78 | const char *name; |
77 | }; | 79 | }; |
@@ -85,17 +87,18 @@ struct pv_init_ops { | |||
85 | * the number of bytes of code generated, as we nop pad the | 87 | * the number of bytes of code generated, as we nop pad the |
86 | * rest in generic code. | 88 | * rest in generic code. |
87 | */ | 89 | */ |
88 | unsigned (*patch)(u8 type, u16 clobber, void *insnbuf, | 90 | unsigned (*patch)(u8 type, void *insnbuf, |
89 | unsigned long addr, unsigned len); | 91 | unsigned long addr, unsigned len); |
90 | } __no_randomize_layout; | 92 | } __no_randomize_layout; |
91 | 93 | ||
92 | 94 | #ifdef CONFIG_PARAVIRT_XXL | |
93 | struct pv_lazy_ops { | 95 | struct pv_lazy_ops { |
94 | /* Set deferred update mode, used for batching operations. */ | 96 | /* Set deferred update mode, used for batching operations. */ |
95 | void (*enter)(void); | 97 | void (*enter)(void); |
96 | void (*leave)(void); | 98 | void (*leave)(void); |
97 | void (*flush)(void); | 99 | void (*flush)(void); |
98 | } __no_randomize_layout; | 100 | } __no_randomize_layout; |
101 | #endif | ||
99 | 102 | ||
100 | struct pv_time_ops { | 103 | struct pv_time_ops { |
101 | unsigned long long (*sched_clock)(void); | 104 | unsigned long long (*sched_clock)(void); |
@@ -104,6 +107,9 @@ struct pv_time_ops { | |||
104 | 107 | ||
105 | struct pv_cpu_ops { | 108 | struct pv_cpu_ops { |
106 | /* hooks for various privileged instructions */ | 109 | /* hooks for various privileged instructions */ |
110 | void (*io_delay)(void); | ||
111 | |||
112 | #ifdef CONFIG_PARAVIRT_XXL | ||
107 | unsigned long (*get_debugreg)(int regno); | 113 | unsigned long (*get_debugreg)(int regno); |
108 | void (*set_debugreg)(int regno, unsigned long value); | 114 | void (*set_debugreg)(int regno, unsigned long value); |
109 | 115 | ||
@@ -141,7 +147,6 @@ struct pv_cpu_ops { | |||
141 | void (*set_iopl_mask)(unsigned mask); | 147 | void (*set_iopl_mask)(unsigned mask); |
142 | 148 | ||
143 | void (*wbinvd)(void); | 149 | void (*wbinvd)(void); |
144 | void (*io_delay)(void); | ||
145 | 150 | ||
146 | /* cpuid emulation, mostly so that caps bits can be disabled */ | 151 | /* cpuid emulation, mostly so that caps bits can be disabled */ |
147 | void (*cpuid)(unsigned int *eax, unsigned int *ebx, | 152 | void (*cpuid)(unsigned int *eax, unsigned int *ebx, |
@@ -176,9 +181,11 @@ struct pv_cpu_ops { | |||
176 | 181 | ||
177 | void (*start_context_switch)(struct task_struct *prev); | 182 | void (*start_context_switch)(struct task_struct *prev); |
178 | void (*end_context_switch)(struct task_struct *next); | 183 | void (*end_context_switch)(struct task_struct *next); |
184 | #endif | ||
179 | } __no_randomize_layout; | 185 | } __no_randomize_layout; |
180 | 186 | ||
181 | struct pv_irq_ops { | 187 | struct pv_irq_ops { |
188 | #ifdef CONFIG_PARAVIRT_XXL | ||
182 | /* | 189 | /* |
183 | * Get/set interrupt state. save_fl and restore_fl are only | 190 | * Get/set interrupt state. save_fl and restore_fl are only |
184 | * expected to use X86_EFLAGS_IF; all other bits | 191 | * expected to use X86_EFLAGS_IF; all other bits |
@@ -195,35 +202,34 @@ struct pv_irq_ops { | |||
195 | 202 | ||
196 | void (*safe_halt)(void); | 203 | void (*safe_halt)(void); |
197 | void (*halt)(void); | 204 | void (*halt)(void); |
198 | 205 | #endif | |
199 | } __no_randomize_layout; | 206 | } __no_randomize_layout; |
200 | 207 | ||
201 | struct pv_mmu_ops { | 208 | struct pv_mmu_ops { |
209 | /* TLB operations */ | ||
210 | void (*flush_tlb_user)(void); | ||
211 | void (*flush_tlb_kernel)(void); | ||
212 | void (*flush_tlb_one_user)(unsigned long addr); | ||
213 | void (*flush_tlb_others)(const struct cpumask *cpus, | ||
214 | const struct flush_tlb_info *info); | ||
215 | |||
216 | void (*tlb_remove_table)(struct mmu_gather *tlb, void *table); | ||
217 | |||
218 | /* Hook for intercepting the destruction of an mm_struct. */ | ||
219 | void (*exit_mmap)(struct mm_struct *mm); | ||
220 | |||
221 | #ifdef CONFIG_PARAVIRT_XXL | ||
202 | unsigned long (*read_cr2)(void); | 222 | unsigned long (*read_cr2)(void); |
203 | void (*write_cr2)(unsigned long); | 223 | void (*write_cr2)(unsigned long); |
204 | 224 | ||
205 | unsigned long (*read_cr3)(void); | 225 | unsigned long (*read_cr3)(void); |
206 | void (*write_cr3)(unsigned long); | 226 | void (*write_cr3)(unsigned long); |
207 | 227 | ||
208 | /* | 228 | /* Hooks for intercepting the creation/use of an mm_struct. */ |
209 | * Hooks for intercepting the creation/use/destruction of an | ||
210 | * mm_struct. | ||
211 | */ | ||
212 | void (*activate_mm)(struct mm_struct *prev, | 229 | void (*activate_mm)(struct mm_struct *prev, |
213 | struct mm_struct *next); | 230 | struct mm_struct *next); |
214 | void (*dup_mmap)(struct mm_struct *oldmm, | 231 | void (*dup_mmap)(struct mm_struct *oldmm, |
215 | struct mm_struct *mm); | 232 | struct mm_struct *mm); |
216 | void (*exit_mmap)(struct mm_struct *mm); | ||
217 | |||
218 | |||
219 | /* TLB operations */ | ||
220 | void (*flush_tlb_user)(void); | ||
221 | void (*flush_tlb_kernel)(void); | ||
222 | void (*flush_tlb_one_user)(unsigned long addr); | ||
223 | void (*flush_tlb_others)(const struct cpumask *cpus, | ||
224 | const struct flush_tlb_info *info); | ||
225 | |||
226 | void (*tlb_remove_table)(struct mmu_gather *tlb, void *table); | ||
227 | 233 | ||
228 | /* Hooks for allocating and freeing a pagetable top-level */ | 234 | /* Hooks for allocating and freeing a pagetable top-level */ |
229 | int (*pgd_alloc)(struct mm_struct *mm); | 235 | int (*pgd_alloc)(struct mm_struct *mm); |
@@ -298,6 +304,7 @@ struct pv_mmu_ops { | |||
298 | an mfn. We can tell which is which from the index. */ | 304 | an mfn. We can tell which is which from the index. */ |
299 | void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx, | 305 | void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx, |
300 | phys_addr_t phys, pgprot_t flags); | 306 | phys_addr_t phys, pgprot_t flags); |
307 | #endif | ||
301 | } __no_randomize_layout; | 308 | } __no_randomize_layout; |
302 | 309 | ||
303 | struct arch_spinlock; | 310 | struct arch_spinlock; |
@@ -321,28 +328,23 @@ struct pv_lock_ops { | |||
321 | * number for each function using the offset which we use to indicate | 328 | * number for each function using the offset which we use to indicate |
322 | * what to patch. */ | 329 | * what to patch. */ |
323 | struct paravirt_patch_template { | 330 | struct paravirt_patch_template { |
324 | struct pv_init_ops pv_init_ops; | 331 | struct pv_init_ops init; |
325 | struct pv_time_ops pv_time_ops; | 332 | struct pv_time_ops time; |
326 | struct pv_cpu_ops pv_cpu_ops; | 333 | struct pv_cpu_ops cpu; |
327 | struct pv_irq_ops pv_irq_ops; | 334 | struct pv_irq_ops irq; |
328 | struct pv_mmu_ops pv_mmu_ops; | 335 | struct pv_mmu_ops mmu; |
329 | struct pv_lock_ops pv_lock_ops; | 336 | struct pv_lock_ops lock; |
330 | } __no_randomize_layout; | 337 | } __no_randomize_layout; |
331 | 338 | ||
332 | extern struct pv_info pv_info; | 339 | extern struct pv_info pv_info; |
333 | extern struct pv_init_ops pv_init_ops; | 340 | extern struct paravirt_patch_template pv_ops; |
334 | extern struct pv_time_ops pv_time_ops; | ||
335 | extern struct pv_cpu_ops pv_cpu_ops; | ||
336 | extern struct pv_irq_ops pv_irq_ops; | ||
337 | extern struct pv_mmu_ops pv_mmu_ops; | ||
338 | extern struct pv_lock_ops pv_lock_ops; | ||
339 | 341 | ||
340 | #define PARAVIRT_PATCH(x) \ | 342 | #define PARAVIRT_PATCH(x) \ |
341 | (offsetof(struct paravirt_patch_template, x) / sizeof(void *)) | 343 | (offsetof(struct paravirt_patch_template, x) / sizeof(void *)) |
342 | 344 | ||
343 | #define paravirt_type(op) \ | 345 | #define paravirt_type(op) \ |
344 | [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \ | 346 | [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \ |
345 | [paravirt_opptr] "i" (&(op)) | 347 | [paravirt_opptr] "i" (&(pv_ops.op)) |
346 | #define paravirt_clobber(clobber) \ | 348 | #define paravirt_clobber(clobber) \ |
347 | [paravirt_clobber] "i" (clobber) | 349 | [paravirt_clobber] "i" (clobber) |
348 | 350 | ||
@@ -361,20 +363,13 @@ extern struct pv_lock_ops pv_lock_ops; | |||
361 | 363 | ||
362 | unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len); | 364 | unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len); |
363 | unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len); | 365 | unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len); |
364 | unsigned paravirt_patch_call(void *insnbuf, | 366 | unsigned paravirt_patch_default(u8 type, void *insnbuf, |
365 | const void *target, u16 tgt_clobbers, | ||
366 | unsigned long addr, u16 site_clobbers, | ||
367 | unsigned len); | ||
368 | unsigned paravirt_patch_jmp(void *insnbuf, const void *target, | ||
369 | unsigned long addr, unsigned len); | ||
370 | unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, | ||
371 | unsigned long addr, unsigned len); | 367 | unsigned long addr, unsigned len); |
372 | 368 | ||
373 | unsigned paravirt_patch_insns(void *insnbuf, unsigned len, | 369 | unsigned paravirt_patch_insns(void *insnbuf, unsigned len, |
374 | const char *start, const char *end); | 370 | const char *start, const char *end); |
375 | 371 | ||
376 | unsigned native_patch(u8 type, u16 clobbers, void *ibuf, | 372 | unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len); |
377 | unsigned long addr, unsigned len); | ||
378 | 373 | ||
379 | int paravirt_disable_iospace(void); | 374 | int paravirt_disable_iospace(void); |
380 | 375 | ||
@@ -488,9 +483,9 @@ int paravirt_disable_iospace(void); | |||
488 | #endif /* CONFIG_X86_32 */ | 483 | #endif /* CONFIG_X86_32 */ |
489 | 484 | ||
490 | #ifdef CONFIG_PARAVIRT_DEBUG | 485 | #ifdef CONFIG_PARAVIRT_DEBUG |
491 | #define PVOP_TEST_NULL(op) BUG_ON(op == NULL) | 486 | #define PVOP_TEST_NULL(op) BUG_ON(pv_ops.op == NULL) |
492 | #else | 487 | #else |
493 | #define PVOP_TEST_NULL(op) ((void)op) | 488 | #define PVOP_TEST_NULL(op) ((void)pv_ops.op) |
494 | #endif | 489 | #endif |
495 | 490 | ||
496 | #define PVOP_RETMASK(rettype) \ | 491 | #define PVOP_RETMASK(rettype) \ |
@@ -666,7 +661,6 @@ struct paravirt_patch_site { | |||
666 | u8 *instr; /* original instructions */ | 661 | u8 *instr; /* original instructions */ |
667 | u8 instrtype; /* type of this instruction */ | 662 | u8 instrtype; /* type of this instruction */ |
668 | u8 len; /* length of original instruction */ | 663 | u8 len; /* length of original instruction */ |
669 | u16 clobbers; /* what registers you may clobber */ | ||
670 | }; | 664 | }; |
671 | 665 | ||
672 | extern struct paravirt_patch_site __parainstructions[], | 666 | extern struct paravirt_patch_site __parainstructions[], |
diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h index fbd578daa66e..ec7f43327033 100644 --- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | static inline int __paravirt_pgd_alloc(struct mm_struct *mm) { return 0; } | 9 | static inline int __paravirt_pgd_alloc(struct mm_struct *mm) { return 0; } |
10 | 10 | ||
11 | #ifdef CONFIG_PARAVIRT | 11 | #ifdef CONFIG_PARAVIRT_XXL |
12 | #include <asm/paravirt.h> | 12 | #include <asm/paravirt.h> |
13 | #else | 13 | #else |
14 | #define paravirt_pgd_alloc(mm) __paravirt_pgd_alloc(mm) | 14 | #define paravirt_pgd_alloc(mm) __paravirt_pgd_alloc(mm) |
diff --git a/arch/x86/include/asm/pgtable-3level_types.h b/arch/x86/include/asm/pgtable-3level_types.h index 858358a82b14..33845d36897c 100644 --- a/arch/x86/include/asm/pgtable-3level_types.h +++ b/arch/x86/include/asm/pgtable-3level_types.h | |||
@@ -20,7 +20,7 @@ typedef union { | |||
20 | } pte_t; | 20 | } pte_t; |
21 | #endif /* !__ASSEMBLY__ */ | 21 | #endif /* !__ASSEMBLY__ */ |
22 | 22 | ||
23 | #ifdef CONFIG_PARAVIRT | 23 | #ifdef CONFIG_PARAVIRT_XXL |
24 | #define SHARED_KERNEL_PMD ((!static_cpu_has(X86_FEATURE_PTI) && \ | 24 | #define SHARED_KERNEL_PMD ((!static_cpu_has(X86_FEATURE_PTI) && \ |
25 | (pv_info.shared_kernel_pmd))) | 25 | (pv_info.shared_kernel_pmd))) |
26 | #else | 26 | #else |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 690c0307afed..40616e805292 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -55,9 +55,9 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); | |||
55 | 55 | ||
56 | extern pmdval_t early_pmd_flags; | 56 | extern pmdval_t early_pmd_flags; |
57 | 57 | ||
58 | #ifdef CONFIG_PARAVIRT | 58 | #ifdef CONFIG_PARAVIRT_XXL |
59 | #include <asm/paravirt.h> | 59 | #include <asm/paravirt.h> |
60 | #else /* !CONFIG_PARAVIRT */ | 60 | #else /* !CONFIG_PARAVIRT_XXL */ |
61 | #define set_pte(ptep, pte) native_set_pte(ptep, pte) | 61 | #define set_pte(ptep, pte) native_set_pte(ptep, pte) |
62 | #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) | 62 | #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) |
63 | 63 | ||
@@ -112,8 +112,7 @@ extern pmdval_t early_pmd_flags; | |||
112 | #define __pte(x) native_make_pte(x) | 112 | #define __pte(x) native_make_pte(x) |
113 | 113 | ||
114 | #define arch_end_context_switch(prev) do {} while(0) | 114 | #define arch_end_context_switch(prev) do {} while(0) |
115 | 115 | #endif /* CONFIG_PARAVIRT_XXL */ | |
116 | #endif /* CONFIG_PARAVIRT */ | ||
117 | 116 | ||
118 | /* | 117 | /* |
119 | * The following only work if pte_present() is true. | 118 | * The following only work if pte_present() is true. |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index d4dfd02b740e..c7a4e2a174b9 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -579,7 +579,7 @@ static inline bool on_thread_stack(void) | |||
579 | current_stack_pointer) < THREAD_SIZE; | 579 | current_stack_pointer) < THREAD_SIZE; |
580 | } | 580 | } |
581 | 581 | ||
582 | #ifdef CONFIG_PARAVIRT | 582 | #ifdef CONFIG_PARAVIRT_XXL |
583 | #include <asm/paravirt.h> | 583 | #include <asm/paravirt.h> |
584 | #else | 584 | #else |
585 | #define __cpuid native_cpuid | 585 | #define __cpuid native_cpuid |
@@ -590,7 +590,7 @@ static inline void load_sp0(unsigned long sp0) | |||
590 | } | 590 | } |
591 | 591 | ||
592 | #define set_iopl_mask native_set_iopl_mask | 592 | #define set_iopl_mask native_set_iopl_mask |
593 | #endif /* CONFIG_PARAVIRT */ | 593 | #endif /* CONFIG_PARAVIRT_XXL */ |
594 | 594 | ||
595 | /* Free all resources held by a thread. */ | 595 | /* Free all resources held by a thread. */ |
596 | extern void release_thread(struct task_struct *); | 596 | extern void release_thread(struct task_struct *); |
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 25f49af1b13c..f236bcd5485d 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h | |||
@@ -146,7 +146,7 @@ static inline int v8086_mode(struct pt_regs *regs) | |||
146 | static inline bool user_64bit_mode(struct pt_regs *regs) | 146 | static inline bool user_64bit_mode(struct pt_regs *regs) |
147 | { | 147 | { |
148 | #ifdef CONFIG_X86_64 | 148 | #ifdef CONFIG_X86_64 |
149 | #ifndef CONFIG_PARAVIRT | 149 | #ifndef CONFIG_PARAVIRT_XXL |
150 | /* | 150 | /* |
151 | * On non-paravirt systems, this is the only long mode CPL 3 | 151 | * On non-paravirt systems, this is the only long mode CPL 3 |
152 | * selector. We do not allow long mode selectors in the LDT. | 152 | * selector. We do not allow long mode selectors in the LDT. |
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index a314087add07..ac3892920419 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h | |||
@@ -210,7 +210,7 @@ | |||
210 | 210 | ||
211 | #endif | 211 | #endif |
212 | 212 | ||
213 | #ifndef CONFIG_PARAVIRT | 213 | #ifndef CONFIG_PARAVIRT_XXL |
214 | # define get_kernel_rpl() 0 | 214 | # define get_kernel_rpl() 0 |
215 | #endif | 215 | #endif |
216 | 216 | ||
diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 317fc59b512c..43c029cdc3fe 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h | |||
@@ -141,7 +141,7 @@ static inline unsigned long __read_cr4(void) | |||
141 | return native_read_cr4(); | 141 | return native_read_cr4(); |
142 | } | 142 | } |
143 | 143 | ||
144 | #ifdef CONFIG_PARAVIRT | 144 | #ifdef CONFIG_PARAVIRT_XXL |
145 | #include <asm/paravirt.h> | 145 | #include <asm/paravirt.h> |
146 | #else | 146 | #else |
147 | 147 | ||
@@ -208,7 +208,7 @@ static inline void load_gs_index(unsigned selector) | |||
208 | 208 | ||
209 | #endif | 209 | #endif |
210 | 210 | ||
211 | #endif/* CONFIG_PARAVIRT */ | 211 | #endif /* CONFIG_PARAVIRT_XXL */ |
212 | 212 | ||
213 | static inline void clflush(volatile void *__p) | 213 | static inline void clflush(volatile void *__p) |
214 | { | 214 | { |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 184e9a06b0ff..ebeac487a20c 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -598,7 +598,7 @@ void __init_or_module apply_paravirt(struct paravirt_patch_site *start, | |||
598 | BUG_ON(p->len > MAX_PATCH_LEN); | 598 | BUG_ON(p->len > MAX_PATCH_LEN); |
599 | /* prep the buffer with the original instructions */ | 599 | /* prep the buffer with the original instructions */ |
600 | memcpy(insnbuf, p->instr, p->len); | 600 | memcpy(insnbuf, p->instr, p->len); |
601 | used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf, | 601 | used = pv_ops.init.patch(p->instrtype, insnbuf, |
602 | (unsigned long)p->instr, p->len); | 602 | (unsigned long)p->instr, p->len); |
603 | 603 | ||
604 | BUG_ON(used > p->len); | 604 | BUG_ON(used > p->len); |
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index 01de31db300d..fc02c3cf238f 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c | |||
@@ -64,15 +64,12 @@ void common(void) { | |||
64 | OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext); | 64 | OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext); |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | #ifdef CONFIG_PARAVIRT | 67 | #ifdef CONFIG_PARAVIRT_XXL |
68 | BLANK(); | 68 | BLANK(); |
69 | OFFSET(PARAVIRT_PATCH_pv_cpu_ops, paravirt_patch_template, pv_cpu_ops); | 69 | OFFSET(PV_IRQ_irq_disable, paravirt_patch_template, irq.irq_disable); |
70 | OFFSET(PARAVIRT_PATCH_pv_irq_ops, paravirt_patch_template, pv_irq_ops); | 70 | OFFSET(PV_IRQ_irq_enable, paravirt_patch_template, irq.irq_enable); |
71 | OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable); | 71 | OFFSET(PV_CPU_iret, paravirt_patch_template, cpu.iret); |
72 | OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable); | 72 | OFFSET(PV_MMU_read_cr2, paravirt_patch_template, mmu.read_cr2); |
73 | OFFSET(PV_CPU_iret, pv_cpu_ops, iret); | ||
74 | OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0); | ||
75 | OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2); | ||
76 | #endif | 73 | #endif |
77 | 74 | ||
78 | #ifdef CONFIG_XEN | 75 | #ifdef CONFIG_XEN |
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 3b9405e7ba2b..ddced33184b5 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c | |||
@@ -21,10 +21,13 @@ static char syscalls_ia32[] = { | |||
21 | int main(void) | 21 | int main(void) |
22 | { | 22 | { |
23 | #ifdef CONFIG_PARAVIRT | 23 | #ifdef CONFIG_PARAVIRT |
24 | OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64); | 24 | #ifdef CONFIG_PARAVIRT_XXL |
25 | OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs); | 25 | OFFSET(PV_CPU_usergs_sysret64, paravirt_patch_template, |
26 | cpu.usergs_sysret64); | ||
27 | OFFSET(PV_CPU_swapgs, paravirt_patch_template, cpu.swapgs); | ||
26 | #ifdef CONFIG_DEBUG_ENTRY | 28 | #ifdef CONFIG_DEBUG_ENTRY |
27 | OFFSET(PV_IRQ_save_fl, pv_irq_ops, save_fl); | 29 | OFFSET(PV_IRQ_save_fl, paravirt_patch_template, irq.save_fl); |
30 | #endif | ||
28 | #endif | 31 | #endif |
29 | BLANK(); | 32 | BLANK(); |
30 | #endif | 33 | #endif |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c519a079b3d5..9315a1660668 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1243,10 +1243,10 @@ static void generic_identify(struct cpuinfo_x86 *c) | |||
1243 | * ESPFIX issue, we can change this. | 1243 | * ESPFIX issue, we can change this. |
1244 | */ | 1244 | */ |
1245 | #ifdef CONFIG_X86_32 | 1245 | #ifdef CONFIG_X86_32 |
1246 | # ifdef CONFIG_PARAVIRT | 1246 | # ifdef CONFIG_PARAVIRT_XXL |
1247 | do { | 1247 | do { |
1248 | extern void native_iret(void); | 1248 | extern void native_iret(void); |
1249 | if (pv_cpu_ops.iret == native_iret) | 1249 | if (pv_ops.cpu.iret == native_iret) |
1250 | set_cpu_bug(c, X86_BUG_ESPFIX); | 1250 | set_cpu_bug(c, X86_BUG_ESPFIX); |
1251 | } while (0); | 1251 | } while (0); |
1252 | # else | 1252 | # else |
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index ad12733f6058..1c72f3819eb1 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c | |||
@@ -199,6 +199,16 @@ static unsigned long hv_get_tsc_khz(void) | |||
199 | return freq / 1000; | 199 | return freq / 1000; |
200 | } | 200 | } |
201 | 201 | ||
202 | #if defined(CONFIG_SMP) && IS_ENABLED(CONFIG_HYPERV) | ||
203 | static void __init hv_smp_prepare_boot_cpu(void) | ||
204 | { | ||
205 | native_smp_prepare_boot_cpu(); | ||
206 | #if defined(CONFIG_X86_64) && defined(CONFIG_PARAVIRT_SPINLOCKS) | ||
207 | hv_init_spinlocks(); | ||
208 | #endif | ||
209 | } | ||
210 | #endif | ||
211 | |||
202 | static void __init ms_hyperv_init_platform(void) | 212 | static void __init ms_hyperv_init_platform(void) |
203 | { | 213 | { |
204 | int hv_host_info_eax; | 214 | int hv_host_info_eax; |
@@ -303,6 +313,10 @@ static void __init ms_hyperv_init_platform(void) | |||
303 | if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) | 313 | if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) |
304 | alloc_intr_gate(HYPERV_STIMER0_VECTOR, | 314 | alloc_intr_gate(HYPERV_STIMER0_VECTOR, |
305 | hv_stimer0_callback_vector); | 315 | hv_stimer0_callback_vector); |
316 | |||
317 | # ifdef CONFIG_SMP | ||
318 | smp_ops.smp_prepare_boot_cpu = hv_smp_prepare_boot_cpu; | ||
319 | # endif | ||
306 | #endif | 320 | #endif |
307 | } | 321 | } |
308 | 322 | ||
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 8e005329648b..d9ab49bed8af 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c | |||
@@ -97,14 +97,14 @@ static void __init vmware_sched_clock_setup(void) | |||
97 | d->cyc2ns_offset = mul_u64_u32_shr(tsc_now, d->cyc2ns_mul, | 97 | d->cyc2ns_offset = mul_u64_u32_shr(tsc_now, d->cyc2ns_mul, |
98 | d->cyc2ns_shift); | 98 | d->cyc2ns_shift); |
99 | 99 | ||
100 | pv_time_ops.sched_clock = vmware_sched_clock; | 100 | pv_ops.time.sched_clock = vmware_sched_clock; |
101 | pr_info("using sched offset of %llu ns\n", d->cyc2ns_offset); | 101 | pr_info("using sched offset of %llu ns\n", d->cyc2ns_offset); |
102 | } | 102 | } |
103 | 103 | ||
104 | static void __init vmware_paravirt_ops_setup(void) | 104 | static void __init vmware_paravirt_ops_setup(void) |
105 | { | 105 | { |
106 | pv_info.name = "VMware hypervisor"; | 106 | pv_info.name = "VMware hypervisor"; |
107 | pv_cpu_ops.io_delay = paravirt_nop; | 107 | pv_ops.cpu.io_delay = paravirt_nop; |
108 | 108 | ||
109 | if (vmware_tsc_khz && vmw_sched_clock) | 109 | if (vmware_tsc_khz && vmw_sched_clock) |
110 | vmware_sched_clock_setup(); | 110 | vmware_sched_clock_setup(); |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index a3618cf04cf6..747c758f67b7 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <asm/nospec-branch.h> | 26 | #include <asm/nospec-branch.h> |
27 | #include <asm/fixmap.h> | 27 | #include <asm/fixmap.h> |
28 | 28 | ||
29 | #ifdef CONFIG_PARAVIRT | 29 | #ifdef CONFIG_PARAVIRT_XXL |
30 | #include <asm/asm-offsets.h> | 30 | #include <asm/asm-offsets.h> |
31 | #include <asm/paravirt.h> | 31 | #include <asm/paravirt.h> |
32 | #define GET_CR2_INTO(reg) GET_CR2_INTO_RAX ; movq %rax, reg | 32 | #define GET_CR2_INTO(reg) GET_CR2_INTO_RAX ; movq %rax, reg |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index d9b71924c23c..ba4bfb7f6a36 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -283,7 +283,7 @@ static void __init paravirt_ops_setup(void) | |||
283 | pv_info.name = "KVM"; | 283 | pv_info.name = "KVM"; |
284 | 284 | ||
285 | if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) | 285 | if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) |
286 | pv_cpu_ops.io_delay = kvm_io_delay; | 286 | pv_ops.cpu.io_delay = kvm_io_delay; |
287 | 287 | ||
288 | #ifdef CONFIG_X86_IO_APIC | 288 | #ifdef CONFIG_X86_IO_APIC |
289 | no_timer_check = 1; | 289 | no_timer_check = 1; |
@@ -632,14 +632,14 @@ static void __init kvm_guest_init(void) | |||
632 | 632 | ||
633 | if (kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { | 633 | if (kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { |
634 | has_steal_clock = 1; | 634 | has_steal_clock = 1; |
635 | pv_time_ops.steal_clock = kvm_steal_clock; | 635 | pv_ops.time.steal_clock = kvm_steal_clock; |
636 | } | 636 | } |
637 | 637 | ||
638 | if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && | 638 | if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && |
639 | !kvm_para_has_hint(KVM_HINTS_REALTIME) && | 639 | !kvm_para_has_hint(KVM_HINTS_REALTIME) && |
640 | kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { | 640 | kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { |
641 | pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others; | 641 | pv_ops.mmu.flush_tlb_others = kvm_flush_tlb_others; |
642 | pv_mmu_ops.tlb_remove_table = tlb_remove_table; | 642 | pv_ops.mmu.tlb_remove_table = tlb_remove_table; |
643 | } | 643 | } |
644 | 644 | ||
645 | if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) | 645 | if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) |
@@ -850,13 +850,14 @@ void __init kvm_spinlock_init(void) | |||
850 | return; | 850 | return; |
851 | 851 | ||
852 | __pv_init_lock_hash(); | 852 | __pv_init_lock_hash(); |
853 | pv_lock_ops.queued_spin_lock_slowpath = __pv_queued_spin_lock_slowpath; | 853 | pv_ops.lock.queued_spin_lock_slowpath = __pv_queued_spin_lock_slowpath; |
854 | pv_lock_ops.queued_spin_unlock = PV_CALLEE_SAVE(__pv_queued_spin_unlock); | 854 | pv_ops.lock.queued_spin_unlock = |
855 | pv_lock_ops.wait = kvm_wait; | 855 | PV_CALLEE_SAVE(__pv_queued_spin_unlock); |
856 | pv_lock_ops.kick = kvm_kick_cpu; | 856 | pv_ops.lock.wait = kvm_wait; |
857 | pv_ops.lock.kick = kvm_kick_cpu; | ||
857 | 858 | ||
858 | if (kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { | 859 | if (kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { |
859 | pv_lock_ops.vcpu_is_preempted = | 860 | pv_ops.lock.vcpu_is_preempted = |
860 | PV_CALLEE_SAVE(__kvm_vcpu_is_preempted); | 861 | PV_CALLEE_SAVE(__kvm_vcpu_is_preempted); |
861 | } | 862 | } |
862 | } | 863 | } |
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 013fe3d21dbb..30084ecaa20f 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
@@ -118,13 +118,13 @@ static u64 kvm_sched_clock_read(void) | |||
118 | static inline void kvm_sched_clock_init(bool stable) | 118 | static inline void kvm_sched_clock_init(bool stable) |
119 | { | 119 | { |
120 | if (!stable) { | 120 | if (!stable) { |
121 | pv_time_ops.sched_clock = kvm_clock_read; | 121 | pv_ops.time.sched_clock = kvm_clock_read; |
122 | clear_sched_clock_stable(); | 122 | clear_sched_clock_stable(); |
123 | return; | 123 | return; |
124 | } | 124 | } |
125 | 125 | ||
126 | kvm_sched_clock_offset = kvm_clock_read(); | 126 | kvm_sched_clock_offset = kvm_clock_read(); |
127 | pv_time_ops.sched_clock = kvm_sched_clock_read; | 127 | pv_ops.time.sched_clock = kvm_sched_clock_read; |
128 | 128 | ||
129 | pr_info("kvm-clock: using sched offset of %llu cycles", | 129 | pr_info("kvm-clock: using sched offset of %llu cycles", |
130 | kvm_sched_clock_offset); | 130 | kvm_sched_clock_offset); |
diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index 71f2d1125ec0..4f75d0cf6305 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c | |||
@@ -17,7 +17,7 @@ PV_CALLEE_SAVE_REGS_THUNK(__native_queued_spin_unlock); | |||
17 | 17 | ||
18 | bool pv_is_native_spin_unlock(void) | 18 | bool pv_is_native_spin_unlock(void) |
19 | { | 19 | { |
20 | return pv_lock_ops.queued_spin_unlock.func == | 20 | return pv_ops.lock.queued_spin_unlock.func == |
21 | __raw_callee_save___native_queued_spin_unlock; | 21 | __raw_callee_save___native_queued_spin_unlock; |
22 | } | 22 | } |
23 | 23 | ||
@@ -29,17 +29,6 @@ PV_CALLEE_SAVE_REGS_THUNK(__native_vcpu_is_preempted); | |||
29 | 29 | ||
30 | bool pv_is_native_vcpu_is_preempted(void) | 30 | bool pv_is_native_vcpu_is_preempted(void) |
31 | { | 31 | { |
32 | return pv_lock_ops.vcpu_is_preempted.func == | 32 | return pv_ops.lock.vcpu_is_preempted.func == |
33 | __raw_callee_save___native_vcpu_is_preempted; | 33 | __raw_callee_save___native_vcpu_is_preempted; |
34 | } | 34 | } |
35 | |||
36 | struct pv_lock_ops pv_lock_ops = { | ||
37 | #ifdef CONFIG_SMP | ||
38 | .queued_spin_lock_slowpath = native_queued_spin_lock_slowpath, | ||
39 | .queued_spin_unlock = PV_CALLEE_SAVE(__native_queued_spin_unlock), | ||
40 | .wait = paravirt_nop, | ||
41 | .kick = paravirt_nop, | ||
42 | .vcpu_is_preempted = PV_CALLEE_SAVE(__native_vcpu_is_preempted), | ||
43 | #endif /* SMP */ | ||
44 | }; | ||
45 | EXPORT_SYMBOL(pv_lock_ops); | ||
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 8dc69d82567e..e4d4df37922a 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -81,10 +81,8 @@ struct branch { | |||
81 | u32 delta; | 81 | u32 delta; |
82 | } __attribute__((packed)); | 82 | } __attribute__((packed)); |
83 | 83 | ||
84 | unsigned paravirt_patch_call(void *insnbuf, | 84 | static unsigned paravirt_patch_call(void *insnbuf, const void *target, |
85 | const void *target, u16 tgt_clobbers, | 85 | unsigned long addr, unsigned len) |
86 | unsigned long addr, u16 site_clobbers, | ||
87 | unsigned len) | ||
88 | { | 86 | { |
89 | struct branch *b = insnbuf; | 87 | struct branch *b = insnbuf; |
90 | unsigned long delta = (unsigned long)target - (addr+5); | 88 | unsigned long delta = (unsigned long)target - (addr+5); |
@@ -103,8 +101,9 @@ unsigned paravirt_patch_call(void *insnbuf, | |||
103 | return 5; | 101 | return 5; |
104 | } | 102 | } |
105 | 103 | ||
106 | unsigned paravirt_patch_jmp(void *insnbuf, const void *target, | 104 | #ifdef CONFIG_PARAVIRT_XXL |
107 | unsigned long addr, unsigned len) | 105 | static unsigned paravirt_patch_jmp(void *insnbuf, const void *target, |
106 | unsigned long addr, unsigned len) | ||
108 | { | 107 | { |
109 | struct branch *b = insnbuf; | 108 | struct branch *b = insnbuf; |
110 | unsigned long delta = (unsigned long)target - (addr+5); | 109 | unsigned long delta = (unsigned long)target - (addr+5); |
@@ -121,6 +120,7 @@ unsigned paravirt_patch_jmp(void *insnbuf, const void *target, | |||
121 | 120 | ||
122 | return 5; | 121 | return 5; |
123 | } | 122 | } |
123 | #endif | ||
124 | 124 | ||
125 | DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key); | 125 | DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key); |
126 | 126 | ||
@@ -130,29 +130,14 @@ void __init native_pv_lock_init(void) | |||
130 | static_branch_disable(&virt_spin_lock_key); | 130 | static_branch_disable(&virt_spin_lock_key); |
131 | } | 131 | } |
132 | 132 | ||
133 | /* | 133 | unsigned paravirt_patch_default(u8 type, void *insnbuf, |
134 | * Neat trick to map patch type back to the call within the | ||
135 | * corresponding structure. | ||
136 | */ | ||
137 | static void *get_call_destination(u8 type) | ||
138 | { | ||
139 | struct paravirt_patch_template tmpl = { | ||
140 | .pv_init_ops = pv_init_ops, | ||
141 | .pv_time_ops = pv_time_ops, | ||
142 | .pv_cpu_ops = pv_cpu_ops, | ||
143 | .pv_irq_ops = pv_irq_ops, | ||
144 | .pv_mmu_ops = pv_mmu_ops, | ||
145 | #ifdef CONFIG_PARAVIRT_SPINLOCKS | ||
146 | .pv_lock_ops = pv_lock_ops, | ||
147 | #endif | ||
148 | }; | ||
149 | return *((void **)&tmpl + type); | ||
150 | } | ||
151 | |||
152 | unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, | ||
153 | unsigned long addr, unsigned len) | 134 | unsigned long addr, unsigned len) |
154 | { | 135 | { |
155 | void *opfunc = get_call_destination(type); | 136 | /* |
137 | * Neat trick to map patch type back to the call within the | ||
138 | * corresponding structure. | ||
139 | */ | ||
140 | void *opfunc = *((void **)&pv_ops + type); | ||
156 | unsigned ret; | 141 | unsigned ret; |
157 | 142 | ||
158 | if (opfunc == NULL) | 143 | if (opfunc == NULL) |
@@ -167,15 +152,15 @@ unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, | |||
167 | else if (opfunc == _paravirt_ident_64) | 152 | else if (opfunc == _paravirt_ident_64) |
168 | ret = paravirt_patch_ident_64(insnbuf, len); | 153 | ret = paravirt_patch_ident_64(insnbuf, len); |
169 | 154 | ||
170 | else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) || | 155 | #ifdef CONFIG_PARAVIRT_XXL |
171 | type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret64)) | 156 | else if (type == PARAVIRT_PATCH(cpu.iret) || |
157 | type == PARAVIRT_PATCH(cpu.usergs_sysret64)) | ||
172 | /* If operation requires a jmp, then jmp */ | 158 | /* If operation requires a jmp, then jmp */ |
173 | ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len); | 159 | ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len); |
160 | #endif | ||
174 | else | 161 | else |
175 | /* Otherwise call the function; assume target could | 162 | /* Otherwise call the function. */ |
176 | clobber any caller-save reg */ | 163 | ret = paravirt_patch_call(insnbuf, opfunc, addr, len); |
177 | ret = paravirt_patch_call(insnbuf, opfunc, CLBR_ANY, | ||
178 | addr, clobbers, len); | ||
179 | 164 | ||
180 | return ret; | 165 | return ret; |
181 | } | 166 | } |
@@ -281,6 +266,7 @@ void paravirt_flush_lazy_mmu(void) | |||
281 | preempt_enable(); | 266 | preempt_enable(); |
282 | } | 267 | } |
283 | 268 | ||
269 | #ifdef CONFIG_PARAVIRT_XXL | ||
284 | void paravirt_start_context_switch(struct task_struct *prev) | 270 | void paravirt_start_context_switch(struct task_struct *prev) |
285 | { | 271 | { |
286 | BUG_ON(preemptible()); | 272 | BUG_ON(preemptible()); |
@@ -301,6 +287,7 @@ void paravirt_end_context_switch(struct task_struct *next) | |||
301 | if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES)) | 287 | if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES)) |
302 | arch_enter_lazy_mmu_mode(); | 288 | arch_enter_lazy_mmu_mode(); |
303 | } | 289 | } |
290 | #endif | ||
304 | 291 | ||
305 | enum paravirt_lazy_mode paravirt_get_lazy_mode(void) | 292 | enum paravirt_lazy_mode paravirt_get_lazy_mode(void) |
306 | { | 293 | { |
@@ -312,85 +299,16 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) | |||
312 | 299 | ||
313 | struct pv_info pv_info = { | 300 | struct pv_info pv_info = { |
314 | .name = "bare hardware", | 301 | .name = "bare hardware", |
302 | #ifdef CONFIG_PARAVIRT_XXL | ||
315 | .kernel_rpl = 0, | 303 | .kernel_rpl = 0, |
316 | .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */ | 304 | .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */ |
317 | 305 | ||
318 | #ifdef CONFIG_X86_64 | 306 | #ifdef CONFIG_X86_64 |
319 | .extra_user_64bit_cs = __USER_CS, | 307 | .extra_user_64bit_cs = __USER_CS, |
320 | #endif | 308 | #endif |
321 | }; | ||
322 | |||
323 | struct pv_init_ops pv_init_ops = { | ||
324 | .patch = native_patch, | ||
325 | }; | ||
326 | |||
327 | struct pv_time_ops pv_time_ops = { | ||
328 | .sched_clock = native_sched_clock, | ||
329 | .steal_clock = native_steal_clock, | ||
330 | }; | ||
331 | |||
332 | __visible struct pv_irq_ops pv_irq_ops = { | ||
333 | .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), | ||
334 | .restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl), | ||
335 | .irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), | ||
336 | .irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), | ||
337 | .safe_halt = native_safe_halt, | ||
338 | .halt = native_halt, | ||
339 | }; | ||
340 | |||
341 | __visible struct pv_cpu_ops pv_cpu_ops = { | ||
342 | .cpuid = native_cpuid, | ||
343 | .get_debugreg = native_get_debugreg, | ||
344 | .set_debugreg = native_set_debugreg, | ||
345 | .read_cr0 = native_read_cr0, | ||
346 | .write_cr0 = native_write_cr0, | ||
347 | .write_cr4 = native_write_cr4, | ||
348 | #ifdef CONFIG_X86_64 | ||
349 | .read_cr8 = native_read_cr8, | ||
350 | .write_cr8 = native_write_cr8, | ||
351 | #endif | 309 | #endif |
352 | .wbinvd = native_wbinvd, | ||
353 | .read_msr = native_read_msr, | ||
354 | .write_msr = native_write_msr, | ||
355 | .read_msr_safe = native_read_msr_safe, | ||
356 | .write_msr_safe = native_write_msr_safe, | ||
357 | .read_pmc = native_read_pmc, | ||
358 | .load_tr_desc = native_load_tr_desc, | ||
359 | .set_ldt = native_set_ldt, | ||
360 | .load_gdt = native_load_gdt, | ||
361 | .load_idt = native_load_idt, | ||
362 | .store_tr = native_store_tr, | ||
363 | .load_tls = native_load_tls, | ||
364 | #ifdef CONFIG_X86_64 | ||
365 | .load_gs_index = native_load_gs_index, | ||
366 | #endif | ||
367 | .write_ldt_entry = native_write_ldt_entry, | ||
368 | .write_gdt_entry = native_write_gdt_entry, | ||
369 | .write_idt_entry = native_write_idt_entry, | ||
370 | |||
371 | .alloc_ldt = paravirt_nop, | ||
372 | .free_ldt = paravirt_nop, | ||
373 | |||
374 | .load_sp0 = native_load_sp0, | ||
375 | |||
376 | #ifdef CONFIG_X86_64 | ||
377 | .usergs_sysret64 = native_usergs_sysret64, | ||
378 | #endif | ||
379 | .iret = native_iret, | ||
380 | .swapgs = native_swapgs, | ||
381 | |||
382 | .set_iopl_mask = native_set_iopl_mask, | ||
383 | .io_delay = native_io_delay, | ||
384 | |||
385 | .start_context_switch = paravirt_nop, | ||
386 | .end_context_switch = paravirt_nop, | ||
387 | }; | 310 | }; |
388 | 311 | ||
389 | /* At this point, native_get/set_debugreg has real function entries */ | ||
390 | NOKPROBE_SYMBOL(native_get_debugreg); | ||
391 | NOKPROBE_SYMBOL(native_set_debugreg); | ||
392 | NOKPROBE_SYMBOL(native_load_idt); | ||
393 | |||
394 | #if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE) | 312 | #if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE) |
395 | /* 32-bit pagetable entries */ | 313 | /* 32-bit pagetable entries */ |
396 | #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_32) | 314 | #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_32) |
@@ -399,85 +317,171 @@ NOKPROBE_SYMBOL(native_load_idt); | |||
399 | #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) | 317 | #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) |
400 | #endif | 318 | #endif |
401 | 319 | ||
402 | struct pv_mmu_ops pv_mmu_ops __ro_after_init = { | 320 | struct paravirt_patch_template pv_ops = { |
321 | /* Init ops. */ | ||
322 | .init.patch = native_patch, | ||
403 | 323 | ||
404 | .read_cr2 = native_read_cr2, | 324 | /* Time ops. */ |
405 | .write_cr2 = native_write_cr2, | 325 | .time.sched_clock = native_sched_clock, |
406 | .read_cr3 = __native_read_cr3, | 326 | .time.steal_clock = native_steal_clock, |
407 | .write_cr3 = native_write_cr3, | ||
408 | 327 | ||
409 | .flush_tlb_user = native_flush_tlb, | 328 | /* Cpu ops. */ |
410 | .flush_tlb_kernel = native_flush_tlb_global, | 329 | .cpu.io_delay = native_io_delay, |
411 | .flush_tlb_one_user = native_flush_tlb_one_user, | ||
412 | .flush_tlb_others = native_flush_tlb_others, | ||
413 | .tlb_remove_table = (void (*)(struct mmu_gather *, void *))tlb_remove_page, | ||
414 | 330 | ||
415 | .pgd_alloc = __paravirt_pgd_alloc, | 331 | #ifdef CONFIG_PARAVIRT_XXL |
416 | .pgd_free = paravirt_nop, | 332 | .cpu.cpuid = native_cpuid, |
333 | .cpu.get_debugreg = native_get_debugreg, | ||
334 | .cpu.set_debugreg = native_set_debugreg, | ||
335 | .cpu.read_cr0 = native_read_cr0, | ||
336 | .cpu.write_cr0 = native_write_cr0, | ||
337 | .cpu.write_cr4 = native_write_cr4, | ||
338 | #ifdef CONFIG_X86_64 | ||
339 | .cpu.read_cr8 = native_read_cr8, | ||
340 | .cpu.write_cr8 = native_write_cr8, | ||
341 | #endif | ||
342 | .cpu.wbinvd = native_wbinvd, | ||
343 | .cpu.read_msr = native_read_msr, | ||
344 | .cpu.write_msr = native_write_msr, | ||
345 | .cpu.read_msr_safe = native_read_msr_safe, | ||
346 | .cpu.write_msr_safe = native_write_msr_safe, | ||
347 | .cpu.read_pmc = native_read_pmc, | ||
348 | .cpu.load_tr_desc = native_load_tr_desc, | ||
349 | .cpu.set_ldt = native_set_ldt, | ||
350 | .cpu.load_gdt = native_load_gdt, | ||
351 | .cpu.load_idt = native_load_idt, | ||
352 | .cpu.store_tr = native_store_tr, | ||
353 | .cpu.load_tls = native_load_tls, | ||
354 | #ifdef CONFIG_X86_64 | ||
355 | .cpu.load_gs_index = native_load_gs_index, | ||
356 | #endif | ||
357 | .cpu.write_ldt_entry = native_write_ldt_entry, | ||
358 | .cpu.write_gdt_entry = native_write_gdt_entry, | ||
359 | .cpu.write_idt_entry = native_write_idt_entry, | ||
417 | 360 | ||
418 | .alloc_pte = paravirt_nop, | 361 | .cpu.alloc_ldt = paravirt_nop, |
419 | .alloc_pmd = paravirt_nop, | 362 | .cpu.free_ldt = paravirt_nop, |
420 | .alloc_pud = paravirt_nop, | ||
421 | .alloc_p4d = paravirt_nop, | ||
422 | .release_pte = paravirt_nop, | ||
423 | .release_pmd = paravirt_nop, | ||
424 | .release_pud = paravirt_nop, | ||
425 | .release_p4d = paravirt_nop, | ||
426 | 363 | ||
427 | .set_pte = native_set_pte, | 364 | .cpu.load_sp0 = native_load_sp0, |
428 | .set_pte_at = native_set_pte_at, | ||
429 | .set_pmd = native_set_pmd, | ||
430 | 365 | ||
431 | .ptep_modify_prot_start = __ptep_modify_prot_start, | 366 | #ifdef CONFIG_X86_64 |
432 | .ptep_modify_prot_commit = __ptep_modify_prot_commit, | 367 | .cpu.usergs_sysret64 = native_usergs_sysret64, |
368 | #endif | ||
369 | .cpu.iret = native_iret, | ||
370 | .cpu.swapgs = native_swapgs, | ||
371 | |||
372 | .cpu.set_iopl_mask = native_set_iopl_mask, | ||
373 | |||
374 | .cpu.start_context_switch = paravirt_nop, | ||
375 | .cpu.end_context_switch = paravirt_nop, | ||
376 | |||
377 | /* Irq ops. */ | ||
378 | .irq.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), | ||
379 | .irq.restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl), | ||
380 | .irq.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), | ||
381 | .irq.irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), | ||
382 | .irq.safe_halt = native_safe_halt, | ||
383 | .irq.halt = native_halt, | ||
384 | #endif /* CONFIG_PARAVIRT_XXL */ | ||
385 | |||
386 | /* Mmu ops. */ | ||
387 | .mmu.flush_tlb_user = native_flush_tlb, | ||
388 | .mmu.flush_tlb_kernel = native_flush_tlb_global, | ||
389 | .mmu.flush_tlb_one_user = native_flush_tlb_one_user, | ||
390 | .mmu.flush_tlb_others = native_flush_tlb_others, | ||
391 | .mmu.tlb_remove_table = | ||
392 | (void (*)(struct mmu_gather *, void *))tlb_remove_page, | ||
393 | |||
394 | .mmu.exit_mmap = paravirt_nop, | ||
395 | |||
396 | #ifdef CONFIG_PARAVIRT_XXL | ||
397 | .mmu.read_cr2 = native_read_cr2, | ||
398 | .mmu.write_cr2 = native_write_cr2, | ||
399 | .mmu.read_cr3 = __native_read_cr3, | ||
400 | .mmu.write_cr3 = native_write_cr3, | ||
401 | |||
402 | .mmu.pgd_alloc = __paravirt_pgd_alloc, | ||
403 | .mmu.pgd_free = paravirt_nop, | ||
404 | |||
405 | .mmu.alloc_pte = paravirt_nop, | ||
406 | .mmu.alloc_pmd = paravirt_nop, | ||
407 | .mmu.alloc_pud = paravirt_nop, | ||
408 | .mmu.alloc_p4d = paravirt_nop, | ||
409 | .mmu.release_pte = paravirt_nop, | ||
410 | .mmu.release_pmd = paravirt_nop, | ||
411 | .mmu.release_pud = paravirt_nop, | ||
412 | .mmu.release_p4d = paravirt_nop, | ||
413 | |||
414 | .mmu.set_pte = native_set_pte, | ||
415 | .mmu.set_pte_at = native_set_pte_at, | ||
416 | .mmu.set_pmd = native_set_pmd, | ||
417 | |||
418 | .mmu.ptep_modify_prot_start = __ptep_modify_prot_start, | ||
419 | .mmu.ptep_modify_prot_commit = __ptep_modify_prot_commit, | ||
433 | 420 | ||
434 | #if CONFIG_PGTABLE_LEVELS >= 3 | 421 | #if CONFIG_PGTABLE_LEVELS >= 3 |
435 | #ifdef CONFIG_X86_PAE | 422 | #ifdef CONFIG_X86_PAE |
436 | .set_pte_atomic = native_set_pte_atomic, | 423 | .mmu.set_pte_atomic = native_set_pte_atomic, |
437 | .pte_clear = native_pte_clear, | 424 | .mmu.pte_clear = native_pte_clear, |
438 | .pmd_clear = native_pmd_clear, | 425 | .mmu.pmd_clear = native_pmd_clear, |
439 | #endif | 426 | #endif |
440 | .set_pud = native_set_pud, | 427 | .mmu.set_pud = native_set_pud, |
441 | 428 | ||
442 | .pmd_val = PTE_IDENT, | 429 | .mmu.pmd_val = PTE_IDENT, |
443 | .make_pmd = PTE_IDENT, | 430 | .mmu.make_pmd = PTE_IDENT, |
444 | 431 | ||
445 | #if CONFIG_PGTABLE_LEVELS >= 4 | 432 | #if CONFIG_PGTABLE_LEVELS >= 4 |
446 | .pud_val = PTE_IDENT, | 433 | .mmu.pud_val = PTE_IDENT, |
447 | .make_pud = PTE_IDENT, | 434 | .mmu.make_pud = PTE_IDENT, |
448 | 435 | ||
449 | .set_p4d = native_set_p4d, | 436 | .mmu.set_p4d = native_set_p4d, |
450 | 437 | ||
451 | #if CONFIG_PGTABLE_LEVELS >= 5 | 438 | #if CONFIG_PGTABLE_LEVELS >= 5 |
452 | .p4d_val = PTE_IDENT, | 439 | .mmu.p4d_val = PTE_IDENT, |
453 | .make_p4d = PTE_IDENT, | 440 | .mmu.make_p4d = PTE_IDENT, |
454 | 441 | ||
455 | .set_pgd = native_set_pgd, | 442 | .mmu.set_pgd = native_set_pgd, |
456 | #endif /* CONFIG_PGTABLE_LEVELS >= 5 */ | 443 | #endif /* CONFIG_PGTABLE_LEVELS >= 5 */ |
457 | #endif /* CONFIG_PGTABLE_LEVELS >= 4 */ | 444 | #endif /* CONFIG_PGTABLE_LEVELS >= 4 */ |
458 | #endif /* CONFIG_PGTABLE_LEVELS >= 3 */ | 445 | #endif /* CONFIG_PGTABLE_LEVELS >= 3 */ |
459 | 446 | ||
460 | .pte_val = PTE_IDENT, | 447 | .mmu.pte_val = PTE_IDENT, |
461 | .pgd_val = PTE_IDENT, | 448 | .mmu.pgd_val = PTE_IDENT, |
462 | 449 | ||
463 | .make_pte = PTE_IDENT, | 450 | .mmu.make_pte = PTE_IDENT, |
464 | .make_pgd = PTE_IDENT, | 451 | .mmu.make_pgd = PTE_IDENT, |
465 | 452 | ||
466 | .dup_mmap = paravirt_nop, | 453 | .mmu.dup_mmap = paravirt_nop, |
467 | .exit_mmap = paravirt_nop, | 454 | .mmu.activate_mm = paravirt_nop, |
468 | .activate_mm = paravirt_nop, | ||
469 | 455 | ||
470 | .lazy_mode = { | 456 | .mmu.lazy_mode = { |
471 | .enter = paravirt_nop, | 457 | .enter = paravirt_nop, |
472 | .leave = paravirt_nop, | 458 | .leave = paravirt_nop, |
473 | .flush = paravirt_nop, | 459 | .flush = paravirt_nop, |
474 | }, | 460 | }, |
475 | 461 | ||
476 | .set_fixmap = native_set_fixmap, | 462 | .mmu.set_fixmap = native_set_fixmap, |
463 | #endif /* CONFIG_PARAVIRT_XXL */ | ||
464 | |||
465 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) | ||
466 | /* Lock ops. */ | ||
467 | #ifdef CONFIG_SMP | ||
468 | .lock.queued_spin_lock_slowpath = native_queued_spin_lock_slowpath, | ||
469 | .lock.queued_spin_unlock = | ||
470 | PV_CALLEE_SAVE(__native_queued_spin_unlock), | ||
471 | .lock.wait = paravirt_nop, | ||
472 | .lock.kick = paravirt_nop, | ||
473 | .lock.vcpu_is_preempted = | ||
474 | PV_CALLEE_SAVE(__native_vcpu_is_preempted), | ||
475 | #endif /* SMP */ | ||
476 | #endif | ||
477 | }; | 477 | }; |
478 | 478 | ||
479 | EXPORT_SYMBOL_GPL(pv_time_ops); | 479 | #ifdef CONFIG_PARAVIRT_XXL |
480 | EXPORT_SYMBOL (pv_cpu_ops); | 480 | /* At this point, native_get/set_debugreg has real function entries */ |
481 | EXPORT_SYMBOL (pv_mmu_ops); | 481 | NOKPROBE_SYMBOL(native_get_debugreg); |
482 | NOKPROBE_SYMBOL(native_set_debugreg); | ||
483 | NOKPROBE_SYMBOL(native_load_idt); | ||
484 | #endif | ||
485 | |||
486 | EXPORT_SYMBOL_GPL(pv_ops); | ||
482 | EXPORT_SYMBOL_GPL(pv_info); | 487 | EXPORT_SYMBOL_GPL(pv_info); |
483 | EXPORT_SYMBOL (pv_irq_ops); | ||
diff --git a/arch/x86/kernel/paravirt_patch_32.c b/arch/x86/kernel/paravirt_patch_32.c index 758e69d72ebf..6368c22fa1fa 100644 --- a/arch/x86/kernel/paravirt_patch_32.c +++ b/arch/x86/kernel/paravirt_patch_32.c | |||
@@ -1,18 +1,20 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <asm/paravirt.h> | 2 | #include <asm/paravirt.h> |
3 | 3 | ||
4 | DEF_NATIVE(pv_irq_ops, irq_disable, "cli"); | 4 | #ifdef CONFIG_PARAVIRT_XXL |
5 | DEF_NATIVE(pv_irq_ops, irq_enable, "sti"); | 5 | DEF_NATIVE(irq, irq_disable, "cli"); |
6 | DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf"); | 6 | DEF_NATIVE(irq, irq_enable, "sti"); |
7 | DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax"); | 7 | DEF_NATIVE(irq, restore_fl, "push %eax; popf"); |
8 | DEF_NATIVE(pv_cpu_ops, iret, "iret"); | 8 | DEF_NATIVE(irq, save_fl, "pushf; pop %eax"); |
9 | DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax"); | 9 | DEF_NATIVE(cpu, iret, "iret"); |
10 | DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3"); | 10 | DEF_NATIVE(mmu, read_cr2, "mov %cr2, %eax"); |
11 | DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax"); | 11 | DEF_NATIVE(mmu, write_cr3, "mov %eax, %cr3"); |
12 | DEF_NATIVE(mmu, read_cr3, "mov %cr3, %eax"); | ||
13 | #endif | ||
12 | 14 | ||
13 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) | 15 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) |
14 | DEF_NATIVE(pv_lock_ops, queued_spin_unlock, "movb $0, (%eax)"); | 16 | DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%eax)"); |
15 | DEF_NATIVE(pv_lock_ops, vcpu_is_preempted, "xor %eax, %eax"); | 17 | DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax"); |
16 | #endif | 18 | #endif |
17 | 19 | ||
18 | unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len) | 20 | unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len) |
@@ -30,53 +32,42 @@ unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len) | |||
30 | extern bool pv_is_native_spin_unlock(void); | 32 | extern bool pv_is_native_spin_unlock(void); |
31 | extern bool pv_is_native_vcpu_is_preempted(void); | 33 | extern bool pv_is_native_vcpu_is_preempted(void); |
32 | 34 | ||
33 | unsigned native_patch(u8 type, u16 clobbers, void *ibuf, | 35 | unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len) |
34 | unsigned long addr, unsigned len) | ||
35 | { | 36 | { |
36 | const unsigned char *start, *end; | ||
37 | unsigned ret; | ||
38 | |||
39 | #define PATCH_SITE(ops, x) \ | 37 | #define PATCH_SITE(ops, x) \ |
40 | case PARAVIRT_PATCH(ops.x): \ | 38 | case PARAVIRT_PATCH(ops.x): \ |
41 | start = start_##ops##_##x; \ | 39 | return paravirt_patch_insns(ibuf, len, start_##ops##_##x, end_##ops##_##x) |
42 | end = end_##ops##_##x; \ | 40 | |
43 | goto patch_site | ||
44 | switch (type) { | 41 | switch (type) { |
45 | PATCH_SITE(pv_irq_ops, irq_disable); | 42 | #ifdef CONFIG_PARAVIRT_XXL |
46 | PATCH_SITE(pv_irq_ops, irq_enable); | 43 | PATCH_SITE(irq, irq_disable); |
47 | PATCH_SITE(pv_irq_ops, restore_fl); | 44 | PATCH_SITE(irq, irq_enable); |
48 | PATCH_SITE(pv_irq_ops, save_fl); | 45 | PATCH_SITE(irq, restore_fl); |
49 | PATCH_SITE(pv_cpu_ops, iret); | 46 | PATCH_SITE(irq, save_fl); |
50 | PATCH_SITE(pv_mmu_ops, read_cr2); | 47 | PATCH_SITE(cpu, iret); |
51 | PATCH_SITE(pv_mmu_ops, read_cr3); | 48 | PATCH_SITE(mmu, read_cr2); |
52 | PATCH_SITE(pv_mmu_ops, write_cr3); | 49 | PATCH_SITE(mmu, read_cr3); |
50 | PATCH_SITE(mmu, write_cr3); | ||
51 | #endif | ||
53 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) | 52 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) |
54 | case PARAVIRT_PATCH(pv_lock_ops.queued_spin_unlock): | 53 | case PARAVIRT_PATCH(lock.queued_spin_unlock): |
55 | if (pv_is_native_spin_unlock()) { | 54 | if (pv_is_native_spin_unlock()) |
56 | start = start_pv_lock_ops_queued_spin_unlock; | 55 | return paravirt_patch_insns(ibuf, len, |
57 | end = end_pv_lock_ops_queued_spin_unlock; | 56 | start_lock_queued_spin_unlock, |
58 | goto patch_site; | 57 | end_lock_queued_spin_unlock); |
59 | } | 58 | break; |
60 | goto patch_default; | ||
61 | 59 | ||
62 | case PARAVIRT_PATCH(pv_lock_ops.vcpu_is_preempted): | 60 | case PARAVIRT_PATCH(lock.vcpu_is_preempted): |
63 | if (pv_is_native_vcpu_is_preempted()) { | 61 | if (pv_is_native_vcpu_is_preempted()) |
64 | start = start_pv_lock_ops_vcpu_is_preempted; | 62 | return paravirt_patch_insns(ibuf, len, |
65 | end = end_pv_lock_ops_vcpu_is_preempted; | 63 | start_lock_vcpu_is_preempted, |
66 | goto patch_site; | 64 | end_lock_vcpu_is_preempted); |
67 | } | 65 | break; |
68 | goto patch_default; | ||
69 | #endif | 66 | #endif |
70 | 67 | ||
71 | default: | 68 | default: |
72 | patch_default: __maybe_unused | ||
73 | ret = paravirt_patch_default(type, clobbers, ibuf, addr, len); | ||
74 | break; | ||
75 | |||
76 | patch_site: | ||
77 | ret = paravirt_patch_insns(ibuf, len, start, end); | ||
78 | break; | 69 | break; |
79 | } | 70 | } |
80 | #undef PATCH_SITE | 71 | #undef PATCH_SITE |
81 | return ret; | 72 | return paravirt_patch_default(type, ibuf, addr, len); |
82 | } | 73 | } |
diff --git a/arch/x86/kernel/paravirt_patch_64.c b/arch/x86/kernel/paravirt_patch_64.c index 9cb98f7b07c9..7ca9cb726f4d 100644 --- a/arch/x86/kernel/paravirt_patch_64.c +++ b/arch/x86/kernel/paravirt_patch_64.c | |||
@@ -3,24 +3,26 @@ | |||
3 | #include <asm/asm-offsets.h> | 3 | #include <asm/asm-offsets.h> |
4 | #include <linux/stringify.h> | 4 | #include <linux/stringify.h> |
5 | 5 | ||
6 | DEF_NATIVE(pv_irq_ops, irq_disable, "cli"); | 6 | #ifdef CONFIG_PARAVIRT_XXL |
7 | DEF_NATIVE(pv_irq_ops, irq_enable, "sti"); | 7 | DEF_NATIVE(irq, irq_disable, "cli"); |
8 | DEF_NATIVE(pv_irq_ops, restore_fl, "pushq %rdi; popfq"); | 8 | DEF_NATIVE(irq, irq_enable, "sti"); |
9 | DEF_NATIVE(pv_irq_ops, save_fl, "pushfq; popq %rax"); | 9 | DEF_NATIVE(irq, restore_fl, "pushq %rdi; popfq"); |
10 | DEF_NATIVE(pv_mmu_ops, read_cr2, "movq %cr2, %rax"); | 10 | DEF_NATIVE(irq, save_fl, "pushfq; popq %rax"); |
11 | DEF_NATIVE(pv_mmu_ops, read_cr3, "movq %cr3, %rax"); | 11 | DEF_NATIVE(mmu, read_cr2, "movq %cr2, %rax"); |
12 | DEF_NATIVE(pv_mmu_ops, write_cr3, "movq %rdi, %cr3"); | 12 | DEF_NATIVE(mmu, read_cr3, "movq %cr3, %rax"); |
13 | DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd"); | 13 | DEF_NATIVE(mmu, write_cr3, "movq %rdi, %cr3"); |
14 | DEF_NATIVE(cpu, wbinvd, "wbinvd"); | ||
14 | 15 | ||
15 | DEF_NATIVE(pv_cpu_ops, usergs_sysret64, "swapgs; sysretq"); | 16 | DEF_NATIVE(cpu, usergs_sysret64, "swapgs; sysretq"); |
16 | DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs"); | 17 | DEF_NATIVE(cpu, swapgs, "swapgs"); |
18 | #endif | ||
17 | 19 | ||
18 | DEF_NATIVE(, mov32, "mov %edi, %eax"); | 20 | DEF_NATIVE(, mov32, "mov %edi, %eax"); |
19 | DEF_NATIVE(, mov64, "mov %rdi, %rax"); | 21 | DEF_NATIVE(, mov64, "mov %rdi, %rax"); |
20 | 22 | ||
21 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) | 23 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) |
22 | DEF_NATIVE(pv_lock_ops, queued_spin_unlock, "movb $0, (%rdi)"); | 24 | DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%rdi)"); |
23 | DEF_NATIVE(pv_lock_ops, vcpu_is_preempted, "xor %eax, %eax"); | 25 | DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax"); |
24 | #endif | 26 | #endif |
25 | 27 | ||
26 | unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len) | 28 | unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len) |
@@ -38,55 +40,44 @@ unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len) | |||
38 | extern bool pv_is_native_spin_unlock(void); | 40 | extern bool pv_is_native_spin_unlock(void); |
39 | extern bool pv_is_native_vcpu_is_preempted(void); | 41 | extern bool pv_is_native_vcpu_is_preempted(void); |
40 | 42 | ||
41 | unsigned native_patch(u8 type, u16 clobbers, void *ibuf, | 43 | unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len) |
42 | unsigned long addr, unsigned len) | ||
43 | { | 44 | { |
44 | const unsigned char *start, *end; | ||
45 | unsigned ret; | ||
46 | |||
47 | #define PATCH_SITE(ops, x) \ | 45 | #define PATCH_SITE(ops, x) \ |
48 | case PARAVIRT_PATCH(ops.x): \ | 46 | case PARAVIRT_PATCH(ops.x): \ |
49 | start = start_##ops##_##x; \ | 47 | return paravirt_patch_insns(ibuf, len, start_##ops##_##x, end_##ops##_##x) |
50 | end = end_##ops##_##x; \ | ||
51 | goto patch_site | ||
52 | switch(type) { | ||
53 | PATCH_SITE(pv_irq_ops, restore_fl); | ||
54 | PATCH_SITE(pv_irq_ops, save_fl); | ||
55 | PATCH_SITE(pv_irq_ops, irq_enable); | ||
56 | PATCH_SITE(pv_irq_ops, irq_disable); | ||
57 | PATCH_SITE(pv_cpu_ops, usergs_sysret64); | ||
58 | PATCH_SITE(pv_cpu_ops, swapgs); | ||
59 | PATCH_SITE(pv_mmu_ops, read_cr2); | ||
60 | PATCH_SITE(pv_mmu_ops, read_cr3); | ||
61 | PATCH_SITE(pv_mmu_ops, write_cr3); | ||
62 | PATCH_SITE(pv_cpu_ops, wbinvd); | ||
63 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) | ||
64 | case PARAVIRT_PATCH(pv_lock_ops.queued_spin_unlock): | ||
65 | if (pv_is_native_spin_unlock()) { | ||
66 | start = start_pv_lock_ops_queued_spin_unlock; | ||
67 | end = end_pv_lock_ops_queued_spin_unlock; | ||
68 | goto patch_site; | ||
69 | } | ||
70 | goto patch_default; | ||
71 | 48 | ||
72 | case PARAVIRT_PATCH(pv_lock_ops.vcpu_is_preempted): | 49 | switch (type) { |
73 | if (pv_is_native_vcpu_is_preempted()) { | 50 | #ifdef CONFIG_PARAVIRT_XXL |
74 | start = start_pv_lock_ops_vcpu_is_preempted; | 51 | PATCH_SITE(irq, restore_fl); |
75 | end = end_pv_lock_ops_vcpu_is_preempted; | 52 | PATCH_SITE(irq, save_fl); |
76 | goto patch_site; | 53 | PATCH_SITE(irq, irq_enable); |
77 | } | 54 | PATCH_SITE(irq, irq_disable); |
78 | goto patch_default; | 55 | PATCH_SITE(cpu, usergs_sysret64); |
56 | PATCH_SITE(cpu, swapgs); | ||
57 | PATCH_SITE(cpu, wbinvd); | ||
58 | PATCH_SITE(mmu, read_cr2); | ||
59 | PATCH_SITE(mmu, read_cr3); | ||
60 | PATCH_SITE(mmu, write_cr3); | ||
79 | #endif | 61 | #endif |
62 | #if defined(CONFIG_PARAVIRT_SPINLOCKS) | ||
63 | case PARAVIRT_PATCH(lock.queued_spin_unlock): | ||
64 | if (pv_is_native_spin_unlock()) | ||
65 | return paravirt_patch_insns(ibuf, len, | ||
66 | start_lock_queued_spin_unlock, | ||
67 | end_lock_queued_spin_unlock); | ||
68 | break; | ||
80 | 69 | ||
81 | default: | 70 | case PARAVIRT_PATCH(lock.vcpu_is_preempted): |
82 | patch_default: __maybe_unused | 71 | if (pv_is_native_vcpu_is_preempted()) |
83 | ret = paravirt_patch_default(type, clobbers, ibuf, addr, len); | 72 | return paravirt_patch_insns(ibuf, len, |
73 | start_lock_vcpu_is_preempted, | ||
74 | end_lock_vcpu_is_preempted); | ||
84 | break; | 75 | break; |
76 | #endif | ||
85 | 77 | ||
86 | patch_site: | 78 | default: |
87 | ret = paravirt_patch_insns(ibuf, len, start, end); | ||
88 | break; | 79 | break; |
89 | } | 80 | } |
90 | #undef PATCH_SITE | 81 | #undef PATCH_SITE |
91 | return ret; | 82 | return paravirt_patch_default(type, ibuf, addr, len); |
92 | } | 83 | } |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 03b7529333a6..e9f777bfed40 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -247,7 +247,7 @@ unsigned long long sched_clock(void) | |||
247 | 247 | ||
248 | bool using_native_sched_clock(void) | 248 | bool using_native_sched_clock(void) |
249 | { | 249 | { |
250 | return pv_time_ops.sched_clock == native_sched_clock; | 250 | return pv_ops.time.sched_clock == native_sched_clock; |
251 | } | 251 | } |
252 | #else | 252 | #else |
253 | unsigned long long | 253 | unsigned long long |
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 44685fb2a192..1eae5af491c2 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | #define TOPOLOGY_REGISTER_OFFSET 0x10 | 27 | #define TOPOLOGY_REGISTER_OFFSET 0x10 |
28 | 28 | ||
29 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT | 29 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT_XXL |
30 | /* | 30 | /* |
31 | * Interrupt control on vSMPowered systems: | 31 | * Interrupt control on vSMPowered systems: |
32 | * ~AC is a shadow of IF. If IF is 'on' AC should be 'off' | 32 | * ~AC is a shadow of IF. If IF is 'on' AC should be 'off' |
@@ -69,17 +69,17 @@ asmlinkage __visible void vsmp_irq_enable(void) | |||
69 | } | 69 | } |
70 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_enable); | 70 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_enable); |
71 | 71 | ||
72 | static unsigned __init vsmp_patch(u8 type, u16 clobbers, void *ibuf, | 72 | static unsigned __init vsmp_patch(u8 type, void *ibuf, |
73 | unsigned long addr, unsigned len) | 73 | unsigned long addr, unsigned len) |
74 | { | 74 | { |
75 | switch (type) { | 75 | switch (type) { |
76 | case PARAVIRT_PATCH(pv_irq_ops.irq_enable): | 76 | case PARAVIRT_PATCH(irq.irq_enable): |
77 | case PARAVIRT_PATCH(pv_irq_ops.irq_disable): | 77 | case PARAVIRT_PATCH(irq.irq_disable): |
78 | case PARAVIRT_PATCH(pv_irq_ops.save_fl): | 78 | case PARAVIRT_PATCH(irq.save_fl): |
79 | case PARAVIRT_PATCH(pv_irq_ops.restore_fl): | 79 | case PARAVIRT_PATCH(irq.restore_fl): |
80 | return paravirt_patch_default(type, clobbers, ibuf, addr, len); | 80 | return paravirt_patch_default(type, ibuf, addr, len); |
81 | default: | 81 | default: |
82 | return native_patch(type, clobbers, ibuf, addr, len); | 82 | return native_patch(type, ibuf, addr, len); |
83 | } | 83 | } |
84 | 84 | ||
85 | } | 85 | } |
@@ -111,11 +111,11 @@ static void __init set_vsmp_pv_ops(void) | |||
111 | 111 | ||
112 | if (cap & ctl & (1 << 4)) { | 112 | if (cap & ctl & (1 << 4)) { |
113 | /* Setup irq ops and turn on vSMP IRQ fastpath handling */ | 113 | /* Setup irq ops and turn on vSMP IRQ fastpath handling */ |
114 | pv_irq_ops.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable); | 114 | pv_ops.irq.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable); |
115 | pv_irq_ops.irq_enable = PV_CALLEE_SAVE(vsmp_irq_enable); | 115 | pv_ops.irq.irq_enable = PV_CALLEE_SAVE(vsmp_irq_enable); |
116 | pv_irq_ops.save_fl = PV_CALLEE_SAVE(vsmp_save_fl); | 116 | pv_ops.irq.save_fl = PV_CALLEE_SAVE(vsmp_save_fl); |
117 | pv_irq_ops.restore_fl = PV_CALLEE_SAVE(vsmp_restore_fl); | 117 | pv_ops.irq.restore_fl = PV_CALLEE_SAVE(vsmp_restore_fl); |
118 | pv_init_ops.patch = vsmp_patch; | 118 | pv_ops.init.patch = vsmp_patch; |
119 | ctl &= ~(1 << 4); | 119 | ctl &= ~(1 << 4); |
120 | } | 120 | } |
121 | writel(ctl, address + 4); | 121 | writel(ctl, address + 4); |
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c index 7ae36868aed2..a19ef1a416ff 100644 --- a/arch/x86/mm/mem_encrypt_identity.c +++ b/arch/x86/mm/mem_encrypt_identity.c | |||
@@ -27,6 +27,7 @@ | |||
27 | * be extended when new paravirt and debugging variants are added.) | 27 | * be extended when new paravirt and debugging variants are added.) |
28 | */ | 28 | */ |
29 | #undef CONFIG_PARAVIRT | 29 | #undef CONFIG_PARAVIRT |
30 | #undef CONFIG_PARAVIRT_XXL | ||
30 | #undef CONFIG_PARAVIRT_SPINLOCKS | 31 | #undef CONFIG_PARAVIRT_SPINLOCKS |
31 | 32 | ||
32 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index 14be6a5935e1..1ef391aa184d 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig | |||
@@ -18,6 +18,7 @@ config XEN_PV | |||
18 | bool "Xen PV guest support" | 18 | bool "Xen PV guest support" |
19 | default y | 19 | default y |
20 | depends on XEN | 20 | depends on XEN |
21 | select PARAVIRT_XXL | ||
21 | select XEN_HAVE_PVMMU | 22 | select XEN_HAVE_PVMMU |
22 | select XEN_HAVE_VPMU | 23 | select XEN_HAVE_VPMU |
23 | help | 24 | help |
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index d83cb5478f54..dd2550d33b38 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile | |||
@@ -12,25 +12,46 @@ endif | |||
12 | # Make sure early boot has no stackprotector | 12 | # Make sure early boot has no stackprotector |
13 | nostackp := $(call cc-option, -fno-stack-protector) | 13 | nostackp := $(call cc-option, -fno-stack-protector) |
14 | CFLAGS_enlighten_pv.o := $(nostackp) | 14 | CFLAGS_enlighten_pv.o := $(nostackp) |
15 | CFLAGS_mmu_pv.o := $(nostackp) | 15 | CFLAGS_mmu_pv.o := $(nostackp) |
16 | 16 | ||
17 | obj-y := enlighten.o multicalls.o mmu.o irq.o \ | 17 | obj-y += enlighten.o |
18 | time.o xen-asm.o xen-asm_$(BITS).o \ | 18 | obj-y += mmu.o |
19 | grant-table.o suspend.o platform-pci-unplug.o | 19 | obj-y += time.o |
20 | obj-y += grant-table.o | ||
21 | obj-y += suspend.o | ||
20 | 22 | ||
21 | obj-$(CONFIG_XEN_PVHVM) += enlighten_hvm.o mmu_hvm.o suspend_hvm.o | 23 | obj-$(CONFIG_XEN_PVHVM) += enlighten_hvm.o |
22 | obj-$(CONFIG_XEN_PV) += setup.o apic.o pmu.o suspend_pv.o \ | 24 | obj-$(CONFIG_XEN_PVHVM) += mmu_hvm.o |
23 | p2m.o enlighten_pv.o mmu_pv.o | 25 | obj-$(CONFIG_XEN_PVHVM) += suspend_hvm.o |
24 | obj-$(CONFIG_XEN_PVH) += enlighten_pvh.o | 26 | obj-$(CONFIG_XEN_PVHVM) += platform-pci-unplug.o |
25 | 27 | ||
26 | obj-$(CONFIG_EVENT_TRACING) += trace.o | 28 | obj-$(CONFIG_XEN_PV) += setup.o |
29 | obj-$(CONFIG_XEN_PV) += apic.o | ||
30 | obj-$(CONFIG_XEN_PV) += pmu.o | ||
31 | obj-$(CONFIG_XEN_PV) += suspend_pv.o | ||
32 | obj-$(CONFIG_XEN_PV) += p2m.o | ||
33 | obj-$(CONFIG_XEN_PV) += enlighten_pv.o | ||
34 | obj-$(CONFIG_XEN_PV) += mmu_pv.o | ||
35 | obj-$(CONFIG_XEN_PV) += irq.o | ||
36 | obj-$(CONFIG_XEN_PV) += multicalls.o | ||
37 | obj-$(CONFIG_XEN_PV) += xen-asm.o | ||
38 | obj-$(CONFIG_XEN_PV) += xen-asm_$(BITS).o | ||
39 | |||
40 | obj-$(CONFIG_XEN_PVH) += enlighten_pvh.o | ||
41 | obj-$(CONFIG_XEN_PVH) += xen-pvh.o | ||
42 | |||
43 | obj-$(CONFIG_EVENT_TRACING) += trace.o | ||
27 | 44 | ||
28 | obj-$(CONFIG_SMP) += smp.o | 45 | obj-$(CONFIG_SMP) += smp.o |
29 | obj-$(CONFIG_XEN_PV_SMP) += smp_pv.o | 46 | obj-$(CONFIG_XEN_PV_SMP) += smp_pv.o |
30 | obj-$(CONFIG_XEN_PVHVM_SMP) += smp_hvm.o | 47 | obj-$(CONFIG_XEN_PVHVM_SMP) += smp_hvm.o |
48 | |||
31 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o | 49 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o |
50 | |||
32 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o | 51 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o |
52 | |||
33 | obj-$(CONFIG_XEN_DOM0) += vga.o | 53 | obj-$(CONFIG_XEN_DOM0) += vga.o |
54 | |||
34 | obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o | 55 | obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o |
56 | |||
35 | obj-$(CONFIG_XEN_EFI) += efi.o | 57 | obj-$(CONFIG_XEN_EFI) += efi.o |
36 | obj-$(CONFIG_XEN_PVH) += xen-pvh.o | ||
diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c index 1804b27f9632..1fbb629a9d78 100644 --- a/arch/x86/xen/efi.c +++ b/arch/x86/xen/efi.c | |||
@@ -1,18 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Copyright (c) 2014 Oracle Co., Daniel Kiper | 3 | * Copyright (c) 2014 Oracle Co., Daniel Kiper |
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | 4 | */ |
17 | 5 | ||
18 | #include <linux/bitops.h> | 6 | #include <linux/bitops.h> |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 0ca46e03b830..67b2f31a1265 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1,3 +1,5 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
1 | #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG | 3 | #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG |
2 | #include <linux/bootmem.h> | 4 | #include <linux/bootmem.h> |
3 | #endif | 5 | #endif |
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c index 19c1ff542387..0e75642d42a3 100644 --- a/arch/x86/xen/enlighten_hvm.c +++ b/arch/x86/xen/enlighten_hvm.c | |||
@@ -1,3 +1,5 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
1 | #include <linux/acpi.h> | 3 | #include <linux/acpi.h> |
2 | #include <linux/cpu.h> | 4 | #include <linux/cpu.h> |
3 | #include <linux/kexec.h> | 5 | #include <linux/kexec.h> |
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 52a7c3faee0c..ec7a4209f310 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c | |||
@@ -995,11 +995,14 @@ void __init xen_setup_vcpu_info_placement(void) | |||
995 | * percpu area for all cpus, so make use of it. | 995 | * percpu area for all cpus, so make use of it. |
996 | */ | 996 | */ |
997 | if (xen_have_vcpu_info_placement) { | 997 | if (xen_have_vcpu_info_placement) { |
998 | pv_irq_ops.save_fl = __PV_IS_CALLEE_SAVE(xen_save_fl_direct); | 998 | pv_ops.irq.save_fl = __PV_IS_CALLEE_SAVE(xen_save_fl_direct); |
999 | pv_irq_ops.restore_fl = __PV_IS_CALLEE_SAVE(xen_restore_fl_direct); | 999 | pv_ops.irq.restore_fl = |
1000 | pv_irq_ops.irq_disable = __PV_IS_CALLEE_SAVE(xen_irq_disable_direct); | 1000 | __PV_IS_CALLEE_SAVE(xen_restore_fl_direct); |
1001 | pv_irq_ops.irq_enable = __PV_IS_CALLEE_SAVE(xen_irq_enable_direct); | 1001 | pv_ops.irq.irq_disable = |
1002 | pv_mmu_ops.read_cr2 = xen_read_cr2_direct; | 1002 | __PV_IS_CALLEE_SAVE(xen_irq_disable_direct); |
1003 | pv_ops.irq.irq_enable = | ||
1004 | __PV_IS_CALLEE_SAVE(xen_irq_enable_direct); | ||
1005 | pv_ops.mmu.read_cr2 = xen_read_cr2_direct; | ||
1003 | } | 1006 | } |
1004 | } | 1007 | } |
1005 | 1008 | ||
@@ -1174,14 +1177,14 @@ static void __init xen_boot_params_init_edd(void) | |||
1174 | */ | 1177 | */ |
1175 | static void __init xen_setup_gdt(int cpu) | 1178 | static void __init xen_setup_gdt(int cpu) |
1176 | { | 1179 | { |
1177 | pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot; | 1180 | pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry_boot; |
1178 | pv_cpu_ops.load_gdt = xen_load_gdt_boot; | 1181 | pv_ops.cpu.load_gdt = xen_load_gdt_boot; |
1179 | 1182 | ||
1180 | setup_stack_canary_segment(cpu); | 1183 | setup_stack_canary_segment(cpu); |
1181 | switch_to_new_gdt(cpu); | 1184 | switch_to_new_gdt(cpu); |
1182 | 1185 | ||
1183 | pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry; | 1186 | pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry; |
1184 | pv_cpu_ops.load_gdt = xen_load_gdt; | 1187 | pv_ops.cpu.load_gdt = xen_load_gdt; |
1185 | } | 1188 | } |
1186 | 1189 | ||
1187 | static void __init xen_dom0_set_legacy_features(void) | 1190 | static void __init xen_dom0_set_legacy_features(void) |
@@ -1206,8 +1209,8 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1206 | 1209 | ||
1207 | /* Install Xen paravirt ops */ | 1210 | /* Install Xen paravirt ops */ |
1208 | pv_info = xen_info; | 1211 | pv_info = xen_info; |
1209 | pv_init_ops.patch = paravirt_patch_default; | 1212 | pv_ops.init.patch = paravirt_patch_default; |
1210 | pv_cpu_ops = xen_cpu_ops; | 1213 | pv_ops.cpu = xen_cpu_ops; |
1211 | xen_init_irq_ops(); | 1214 | xen_init_irq_ops(); |
1212 | 1215 | ||
1213 | /* | 1216 | /* |
@@ -1276,8 +1279,10 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1276 | #endif | 1279 | #endif |
1277 | 1280 | ||
1278 | if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { | 1281 | if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { |
1279 | pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start; | 1282 | pv_ops.mmu.ptep_modify_prot_start = |
1280 | pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit; | 1283 | xen_ptep_modify_prot_start; |
1284 | pv_ops.mmu.ptep_modify_prot_commit = | ||
1285 | xen_ptep_modify_prot_commit; | ||
1281 | } | 1286 | } |
1282 | 1287 | ||
1283 | machine_ops = xen_machine_ops; | 1288 | machine_ops = xen_machine_ops; |
diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c index 92ccc718152d..ecb0d5450334 100644 --- a/arch/x86/xen/grant-table.c +++ b/arch/x86/xen/grant-table.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 OR MIT | ||
1 | /****************************************************************************** | 2 | /****************************************************************************** |
2 | * grant_table.c | 3 | * grant_table.c |
3 | * x86 specific part | 4 | * x86 specific part |
@@ -8,30 +9,6 @@ | |||
8 | * Copyright (c) 2004-2005, K A Fraser | 9 | * Copyright (c) 2004-2005, K A Fraser |
9 | * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> | 10 | * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> |
10 | * VA Linux Systems Japan. Split out x86 specific part. | 11 | * VA Linux Systems Japan. Split out x86 specific part. |
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License version 2 | ||
14 | * as published by the Free Software Foundation; or, when distributed | ||
15 | * separately from the Linux kernel or incorporated into other | ||
16 | * software packages, subject to the following license: | ||
17 | * | ||
18 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
19 | * of this source file (the "Software"), to deal in the Software without | ||
20 | * restriction, including without limitation the rights to use, copy, modify, | ||
21 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
22 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
23 | * the following conditions: | ||
24 | * | ||
25 | * The above copyright notice and this permission notice shall be included in | ||
26 | * all copies or substantial portions of the Software. | ||
27 | * | ||
28 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
29 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
30 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
31 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
32 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
33 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
34 | * IN THE SOFTWARE. | ||
35 | */ | 12 | */ |
36 | 13 | ||
37 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c index 7515a19fd324..850c93f346c7 100644 --- a/arch/x86/xen/irq.c +++ b/arch/x86/xen/irq.c | |||
@@ -128,6 +128,6 @@ static const struct pv_irq_ops xen_irq_ops __initconst = { | |||
128 | 128 | ||
129 | void __init xen_init_irq_ops(void) | 129 | void __init xen_init_irq_ops(void) |
130 | { | 130 | { |
131 | pv_irq_ops = xen_irq_ops; | 131 | pv_ops.irq = xen_irq_ops; |
132 | x86_init.irqs.intr_init = xen_init_IRQ; | 132 | x86_init.irqs.intr_init = xen_init_IRQ; |
133 | } | 133 | } |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 96fc2f0fdbfe..60e9c37fd79f 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1,3 +1,5 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
1 | #include <linux/pfn.h> | 3 | #include <linux/pfn.h> |
2 | #include <asm/xen/page.h> | 4 | #include <asm/xen/page.h> |
3 | #include <asm/xen/hypercall.h> | 5 | #include <asm/xen/hypercall.h> |
@@ -6,12 +8,6 @@ | |||
6 | #include "multicalls.h" | 8 | #include "multicalls.h" |
7 | #include "mmu.h" | 9 | #include "mmu.h" |
8 | 10 | ||
9 | /* | ||
10 | * Protects atomic reservation decrease/increase against concurrent increases. | ||
11 | * Also protects non-atomic updates of current_pages and balloon lists. | ||
12 | */ | ||
13 | DEFINE_SPINLOCK(xen_reservation_lock); | ||
14 | |||
15 | unsigned long arbitrary_virt_to_mfn(void *vaddr) | 11 | unsigned long arbitrary_virt_to_mfn(void *vaddr) |
16 | { | 12 | { |
17 | xmaddr_t maddr = arbitrary_virt_to_machine(vaddr); | 13 | xmaddr_t maddr = arbitrary_virt_to_machine(vaddr); |
@@ -42,186 +38,6 @@ xmaddr_t arbitrary_virt_to_machine(void *vaddr) | |||
42 | } | 38 | } |
43 | EXPORT_SYMBOL_GPL(arbitrary_virt_to_machine); | 39 | EXPORT_SYMBOL_GPL(arbitrary_virt_to_machine); |
44 | 40 | ||
45 | static noinline void xen_flush_tlb_all(void) | ||
46 | { | ||
47 | struct mmuext_op *op; | ||
48 | struct multicall_space mcs; | ||
49 | |||
50 | preempt_disable(); | ||
51 | |||
52 | mcs = xen_mc_entry(sizeof(*op)); | ||
53 | |||
54 | op = mcs.args; | ||
55 | op->cmd = MMUEXT_TLB_FLUSH_ALL; | ||
56 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); | ||
57 | |||
58 | xen_mc_issue(PARAVIRT_LAZY_MMU); | ||
59 | |||
60 | preempt_enable(); | ||
61 | } | ||
62 | |||
63 | #define REMAP_BATCH_SIZE 16 | ||
64 | |||
65 | struct remap_data { | ||
66 | xen_pfn_t *pfn; | ||
67 | bool contiguous; | ||
68 | bool no_translate; | ||
69 | pgprot_t prot; | ||
70 | struct mmu_update *mmu_update; | ||
71 | }; | ||
72 | |||
73 | static int remap_area_pfn_pte_fn(pte_t *ptep, pgtable_t token, | ||
74 | unsigned long addr, void *data) | ||
75 | { | ||
76 | struct remap_data *rmd = data; | ||
77 | pte_t pte = pte_mkspecial(mfn_pte(*rmd->pfn, rmd->prot)); | ||
78 | |||
79 | /* | ||
80 | * If we have a contiguous range, just update the pfn itself, | ||
81 | * else update pointer to be "next pfn". | ||
82 | */ | ||
83 | if (rmd->contiguous) | ||
84 | (*rmd->pfn)++; | ||
85 | else | ||
86 | rmd->pfn++; | ||
87 | |||
88 | rmd->mmu_update->ptr = virt_to_machine(ptep).maddr; | ||
89 | rmd->mmu_update->ptr |= rmd->no_translate ? | ||
90 | MMU_PT_UPDATE_NO_TRANSLATE : | ||
91 | MMU_NORMAL_PT_UPDATE; | ||
92 | rmd->mmu_update->val = pte_val_ma(pte); | ||
93 | rmd->mmu_update++; | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int do_remap_pfn(struct vm_area_struct *vma, | ||
99 | unsigned long addr, | ||
100 | xen_pfn_t *pfn, int nr, | ||
101 | int *err_ptr, pgprot_t prot, | ||
102 | unsigned int domid, | ||
103 | bool no_translate, | ||
104 | struct page **pages) | ||
105 | { | ||
106 | int err = 0; | ||
107 | struct remap_data rmd; | ||
108 | struct mmu_update mmu_update[REMAP_BATCH_SIZE]; | ||
109 | unsigned long range; | ||
110 | int mapped = 0; | ||
111 | |||
112 | BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO))); | ||
113 | |||
114 | rmd.pfn = pfn; | ||
115 | rmd.prot = prot; | ||
116 | /* | ||
117 | * We use the err_ptr to indicate if there we are doing a contiguous | ||
118 | * mapping or a discontigious mapping. | ||
119 | */ | ||
120 | rmd.contiguous = !err_ptr; | ||
121 | rmd.no_translate = no_translate; | ||
122 | |||
123 | while (nr) { | ||
124 | int index = 0; | ||
125 | int done = 0; | ||
126 | int batch = min(REMAP_BATCH_SIZE, nr); | ||
127 | int batch_left = batch; | ||
128 | range = (unsigned long)batch << PAGE_SHIFT; | ||
129 | |||
130 | rmd.mmu_update = mmu_update; | ||
131 | err = apply_to_page_range(vma->vm_mm, addr, range, | ||
132 | remap_area_pfn_pte_fn, &rmd); | ||
133 | if (err) | ||
134 | goto out; | ||
135 | |||
136 | /* We record the error for each page that gives an error, but | ||
137 | * continue mapping until the whole set is done */ | ||
138 | do { | ||
139 | int i; | ||
140 | |||
141 | err = HYPERVISOR_mmu_update(&mmu_update[index], | ||
142 | batch_left, &done, domid); | ||
143 | |||
144 | /* | ||
145 | * @err_ptr may be the same buffer as @gfn, so | ||
146 | * only clear it after each chunk of @gfn is | ||
147 | * used. | ||
148 | */ | ||
149 | if (err_ptr) { | ||
150 | for (i = index; i < index + done; i++) | ||
151 | err_ptr[i] = 0; | ||
152 | } | ||
153 | if (err < 0) { | ||
154 | if (!err_ptr) | ||
155 | goto out; | ||
156 | err_ptr[i] = err; | ||
157 | done++; /* Skip failed frame. */ | ||
158 | } else | ||
159 | mapped += done; | ||
160 | batch_left -= done; | ||
161 | index += done; | ||
162 | } while (batch_left); | ||
163 | |||
164 | nr -= batch; | ||
165 | addr += range; | ||
166 | if (err_ptr) | ||
167 | err_ptr += batch; | ||
168 | cond_resched(); | ||
169 | } | ||
170 | out: | ||
171 | |||
172 | xen_flush_tlb_all(); | ||
173 | |||
174 | return err < 0 ? err : mapped; | ||
175 | } | ||
176 | |||
177 | int xen_remap_domain_gfn_range(struct vm_area_struct *vma, | ||
178 | unsigned long addr, | ||
179 | xen_pfn_t gfn, int nr, | ||
180 | pgprot_t prot, unsigned domid, | ||
181 | struct page **pages) | ||
182 | { | ||
183 | if (xen_feature(XENFEAT_auto_translated_physmap)) | ||
184 | return -EOPNOTSUPP; | ||
185 | |||
186 | return do_remap_pfn(vma, addr, &gfn, nr, NULL, prot, domid, false, | ||
187 | pages); | ||
188 | } | ||
189 | EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_range); | ||
190 | |||
191 | int xen_remap_domain_gfn_array(struct vm_area_struct *vma, | ||
192 | unsigned long addr, | ||
193 | xen_pfn_t *gfn, int nr, | ||
194 | int *err_ptr, pgprot_t prot, | ||
195 | unsigned domid, struct page **pages) | ||
196 | { | ||
197 | if (xen_feature(XENFEAT_auto_translated_physmap)) | ||
198 | return xen_xlate_remap_gfn_array(vma, addr, gfn, nr, err_ptr, | ||
199 | prot, domid, pages); | ||
200 | |||
201 | /* We BUG_ON because it's a programmer error to pass a NULL err_ptr, | ||
202 | * and the consequences later is quite hard to detect what the actual | ||
203 | * cause of "wrong memory was mapped in". | ||
204 | */ | ||
205 | BUG_ON(err_ptr == NULL); | ||
206 | return do_remap_pfn(vma, addr, gfn, nr, err_ptr, prot, domid, | ||
207 | false, pages); | ||
208 | } | ||
209 | EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_array); | ||
210 | |||
211 | int xen_remap_domain_mfn_array(struct vm_area_struct *vma, | ||
212 | unsigned long addr, | ||
213 | xen_pfn_t *mfn, int nr, | ||
214 | int *err_ptr, pgprot_t prot, | ||
215 | unsigned int domid, struct page **pages) | ||
216 | { | ||
217 | if (xen_feature(XENFEAT_auto_translated_physmap)) | ||
218 | return -EOPNOTSUPP; | ||
219 | |||
220 | return do_remap_pfn(vma, addr, mfn, nr, err_ptr, prot, domid, | ||
221 | true, pages); | ||
222 | } | ||
223 | EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_array); | ||
224 | |||
225 | /* Returns: 0 success */ | 41 | /* Returns: 0 success */ |
226 | int xen_unmap_domain_gfn_range(struct vm_area_struct *vma, | 42 | int xen_unmap_domain_gfn_range(struct vm_area_struct *vma, |
227 | int nr, struct page **pages) | 43 | int nr, struct page **pages) |
diff --git a/arch/x86/xen/mmu_hvm.c b/arch/x86/xen/mmu_hvm.c index dd2ad82eee80..57409373750f 100644 --- a/arch/x86/xen/mmu_hvm.c +++ b/arch/x86/xen/mmu_hvm.c | |||
@@ -73,7 +73,7 @@ static int is_pagetable_dying_supported(void) | |||
73 | void __init xen_hvm_init_mmu_ops(void) | 73 | void __init xen_hvm_init_mmu_ops(void) |
74 | { | 74 | { |
75 | if (is_pagetable_dying_supported()) | 75 | if (is_pagetable_dying_supported()) |
76 | pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap; | 76 | pv_ops.mmu.exit_mmap = xen_hvm_exit_mmap; |
77 | #ifdef CONFIG_PROC_VMCORE | 77 | #ifdef CONFIG_PROC_VMCORE |
78 | WARN_ON(register_oldmem_pfn_is_ram(&xen_oldmem_pfn_is_ram)); | 78 | WARN_ON(register_oldmem_pfn_is_ram(&xen_oldmem_pfn_is_ram)); |
79 | #endif | 79 | #endif |
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index dd461c0167ef..70ea598a37d2 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c | |||
@@ -1,3 +1,5 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
1 | /* | 3 | /* |
2 | * Xen mmu operations | 4 | * Xen mmu operations |
3 | * | 5 | * |
@@ -99,6 +101,12 @@ static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss; | |||
99 | #endif /* CONFIG_X86_64 */ | 101 | #endif /* CONFIG_X86_64 */ |
100 | 102 | ||
101 | /* | 103 | /* |
104 | * Protects atomic reservation decrease/increase against concurrent increases. | ||
105 | * Also protects non-atomic updates of current_pages and balloon lists. | ||
106 | */ | ||
107 | static DEFINE_SPINLOCK(xen_reservation_lock); | ||
108 | |||
109 | /* | ||
102 | * Note about cr3 (pagetable base) values: | 110 | * Note about cr3 (pagetable base) values: |
103 | * | 111 | * |
104 | * xen_cr3 contains the current logical cr3 value; it contains the | 112 | * xen_cr3 contains the current logical cr3 value; it contains the |
@@ -2209,7 +2217,7 @@ static void __init xen_write_cr3_init(unsigned long cr3) | |||
2209 | set_page_prot(initial_page_table, PAGE_KERNEL); | 2217 | set_page_prot(initial_page_table, PAGE_KERNEL); |
2210 | set_page_prot(initial_kernel_pmd, PAGE_KERNEL); | 2218 | set_page_prot(initial_kernel_pmd, PAGE_KERNEL); |
2211 | 2219 | ||
2212 | pv_mmu_ops.write_cr3 = &xen_write_cr3; | 2220 | pv_ops.mmu.write_cr3 = &xen_write_cr3; |
2213 | } | 2221 | } |
2214 | 2222 | ||
2215 | /* | 2223 | /* |
@@ -2358,27 +2366,27 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) | |||
2358 | 2366 | ||
2359 | static void __init xen_post_allocator_init(void) | 2367 | static void __init xen_post_allocator_init(void) |
2360 | { | 2368 | { |
2361 | pv_mmu_ops.set_pte = xen_set_pte; | 2369 | pv_ops.mmu.set_pte = xen_set_pte; |
2362 | pv_mmu_ops.set_pmd = xen_set_pmd; | 2370 | pv_ops.mmu.set_pmd = xen_set_pmd; |
2363 | pv_mmu_ops.set_pud = xen_set_pud; | 2371 | pv_ops.mmu.set_pud = xen_set_pud; |
2364 | #ifdef CONFIG_X86_64 | 2372 | #ifdef CONFIG_X86_64 |
2365 | pv_mmu_ops.set_p4d = xen_set_p4d; | 2373 | pv_ops.mmu.set_p4d = xen_set_p4d; |
2366 | #endif | 2374 | #endif |
2367 | 2375 | ||
2368 | /* This will work as long as patching hasn't happened yet | 2376 | /* This will work as long as patching hasn't happened yet |
2369 | (which it hasn't) */ | 2377 | (which it hasn't) */ |
2370 | pv_mmu_ops.alloc_pte = xen_alloc_pte; | 2378 | pv_ops.mmu.alloc_pte = xen_alloc_pte; |
2371 | pv_mmu_ops.alloc_pmd = xen_alloc_pmd; | 2379 | pv_ops.mmu.alloc_pmd = xen_alloc_pmd; |
2372 | pv_mmu_ops.release_pte = xen_release_pte; | 2380 | pv_ops.mmu.release_pte = xen_release_pte; |
2373 | pv_mmu_ops.release_pmd = xen_release_pmd; | 2381 | pv_ops.mmu.release_pmd = xen_release_pmd; |
2374 | #ifdef CONFIG_X86_64 | 2382 | #ifdef CONFIG_X86_64 |
2375 | pv_mmu_ops.alloc_pud = xen_alloc_pud; | 2383 | pv_ops.mmu.alloc_pud = xen_alloc_pud; |
2376 | pv_mmu_ops.release_pud = xen_release_pud; | 2384 | pv_ops.mmu.release_pud = xen_release_pud; |
2377 | #endif | 2385 | #endif |
2378 | pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte); | 2386 | pv_ops.mmu.make_pte = PV_CALLEE_SAVE(xen_make_pte); |
2379 | 2387 | ||
2380 | #ifdef CONFIG_X86_64 | 2388 | #ifdef CONFIG_X86_64 |
2381 | pv_mmu_ops.write_cr3 = &xen_write_cr3; | 2389 | pv_ops.mmu.write_cr3 = &xen_write_cr3; |
2382 | #endif | 2390 | #endif |
2383 | } | 2391 | } |
2384 | 2392 | ||
@@ -2466,7 +2474,7 @@ void __init xen_init_mmu_ops(void) | |||
2466 | x86_init.paging.pagetable_init = xen_pagetable_init; | 2474 | x86_init.paging.pagetable_init = xen_pagetable_init; |
2467 | x86_init.hyper.init_after_bootmem = xen_after_bootmem; | 2475 | x86_init.hyper.init_after_bootmem = xen_after_bootmem; |
2468 | 2476 | ||
2469 | pv_mmu_ops = xen_mmu_ops; | 2477 | pv_ops.mmu = xen_mmu_ops; |
2470 | 2478 | ||
2471 | memset(dummy_mapping, 0xff, PAGE_SIZE); | 2479 | memset(dummy_mapping, 0xff, PAGE_SIZE); |
2472 | } | 2480 | } |
@@ -2666,6 +2674,138 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order) | |||
2666 | } | 2674 | } |
2667 | EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region); | 2675 | EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region); |
2668 | 2676 | ||
2677 | static noinline void xen_flush_tlb_all(void) | ||
2678 | { | ||
2679 | struct mmuext_op *op; | ||
2680 | struct multicall_space mcs; | ||
2681 | |||
2682 | preempt_disable(); | ||
2683 | |||
2684 | mcs = xen_mc_entry(sizeof(*op)); | ||
2685 | |||
2686 | op = mcs.args; | ||
2687 | op->cmd = MMUEXT_TLB_FLUSH_ALL; | ||
2688 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); | ||
2689 | |||
2690 | xen_mc_issue(PARAVIRT_LAZY_MMU); | ||
2691 | |||
2692 | preempt_enable(); | ||
2693 | } | ||
2694 | |||
2695 | #define REMAP_BATCH_SIZE 16 | ||
2696 | |||
2697 | struct remap_data { | ||
2698 | xen_pfn_t *pfn; | ||
2699 | bool contiguous; | ||
2700 | bool no_translate; | ||
2701 | pgprot_t prot; | ||
2702 | struct mmu_update *mmu_update; | ||
2703 | }; | ||
2704 | |||
2705 | static int remap_area_pfn_pte_fn(pte_t *ptep, pgtable_t token, | ||
2706 | unsigned long addr, void *data) | ||
2707 | { | ||
2708 | struct remap_data *rmd = data; | ||
2709 | pte_t pte = pte_mkspecial(mfn_pte(*rmd->pfn, rmd->prot)); | ||
2710 | |||
2711 | /* | ||
2712 | * If we have a contiguous range, just update the pfn itself, | ||
2713 | * else update pointer to be "next pfn". | ||
2714 | */ | ||
2715 | if (rmd->contiguous) | ||
2716 | (*rmd->pfn)++; | ||
2717 | else | ||
2718 | rmd->pfn++; | ||
2719 | |||
2720 | rmd->mmu_update->ptr = virt_to_machine(ptep).maddr; | ||
2721 | rmd->mmu_update->ptr |= rmd->no_translate ? | ||
2722 | MMU_PT_UPDATE_NO_TRANSLATE : | ||
2723 | MMU_NORMAL_PT_UPDATE; | ||
2724 | rmd->mmu_update->val = pte_val_ma(pte); | ||
2725 | rmd->mmu_update++; | ||
2726 | |||
2727 | return 0; | ||
2728 | } | ||
2729 | |||
2730 | int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr, | ||
2731 | xen_pfn_t *pfn, int nr, int *err_ptr, pgprot_t prot, | ||
2732 | unsigned int domid, bool no_translate, struct page **pages) | ||
2733 | { | ||
2734 | int err = 0; | ||
2735 | struct remap_data rmd; | ||
2736 | struct mmu_update mmu_update[REMAP_BATCH_SIZE]; | ||
2737 | unsigned long range; | ||
2738 | int mapped = 0; | ||
2739 | |||
2740 | BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO))); | ||
2741 | |||
2742 | rmd.pfn = pfn; | ||
2743 | rmd.prot = prot; | ||
2744 | /* | ||
2745 | * We use the err_ptr to indicate if there we are doing a contiguous | ||
2746 | * mapping or a discontigious mapping. | ||
2747 | */ | ||
2748 | rmd.contiguous = !err_ptr; | ||
2749 | rmd.no_translate = no_translate; | ||
2750 | |||
2751 | while (nr) { | ||
2752 | int index = 0; | ||
2753 | int done = 0; | ||
2754 | int batch = min(REMAP_BATCH_SIZE, nr); | ||
2755 | int batch_left = batch; | ||
2756 | |||
2757 | range = (unsigned long)batch << PAGE_SHIFT; | ||
2758 | |||
2759 | rmd.mmu_update = mmu_update; | ||
2760 | err = apply_to_page_range(vma->vm_mm, addr, range, | ||
2761 | remap_area_pfn_pte_fn, &rmd); | ||
2762 | if (err) | ||
2763 | goto out; | ||
2764 | |||
2765 | /* | ||
2766 | * We record the error for each page that gives an error, but | ||
2767 | * continue mapping until the whole set is done | ||
2768 | */ | ||
2769 | do { | ||
2770 | int i; | ||
2771 | |||
2772 | err = HYPERVISOR_mmu_update(&mmu_update[index], | ||
2773 | batch_left, &done, domid); | ||
2774 | |||
2775 | /* | ||
2776 | * @err_ptr may be the same buffer as @gfn, so | ||
2777 | * only clear it after each chunk of @gfn is | ||
2778 | * used. | ||
2779 | */ | ||
2780 | if (err_ptr) { | ||
2781 | for (i = index; i < index + done; i++) | ||
2782 | err_ptr[i] = 0; | ||
2783 | } | ||
2784 | if (err < 0) { | ||
2785 | if (!err_ptr) | ||
2786 | goto out; | ||
2787 | err_ptr[i] = err; | ||
2788 | done++; /* Skip failed frame. */ | ||
2789 | } else | ||
2790 | mapped += done; | ||
2791 | batch_left -= done; | ||
2792 | index += done; | ||
2793 | } while (batch_left); | ||
2794 | |||
2795 | nr -= batch; | ||
2796 | addr += range; | ||
2797 | if (err_ptr) | ||
2798 | err_ptr += batch; | ||
2799 | cond_resched(); | ||
2800 | } | ||
2801 | out: | ||
2802 | |||
2803 | xen_flush_tlb_all(); | ||
2804 | |||
2805 | return err < 0 ? err : mapped; | ||
2806 | } | ||
2807 | EXPORT_SYMBOL_GPL(xen_remap_pfn); | ||
2808 | |||
2669 | #ifdef CONFIG_KEXEC_CORE | 2809 | #ifdef CONFIG_KEXEC_CORE |
2670 | phys_addr_t paddr_vmcoreinfo_note(void) | 2810 | phys_addr_t paddr_vmcoreinfo_note(void) |
2671 | { | 2811 | { |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 159a897151d6..d6d74efd8912 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -1,3 +1,5 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
1 | /* | 3 | /* |
2 | * Xen leaves the responsibility for maintaining p2m mappings to the | 4 | * Xen leaves the responsibility for maintaining p2m mappings to the |
3 | * guests themselves, but it must also access and update the p2m array | 5 | * guests themselves, but it must also access and update the p2m array |
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index 37c6056a7bba..33293ce01d8d 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c | |||
@@ -1,3 +1,5 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
1 | /* Glue code to lib/swiotlb-xen.c */ | 3 | /* Glue code to lib/swiotlb-xen.c */ |
2 | 4 | ||
3 | #include <linux/dma-mapping.h> | 5 | #include <linux/dma-mapping.h> |
diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c index b99585034dd2..66ab96a4e2b3 100644 --- a/arch/x86/xen/platform-pci-unplug.c +++ b/arch/x86/xen/platform-pci-unplug.c | |||
@@ -1,22 +1,10 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
1 | /****************************************************************************** | 3 | /****************************************************************************** |
2 | * platform-pci-unplug.c | 4 | * platform-pci-unplug.c |
3 | * | 5 | * |
4 | * Xen platform PCI device driver | 6 | * Xen platform PCI device driver |
5 | * Copyright (c) 2010, Citrix | 7 | * Copyright (c) 2010, Citrix |
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
18 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
19 | * | ||
20 | */ | 8 | */ |
21 | 9 | ||
22 | #include <linux/init.h> | 10 | #include <linux/init.h> |
@@ -31,7 +19,6 @@ | |||
31 | #define XEN_PLATFORM_ERR_PROTOCOL -2 | 19 | #define XEN_PLATFORM_ERR_PROTOCOL -2 |
32 | #define XEN_PLATFORM_ERR_BLACKLIST -3 | 20 | #define XEN_PLATFORM_ERR_BLACKLIST -3 |
33 | 21 | ||
34 | #ifdef CONFIG_XEN_PVHVM | ||
35 | /* store the value of xen_emul_unplug after the unplug is done */ | 22 | /* store the value of xen_emul_unplug after the unplug is done */ |
36 | static int xen_platform_pci_unplug; | 23 | static int xen_platform_pci_unplug; |
37 | static int xen_emul_unplug; | 24 | static int xen_emul_unplug; |
@@ -215,4 +202,3 @@ static int __init parse_xen_emul_unplug(char *arg) | |||
215 | return 0; | 202 | return 0; |
216 | } | 203 | } |
217 | early_param("xen_emul_unplug", parse_xen_emul_unplug); | 204 | early_param("xen_emul_unplug", parse_xen_emul_unplug); |
218 | #endif | ||
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 973f10e05211..23f6793af88a 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
@@ -141,11 +141,12 @@ void __init xen_init_spinlocks(void) | |||
141 | printk(KERN_DEBUG "xen: PV spinlocks enabled\n"); | 141 | printk(KERN_DEBUG "xen: PV spinlocks enabled\n"); |
142 | 142 | ||
143 | __pv_init_lock_hash(); | 143 | __pv_init_lock_hash(); |
144 | pv_lock_ops.queued_spin_lock_slowpath = __pv_queued_spin_lock_slowpath; | 144 | pv_ops.lock.queued_spin_lock_slowpath = __pv_queued_spin_lock_slowpath; |
145 | pv_lock_ops.queued_spin_unlock = PV_CALLEE_SAVE(__pv_queued_spin_unlock); | 145 | pv_ops.lock.queued_spin_unlock = |
146 | pv_lock_ops.wait = xen_qlock_wait; | 146 | PV_CALLEE_SAVE(__pv_queued_spin_unlock); |
147 | pv_lock_ops.kick = xen_qlock_kick; | 147 | pv_ops.lock.wait = xen_qlock_wait; |
148 | pv_lock_ops.vcpu_is_preempted = PV_CALLEE_SAVE(xen_vcpu_stolen); | 148 | pv_ops.lock.kick = xen_qlock_kick; |
149 | pv_ops.lock.vcpu_is_preempted = PV_CALLEE_SAVE(xen_vcpu_stolen); | ||
149 | } | 150 | } |
150 | 151 | ||
151 | static __init int xen_parse_nopvspin(char *arg) | 152 | static __init int xen_parse_nopvspin(char *arg) |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index c84f1e039d84..72bf446c3fee 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -513,7 +513,7 @@ static void __init xen_time_init(void) | |||
513 | void __init xen_init_time_ops(void) | 513 | void __init xen_init_time_ops(void) |
514 | { | 514 | { |
515 | xen_sched_clock_offset = xen_clocksource_read(); | 515 | xen_sched_clock_offset = xen_clocksource_read(); |
516 | pv_time_ops = xen_time_ops; | 516 | pv_ops.time = xen_time_ops; |
517 | 517 | ||
518 | x86_init.timers.timer_init = xen_time_init; | 518 | x86_init.timers.timer_init = xen_time_init; |
519 | x86_init.timers.setup_percpu_clockev = x86_init_noop; | 519 | x86_init.timers.setup_percpu_clockev = x86_init_noop; |
@@ -555,7 +555,7 @@ void __init xen_hvm_init_time_ops(void) | |||
555 | } | 555 | } |
556 | 556 | ||
557 | xen_sched_clock_offset = xen_clocksource_read(); | 557 | xen_sched_clock_offset = xen_clocksource_read(); |
558 | pv_time_ops = xen_time_ops; | 558 | pv_ops.time = xen_time_ops; |
559 | x86_init.timers.setup_percpu_clockev = xen_time_init; | 559 | x86_init.timers.setup_percpu_clockev = xen_time_init; |
560 | x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents; | 560 | x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents; |
561 | 561 | ||
diff --git a/arch/x86/xen/vdso.h b/arch/x86/xen/vdso.h index 861fedfe5230..873c54c488fe 100644 --- a/arch/x86/xen/vdso.h +++ b/arch/x86/xen/vdso.h | |||
@@ -1,3 +1,5 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | |||
1 | /* Bit used for the pseudo-hwcap for non-negative segments. We use | 3 | /* Bit used for the pseudo-hwcap for non-negative segments. We use |
2 | bit 1 to avoid bugs in some versions of glibc when bit 0 is | 4 | bit 1 to avoid bugs in some versions of glibc when bit 0 is |
3 | used; the choice is otherwise arbitrary. */ | 5 | used; the choice is otherwise arbitrary. */ |
diff --git a/arch/x86/xen/xen-pvh.S b/arch/x86/xen/xen-pvh.S index ca2d3b2bf2af..b0e471506cd8 100644 --- a/arch/x86/xen/xen-pvh.S +++ b/arch/x86/xen/xen-pvh.S | |||
@@ -1,18 +1,7 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | |||
1 | /* | 3 | /* |
2 | * Copyright C 2016, Oracle and/or its affiliates. All rights reserved. | 4 | * Copyright C 2016, Oracle and/or its affiliates. All rights reserved. |
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | 5 | */ |
17 | 6 | ||
18 | .code32 | 7 | .code32 |
diff --git a/drivers/xen/time.c b/drivers/xen/time.c index 3e741cd1409c..0968859c29d0 100644 --- a/drivers/xen/time.c +++ b/drivers/xen/time.c | |||
@@ -175,7 +175,7 @@ void __init xen_time_setup_guest(void) | |||
175 | xen_runstate_remote = !HYPERVISOR_vm_assist(VMASST_CMD_enable, | 175 | xen_runstate_remote = !HYPERVISOR_vm_assist(VMASST_CMD_enable, |
176 | VMASST_TYPE_runstate_update_flag); | 176 | VMASST_TYPE_runstate_update_flag); |
177 | 177 | ||
178 | pv_time_ops.steal_clock = xen_steal_clock; | 178 | pv_ops.time.steal_clock = xen_steal_clock; |
179 | 179 | ||
180 | static_key_slow_inc(¶virt_steal_enabled); | 180 | static_key_slow_inc(¶virt_steal_enabled); |
181 | if (xen_runstate_remote) | 181 | if (xen_runstate_remote) |
diff --git a/include/xen/events.h b/include/xen/events.h index c3e6bc643a7b..a48897199975 100644 --- a/include/xen/events.h +++ b/include/xen/events.h | |||
@@ -89,11 +89,13 @@ unsigned irq_from_evtchn(unsigned int evtchn); | |||
89 | int irq_from_virq(unsigned int cpu, unsigned int virq); | 89 | int irq_from_virq(unsigned int cpu, unsigned int virq); |
90 | unsigned int evtchn_from_irq(unsigned irq); | 90 | unsigned int evtchn_from_irq(unsigned irq); |
91 | 91 | ||
92 | #ifdef CONFIG_XEN_PVHVM | ||
92 | /* Xen HVM evtchn vector callback */ | 93 | /* Xen HVM evtchn vector callback */ |
93 | void xen_hvm_callback_vector(void); | 94 | void xen_hvm_callback_vector(void); |
94 | #ifdef CONFIG_TRACING | 95 | #ifdef CONFIG_TRACING |
95 | #define trace_xen_hvm_callback_vector xen_hvm_callback_vector | 96 | #define trace_xen_hvm_callback_vector xen_hvm_callback_vector |
96 | #endif | 97 | #endif |
98 | #endif | ||
97 | int xen_set_callback_via(uint64_t via); | 99 | int xen_set_callback_via(uint64_t via); |
98 | void xen_evtchn_do_upcall(struct pt_regs *regs); | 100 | void xen_evtchn_do_upcall(struct pt_regs *regs); |
99 | void xen_hvm_evtchn_do_upcall(void); | 101 | void xen_hvm_evtchn_do_upcall(void); |
diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h index 4c5751c26f87..447004861f00 100644 --- a/include/xen/interface/memory.h +++ b/include/xen/interface/memory.h | |||
@@ -245,12 +245,6 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_memory_map); | |||
245 | 245 | ||
246 | 246 | ||
247 | /* | 247 | /* |
248 | * Prevent the balloon driver from changing the memory reservation | ||
249 | * during a driver critical region. | ||
250 | */ | ||
251 | extern spinlock_t xen_reservation_lock; | ||
252 | |||
253 | /* | ||
254 | * Unmaps the page appearing at a particular GPFN from the specified guest's | 248 | * Unmaps the page appearing at a particular GPFN from the specified guest's |
255 | * pseudophysical address space. | 249 | * pseudophysical address space. |
256 | * arg == addr of xen_remove_from_physmap_t. | 250 | * arg == addr of xen_remove_from_physmap_t. |
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index fd18c974a619..18803ff76e27 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/percpu.h> | 5 | #include <linux/percpu.h> |
6 | #include <linux/notifier.h> | 6 | #include <linux/notifier.h> |
7 | #include <linux/efi.h> | 7 | #include <linux/efi.h> |
8 | #include <xen/features.h> | ||
8 | #include <asm/xen/interface.h> | 9 | #include <asm/xen/interface.h> |
9 | #include <xen/interface/vcpu.h> | 10 | #include <xen/interface/vcpu.h> |
10 | 11 | ||
@@ -47,6 +48,10 @@ int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order, | |||
47 | dma_addr_t *dma_handle); | 48 | dma_addr_t *dma_handle); |
48 | 49 | ||
49 | void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order); | 50 | void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order); |
51 | |||
52 | int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr, | ||
53 | xen_pfn_t *pfn, int nr, int *err_ptr, pgprot_t prot, | ||
54 | unsigned int domid, bool no_translate, struct page **pages); | ||
50 | #else | 55 | #else |
51 | static inline int xen_create_contiguous_region(phys_addr_t pstart, | 56 | static inline int xen_create_contiguous_region(phys_addr_t pstart, |
52 | unsigned int order, | 57 | unsigned int order, |
@@ -58,10 +63,50 @@ static inline int xen_create_contiguous_region(phys_addr_t pstart, | |||
58 | 63 | ||
59 | static inline void xen_destroy_contiguous_region(phys_addr_t pstart, | 64 | static inline void xen_destroy_contiguous_region(phys_addr_t pstart, |
60 | unsigned int order) { } | 65 | unsigned int order) { } |
66 | |||
67 | static inline int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr, | ||
68 | xen_pfn_t *pfn, int nr, int *err_ptr, | ||
69 | pgprot_t prot, unsigned int domid, | ||
70 | bool no_translate, struct page **pages) | ||
71 | { | ||
72 | BUG(); | ||
73 | return 0; | ||
74 | } | ||
61 | #endif | 75 | #endif |
62 | 76 | ||
63 | struct vm_area_struct; | 77 | struct vm_area_struct; |
64 | 78 | ||
79 | #ifdef CONFIG_XEN_AUTO_XLATE | ||
80 | int xen_xlate_remap_gfn_array(struct vm_area_struct *vma, | ||
81 | unsigned long addr, | ||
82 | xen_pfn_t *gfn, int nr, | ||
83 | int *err_ptr, pgprot_t prot, | ||
84 | unsigned int domid, | ||
85 | struct page **pages); | ||
86 | int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma, | ||
87 | int nr, struct page **pages); | ||
88 | #else | ||
89 | /* | ||
90 | * These two functions are called from arch/x86/xen/mmu.c and so stubs | ||
91 | * are needed for a configuration not specifying CONFIG_XEN_AUTO_XLATE. | ||
92 | */ | ||
93 | static inline int xen_xlate_remap_gfn_array(struct vm_area_struct *vma, | ||
94 | unsigned long addr, | ||
95 | xen_pfn_t *gfn, int nr, | ||
96 | int *err_ptr, pgprot_t prot, | ||
97 | unsigned int domid, | ||
98 | struct page **pages) | ||
99 | { | ||
100 | return -EOPNOTSUPP; | ||
101 | } | ||
102 | |||
103 | static inline int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma, | ||
104 | int nr, struct page **pages) | ||
105 | { | ||
106 | return -EOPNOTSUPP; | ||
107 | } | ||
108 | #endif | ||
109 | |||
65 | /* | 110 | /* |
66 | * xen_remap_domain_gfn_array() - map an array of foreign frames by gfn | 111 | * xen_remap_domain_gfn_array() - map an array of foreign frames by gfn |
67 | * @vma: VMA to map the pages into | 112 | * @vma: VMA to map the pages into |
@@ -79,12 +124,25 @@ struct vm_area_struct; | |||
79 | * Returns the number of successfully mapped frames, or a -ve error | 124 | * Returns the number of successfully mapped frames, or a -ve error |
80 | * code. | 125 | * code. |
81 | */ | 126 | */ |
82 | int xen_remap_domain_gfn_array(struct vm_area_struct *vma, | 127 | static inline int xen_remap_domain_gfn_array(struct vm_area_struct *vma, |
83 | unsigned long addr, | 128 | unsigned long addr, |
84 | xen_pfn_t *gfn, int nr, | 129 | xen_pfn_t *gfn, int nr, |
85 | int *err_ptr, pgprot_t prot, | 130 | int *err_ptr, pgprot_t prot, |
86 | unsigned domid, | 131 | unsigned int domid, |
87 | struct page **pages); | 132 | struct page **pages) |
133 | { | ||
134 | if (xen_feature(XENFEAT_auto_translated_physmap)) | ||
135 | return xen_xlate_remap_gfn_array(vma, addr, gfn, nr, err_ptr, | ||
136 | prot, domid, pages); | ||
137 | |||
138 | /* We BUG_ON because it's a programmer error to pass a NULL err_ptr, | ||
139 | * and the consequences later is quite hard to detect what the actual | ||
140 | * cause of "wrong memory was mapped in". | ||
141 | */ | ||
142 | BUG_ON(err_ptr == NULL); | ||
143 | return xen_remap_pfn(vma, addr, gfn, nr, err_ptr, prot, domid, | ||
144 | false, pages); | ||
145 | } | ||
88 | 146 | ||
89 | /* | 147 | /* |
90 | * xen_remap_domain_mfn_array() - map an array of foreign frames by mfn | 148 | * xen_remap_domain_mfn_array() - map an array of foreign frames by mfn |
@@ -103,10 +161,18 @@ int xen_remap_domain_gfn_array(struct vm_area_struct *vma, | |||
103 | * Returns the number of successfully mapped frames, or a -ve error | 161 | * Returns the number of successfully mapped frames, or a -ve error |
104 | * code. | 162 | * code. |
105 | */ | 163 | */ |
106 | int xen_remap_domain_mfn_array(struct vm_area_struct *vma, | 164 | static inline int xen_remap_domain_mfn_array(struct vm_area_struct *vma, |
107 | unsigned long addr, xen_pfn_t *mfn, int nr, | 165 | unsigned long addr, xen_pfn_t *mfn, |
108 | int *err_ptr, pgprot_t prot, | 166 | int nr, int *err_ptr, |
109 | unsigned int domid, struct page **pages); | 167 | pgprot_t prot, unsigned int domid, |
168 | struct page **pages) | ||
169 | { | ||
170 | if (xen_feature(XENFEAT_auto_translated_physmap)) | ||
171 | return -EOPNOTSUPP; | ||
172 | |||
173 | return xen_remap_pfn(vma, addr, mfn, nr, err_ptr, prot, domid, | ||
174 | true, pages); | ||
175 | } | ||
110 | 176 | ||
111 | /* xen_remap_domain_gfn_range() - map a range of foreign frames | 177 | /* xen_remap_domain_gfn_range() - map a range of foreign frames |
112 | * @vma: VMA to map the pages into | 178 | * @vma: VMA to map the pages into |
@@ -120,44 +186,21 @@ int xen_remap_domain_mfn_array(struct vm_area_struct *vma, | |||
120 | * Returns the number of successfully mapped frames, or a -ve error | 186 | * Returns the number of successfully mapped frames, or a -ve error |
121 | * code. | 187 | * code. |
122 | */ | 188 | */ |
123 | int xen_remap_domain_gfn_range(struct vm_area_struct *vma, | 189 | static inline int xen_remap_domain_gfn_range(struct vm_area_struct *vma, |
124 | unsigned long addr, | 190 | unsigned long addr, |
125 | xen_pfn_t gfn, int nr, | 191 | xen_pfn_t gfn, int nr, |
126 | pgprot_t prot, unsigned domid, | 192 | pgprot_t prot, unsigned int domid, |
127 | struct page **pages); | 193 | struct page **pages) |
128 | int xen_unmap_domain_gfn_range(struct vm_area_struct *vma, | ||
129 | int numpgs, struct page **pages); | ||
130 | |||
131 | #ifdef CONFIG_XEN_AUTO_XLATE | ||
132 | int xen_xlate_remap_gfn_array(struct vm_area_struct *vma, | ||
133 | unsigned long addr, | ||
134 | xen_pfn_t *gfn, int nr, | ||
135 | int *err_ptr, pgprot_t prot, | ||
136 | unsigned domid, | ||
137 | struct page **pages); | ||
138 | int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma, | ||
139 | int nr, struct page **pages); | ||
140 | #else | ||
141 | /* | ||
142 | * These two functions are called from arch/x86/xen/mmu.c and so stubs | ||
143 | * are needed for a configuration not specifying CONFIG_XEN_AUTO_XLATE. | ||
144 | */ | ||
145 | static inline int xen_xlate_remap_gfn_array(struct vm_area_struct *vma, | ||
146 | unsigned long addr, | ||
147 | xen_pfn_t *gfn, int nr, | ||
148 | int *err_ptr, pgprot_t prot, | ||
149 | unsigned int domid, | ||
150 | struct page **pages) | ||
151 | { | 194 | { |
152 | return -EOPNOTSUPP; | 195 | if (xen_feature(XENFEAT_auto_translated_physmap)) |
153 | } | 196 | return -EOPNOTSUPP; |
154 | 197 | ||
155 | static inline int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma, | 198 | return xen_remap_pfn(vma, addr, &gfn, nr, NULL, prot, domid, false, |
156 | int nr, struct page **pages) | 199 | pages); |
157 | { | ||
158 | return -EOPNOTSUPP; | ||
159 | } | 200 | } |
160 | #endif | 201 | |
202 | int xen_unmap_domain_gfn_range(struct vm_area_struct *vma, | ||
203 | int numpgs, struct page **pages); | ||
161 | 204 | ||
162 | int xen_xlate_map_ballooned_pages(xen_pfn_t **pfns, void **vaddr, | 205 | int xen_xlate_map_ballooned_pages(xen_pfn_t **pfns, void **vaddr, |
163 | unsigned long nr_grant_frames); | 206 | unsigned long nr_grant_frames); |