diff --git a/[refs] b/[refs] index 5db4d464a6b4..b976faa6e46e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 17c38b7490b3f0300c7812aefdae2ddda7ab4112 +refs/heads/master: b0fcd903e6f3f47189baddf3fe085bdf78c9644c diff --git a/trunk/drivers/kvm/kvm_main.c b/trunk/drivers/kvm/kvm_main.c index bcbe6835beb4..a0a3fddba815 100644 --- a/trunk/drivers/kvm/kvm_main.c +++ b/trunk/drivers/kvm/kvm_main.c @@ -1078,10 +1078,10 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, return 1; } -static int emulator_write_emulated(unsigned long addr, - const void *val, - unsigned int bytes, - struct x86_emulate_ctxt *ctxt) +static int emulator_write_emulated_onepage(unsigned long addr, + const void *val, + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) { struct kvm_vcpu *vcpu = ctxt->vcpu; struct kvm_io_device *mmio_dev; @@ -1113,6 +1113,26 @@ static int emulator_write_emulated(unsigned long addr, return X86EMUL_CONTINUE; } +static int emulator_write_emulated(unsigned long addr, + const void *val, + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) +{ + /* Crossing a page boundary? */ + if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { + int rc, now; + + now = -addr & ~PAGE_MASK; + rc = emulator_write_emulated_onepage(addr, val, now, ctxt); + if (rc != X86EMUL_CONTINUE) + return rc; + addr += now; + val += now; + bytes -= now; + } + return emulator_write_emulated_onepage(addr, val, bytes, ctxt); +} + static int emulator_cmpxchg_emulated(unsigned long addr, const void *old, const void *new, diff --git a/trunk/drivers/rtc/class.c b/trunk/drivers/rtc/class.c index 10ab3b71ffc6..8b3cd31d6a61 100644 --- a/trunk/drivers/rtc/class.c +++ b/trunk/drivers/rtc/class.c @@ -46,7 +46,6 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg) { struct rtc_device *rtc = to_rtc_device(dev); struct rtc_time tm; - struct timespec ts = current_kernel_time(); if (strncmp(rtc->dev.bus_id, CONFIG_RTC_HCTOSYS_DEVICE, @@ -58,8 +57,8 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg) /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */ set_normalized_timespec(&delta, - ts.tv_sec - oldtime, - ts.tv_nsec - (NSEC_PER_SEC >> 1)); + xtime.tv_sec - oldtime, + xtime.tv_nsec - (NSEC_PER_SEC >> 1)); return 0; } diff --git a/trunk/drivers/s390/net/ctcmain.c b/trunk/drivers/s390/net/ctcmain.c index 92e8a37b5022..b20fd0681733 100644 --- a/trunk/drivers/s390/net/ctcmain.c +++ b/trunk/drivers/s390/net/ctcmain.c @@ -674,7 +674,7 @@ ch_action_txdone(fsm_instance * fi, int event, void *arg) int first = 1; int i; unsigned long duration; - struct timespec done_stamp = current_kernel_time(); + struct timespec done_stamp = xtime; DBF_TEXT(trace, 4, __FUNCTION__); @@ -730,7 +730,7 @@ ch_action_txdone(fsm_instance * fi, int event, void *arg) spin_unlock(&ch->collect_lock); ch->ccw[1].count = ch->trans_skb->len; fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch); - ch->prof.send_stamp = current_kernel_time(); + ch->prof.send_stamp = xtime; rc = ccw_device_start(ch->cdev, &ch->ccw[0], (unsigned long) ch, 0xff, 0); ch->prof.doios_multi++; @@ -2281,7 +2281,7 @@ transmit_skb(struct channel *ch, struct sk_buff *skb) fsm_newstate(ch->fsm, CH_STATE_TX); fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch); spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags); - ch->prof.send_stamp = current_kernel_time(); + ch->prof.send_stamp = xtime; rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], (unsigned long) ch, 0xff, 0); spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags); diff --git a/trunk/drivers/s390/net/netiucv.c b/trunk/drivers/s390/net/netiucv.c index 268889474339..3d28e1a5bf79 100644 --- a/trunk/drivers/s390/net/netiucv.c +++ b/trunk/drivers/s390/net/netiucv.c @@ -753,7 +753,7 @@ static void conn_action_txdone(fsm_instance *fi, int event, void *arg) header.next = 0; memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN); - conn->prof.send_stamp = current_kernel_time(); + conn->prof.send_stamp = xtime; txmsg.class = 0; txmsg.tag = 0; rc = iucv_message_send(conn->path, &txmsg, 0, 0, @@ -1185,7 +1185,7 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, memcpy(skb_put(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN); fsm_newstate(conn->fsm, CONN_STATE_TX); - conn->prof.send_stamp = current_kernel_time(); + conn->prof.send_stamp = xtime; msg.tag = 1; msg.class = 0; diff --git a/trunk/include/linux/time.h b/trunk/include/linux/time.h index 6a5f503b4f1d..e6aea5146e5d 100644 --- a/trunk/include/linux/time.h +++ b/trunk/include/linux/time.h @@ -99,11 +99,15 @@ extern int update_persistent_clock(struct timespec now); extern int no_sync_cmos_clock __read_mostly; void timekeeping_init(void); -unsigned long get_seconds(void); +static inline unsigned long get_seconds(void) +{ + return xtime.tv_sec; +} + struct timespec current_kernel_time(void); #define CURRENT_TIME (current_kernel_time()) -#define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 }) +#define CURRENT_TIME_SEC ((struct timespec) { xtime.tv_sec, 0 }) extern void do_gettimeofday(struct timeval *tv); extern int do_settimeofday(struct timespec *tv); diff --git a/trunk/kernel/acct.c b/trunk/kernel/acct.c index 24f0f8b2ba72..70d0d88e5554 100644 --- a/trunk/kernel/acct.c +++ b/trunk/kernel/acct.c @@ -468,7 +468,7 @@ static void do_acct_process(struct file *file) } #endif do_div(elapsed, AHZ); - ac.ac_btime = get_seconds() - elapsed; + ac.ac_btime = xtime.tv_sec - elapsed; /* we really need to bite the bullet and change layout */ ac.ac_uid = current->uid; ac.ac_gid = current->gid; diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index c21ca6bfaa66..eb1ddebd2c04 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -141,7 +141,11 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) do { seq = read_seqbegin(&xtime_lock); - xts = current_kernel_time(); +#ifdef CONFIG_NO_HZ + getnstimeofday(&xts); +#else + xts = xtime; +#endif tom = wall_to_monotonic; } while (read_seqretry(&xtime_lock, seq)); diff --git a/trunk/kernel/time.c b/trunk/kernel/time.c index 2289a8d68314..5b81da08bbdb 100644 --- a/trunk/kernel/time.c +++ b/trunk/kernel/time.c @@ -215,6 +215,22 @@ asmlinkage long sys_adjtimex(struct timex __user *txc_p) return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret; } +inline struct timespec current_kernel_time(void) +{ + struct timespec now; + unsigned long seq; + + do { + seq = read_seqbegin(&xtime_lock); + + now = xtime; + } while (read_seqretry(&xtime_lock, seq)); + + return now; +} + +EXPORT_SYMBOL(current_kernel_time); + /** * current_fs_time - Return FS time * @sb: Superblock. diff --git a/trunk/kernel/time/timekeeping.c b/trunk/kernel/time/timekeeping.c index acc417b5a9b7..88c81026e003 100644 --- a/trunk/kernel/time/timekeeping.c +++ b/trunk/kernel/time/timekeeping.c @@ -47,21 +47,9 @@ EXPORT_SYMBOL(xtime_lock); struct timespec xtime __attribute__ ((aligned (16))); struct timespec wall_to_monotonic __attribute__ ((aligned (16))); static unsigned long total_sleep_time; /* seconds */ -EXPORT_SYMBOL(xtime); +EXPORT_SYMBOL(xtime); -#ifdef CONFIG_NO_HZ -static struct timespec xtime_cache __attribute__ ((aligned (16))); -static inline void update_xtime_cache(u64 nsec) -{ - xtime_cache = xtime; - timespec_add_ns(&xtime_cache, nsec); -} -#else -#define xtime_cache xtime -/* We do *not* want to evaluate the argument for this case */ -#define update_xtime_cache(n) do { } while (0) -#endif static struct clocksource *clock; /* pointer to current clocksource */ @@ -490,8 +478,6 @@ void update_wall_time(void) xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift; clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift; - update_xtime_cache(cyc2ns(clock, offset)); - /* check to see if there is a new clocksource to use */ change_clocksource(); update_vsyscall(&xtime, clock); @@ -523,25 +509,3 @@ void monotonic_to_bootbased(struct timespec *ts) { ts->tv_sec += total_sleep_time; } - -unsigned long get_seconds(void) -{ - return xtime_cache.tv_sec; -} -EXPORT_SYMBOL(get_seconds); - - -struct timespec current_kernel_time(void) -{ - struct timespec now; - unsigned long seq; - - do { - seq = read_seqbegin(&xtime_lock); - - now = xtime_cache; - } while (read_seqretry(&xtime_lock, seq)); - - return now; -} -EXPORT_SYMBOL(current_kernel_time); diff --git a/trunk/kernel/tsacct.c b/trunk/kernel/tsacct.c index c122131a122f..658f638c402c 100644 --- a/trunk/kernel/tsacct.c +++ b/trunk/kernel/tsacct.c @@ -39,7 +39,7 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) ac_etime = timespec_to_ns(&ts); do_div(ac_etime, NSEC_PER_USEC); stats->ac_etime = ac_etime; - stats->ac_btime = get_seconds() - ts.tv_sec; + stats->ac_btime = xtime.tv_sec - ts.tv_sec; if (thread_group_leader(tsk)) { stats->ac_exitcode = tsk->exit_code; if (tsk->flags & PF_FORKNOEXEC) diff --git a/trunk/net/rxrpc/af_rxrpc.c b/trunk/net/rxrpc/af_rxrpc.c index c58fa0d1be26..16a68df4e36b 100644 --- a/trunk/net/rxrpc/af_rxrpc.c +++ b/trunk/net/rxrpc/af_rxrpc.c @@ -787,7 +787,7 @@ static int __init af_rxrpc_init(void) BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > sizeof(dummy_skb->cb)); - rxrpc_epoch = htonl(get_seconds()); + rxrpc_epoch = htonl(xtime.tv_sec); ret = -ENOMEM; rxrpc_call_jar = kmem_cache_create( diff --git a/trunk/net/rxrpc/ar-connection.c b/trunk/net/rxrpc/ar-connection.c index 372b24466dc7..482750efc235 100644 --- a/trunk/net/rxrpc/ar-connection.c +++ b/trunk/net/rxrpc/ar-connection.c @@ -791,7 +791,7 @@ void rxrpc_put_connection(struct rxrpc_connection *conn) ASSERTCMP(atomic_read(&conn->usage), >, 0); - conn->put_time = get_seconds(); + conn->put_time = xtime.tv_sec; if (atomic_dec_and_test(&conn->usage)) { _debug("zombie"); rxrpc_queue_delayed_work(&rxrpc_connection_reap, 0); @@ -835,7 +835,7 @@ void rxrpc_connection_reaper(struct work_struct *work) _enter(""); - now = get_seconds(); + now = xtime.tv_sec; earliest = ULONG_MAX; write_lock_bh(&rxrpc_connection_lock); diff --git a/trunk/net/rxrpc/ar-transport.c b/trunk/net/rxrpc/ar-transport.c index bb282a6a19f0..d43d78f19302 100644 --- a/trunk/net/rxrpc/ar-transport.c +++ b/trunk/net/rxrpc/ar-transport.c @@ -183,7 +183,7 @@ void rxrpc_put_transport(struct rxrpc_transport *trans) ASSERTCMP(atomic_read(&trans->usage), >, 0); - trans->put_time = get_seconds(); + trans->put_time = xtime.tv_sec; if (unlikely(atomic_dec_and_test(&trans->usage))) _debug("zombie"); /* let the reaper determine the timeout to avoid a race with @@ -219,7 +219,7 @@ static void rxrpc_transport_reaper(struct work_struct *work) _enter(""); - now = get_seconds(); + now = xtime.tv_sec; earliest = ULONG_MAX; /* extract all the transports that have been dead too long */ diff --git a/trunk/net/rxrpc/rxkad.c b/trunk/net/rxrpc/rxkad.c index ac3cabdca78c..5ec705144e10 100644 --- a/trunk/net/rxrpc/rxkad.c +++ b/trunk/net/rxrpc/rxkad.c @@ -916,7 +916,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, issue = be32_to_cpu(stamp); } p += 4; - now = get_seconds(); + now = xtime.tv_sec; _debug("KIV ISSUE: %lx [%lx]", issue, now); /* check the ticket is in date */