diff options
Diffstat (limited to 'arch/x86/kernel/paravirt.c')
| -rw-r--r-- | arch/x86/kernel/paravirt.c | 56 | 
1 files changed, 26 insertions, 30 deletions
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 9faf43bea33..70ec9b951d7 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -248,18 +248,16 @@ static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LA  static inline void enter_lazy(enum paravirt_lazy_mode mode)  { -	BUG_ON(__get_cpu_var(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE); -	BUG_ON(preemptible()); +	BUG_ON(percpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE); -	__get_cpu_var(paravirt_lazy_mode) = mode; +	percpu_write(paravirt_lazy_mode, mode);  } -void paravirt_leave_lazy(enum paravirt_lazy_mode mode) +static void leave_lazy(enum paravirt_lazy_mode mode)  { -	BUG_ON(__get_cpu_var(paravirt_lazy_mode) != mode); -	BUG_ON(preemptible()); +	BUG_ON(percpu_read(paravirt_lazy_mode) != mode); -	__get_cpu_var(paravirt_lazy_mode) = PARAVIRT_LAZY_NONE; +	percpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);  }  void paravirt_enter_lazy_mmu(void) @@ -269,22 +267,36 @@ void paravirt_enter_lazy_mmu(void)  void paravirt_leave_lazy_mmu(void)  { -	paravirt_leave_lazy(PARAVIRT_LAZY_MMU); +	leave_lazy(PARAVIRT_LAZY_MMU);  } -void paravirt_enter_lazy_cpu(void) +void paravirt_start_context_switch(struct task_struct *prev)  { +	BUG_ON(preemptible()); + +	if (percpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) { +		arch_leave_lazy_mmu_mode(); +		set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES); +	}  	enter_lazy(PARAVIRT_LAZY_CPU);  } -void paravirt_leave_lazy_cpu(void) +void paravirt_end_context_switch(struct task_struct *next)  { -	paravirt_leave_lazy(PARAVIRT_LAZY_CPU); +	BUG_ON(preemptible()); + +	leave_lazy(PARAVIRT_LAZY_CPU); + +	if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES)) +		arch_enter_lazy_mmu_mode();  }  enum paravirt_lazy_mode paravirt_get_lazy_mode(void)  { -	return __get_cpu_var(paravirt_lazy_mode); +	if (in_interrupt()) +		return PARAVIRT_LAZY_NONE; + +	return percpu_read(paravirt_lazy_mode);  }  void arch_flush_lazy_mmu_mode(void) @@ -292,7 +304,6 @@ void arch_flush_lazy_mmu_mode(void)  	preempt_disable();  	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { -		WARN_ON(preempt_count() == 1);  		arch_leave_lazy_mmu_mode();  		arch_enter_lazy_mmu_mode();  	} @@ -300,19 +311,6 @@ void arch_flush_lazy_mmu_mode(void)  	preempt_enable();  } -void arch_flush_lazy_cpu_mode(void) -{ -	preempt_disable(); - -	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) { -		WARN_ON(preempt_count() == 1); -		arch_leave_lazy_cpu_mode(); -		arch_enter_lazy_cpu_mode(); -	} - -	preempt_enable(); -} -  struct pv_info pv_info = {  	.name = "bare hardware",  	.paravirt_enabled = 0, @@ -404,10 +402,8 @@ struct pv_cpu_ops pv_cpu_ops = {  	.set_iopl_mask = native_set_iopl_mask,  	.io_delay = native_io_delay, -	.lazy_mode = { -		.enter = paravirt_nop, -		.leave = paravirt_nop, -	}, +	.start_context_switch = paravirt_nop, +	.end_context_switch = paravirt_nop,  };  struct pv_apic_ops pv_apic_ops = {  |