Commit 6c8e6bb2 authored by Sukadev Bhattiprolu's avatar Sukadev Bhattiprolu Committed by Michael Ellerman

powerpc/vas: Add support for user receive window

Add support for user space receive window (for the Fast thread-wakeup
coprocessor type)
Signed-off-by: default avatarSukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 61f3cca8
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/cred.h> #include <linux/cred.h>
#include <asm/switch_to.h>
#include <asm/ppc-opcode.h>
#include "vas.h" #include "vas.h"
#include "copy-paste.h" #include "copy-paste.h"
...@@ -597,6 +598,32 @@ static void put_rx_win(struct vas_window *rxwin) ...@@ -597,6 +598,32 @@ static void put_rx_win(struct vas_window *rxwin)
atomic_dec(&rxwin->num_txwins); atomic_dec(&rxwin->num_txwins);
} }
/*
* Find the user space receive window given the @pswid.
* - We must have a valid vasid and it must belong to this instance.
* (so both send and receive windows are on the same VAS instance)
* - The window must refer to an OPEN, FTW, RECEIVE window.
*
* NOTE: We access ->windows[] table and assume that vinst->mutex is held.
*/
static struct vas_window *get_user_rxwin(struct vas_instance *vinst, u32 pswid)
{
int vasid, winid;
struct vas_window *rxwin;
decode_pswid(pswid, &vasid, &winid);
if (vinst->vas_id != vasid)
return ERR_PTR(-EINVAL);
rxwin = vinst->windows[winid];
if (!rxwin || rxwin->tx_win || rxwin->cop != VAS_COP_TYPE_FTW)
return ERR_PTR(-EINVAL);
return rxwin;
}
/* /*
* Get the VAS receive window associated with NX engine identified * Get the VAS receive window associated with NX engine identified
* by @cop and if applicable, @pswid. * by @cop and if applicable, @pswid.
...@@ -610,10 +637,10 @@ static struct vas_window *get_vinst_rxwin(struct vas_instance *vinst, ...@@ -610,10 +637,10 @@ static struct vas_window *get_vinst_rxwin(struct vas_instance *vinst,
mutex_lock(&vinst->mutex); mutex_lock(&vinst->mutex);
if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) if (cop == VAS_COP_TYPE_FTW)
rxwin = vinst->rxwin[cop] ?: ERR_PTR(-EINVAL); rxwin = get_user_rxwin(vinst, pswid);
else else
rxwin = ERR_PTR(-EINVAL); rxwin = vinst->rxwin[cop] ?: ERR_PTR(-EINVAL);
if (!IS_ERR(rxwin)) if (!IS_ERR(rxwin))
atomic_inc(&rxwin->num_txwins); atomic_inc(&rxwin->num_txwins);
...@@ -937,10 +964,9 @@ static void init_winctx_for_txwin(struct vas_window *txwin, ...@@ -937,10 +964,9 @@ static void init_winctx_for_txwin(struct vas_window *txwin,
winctx->tx_word_mode = txattr->tx_win_ord_mode; winctx->tx_word_mode = txattr->tx_win_ord_mode;
winctx->rsvd_txbuf_count = txattr->rsvd_txbuf_count; winctx->rsvd_txbuf_count = txattr->rsvd_txbuf_count;
if (winctx->nx_win) {
winctx->data_stamp = true;
winctx->intr_disable = true; winctx->intr_disable = true;
} if (winctx->nx_win)
winctx->data_stamp = true;
winctx->lpid = txattr->lpid; winctx->lpid = txattr->lpid;
winctx->pidr = txattr->pidr; winctx->pidr = txattr->pidr;
...@@ -985,6 +1011,14 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, ...@@ -985,6 +1011,14 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
if (!tx_win_args_valid(cop, attr)) if (!tx_win_args_valid(cop, attr))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
/*
* If caller did not specify a vasid but specified the PSWID of a
* receive window (applicable only to FTW windows), use the vasid
* from that receive window.
*/
if (vasid == -1 && attr->pswid)
decode_pswid(attr->pswid, &vasid, NULL);
vinst = find_vas_instance(vasid); vinst = find_vas_instance(vasid);
if (!vinst) { if (!vinst) {
pr_devel("vasid %d not found!\n", vasid); pr_devel("vasid %d not found!\n", vasid);
...@@ -1031,6 +1065,14 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, ...@@ -1031,6 +1065,14 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
} }
} }
/*
* Now that we have a send window, ensure context switch issues
* CP_ABORT for this thread.
*/
rc = -EINVAL;
if (set_thread_uses_vas() < 0)
goto free_window;
set_vinst_win(vinst, txwin); set_vinst_win(vinst, txwin);
return txwin; return txwin;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment