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