aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 16:05:36 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 16:05:36 -0500
commitc9bed1cf51011c815d88288b774865d013ca78a8 (patch)
tree77e205b9442338a3d11567d4abcdb8df616979cf
parent75777c1855e10c010c9c3a21611d95dd9be01ab1 (diff)
parenta4cdb556cae05cd3e7b602b3a44c01420c4e2258 (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
-rw-r--r--arch/arm/Kconfig20
-rw-r--r--arch/arm/include/asm/paravirt.h20
-rw-r--r--arch/arm/include/asm/xen/hypercall.h7
-rw-r--r--arch/arm/include/asm/xen/interface.h3
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/paravirt.c25
-rw-r--r--arch/arm/xen/enlighten.c95
-rw-r--r--arch/arm/xen/hypercall.S1
-rw-r--r--arch/arm64/Kconfig20
-rw-r--r--arch/arm64/include/asm/paravirt.h20
-rw-r--r--arch/arm64/kernel/Makefile1
-rw-r--r--arch/arm64/kernel/paravirt.c25
-rw-r--r--arch/arm64/xen/hypercall.S1
-rw-r--r--arch/x86/include/asm/xen/hypercall.h6
-rw-r--r--arch/x86/xen/apic.c2
-rw-r--r--arch/x86/xen/enlighten.c8
-rw-r--r--arch/x86/xen/suspend.c3
-rw-r--r--arch/x86/xen/time.c115
-rw-r--r--drivers/xen/Makefile2
-rw-r--r--drivers/xen/acpi.c2
-rw-r--r--drivers/xen/efi.c30
-rw-r--r--drivers/xen/gntdev.c205
-rw-r--r--drivers/xen/grant-table.c4
-rw-r--r--drivers/xen/pcpu.c8
-rw-r--r--drivers/xen/time.c88
-rw-r--r--drivers/xen/xen-acpi-cpuhotplug.c2
-rw-r--r--drivers/xen/xen-acpi-pad.c4
-rw-r--r--drivers/xen/xen-acpi-processor.c8
-rw-r--r--drivers/xen/xenfs/xensyms.c4
-rw-r--r--include/uapi/xen/gntdev.h50
-rw-r--r--include/xen/interface/platform.h18
-rw-r--r--include/xen/interface/xen.h2
-rw-r--r--include/xen/xen-ops.h5
-rw-r--r--kernel/sched/cputime.c3
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
1824config IOMMU_HELPER 1824config IOMMU_HELPER
1825 def_bool SWIOTLB 1825 def_bool SWIOTLB
1826 1826
1827config 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
1834config 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
1827config XEN_DOM0 1846config 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
5struct static_key;
6extern struct static_key paravirt_steal_enabled;
7extern struct static_key paravirt_steal_rq_enabled;
8
9struct pv_time_ops {
10 unsigned long long (*steal_clock)(int cpu);
11};
12extern struct pv_time_ops pv_time_ops;
13
14static 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
39long privcmd_call(unsigned call, unsigned long a1, 40long 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);
49int HYPERVISOR_physdev_op(int cmd, void *arg); 50int HYPERVISOR_physdev_op(int cmd, void *arg);
50int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args); 51int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args);
51int HYPERVISOR_tmem_op(void *arg); 52int HYPERVISOR_tmem_op(void *arg);
53int HYPERVISOR_platform_op_raw(void *arg);
54static 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}
52int HYPERVISOR_multicall(struct multicall_entry *calls, uint32_t nr); 59int HYPERVISOR_multicall(struct multicall_entry *calls, uint32_t nr);
53 60
54static inline int 61static 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
81ifneq ($(CONFIG_ARCH_EBSA110),y) 81ifneq ($(CONFIG_ARCH_EBSA110),y)
82 obj-y += io.o 82 obj-y += io.o
83endif 83endif
84obj-$(CONFIG_PARAVIRT) += paravirt.o
84 85
85head-y := head$(MMUEXT).o 86head-y := head$(MMUEXT).o
86obj-$(CONFIG_DEBUG_LL) += debug.o 87obj-$(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
21struct static_key paravirt_steal_enabled;
22struct static_key paravirt_steal_rq_enabled;
23
24struct pv_time_ops pv_time_ops;
25EXPORT_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}
80EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range); 85EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range);
81 86
87static 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
100static 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
121static 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
160static struct notifier_block xen_pvclock_gtod_notifier = {
161 .notifier_call = xen_pvclock_gtod_notify,
162};
163
82static void xen_percpu_init(void) 164static 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
107after_register_vcpu_info: 191after_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(&paravirt_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}
276early_initcall(xen_guest_init); 365early_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);
307EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); 401EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
308EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op); 402EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);
309EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op); 403EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op);
404EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op);
310EXPORT_SYMBOL_GPL(HYPERVISOR_multicall); 405EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
311EXPORT_SYMBOL_GPL(privcmd_call); 406EXPORT_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);
89HYPERCALL2(physdev_op); 89HYPERCALL2(physdev_op);
90HYPERCALL3(vcpu_op); 90HYPERCALL3(vcpu_op);
91HYPERCALL1(tmem_op); 91HYPERCALL1(tmem_op);
92HYPERCALL1(platform_op_raw);
92HYPERCALL2(multicall); 93HYPERCALL2(multicall);
93 94
94ENTRY(privcmd_call) 95ENTRY(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
558config 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
565config 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
558config XEN_DOM0 577config 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
5struct static_key;
6extern struct static_key paravirt_steal_enabled;
7extern struct static_key paravirt_steal_rq_enabled;
8
9struct pv_time_ops {
10 unsigned long long (*steal_clock)(int cpu);
11};
12extern struct pv_time_ops pv_time_ops;
13
14static 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
41arm64-obj-$(CONFIG_PCI) += pci.o 41arm64-obj-$(CONFIG_PCI) += pci.o
42arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o 42arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
43arm64-obj-$(CONFIG_ACPI) += acpi.o 43arm64-obj-$(CONFIG_ACPI) += acpi.o
44arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o
44 45
45obj-y += $(arm64-obj-y) vdso/ 46obj-y += $(arm64-obj-y) vdso/
46obj-m += $(arm64-obj-m) 47obj-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
21struct static_key paravirt_steal_enabled;
22struct static_key paravirt_steal_rq_enabled;
23
24struct pv_time_ops pv_time_ops;
25EXPORT_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);
80HYPERCALL2(physdev_op); 80HYPERCALL2(physdev_op);
81HYPERCALL3(vcpu_op); 81HYPERCALL3(vcpu_op);
82HYPERCALL1(tmem_op); 82HYPERCALL1(tmem_op);
83HYPERCALL1(platform_op_raw);
83HYPERCALL2(multicall); 84HYPERCALL2(multicall);
84 85
85ENTRY(privcmd_call) 86ENTRY(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
312static inline int 312static inline int
313HYPERVISOR_dom0_op(struct xen_platform_op *platform_op) 313HYPERVISOR_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
319static inline int 319static 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 */
36static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate);
37
38/* snapshots of runstate info */ 36/* snapshots of runstate info */
39static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot); 37static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot);
40 38
41/* unused ns of stolen time */ 39/* unused ns of stolen time */
42static DEFINE_PER_CPU(u64, xen_residual_stolen); 40static DEFINE_PER_CPU(u64, xen_residual_stolen);
43 41
44/* return an consistent snapshot of 64-bit time/counter value */
45static 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 */
76static 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 */
99bool xen_vcpu_stolen(int vcpu)
100{
101 return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable;
102}
103
104void 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
115static void do_stolen_accounting(void) 42static 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; 142again:
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 @@
1obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o 1obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
2obj-$(CONFIG_X86) += fallback.o 2obj-$(CONFIG_X86) += fallback.o
3obj-y += grant-table.o features.o balloon.o manage.o preempt.o 3obj-y += grant-table.o features.o balloon.o manage.o preempt.o time.o
4obj-y += events/ 4obj-y += events/
5obj-y += xenbus/ 5obj-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
521static struct mmu_notifier_ops gntdev_mmu_ops = { 521static 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
753struct 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
761static 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
781static 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
790static 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
822static 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
915static 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(&copy, 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, &copy.segments[i], sizeof(seg))) {
932 ret = -EFAULT;
933 goto out;
934 }
935
936 ret = gntdev_grant_copy_seg(&batch, &seg, &copy.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
751static long gntdev_ioctl(struct file *flip, 951static 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
131static struct gnttab_ops *gnttab_interface; 131static const struct gnttab_ops *gnttab_interface;
132 132
133static int grant_table_version; 133static int grant_table_version;
134static int grefs_per_grant_frame; 134static 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
1016static struct gnttab_ops gnttab_v1_ops = { 1016static 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
84static int xen_pcpu_up(uint32_t cpu_id) 84static 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
95static ssize_t show_online(struct device *dev, 95static 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 */
19static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate);
20
21/* return an consistent snapshot of 64-bit time/counter value */
22static 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 */
52void 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 */
73bool xen_vcpu_stolen(int vcpu)
74{
75 return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable;
76}
77
78void 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
42static int xen_acpi_pad_idle_cpus_num(void) 42static 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
147struct 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))
192struct 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
39struct xenpf_settime { 39struct 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};
45DEFINE_GUEST_HANDLE_STRUCT(xenpf_settime_t); 45DEFINE_GUEST_HANDLE_STRUCT(xenpf_settime32_t);
46#define XENPF_settime64 62
47struct xenpf_settime64 {
48 /* IN variables. */
49 uint64_t secs;
50 uint32_t nsecs;
51 uint32_t mbz;
52 uint64_t system_time;
53};
54DEFINE_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
9DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); 10DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
10 11
@@ -18,6 +19,10 @@ void xen_arch_suspend(void);
18void xen_resume_notifier_register(struct notifier_block *nb); 19void xen_resume_notifier_register(struct notifier_block *nb);
19void xen_resume_notifier_unregister(struct notifier_block *nb); 20void xen_resume_notifier_unregister(struct notifier_block *nb);
20 21
22bool xen_vcpu_stolen(int vcpu);
23void xen_setup_runstate_info(int cpu);
24void xen_get_runstate_snapshot(struct vcpu_runstate_info *res);
25
21int xen_setup_shutdown_event(void); 26int xen_setup_shutdown_event(void);
22 27
23extern unsigned long *xen_contiguous_bitmap; 28extern 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