|
@@ -24,6 +24,7 @@
|
|
|
#include <asm/machvec.h>
|
|
|
#include <asm/delay.h>
|
|
|
#include <asm/hw_irq.h>
|
|
|
+#include <asm/paravirt.h>
|
|
|
#include <asm/ptrace.h>
|
|
|
#include <asm/sal.h>
|
|
|
#include <asm/sections.h>
|
|
@@ -48,6 +49,15 @@ EXPORT_SYMBOL(last_cli_ip);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
+#ifdef CONFIG_PARAVIRT
|
|
|
+static void
|
|
|
+paravirt_clocksource_resume(void)
|
|
|
+{
|
|
|
+ if (pv_time_ops.clocksource_resume)
|
|
|
+ pv_time_ops.clocksource_resume();
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
static struct clocksource clocksource_itc = {
|
|
|
.name = "itc",
|
|
|
.rating = 350,
|
|
@@ -56,6 +66,9 @@ static struct clocksource clocksource_itc = {
|
|
|
.mult = 0, /*to be calculated*/
|
|
|
.shift = 16,
|
|
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
|
|
+#ifdef CONFIG_PARAVIRT
|
|
|
+ .resume = paravirt_clocksource_resume,
|
|
|
+#endif
|
|
|
};
|
|
|
static struct clocksource *itc_clocksource;
|
|
|
|
|
@@ -156,6 +169,9 @@ timer_interrupt (int irq, void *dev_id)
|
|
|
|
|
|
profile_tick(CPU_PROFILING);
|
|
|
|
|
|
+ if (paravirt_do_steal_accounting(&new_itm))
|
|
|
+ goto skip_process_time_accounting;
|
|
|
+
|
|
|
while (1) {
|
|
|
update_process_times(user_mode(get_irq_regs()));
|
|
|
|
|
@@ -185,6 +201,8 @@ timer_interrupt (int irq, void *dev_id)
|
|
|
local_irq_disable();
|
|
|
}
|
|
|
|
|
|
+skip_process_time_accounting:
|
|
|
+
|
|
|
do {
|
|
|
/*
|
|
|
* If we're too close to the next clock tick for
|
|
@@ -334,6 +352,11 @@ ia64_init_itm (void)
|
|
|
*/
|
|
|
clocksource_itc.rating = 50;
|
|
|
|
|
|
+ paravirt_init_missing_ticks_accounting(smp_processor_id());
|
|
|
+
|
|
|
+ /* avoid softlock up message when cpu is unplug and plugged again. */
|
|
|
+ touch_softlockup_watchdog();
|
|
|
+
|
|
|
/* Setup the CPU local timer tick */
|
|
|
ia64_cpu_local_tick();
|
|
|
|