diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index c7ab0dd..9600133 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -44,6 +44,8 @@ struct vhost_vsock {
 	atomic_t queued_replies;

 	u32 guest_cid;
+
+	bool mergeable;
 };

 static u32 vhost_transport_get_local_cid(void)
@@ -151,7 +153,6 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
 	struct vhost_virtqueue *tx_vq = &vsock->vqs[VSOCK_VQ_TX];
 	bool added = false;
 	bool restart_tx = false;
-	int mergeable;
 	size_t vsock_hlen;

 	mutex_lock(&vq->mutex);
@@ -159,12 +160,11 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
 	if (!vq->private_data)
 		goto out;

-	mergeable = vhost_has_feature(vq, VIRTIO_VSOCK_F_MRG_RXBUF);
 	/*
 	 * Guest fill page for rx vq in mergeable case, so it will not
 	 * allocate pkt structure, we should reserve size of pkt in advance.
 	 */
-	if (likely(mergeable))
+	if (likely(vsock->mergeable))
 		vsock_hlen = sizeof(struct virtio_vsock_pkt);
 	else
 		vsock_hlen = sizeof(struct virtio_vsock_hdr);
@@ -195,7 +195,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
 		spin_unlock_bh(&vsock->send_pkt_list_lock);

 		headcount = get_rx_bufs(vq, vq->heads, vsock_hlen + pkt->len,
-				&in, likely(mergeable) ? UIO_MAXIOV : 1);
+				&in, likely(vsock->mergeable) ? UIO_MAXIOV : 1);
 		if (headcount <= 0) {
 			spin_lock_bh(&vsock->send_pkt_list_lock);
 			list_add(&pkt->list, &vsock->send_pkt_list);
@@ -214,7 +214,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
 		len = iov_length(&vq->iov[out], in);
 		iov_iter_init(&iov_iter, READ, &vq->iov[out], in, len);

-		if (likely(mergeable))
+		if (likely(vsock->mergeable))
 			pkt->mrg_rxbuf_hdr.num_buffers = cpu_to_le16(headcount);
 		nbytes = copy_to_iter(&pkt->hdr, vsock_hlen, &iov_iter);
 		if (nbytes != vsock_hlen) {
@@ -303,6 +303,22 @@ static void vhost_transport_send_pkt_work(struct vhost_work *work)
 	return len;
 }

+static u32
+vhost_transport_get_max_pkt_len(u32 guest_cid)
+{
+	int len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE;
+	struct vhost_vsock *vsock;
+
+	vsock = vhost_vsock_get(guest_cid);
+	if (!vsock)
+		return len;
+
+	if (vsock->mergeable)
+		len = VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
+
+	return len;
+}
+
 static int
 vhost_transport_cancel_pkt(struct vsock_sock *vsk)
 {
@@ -602,6 +618,8 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)

 	atomic_set(&vsock->queued_replies, 0);

+	vsock->mergeable = false;
+
 	vqs[VSOCK_VQ_TX] = &vsock->vqs[VSOCK_VQ_TX];
 	vqs[VSOCK_VQ_RX] = &vsock->vqs[VSOCK_VQ_RX];
 	vsock->vqs[VSOCK_VQ_TX].handle_kick = vhost_vsock_handle_tx_kick;
@@ -726,6 +744,9 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
 		return -EFAULT;
 	}

+	if (features & (1 << VIRTIO_VSOCK_F_MRG_RXBUF))
+		vsock->mergeable = true;
+
 	for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
 		vq = &vsock->vqs[i];
 		mutex_lock(&vq->mutex);
@@ -848,6 +869,8 @@ static long vhost_vsock_dev_compat_ioctl(struct file *f, unsigned int ioctl,
 	},

 	.send_pkt = vhost_transport_send_pkt,
+
+	.max_pkt_len = vhost_transport_get_max_pkt_len,
 };

 static int __init vhost_vsock_init(void)
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 734eeed..ad95319 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -82,6 +82,9 @@ struct virtio_transport {

 	/* Takes ownership of the packet */
 	int (*send_pkt)(struct virtio_vsock_pkt *pkt);
+
+	/* Get max pkt len, cid only be used for Host */
+	u32 (*max_pkt_len)(u32 cid);
 };

 ssize_t
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index 148b58a..809085a 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -222,6 +222,22 @@ static int virtio_transport_send_pkt_loopback(struct virtio_vsock *vsock,
 	return len;
 }

+static u32
+virtio_transport_get_max_pkt_len(u32 cid)
+{
+	int len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE;
+	struct virtio_vsock *vsock;
+
+	vsock = virtio_vsock_get();
+	if (!vsock)
+		return len;
+
+	if (vsock->mergeable)
+		len = VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
+
+	return len;
+}
+
 static int
 virtio_transport_cancel_pkt(struct vsock_sock *vsk)
 {
@@ -675,6 +691,8 @@ static void virtio_vsock_rx_done(struct virtqueue *vq)
 	},

 	.send_pkt = virtio_transport_send_pkt,
+
+	.max_pkt_len = virtio_transport_get_max_pkt_len,
 };

 static int virtio_vsock_probe(struct virtio_device *vdev)
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index 123a8b6..cc14ace 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -159,7 +159,8 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
 	u32 src_cid, src_port, dst_cid, dst_port;
 	struct virtio_vsock_sock *vvs;
 	struct virtio_vsock_pkt *pkt;
-	u32 pkt_len = info->pkt_len;
+	u32 pkt_len;
+	u32 max_pkt_len;

 	src_cid = vm_sockets_get_local_cid();
 	src_port = vsk->local_addr.svm_port;
@@ -174,8 +175,8 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
 	vvs = vsk->trans;

 	/* we can send less than pkt_len bytes */
-	if (pkt_len > VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE)
-		pkt_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE;
+	max_pkt_len = virtio_transport_get_ops()->max_pkt_len(dst_cid);
+	pkt_len = min(max_pkt_len, info->pkt_len);

 	/* virtio_transport_get_credit might return less than pkt_len credit */
 	pkt_len = virtio_transport_get_credit(vvs, pkt_len);
