Skip to content

Commit e27c492

Browse files
arndbKAGA-KOKO
authored andcommitted
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
1 parent 06aa376 commit e27c492

File tree

10 files changed

+38
-31
lines changed

10 files changed

+38
-31
lines changed

arch/x86/include/asm/intel_mid_vrtc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
extern unsigned char vrtc_cmos_read(unsigned char reg);
66
extern void vrtc_cmos_write(unsigned char val, unsigned char reg);
7-
extern void vrtc_get_time(struct timespec *now);
8-
extern int vrtc_set_mmss(const struct timespec *now);
7+
extern void vrtc_get_time(struct timespec64 *now);
8+
extern int vrtc_set_mmss(const struct timespec64 *now);
99

1010
#endif

arch/x86/include/asm/mc146818rtc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ static inline unsigned char current_lock_cmos_reg(void)
9595
unsigned char rtc_cmos_read(unsigned char addr);
9696
void rtc_cmos_write(unsigned char val, unsigned char addr);
9797

98-
extern int mach_set_rtc_mmss(const struct timespec *now);
99-
extern void mach_get_cmos_time(struct timespec *now);
98+
extern int mach_set_rtc_mmss(const struct timespec64 *now);
99+
extern void mach_get_cmos_time(struct timespec64 *now);
100100

101101
#define RTC_IRQ 8
102102

arch/x86/include/asm/pvclock.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void pvclock_set_flags(u8 flags);
1212
unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
1313
void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
1414
struct pvclock_vcpu_time_info *vcpu,
15-
struct timespec *ts);
15+
struct timespec64 *ts);
1616
void pvclock_resume(void);
1717

1818
void pvclock_touch_watchdogs(void);

arch/x86/include/asm/x86_init.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ struct x86_cpuinit_ops {
170170
void (*fixup_cpu_id)(struct cpuinfo_x86 *c, int node);
171171
};
172172

173-
struct timespec;
173+
struct timespec64;
174174

175175
/**
176176
* struct x86_legacy_devices - legacy x86 devices
@@ -264,8 +264,8 @@ struct x86_hyper_runtime {
264264
struct x86_platform_ops {
265265
unsigned long (*calibrate_cpu)(void);
266266
unsigned long (*calibrate_tsc)(void);
267-
void (*get_wallclock)(struct timespec *ts);
268-
int (*set_wallclock)(const struct timespec *ts);
267+
void (*get_wallclock)(struct timespec64 *ts);
268+
int (*set_wallclock)(const struct timespec64 *ts);
269269
void (*iommu_shutdown)(void);
270270
bool (*is_untracked_pat_range)(u64 start, u64 end);
271271
void (*nmi_init)(void);

arch/x86/kernel/jailhouse.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static uint32_t __init jailhouse_detect(void)
3737
return jailhouse_cpuid_base();
3838
}
3939

40-
static void jailhouse_get_wallclock(struct timespec *now)
40+
static void jailhouse_get_wallclock(struct timespec64 *now)
4141
{
4242
memset(now, 0, sizeof(*now));
4343
}

arch/x86/kernel/kvmclock.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static struct pvclock_wall_clock *wall_clock;
5353
* have elapsed since the hypervisor wrote the data. So we try to account for
5454
* that with system time
5555
*/
56-
static void kvm_get_wallclock(struct timespec *now)
56+
static void kvm_get_wallclock(struct timespec64 *now)
5757
{
5858
struct pvclock_vcpu_time_info *vcpu_time;
5959
int low, high;
@@ -72,7 +72,7 @@ static void kvm_get_wallclock(struct timespec *now)
7272
put_cpu();
7373
}
7474

75-
static int kvm_set_wallclock(const struct timespec *now)
75+
static int kvm_set_wallclock(const struct timespec64 *now)
7676
{
7777
return -ENODEV;
7878
}

arch/x86/kernel/pvclock.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,28 +123,35 @@ u64 pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
123123

124124
void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock,
125125
struct pvclock_vcpu_time_info *vcpu_time,
126-
struct timespec *ts)
126+
struct timespec64 *ts)
127127
{
128128
u32 version;
129129
u64 delta;
130-
struct timespec now;
130+
struct timespec64 now;
131131

132132
/* get wallclock at system boot */
133133
do {
134134
version = wall_clock->version;
135135
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+
*/
136143
now.tv_sec = wall_clock->sec;
137144
now.tv_nsec = wall_clock->nsec;
138145
rmb(); /* fetch time before checking version */
139146
} while ((wall_clock->version & 1) || (version != wall_clock->version));
140147

141148
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;
143150

144151
now.tv_nsec = do_div(delta, NSEC_PER_SEC);
145152
now.tv_sec = delta;
146153

147-
set_normalized_timespec(ts, now.tv_sec, now.tv_nsec);
154+
set_normalized_timespec64(ts, now.tv_sec, now.tv_nsec);
148155
}
149156

150157
void pvclock_set_pvti_cpu0_va(struct pvclock_vsyscall_time_info *pvti)

arch/x86/kernel/rtc.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ EXPORT_SYMBOL(rtc_lock);
3939
* jump to the next second precisely 500 ms later. Check the Motorola
4040
* MC146818A or Dallas DS12887 data sheet for details.
4141
*/
42-
int mach_set_rtc_mmss(const struct timespec *now)
42+
int mach_set_rtc_mmss(const struct timespec64 *now)
4343
{
4444
unsigned long long nowtime = now->tv_sec;
4545
struct rtc_time tm;
@@ -60,7 +60,7 @@ int mach_set_rtc_mmss(const struct timespec *now)
6060
return retval;
6161
}
6262

63-
void mach_get_cmos_time(struct timespec *now)
63+
void mach_get_cmos_time(struct timespec64 *now)
6464
{
6565
unsigned int status, year, mon, day, hour, min, sec, century = 0;
6666
unsigned long flags;
@@ -118,7 +118,7 @@ void mach_get_cmos_time(struct timespec *now)
118118
} else
119119
year += CMOS_YEARS_OFFS;
120120

121-
now->tv_sec = mktime(year, mon, day, hour, min, sec);
121+
now->tv_sec = mktime64(year, mon, day, hour, min, sec);
122122
now->tv_nsec = 0;
123123
}
124124

@@ -145,13 +145,13 @@ void rtc_cmos_write(unsigned char val, unsigned char addr)
145145
}
146146
EXPORT_SYMBOL(rtc_cmos_write);
147147

148-
int update_persistent_clock(struct timespec now)
148+
int update_persistent_clock64(struct timespec64 now)
149149
{
150150
return x86_platform.set_wallclock(&now);
151151
}
152152

153153
/* not static: needed by APM */
154-
void read_persistent_clock(struct timespec *ts)
154+
void read_persistent_clock64(struct timespec64 *ts)
155155
{
156156
x86_platform.get_wallclock(ts);
157157
}

arch/x86/platform/intel-mid/intel_mid_vrtc.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ void vrtc_cmos_write(unsigned char val, unsigned char reg)
5757
}
5858
EXPORT_SYMBOL_GPL(vrtc_cmos_write);
5959

60-
void vrtc_get_time(struct timespec *now)
60+
void vrtc_get_time(struct timespec64 *now)
6161
{
6262
u8 sec, min, hour, mday, mon;
6363
unsigned long flags;
@@ -83,18 +83,18 @@ void vrtc_get_time(struct timespec *now)
8383
pr_info("vRTC: sec: %d min: %d hour: %d day: %d "
8484
"mon: %d year: %d\n", sec, min, hour, mday, mon, year);
8585

86-
now->tv_sec = mktime(year, mon, mday, hour, min, sec);
86+
now->tv_sec = mktime64(year, mon, mday, hour, min, sec);
8787
now->tv_nsec = 0;
8888
}
8989

90-
int vrtc_set_mmss(const struct timespec *now)
90+
int vrtc_set_mmss(const struct timespec64 *now)
9191
{
9292
unsigned long flags;
9393
struct rtc_time tm;
9494
int year;
9595
int retval = 0;
9696

97-
rtc_time_to_tm(now->tv_sec, &tm);
97+
rtc_time64_to_tm(now->tv_sec, &tm);
9898
if (!rtc_valid_tm(&tm) && tm.tm_year >= 72) {
9999
/*
100100
* tm.year is the number of years since 1900, and the
@@ -110,8 +110,8 @@ int vrtc_set_mmss(const struct timespec *now)
110110
vrtc_cmos_write(tm.tm_sec, RTC_SECONDS);
111111
spin_unlock_irqrestore(&rtc_lock, flags);
112112
} else {
113-
pr_err("%s: Invalid vRTC value: write of %lx to vRTC failed\n",
114-
__func__, now->tv_sec);
113+
pr_err("%s: Invalid vRTC value: write of %llx to vRTC failed\n",
114+
__func__, (s64)now->tv_sec);
115115
retval = -EINVAL;
116116
}
117117
return retval;

arch/x86/xen/time.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static u64 xen_clocksource_get_cycles(struct clocksource *cs)
5757
return xen_clocksource_read();
5858
}
5959

60-
static void xen_read_wallclock(struct timespec *ts)
60+
static void xen_read_wallclock(struct timespec64 *ts)
6161
{
6262
struct shared_info *s = HYPERVISOR_shared_info;
6363
struct pvclock_wall_clock *wall_clock = &(s->wc);
@@ -68,12 +68,12 @@ static void xen_read_wallclock(struct timespec *ts)
6868
put_cpu_var(xen_vcpu);
6969
}
7070

71-
static void xen_get_wallclock(struct timespec *now)
71+
static void xen_get_wallclock(struct timespec64 *now)
7272
{
7373
xen_read_wallclock(now);
7474
}
7575

76-
static int xen_set_wallclock(const struct timespec *now)
76+
static int xen_set_wallclock(const struct timespec64 *now)
7777
{
7878
return -ENODEV;
7979
}
@@ -461,7 +461,7 @@ static void __init xen_time_init(void)
461461
{
462462
struct pvclock_vcpu_time_info *pvti;
463463
int cpu = smp_processor_id();
464-
struct timespec tp;
464+
struct timespec64 tp;
465465

466466
/* As Dom0 is never moved, no penalty on using TSC there */
467467
if (xen_initial_domain())
@@ -479,7 +479,7 @@ static void __init xen_time_init(void)
479479

480480
/* Set initial system time with full resolution */
481481
xen_read_wallclock(&tp);
482-
do_settimeofday(&tp);
482+
do_settimeofday64(&tp);
483483

484484
setup_force_cpu_cap(X86_FEATURE_TSC);
485485

0 commit comments

Comments
 (0)