quic/qbox
Loading...
Searching...
No Matches
vhost_user_vsock_pci.h
1/*
2 * This file is part of libqbox
3 * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#pragma once
9
10#include <cci_configuration>
11
12#include <libgssync.h>
13#include <qemu-instance.h>
14
15#include <module_factory_registery.h>
16
17#include <qemu_gpex.h>
18#include <cstring>
19#include <errno.h>
20
22{
23 SCP_LOGGER(());
24
25public:
26 cci::cci_param<std::string> p_vsock_backend_path;
27 cci::cci_param<std::string> p_vsock_vm_option;
28 cci::cci_param<std::string> p_vsock_sock_path;
29 cci::cci_param<bool> p_exec_backend;
30
31 vhost_user_vsock_pci(const sc_core::sc_module_name& name, sc_core::sc_object* o, sc_core::sc_object* t)
32 : vhost_user_vsock_pci(name, *(dynamic_cast<QemuInstance*>(o)), (dynamic_cast<qemu_gpex*>(t)))
33 {
34 }
35
36 vhost_user_vsock_pci(const sc_core::sc_module_name& name, QemuInstance& inst, qemu_gpex* gpex)
37 : qemu_gpex::Device(name, inst, "vhost-user-vsock-pci")
38 , p_vsock_backend_path("vsock_device_backend_path", "", "path of vhost-device-vsock")
39 , p_vsock_vm_option(
40 "vsock_vm_option",
41 "guest-cid=4,uds-path=/tmp/vm4.vsock,socket=/tmp/vsock.sock,tx-buffer-size=65536,queue-size=1024",
42 "value of --vm option passed to vhost-device-vsock")
43 , p_vsock_sock_path("vsock_socket_path", "/tmp/vsock.sock",
44 "path of vhost chardev socket to communicate with vhost-device-vsock")
45 , p_exec_backend("exec_backend", true,
46 "boolean parameter to decide if the platform should start the backend, or we can only connect "
47 "to an already started backend")
48 {
49 if (p_exec_backend.get_value()) {
50 if (p_vsock_backend_path.get_value().empty()) {
51 SCP_FATAL(())
52 << "vsock_path CCI parameter is empty, please use the path of vhost-device-vsock executable";
53 }
54 if (p_vsock_vm_option.get_value().empty()) {
55 SCP_FATAL(())
56 << "vsock_vm_option CCI parameter is empty, please use a correct value of \"--vm\" option "
57 "passed to vhost-device-vsock";
58 }
59 exec_vhost_user_vsock(p_vsock_backend_path.get_value(), p_vsock_vm_option.get_value());
60 }
61 m_inst.add_arg("-chardev");
62 std::string chardev_str = "socket,id=vhost_user_vsock_pci_sock_chardev,path=" + p_vsock_sock_path.get_value();
63 m_inst.add_arg(chardev_str.c_str());
64 gpex->add_device(*this);
65 }
66
67 void before_end_of_elaboration() override
68 {
69 qemu_gpex::Device::before_end_of_elaboration();
70 m_dev.set_prop_str("chardev", "vhost_user_vsock_pci_sock_chardev");
71 }
72
73private:
74 void exec_vhost_user_vsock(std::string path, std::string vsock_vm)
75 {
76 if (path.empty()) {
77 SCP_FATAL(()) << "exec_vhost_user_vsock() failed, path is empty!";
78 }
79 if (vsock_vm.empty()) {
80 SCP_FATAL(()) << "exec_vhost_user_vsock() failed, vsock_vm is empty!";
81 }
82 pid_t pid = fork();
83 if (pid < 0) {
84 SCP_FATAL(()) << "couldn't fork " << path << " Error: " << strerror(errno);
85 }
86 // child process
87 if (pid == 0) {
88 const char* vhost_user_vsock_path = path.c_str();
89 const char* vhost_vm_option = vsock_vm.c_str();
90 const char* vhost_vm = "--vm";
91 char* vhost_user_gpu_argv[] = { const_cast<char*>(vhost_user_vsock_path), const_cast<char*>(vhost_vm),
92 const_cast<char*>(vhost_vm_option), nullptr };
93 char* vhost_user_gpu_environ[] = { nullptr };
95 perror(std::string("couldn't execve " + path).c_str());
96 exit(EXIT_FAILURE);
97 }
98 }
99};
100
101extern "C" void module_register();
This class encapsulates a libqemu-cxx qemu::LibQemu instance. It handles QEMU parameters and instance...
Definition qemu-instance.h:89
void add_arg(const char *arg)
Add a command line argument to the qemu instance.
Definition qemu-instance.h:329
Definition target.h:160
Definition qemu_gpex.h:35
Definition qemu_gpex.h:32
Definition vhost_user_vsock_pci.h:22