diff mbox series

[1/5] tracehook: Provide TIF_NOTIFY_RESUME handling for KVM

Message ID 20190801143657.785902257@linutronix.de (mailing list archive)
State New, archived
Headers show
Series posix-cpu-timers: Move expiry into task work context | expand

Commit Message

Thomas Gleixner Aug. 1, 2019, 2:32 p.m. UTC
TIF_NOTITY_RESUME is evaluated on return to user space along with other TIF
flags.

>From the kernels point of view a VMENTER is more or less equivalent to
return to user space which means that at least a subset of TIF flags needs
to be evaluated and handled.

Currently KVM handles only TIF_SIGPENDING and TIF_NEED_RESCHED, but
TIF_NOTIFY_RESUME is ignored. So pending task_work etc, is completely
ignored until the vCPU thread actually goes all the way back into
userspace/qemu.

Provide notify_resume_pending() and tracehook_handle_notify_resume() so
this can be handled similar to SIGPENDING.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Oleg Nesterov <oleg@redhat.com>
---
 include/linux/tracehook.h |   15 +++++++++++++++
 kernel/task_work.c        |   19 +++++++++++++++++++
 2 files changed, 34 insertions(+)

Comments

Peter Zijlstra Aug. 1, 2019, 2:48 p.m. UTC | #1
On Thu, Aug 01, 2019 at 04:32:51PM +0200, Thomas Gleixner wrote:
> +#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
> +/**
> + * tracehook_handle_notify_resume - Notify resume handling for virt
> + *
> + * Called with interrupts and preemption enabled from VMENTER/EXIT.
> + */
> +void tracehook_handle_notify_resume(void)
> +{
> +	local_irq_disable();
> +	while (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
> +		local_irq_enable();
> +		tracehook_notify_resume(NULL);
> +		local_irq_disable();
> +	}
> +	local_irq_enable();

I'm confused by the IRQ state swizzling here, what is it doing?

> +}
> +EXPORT_SYMBOL_GPL(tracehook_handle_notify_resume);
> +#endif
> 
>
Thomas Gleixner Aug. 1, 2019, 3:10 p.m. UTC | #2
On Thu, 1 Aug 2019, Peter Zijlstra wrote:
> On Thu, Aug 01, 2019 at 04:32:51PM +0200, Thomas Gleixner wrote:
> > +#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
> > +/**
> > + * tracehook_handle_notify_resume - Notify resume handling for virt
> > + *
> > + * Called with interrupts and preemption enabled from VMENTER/EXIT.
> > + */
> > +void tracehook_handle_notify_resume(void)
> > +{
> > +	local_irq_disable();
> > +	while (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
> > +		local_irq_enable();
> > +		tracehook_notify_resume(NULL);
> > +		local_irq_disable();
> > +	}
> > +	local_irq_enable();
> 
> I'm confused by the IRQ state swizzling here, what is it doing?

Hmm, right. It's not really needed. Modeled it after the user space return
code, but the KVM case is different because it evaluates the TIF bit again
before entering the VM with interrupts disabled anyway.

I'll remove the brainfart in V2.

Thanks,

	tglx
Andy Lutomirski Aug. 1, 2019, 5:02 p.m. UTC | #3
> On Aug 1, 2019, at 7:48 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> 
>> On Thu, Aug 01, 2019 at 04:32:51PM +0200, Thomas Gleixner wrote:
>> +#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
>> +/**
>> + * tracehook_handle_notify_resume - Notify resume handling for virt
>> + *
>> + * Called with interrupts and preemption enabled from VMENTER/EXIT.
>> + */
>> +void tracehook_handle_notify_resume(void)
>> +{
>> +    local_irq_disable();
>> +    while (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
>> +        local_irq_enable();
>> +        tracehook_notify_resume(NULL);
>> +        local_irq_disable();
>> +    }
>> +    local_irq_enable();
> 
> I'm confused by the IRQ state swizzling here, what is it doing?

Me too. Also, why is a loop needed?

> 
>> +}
>> +EXPORT_SYMBOL_GPL(tracehook_handle_notify_resume);
>> +#endif
>> 
>>
diff mbox series

Patch

--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -163,6 +163,21 @@  static inline void set_notify_resume(str
 #endif
 }
 
+#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
+/**
+ * notify_resume_pending - Check whether current has TIF_NOTIFY_RESUME set
+ */
+static inline bool notify_resume_pending(void)
+{
+	return test_thread_flag(TIF_NOTIFY_RESUME);
+}
+
+void tracehook_handle_notify_resume(void);
+#else
+static inline bool notify_resume_pending(void) { return false; }
+static inline void tracehook_handle_notify_resume(void) { }
+#endif
+
 /**
  * tracehook_notify_resume - report when about to return to user mode
  * @regs:		user-mode registers of @current task
--- a/kernel/task_work.c
+++ b/kernel/task_work.c
@@ -116,3 +116,22 @@  void task_work_run(void)
 		} while (work);
 	}
 }
+
+#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
+/**
+ * tracehook_handle_notify_resume - Notify resume handling for virt
+ *
+ * Called with interrupts and preemption enabled from VMENTER/EXIT.
+ */
+void tracehook_handle_notify_resume(void)
+{
+	local_irq_disable();
+	while (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
+		local_irq_enable();
+		tracehook_notify_resume(NULL);
+		local_irq_disable();
+	}
+	local_irq_enable();
+}
+EXPORT_SYMBOL_GPL(tracehook_handle_notify_resume);
+#endif