aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2018-04-27 16:13:23 -0400
committerThomas Gleixner <tglx@linutronix.de>2018-05-19 08:03:14 -0400
commite27c49291a7fe9dc415c9fcab5bd781ec82dfe04 (patch)
tree008966041f82225a331bbb55bed874e82f367fcd
parent06aa376903b6e8c8741395a4702d78d47c7c27c6 (diff)
x86: Convert x86_platform_ops to timespec64
The x86 platform operations are fairly isolated, so it's easy to change them from using timespec to timespec64. It has been checked that all the users and callers are safe, and there is only one critical function that is broken beyond 2106: pvclock_read_wallclock() uses a 32-bit number of seconds since the epoch to communicate the boot time between host and guest in a virtual environment. This will work until 2106, but fixing this is outside the scope of this change, Add a comment at least. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Acked-by: Radim Krčmář <rkrcmar@redhat.com> Acked-by: Jan Kiszka <jan.kiszka@siemens.com> Cc: Juergen Gross <jgross@suse.com> Cc: jailhouse-dev@googlegroups.com Cc: Borislav Petkov <bp@suse.de> Cc: kvm@vger.kernel.org Cc: y2038@lists.linaro.org Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Cc: xen-devel@lists.xenproject.org Cc: John Stultz <john.stultz@linaro.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Joao Martins <joao.m.martins@oracle.com> Link: https://lkml.kernel.org/r/20180427201435.3194219-1-arnd@arndb.de
-rw-r--r--arch/x86/include/asm/intel_mid_vrtc.h4
-rw-r--r--arch/x86/include/asm/mc146818rtc.h4
-rw-r--r--arch/x86/include/asm/pvclock.h2
-rw-r--r--arch/x86/include/asm/x86_init.h6
-rw-r--r--arch/x86/kernel/jailhouse.c2
-rw-r--r--arch/x86/kernel/kvmclock.c4
-rw-r--r--arch/x86/kernel/pvclock.c15
-rw-r--r--arch/x86/kernel/rtc.c10
-rw-r--r--arch/x86/platform/intel-mid/intel_mid_vrtc.c12
-rw-r--r--arch/x86/xen/time.c10
10 files changed, 38 insertions, 31 deletions
diff --git a/arch/x86/include/asm/intel_mid_vrtc.h b/arch/x86/include/asm/intel_mid_vrtc.h
index 35555016b1be..0b44b1abe4d9 100644
--- a/arch/x86/include/asm/intel_mid_vrtc.h
+++ b/arch/x86/include/asm/intel_mid_vrtc.h
@@ -4,7 +4,7 @@
4 4
5extern unsigned char vrtc_cmos_read(unsigned char reg); 5extern unsigned char vrtc_cmos_read(unsigned char reg);
6extern void vrtc_cmos_write(unsigned char val, unsigned char reg); 6extern void vrtc_cmos_write(unsigned char val, unsigned char reg);
7extern void vrtc_get_time(struct timespec *now); 7extern void vrtc_get_time(struct timespec64 *now);
8extern int vrtc_set_mmss(const struct timespec *now); 8extern int vrtc_set_mmss(const struct timespec64 *now);
9 9
10#endif 10#endif
diff --git a/arch/x86/include/asm/mc146818rtc.h b/arch/x86/include/asm/mc146818rtc.h
index 1775a32f7ea6..97198001e567 100644
--- a/arch/x86/include/asm/mc146818rtc.h
+++ b/arch/x86/include/asm/mc146818rtc.h
@@ -95,8 +95,8 @@ static inline unsigned char current_lock_cmos_reg(void)
95unsigned char rtc_cmos_read(unsigned char addr); 95unsigned char rtc_cmos_read(unsigned char addr);
96void rtc_cmos_write(unsigned char val, unsigned char addr); 96void rtc_cmos_write(unsigned char val, unsigned char addr);
97 97
98extern int mach_set_rtc_mmss(const struct timespec *now); 98extern int mach_set_rtc_mmss(const struct timespec64 *now);
99extern void mach_get_cmos_time(struct timespec *now); 99extern void mach_get_cmos_time(struct timespec64 *now);
100 100
101#define RTC_IRQ 8 101#define RTC_IRQ 8
102 102
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
index a7471dcd2205..b6033680d458 100644
--- a/arch/x86/include/asm/pvclock.h
+++ b/arch/x86/include/asm/pvclock.h
@@ -12,7 +12,7 @@ void pvclock_set_flags(u8 flags);
12unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src); 12unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
13void pvclock_read_wallclock(struct pvclock_wall_clock *wall, 13void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
14 struct pvclock_vcpu_time_info *vcpu, 14 struct pvclock_vcpu_time_info *vcpu,
15 struct timespec *ts); 15 struct timespec64 *ts);
16void pvclock_resume(void); 16void pvclock_resume(void);
17 17
18void pvclock_touch_watchdogs(void); 18void pvclock_touch_watchdogs(void);
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index ce8b4da07e35..2d27236c16a3 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -170,7 +170,7 @@ struct x86_cpuinit_ops {
170 void (*fixup_cpu_id)(struct cpuinfo_x86 *c, int node); 170 void (*fixup_cpu_id)(struct cpuinfo_x86 *c, int node);
171}; 171};
172 172
173struct timespec; 173struct timespec64;
174 174
175/** 175/**
176 * struct x86_legacy_devices - legacy x86 devices 176 * struct x86_legacy_devices - legacy x86 devices
@@ -264,8 +264,8 @@ struct x86_hyper_runtime {
264struct x86_platform_ops { 264struct x86_platform_ops {
265 unsigned long (*calibrate_cpu)(void); 265 unsigned long (*calibrate_cpu)(void);
266 unsigned long (*calibrate_tsc)(void); 266 unsigned long (*calibrate_tsc)(void);
267 void (*get_wallclock)(struct timespec *ts); 267 void (*get_wallclock)(struct timespec64 *ts);
268 int (*set_wallclock)(const struct timespec *ts); 268 int (*set_wallclock)(const struct timespec64 *ts);
269 void (*iommu_shutdown)(void); 269 void (*iommu_shutdown)(void);
270 bool (*is_untracked_pat_range)(u64 start, u64 end); 270 bool (*is_untracked_pat_range)(u64 start, u64 end);
271 void (*nmi_init)(void); 271 void (*nmi_init)(void);
diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c
index a15fe0e92cf9..108c48d0d40e 100644
--- a/arch/x86/kernel/jailhouse.c
+++ b/arch/x86/kernel/jailhouse.c
@@ -37,7 +37,7 @@ static uint32_t __init jailhouse_detect(void)
37 return jailhouse_cpuid_base(); 37 return jailhouse_cpuid_base();
38} 38}
39 39
40static void jailhouse_get_wallclock(struct timespec *now) 40static void jailhouse_get_wallclock(struct timespec64 *now)
41{ 41{
42 memset(now, 0, sizeof(*now)); 42 memset(now, 0, sizeof(*now));
43} 43}
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 8b26c9e01cc4..bf8d1eb7fca3 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -53,7 +53,7 @@ static struct pvclock_wall_clock *wall_clock;
53 * have elapsed since the hypervisor wrote the data. So we try to account for 53 * have elapsed since the hypervisor wrote the data. So we try to account for
54 * that with system time 54 * that with system time
55 */ 55 */
56static void kvm_get_wallclock(struct timespec *now) 56static void kvm_get_wallclock(struct timespec64 *now)
57{ 57{
58 struct pvclock_vcpu_time_info *vcpu_time; 58 struct pvclock_vcpu_time_info *vcpu_time;
59 int low, high; 59 int low, high;
@@ -72,7 +72,7 @@ static void kvm_get_wallclock(struct timespec *now)
72 put_cpu(); 72 put_cpu();
73} 73}
74 74
75static int kvm_set_wallclock(const struct timespec *now) 75static int kvm_set_wallclock(const struct timespec64 *now)
76{ 76{
77 return -ENODEV; 77 return -ENODEV;
78} 78}
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index 761f6af6efa5..637982efecd8 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -123,28 +123,35 @@ u64 pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
123 123
124void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock, 124void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock,
125 struct pvclock_vcpu_time_info *vcpu_time, 125 struct pvclock_vcpu_time_info *vcpu_time,
126 struct timespec *ts) 126 struct timespec64 *ts)
127{ 127{
128 u32 version; 128 u32 version;
129 u64 delta; 129 u64 delta;
130 struct timespec now; 130 struct timespec64 now;
131 131
132 /* get wallclock at system boot */ 132 /* get wallclock at system boot */
133 do { 133 do {
134 version = wall_clock->version; 134 version = wall_clock->version;
135 rmb(); /* fetch version before time */ 135 rmb(); /* fetch version before time */
136 /*
137 * Note: wall_clock->sec is a u32 value, so it can
138 * only store dates between 1970 and 2106. To allow
139 * times beyond that, we need to create a new hypercall
140 * interface with an extended pvclock_wall_clock structure
141 * like ARM has.
142 */
136 now.tv_sec = wall_clock->sec; 143 now.tv_sec = wall_clock->sec;
137 now.tv_nsec = wall_clock->nsec; 144 now.tv_nsec = wall_clock->nsec;
138 rmb(); /* fetch time before checking version */ 145 rmb(); /* fetch time before checking version */
139 } while ((wall_clock->version & 1) || (version != wall_clock->version)); 146 } while ((wall_clock->version & 1) || (version != wall_clock->version));
140 147
141 delta = pvclock_clocksource_read(vcpu_time); /* time since system boot */ 148 delta = pvclock_clocksource_read(vcpu_time); /* time since system boot */
142 delta += now.tv_sec * (u64)NSEC_PER_SEC + now.tv_nsec; 149 delta += now.tv_sec * NSEC_PER_SEC + now.tv_nsec;
143 150
144 now.tv_nsec = do_div(delta, NSEC_PER_SEC); 151 now.tv_nsec = do_div(delta, NSEC_PER_SEC);
145 now.tv_sec = delta; 152 now.tv_sec = delta;
146 153
147 set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); 154 set_normalized_timespec64(ts, now.tv_sec, now.tv_nsec);
148} 155}
149 156
150void pvclock_set_pvti_cpu0_va(struct pvclock_vsyscall_time_info *pvti) 157void pvclock_set_pvti_cpu0_va(struct pvclock_vsyscall_time_info *pvti)
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index f7b82ed7b5b5..586f718b8e95 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -39,7 +39,7 @@ EXPORT_SYMBOL(rtc_lock);
39 * jump to the next second precisely 500 ms later. Check the Motorola 39 * jump to the next second precisely 500 ms later. Check the Motorola
40 * MC146818A or Dallas DS12887 data sheet for details. 40 * MC146818A or Dallas DS12887 data sheet for details.
41 */ 41 */
42int mach_set_rtc_mmss(const struct timespec *now) 42int mach_set_rtc_mmss(const struct timespec64 *now)
43{ 43{
44 unsigned long long nowtime = now->tv_sec; 44 unsigned long long nowtime = now->tv_sec;
45 struct rtc_time tm; 45 struct rtc_time tm;
@@ -60,7 +60,7 @@ int mach_set_rtc_mmss(const struct timespec *now)
60 return retval; 60 return retval;
61} 61}
62 62
63void mach_get_cmos_time(struct timespec *now) 63void mach_get_cmos_time(struct timespec64 *now)
64{ 64{
65 unsigned int status, year, mon, day, hour, min, sec, century = 0; 65 unsigned int status, year, mon, day, hour, min, sec, century = 0;
66 unsigned long flags; 66 unsigned long flags;
@@ -118,7 +118,7 @@ void mach_get_cmos_time(struct timespec *now)
118 } else 118 } else
119 year += CMOS_YEARS_OFFS; 119 year += CMOS_YEARS_OFFS;
120 120
121 now->tv_sec = mktime(year, mon, day, hour, min, sec); 121 now->tv_sec = mktime64(year, mon, day, hour, min, sec);
122 now->tv_nsec = 0; 122 now->tv_nsec = 0;
123} 123}
124 124
@@ -145,13 +145,13 @@ void rtc_cmos_write(unsigned char val, unsigned char addr)
145} 145}
146EXPORT_SYMBOL(rtc_cmos_write); 146EXPORT_SYMBOL(rtc_cmos_write);
147 147
148int update_persistent_clock(struct timespec now) 148int update_persistent_clock64(struct timespec64 now)
149{ 149{
150 return x86_platform.set_wallclock(&now); 150 return x86_platform.set_wallclock(&now);
151} 151}
152 152
153/* not static: needed by APM */ 153/* not static: needed by APM */
154void read_persistent_clock(struct timespec *ts) 154void read_persistent_clock64(struct timespec64 *ts)
155{ 155{
156 x86_platform.get_wallclock(ts); 156 x86_platform.get_wallclock(ts);
157} 157}
diff --git a/arch/x86/platform/intel-mid/intel_mid_vrtc.c b/arch/x86/platform/intel-mid/intel_mid_vrtc.c
index 58024862a7eb..a52914aa3b6c 100644
--- a/arch/x86/platform/intel-mid/intel_mid_vrtc.c
+++ b/arch/x86/platform/intel-mid/intel_mid_vrtc.c
@@ -57,7 +57,7 @@ void vrtc_cmos_write(unsigned char val, unsigned char reg)
57} 57}
58EXPORT_SYMBOL_GPL(vrtc_cmos_write); 58EXPORT_SYMBOL_GPL(vrtc_cmos_write);
59 59
60void vrtc_get_time(struct timespec *now) 60void vrtc_get_time(struct timespec64 *now)
61{ 61{
62 u8 sec, min, hour, mday, mon; 62 u8 sec, min, hour, mday, mon;
63 unsigned long flags; 63 unsigned long flags;
@@ -83,18 +83,18 @@ void vrtc_get_time(struct timespec *now)
83 pr_info("vRTC: sec: %d min: %d hour: %d day: %d " 83 pr_info("vRTC: sec: %d min: %d hour: %d day: %d "
84 "mon: %d year: %d\n", sec, min, hour, mday, mon, year); 84 "mon: %d year: %d\n", sec, min, hour, mday, mon, year);
85 85
86 now->tv_sec = mktime(year, mon, mday, hour, min, sec); 86 now->tv_sec = mktime64(year, mon, mday, hour, min, sec);
87 now->tv_nsec = 0; 87 now->tv_nsec = 0;
88} 88}
89 89
90int vrtc_set_mmss(const struct timespec *now) 90int vrtc_set_mmss(const struct timespec64 *now)
91{ 91{
92 unsigned long flags; 92 unsigned long flags;
93 struct rtc_time tm; 93 struct rtc_time tm;
94 int year; 94 int year;
95 int retval = 0; 95 int retval = 0;
96 96
97 rtc_time_to_tm(now->tv_sec, &tm); 97 rtc_time64_to_tm(now->tv_sec, &tm);
98 if (!rtc_valid_tm(&tm) && tm.tm_year >= 72) { 98 if (!rtc_valid_tm(&tm) && tm.tm_year >= 72) {
99 /* 99 /*
100 * tm.year is the number of years since 1900, and the 100 * tm.year is the number of years since 1900, and the
@@ -110,8 +110,8 @@ int vrtc_set_mmss(const struct timespec *now)
110 vrtc_cmos_write(tm.tm_sec, RTC_SECONDS); 110 vrtc_cmos_write(tm.tm_sec, RTC_SECONDS);
111 spin_unlock_irqrestore(&rtc_lock, flags); 111 spin_unlock_irqrestore(&rtc_lock, flags);
112 } else { 112 } else {
113 pr_err("%s: Invalid vRTC value: write of %lx to vRTC failed\n", 113 pr_err("%s: Invalid vRTC value: write of %llx to vRTC failed\n",
114 __func__, now->tv_sec); 114 __func__, (s64)now->tv_sec);
115 retval = -EINVAL; 115 retval = -EINVAL;
116 } 116 }
117 return retval; 117 return retval;
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 29163c43ebbd..e0f1bcf01d63 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -57,7 +57,7 @@ static u64 xen_clocksource_get_cycles(struct clocksource *cs)
57 return xen_clocksource_read(); 57 return xen_clocksource_read();
58} 58}
59 59
60static void xen_read_wallclock(struct timespec *ts) 60static void xen_read_wallclock(struct timespec64 *ts)
61{ 61{
62 struct shared_info *s = HYPERVISOR_shared_info; 62 struct shared_info *s = HYPERVISOR_shared_info;
63 struct pvclock_wall_clock *wall_clock = &(s->wc); 63 struct pvclock_wall_clock *wall_clock = &(s->wc);
@@ -68,12 +68,12 @@ static void xen_read_wallclock(struct timespec *ts)
68 put_cpu_var(xen_vcpu); 68 put_cpu_var(xen_vcpu);
69} 69}
70 70
71static void xen_get_wallclock(struct timespec *now) 71static void xen_get_wallclock(struct timespec64 *now)
72{ 72{
73 xen_read_wallclock(now); 73 xen_read_wallclock(now);
74} 74}
75 75
76static int xen_set_wallclock(const struct timespec *now) 76static int xen_set_wallclock(const struct timespec64 *now)
77{ 77{
78 return -ENODEV; 78 return -ENODEV;
79} 79}
@@ -461,7 +461,7 @@ static void __init xen_time_init(void)
461{ 461{
462 struct pvclock_vcpu_time_info *pvti; 462 struct pvclock_vcpu_time_info *pvti;
463 int cpu = smp_processor_id(); 463 int cpu = smp_processor_id();
464 struct timespec tp; 464 struct timespec64 tp;
465 465
466 /* As Dom0 is never moved, no penalty on using TSC there */ 466 /* As Dom0 is never moved, no penalty on using TSC there */
467 if (xen_initial_domain()) 467 if (xen_initial_domain())
@@ -479,7 +479,7 @@ static void __init xen_time_init(void)
479 479
480 /* Set initial system time with full resolution */ 480 /* Set initial system time with full resolution */
481 xen_read_wallclock(&tp); 481 xen_read_wallclock(&tp);
482 do_settimeofday(&tp); 482 do_settimeofday64(&tp);
483 483
484 setup_force_cpu_cap(X86_FEATURE_TSC); 484 setup_force_cpu_cap(X86_FEATURE_TSC);
485 485