linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Haren Myneni <haren@linux.ibm.com>
To: mpe@ellerman.id.au
Cc: mikey@neuling.org, srikar@linux.vnet.ibm.com,
	frederic.barrat@fr.ibm.com, ajd@linux.ibm.com,
	linux-kernel@vger.kernel.org, npiggin@gmail.com,
	hch@infradead.org, oohall@gmail.com, clg@kaod.org,
	sukadev@linux.vnet.ibm.com, linuxppc-dev@lists.ozlabs.org,
	herbert@gondor.apana.org.au
Subject: [PATCH v10 08/14] powerpc/vas: Update CSB and notify process for fault CRBs
Date: Thu, 02 Apr 2020 00:14:54 -0700	[thread overview]
Message-ID: <1585811694.2275.52.camel@hbabu-laptop> (raw)
In-Reply-To: <1585810846.2275.23.camel@hbabu-laptop>


Applications polls on CSB for the status update after requests are
issued. NX process these requests and update the CSB with the status.
If it encounters translation error, pastes CRB in fault FIFO and
raises an interrupt. The kernel handles fault by reading CRB from
fault FIFO and process the fault CRB.

For each fault CRB, update fault address in CRB (fault_storage_addr)
and translation error status in CSB so that user space can touch the
fault address and resend the request. If the user space passed invalid
CSB address send signal to process with SIGSEGV.

In the case of multi-thread applications, child thread may not be
available. So if the task is not running, send signal to tgid.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
 arch/powerpc/platforms/powernv/vas-fault.c | 126 ++++++++++++++++++++++++++++-
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/vas-fault.c b/arch/powerpc/platforms/powernv/vas-fault.c
index 0da8358..354577d 100644
--- a/arch/powerpc/platforms/powernv/vas-fault.c
+++ b/arch/powerpc/platforms/powernv/vas-fault.c
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/kthread.h>
+#include <linux/sched/signal.h>
 #include <linux/mmu_context.h>
 #include <asm/icswx.h>
 
@@ -26,6 +27,128 @@
 #define VAS_FAULT_WIN_FIFO_SIZE	(4 << 20)
 
 /*
+ * Update the CSB to indicate a translation error.
+ *
+ * User space will be polling on CSB after the request is issued.
+ * If NX can handle the request without any issues, it updates CSB.
+ * Whereas if NX encounters page fault, the kernel will handle the
+ * fault and update CSB with translation error.
+ *
+ * If we are unable to update the CSB means copy_to_user failed due to
+ * invalid csb_addr, send a signal to the process.
+ */
+static void update_csb(struct vas_window *window,
+			struct coprocessor_request_block *crb)
+{
+	struct coprocessor_status_block csb;
+	struct kernel_siginfo info;
+	struct task_struct *tsk;
+	void __user *csb_addr;
+	struct pid *pid;
+	int rc;
+
+	/*
+	 * NX user space windows can not be opened for task->mm=NULL
+	 * and faults will not be generated for kernel requests.
+	 */
+	if (WARN_ON_ONCE(!window->mm || !window->user_win))
+		return;
+
+	csb_addr = (void __user *)be64_to_cpu(crb->csb_addr);
+
+	memset(&csb, 0, sizeof(csb));
+	csb.cc = CSB_CC_TRANSLATION;
+	csb.ce = CSB_CE_TERMINATION;
+	csb.cs = 0;
+	csb.count = 0;
+
+	/*
+	 * NX operates and returns in BE format as defined CRB struct.
+	 * So saves fault_storage_addr in BE as NX pastes in FIFO and
+	 * expects user space to convert to CPU format.
+	 */
+	csb.address = crb->stamp.nx.fault_storage_addr;
+	csb.flags = 0;
+
+	pid = window->pid;
+	tsk = get_pid_task(pid, PIDTYPE_PID);
+	/*
+	 * Process closes send window after all pending NX requests are
+	 * completed. In multi-thread applications, a child thread can
+	 * open a window and can exit without closing it. May be some
+	 * requests are pending or this window can be used by other
+	 * threads later. We should handle faults if NX encounters
+	 * pages faults on these requests. Update CSB with translation
+	 * error and fault address. If csb_addr passed by user space is
+	 * invalid, send SEGV signal to pid saved in window. If the
+	 * child thread is not running, send the signal to tgid.
+	 * Parent thread (tgid) will close this window upon its exit.
+	 *
+	 * pid and mm references are taken when window is opened by
+	 * process (pid). So tgid is used only when child thread opens
+	 * a window and exits without closing it.
+	 */
+	if (!tsk) {
+		pid = window->tgid;
+		tsk = get_pid_task(pid, PIDTYPE_PID);
+		/*
+		 * Parent thread (tgid) will be closing window when it
+		 * exits. So should not get here.
+		 */
+		if (WARN_ON_ONCE(!tsk))
+			return;
+	}
+
+	/* Return if the task is exiting. */
+	if (tsk->flags & PF_EXITING) {
+		put_task_struct(tsk);
+		return;
+	}
+
+	use_mm(window->mm);
+	rc = copy_to_user(csb_addr, &csb, sizeof(csb));
+	/*
+	 * User space polls on csb.flags (first byte). So add barrier
+	 * then copy first byte with csb flags update.
+	 */
+	if (!rc) {
+		csb.flags = CSB_V;
+		/* Make sure update to csb.flags is visible now */
+		smp_mb();
+		rc = copy_to_user(csb_addr, &csb, sizeof(u8));
+	}
+	unuse_mm(window->mm);
+	put_task_struct(tsk);
+
+	/* Success */
+	if (!rc)
+		return;
+
+	pr_debug("Invalid CSB address 0x%p signalling pid(%d)\n",
+			csb_addr, pid_vnr(pid));
+
+	clear_siginfo(&info);
+	info.si_signo = SIGSEGV;
+	info.si_errno = EFAULT;
+	info.si_code = SEGV_MAPERR;
+	info.si_addr = csb_addr;
+
+	/*
+	 * process will be polling on csb.flags after request is sent to
+	 * NX. So generally CSB update should not fail except when an
+	 * application passes invalid csb_addr. So an error message will
+	 * be displayed and leave it to user space whether to ignore or
+	 * handle this signal.
+	 */
+	rcu_read_lock();
+	rc = kill_pid_info(SIGSEGV, &info, pid);
+	rcu_read_unlock();
+
+	pr_devel("%s(): pid %d kill_proc_info() rc %d\n", __func__,
+			pid_vnr(pid), rc);
+}
+
+/*
  * Process valid CRBs in fault FIFO.
  * NX process user space requests, return credit and update the status
  * in CRB. If it encounters transalation error when accessing CRB or
@@ -124,8 +247,9 @@ irqreturn_t vas_fault_thread_fn(int irq, void *data)
 				vinst->fault_crbs);
 
 			WARN_ON_ONCE(1);
+		} else {
+			update_csb(window, crb);
 		}
-
 	}
 }
 
-- 
1.8.3.1




  parent reply	other threads:[~2020-04-02  7:15 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-02  7:00 [PATCH v10 00/14] powerpc/vas: Page fault handling for user space NX requests Haren Myneni
2020-04-02  7:09 ` [PATCH v10 01/14] powerpc/xive: Define xive_native_alloc_irq_on_chip() Haren Myneni
2020-04-02  7:09 ` [PATCH v10 02/14] powerpc/vas: Define nx_fault_stamp in coprocessor_request_block Haren Myneni
2020-04-02  7:10 ` [PATCH v10 03/14] powerpc/vas: Alloc and setup IRQ and trigger port address Haren Myneni
2020-04-02  8:08   ` Cédric Le Goater
2020-04-02  7:11 ` [PATCH v10 04/14] powerpc/vas: Setup fault window per VAS instance Haren Myneni
2020-04-02  7:11 ` [PATCH v10 05/14] powerpc/vas: Register NX with fault window ID and IRQ port value Haren Myneni
2020-04-02  7:13 ` [PATCH v10 06/14] powerpc/vas: Take reference to PID and mm for user space windows Haren Myneni
2020-04-02  7:13 ` [PATCH v10 07/14] powerpc/vas: Setup thread IRQ handler per VAS instance Haren Myneni
2020-04-02  7:14 ` Haren Myneni [this message]
2020-04-02  7:15 ` [PATCH v10 09/14] powerpc/vas: Return credits after handling fault Haren Myneni
2020-04-02  7:16 ` [PATCH v10 10/14] powerpc/vas: Print CRB and FIFO values Haren Myneni
2020-04-02  7:17 ` [PATCH v10 11/14] powerpc/vas: Do not use default credits for receive window Haren Myneni
2020-04-02  7:18 ` [PATCH v10 12/14] powerpc/vas: Display process stuck message Haren Myneni
2020-04-02  7:19 ` [PATCH v10 13/14] powerpc/vas: Free send window in VAS instance after credits returned Haren Myneni
2020-04-02  7:20 ` [PATCH v10 14/14] powerpc: Use mm_context vas_windows counter to issue CP_ABORT Haren Myneni
2020-04-11 10:28   ` Michael Ellerman
2020-04-14  7:54   ` Haren Myneni
2020-04-03  8:19 ` [PATCH v10 00/14] powerpc/vas: Page fault handling for user space NX requests Cédric Le Goater

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=1585811694.2275.52.camel@hbabu-laptop \
    --to=haren@linux.ibm.com \
    --cc=ajd@linux.ibm.com \
    --cc=clg@kaod.org \
    --cc=frederic.barrat@fr.ibm.com \
    --cc=hch@infradead.org \
    --cc=herbert@gondor.apana.org.au \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mikey@neuling.org \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    --cc=oohall@gmail.com \
    --cc=srikar@linux.vnet.ibm.com \
    --cc=sukadev@linux.vnet.ibm.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).