diff options
| -rw-r--r-- | arch/ia64/kernel/paravirt.c | 15 | ||||
| -rw-r--r-- | arch/ia64/kernel/time.c | 23 | ||||
| -rw-r--r-- | include/asm-ia64/paravirt.h | 32 |
3 files changed, 70 insertions, 0 deletions
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c index ba5383be03cb..afaf5b9a2cf0 100644 --- a/arch/ia64/kernel/paravirt.c +++ b/arch/ia64/kernel/paravirt.c | |||
| @@ -352,3 +352,18 @@ struct pv_irq_ops pv_irq_ops = { | |||
| 352 | 352 | ||
| 353 | .resend_irq = ia64_native_resend_irq, | 353 | .resend_irq = ia64_native_resend_irq, |
| 354 | }; | 354 | }; |
| 355 | |||
| 356 | /*************************************************************************** | ||
| 357 | * pv_time_ops | ||
| 358 | * time operations | ||
| 359 | */ | ||
| 360 | |||
| 361 | static int | ||
| 362 | ia64_native_do_steal_accounting(unsigned long *new_itm) | ||
| 363 | { | ||
| 364 | return 0; | ||
| 365 | } | ||
| 366 | |||
| 367 | struct pv_time_ops pv_time_ops = { | ||
| 368 | .do_steal_accounting = ia64_native_do_steal_accounting, | ||
| 369 | }; | ||
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 8c73643f2d66..046ca89efc05 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <asm/machvec.h> | 24 | #include <asm/machvec.h> |
| 25 | #include <asm/delay.h> | 25 | #include <asm/delay.h> |
| 26 | #include <asm/hw_irq.h> | 26 | #include <asm/hw_irq.h> |
| 27 | #include <asm/paravirt.h> | ||
| 27 | #include <asm/ptrace.h> | 28 | #include <asm/ptrace.h> |
| 28 | #include <asm/sal.h> | 29 | #include <asm/sal.h> |
| 29 | #include <asm/sections.h> | 30 | #include <asm/sections.h> |
| @@ -48,6 +49,15 @@ EXPORT_SYMBOL(last_cli_ip); | |||
| 48 | 49 | ||
| 49 | #endif | 50 | #endif |
| 50 | 51 | ||
| 52 | #ifdef CONFIG_PARAVIRT | ||
| 53 | static void | ||
| 54 | paravirt_clocksource_resume(void) | ||
| 55 | { | ||
| 56 | if (pv_time_ops.clocksource_resume) | ||
| 57 | pv_time_ops.clocksource_resume(); | ||
| 58 | } | ||
| 59 | #endif | ||
| 60 | |||
| 51 | static struct clocksource clocksource_itc = { | 61 | static struct clocksource clocksource_itc = { |
| 52 | .name = "itc", | 62 | .name = "itc", |
| 53 | .rating = 350, | 63 | .rating = 350, |
| @@ -56,6 +66,9 @@ static struct clocksource clocksource_itc = { | |||
| 56 | .mult = 0, /*to be calculated*/ | 66 | .mult = 0, /*to be calculated*/ |
| 57 | .shift = 16, | 67 | .shift = 16, |
| 58 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 68 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
| 69 | #ifdef CONFIG_PARAVIRT | ||
| 70 | .resume = paravirt_clocksource_resume, | ||
| 71 | #endif | ||
| 59 | }; | 72 | }; |
| 60 | static struct clocksource *itc_clocksource; | 73 | static struct clocksource *itc_clocksource; |
| 61 | 74 | ||
| @@ -156,6 +169,9 @@ timer_interrupt (int irq, void *dev_id) | |||
| 156 | 169 | ||
| 157 | profile_tick(CPU_PROFILING); | 170 | profile_tick(CPU_PROFILING); |
| 158 | 171 | ||
| 172 | if (paravirt_do_steal_accounting(&new_itm)) | ||
| 173 | goto skip_process_time_accounting; | ||
| 174 | |||
| 159 | while (1) { | 175 | while (1) { |
| 160 | update_process_times(user_mode(get_irq_regs())); | 176 | update_process_times(user_mode(get_irq_regs())); |
| 161 | 177 | ||
| @@ -185,6 +201,8 @@ timer_interrupt (int irq, void *dev_id) | |||
| 185 | local_irq_disable(); | 201 | local_irq_disable(); |
| 186 | } | 202 | } |
| 187 | 203 | ||
| 204 | skip_process_time_accounting: | ||
| 205 | |||
| 188 | do { | 206 | do { |
| 189 | /* | 207 | /* |
| 190 | * If we're too close to the next clock tick for | 208 | * If we're too close to the next clock tick for |
| @@ -334,6 +352,11 @@ ia64_init_itm (void) | |||
| 334 | */ | 352 | */ |
| 335 | clocksource_itc.rating = 50; | 353 | clocksource_itc.rating = 50; |
| 336 | 354 | ||
| 355 | paravirt_init_missing_ticks_accounting(smp_processor_id()); | ||
| 356 | |||
| 357 | /* avoid softlock up message when cpu is unplug and plugged again. */ | ||
| 358 | touch_softlockup_watchdog(); | ||
| 359 | |||
| 337 | /* Setup the CPU local timer tick */ | 360 | /* Setup the CPU local timer tick */ |
| 338 | ia64_cpu_local_tick(); | 361 | ia64_cpu_local_tick(); |
| 339 | 362 | ||
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h index ee15646b6d66..1b4df129f579 100644 --- a/include/asm-ia64/paravirt.h +++ b/include/asm-ia64/paravirt.h | |||
| @@ -200,6 +200,35 @@ ia64_resend_irq(unsigned int vector) | |||
| 200 | pv_irq_ops.resend_irq(vector); | 200 | pv_irq_ops.resend_irq(vector); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | /****************************************************************************** | ||
| 204 | * replacement of time operations. | ||
| 205 | */ | ||
| 206 | |||
| 207 | extern struct itc_jitter_data_t itc_jitter_data; | ||
| 208 | extern volatile int time_keeper_id; | ||
| 209 | |||
| 210 | struct pv_time_ops { | ||
| 211 | void (*init_missing_ticks_accounting)(int cpu); | ||
| 212 | int (*do_steal_accounting)(unsigned long *new_itm); | ||
| 213 | |||
| 214 | void (*clocksource_resume)(void); | ||
| 215 | }; | ||
| 216 | |||
| 217 | extern struct pv_time_ops pv_time_ops; | ||
| 218 | |||
| 219 | static inline void | ||
| 220 | paravirt_init_missing_ticks_accounting(int cpu) | ||
| 221 | { | ||
| 222 | if (pv_time_ops.init_missing_ticks_accounting) | ||
| 223 | pv_time_ops.init_missing_ticks_accounting(cpu); | ||
| 224 | } | ||
| 225 | |||
| 226 | static inline int | ||
| 227 | paravirt_do_steal_accounting(unsigned long *new_itm) | ||
| 228 | { | ||
| 229 | return pv_time_ops.do_steal_accounting(new_itm); | ||
| 230 | } | ||
| 231 | |||
| 203 | #endif /* !__ASSEMBLY__ */ | 232 | #endif /* !__ASSEMBLY__ */ |
| 204 | 233 | ||
| 205 | #else | 234 | #else |
| @@ -215,6 +244,9 @@ ia64_resend_irq(unsigned int vector) | |||
| 215 | #define paravirt_arch_setup_nomca() 0 | 244 | #define paravirt_arch_setup_nomca() 0 |
| 216 | #define paravirt_post_smp_prepare_boot_cpu() do { } while (0) | 245 | #define paravirt_post_smp_prepare_boot_cpu() do { } while (0) |
| 217 | 246 | ||
| 247 | #define paravirt_init_missing_ticks_accounting(cpu) do { } while (0) | ||
| 248 | #define paravirt_do_steal_accounting(new_itm) 0 | ||
| 249 | |||
| 218 | #endif /* __ASSEMBLY__ */ | 250 | #endif /* __ASSEMBLY__ */ |
| 219 | 251 | ||
| 220 | 252 | ||
