16
16
#include <linux/log2.h>
17
17
#include <linux/rcupdate.h>
18
18
#include <linux/cred.h>
19
-
19
+ #include <asm/switch_to.h>
20
+ #include <asm/ppc-opcode.h>
20
21
#include "vas.h"
21
22
#include "copy-paste.h"
22
23
@@ -597,6 +598,32 @@ static void put_rx_win(struct vas_window *rxwin)
597
598
atomic_dec (& rxwin -> num_txwins );
598
599
}
599
600
601
+ /*
602
+ * Find the user space receive window given the @pswid.
603
+ * - We must have a valid vasid and it must belong to this instance.
604
+ * (so both send and receive windows are on the same VAS instance)
605
+ * - The window must refer to an OPEN, FTW, RECEIVE window.
606
+ *
607
+ * NOTE: We access ->windows[] table and assume that vinst->mutex is held.
608
+ */
609
+ static struct vas_window * get_user_rxwin (struct vas_instance * vinst , u32 pswid )
610
+ {
611
+ int vasid , winid ;
612
+ struct vas_window * rxwin ;
613
+
614
+ decode_pswid (pswid , & vasid , & winid );
615
+
616
+ if (vinst -> vas_id != vasid )
617
+ return ERR_PTR (- EINVAL );
618
+
619
+ rxwin = vinst -> windows [winid ];
620
+
621
+ if (!rxwin || rxwin -> tx_win || rxwin -> cop != VAS_COP_TYPE_FTW )
622
+ return ERR_PTR (- EINVAL );
623
+
624
+ return rxwin ;
625
+ }
626
+
600
627
/*
601
628
* Get the VAS receive window associated with NX engine identified
602
629
* by @cop and if applicable, @pswid.
@@ -610,10 +637,10 @@ static struct vas_window *get_vinst_rxwin(struct vas_instance *vinst,
610
637
611
638
mutex_lock (& vinst -> mutex );
612
639
613
- if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI )
614
- rxwin = vinst -> rxwin [ cop ] ?: ERR_PTR ( - EINVAL );
640
+ if (cop == VAS_COP_TYPE_FTW )
641
+ rxwin = get_user_rxwin ( vinst , pswid );
615
642
else
616
- rxwin = ERR_PTR (- EINVAL );
643
+ rxwin = vinst -> rxwin [ cop ] ?: ERR_PTR (- EINVAL );
617
644
618
645
if (!IS_ERR (rxwin ))
619
646
atomic_inc (& rxwin -> num_txwins );
@@ -937,10 +964,9 @@ static void init_winctx_for_txwin(struct vas_window *txwin,
937
964
winctx -> tx_word_mode = txattr -> tx_win_ord_mode ;
938
965
winctx -> rsvd_txbuf_count = txattr -> rsvd_txbuf_count ;
939
966
940
- if (winctx -> nx_win ) {
967
+ winctx -> intr_disable = true;
968
+ if (winctx -> nx_win )
941
969
winctx -> data_stamp = true;
942
- winctx -> intr_disable = true;
943
- }
944
970
945
971
winctx -> lpid = txattr -> lpid ;
946
972
winctx -> pidr = txattr -> pidr ;
@@ -985,6 +1011,14 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
985
1011
if (!tx_win_args_valid (cop , attr ))
986
1012
return ERR_PTR (- EINVAL );
987
1013
1014
+ /*
1015
+ * If caller did not specify a vasid but specified the PSWID of a
1016
+ * receive window (applicable only to FTW windows), use the vasid
1017
+ * from that receive window.
1018
+ */
1019
+ if (vasid == -1 && attr -> pswid )
1020
+ decode_pswid (attr -> pswid , & vasid , NULL );
1021
+
988
1022
vinst = find_vas_instance (vasid );
989
1023
if (!vinst ) {
990
1024
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
1065
}
1032
1066
}
1033
1067
1068
+ /*
1069
+ * Now that we have a send window, ensure context switch issues
1070
+ * CP_ABORT for this thread.
1071
+ */
1072
+ rc = - EINVAL ;
1073
+ if (set_thread_uses_vas () < 0 )
1074
+ goto free_window ;
1075
+
1034
1076
set_vinst_win (vinst , txwin );
1035
1077
1036
1078
return txwin ;
0 commit comments