lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210913200132.3396598-2-sohil.mehta@intel.com>
Date:   Mon, 13 Sep 2021 13:01:20 -0700
From:   Sohil Mehta <sohil.mehta@...el.com>
To:     x86@...nel.org
Cc:     Sohil Mehta <sohil.mehta@...el.com>,
        Tony Luck <tony.luck@...el.com>,
        Dave Hansen <dave.hansen@...el.com>,
        Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
        "H . Peter Anvin" <hpa@...or.com>,
        Andy Lutomirski <luto@...nel.org>,
        Jens Axboe <axboe@...nel.dk>,
        Christian Brauner <christian@...uner.io>,
        Peter Zijlstra <peterz@...radead.org>,
        Shuah Khan <shuah@...nel.org>, Arnd Bergmann <arnd@...db.de>,
        Jonathan Corbet <corbet@....net>,
        Ashok Raj <ashok.raj@...el.com>,
        Jacob Pan <jacob.jun.pan@...ux.intel.com>,
        Gayatri Kammela <gayatri.kammela@...el.com>,
        Zeng Guang <guang.zeng@...el.com>,
        Dan Williams <dan.j.williams@...el.com>,
        Randy E Witt <randy.e.witt@...el.com>,
        Ravi V Shankar <ravi.v.shankar@...el.com>,
        Ramesh Thomas <ramesh.thomas@...el.com>,
        linux-api@...r.kernel.org, linux-arch@...r.kernel.org,
        linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org
Subject: [RFC PATCH 01/13] x86/uintr/man-page: Include man pages draft for reference

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@...el.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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ