diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-12 16:05:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-12 16:05:36 -0500 |
commit | c9bed1cf51011c815d88288b774865d013ca78a8 (patch) | |
tree | 77e205b9442338a3d11567d4abcdb8df616979cf | |
parent | 75777c1855e10c010c9c3a21611d95dd9be01ab1 (diff) | |
parent | a4cdb556cae05cd3e7b602b3a44c01420c4e2258 (diff) |
Merge tag 'for-linus-4.5-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from David Vrabel:
"Xen features and fixes for 4.5-rc0:
- Stolen ticks and PV wallclock support for arm/arm64
- Add grant copy ioctl to gntdev device"
* tag 'for-linus-4.5-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
xen/gntdev: add ioctl for grant copy
x86/xen: don't reset vcpu_info on a cancelled suspend
xen/gntdev: constify mmu_notifier_ops structures
xen/grant-table: constify gnttab_ops structure
xen/time: use READ_ONCE
xen/x86: convert remaining timespec to timespec64 in xen_pvclock_gtod_notify
xen/x86: support XENPF_settime64
xen/arm: set the system time in Xen via the XENPF_settime64 hypercall
xen/arm: introduce xen_read_wallclock
arm: extend pvclock_wall_clock with sec_hi
xen: introduce XENPF_settime64
xen/arm: introduce HYPERVISOR_platform_op on arm and arm64
xen: rename dom0_op to platform_op
xen/arm: account for stolen ticks
arm64: introduce CONFIG_PARAVIRT, PARAVIRT_TIME_ACCOUNTING and pv_time_ops
arm: introduce CONFIG_PARAVIRT, PARAVIRT_TIME_ACCOUNTING and pv_time_ops
missing include asm/paravirt.h in cputime.c
xen: move xen_setup_runstate_info and get_runstate_snapshot to drivers/xen/time.c
34 files changed, 677 insertions, 131 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b0e7ff176028..426115f7cb63 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1824,6 +1824,25 @@ config SWIOTLB | |||
1824 | config IOMMU_HELPER | 1824 | config IOMMU_HELPER |
1825 | def_bool SWIOTLB | 1825 | def_bool SWIOTLB |
1826 | 1826 | ||
1827 | config PARAVIRT | ||
1828 | bool "Enable paravirtualization code" | ||
1829 | help | ||
1830 | This changes the kernel so it can modify itself when it is run | ||
1831 | under a hypervisor, potentially improving performance significantly | ||
1832 | over full virtualization. | ||
1833 | |||
1834 | config PARAVIRT_TIME_ACCOUNTING | ||
1835 | bool "Paravirtual steal time accounting" | ||
1836 | select PARAVIRT | ||
1837 | default n | ||
1838 | help | ||
1839 | Select this option to enable fine granularity task steal time | ||
1840 | accounting. Time spent executing other tasks in parallel with | ||
1841 | the current vCPU is discounted from the vCPU power. To account for | ||
1842 | that, there can be a small performance impact. | ||
1843 | |||
1844 | If in doubt, say N here. | ||
1845 | |||
1827 | config XEN_DOM0 | 1846 | config XEN_DOM0 |
1828 | def_bool y | 1847 | def_bool y |
1829 | depends on XEN | 1848 | depends on XEN |
@@ -1837,6 +1856,7 @@ config XEN | |||
1837 | select ARCH_DMA_ADDR_T_64BIT | 1856 | select ARCH_DMA_ADDR_T_64BIT |
1838 | select ARM_PSCI | 1857 | select ARM_PSCI |
1839 | select SWIOTLB_XEN | 1858 | select SWIOTLB_XEN |
1859 | select PARAVIRT | ||
1840 | help | 1860 | help |
1841 | Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. | 1861 | Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. |
1842 | 1862 | ||
diff --git a/arch/arm/include/asm/paravirt.h b/arch/arm/include/asm/paravirt.h new file mode 100644 index 000000000000..8435ff591386 --- /dev/null +++ b/arch/arm/include/asm/paravirt.h | |||
@@ -0,0 +1,20 @@ | |||
1 | #ifndef _ASM_ARM_PARAVIRT_H | ||
2 | #define _ASM_ARM_PARAVIRT_H | ||
3 | |||
4 | #ifdef CONFIG_PARAVIRT | ||
5 | struct static_key; | ||
6 | extern struct static_key paravirt_steal_enabled; | ||
7 | extern struct static_key paravirt_steal_rq_enabled; | ||
8 | |||
9 | struct pv_time_ops { | ||
10 | unsigned long long (*steal_clock)(int cpu); | ||
11 | }; | ||
12 | extern struct pv_time_ops pv_time_ops; | ||
13 | |||
14 | static inline u64 paravirt_steal_clock(int cpu) | ||
15 | { | ||
16 | return pv_time_ops.steal_clock(cpu); | ||
17 | } | ||
18 | #endif | ||
19 | |||
20 | #endif | ||
diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h index 712b50e0a6dc..d769972db8cb 100644 --- a/arch/arm/include/asm/xen/hypercall.h +++ b/arch/arm/include/asm/xen/hypercall.h | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include <xen/interface/xen.h> | 36 | #include <xen/interface/xen.h> |
37 | #include <xen/interface/sched.h> | 37 | #include <xen/interface/sched.h> |
38 | #include <xen/interface/platform.h> | ||
38 | 39 | ||
39 | long privcmd_call(unsigned call, unsigned long a1, | 40 | long privcmd_call(unsigned call, unsigned long a1, |
40 | unsigned long a2, unsigned long a3, | 41 | unsigned long a2, unsigned long a3, |
@@ -49,6 +50,12 @@ int HYPERVISOR_memory_op(unsigned int cmd, void *arg); | |||
49 | int HYPERVISOR_physdev_op(int cmd, void *arg); | 50 | int HYPERVISOR_physdev_op(int cmd, void *arg); |
50 | int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args); | 51 | int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args); |
51 | int HYPERVISOR_tmem_op(void *arg); | 52 | int HYPERVISOR_tmem_op(void *arg); |
53 | int HYPERVISOR_platform_op_raw(void *arg); | ||
54 | static inline int HYPERVISOR_platform_op(struct xen_platform_op *op) | ||
55 | { | ||
56 | op->interface_version = XENPF_INTERFACE_VERSION; | ||
57 | return HYPERVISOR_platform_op_raw(op); | ||
58 | } | ||
52 | int HYPERVISOR_multicall(struct multicall_entry *calls, uint32_t nr); | 59 | int HYPERVISOR_multicall(struct multicall_entry *calls, uint32_t nr); |
53 | 60 | ||
54 | static inline int | 61 | static inline int |
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h index 50066006e6bd..75d596862892 100644 --- a/arch/arm/include/asm/xen/interface.h +++ b/arch/arm/include/asm/xen/interface.h | |||
@@ -27,6 +27,8 @@ | |||
27 | (hnd).p = val; \ | 27 | (hnd).p = val; \ |
28 | } while (0) | 28 | } while (0) |
29 | 29 | ||
30 | #define __HYPERVISOR_platform_op_raw __HYPERVISOR_platform_op | ||
31 | |||
30 | #ifndef __ASSEMBLY__ | 32 | #ifndef __ASSEMBLY__ |
31 | /* Explicitly size integers that represent pfns in the interface with | 33 | /* Explicitly size integers that represent pfns in the interface with |
32 | * Xen so that we can have one ABI that works for 32 and 64 bit guests. | 34 | * Xen so that we can have one ABI that works for 32 and 64 bit guests. |
@@ -76,6 +78,7 @@ struct pvclock_wall_clock { | |||
76 | u32 version; | 78 | u32 version; |
77 | u32 sec; | 79 | u32 sec; |
78 | u32 nsec; | 80 | u32 nsec; |
81 | u32 sec_hi; | ||
79 | } __attribute__((__packed__)); | 82 | } __attribute__((__packed__)); |
80 | #endif | 83 | #endif |
81 | 84 | ||
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index f729085ece28..2c5f160be65e 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -81,6 +81,7 @@ obj-$(CONFIG_EFI) += efi.o | |||
81 | ifneq ($(CONFIG_ARCH_EBSA110),y) | 81 | ifneq ($(CONFIG_ARCH_EBSA110),y) |
82 | obj-y += io.o | 82 | obj-y += io.o |
83 | endif | 83 | endif |
84 | obj-$(CONFIG_PARAVIRT) += paravirt.o | ||
84 | 85 | ||
85 | head-y := head$(MMUEXT).o | 86 | head-y := head$(MMUEXT).o |
86 | obj-$(CONFIG_DEBUG_LL) += debug.o | 87 | obj-$(CONFIG_DEBUG_LL) += debug.o |
diff --git a/arch/arm/kernel/paravirt.c b/arch/arm/kernel/paravirt.c new file mode 100644 index 000000000000..53f371ed4568 --- /dev/null +++ b/arch/arm/kernel/paravirt.c | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * Copyright (C) 2013 Citrix Systems | ||
12 | * | ||
13 | * Author: Stefano Stabellini <stefano.stabellini@eu.citrix.com> | ||
14 | */ | ||
15 | |||
16 | #include <linux/export.h> | ||
17 | #include <linux/jump_label.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <asm/paravirt.h> | ||
20 | |||
21 | struct static_key paravirt_steal_enabled; | ||
22 | struct static_key paravirt_steal_rq_enabled; | ||
23 | |||
24 | struct pv_time_ops pv_time_ops; | ||
25 | EXPORT_SYMBOL_GPL(pv_time_ops); | ||
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index fc7ea529f462..75cd7345c654 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <xen/page.h> | 12 | #include <xen/page.h> |
13 | #include <xen/interface/sched.h> | 13 | #include <xen/interface/sched.h> |
14 | #include <xen/xen-ops.h> | 14 | #include <xen/xen-ops.h> |
15 | #include <asm/paravirt.h> | ||
15 | #include <asm/xen/hypervisor.h> | 16 | #include <asm/xen/hypervisor.h> |
16 | #include <asm/xen/hypercall.h> | 17 | #include <asm/xen/hypercall.h> |
17 | #include <asm/system_misc.h> | 18 | #include <asm/system_misc.h> |
@@ -25,6 +26,10 @@ | |||
25 | #include <linux/cpufreq.h> | 26 | #include <linux/cpufreq.h> |
26 | #include <linux/cpu.h> | 27 | #include <linux/cpu.h> |
27 | #include <linux/console.h> | 28 | #include <linux/console.h> |
29 | #include <linux/pvclock_gtod.h> | ||
30 | #include <linux/time64.h> | ||
31 | #include <linux/timekeeping.h> | ||
32 | #include <linux/timekeeper_internal.h> | ||
28 | 33 | ||
29 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
30 | 35 | ||
@@ -79,6 +84,83 @@ int xen_unmap_domain_gfn_range(struct vm_area_struct *vma, | |||
79 | } | 84 | } |
80 | EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range); | 85 | EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range); |
81 | 86 | ||
87 | static unsigned long long xen_stolen_accounting(int cpu) | ||
88 | { | ||
89 | struct vcpu_runstate_info state; | ||
90 | |||
91 | BUG_ON(cpu != smp_processor_id()); | ||
92 | |||
93 | xen_get_runstate_snapshot(&state); | ||
94 | |||
95 | WARN_ON(state.state != RUNSTATE_running); | ||
96 | |||
97 | return state.time[RUNSTATE_runnable] + state.time[RUNSTATE_offline]; | ||
98 | } | ||
99 | |||
100 | static void xen_read_wallclock(struct timespec64 *ts) | ||
101 | { | ||
102 | u32 version; | ||
103 | struct timespec64 now, ts_monotonic; | ||
104 | struct shared_info *s = HYPERVISOR_shared_info; | ||
105 | struct pvclock_wall_clock *wall_clock = &(s->wc); | ||
106 | |||
107 | /* get wallclock at system boot */ | ||
108 | do { | ||
109 | version = wall_clock->version; | ||
110 | rmb(); /* fetch version before time */ | ||
111 | now.tv_sec = ((uint64_t)wall_clock->sec_hi << 32) | wall_clock->sec; | ||
112 | now.tv_nsec = wall_clock->nsec; | ||
113 | rmb(); /* fetch time before checking version */ | ||
114 | } while ((wall_clock->version & 1) || (version != wall_clock->version)); | ||
115 | |||
116 | /* time since system boot */ | ||
117 | ktime_get_ts64(&ts_monotonic); | ||
118 | *ts = timespec64_add(now, ts_monotonic); | ||
119 | } | ||
120 | |||
121 | static int xen_pvclock_gtod_notify(struct notifier_block *nb, | ||
122 | unsigned long was_set, void *priv) | ||
123 | { | ||
124 | /* Protected by the calling core code serialization */ | ||
125 | static struct timespec64 next_sync; | ||
126 | |||
127 | struct xen_platform_op op; | ||
128 | struct timespec64 now, system_time; | ||
129 | struct timekeeper *tk = priv; | ||
130 | |||
131 | now.tv_sec = tk->xtime_sec; | ||
132 | now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); | ||
133 | system_time = timespec64_add(now, tk->wall_to_monotonic); | ||
134 | |||
135 | /* | ||
136 | * We only take the expensive HV call when the clock was set | ||
137 | * or when the 11 minutes RTC synchronization time elapsed. | ||
138 | */ | ||
139 | if (!was_set && timespec64_compare(&now, &next_sync) < 0) | ||
140 | return NOTIFY_OK; | ||
141 | |||
142 | op.cmd = XENPF_settime64; | ||
143 | op.u.settime64.mbz = 0; | ||
144 | op.u.settime64.secs = now.tv_sec; | ||
145 | op.u.settime64.nsecs = now.tv_nsec; | ||
146 | op.u.settime64.system_time = timespec64_to_ns(&system_time); | ||
147 | (void)HYPERVISOR_platform_op(&op); | ||
148 | |||
149 | /* | ||
150 | * Move the next drift compensation time 11 minutes | ||
151 | * ahead. That's emulating the sync_cmos_clock() update for | ||
152 | * the hardware RTC. | ||
153 | */ | ||
154 | next_sync = now; | ||
155 | next_sync.tv_sec += 11 * 60; | ||
156 | |||
157 | return NOTIFY_OK; | ||
158 | } | ||
159 | |||
160 | static struct notifier_block xen_pvclock_gtod_notifier = { | ||
161 | .notifier_call = xen_pvclock_gtod_notify, | ||
162 | }; | ||
163 | |||
82 | static void xen_percpu_init(void) | 164 | static void xen_percpu_init(void) |
83 | { | 165 | { |
84 | struct vcpu_register_vcpu_info info; | 166 | struct vcpu_register_vcpu_info info; |
@@ -104,6 +186,8 @@ static void xen_percpu_init(void) | |||
104 | BUG_ON(err); | 186 | BUG_ON(err); |
105 | per_cpu(xen_vcpu, cpu) = vcpup; | 187 | per_cpu(xen_vcpu, cpu) = vcpup; |
106 | 188 | ||
189 | xen_setup_runstate_info(cpu); | ||
190 | |||
107 | after_register_vcpu_info: | 191 | after_register_vcpu_info: |
108 | enable_percpu_irq(xen_events_irq, 0); | 192 | enable_percpu_irq(xen_events_irq, 0); |
109 | put_cpu(); | 193 | put_cpu(); |
@@ -271,6 +355,11 @@ static int __init xen_guest_init(void) | |||
271 | 355 | ||
272 | register_cpu_notifier(&xen_cpu_notifier); | 356 | register_cpu_notifier(&xen_cpu_notifier); |
273 | 357 | ||
358 | pv_time_ops.steal_clock = xen_stolen_accounting; | ||
359 | static_key_slow_inc(¶virt_steal_enabled); | ||
360 | if (xen_initial_domain()) | ||
361 | pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier); | ||
362 | |||
274 | return 0; | 363 | return 0; |
275 | } | 364 | } |
276 | early_initcall(xen_guest_init); | 365 | early_initcall(xen_guest_init); |
@@ -282,6 +371,11 @@ static int __init xen_pm_init(void) | |||
282 | 371 | ||
283 | pm_power_off = xen_power_off; | 372 | pm_power_off = xen_power_off; |
284 | arm_pm_restart = xen_restart; | 373 | arm_pm_restart = xen_restart; |
374 | if (!xen_initial_domain()) { | ||
375 | struct timespec64 ts; | ||
376 | xen_read_wallclock(&ts); | ||
377 | do_settimeofday64(&ts); | ||
378 | } | ||
285 | 379 | ||
286 | return 0; | 380 | return 0; |
287 | } | 381 | } |
@@ -307,5 +401,6 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op); | |||
307 | EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); | 401 | EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); |
308 | EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op); | 402 | EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op); |
309 | EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op); | 403 | EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op); |
404 | EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op); | ||
310 | EXPORT_SYMBOL_GPL(HYPERVISOR_multicall); | 405 | EXPORT_SYMBOL_GPL(HYPERVISOR_multicall); |
311 | EXPORT_SYMBOL_GPL(privcmd_call); | 406 | EXPORT_SYMBOL_GPL(privcmd_call); |
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S index 10fd99c568c6..9a36f4f49c10 100644 --- a/arch/arm/xen/hypercall.S +++ b/arch/arm/xen/hypercall.S | |||
@@ -89,6 +89,7 @@ HYPERCALL2(memory_op); | |||
89 | HYPERCALL2(physdev_op); | 89 | HYPERCALL2(physdev_op); |
90 | HYPERCALL3(vcpu_op); | 90 | HYPERCALL3(vcpu_op); |
91 | HYPERCALL1(tmem_op); | 91 | HYPERCALL1(tmem_op); |
92 | HYPERCALL1(platform_op_raw); | ||
92 | HYPERCALL2(multicall); | 93 | HYPERCALL2(multicall); |
93 | 94 | ||
94 | ENTRY(privcmd_call) | 95 | ENTRY(privcmd_call) |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index bf82ffe895bf..d6ebffdc6bb1 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -555,6 +555,25 @@ config SECCOMP | |||
555 | and the task is only allowed to execute a few safe syscalls | 555 | and the task is only allowed to execute a few safe syscalls |
556 | defined by each seccomp mode. | 556 | defined by each seccomp mode. |
557 | 557 | ||
558 | config PARAVIRT | ||
559 | bool "Enable paravirtualization code" | ||
560 | help | ||
561 | This changes the kernel so it can modify itself when it is run | ||
562 | under a hypervisor, potentially improving performance significantly | ||
563 | over full virtualization. | ||
564 | |||
565 | config PARAVIRT_TIME_ACCOUNTING | ||
566 | bool "Paravirtual steal time accounting" | ||
567 | select PARAVIRT | ||
568 | default n | ||
569 | help | ||
570 | Select this option to enable fine granularity task steal time | ||
571 | accounting. Time spent executing other tasks in parallel with | ||
572 | the current vCPU is discounted from the vCPU power. To account for | ||
573 | that, there can be a small performance impact. | ||
574 | |||
575 | If in doubt, say N here. | ||
576 | |||
558 | config XEN_DOM0 | 577 | config XEN_DOM0 |
559 | def_bool y | 578 | def_bool y |
560 | depends on XEN | 579 | depends on XEN |
@@ -563,6 +582,7 @@ config XEN | |||
563 | bool "Xen guest support on ARM64" | 582 | bool "Xen guest support on ARM64" |
564 | depends on ARM64 && OF | 583 | depends on ARM64 && OF |
565 | select SWIOTLB_XEN | 584 | select SWIOTLB_XEN |
585 | select PARAVIRT | ||
566 | help | 586 | help |
567 | Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64. | 587 | Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64. |
568 | 588 | ||
diff --git a/arch/arm64/include/asm/paravirt.h b/arch/arm64/include/asm/paravirt.h new file mode 100644 index 000000000000..fd5f42886251 --- /dev/null +++ b/arch/arm64/include/asm/paravirt.h | |||
@@ -0,0 +1,20 @@ | |||
1 | #ifndef _ASM_ARM64_PARAVIRT_H | ||
2 | #define _ASM_ARM64_PARAVIRT_H | ||
3 | |||
4 | #ifdef CONFIG_PARAVIRT | ||
5 | struct static_key; | ||
6 | extern struct static_key paravirt_steal_enabled; | ||
7 | extern struct static_key paravirt_steal_rq_enabled; | ||
8 | |||
9 | struct pv_time_ops { | ||
10 | unsigned long long (*steal_clock)(int cpu); | ||
11 | }; | ||
12 | extern struct pv_time_ops pv_time_ops; | ||
13 | |||
14 | static inline u64 paravirt_steal_clock(int cpu) | ||
15 | { | ||
16 | return pv_time_ops.steal_clock(cpu); | ||
17 | } | ||
18 | #endif | ||
19 | |||
20 | #endif | ||
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 27bf1e5180a1..83cd7e68e83b 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
@@ -41,6 +41,7 @@ arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o | |||
41 | arm64-obj-$(CONFIG_PCI) += pci.o | 41 | arm64-obj-$(CONFIG_PCI) += pci.o |
42 | arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o | 42 | arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o |
43 | arm64-obj-$(CONFIG_ACPI) += acpi.o | 43 | arm64-obj-$(CONFIG_ACPI) += acpi.o |
44 | arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o | ||
44 | 45 | ||
45 | obj-y += $(arm64-obj-y) vdso/ | 46 | obj-y += $(arm64-obj-y) vdso/ |
46 | obj-m += $(arm64-obj-m) | 47 | obj-m += $(arm64-obj-m) |
diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c new file mode 100644 index 000000000000..53f371ed4568 --- /dev/null +++ b/arch/arm64/kernel/paravirt.c | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * Copyright (C) 2013 Citrix Systems | ||
12 | * | ||
13 | * Author: Stefano Stabellini <stefano.stabellini@eu.citrix.com> | ||
14 | */ | ||
15 | |||
16 | #include <linux/export.h> | ||
17 | #include <linux/jump_label.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <asm/paravirt.h> | ||
20 | |||
21 | struct static_key paravirt_steal_enabled; | ||
22 | struct static_key paravirt_steal_rq_enabled; | ||
23 | |||
24 | struct pv_time_ops pv_time_ops; | ||
25 | EXPORT_SYMBOL_GPL(pv_time_ops); | ||
diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S index 8bbe9401f4f0..70df80e8da2c 100644 --- a/arch/arm64/xen/hypercall.S +++ b/arch/arm64/xen/hypercall.S | |||
@@ -80,6 +80,7 @@ HYPERCALL2(memory_op); | |||
80 | HYPERCALL2(physdev_op); | 80 | HYPERCALL2(physdev_op); |
81 | HYPERCALL3(vcpu_op); | 81 | HYPERCALL3(vcpu_op); |
82 | HYPERCALL1(tmem_op); | 82 | HYPERCALL1(tmem_op); |
83 | HYPERCALL1(platform_op_raw); | ||
83 | HYPERCALL2(multicall); | 84 | HYPERCALL2(multicall); |
84 | 85 | ||
85 | ENTRY(privcmd_call) | 86 | ENTRY(privcmd_call) |
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 4c20dd333412..3bcdcc84259d 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h | |||
@@ -310,10 +310,10 @@ HYPERVISOR_mca(struct xen_mc *mc_op) | |||
310 | } | 310 | } |
311 | 311 | ||
312 | static inline int | 312 | static inline int |
313 | HYPERVISOR_dom0_op(struct xen_platform_op *platform_op) | 313 | HYPERVISOR_platform_op(struct xen_platform_op *op) |
314 | { | 314 | { |
315 | platform_op->interface_version = XENPF_INTERFACE_VERSION; | 315 | op->interface_version = XENPF_INTERFACE_VERSION; |
316 | return _hypercall1(int, dom0_op, platform_op); | 316 | return _hypercall1(int, platform_op, op); |
317 | } | 317 | } |
318 | 318 | ||
319 | static inline int | 319 | static inline int |
diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c index acda713ab5be..abf4901c917b 100644 --- a/arch/x86/xen/apic.c +++ b/arch/x86/xen/apic.c | |||
@@ -64,7 +64,7 @@ static u32 xen_apic_read(u32 reg) | |||
64 | if (reg != APIC_ID) | 64 | if (reg != APIC_ID) |
65 | return 0; | 65 | return 0; |
66 | 66 | ||
67 | ret = HYPERVISOR_dom0_op(&op); | 67 | ret = HYPERVISOR_platform_op(&op); |
68 | if (ret) | 68 | if (ret) |
69 | return 0; | 69 | return 0; |
70 | 70 | ||
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 23063923e364..d09e4c9d7cc5 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -415,7 +415,7 @@ static bool __init xen_check_mwait(void) | |||
415 | 415 | ||
416 | set_xen_guest_handle(op.u.set_pminfo.pdc, buf); | 416 | set_xen_guest_handle(op.u.set_pminfo.pdc, buf); |
417 | 417 | ||
418 | if ((HYPERVISOR_dom0_op(&op) == 0) && | 418 | if ((HYPERVISOR_platform_op(&op) == 0) && |
419 | (buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) { | 419 | (buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) { |
420 | cpuid_leaf5_ecx_val = cx; | 420 | cpuid_leaf5_ecx_val = cx; |
421 | cpuid_leaf5_edx_val = dx; | 421 | cpuid_leaf5_edx_val = dx; |
@@ -1365,7 +1365,7 @@ static void __init xen_boot_params_init_edd(void) | |||
1365 | info->params.length = sizeof(info->params); | 1365 | info->params.length = sizeof(info->params); |
1366 | set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, | 1366 | set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, |
1367 | &info->params); | 1367 | &info->params); |
1368 | ret = HYPERVISOR_dom0_op(&op); | 1368 | ret = HYPERVISOR_platform_op(&op); |
1369 | if (ret) | 1369 | if (ret) |
1370 | break; | 1370 | break; |
1371 | 1371 | ||
@@ -1383,7 +1383,7 @@ static void __init xen_boot_params_init_edd(void) | |||
1383 | op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; | 1383 | op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; |
1384 | for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { | 1384 | for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { |
1385 | op.u.firmware_info.index = nr; | 1385 | op.u.firmware_info.index = nr; |
1386 | ret = HYPERVISOR_dom0_op(&op); | 1386 | ret = HYPERVISOR_platform_op(&op); |
1387 | if (ret) | 1387 | if (ret) |
1388 | break; | 1388 | break; |
1389 | mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; | 1389 | mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; |
@@ -1690,7 +1690,7 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1690 | xen_start_info->console.domU.mfn = 0; | 1690 | xen_start_info->console.domU.mfn = 0; |
1691 | xen_start_info->console.domU.evtchn = 0; | 1691 | xen_start_info->console.domU.evtchn = 0; |
1692 | 1692 | ||
1693 | if (HYPERVISOR_dom0_op(&op) == 0) | 1693 | if (HYPERVISOR_platform_op(&op) == 0) |
1694 | boot_params.kbd_status = op.u.firmware_info.u.kbd_shift_flags; | 1694 | boot_params.kbd_status = op.u.firmware_info.u.kbd_shift_flags; |
1695 | 1695 | ||
1696 | /* Make sure ACS will be enabled */ | 1696 | /* Make sure ACS will be enabled */ |
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index df0c40559583..7f664c416faf 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c | |||
@@ -34,7 +34,8 @@ static void xen_hvm_post_suspend(int suspend_cancelled) | |||
34 | { | 34 | { |
35 | #ifdef CONFIG_XEN_PVHVM | 35 | #ifdef CONFIG_XEN_PVHVM |
36 | int cpu; | 36 | int cpu; |
37 | xen_hvm_init_shared_info(); | 37 | if (!suspend_cancelled) |
38 | xen_hvm_init_shared_info(); | ||
38 | xen_callback_vector(); | 39 | xen_callback_vector(); |
39 | xen_unplug_emulated_devices(); | 40 | xen_unplug_emulated_devices(); |
40 | if (xen_feature(XENFEAT_hvm_safe_pvclock)) { | 41 | if (xen_feature(XENFEAT_hvm_safe_pvclock)) { |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index f1ba6a092854..a0a4e554c6f1 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/gfp.h> | 16 | #include <linux/gfp.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/pvclock_gtod.h> | 18 | #include <linux/pvclock_gtod.h> |
19 | #include <linux/timekeeper_internal.h> | ||
19 | 20 | ||
20 | #include <asm/pvclock.h> | 21 | #include <asm/pvclock.h> |
21 | #include <asm/xen/hypervisor.h> | 22 | #include <asm/xen/hypervisor.h> |
@@ -32,86 +33,12 @@ | |||
32 | #define TIMER_SLOP 100000 | 33 | #define TIMER_SLOP 100000 |
33 | #define NS_PER_TICK (1000000000LL / HZ) | 34 | #define NS_PER_TICK (1000000000LL / HZ) |
34 | 35 | ||
35 | /* runstate info updated by Xen */ | ||
36 | static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate); | ||
37 | |||
38 | /* snapshots of runstate info */ | 36 | /* snapshots of runstate info */ |
39 | static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot); | 37 | static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot); |
40 | 38 | ||
41 | /* unused ns of stolen time */ | 39 | /* unused ns of stolen time */ |
42 | static DEFINE_PER_CPU(u64, xen_residual_stolen); | 40 | static DEFINE_PER_CPU(u64, xen_residual_stolen); |
43 | 41 | ||
44 | /* return an consistent snapshot of 64-bit time/counter value */ | ||
45 | static u64 get64(const u64 *p) | ||
46 | { | ||
47 | u64 ret; | ||
48 | |||
49 | if (BITS_PER_LONG < 64) { | ||
50 | u32 *p32 = (u32 *)p; | ||
51 | u32 h, l; | ||
52 | |||
53 | /* | ||
54 | * Read high then low, and then make sure high is | ||
55 | * still the same; this will only loop if low wraps | ||
56 | * and carries into high. | ||
57 | * XXX some clean way to make this endian-proof? | ||
58 | */ | ||
59 | do { | ||
60 | h = p32[1]; | ||
61 | barrier(); | ||
62 | l = p32[0]; | ||
63 | barrier(); | ||
64 | } while (p32[1] != h); | ||
65 | |||
66 | ret = (((u64)h) << 32) | l; | ||
67 | } else | ||
68 | ret = *p; | ||
69 | |||
70 | return ret; | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Runstate accounting | ||
75 | */ | ||
76 | static void get_runstate_snapshot(struct vcpu_runstate_info *res) | ||
77 | { | ||
78 | u64 state_time; | ||
79 | struct vcpu_runstate_info *state; | ||
80 | |||
81 | BUG_ON(preemptible()); | ||
82 | |||
83 | state = this_cpu_ptr(&xen_runstate); | ||
84 | |||
85 | /* | ||
86 | * The runstate info is always updated by the hypervisor on | ||
87 | * the current CPU, so there's no need to use anything | ||
88 | * stronger than a compiler barrier when fetching it. | ||
89 | */ | ||
90 | do { | ||
91 | state_time = get64(&state->state_entry_time); | ||
92 | barrier(); | ||
93 | *res = *state; | ||
94 | barrier(); | ||
95 | } while (get64(&state->state_entry_time) != state_time); | ||
96 | } | ||
97 | |||
98 | /* return true when a vcpu could run but has no real cpu to run on */ | ||
99 | bool xen_vcpu_stolen(int vcpu) | ||
100 | { | ||
101 | return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable; | ||
102 | } | ||
103 | |||
104 | void xen_setup_runstate_info(int cpu) | ||
105 | { | ||
106 | struct vcpu_register_runstate_memory_area area; | ||
107 | |||
108 | area.addr.v = &per_cpu(xen_runstate, cpu); | ||
109 | |||
110 | if (HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, | ||
111 | cpu, &area)) | ||
112 | BUG(); | ||
113 | } | ||
114 | |||
115 | static void do_stolen_accounting(void) | 42 | static void do_stolen_accounting(void) |
116 | { | 43 | { |
117 | struct vcpu_runstate_info state; | 44 | struct vcpu_runstate_info state; |
@@ -119,7 +46,7 @@ static void do_stolen_accounting(void) | |||
119 | s64 runnable, offline, stolen; | 46 | s64 runnable, offline, stolen; |
120 | cputime_t ticks; | 47 | cputime_t ticks; |
121 | 48 | ||
122 | get_runstate_snapshot(&state); | 49 | xen_get_runstate_snapshot(&state); |
123 | 50 | ||
124 | WARN_ON(state.state != RUNSTATE_running); | 51 | WARN_ON(state.state != RUNSTATE_running); |
125 | 52 | ||
@@ -194,26 +121,46 @@ static int xen_pvclock_gtod_notify(struct notifier_block *nb, | |||
194 | unsigned long was_set, void *priv) | 121 | unsigned long was_set, void *priv) |
195 | { | 122 | { |
196 | /* Protected by the calling core code serialization */ | 123 | /* Protected by the calling core code serialization */ |
197 | static struct timespec next_sync; | 124 | static struct timespec64 next_sync; |
198 | 125 | ||
199 | struct xen_platform_op op; | 126 | struct xen_platform_op op; |
200 | struct timespec now; | 127 | struct timespec64 now; |
128 | struct timekeeper *tk = priv; | ||
129 | static bool settime64_supported = true; | ||
130 | int ret; | ||
201 | 131 | ||
202 | now = __current_kernel_time(); | 132 | now.tv_sec = tk->xtime_sec; |
133 | now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); | ||
203 | 134 | ||
204 | /* | 135 | /* |
205 | * We only take the expensive HV call when the clock was set | 136 | * We only take the expensive HV call when the clock was set |
206 | * or when the 11 minutes RTC synchronization time elapsed. | 137 | * or when the 11 minutes RTC synchronization time elapsed. |
207 | */ | 138 | */ |
208 | if (!was_set && timespec_compare(&now, &next_sync) < 0) | 139 | if (!was_set && timespec64_compare(&now, &next_sync) < 0) |
209 | return NOTIFY_OK; | 140 | return NOTIFY_OK; |
210 | 141 | ||
211 | op.cmd = XENPF_settime; | 142 | again: |
212 | op.u.settime.secs = now.tv_sec; | 143 | if (settime64_supported) { |
213 | op.u.settime.nsecs = now.tv_nsec; | 144 | op.cmd = XENPF_settime64; |
214 | op.u.settime.system_time = xen_clocksource_read(); | 145 | op.u.settime64.mbz = 0; |
146 | op.u.settime64.secs = now.tv_sec; | ||
147 | op.u.settime64.nsecs = now.tv_nsec; | ||
148 | op.u.settime64.system_time = xen_clocksource_read(); | ||
149 | } else { | ||
150 | op.cmd = XENPF_settime32; | ||
151 | op.u.settime32.secs = now.tv_sec; | ||
152 | op.u.settime32.nsecs = now.tv_nsec; | ||
153 | op.u.settime32.system_time = xen_clocksource_read(); | ||
154 | } | ||
155 | |||
156 | ret = HYPERVISOR_platform_op(&op); | ||
215 | 157 | ||
216 | (void)HYPERVISOR_dom0_op(&op); | 158 | if (ret == -ENOSYS && settime64_supported) { |
159 | settime64_supported = false; | ||
160 | goto again; | ||
161 | } | ||
162 | if (ret < 0) | ||
163 | return NOTIFY_BAD; | ||
217 | 164 | ||
218 | /* | 165 | /* |
219 | * Move the next drift compensation time 11 minutes | 166 | * Move the next drift compensation time 11 minutes |
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index aa8a7f71f310..9b7a35c9e51d 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o | 1 | obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o |
2 | obj-$(CONFIG_X86) += fallback.o | 2 | obj-$(CONFIG_X86) += fallback.o |
3 | obj-y += grant-table.o features.o balloon.o manage.o preempt.o | 3 | obj-y += grant-table.o features.o balloon.o manage.o preempt.o time.o |
4 | obj-y += events/ | 4 | obj-y += events/ |
5 | obj-y += xenbus/ | 5 | obj-y += xenbus/ |
6 | 6 | ||
diff --git a/drivers/xen/acpi.c b/drivers/xen/acpi.c index 90307c0b630c..6893c79fd2a1 100644 --- a/drivers/xen/acpi.c +++ b/drivers/xen/acpi.c | |||
@@ -58,7 +58,7 @@ static int xen_acpi_notify_hypervisor_state(u8 sleep_state, | |||
58 | bits, val_a, val_b)) | 58 | bits, val_a, val_b)) |
59 | return -1; | 59 | return -1; |
60 | 60 | ||
61 | HYPERVISOR_dom0_op(&op); | 61 | HYPERVISOR_platform_op(&op); |
62 | return 1; | 62 | return 1; |
63 | } | 63 | } |
64 | 64 | ||
diff --git a/drivers/xen/efi.c b/drivers/xen/efi.c index f745db270171..be7e56a338e8 100644 --- a/drivers/xen/efi.c +++ b/drivers/xen/efi.c | |||
@@ -42,7 +42,7 @@ static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) | |||
42 | { | 42 | { |
43 | struct xen_platform_op op = INIT_EFI_OP(get_time); | 43 | struct xen_platform_op op = INIT_EFI_OP(get_time); |
44 | 44 | ||
45 | if (HYPERVISOR_dom0_op(&op) < 0) | 45 | if (HYPERVISOR_platform_op(&op) < 0) |
46 | return EFI_UNSUPPORTED; | 46 | return EFI_UNSUPPORTED; |
47 | 47 | ||
48 | if (tm) { | 48 | if (tm) { |
@@ -67,7 +67,7 @@ static efi_status_t xen_efi_set_time(efi_time_t *tm) | |||
67 | BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_time)); | 67 | BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_time)); |
68 | memcpy(&efi_data(op).u.set_time, tm, sizeof(*tm)); | 68 | memcpy(&efi_data(op).u.set_time, tm, sizeof(*tm)); |
69 | 69 | ||
70 | if (HYPERVISOR_dom0_op(&op) < 0) | 70 | if (HYPERVISOR_platform_op(&op) < 0) |
71 | return EFI_UNSUPPORTED; | 71 | return EFI_UNSUPPORTED; |
72 | 72 | ||
73 | return efi_data(op).status; | 73 | return efi_data(op).status; |
@@ -79,7 +79,7 @@ static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, | |||
79 | { | 79 | { |
80 | struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time); | 80 | struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time); |
81 | 81 | ||
82 | if (HYPERVISOR_dom0_op(&op) < 0) | 82 | if (HYPERVISOR_platform_op(&op) < 0) |
83 | return EFI_UNSUPPORTED; | 83 | return EFI_UNSUPPORTED; |
84 | 84 | ||
85 | if (tm) { | 85 | if (tm) { |
@@ -108,7 +108,7 @@ static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) | |||
108 | else | 108 | else |
109 | efi_data(op).misc |= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY; | 109 | efi_data(op).misc |= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY; |
110 | 110 | ||
111 | if (HYPERVISOR_dom0_op(&op) < 0) | 111 | if (HYPERVISOR_platform_op(&op) < 0) |
112 | return EFI_UNSUPPORTED; | 112 | return EFI_UNSUPPORTED; |
113 | 113 | ||
114 | return efi_data(op).status; | 114 | return efi_data(op).status; |
@@ -129,7 +129,7 @@ static efi_status_t xen_efi_get_variable(efi_char16_t *name, | |||
129 | efi_data(op).u.get_variable.size = *data_size; | 129 | efi_data(op).u.get_variable.size = *data_size; |
130 | set_xen_guest_handle(efi_data(op).u.get_variable.data, data); | 130 | set_xen_guest_handle(efi_data(op).u.get_variable.data, data); |
131 | 131 | ||
132 | if (HYPERVISOR_dom0_op(&op) < 0) | 132 | if (HYPERVISOR_platform_op(&op) < 0) |
133 | return EFI_UNSUPPORTED; | 133 | return EFI_UNSUPPORTED; |
134 | 134 | ||
135 | *data_size = efi_data(op).u.get_variable.size; | 135 | *data_size = efi_data(op).u.get_variable.size; |
@@ -152,7 +152,7 @@ static efi_status_t xen_efi_get_next_variable(unsigned long *name_size, | |||
152 | memcpy(&efi_data(op).u.get_next_variable_name.vendor_guid, vendor, | 152 | memcpy(&efi_data(op).u.get_next_variable_name.vendor_guid, vendor, |
153 | sizeof(*vendor)); | 153 | sizeof(*vendor)); |
154 | 154 | ||
155 | if (HYPERVISOR_dom0_op(&op) < 0) | 155 | if (HYPERVISOR_platform_op(&op) < 0) |
156 | return EFI_UNSUPPORTED; | 156 | return EFI_UNSUPPORTED; |
157 | 157 | ||
158 | *name_size = efi_data(op).u.get_next_variable_name.size; | 158 | *name_size = efi_data(op).u.get_next_variable_name.size; |
@@ -178,7 +178,7 @@ static efi_status_t xen_efi_set_variable(efi_char16_t *name, | |||
178 | efi_data(op).u.set_variable.size = data_size; | 178 | efi_data(op).u.set_variable.size = data_size; |
179 | set_xen_guest_handle(efi_data(op).u.set_variable.data, data); | 179 | set_xen_guest_handle(efi_data(op).u.set_variable.data, data); |
180 | 180 | ||
181 | if (HYPERVISOR_dom0_op(&op) < 0) | 181 | if (HYPERVISOR_platform_op(&op) < 0) |
182 | return EFI_UNSUPPORTED; | 182 | return EFI_UNSUPPORTED; |
183 | 183 | ||
184 | return efi_data(op).status; | 184 | return efi_data(op).status; |
@@ -196,7 +196,7 @@ static efi_status_t xen_efi_query_variable_info(u32 attr, | |||
196 | 196 | ||
197 | efi_data(op).u.query_variable_info.attr = attr; | 197 | efi_data(op).u.query_variable_info.attr = attr; |
198 | 198 | ||
199 | if (HYPERVISOR_dom0_op(&op) < 0) | 199 | if (HYPERVISOR_platform_op(&op) < 0) |
200 | return EFI_UNSUPPORTED; | 200 | return EFI_UNSUPPORTED; |
201 | 201 | ||
202 | *storage_space = efi_data(op).u.query_variable_info.max_store_size; | 202 | *storage_space = efi_data(op).u.query_variable_info.max_store_size; |
@@ -210,7 +210,7 @@ static efi_status_t xen_efi_get_next_high_mono_count(u32 *count) | |||
210 | { | 210 | { |
211 | struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count); | 211 | struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count); |
212 | 212 | ||
213 | if (HYPERVISOR_dom0_op(&op) < 0) | 213 | if (HYPERVISOR_platform_op(&op) < 0) |
214 | return EFI_UNSUPPORTED; | 214 | return EFI_UNSUPPORTED; |
215 | 215 | ||
216 | *count = efi_data(op).misc; | 216 | *count = efi_data(op).misc; |
@@ -232,7 +232,7 @@ static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules, | |||
232 | efi_data(op).u.update_capsule.capsule_count = count; | 232 | efi_data(op).u.update_capsule.capsule_count = count; |
233 | efi_data(op).u.update_capsule.sg_list = sg_list; | 233 | efi_data(op).u.update_capsule.sg_list = sg_list; |
234 | 234 | ||
235 | if (HYPERVISOR_dom0_op(&op) < 0) | 235 | if (HYPERVISOR_platform_op(&op) < 0) |
236 | return EFI_UNSUPPORTED; | 236 | return EFI_UNSUPPORTED; |
237 | 237 | ||
238 | return efi_data(op).status; | 238 | return efi_data(op).status; |
@@ -252,7 +252,7 @@ static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules, | |||
252 | capsules); | 252 | capsules); |
253 | efi_data(op).u.query_capsule_capabilities.capsule_count = count; | 253 | efi_data(op).u.query_capsule_capabilities.capsule_count = count; |
254 | 254 | ||
255 | if (HYPERVISOR_dom0_op(&op) < 0) | 255 | if (HYPERVISOR_platform_op(&op) < 0) |
256 | return EFI_UNSUPPORTED; | 256 | return EFI_UNSUPPORTED; |
257 | 257 | ||
258 | *max_size = efi_data(op).u.query_capsule_capabilities.max_capsule_size; | 258 | *max_size = efi_data(op).u.query_capsule_capabilities.max_capsule_size; |
@@ -331,7 +331,7 @@ efi_system_table_t __init *xen_efi_probe(void) | |||
331 | }; | 331 | }; |
332 | union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info; | 332 | union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info; |
333 | 333 | ||
334 | if (!xen_initial_domain() || HYPERVISOR_dom0_op(&op) < 0) | 334 | if (!xen_initial_domain() || HYPERVISOR_platform_op(&op) < 0) |
335 | return NULL; | 335 | return NULL; |
336 | 336 | ||
337 | /* Here we know that Xen runs on EFI platform. */ | 337 | /* Here we know that Xen runs on EFI platform. */ |
@@ -347,7 +347,7 @@ efi_system_table_t __init *xen_efi_probe(void) | |||
347 | info->vendor.bufsz = sizeof(vendor); | 347 | info->vendor.bufsz = sizeof(vendor); |
348 | set_xen_guest_handle(info->vendor.name, vendor); | 348 | set_xen_guest_handle(info->vendor.name, vendor); |
349 | 349 | ||
350 | if (HYPERVISOR_dom0_op(&op) == 0) { | 350 | if (HYPERVISOR_platform_op(&op) == 0) { |
351 | efi_systab_xen.fw_vendor = __pa_symbol(vendor); | 351 | efi_systab_xen.fw_vendor = __pa_symbol(vendor); |
352 | efi_systab_xen.fw_revision = info->vendor.revision; | 352 | efi_systab_xen.fw_revision = info->vendor.revision; |
353 | } else | 353 | } else |
@@ -357,14 +357,14 @@ efi_system_table_t __init *xen_efi_probe(void) | |||
357 | op.u.firmware_info.type = XEN_FW_EFI_INFO; | 357 | op.u.firmware_info.type = XEN_FW_EFI_INFO; |
358 | op.u.firmware_info.index = XEN_FW_EFI_VERSION; | 358 | op.u.firmware_info.index = XEN_FW_EFI_VERSION; |
359 | 359 | ||
360 | if (HYPERVISOR_dom0_op(&op) == 0) | 360 | if (HYPERVISOR_platform_op(&op) == 0) |
361 | efi_systab_xen.hdr.revision = info->version; | 361 | efi_systab_xen.hdr.revision = info->version; |
362 | 362 | ||
363 | op.cmd = XENPF_firmware_info; | 363 | op.cmd = XENPF_firmware_info; |
364 | op.u.firmware_info.type = XEN_FW_EFI_INFO; | 364 | op.u.firmware_info.type = XEN_FW_EFI_INFO; |
365 | op.u.firmware_info.index = XEN_FW_EFI_RT_VERSION; | 365 | op.u.firmware_info.index = XEN_FW_EFI_RT_VERSION; |
366 | 366 | ||
367 | if (HYPERVISOR_dom0_op(&op) == 0) | 367 | if (HYPERVISOR_platform_op(&op) == 0) |
368 | efi.runtime_version = info->version; | 368 | efi.runtime_version = info->version; |
369 | 369 | ||
370 | return &efi_systab_xen; | 370 | return &efi_systab_xen; |
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 1be5dd048622..dc495383ad73 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
@@ -518,7 +518,7 @@ static void mn_release(struct mmu_notifier *mn, | |||
518 | mutex_unlock(&priv->lock); | 518 | mutex_unlock(&priv->lock); |
519 | } | 519 | } |
520 | 520 | ||
521 | static struct mmu_notifier_ops gntdev_mmu_ops = { | 521 | static const struct mmu_notifier_ops gntdev_mmu_ops = { |
522 | .release = mn_release, | 522 | .release = mn_release, |
523 | .invalidate_page = mn_invl_page, | 523 | .invalidate_page = mn_invl_page, |
524 | .invalidate_range_start = mn_invl_range_start, | 524 | .invalidate_range_start = mn_invl_range_start, |
@@ -748,6 +748,206 @@ static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u) | |||
748 | return rc; | 748 | return rc; |
749 | } | 749 | } |
750 | 750 | ||
751 | #define GNTDEV_COPY_BATCH 24 | ||
752 | |||
753 | struct gntdev_copy_batch { | ||
754 | struct gnttab_copy ops[GNTDEV_COPY_BATCH]; | ||
755 | struct page *pages[GNTDEV_COPY_BATCH]; | ||
756 | s16 __user *status[GNTDEV_COPY_BATCH]; | ||
757 | unsigned int nr_ops; | ||
758 | unsigned int nr_pages; | ||
759 | }; | ||
760 | |||
761 | static int gntdev_get_page(struct gntdev_copy_batch *batch, void __user *virt, | ||
762 | bool writeable, unsigned long *gfn) | ||
763 | { | ||
764 | unsigned long addr = (unsigned long)virt; | ||
765 | struct page *page; | ||
766 | unsigned long xen_pfn; | ||
767 | int ret; | ||
768 | |||
769 | ret = get_user_pages_fast(addr, 1, writeable, &page); | ||
770 | if (ret < 0) | ||
771 | return ret; | ||
772 | |||
773 | batch->pages[batch->nr_pages++] = page; | ||
774 | |||
775 | xen_pfn = page_to_xen_pfn(page) + XEN_PFN_DOWN(addr & ~PAGE_MASK); | ||
776 | *gfn = pfn_to_gfn(xen_pfn); | ||
777 | |||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | static void gntdev_put_pages(struct gntdev_copy_batch *batch) | ||
782 | { | ||
783 | unsigned int i; | ||
784 | |||
785 | for (i = 0; i < batch->nr_pages; i++) | ||
786 | put_page(batch->pages[i]); | ||
787 | batch->nr_pages = 0; | ||
788 | } | ||
789 | |||
790 | static int gntdev_copy(struct gntdev_copy_batch *batch) | ||
791 | { | ||
792 | unsigned int i; | ||
793 | |||
794 | gnttab_batch_copy(batch->ops, batch->nr_ops); | ||
795 | gntdev_put_pages(batch); | ||
796 | |||
797 | /* | ||
798 | * For each completed op, update the status if the op failed | ||
799 | * and all previous ops for the segment were successful. | ||
800 | */ | ||
801 | for (i = 0; i < batch->nr_ops; i++) { | ||
802 | s16 status = batch->ops[i].status; | ||
803 | s16 old_status; | ||
804 | |||
805 | if (status == GNTST_okay) | ||
806 | continue; | ||
807 | |||
808 | if (__get_user(old_status, batch->status[i])) | ||
809 | return -EFAULT; | ||
810 | |||
811 | if (old_status != GNTST_okay) | ||
812 | continue; | ||
813 | |||
814 | if (__put_user(status, batch->status[i])) | ||
815 | return -EFAULT; | ||
816 | } | ||
817 | |||
818 | batch->nr_ops = 0; | ||
819 | return 0; | ||
820 | } | ||
821 | |||
822 | static int gntdev_grant_copy_seg(struct gntdev_copy_batch *batch, | ||
823 | struct gntdev_grant_copy_segment *seg, | ||
824 | s16 __user *status) | ||
825 | { | ||
826 | uint16_t copied = 0; | ||
827 | |||
828 | /* | ||
829 | * Disallow local -> local copies since there is only space in | ||
830 | * batch->pages for one page per-op and this would be a very | ||
831 | * expensive memcpy(). | ||
832 | */ | ||
833 | if (!(seg->flags & (GNTCOPY_source_gref | GNTCOPY_dest_gref))) | ||
834 | return -EINVAL; | ||
835 | |||
836 | /* Can't cross page if source/dest is a grant ref. */ | ||
837 | if (seg->flags & GNTCOPY_source_gref) { | ||
838 | if (seg->source.foreign.offset + seg->len > XEN_PAGE_SIZE) | ||
839 | return -EINVAL; | ||
840 | } | ||
841 | if (seg->flags & GNTCOPY_dest_gref) { | ||
842 | if (seg->dest.foreign.offset + seg->len > XEN_PAGE_SIZE) | ||
843 | return -EINVAL; | ||
844 | } | ||
845 | |||
846 | if (put_user(GNTST_okay, status)) | ||
847 | return -EFAULT; | ||
848 | |||
849 | while (copied < seg->len) { | ||
850 | struct gnttab_copy *op; | ||
851 | void __user *virt; | ||
852 | size_t len, off; | ||
853 | unsigned long gfn; | ||
854 | int ret; | ||
855 | |||
856 | if (batch->nr_ops >= GNTDEV_COPY_BATCH) { | ||
857 | ret = gntdev_copy(batch); | ||
858 | if (ret < 0) | ||
859 | return ret; | ||
860 | } | ||
861 | |||
862 | len = seg->len - copied; | ||
863 | |||
864 | op = &batch->ops[batch->nr_ops]; | ||
865 | op->flags = 0; | ||
866 | |||
867 | if (seg->flags & GNTCOPY_source_gref) { | ||
868 | op->source.u.ref = seg->source.foreign.ref; | ||
869 | op->source.domid = seg->source.foreign.domid; | ||
870 | op->source.offset = seg->source.foreign.offset + copied; | ||
871 | op->flags |= GNTCOPY_source_gref; | ||
872 | } else { | ||
873 | virt = seg->source.virt + copied; | ||
874 | off = (unsigned long)virt & ~XEN_PAGE_MASK; | ||
875 | len = min(len, (size_t)XEN_PAGE_SIZE - off); | ||
876 | |||
877 | ret = gntdev_get_page(batch, virt, false, &gfn); | ||
878 | if (ret < 0) | ||
879 | return ret; | ||
880 | |||
881 | op->source.u.gmfn = gfn; | ||
882 | op->source.domid = DOMID_SELF; | ||
883 | op->source.offset = off; | ||
884 | } | ||
885 | |||
886 | if (seg->flags & GNTCOPY_dest_gref) { | ||
887 | op->dest.u.ref = seg->dest.foreign.ref; | ||
888 | op->dest.domid = seg->dest.foreign.domid; | ||
889 | op->dest.offset = seg->dest.foreign.offset + copied; | ||
890 | op->flags |= GNTCOPY_dest_gref; | ||
891 | } else { | ||
892 | virt = seg->dest.virt + copied; | ||
893 | off = (unsigned long)virt & ~XEN_PAGE_MASK; | ||
894 | len = min(len, (size_t)XEN_PAGE_SIZE - off); | ||
895 | |||
896 | ret = gntdev_get_page(batch, virt, true, &gfn); | ||
897 | if (ret < 0) | ||
898 | return ret; | ||
899 | |||
900 | op->dest.u.gmfn = gfn; | ||
901 | op->dest.domid = DOMID_SELF; | ||
902 | op->dest.offset = off; | ||
903 | } | ||
904 | |||
905 | op->len = len; | ||
906 | copied += len; | ||
907 | |||
908 | batch->status[batch->nr_ops] = status; | ||
909 | batch->nr_ops++; | ||
910 | } | ||
911 | |||
912 | return 0; | ||
913 | } | ||
914 | |||
915 | static long gntdev_ioctl_grant_copy(struct gntdev_priv *priv, void __user *u) | ||
916 | { | ||
917 | struct ioctl_gntdev_grant_copy copy; | ||
918 | struct gntdev_copy_batch batch; | ||
919 | unsigned int i; | ||
920 | int ret = 0; | ||
921 | |||
922 | if (copy_from_user(©, u, sizeof(copy))) | ||
923 | return -EFAULT; | ||
924 | |||
925 | batch.nr_ops = 0; | ||
926 | batch.nr_pages = 0; | ||
927 | |||
928 | for (i = 0; i < copy.count; i++) { | ||
929 | struct gntdev_grant_copy_segment seg; | ||
930 | |||
931 | if (copy_from_user(&seg, ©.segments[i], sizeof(seg))) { | ||
932 | ret = -EFAULT; | ||
933 | goto out; | ||
934 | } | ||
935 | |||
936 | ret = gntdev_grant_copy_seg(&batch, &seg, ©.segments[i].status); | ||
937 | if (ret < 0) | ||
938 | goto out; | ||
939 | |||
940 | cond_resched(); | ||
941 | } | ||
942 | if (batch.nr_ops) | ||
943 | ret = gntdev_copy(&batch); | ||
944 | return ret; | ||
945 | |||
946 | out: | ||
947 | gntdev_put_pages(&batch); | ||
948 | return ret; | ||
949 | } | ||
950 | |||
751 | static long gntdev_ioctl(struct file *flip, | 951 | static long gntdev_ioctl(struct file *flip, |
752 | unsigned int cmd, unsigned long arg) | 952 | unsigned int cmd, unsigned long arg) |
753 | { | 953 | { |
@@ -767,6 +967,9 @@ static long gntdev_ioctl(struct file *flip, | |||
767 | case IOCTL_GNTDEV_SET_UNMAP_NOTIFY: | 967 | case IOCTL_GNTDEV_SET_UNMAP_NOTIFY: |
768 | return gntdev_ioctl_notify(priv, ptr); | 968 | return gntdev_ioctl_notify(priv, ptr); |
769 | 969 | ||
970 | case IOCTL_GNTDEV_GRANT_COPY: | ||
971 | return gntdev_ioctl_grant_copy(priv, ptr); | ||
972 | |||
770 | default: | 973 | default: |
771 | pr_debug("priv %p, unknown cmd %x\n", priv, cmd); | 974 | pr_debug("priv %p, unknown cmd %x\n", priv, cmd); |
772 | return -ENOIOCTLCMD; | 975 | return -ENOIOCTLCMD; |
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index c49f79ed58c5..effbaf91791f 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -128,7 +128,7 @@ struct unmap_refs_callback_data { | |||
128 | int result; | 128 | int result; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static struct gnttab_ops *gnttab_interface; | 131 | static const struct gnttab_ops *gnttab_interface; |
132 | 132 | ||
133 | static int grant_table_version; | 133 | static int grant_table_version; |
134 | static int grefs_per_grant_frame; | 134 | static int grefs_per_grant_frame; |
@@ -1013,7 +1013,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx) | |||
1013 | return rc; | 1013 | return rc; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | static struct gnttab_ops gnttab_v1_ops = { | 1016 | static const struct gnttab_ops gnttab_v1_ops = { |
1017 | .map_frames = gnttab_map_frames_v1, | 1017 | .map_frames = gnttab_map_frames_v1, |
1018 | .unmap_frames = gnttab_unmap_frames_v1, | 1018 | .unmap_frames = gnttab_unmap_frames_v1, |
1019 | .update_entry = gnttab_update_entry_v1, | 1019 | .update_entry = gnttab_update_entry_v1, |
diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c index 49e88f2ce7a1..cdc6daa7a9f6 100644 --- a/drivers/xen/pcpu.c +++ b/drivers/xen/pcpu.c | |||
@@ -78,7 +78,7 @@ static int xen_pcpu_down(uint32_t cpu_id) | |||
78 | .u.cpu_ol.cpuid = cpu_id, | 78 | .u.cpu_ol.cpuid = cpu_id, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | return HYPERVISOR_dom0_op(&op); | 81 | return HYPERVISOR_platform_op(&op); |
82 | } | 82 | } |
83 | 83 | ||
84 | static int xen_pcpu_up(uint32_t cpu_id) | 84 | static int xen_pcpu_up(uint32_t cpu_id) |
@@ -89,7 +89,7 @@ static int xen_pcpu_up(uint32_t cpu_id) | |||
89 | .u.cpu_ol.cpuid = cpu_id, | 89 | .u.cpu_ol.cpuid = cpu_id, |
90 | }; | 90 | }; |
91 | 91 | ||
92 | return HYPERVISOR_dom0_op(&op); | 92 | return HYPERVISOR_platform_op(&op); |
93 | } | 93 | } |
94 | 94 | ||
95 | static ssize_t show_online(struct device *dev, | 95 | static ssize_t show_online(struct device *dev, |
@@ -277,7 +277,7 @@ static int sync_pcpu(uint32_t cpu, uint32_t *max_cpu) | |||
277 | .u.pcpu_info.xen_cpuid = cpu, | 277 | .u.pcpu_info.xen_cpuid = cpu, |
278 | }; | 278 | }; |
279 | 279 | ||
280 | ret = HYPERVISOR_dom0_op(&op); | 280 | ret = HYPERVISOR_platform_op(&op); |
281 | if (ret) | 281 | if (ret) |
282 | return ret; | 282 | return ret; |
283 | 283 | ||
@@ -364,7 +364,7 @@ int xen_pcpu_id(uint32_t acpi_id) | |||
364 | op.cmd = XENPF_get_cpuinfo; | 364 | op.cmd = XENPF_get_cpuinfo; |
365 | while (cpu_id <= max_id) { | 365 | while (cpu_id <= max_id) { |
366 | op.u.pcpu_info.xen_cpuid = cpu_id; | 366 | op.u.pcpu_info.xen_cpuid = cpu_id; |
367 | if (HYPERVISOR_dom0_op(&op)) { | 367 | if (HYPERVISOR_platform_op(&op)) { |
368 | cpu_id++; | 368 | cpu_id++; |
369 | continue; | 369 | continue; |
370 | } | 370 | } |
diff --git a/drivers/xen/time.c b/drivers/xen/time.c new file mode 100644 index 000000000000..71078425c9ea --- /dev/null +++ b/drivers/xen/time.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * Xen stolen ticks accounting. | ||
3 | */ | ||
4 | #include <linux/kernel.h> | ||
5 | #include <linux/kernel_stat.h> | ||
6 | #include <linux/math64.h> | ||
7 | #include <linux/gfp.h> | ||
8 | |||
9 | #include <asm/xen/hypervisor.h> | ||
10 | #include <asm/xen/hypercall.h> | ||
11 | |||
12 | #include <xen/events.h> | ||
13 | #include <xen/features.h> | ||
14 | #include <xen/interface/xen.h> | ||
15 | #include <xen/interface/vcpu.h> | ||
16 | #include <xen/xen-ops.h> | ||
17 | |||
18 | /* runstate info updated by Xen */ | ||
19 | static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate); | ||
20 | |||
21 | /* return an consistent snapshot of 64-bit time/counter value */ | ||
22 | static u64 get64(const u64 *p) | ||
23 | { | ||
24 | u64 ret; | ||
25 | |||
26 | if (BITS_PER_LONG < 64) { | ||
27 | u32 *p32 = (u32 *)p; | ||
28 | u32 h, l, h2; | ||
29 | |||
30 | /* | ||
31 | * Read high then low, and then make sure high is | ||
32 | * still the same; this will only loop if low wraps | ||
33 | * and carries into high. | ||
34 | * XXX some clean way to make this endian-proof? | ||
35 | */ | ||
36 | do { | ||
37 | h = READ_ONCE(p32[1]); | ||
38 | l = READ_ONCE(p32[0]); | ||
39 | h2 = READ_ONCE(p32[1]); | ||
40 | } while(h2 != h); | ||
41 | |||
42 | ret = (((u64)h) << 32) | l; | ||
43 | } else | ||
44 | ret = READ_ONCE(*p); | ||
45 | |||
46 | return ret; | ||
47 | } | ||
48 | |||
49 | /* | ||
50 | * Runstate accounting | ||
51 | */ | ||
52 | void xen_get_runstate_snapshot(struct vcpu_runstate_info *res) | ||
53 | { | ||
54 | u64 state_time; | ||
55 | struct vcpu_runstate_info *state; | ||
56 | |||
57 | BUG_ON(preemptible()); | ||
58 | |||
59 | state = this_cpu_ptr(&xen_runstate); | ||
60 | |||
61 | /* | ||
62 | * The runstate info is always updated by the hypervisor on | ||
63 | * the current CPU, so there's no need to use anything | ||
64 | * stronger than a compiler barrier when fetching it. | ||
65 | */ | ||
66 | do { | ||
67 | state_time = get64(&state->state_entry_time); | ||
68 | *res = READ_ONCE(*state); | ||
69 | } while (get64(&state->state_entry_time) != state_time); | ||
70 | } | ||
71 | |||
72 | /* return true when a vcpu could run but has no real cpu to run on */ | ||
73 | bool xen_vcpu_stolen(int vcpu) | ||
74 | { | ||
75 | return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable; | ||
76 | } | ||
77 | |||
78 | void xen_setup_runstate_info(int cpu) | ||
79 | { | ||
80 | struct vcpu_register_runstate_memory_area area; | ||
81 | |||
82 | area.addr.v = &per_cpu(xen_runstate, cpu); | ||
83 | |||
84 | if (HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, | ||
85 | cpu, &area)) | ||
86 | BUG(); | ||
87 | } | ||
88 | |||
diff --git a/drivers/xen/xen-acpi-cpuhotplug.c b/drivers/xen/xen-acpi-cpuhotplug.c index f4a369429553..fdc9e67b842d 100644 --- a/drivers/xen/xen-acpi-cpuhotplug.c +++ b/drivers/xen/xen-acpi-cpuhotplug.c | |||
@@ -206,7 +206,7 @@ static int xen_hotadd_cpu(struct acpi_processor *pr) | |||
206 | op.u.cpu_add.acpi_id = pr->acpi_id; | 206 | op.u.cpu_add.acpi_id = pr->acpi_id; |
207 | op.u.cpu_add.pxm = pxm; | 207 | op.u.cpu_add.pxm = pxm; |
208 | 208 | ||
209 | cpu_id = HYPERVISOR_dom0_op(&op); | 209 | cpu_id = HYPERVISOR_platform_op(&op); |
210 | if (cpu_id < 0) | 210 | if (cpu_id < 0) |
211 | pr_err(PREFIX "Failed to hotadd CPU for acpi_id %d\n", | 211 | pr_err(PREFIX "Failed to hotadd CPU for acpi_id %d\n", |
212 | pr->acpi_id); | 212 | pr->acpi_id); |
diff --git a/drivers/xen/xen-acpi-pad.c b/drivers/xen/xen-acpi-pad.c index f83b754505f8..23d1808fe027 100644 --- a/drivers/xen/xen-acpi-pad.c +++ b/drivers/xen/xen-acpi-pad.c | |||
@@ -36,7 +36,7 @@ static int xen_acpi_pad_idle_cpus(unsigned int idle_nums) | |||
36 | op.u.core_parking.type = XEN_CORE_PARKING_SET; | 36 | op.u.core_parking.type = XEN_CORE_PARKING_SET; |
37 | op.u.core_parking.idle_nums = idle_nums; | 37 | op.u.core_parking.idle_nums = idle_nums; |
38 | 38 | ||
39 | return HYPERVISOR_dom0_op(&op); | 39 | return HYPERVISOR_platform_op(&op); |
40 | } | 40 | } |
41 | 41 | ||
42 | static int xen_acpi_pad_idle_cpus_num(void) | 42 | static int xen_acpi_pad_idle_cpus_num(void) |
@@ -46,7 +46,7 @@ static int xen_acpi_pad_idle_cpus_num(void) | |||
46 | op.cmd = XENPF_core_parking; | 46 | op.cmd = XENPF_core_parking; |
47 | op.u.core_parking.type = XEN_CORE_PARKING_GET; | 47 | op.u.core_parking.type = XEN_CORE_PARKING_GET; |
48 | 48 | ||
49 | return HYPERVISOR_dom0_op(&op) | 49 | return HYPERVISOR_platform_op(&op) |
50 | ?: op.u.core_parking.idle_nums; | 50 | ?: op.u.core_parking.idle_nums; |
51 | } | 51 | } |
52 | 52 | ||
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 70fa438000af..076970a54f89 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c | |||
@@ -116,7 +116,7 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr) | |||
116 | set_xen_guest_handle(op.u.set_pminfo.power.states, dst_cx_states); | 116 | set_xen_guest_handle(op.u.set_pminfo.power.states, dst_cx_states); |
117 | 117 | ||
118 | if (!no_hypercall) | 118 | if (!no_hypercall) |
119 | ret = HYPERVISOR_dom0_op(&op); | 119 | ret = HYPERVISOR_platform_op(&op); |
120 | 120 | ||
121 | if (!ret) { | 121 | if (!ret) { |
122 | pr_debug("ACPI CPU%u - C-states uploaded.\n", _pr->acpi_id); | 122 | pr_debug("ACPI CPU%u - C-states uploaded.\n", _pr->acpi_id); |
@@ -244,7 +244,7 @@ static int push_pxx_to_hypervisor(struct acpi_processor *_pr) | |||
244 | } | 244 | } |
245 | 245 | ||
246 | if (!no_hypercall) | 246 | if (!no_hypercall) |
247 | ret = HYPERVISOR_dom0_op(&op); | 247 | ret = HYPERVISOR_platform_op(&op); |
248 | 248 | ||
249 | if (!ret) { | 249 | if (!ret) { |
250 | struct acpi_processor_performance *perf; | 250 | struct acpi_processor_performance *perf; |
@@ -302,7 +302,7 @@ static unsigned int __init get_max_acpi_id(void) | |||
302 | info = &op.u.pcpu_info; | 302 | info = &op.u.pcpu_info; |
303 | info->xen_cpuid = 0; | 303 | info->xen_cpuid = 0; |
304 | 304 | ||
305 | ret = HYPERVISOR_dom0_op(&op); | 305 | ret = HYPERVISOR_platform_op(&op); |
306 | if (ret) | 306 | if (ret) |
307 | return NR_CPUS; | 307 | return NR_CPUS; |
308 | 308 | ||
@@ -310,7 +310,7 @@ static unsigned int __init get_max_acpi_id(void) | |||
310 | last_cpu = op.u.pcpu_info.max_present; | 310 | last_cpu = op.u.pcpu_info.max_present; |
311 | for (i = 0; i <= last_cpu; i++) { | 311 | for (i = 0; i <= last_cpu; i++) { |
312 | info->xen_cpuid = i; | 312 | info->xen_cpuid = i; |
313 | ret = HYPERVISOR_dom0_op(&op); | 313 | ret = HYPERVISOR_platform_op(&op); |
314 | if (ret) | 314 | if (ret) |
315 | continue; | 315 | continue; |
316 | max_acpi_id = max(info->acpi_id, max_acpi_id); | 316 | max_acpi_id = max(info->acpi_id, max_acpi_id); |
diff --git a/drivers/xen/xenfs/xensyms.c b/drivers/xen/xenfs/xensyms.c index f8b12856753f..a03f261b12d8 100644 --- a/drivers/xen/xenfs/xensyms.c +++ b/drivers/xen/xenfs/xensyms.c | |||
@@ -31,7 +31,7 @@ static int xensyms_next_sym(struct xensyms *xs) | |||
31 | 31 | ||
32 | symnum = symdata->symnum; | 32 | symnum = symdata->symnum; |
33 | 33 | ||
34 | ret = HYPERVISOR_dom0_op(&xs->op); | 34 | ret = HYPERVISOR_platform_op(&xs->op); |
35 | if (ret < 0) | 35 | if (ret < 0) |
36 | return ret; | 36 | return ret; |
37 | 37 | ||
@@ -50,7 +50,7 @@ static int xensyms_next_sym(struct xensyms *xs) | |||
50 | set_xen_guest_handle(symdata->name, xs->name); | 50 | set_xen_guest_handle(symdata->name, xs->name); |
51 | symdata->symnum--; /* Rewind */ | 51 | symdata->symnum--; /* Rewind */ |
52 | 52 | ||
53 | ret = HYPERVISOR_dom0_op(&xs->op); | 53 | ret = HYPERVISOR_platform_op(&xs->op); |
54 | if (ret < 0) | 54 | if (ret < 0) |
55 | return ret; | 55 | return ret; |
56 | } | 56 | } |
diff --git a/include/uapi/xen/gntdev.h b/include/uapi/xen/gntdev.h index aa7610a9b867..d0661977667e 100644 --- a/include/uapi/xen/gntdev.h +++ b/include/uapi/xen/gntdev.h | |||
@@ -144,6 +144,56 @@ struct ioctl_gntdev_unmap_notify { | |||
144 | __u32 event_channel_port; | 144 | __u32 event_channel_port; |
145 | }; | 145 | }; |
146 | 146 | ||
147 | struct gntdev_grant_copy_segment { | ||
148 | union { | ||
149 | void __user *virt; | ||
150 | struct { | ||
151 | grant_ref_t ref; | ||
152 | __u16 offset; | ||
153 | domid_t domid; | ||
154 | } foreign; | ||
155 | } source, dest; | ||
156 | __u16 len; | ||
157 | |||
158 | __u16 flags; /* GNTCOPY_* */ | ||
159 | __s16 status; /* GNTST_* */ | ||
160 | }; | ||
161 | |||
162 | /* | ||
163 | * Copy between grant references and local buffers. | ||
164 | * | ||
165 | * The copy is split into @count @segments, each of which can copy | ||
166 | * to/from one grant reference. | ||
167 | * | ||
168 | * Each segment is similar to struct gnttab_copy in the hypervisor ABI | ||
169 | * except the local buffer is specified using a virtual address | ||
170 | * (instead of a GFN and offset). | ||
171 | * | ||
172 | * The local buffer may cross a Xen page boundary -- the driver will | ||
173 | * split segments into multiple ops if required. | ||
174 | * | ||
175 | * Returns 0 if all segments have been processed and @status in each | ||
176 | * segment is valid. Note that one or more segments may have failed | ||
177 | * (status != GNTST_okay). | ||
178 | * | ||
179 | * If the driver had to split a segment into two or more ops, @status | ||
180 | * includes the status of the first failed op for that segment (or | ||
181 | * GNTST_okay if all ops were successful). | ||
182 | * | ||
183 | * If -1 is returned, the status of all segments is undefined. | ||
184 | * | ||
185 | * EINVAL: A segment has local buffers for both source and | ||
186 | * destination. | ||
187 | * EINVAL: A segment crosses the boundary of a foreign page. | ||
188 | * EFAULT: A segment's local buffer is not accessible. | ||
189 | */ | ||
190 | #define IOCTL_GNTDEV_GRANT_COPY \ | ||
191 | _IOC(_IOC_NONE, 'G', 8, sizeof(struct ioctl_gntdev_grant_copy)) | ||
192 | struct ioctl_gntdev_grant_copy { | ||
193 | unsigned int count; | ||
194 | struct gntdev_grant_copy_segment __user *segments; | ||
195 | }; | ||
196 | |||
147 | /* Clear (set to zero) the byte specified by index */ | 197 | /* Clear (set to zero) the byte specified by index */ |
148 | #define UNMAP_NOTIFY_CLEAR_BYTE 0x1 | 198 | #define UNMAP_NOTIFY_CLEAR_BYTE 0x1 |
149 | /* Send an interrupt on the indicated event channel */ | 199 | /* Send an interrupt on the indicated event channel */ |
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h index 8e035871360e..732efb08c3e1 100644 --- a/include/xen/interface/platform.h +++ b/include/xen/interface/platform.h | |||
@@ -35,14 +35,23 @@ | |||
35 | * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC, | 35 | * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC, |
36 | * 1 January, 1970 if the current system time was <system_time>. | 36 | * 1 January, 1970 if the current system time was <system_time>. |
37 | */ | 37 | */ |
38 | #define XENPF_settime 17 | 38 | #define XENPF_settime32 17 |
39 | struct xenpf_settime { | 39 | struct xenpf_settime32 { |
40 | /* IN variables. */ | 40 | /* IN variables. */ |
41 | uint32_t secs; | 41 | uint32_t secs; |
42 | uint32_t nsecs; | 42 | uint32_t nsecs; |
43 | uint64_t system_time; | 43 | uint64_t system_time; |
44 | }; | 44 | }; |
45 | DEFINE_GUEST_HANDLE_STRUCT(xenpf_settime_t); | 45 | DEFINE_GUEST_HANDLE_STRUCT(xenpf_settime32_t); |
46 | #define XENPF_settime64 62 | ||
47 | struct xenpf_settime64 { | ||
48 | /* IN variables. */ | ||
49 | uint64_t secs; | ||
50 | uint32_t nsecs; | ||
51 | uint32_t mbz; | ||
52 | uint64_t system_time; | ||
53 | }; | ||
54 | DEFINE_GUEST_HANDLE_STRUCT(xenpf_settime64_t); | ||
46 | 55 | ||
47 | /* | 56 | /* |
48 | * Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type. | 57 | * Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type. |
@@ -495,7 +504,8 @@ struct xen_platform_op { | |||
495 | uint32_t cmd; | 504 | uint32_t cmd; |
496 | uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ | 505 | uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ |
497 | union { | 506 | union { |
498 | struct xenpf_settime settime; | 507 | struct xenpf_settime32 settime32; |
508 | struct xenpf_settime64 settime64; | ||
499 | struct xenpf_add_memtype add_memtype; | 509 | struct xenpf_add_memtype add_memtype; |
500 | struct xenpf_del_memtype del_memtype; | 510 | struct xenpf_del_memtype del_memtype; |
501 | struct xenpf_read_memtype read_memtype; | 511 | struct xenpf_read_memtype read_memtype; |
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h index 167071c290b3..d1331121c0bd 100644 --- a/include/xen/interface/xen.h +++ b/include/xen/interface/xen.h | |||
@@ -48,7 +48,7 @@ | |||
48 | #define __HYPERVISOR_set_callbacks 4 | 48 | #define __HYPERVISOR_set_callbacks 4 |
49 | #define __HYPERVISOR_fpu_taskswitch 5 | 49 | #define __HYPERVISOR_fpu_taskswitch 5 |
50 | #define __HYPERVISOR_sched_op_compat 6 | 50 | #define __HYPERVISOR_sched_op_compat 6 |
51 | #define __HYPERVISOR_dom0_op 7 | 51 | #define __HYPERVISOR_platform_op 7 |
52 | #define __HYPERVISOR_set_debugreg 8 | 52 | #define __HYPERVISOR_set_debugreg 8 |
53 | #define __HYPERVISOR_get_debugreg 9 | 53 | #define __HYPERVISOR_get_debugreg 9 |
54 | #define __HYPERVISOR_update_descriptor 10 | 54 | #define __HYPERVISOR_update_descriptor 10 |
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index e4e214a5abd5..86abe07b20ec 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/notifier.h> | 5 | #include <linux/notifier.h> |
6 | #include <linux/efi.h> | 6 | #include <linux/efi.h> |
7 | #include <asm/xen/interface.h> | 7 | #include <asm/xen/interface.h> |
8 | #include <xen/interface/vcpu.h> | ||
8 | 9 | ||
9 | DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); | 10 | DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); |
10 | 11 | ||
@@ -18,6 +19,10 @@ void xen_arch_suspend(void); | |||
18 | void xen_resume_notifier_register(struct notifier_block *nb); | 19 | void xen_resume_notifier_register(struct notifier_block *nb); |
19 | void xen_resume_notifier_unregister(struct notifier_block *nb); | 20 | void xen_resume_notifier_unregister(struct notifier_block *nb); |
20 | 21 | ||
22 | bool xen_vcpu_stolen(int vcpu); | ||
23 | void xen_setup_runstate_info(int cpu); | ||
24 | void xen_get_runstate_snapshot(struct vcpu_runstate_info *res); | ||
25 | |||
21 | int xen_setup_shutdown_event(void); | 26 | int xen_setup_shutdown_event(void); |
22 | 27 | ||
23 | extern unsigned long *xen_contiguous_bitmap; | 28 | extern unsigned long *xen_contiguous_bitmap; |
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index d5ff5c6bf829..b2ab2ffb1adc 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c | |||
@@ -5,6 +5,9 @@ | |||
5 | #include <linux/static_key.h> | 5 | #include <linux/static_key.h> |
6 | #include <linux/context_tracking.h> | 6 | #include <linux/context_tracking.h> |
7 | #include "sched.h" | 7 | #include "sched.h" |
8 | #ifdef CONFIG_PARAVIRT | ||
9 | #include <asm/paravirt.h> | ||
10 | #endif | ||
8 | 11 | ||
9 | 12 | ||
10 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING | 13 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING |