All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sohil Mehta <sohil.mehta@intel.com>
To: x86@kernel.org
Cc: Sohil Mehta <sohil.mehta@intel.com>,
	Tony Luck <tony.luck@intel.com>,
	Dave Hansen <dave.hansen@intel.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	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: [RFC PATCH 01/13] x86/uintr/man-page: Include man pages draft for reference
Date: Mon, 13 Sep 2021 13:01:20 -0700	[thread overview]
Message-ID: <20210913200132.3396598-2-sohil.mehta@intel.com> (raw)
In-Reply-To: <20210913200132.3396598-1-sohil.mehta@intel.com>

Included here in plain text format for reference and review.

<Will eventually send the man pages in groff format separately to the
man-pages repository.>

The formatting for the man pages still needs a little bit of work.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
---
 tools/uintr/manpages/0_overview.txt           | 265 ++++++++++++++++++
 tools/uintr/manpages/1_register_receiver.txt  | 122 ++++++++
 .../uintr/manpages/2_unregister_receiver.txt  |  62 ++++
 tools/uintr/manpages/3_create_fd.txt          | 104 +++++++
 tools/uintr/manpages/4_register_sender.txt    | 121 ++++++++
 tools/uintr/manpages/5_unregister_sender.txt  |  79 ++++++
 tools/uintr/manpages/6_wait.txt               |  59 ++++
 7 files changed, 812 insertions(+)
 create mode 100644 tools/uintr/manpages/0_overview.txt
 create mode 100644 tools/uintr/manpages/1_register_receiver.txt
 create mode 100644 tools/uintr/manpages/2_unregister_receiver.txt
 create mode 100644 tools/uintr/manpages/3_create_fd.txt
 create mode 100644 tools/uintr/manpages/4_register_sender.txt
 create mode 100644 tools/uintr/manpages/5_unregister_sender.txt
 create mode 100644 tools/uintr/manpages/6_wait.txt

diff --git a/tools/uintr/manpages/0_overview.txt b/tools/uintr/manpages/0_overview.txt
new file mode 100644
index 000000000000..349538effb15
--- /dev/null
+++ b/tools/uintr/manpages/0_overview.txt
@@ -0,0 +1,265 @@
+UINTR(7)               Miscellaneous Information Manual               UINTR(7)
+
+
+
+NAME
+       Uintr - overview of User Interrupts
+
+DESCRIPTION
+       User Interrupts (Uintr) provides a low latency event delivery and inter
+       process communication mechanism. These events can be delivered directly
+       to userspace without a transition to the kernel.
+
+       In  the  User  Interrupts  hardware  architecture, a receiver is always
+       expected to be a user space task. However, a user interrupt can be sent
+       by  another  user  space  task,  kernel  or  an external source (like a
+       device). The feature that allows another  userspace  task  to  send  an
+       interrupt is referred to as User IPI.
+
+       Uintr  is  a  hardware  dependent,  opt-in  feature. Application aren't
+       expected or able to send or receive  interrupts  unless  they  register
+       themselves with the kernel using the syscall interface described below.
+       It is recommended that applications wanting to use User Interrupts call
+       uintr_register_handler(2) and test whether the call succeeds.
+
+       Hardware  support  for  User  interrupts  may  be  detected using other
+       mechanisms but they could be misleading and are generally not needed:
+        - Using the cpuid instruction (Refer  the  Intel  Software  Developers
+       Manual).
+        -  Checking  for the "uintr" string in /proc/cpuinfo under the "flags"
+       field.
+
+
+       Applications wanting to use Uintr  should  also  be  able  to  function
+       without  it  as well. Uintr support might be unavailable because of any
+       one of the following reasons:
+        - the kernel code does not contain support
+        - the kernel support has been disabled
+        - the hardware does not support it
+
+
+   Uintr syscall interface
+       Applications can use and manage Uintr using the system calls  described
+       here.   The  Uintr  system  calls  are  available only if the kernel is
+       configured with the CONFIG_X86_USER_INTERRUPTS option.
+
+       1)  A  user  application   registers   an   interrupt   handler   using
+       uintr_register_handler(2).  The  registered  interrupt  handler will be
+       invoked when a user interrupt is delivered to  that  thread.  Only  one
+       interrupt  handler  can  be  registered by a particular thread within a
+       process.
+
+       2) Each thread that registered a handler  has  its  own  unique  vector
+       space  of  64  vectors.  The  thread can then use uintr_create_fd(2) to
+       register a vector  and  create  a  user  interrupt  file  descriptor  -
+       uintr_fd.
+
+       3)  The  uintr_fd is only associated with only one Uintr vector.  A new
+       uintr_fd must be created for  each  of  the  64  vectors.  uintr_fd  is
+       automatically  inherited  by forked processes but the receiver can also
+       share the uintr_fd with potential senders using any of the existing  FD
+       sharing  mechanisms  (like pidfd_getfd(2) or socket sendmsg(2)). Access
+       to  uintr_fd  allows  a  sender  to  generate  an  interrupt  with  the
+       associated  vector.  Upon  interrupt delivery, the interrupt handler is
+       invoked with the vector number pushed onto the stack  to  identify  the
+       source of the interrupt.
+
+       4)  Each  thread has a local flag called User Interrupt flag (UIF). The
+       thread can set or clear this flag to enable or disable interrupts.  The
+       default value of UIF is always 0 (Interrupts disabled). A receiver must
+       execute the _stui() intrinsic instruction  at  some  point  (before  or
+       anytime  after  registration)  to  start  receiving user interrupts. To
+       disable interrupts during critical sections the  thread  can  call  the
+       _clui() instruction to clear UIF.
+
+       5a)  For  sending a user IPI, the sender task registers with the kernel
+       using uintr_register_sender(2). The  kernel  would  setup  the  routing
+       tables to connect the sender and receiver. The syscall returns an index
+       that can be used with the 'SENDUIPI <index>' instruction to send a user
+       IPI.   If  the receiver is running, the interrupt is delivered directly
+       to the receiver without any kernel intervention.
+
+       5b) If the sender is the kernel or an external source, the uintr_fd can
+       be  passed  onto the related kernel entity to allow them to connect and
+       generate the user interrupt.  <The exact details of this API are  still
+       being worked upon.>
+
+       6)  The  receiver  can block in the kernel while it is waiting for user
+       interrupts to get delivered using uintr_wait(2). If  the  receiver  has
+       been  context switched out due to other reasons the user interrupt will
+       be delivered when the receiver gets scheduled back in.
+
+       <The behavior when the receiver has made  some  other  blocking  system
+       call like sleep(2) or read(2) is still to be decided. We are evaluating
+       if a thread made another blocking syscall  should  be  interrupted  and
+       woken  up  when a user interrupt arrives for that thread. uintr_wait(2)
+       has been implemented as a placeholder in the meantime.>
+
+       7) The sender and receiver are expected to coordinate and then call the
+       teardown syscalls to terminate the connection:
+         a. A sender unregisters with uintr_unregister_sender(2)
+         b. A vector is unregistered using close(uintr_fd)
+         c. A receiver unregisters with uintr_unregister_handler(2)
+
+       If  the  sender  and  receiver  aren't  able to coordinate, some shared
+       kernel resources between them would  get  freed  later  when  the  file
+       descriptors get released automatically on process exit.
+
+
+       Multi-threaded  applications  need to be careful when using Uintr since
+       it is a thread specific feature. Actions by one thread don't reflect on
+       other threads of the same application.
+
+
+   Toolchain support
+       Support  has  added  to  GCC(11.1)  and Binutils(2.36.1) to enable user
+       interrupt intrinsic instructions and compiler flag (-muintr).
+
+       The "(interrupt)" attribute can be used to compile a function as a user
+       interrupt  handler. In conjunction with the 'muintr' flag, the compiler
+       would:
+         - Generate the entry  and  exit  sequences  for  the  User  interrupt
+       handler
+         - Handle the saving and restoring of registers
+         - Call uiret to return from a user interrupt handler
+
+       User    Interrupts    related   compiler   intrinsic   instructions   -
+       <x86gprintrin.h>:
+
+       _clui() - Disable user interrupts - clear UIF (User Interrupt Flag).
+
+       _stui() - enable user interrupts - set UIF.
+
+       _testui() - test current value of UIF.
+
+       _uiret() - return from a user interrupt handler.
+
+       _senduipi <uipi_index> -  send  a  user  IPI  to  a  target  task.  The
+       uipi_index is obtained using uintr_register_sender(2).
+
+
+   Interrupt handler restrictions
+       There are restrictions on what can be done in a user interrupt handler.
+
+       For  example,  the  handler  and  the functions called from the handler
+       should only use general purpose registers.
+
+       For   details   refer   the   Uintr   compiler    programming    guide.
+       https://github.com/intel/uintr-compiler-guide/blob/uintr-
+       gcc-11.1/UINTR-compiler-guide.pdf
+
+
+CONFORMING TO
+              Uintr related system calls are Linux specific.
+
+EXAMPLES
+   Build
+       To compile this sample an updated toolchain is needed.
+        - Use GCC release 11 or higher &
+        - Use Binutils release 2.36 or higher
+
+       gcc -muintr -mgeneral-regs-only -minline-all-stringops uipi_sample.c -lpthread -o uipi_sample
+
+
+   Run
+       $./uipi_sample
+       Receiver enabled interrupts
+       Sending IPI from sender thread
+            -- User Interrupt handler --
+       Success
+
+
+   Program source
+       #define _GNU_SOURCE
+       #include <pthread.h>
+       #include <stdio.h>
+       #include <stdlib.h>
+       #include <syscall.h>
+       #include <unistd.h>
+       #include <x86gprintrin.h>
+
+       #define __NR_uintr_register_handler     449
+       #define __NR_uintr_unregister_handler   450
+       #define __NR_uintr_create_fd       451
+       #define __NR_uintr_register_sender 452
+       #define __NR_uintr_unregister_sender    453
+
+       #define uintr_register_handler(handler, flags)    syscall(__NR_uintr_register_handler, handler, flags)
+       #define uintr_unregister_handler(flags)      syscall(__NR_uintr_unregister_handler, flags)
+       #define uintr_create_fd(vector, flags)       syscall(__NR_uintr_create_fd, vector, flags)
+       #define uintr_register_sender(fd, flags)     syscall(__NR_uintr_register_sender, fd, flags)
+       #define uintr_unregister_sender(fd, flags)   syscall(__NR_uintr_unregister_sender, fd, flags)
+
+       unsigned int uintr_received;
+       unsigned int uintr_fd;
+
+       void __attribute__ ((interrupt)) uintr_handler(struct __uintr_frame *ui_frame,
+                                    unsigned long long vector)
+       {
+            static const char print[] = "\t-- User Interrupt handler --\n";
+
+            write(STDOUT_FILENO, print, sizeof(print) - 1);
+            uintr_received = 1;
+       }
+
+       void *sender_thread(void *arg)
+       {
+            int uipi_index;
+
+            uipi_index = uintr_register_sender(uintr_fd, 0);
+            if (uipi_index < 0) {
+                 printf("Sender register error\n");
+                 exit(EXIT_FAILURE);
+            }
+
+            printf("Sending IPI from sender thread\n");
+            _senduipi(uipi_index);
+
+            uintr_unregister_sender(uintr_fd, 0);
+
+            return NULL;
+       }
+
+       int main(int argc, char *argv[])
+       {
+            pthread_t pt;
+
+            if (uintr_register_handler(uintr_handler, 0)) {
+                 printf("Interrupt handler register error\n");
+                 exit(EXIT_FAILURE);
+            }
+
+            uintr_fd = uintr_create_fd(0, 0);
+            if (uintr_fd < 0) {
+                 printf("Interrupt vector registration error\n");
+                 exit(EXIT_FAILURE);
+            }
+
+            _stui();
+            printf("Receiver enabled interrupts\n");
+
+            if (pthread_create(&pt, NULL, &sender_thread, NULL)) {
+                 printf("Error creating sender thread\n");
+                 exit(EXIT_FAILURE);
+            }
+
+            /* Do some other work */
+            while (!uintr_received)
+                 usleep(1);
+
+            pthread_join(pt, NULL);
+            close(uintr_fd);
+            uintr_unregister_handler(0);
+
+            printf("Success\n");
+            exit(EXIT_SUCCESS);
+       }
+
+
+NOTES
+       Currently, there is no glibc wrapper for the Uintr related system call;
+       call  the system calls using syscall(2).
+
+
+
+                                                                      UINTR(7)
diff --git a/tools/uintr/manpages/1_register_receiver.txt b/tools/uintr/manpages/1_register_receiver.txt
new file mode 100644
index 000000000000..4b6652c94faa
--- /dev/null
+++ b/tools/uintr/manpages/1_register_receiver.txt
@@ -0,0 +1,122 @@
+uintr_register_handler(2)     System Calls Manual    uintr_register_handler(2)
+
+
+
+NAME
+       uintr_register_handler - register a user interrupt handler
+
+
+SYNOPSIS
+        int uintr_register_handler(u64 handler_address, unsigned int flags);
+
+
+DESCRIPTION
+       uintr_register_handler()  registers  a  user  interrupt handler for the
+       calling process. In case of multi-threaded processes the user interrupt
+       handler is only registered for the thread that makes this system call.
+
+       The  handler_address  is  the  function  that would be invoked when the
+       process receives a user interrupt. The function should  be  defined  as
+       below:
+
+       void __attribute__ ((interrupt)) ui_handler(struct __uintr_frame *frame,
+                                                   unsigned long long vector)
+
+       For  more  details  and  an  example  for  the handler definition refer
+       uintr(7).
+
+       Providing an invalid handler_address could lead to  undefined  behavior
+       for the process.
+
+       The  flags  argument is reserved for future use.  Currently, it must be
+       specified as 0.
+
+       Each user thread can register only one interrupt handler.  Each  thread
+       that  would  like to be a receiver must register once. The registration
+       is not inherited across forks(2) or when additional threads are created
+       within the same process.
+
+       Each thread within a process gets its own interrupt vector space for 64
+       vectors. The vector number  is  pushed  onto  the  stack  when  a  user
+       interrupt  is  delivered.  Since  the  vector space is per-thread, each
+       receiver can receive up to 64 unique interrupt events.
+
+       For information on creating uintr_fd to register and  manage  interrupt
+       vectors, refer uintr_create_fd(2) system call.
+
+       Once an interrupt handler is registered it cannot be changed before the
+       handler  is  unregistered  via   uintr_unregister_handler(2).   Calling
+       uintr_unregister_handler(2)   would   however  invalidate  the  current
+       interrupt resources registered with the kernel.
+
+       The interrupt handler gets invoked only while the process  is  running.
+       If  the  process  is scheduled out or blocked in the kernel, interrupts
+       will be delivered when the process is scheduled again. <A mechanism  to
+       unblock a process as soon as a user interrupt is posted is being worked
+       upon.>
+
+
+   Interrupt handler restrictions
+       There are restrictions on what can be done in a user interrupt handler.
+
+       For example, the handler and the  functions  called  from  the  handler
+       should only use general purpose registers.
+
+       For    details    refer   the   Uintr   compiler   programming   guide.
+       https://github.com/intel/uintr-compiler-guide/blob/uintr-
+       gcc-11.1/UINTR-compiler-guide.pdf
+
+
+   Security implications
+       A  lot  of security issues that are applicable to signal handlers, also
+       apply to user interrupt handlers.
+
+       The user interrupt handler  by-itself  need  not  be  re-entrant  since
+       interrupts  are automatically disabled when the handler is invoked. But
+       this isn't valid if the handler is shared between multiple  threads  or
+       nested interrupts have been enabled.
+
+       Similar  to  signal handlers, the functions that are called from a user
+       interrupt should be async-signal-safe.  Refer  signal-safety(7)  for  a
+       discussion of async-signal-safe functions.
+
+       It  is  recommended  to  disable  interrupts  using _clui() instruction
+       before executing any privileged code. Doing so  would  prevent  a  user
+       interrupt handler from running at a higher privilege level.
+
+
+RETURN VALUE
+       On  success,  uintr_register_handler()  returns  0.   On  error,  -1 is
+       returned and errno is set to indicate the cause of the error.
+
+
+ERRORS
+       EOPNOTSUPP  Underlying hardware doesn't have support for Uintr.
+
+       EINVAL      flags is not 0.
+
+       EFAULT      handler address is not valid.
+
+       ENOMEM      The system is out of available memory.
+
+       EBUSY       An interrupt handler has already been registered.
+
+
+VERSIONS
+       uintr_register_handler() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+       uintr_register_handler() is Linux specific.
+
+
+NOTES
+       Currently, there is no glibc wrapper for  this  system  call;  call  it
+       using syscall(2).
+
+       The  user  interrupt  related  system  calls  need  hardware support to
+       generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+                                                     uintr_register_handler(2)
diff --git a/tools/uintr/manpages/2_unregister_receiver.txt b/tools/uintr/manpages/2_unregister_receiver.txt
new file mode 100644
index 000000000000..dd6981f33597
--- /dev/null
+++ b/tools/uintr/manpages/2_unregister_receiver.txt
@@ -0,0 +1,62 @@
+uintr_unregister_handler(2)   System Calls Manual  uintr_unregister_handler(2)
+
+
+
+NAME
+       uintr_unregister_handler - unregister a user interrupt handler
+
+
+SYNOPSIS
+        int uintr_unregister_handler(unsigned int flags);
+
+
+DESCRIPTION
+       uintr_unregister_handler()  unregisters  a  previously  registered user
+       interrupt handler. If  no  interrupt  handler  was  registered  by  the
+       process uintr_unregister_handler() would return an error.
+
+       Since  interrupt handler is local to a thread, only the thread that has
+       registered      via      uintr_register_handler(2)       can       call
+       uintr_unregister_handler().
+
+       The  interrupt  resources  such as interrupt vectors and uintr_fd, that
+       have been allocated  for  this  thread,  would  be  deactivated.  Other
+       senders posting interrupts to this thread will not be delivered.
+
+       The  kernel  does not automatically close the uintr_fds related to this
+       process/thread   when   uintr_unregister_handler()   is   called.   The
+       application  is  expected  to  close the unused uintr_fds before or the
+       after the handler has been unregistered.
+
+
+RETURN VALUE
+       On success, uintr_unregister_handler() returns  0.   On  error,  -1  is
+       returned and errno is set to indicate the cause of the error.
+
+
+ERRORS
+       EOPNOTSUPP  Underlying hardware doesn't have support for Uintr.
+
+       EINVAL       flags is not 0.
+
+       EINVAL       No registered user interrupt handler.
+
+
+VERSIONS
+       uintr_unregister_handler() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+       uintr_unregister_handler() is Linux specific.
+
+
+NOTES
+       Currently,  there  is  no  glibc  wrapper for this system call; call it
+       using syscall(2).
+
+       The user interrupt  related  system  calls  need  hardware  support  to
+       generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+                                                   uintr_unregister_handler(2)
diff --git a/tools/uintr/manpages/3_create_fd.txt b/tools/uintr/manpages/3_create_fd.txt
new file mode 100644
index 000000000000..e90b0dce2703
--- /dev/null
+++ b/tools/uintr/manpages/3_create_fd.txt
@@ -0,0 +1,104 @@
+uintr_create_fd(2)            System Calls Manual           uintr_create_fd(2)
+
+
+
+NAME
+       uintr_create_fd - Create a user interrupt file descriptor - uintr_fd
+
+
+SYNOPSIS
+        int uintr_create_fd(u64 vector, unsigned int flags);
+
+
+DESCRIPTION
+       uintr_create_fd()  allocates  a  new  user  interrupt  file  descriptor
+       (uintr_fd) based on the vector registered by the calling  process.  The
+       uintr_fd  can  be  shared  with other processes and the kernel to allow
+       them to generate interrupts with the associated vector.
+
+       The caller must have registered a handler via uintr_register_handler(2)
+       before attempting to create uintr_fd. The interrupts generated based on
+       this uintr_fd will be delivered only to the thread  that  created  this
+       file  descriptor.  A  unique  uintr_fd  is  generated  for  each vector
+       registered using uintr_create_fd().
+
+       Each thread has a private vector space of 64 vectors ranging from 0-63.
+       Vector number 63 has the highest priority while vector number 0 has the
+       lowest.  If two or more interrupts are pending to be delivered then the
+       interrupt  with  the  higher  vector  number  will  be  delivered first
+       followed by the ones with lower vector numbers. Applications can choose
+       appropriate  vector  numbers  to  prioritize  certain  interrupts  over
+       others.
+
+       Upon interrupt delivery, the handler is invoked with the vector  number
+       pushed  onto  the  stack  to help identify the source of the interrupt.
+       Since the vector space is per-thread, each receiver can receive  up  to
+       64 unique interrupt events.
+
+       A receiver can choose to share the same uintr_fd with multiple senders.
+       Since an interrupt with the same vector number would be delivered,  the
+       receiver  would  need  to  use  other  mechanisms to identify the exact
+       source of the interrupt.
+
+       The flags argument is reserved for future use.  Currently, it  must  be
+       specified as 0.
+
+       close(2)
+             When the file descriptor is no longer required it should be
+             closed.  When all file descriptors associated with the same
+             uintr_fd object have been closed, the resources for object are
+             freed by the kernel.
+
+       fork(2)
+             A copy of the file descriptor created by uintr_create_fd() is
+             inherited by the child produced by fork(2).  The duplicate file
+             descriptor is associated with the same uintr_fd object. The
+             close-on-exec flag (FD_CLOEXEC; see fcntl(2)) is set on the
+             file descriptor returned by uintr_create_fd().
+
+       For  information  on  how  to  generate  interrupts with uintr_fd refer
+       uintr_register_sender(2).
+
+
+RETURN VALUE
+       On success, uintr_create_fd() returns a new uintr_fd  file  descriptor.
+       On  error, -1 is returned and errno is set to indicate the cause of the
+       error.
+
+
+ERRORS
+       EOPNOTSUPP  Underlying hardware doesn't have support for Uintr.
+
+       EINVAL      flags is not 0.
+
+       EFAULT      handler address is not valid.
+
+       EMFILE        The  per-process  limit  on  the  number  of  open   file
+       descriptors has been reached.
+
+       ENFILE        The  system-wide  limit on the total number of open files
+       has been reached.
+
+       ENODEV       Could not mount (internal) anonymous inode device.
+
+       ENOMEM      The system is out of available memory to allocate uintr_fd.
+
+
+VERSIONS
+       uintr_create_fd() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+       uintr_create_fd() is Linux specific.
+
+
+NOTES
+       Currently, there is no glibc wrapper for  this  system  call;  call  it
+       using syscall(2).
+
+       The  user  interrupt  related  system  calls  need  hardware support to
+       generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+                                                            uintr_create_fd(2)
diff --git a/tools/uintr/manpages/4_register_sender.txt b/tools/uintr/manpages/4_register_sender.txt
new file mode 100644
index 000000000000..1dc17f4c041f
--- /dev/null
+++ b/tools/uintr/manpages/4_register_sender.txt
@@ -0,0 +1,121 @@
+uintr_register_sender(2)      System Calls Manual     uintr_register_sender(2)
+
+
+
+NAME
+       uintr_register_sender - Register a user inter-process interrupt sender
+
+
+SYNOPSIS
+        int uintr_register_sender(int uintr_fd, unsigned int flags);
+
+
+DESCRIPTION
+       uintr_register_sender() allows a sender process to connect with a Uintr
+       receiver  based  on  the  uintr_fd.  It  returns  a  user   IPI   index
+       (uipi_index)  that  the  sender process can use in conjunction with the
+       SENDUIPI instruction to generate a user IPI.
+
+       When a sender executes 'SENDUIPI  <uipi_index>',  a  user  IPI  can  be
+       delivered by the hardware to the receiver without any intervention from
+       the kernel. Upon IPI delivery, the handler is invoked with  the  vector
+       number,  associated  with  uintr_fd,  pushed  onto  the  stack  to help
+       identify the source of the interrupt.
+
+       If the receiver for the thread is running the hardware  would  directly
+       deliver the user IPI to the receiver. If the receiver is not running or
+       has disabled receiving  interrupts  using  the  STUI  instruction,  the
+       interrupt  will  be stored in memory and delivered when the receiver is
+       able to receive it.
+
+       If the sender tries to send multiple IPIs while  the  receiver  is  not
+       able  to  receive  them then all the IPIs with the same vector would be
+       coalesced.  Only a single IPI per vector would be delivered.
+
+       uintr_register_sender() can be used to connect with multiple uintr_fds.
+       uintr_register_sender()  would  return  a  unique  uipi_index  for each
+       uintr_fd the sender connects with.
+
+       In case of a multi-threaded process, the uipi_index is only  valid  for
+       the thread that registered itself. Other threads would need to register
+       themselves if they intend to be a user IPI sender.  Executing  SENDUIPI
+       on  different threads can have varying results based on the connections
+       that have been setup.
+
+       <We  are  also  considering  an  alternate  approach  where  the   same
+       uipi_index  would  be  valid  for all threads that are part of the same
+       process.  All threads would see consistent SENDUIPI behaviour  in  that
+       case.>
+
+       If    a    process    uses    SENDUIPI    without   registering   using
+       uintr_register_sender() it receives a SIGILL signal. If a process  uses
+       an  illegal  uipi_index, it receives a SIGSEGV signal. See sigaction(2)
+       for details of the information available with that signal.
+
+       The flags argument is reserved for future use.  Currently, it  must  be
+       specified as 0.
+
+       close(2)
+             When the file descriptor is no longer required it should be
+             closed.  When all file descriptors associated with the same
+             uintr_fd object have been closed, the resources for object are
+             freed by the kernel. Freeing the uintr_fd object would also
+             result in the associated uipi_index to be freed.
+
+       fork(2)
+             A copy of uintr_fd is inherited by the child produced by
+             fork(2). However the uipi_index would not get inherited by the
+             child. If the child wants to send a user IPI it would have to
+             explicitly register itself using the uintr_register_sender()
+             system call.
+
+       For    information    on    how    to   unregister   a   sender   refer
+       uintr_unregister_sender(2).
+
+
+RETURN VALUE
+       On success, uintr_register_sender() returns a  new  user  IPI  index  -
+       uipi_index.  On  error, -1 is returned and errno is set to indicate the
+       cause of the error.
+
+
+ERRORS
+       EOPNOTSUPP  Underlying hardware doesn't have support for uintr(7).
+
+       EOPNOTSUPP  uintr_fd does not refer to a Uintr instance.
+
+       EBADF       The uintr_fd passed to the kernel is invalid.
+
+       EINVAL      flags is not 0.
+
+       EISCONN     A connection to this uintr_fd has already been established.
+
+       ECONNRESET  The user interrupt receiver has disabled the connection.
+
+       ESHUTDOWN   The user interrupt receiver has exited the connection.
+
+       ENOSPC       No uipi_index can be allocated. The system has run out  of
+       the available user IPI indexes.
+
+       ENOMEM       The  system  is out of available memory to register a user
+       IPI sender.
+
+
+VERSIONS
+       uintr_register_sender() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+       uintr_register_sender() is Linux specific.
+
+
+NOTES
+       Currently, there is no glibc wrapper for  this  system  call;  call  it
+       using syscall(2).
+
+       The  user  interrupt  related  system  calls  need  hardware support to
+       generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+                                                      uintr_register_sender(2)
diff --git a/tools/uintr/manpages/5_unregister_sender.txt b/tools/uintr/manpages/5_unregister_sender.txt
new file mode 100644
index 000000000000..31a8c574dc25
--- /dev/null
+++ b/tools/uintr/manpages/5_unregister_sender.txt
@@ -0,0 +1,79 @@
+uintr_unregister_sender(2)    System Calls Manual   uintr_unregister_sender(2)
+
+
+
+NAME
+       uintr_unregister_sender  -  Unregister  a  user inter-process interrupt
+       sender
+
+
+SYNOPSIS
+        int uintr_unregister_sender(int uintr_fd, unsigned int flags);
+
+
+DESCRIPTION
+       uintr_unregister_sender() unregisters a sender process from a  uintr_fd
+       it had previously connected with. If no connection is present with this
+       uintr_fd the system call return an error.
+
+       The uipi_index that was allocated during uintr_register_sender(2)  will
+       also be freed. If a process tries to use a uipi_index after it has been
+       freed it would receive a SIGSEGV signal.
+
+       In case of a multi-threaded process uintr_unregister_sender() will only
+       disconnect  the thread that makes this call. Other threads can continue
+       to use their connection with the uintr_fd based on their uipi_index.
+
+       <We are considering an  alternate  approach  where  all  threads  in  a
+       process  see  a  consistent  view  of  the  uipi_index.  In  that case,
+       uintr_unregister_sender() would disconnect all threads from uintr_fd.>
+
+       The flags argument is reserved for future use.  Currently, it  must  be
+       specified as 0.
+
+       close(2)
+             When the file descriptor is no longer required it should be
+             closed.  When all file descriptors associated with the same
+             uintr_fd object have been closed, the resources for object are
+             freed by the kernel. Freeing the uintr_fd object would also
+             result in the associated uipi_index to be freed.
+
+       The  behavior  of  uintr_unregister_sender() system call after uintr_fd
+       has been close is undefined.
+
+
+RETURN VALUE
+       On success,  uintr_unregister_sender()  returns  0.  On  error,  -1  is
+       returned and errno is set to indicate the cause of the error.
+
+
+ERRORS
+       EOPNOTSUPP  Underlying hardware doesn't have support for uintr(7).
+
+       EOPNOTSUPP  uintr_fd does not refer to a Uintr instance.
+
+       EBADF       The uintr_fd passed to the kernel is invalid.
+
+       EINVAL      flags is not 0.
+
+       EINVAL      No connection has been setup with this uintr_fd.
+
+
+VERSIONS
+       uintr_unregister_sender() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+       uintr_unregister_sender() is Linux specific.
+
+
+NOTES
+       Currently,  there  is  no  glibc  wrapper for this system call; call it
+       using syscall(2).
+
+       The user interrupt  related  system  calls  need  hardware  support  to
+       generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+                                                    uintr_unregister_sender(2)
diff --git a/tools/uintr/manpages/6_wait.txt b/tools/uintr/manpages/6_wait.txt
new file mode 100644
index 000000000000..f281a6ce83aa
--- /dev/null
+++ b/tools/uintr/manpages/6_wait.txt
@@ -0,0 +1,59 @@
+uintr_wait(2)                 System Calls Manual                uintr_wait(2)
+
+
+
+NAME
+       uintr_wait - wait for user interrupts
+
+
+SYNOPSIS
+        int uintr_wait(unsigned int flags);
+
+
+DESCRIPTION
+       uintr_wait()  causes  the  calling process (or thread) to sleep until a
+       user interrupt is delivered.
+
+       uintr_wait() will block in the kernel only when a interrupt handler has
+       been registered using uintr_register_handler(2)
+
+       <uintr_wait() is a placeholder syscall while we decide on the behaviour
+       of blocking system calls like sleep(2) and read(2) being interrupted by
+       uintr(7).>
+
+
+RETURN VALUE
+       uintr_wait()  returns  only  when  a user interrupt is received and the
+       interrupt handler function returned.  In this case, -1 is returned  and
+       errno is set to EINTR.
+
+
+ERRORS
+       EOPNOTSUPP  Underlying hardware doesn't have support for Uintr.
+
+       EOPNOTSUPP  No interrupt handler registered.
+
+       EINVAL        flags is not 0.
+
+       EINTR        A  user  interrupt  was received and the interrupt handler
+       returned.
+
+
+VERSIONS
+       uintr_wait() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+       uintr_wait() is Linux specific.
+
+
+NOTES
+       Currently, there is no glibc wrapper for  this  system  call;  call  it
+       using syscall(2).
+
+       The  user  interrupt  related  system  calls  need  hardware support to
+       generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+                                                                 uintr_wait(2)
-- 
2.33.0


  reply	other threads:[~2021-09-13 20:04 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 ` Sohil Mehta [this message]
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
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=20210913200132.3396598-2-sohil.mehta@intel.com \
    --to=sohil.mehta@intel.com \
    --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=tglx@linutronix.de \
    --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.