aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kernel/early.c3
-rw-r--r--arch/s390/kernel/time.c38
-rw-r--r--arch/s390/kvm/interrupt.c2
-rw-r--r--arch/s390/kvm/sigp.c7
4 files changed, 18 insertions, 32 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 8d15314381e0..cae14c499511 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -208,6 +208,9 @@ static noinline __init void detect_machine_type(void)
208 machine_flags |= MACHINE_FLAG_KVM; 208 machine_flags |= MACHINE_FLAG_KVM;
209 else 209 else
210 machine_flags |= MACHINE_FLAG_VM; 210 machine_flags |= MACHINE_FLAG_VM;
211
212 /* Store machine flags for setting up lowcore early */
213 S390_lowcore.machine_flags = machine_flags;
211} 214}
212 215
213static __init void early_pgm_check_handler(void) 216static __init void early_pgm_check_handler(void)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index d4c8e9c47c81..6bff1a1d9060 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -182,12 +182,14 @@ static void timing_alert_interrupt(__u16 code)
182static void etr_reset(void); 182static void etr_reset(void);
183static void stp_reset(void); 183static void stp_reset(void);
184 184
185unsigned long read_persistent_clock(void) 185void read_persistent_clock(struct timespec *ts)
186{ 186{
187 struct timespec ts; 187 tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, ts);
188}
188 189
189 tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, &ts); 190void read_boot_clock(struct timespec *ts)
190 return ts.tv_sec; 191{
192 tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, ts);
191} 193}
192 194
193static cycle_t read_tod_clock(struct clocksource *cs) 195static cycle_t read_tod_clock(struct clocksource *cs)
@@ -205,6 +207,10 @@ static struct clocksource clocksource_tod = {
205 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 207 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
206}; 208};
207 209
210struct clocksource * __init clocksource_default_clock(void)
211{
212 return &clocksource_tod;
213}
208 214
209void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) 215void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
210{ 216{
@@ -242,10 +248,6 @@ void update_vsyscall_tz(void)
242 */ 248 */
243void __init time_init(void) 249void __init time_init(void)
244{ 250{
245 struct timespec ts;
246 unsigned long flags;
247 cycle_t now;
248
249 /* Reset time synchronization interfaces. */ 251 /* Reset time synchronization interfaces. */
250 etr_reset(); 252 etr_reset();
251 stp_reset(); 253 stp_reset();
@@ -261,26 +263,6 @@ void __init time_init(void)
261 if (clocksource_register(&clocksource_tod) != 0) 263 if (clocksource_register(&clocksource_tod) != 0)
262 panic("Could not register TOD clock source"); 264 panic("Could not register TOD clock source");
263 265
264 /*
265 * The TOD clock is an accurate clock. The xtime should be
266 * initialized in a way that the difference between TOD and
267 * xtime is reasonably small. Too bad that timekeeping_init
268 * sets xtime.tv_nsec to zero. In addition the clock source
269 * change from the jiffies clock source to the TOD clock
270 * source add another error of up to 1/HZ second. The same
271 * function sets wall_to_monotonic to a value that is too
272 * small for /proc/uptime to be accurate.
273 * Reset xtime and wall_to_monotonic to sane values.
274 */
275 write_seqlock_irqsave(&xtime_lock, flags);
276 now = get_clock();
277 tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime);
278 clocksource_tod.cycle_last = now;
279 clocksource_tod.raw_time = xtime;
280 tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts);
281 set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec);
282 write_sequnlock_irqrestore(&xtime_lock, flags);
283
284 /* Enable TOD clock interrupts on the boot cpu. */ 266 /* Enable TOD clock interrupts on the boot cpu. */
285 init_cpu_timer(); 267 init_cpu_timer();
286 268
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index f04f5301b1b4..4d613415c435 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -386,7 +386,7 @@ no_timer:
386 } 386 }
387 __unset_cpu_idle(vcpu); 387 __unset_cpu_idle(vcpu);
388 __set_current_state(TASK_RUNNING); 388 __set_current_state(TASK_RUNNING);
389 remove_wait_queue(&vcpu->wq, &wait); 389 remove_wait_queue(&vcpu->arch.local_int.wq, &wait);
390 spin_unlock_bh(&vcpu->arch.local_int.lock); 390 spin_unlock_bh(&vcpu->arch.local_int.lock);
391 spin_unlock(&vcpu->arch.local_int.float_int->lock); 391 spin_unlock(&vcpu->arch.local_int.float_int->lock);
392 hrtimer_try_to_cancel(&vcpu->arch.ckc_timer); 392 hrtimer_try_to_cancel(&vcpu->arch.ckc_timer);
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 36678835034d..0ef81d6776e9 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -169,7 +169,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
169 unsigned long *reg) 169 unsigned long *reg)
170{ 170{
171 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 171 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
172 struct kvm_s390_local_interrupt *li; 172 struct kvm_s390_local_interrupt *li = NULL;
173 struct kvm_s390_interrupt_info *inti; 173 struct kvm_s390_interrupt_info *inti;
174 int rc; 174 int rc;
175 u8 tmp; 175 u8 tmp;
@@ -189,9 +189,10 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
189 return 2; /* busy */ 189 return 2; /* busy */
190 190
191 spin_lock(&fi->lock); 191 spin_lock(&fi->lock);
192 li = fi->local_int[cpu_addr]; 192 if (cpu_addr < KVM_MAX_VCPUS)
193 li = fi->local_int[cpu_addr];
193 194
194 if ((cpu_addr >= KVM_MAX_VCPUS) || (li == NULL)) { 195 if (li == NULL) {
195 rc = 1; /* incorrect state */ 196 rc = 1; /* incorrect state */
196 *reg &= SIGP_STAT_INCORRECT_STATE; 197 *reg &= SIGP_STAT_INCORRECT_STATE;
197 kfree(inti); 198 kfree(inti);