@@ -43,6 +43,9 @@
#include "virtio_ethdev.h"
#include "qtest_utils.h"
+/* ivshmem configuration */
+#define IVSHMEM_PROTOCOL_VERSION 0
+
#define PCI_CONFIG_ADDR(_bus, _device, _function, _offset) ( \
(1 << 31) | ((_bus) & 0xff) << 16 | ((_device) & 0x1f) << 11 | \
((_function) & 0x7) << 8 | ((_offset) & 0xfc))
@@ -59,6 +62,7 @@ union qtest_pipefds {
struct qtest_session {
int qtest_socket;
+ int ivshmem_socket;
pthread_mutex_t qtest_session_lock;
struct qtest_pci_device_list head;
@@ -411,6 +415,7 @@ qtest_close_sockets(struct qtest_session *s)
qtest_close_one_socket(&s->qtest_socket);
qtest_close_one_socket(&s->msgfds.readfd);
qtest_close_one_socket(&s->msgfds.writefd);
+ qtest_close_one_socket(&s->ivshmem_socket);
}
static void
@@ -716,6 +721,93 @@ qtest_register_target_devices(struct qtest_session *s,
}
static int
+qtest_send_message_to_ivshmem(int sock_fd, uint64_t client_id, int shm_fd)
+{
+ struct iovec iov;
+ struct msghdr msgh;
+ size_t fdsize = sizeof(int);
+ char control[CMSG_SPACE(fdsize)];
+ struct cmsghdr *cmsg;
+ int ret;
+
+ memset(&msgh, 0, sizeof(msgh));
+ iov.iov_base = &client_id;
+ iov.iov_len = sizeof(client_id);
+
+ msgh.msg_iov = &iov;
+ msgh.msg_iovlen = 1;
+
+ if (shm_fd >= 0) {
+ msgh.msg_control = &control;
+ msgh.msg_controllen = sizeof(control);
+ cmsg = CMSG_FIRSTHDR(&msgh);
+ cmsg->cmsg_len = CMSG_LEN(fdsize);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ memcpy(CMSG_DATA(cmsg), &shm_fd, fdsize);
+ }
+
+ do {
+ ret = sendmsg(sock_fd, &msgh, 0);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "sendmsg error\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int
+qtest_setup_shared_memory(struct qtest_session *s)
+{
+ int shm_fd, num, ret;
+ struct back_file *huges;
+
+ num = rte_eal_get_backfile_info(&huges);
+ if (num != 1) {
+ PMD_DRV_LOG(ERR,
+ "Not supported memory configuration\n");
+ return -1;
+ }
+
+ shm_fd = open(huges[0].filepath, O_RDWR);
+ if (shm_fd < 0) {
+ PMD_DRV_LOG(ERR,
+ "Cannot open file: %s\n", huges[0].filepath);
+ return -1;
+ }
+
+ /* send our protocol version first */
+ ret = qtest_send_message_to_ivshmem(s->ivshmem_socket,
+ IVSHMEM_PROTOCOL_VERSION, -1);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR,
+ "Failed to send protocol version to ivshmem\n");
+ return -1;
+ }
+
+ /* send client id */
+ ret = qtest_send_message_to_ivshmem(s->ivshmem_socket, 0, -1);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to send VMID to ivshmem\n");
+ return -1;
+ }
+
+ /* send message to ivshmem */
+ ret = qtest_send_message_to_ivshmem(s->ivshmem_socket, -1, shm_fd);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to file descriptor to ivshmem\n");
+ return -1;
+ }
+
+ close(shm_fd);
+
+ return 0;
+}
+
+static int
qtest_open_socket(char *path)
{
struct sockaddr_un sa = {0};
@@ -769,7 +861,7 @@ qtest_vdev_uninit(struct qtest_session *s)
}
struct qtest_session *
-qtest_vdev_init(char *qtest_path,
+qtest_vdev_init(char *qtest_path, char *ivshmem_path,
struct qtest_pci_device *devices, int devnum)
{
struct qtest_session *s;
@@ -800,6 +892,12 @@ qtest_vdev_init(char *qtest_path,
goto error;
}
+ s->ivshmem_socket = qtest_open_socket(ivshmem_path);
+ if (s->ivshmem_socket < 0) {
+ PMD_DRV_LOG(ERR, "Failed to open %s\n", ivshmem_path);
+ goto error;
+ }
+
s->qtest_socket = qtest_open_socket(qtest_path);
if (s->qtest_socket < 0) {
PMD_DRV_LOG(ERR, "Failed to open %s\n", qtest_path);
@@ -813,6 +911,12 @@ qtest_vdev_init(char *qtest_path,
}
s->event_th_started = 1;
+ ret = qtest_setup_shared_memory(s);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "Failed to setup shared memory\n");
+ goto error;
+ }
+
ret = qtest_init_pci_devices(s, devices, devnum);
if (ret != 0) {
PMD_DRV_LOG(ERR, "Failed to initialize devices\n");
@@ -132,6 +132,8 @@ struct qtest_pci_device {
*
* @param qtest_path
* Path of qtest socket.
+ * @param ivshmem_path
+ * Path of ivshmem socket.
* @param devices
* Array of device information. It should contain piix3, ivshmem and target
* device(virtio-net device).
@@ -140,7 +142,7 @@ struct qtest_pci_device {
* @return
* The pointer to qtest session structure.
*/
-struct qtest_session *qtest_vdev_init(char *qtest_path,
+struct qtest_session *qtest_vdev_init(char *qtest_path, char *ivshmem_path,
struct qtest_pci_device *devices, int devnum);
/**