From: Thomas Gleixner <tglx@linutronix.de>
To: Sohil Mehta <sohil.mehta@intel.com>, x86@kernel.org
Cc: Sohil Mehta <sohil.mehta@intel.com>,
Tony Luck <tony.luck@intel.com>,
Dave Hansen <dave.hansen@intel.com>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
"H . Peter Anvin" <hpa@zytor.com>,
Andy Lutomirski <luto@kernel.org>, Jens Axboe <axboe@kernel.dk>,
Christian Brauner <christian@brauner.io>,
Peter Zijlstra <peterz@infradead.org>,
Shuah Khan <shuah@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Jonathan Corbet <corbet@lwn.net>, Ashok Raj <ashok.raj@intel.com>,
Jacob Pan <jacob.jun.pan@linux.intel.com>,
Gayatri Kammela <gayatri.kammela@intel.com>,
Zeng Guang <guang.zeng@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
Randy E Witt <randy.e.witt@intel.com>,
Ravi V Shankar <ravi.v.shankar@intel.com>,
Ramesh Thomas <ramesh.thomas@intel.com>,
linux-api@vger.kernel.org, linux-arch@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: Re: [RFC PATCH 10/13] x86/uintr: Introduce user IPI sender syscalls
Date: Fri, 24 Sep 2021 12:54:12 +0200 [thread overview]
Message-ID: <87tuiadz1n.ffs@tglx> (raw)
In-Reply-To: <20210913200132.3396598-11-sohil.mehta@intel.com>
On Mon, Sep 13 2021 at 13:01, Sohil Mehta wrote:
> +/*
> + * No lock is needed to read the active flag. Writes only happen from
> + * r_info->task that owns the UPID. Everyone else would just read this flag.
> + *
> + * This only provides a static check. The receiver may become inactive right
> + * after this check. The primary reason to have this check is to prevent future
> + * senders from connecting with this UPID, since the receiver task has already
> + * made this UPID inactive.
How is that not racy?
> +static void free_uitt(struct uintr_uitt_ctx *uitt_ctx)
> +{
> + unsigned long flags;
> +
> + spin_lock_irqsave(&uitt_ctx->uitt_lock, flags);
> + kfree(uitt_ctx->uitt);
Again. Please move kfree() outside of the lock held region. But aside of
that what is this lock protecting here?
> + uitt_ctx->uitt = NULL;
> + spin_unlock_irqrestore(&uitt_ctx->uitt_lock, flags);
If there is concurrency then the other task which is blocked on
uitt_lock will operate on uitt_ctx while the same is freed.
Again, this lacks any life time and serialization rules. Just sprinkling
locks all over the place does not make it magically correct.
> + kfree(uitt_ctx);
> +}
> +static void put_uitt_ref(struct uintr_uitt_ctx *uitt_ctx)
> +{
> + if (refcount_dec_and_test(&uitt_ctx->refs))
> + free_uitt(uitt_ctx);
> +}
> +static struct uintr_uitt_ctx *get_uitt_ref(struct uintr_uitt_ctx *uitt_ctx)
> +{
> + refcount_inc(&uitt_ctx->refs);
> + return uitt_ctx;
> +}
> +
> +static inline void mark_uitte_invalid(struct uintr_sender_info *s_info)
> +{
> + struct uintr_uitt_entry *uitte;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&s_info->uitt_ctx->uitt_lock, flags);
> + uitte = &s_info->uitt_ctx->uitt[s_info->uitt_index];
> + uitte->valid = 0;
> + spin_unlock_irqrestore(&s_info->uitt_ctx->uitt_lock, flags);
> +}
> +
> static void __clear_vector_from_upid(u64 uvec, struct uintr_upid *upid)
> {
> clear_bit(uvec, (unsigned long *)&upid->puir);
> @@ -175,6 +290,210 @@ static void receiver_clear_uvec(struct callback_head *head)
> kfree(r_info);
> }
>
> +static void teardown_uitt(void)
> +{
> + struct task_struct *t = current;
> + struct fpu *fpu = &t->thread.fpu;
> + u64 msr64;
> +
> + put_uitt_ref(t->thread.ui_send->uitt_ctx);
> + kfree(t->thread.ui_send);
> + t->thread.ui_send = NULL;
> +
> + fpregs_lock();
> +
> + if (fpregs_state_valid(fpu, smp_processor_id())) {
> + /* Modify only the relevant bits of the MISC MSR */
> + rdmsrl(MSR_IA32_UINTR_MISC, msr64);
> + msr64 &= GENMASK_ULL(63, 32);
More magic numbers.
> + wrmsrl(MSR_IA32_UINTR_MISC, msr64);
> + wrmsrl(MSR_IA32_UINTR_TT, 0ULL);
> +static void __free_uitt_entry(unsigned int entry)
> +{
> + struct task_struct *t = current;
> + unsigned long flags;
> +
> + if (entry >= UINTR_MAX_UITT_NR)
> + return;
> +
> + if (!is_uintr_sender(t))
> + return;
> +
> + pr_debug("send: Freeing UITTE entry %d for task=%d\n", entry, t->pid);
> +
> + spin_lock_irqsave(&t->thread.ui_send->uitt_ctx->uitt_lock, flags);
> + memset(&t->thread.ui_send->uitt_ctx->uitt[entry], 0,
> + sizeof(struct uintr_uitt_entry));
> + spin_unlock_irqrestore(&t->thread.ui_send->uitt_ctx->uitt_lock,
> flags);
What's the spinlock protecting here?
> + clear_bit(entry, (unsigned long *)t->thread.ui_send->uitt_mask);
> +
> + if (is_uitt_empty(t)) {
> + pr_debug("send: UITT mask is empty. Dereference and teardown UITT\n");
> + teardown_uitt();
> + }
> +}
> +void do_uintr_unregister_sender(struct uintr_receiver_info *r_info,
> + struct uintr_sender_info *s_info)
> +{
> + int ret;
> +
> + /*
> + * To make sure any new senduipi result in a #GP fault.
> + * The task work might take non-zero time to kick the process out.
-ENOPARSE
> + */
> + mark_uitte_invalid(s_info);
> +
> + pr_debug("send: Adding Free UITTE %d task work for task=%d\n",
> + s_info->uitt_index, s_info->task->pid);
> +
> + init_task_work(&s_info->twork, sender_free_uitte);
> + ret = task_work_add(s_info->task, &s_info->twork, true);
> + if (ret) {
> + /*
> + * Dereferencing the UITT and UPID here since the task has
> + * exited.
> + */
> + pr_debug("send: Free UITTE %d task=%d has already exited\n",
> + s_info->uitt_index, s_info->task->pid);
> + put_upid_ref(s_info->r_upid_ctx);
> + put_uitt_ref(s_info->uitt_ctx);
> + put_task_struct(s_info->task);
> + kfree(s_info);
> + return;
> + }
> +}
> +
> +int do_uintr_register_sender(struct uintr_receiver_info *r_info,
> + struct uintr_sender_info *s_info)
> +{
> + struct uintr_uitt_entry *uitte = NULL;
> + struct uintr_sender *ui_send;
> + struct task_struct *t = current;
> + unsigned long flags;
> + int entry;
> + int ret;
> +
> + /*
> + * Only a static check. Receiver could exit anytime after this check.
> + * This check only prevents connections using uintr_fd after the
> + * receiver has already exited/unregistered.
> + */
> + if (!uintr_is_receiver_active(r_info))
> + return -ESHUTDOWN;
How is this safe against a concurrent unregister/exit operation?
Thanks,
tglx
next prev parent reply other threads:[~2021-09-24 10:54 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-13 20:01 [RFC PATCH 00/13] x86 User Interrupts support Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 01/13] x86/uintr/man-page: Include man pages draft for reference Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 02/13] Documentation/x86: Add documentation for User Interrupts Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 03/13] x86/cpu: Enumerate User Interrupts support Sohil Mehta
2021-09-23 22:24 ` Thomas Gleixner
2021-09-24 19:59 ` Sohil Mehta
2021-09-27 20:42 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 04/13] x86/fpu/xstate: Enumerate User Interrupts supervisor state Sohil Mehta
2021-09-23 22:34 ` Thomas Gleixner
2021-09-27 22:25 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 05/13] x86/irq: Reserve a user IPI notification vector Sohil Mehta
2021-09-23 23:07 ` Thomas Gleixner
2021-09-25 13:30 ` Thomas Gleixner
2021-09-26 12:39 ` Thomas Gleixner
2021-09-27 19:07 ` Sohil Mehta
2021-09-28 8:11 ` Thomas Gleixner
2021-09-27 19:26 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 06/13] x86/uintr: Introduce uintr receiver syscalls Sohil Mehta
2021-09-23 12:26 ` Greg KH
2021-09-24 0:05 ` Thomas Gleixner
2021-09-27 23:20 ` Sohil Mehta
2021-09-28 4:39 ` Greg KH
2021-09-28 16:47 ` Sohil Mehta
2021-09-23 23:52 ` Thomas Gleixner
2021-09-27 23:57 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 07/13] x86/process/64: Add uintr task context switch support Sohil Mehta
2021-09-24 0:41 ` Thomas Gleixner
2021-09-28 0:30 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 08/13] x86/process/64: Clean up uintr task fork and exit paths Sohil Mehta
2021-09-24 1:02 ` Thomas Gleixner
2021-09-28 1:23 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 09/13] x86/uintr: Introduce vector registration and uintr_fd syscall Sohil Mehta
2021-09-24 10:33 ` Thomas Gleixner
2021-09-28 20:40 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 10/13] x86/uintr: Introduce user IPI sender syscalls Sohil Mehta
2021-09-23 12:28 ` Greg KH
2021-09-28 18:01 ` Sohil Mehta
2021-09-29 7:04 ` Greg KH
2021-09-29 14:27 ` Sohil Mehta
2021-09-24 10:54 ` Thomas Gleixner [this message]
2021-09-13 20:01 ` [RFC PATCH 11/13] x86/uintr: Introduce uintr_wait() syscall Sohil Mehta
2021-09-24 11:04 ` Thomas Gleixner
2021-09-25 12:08 ` Thomas Gleixner
2021-09-28 23:13 ` Sohil Mehta
2021-09-28 23:08 ` Sohil Mehta
2021-09-26 14:41 ` Thomas Gleixner
2021-09-29 1:09 ` Sohil Mehta
2021-09-29 3:30 ` Andy Lutomirski
2021-09-29 4:56 ` Sohil Mehta
2021-09-30 18:08 ` Andy Lutomirski
2021-09-30 19:29 ` Thomas Gleixner
2021-09-30 22:01 ` Andy Lutomirski
2021-10-01 0:01 ` Thomas Gleixner
2021-10-01 4:41 ` Andy Lutomirski
2021-10-01 9:56 ` Thomas Gleixner
2021-10-01 15:13 ` Andy Lutomirski
2021-10-01 18:04 ` Sohil Mehta
2021-10-01 21:29 ` Thomas Gleixner
2021-10-01 23:00 ` Sohil Mehta
2021-10-01 23:04 ` Andy Lutomirski
2021-09-13 20:01 ` [RFC PATCH 12/13] x86/uintr: Wire up the user interrupt syscalls Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 13/13] selftests/x86: Add basic tests for User IPI Sohil Mehta
2021-09-13 20:27 ` [RFC PATCH 00/13] x86 User Interrupts support Dave Hansen
2021-09-14 19:03 ` Mehta, Sohil
2021-09-23 12:19 ` Greg KH
2021-09-23 14:09 ` Greg KH
2021-09-23 14:46 ` Dave Hansen
2021-09-23 15:07 ` Greg KH
2021-09-23 23:24 ` Sohil Mehta
2021-09-23 23:09 ` Sohil Mehta
2021-09-24 0:17 ` Sohil Mehta
2021-09-23 14:39 ` Jens Axboe
2021-09-29 4:31 ` Andy Lutomirski
2021-09-30 16:30 ` Stefan Hajnoczi
2021-09-30 17:24 ` Sohil Mehta
2021-09-30 17:26 ` Andy Lutomirski
2021-10-01 16:35 ` Stefan Hajnoczi
2021-10-01 16:35 ` Stefan Hajnoczi
2021-10-01 16:41 ` Richard Henderson
2021-10-01 16:41 ` Richard Henderson
2021-09-30 16:26 ` Stefan Hajnoczi
2021-10-01 0:40 ` Sohil Mehta
2021-10-01 8:19 ` Pavel Machek
2021-11-18 22:19 ` Sohil Mehta
2021-11-16 3:49 ` Prakash Sangappa
2021-11-18 21:44 ` Sohil Mehta
2021-12-22 16:17 ` Chrisma Pakha
2022-01-07 2:08 ` Sohil Mehta
2022-01-17 1:14 ` Chrisma Pakha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87tuiadz1n.ffs@tglx \
--to=tglx@linutronix.de \
--cc=arnd@arndb.de \
--cc=ashok.raj@intel.com \
--cc=axboe@kernel.dk \
--cc=bp@alien8.de \
--cc=christian@brauner.io \
--cc=corbet@lwn.net \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@intel.com \
--cc=gayatri.kammela@intel.com \
--cc=guang.zeng@intel.com \
--cc=hpa@zytor.com \
--cc=jacob.jun.pan@linux.intel.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=ramesh.thomas@intel.com \
--cc=randy.e.witt@intel.com \
--cc=ravi.v.shankar@intel.com \
--cc=shuah@kernel.org \
--cc=sohil.mehta@intel.com \
--cc=tony.luck@intel.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.