#include <linux/wait.h>
 
 #include <net/inet_common.h>
+#include <net/tls.h>
 
 static bool tcp_bpf_stream_read(const struct sock *sk)
 {
        u32 off;
 
        while (1) {
+               bool has_tx_ulp;
+
                sge = sk_msg_elem(msg, msg->sg.start);
                size = (apply && apply_bytes < sge->length) ?
                        apply_bytes : sge->length;
 
                tcp_rate_check_app_limited(sk);
 retry:
-               ret = do_tcp_sendpages(sk, page, off, size, flags);
+               has_tx_ulp = tls_sw_has_ctx_tx(sk);
+               if (has_tx_ulp) {
+                       flags |= MSG_SENDPAGE_NOPOLICY;
+                       ret = kernel_sendpage_locked(sk,
+                                                    page, off, size, flags);
+               } else {
+                       ret = do_tcp_sendpages(sk, page, off, size, flags);
+               }
+
                if (ret <= 0)
                        return ret;
                if (apply)
 
        struct sk_psock *psock;
        struct sock *sk_redir;
        struct tls_rec *rec;
+       bool enospc, policy;
        int err = 0, send;
        u32 delta = 0;
-       bool enospc;
 
+       policy = !(flags & MSG_SENDPAGE_NOPOLICY);
        psock = sk_psock_get(sk);
-       if (!psock)
+       if (!psock || !policy)
                return tls_push_record(sk, flags, record_type);
 more_data:
        enospc = sk_msg_full(msg);
        return copied ? copied : ret;
 }
 
-int tls_sw_sendpage(struct sock *sk, struct page *page,
-                   int offset, size_t size, int flags)
+int tls_sw_do_sendpage(struct sock *sk, struct page *page,
+                      int offset, size_t size, int flags)
 {
        long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
        struct tls_context *tls_ctx = tls_get_ctx(sk);
        int ret = 0;
        bool eor;
 
-       if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
-                     MSG_SENDPAGE_NOTLAST))
-               return -ENOTSUPP;
-
-       /* No MSG_EOR from splice, only look at MSG_MORE */
        eor = !(flags & (MSG_MORE | MSG_SENDPAGE_NOTLAST));
-
-       lock_sock(sk);
-
        sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
        /* Wait till there is any pending write on socket */
        }
 sendpage_end:
        ret = sk_stream_error(sk, flags, ret);
-       release_sock(sk);
        return copied ? copied : ret;
 }
 
+int tls_sw_sendpage_locked(struct sock *sk, struct page *page,
+                          int offset, size_t size, int flags)
+{
+       if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
+                     MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY))
+               return -ENOTSUPP;
+
+       return tls_sw_do_sendpage(sk, page, offset, size, flags);
+}
+
+int tls_sw_sendpage(struct sock *sk, struct page *page,
+                   int offset, size_t size, int flags)
+{
+       int ret;
+
+       if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
+                     MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY))
+               return -ENOTSUPP;
+
+       lock_sock(sk);
+       ret = tls_sw_do_sendpage(sk, page, offset, size, flags);
+       release_sock(sk);
+       return ret;
+}
+
 static struct sk_buff *tls_wait_data(struct sock *sk, struct sk_psock *psock,
                                     int flags, long timeo, int *err)
 {