- balloon: don't crash in HVM-with-PoD guests.
[opensuse:kernel-source.git] / patches.xen / xen-x86_64-vread-pvclock
1 From: jbeulich@suse.com
2 Subject: use vCPU time info registration to support vread_pvclock()
3 Patch-mainline: n/a
4
5 Could be merged into the 3.8 merge patch, but conflicts heavily with
6 the later xen-clockevents changes.
7
8 --- 13.1.orig/arch/x86/Kconfig  2013-08-12 16:20:29.000000000 +0200
9 +++ 13.1/arch/x86/Kconfig       2013-08-12 16:21:44.000000000 +0200
10 @@ -381,6 +381,7 @@ config X86_64_XEN
11         bool "Enable Xen compatible kernel"
12         depends on X86_64
13         select XEN
14 +       select PARAVIRT_CLOCK
15         help
16           This option will compile a kernel compatible with Xen hypervisor
17  
18 @@ -696,11 +697,11 @@ config PARAVIRT_TIME_ACCOUNTING
19  
20           If in doubt, say N here.
21  
22 +endif #HYPERVISOR_GUEST
23 +
24  config PARAVIRT_CLOCK
25         bool
26  
27 -endif #HYPERVISOR_GUEST
28 -
29  config NO_BOOTMEM
30         def_bool y
31  
32 --- 13.1.orig/arch/x86/include/asm/pvclock.h    2014-02-10 16:07:57.000000000 +0100
33 +++ 13.1/arch/x86/include/asm/pvclock.h 2013-05-10 18:08:00.000000000 +0200
34 @@ -83,7 +83,11 @@ unsigned __pvclock_read_cycles(const str
35         rdtsc_barrier();
36         offset = pvclock_get_nsec_offset(src);
37         ret = src->system_time + offset;
38 +#ifndef CONFIG_XEN
39         ret_flags = src->flags;
40 +#else
41 +       ret_flags = PVCLOCK_TSC_STABLE_BIT;
42 +#endif
43         rdtsc_barrier();
44  
45         *cycles = ret;
46 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
47 +++ 13.1/arch/x86/include/mach-xen/asm/pvclock-abi.h    2013-05-14 08:22:22.000000000 +0200
48 @@ -0,0 +1,12 @@
49 +#ifndef _ASM_X86_PVCLOCK_ABI_H
50 +#define _ASM_X86_PVCLOCK_ABI_H
51 +#ifndef __ASSEMBLY__
52 +
53 +#include <xen/interface/xen.h>
54 +
55 +#define pvclock_vcpu_time_info vcpu_time_info
56 +struct pvclock_wall_clock; /* not used */
57 +
58 +#define PVCLOCK_TSC_STABLE_BIT (1 << 0)
59 +#endif /* __ASSEMBLY__ */
60 +#endif /* _ASM_X86_PVCLOCK_ABI_H */
61 --- 13.1.orig/arch/x86/kernel/pvclock.c 2014-02-10 16:07:57.000000000 +0100
62 +++ 13.1/arch/x86/kernel/pvclock.c      2013-05-10 17:20:32.000000000 +0200
63 @@ -24,6 +24,7 @@
64  #include <asm/fixmap.h>
65  #include <asm/pvclock.h>
66  
67 +#ifndef CONFIG_XEN
68  static u8 valid_flags __read_mostly = 0;
69  
70  void pvclock_set_flags(u8 flags)
71 @@ -127,6 +128,7 @@ void pvclock_read_wallclock(struct pvclo
72  
73         set_normalized_timespec(ts, now.tv_sec, now.tv_nsec);
74  }
75 +#endif /* !CONFIG_XEN */
76  
77  static struct pvclock_vsyscall_time_info *pvclock_vdso_info;
78  
79 --- 13.1.orig/arch/x86/kernel/time-xen.c        2013-08-12 16:20:11.000000000 +0200
80 +++ 13.1/arch/x86/kernel/time-xen.c     2014-02-10 16:27:13.000000000 +0100
81 @@ -31,6 +31,10 @@
82  #include <xen/interface/vcpu.h>
83  
84  #ifdef CONFIG_X86_64
85 +#include <asm/pvclock.h>
86 +#include <asm/vgtod.h>
87 +
88 +struct pvclock_vsyscall_time_info *__read_mostly pvclock_vsyscall_time;
89  DEFINE_VVAR(volatile unsigned long, jiffies) = INITIAL_JIFFIES;
90  #endif
91  
92 @@ -504,8 +508,42 @@ void setup_runstate_area(unsigned int cp
93         }
94  }
95  
96 +void setup_vsyscall_time_area(unsigned int cpu)
97 +{
98 +#ifdef CONFIG_X86_64
99 +       if (pvclock_vsyscall_time) {
100 +               struct vcpu_register_time_memory_area area = {
101 +                       .addr.v = &pvclock_vsyscall_time[cpu].pvti
102 +               };
103 +
104 +               if (HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_time_memory_area,
105 +                                      cpu, &area)) {
106 +                       clocksource_xen.archdata.vclock_mode = VCLOCK_NONE;
107 +                       vsyscall_gtod_data.clock.vclock_mode = VCLOCK_NONE;
108 +               }
109 +       }
110 +#endif
111 +}
112 +
113  static void __init _late_time_init(void)
114  {
115 +#ifdef CONFIG_X86_64
116 +       unsigned int size = ALIGN(PVTI_SIZE * NR_CPUS, PAGE_SIZE);
117 +       struct pvclock_vsyscall_time_info *array
118 +               = alloc_pages_exact(size, GFP_KERNEL);
119 +       struct vcpu_register_time_memory_area area = {
120 +               .addr.v = &array->pvti
121 +       };
122 +
123 +       if (array && pvclock_init_vsyscall(array, size) == 0
124 +           && HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_time_memory_area,
125 +                                 0, &area) == 0) {
126 +               pvclock_vsyscall_time = array;
127 +               clocksource_xen.archdata.vclock_mode = VCLOCK_PVCLOCK;
128 +               vsyscall_gtod_data.clock.vclock_mode = VCLOCK_PVCLOCK;
129 +       } else if (area.addr.v)
130 +               free_pages_exact(array, size);
131 +#endif
132         update_wallclock();
133         xen_clockevents_init();
134  }
135 --- 13.1.orig/arch/x86/mm/pgtable-xen.c 2013-04-26 11:41:06.000000000 +0200
136 +++ 13.1/arch/x86/mm/pgtable-xen.c      2013-08-12 16:21:39.000000000 +0200
137 @@ -961,6 +961,7 @@ void xen_set_fixmap(enum fixed_addresses
138  
139         case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE:
140         case VVAR_PAGE:
141 +       case PVCLOCK_FIXMAP_BEGIN ... PVCLOCK_FIXMAP_END:
142                 pte = pfn_pte(phys >> PAGE_SHIFT, flags);
143                 set_pte_vaddr_pud(level3_user_pgt, address, pte);
144                 break;
145 --- 13.1.orig/arch/x86/vdso/vclock_gettime.c    2013-03-21 15:31:34.000000000 +0100
146 +++ 13.1/arch/x86/vdso/vclock_gettime.c 2013-05-14 09:12:44.000000000 +0200
147 @@ -26,9 +26,7 @@
148  
149  #define gtod (&VVAR(vsyscall_gtod_data))
150  
151 -#ifdef CONFIG_XEN
152 -#define VCLOCK_NONE 0
153 -#else
154 +#ifndef CONFIG_XEN
155  notrace static cycle_t vread_tsc(void)
156  {
157         cycle_t ret;
158 @@ -155,21 +153,29 @@ notrace static long vdso_fallback_gtod(s
159  }
160  
161  
162 -#ifndef CONFIG_XEN
163  notrace static inline u64 vgetsns(int *mode)
164  {
165         long v;
166         cycles_t cycles;
167 -       if (gtod->clock.vclock_mode == VCLOCK_TSC)
168 +
169 +       switch (*mode) {
170 +#ifndef CONFIG_XEN
171 +       case VCLOCK_TSC:
172                 cycles = vread_tsc();
173 -       else if (gtod->clock.vclock_mode == VCLOCK_HPET)
174 +               break;
175 +       case VCLOCK_HPET:
176                 cycles = vread_hpet();
177 +               break;
178 +#endif
179  #ifdef CONFIG_PARAVIRT_CLOCK
180 -       else if (gtod->clock.vclock_mode == VCLOCK_PVCLOCK)
181 +       case VCLOCK_PVCLOCK:
182                 cycles = vread_pvclock(mode);
183 +               break;
184  #endif
185 -       else
186 +       default:
187 +               *mode = VCLOCK_NONE;
188                 return 0;
189 +       }
190         v = (cycles - gtod->clock.cycle_last) & gtod->clock.mask;
191         return v * gtod->clock.mult;
192  }
193 @@ -214,7 +220,6 @@ notrace static int do_monotonic(struct t
194  
195         return mode;
196  }
197 -#endif /* CONFIG_XEN */
198  
199  notrace static int do_realtime_coarse(struct timespec *ts)
200  {
201 @@ -244,14 +249,12 @@ notrace int __vdso_clock_gettime(clockid
202         int ret = VCLOCK_NONE;
203  
204         switch (clock) {
205 -#ifndef CONFIG_XEN
206         case CLOCK_REALTIME:
207                 ret = do_realtime(ts);
208                 break;
209         case CLOCK_MONOTONIC:
210                 ret = do_monotonic(ts);
211                 break;
212 -#endif
213         case CLOCK_REALTIME_COARSE:
214                 return do_realtime_coarse(ts);
215         case CLOCK_MONOTONIC_COARSE:
216 --- 13.1.orig/drivers/xen/core/machine_reboot.c 2011-11-18 17:18:17.000000000 +0100
217 +++ 13.1/drivers/xen/core/machine_reboot.c      2013-05-10 17:55:57.000000000 +0200
218 @@ -100,6 +100,9 @@ static void post_suspend(int suspend_can
219                             && HYPERVISOR_vcpu_op(VCPUOP_up, i, NULL))
220                                 BUG();
221  #endif
222 +
223 +                       if (cpu_online(i))
224 +                               setup_vsyscall_time_area(i);
225                 }
226         }
227  
228 --- 13.1.orig/drivers/xen/core/smpboot.c        2013-08-12 16:19:37.000000000 +0200
229 +++ 13.1/drivers/xen/core/smpboot.c     2013-08-12 16:21:48.000000000 +0200
230 @@ -337,6 +337,8 @@ int __cpu_up(unsigned int cpu, struct ta
231         if (rc)
232                 return rc;
233  
234 +       setup_vsyscall_time_area(cpu);
235 +
236         rc = xen_smp_intr_init(cpu);
237         if (rc)
238                 return rc;
239 --- 13.1.orig/include/xen/clock.h       2013-03-05 13:44:28.000000000 +0100
240 +++ 13.1/include/xen/clock.h    2013-05-10 17:53:29.000000000 +0200
241 @@ -3,6 +3,9 @@
242  
243  void setup_runstate_area(unsigned int cpu);
244  
245 +extern struct pvclock_vsyscall_time_info *pvclock_vsyscall_time;
246 +void setup_vsyscall_time_area(unsigned int cpu);
247 +
248  unsigned long long xen_local_clock(void);
249  void xen_check_wallclock_update(void);
250