acpi, vhost, misc: fixes, features
vDPA support, fix to vhost blk RO bit handling, some include path cleanups, NFIT ACPI table. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJbEXNvAAoJECgfDbjSjVRpc8gH/R8xrcFrV+k9wwbgYcOcGb6Y LWjseE31pqJcxRV80vLOdzYEuLStZQKQQY7xBDMlA5vdyvZxIA6FLO2IsiJSbFAk EK8pclwhpwQAahr8BfzenabohBv2UO7zu5+dqSvuJCiMWF3jGtPAIMxInfjXaOZY odc1zY2D2EgsC7wZZ1hfraRbISBOiRaez9BoGDKPOyBY9G1ASEgxJgleFgoBLfsK a1XU+fDM6hAVdxftfkTm0nibyf7PWPDyzqghLqjR9WXLvZP3Cqud4p8N29mY51pR KSTjA4FYk6Z9EVMltyBHfdJs6RQzglKjxcNGdlrvacDfyFi79fGdiosVllrjfJM= =3+V0 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging acpi, vhost, misc: fixes, features vDPA support, fix to vhost blk RO bit handling, some include path cleanups, NFIT ACPI table. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Fri 01 Jun 2018 17:25:19 BST # gpg: using RSA key 281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: (31 commits) vhost-blk: turn on pre-defined RO feature bit ACPI testing: test NFIT platform capabilities nvdimm, acpi: support NFIT platform capabilities tests/.gitignore: add entry for generated file arch_init: sort architectures ui: use local path for local headers qga: use local path for local headers colo: use local path for local headers migration: use local path for local headers usb: use local path for local headers sd: fix up include vhost-scsi: drop an unused include ppc: use local path for local headers rocker: drop an unused include e1000e: use local path for local headers ioapic: fix up includes ide: use local path for local headers display: use local path for local headers trace: use local path for local headers migration: drop an unused include ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
f67c9b693a
16
arch_init.c
16
arch_init.c
@ -52,14 +52,14 @@ int graphic_depth = 32;
|
|||||||
#define QEMU_ARCH QEMU_ARCH_ARM
|
#define QEMU_ARCH QEMU_ARCH_ARM
|
||||||
#elif defined(TARGET_CRIS)
|
#elif defined(TARGET_CRIS)
|
||||||
#define QEMU_ARCH QEMU_ARCH_CRIS
|
#define QEMU_ARCH QEMU_ARCH_CRIS
|
||||||
#elif defined(TARGET_I386)
|
|
||||||
#define QEMU_ARCH QEMU_ARCH_I386
|
|
||||||
#elif defined(TARGET_HPPA)
|
#elif defined(TARGET_HPPA)
|
||||||
#define QEMU_ARCH QEMU_ARCH_HPPA
|
#define QEMU_ARCH QEMU_ARCH_HPPA
|
||||||
#elif defined(TARGET_M68K)
|
#elif defined(TARGET_I386)
|
||||||
#define QEMU_ARCH QEMU_ARCH_M68K
|
#define QEMU_ARCH QEMU_ARCH_I386
|
||||||
#elif defined(TARGET_LM32)
|
#elif defined(TARGET_LM32)
|
||||||
#define QEMU_ARCH QEMU_ARCH_LM32
|
#define QEMU_ARCH QEMU_ARCH_LM32
|
||||||
|
#elif defined(TARGET_M68K)
|
||||||
|
#define QEMU_ARCH QEMU_ARCH_M68K
|
||||||
#elif defined(TARGET_MICROBLAZE)
|
#elif defined(TARGET_MICROBLAZE)
|
||||||
#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
|
#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
|
||||||
#elif defined(TARGET_MIPS)
|
#elif defined(TARGET_MIPS)
|
||||||
@ -80,12 +80,12 @@ int graphic_depth = 32;
|
|||||||
#define QEMU_ARCH QEMU_ARCH_SH4
|
#define QEMU_ARCH QEMU_ARCH_SH4
|
||||||
#elif defined(TARGET_SPARC)
|
#elif defined(TARGET_SPARC)
|
||||||
#define QEMU_ARCH QEMU_ARCH_SPARC
|
#define QEMU_ARCH QEMU_ARCH_SPARC
|
||||||
#elif defined(TARGET_XTENSA)
|
|
||||||
#define QEMU_ARCH QEMU_ARCH_XTENSA
|
|
||||||
#elif defined(TARGET_UNICORE32)
|
|
||||||
#define QEMU_ARCH QEMU_ARCH_UNICORE32
|
|
||||||
#elif defined(TARGET_TRICORE)
|
#elif defined(TARGET_TRICORE)
|
||||||
#define QEMU_ARCH QEMU_ARCH_TRICORE
|
#define QEMU_ARCH QEMU_ARCH_TRICORE
|
||||||
|
#elif defined(TARGET_UNICORE32)
|
||||||
|
#define QEMU_ARCH QEMU_ARCH_UNICORE32
|
||||||
|
#elif defined(TARGET_XTENSA)
|
||||||
|
#define QEMU_ARCH QEMU_ARCH_XTENSA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uint32_t arch_type = QEMU_ARCH;
|
const uint32_t arch_type = QEMU_ARCH;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
#include "hw/virtio/vhost-user.h"
|
||||||
#include "standard-headers/linux/virtio_crypto.h"
|
#include "standard-headers/linux/virtio_crypto.h"
|
||||||
#include "sysemu/cryptodev-vhost.h"
|
#include "sysemu/cryptodev-vhost.h"
|
||||||
#include "chardev/char-fe.h"
|
#include "chardev/char-fe.h"
|
||||||
@ -46,6 +47,7 @@
|
|||||||
typedef struct CryptoDevBackendVhostUser {
|
typedef struct CryptoDevBackendVhostUser {
|
||||||
CryptoDevBackend parent_obj;
|
CryptoDevBackend parent_obj;
|
||||||
|
|
||||||
|
VhostUserState *vhost_user;
|
||||||
CharBackend chr;
|
CharBackend chr;
|
||||||
char *chr_name;
|
char *chr_name;
|
||||||
bool opened;
|
bool opened;
|
||||||
@ -102,7 +104,7 @@ cryptodev_vhost_user_start(int queues,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
options.opaque = &s->chr;
|
options.opaque = s->vhost_user;
|
||||||
options.backend_type = VHOST_BACKEND_TYPE_USER;
|
options.backend_type = VHOST_BACKEND_TYPE_USER;
|
||||||
options.cc = b->conf.peers.ccs[i];
|
options.cc = b->conf.peers.ccs[i];
|
||||||
s->vhost_crypto[i] = cryptodev_vhost_init(&options);
|
s->vhost_crypto[i] = cryptodev_vhost_init(&options);
|
||||||
@ -185,6 +187,7 @@ static void cryptodev_vhost_user_init(
|
|||||||
size_t i;
|
size_t i;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
Chardev *chr;
|
Chardev *chr;
|
||||||
|
VhostUserState *user;
|
||||||
CryptoDevBackendClient *cc;
|
CryptoDevBackendClient *cc;
|
||||||
CryptoDevBackendVhostUser *s =
|
CryptoDevBackendVhostUser *s =
|
||||||
CRYPTODEV_BACKEND_VHOST_USER(backend);
|
CRYPTODEV_BACKEND_VHOST_USER(backend);
|
||||||
@ -215,6 +218,15 @@ static void cryptodev_vhost_user_init(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user = vhost_user_init();
|
||||||
|
if (!user) {
|
||||||
|
error_setg(errp, "Failed to init vhost_user");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user->chr = &s->chr;
|
||||||
|
s->vhost_user = user;
|
||||||
|
|
||||||
qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
|
qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
|
||||||
cryptodev_vhost_user_event, NULL, s, NULL, true);
|
cryptodev_vhost_user_event, NULL, s, NULL, true);
|
||||||
|
|
||||||
@ -299,6 +311,12 @@ static void cryptodev_vhost_user_cleanup(
|
|||||||
backend->conf.peers.ccs[i] = NULL;
|
backend->conf.peers.ccs[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->vhost_user) {
|
||||||
|
vhost_user_cleanup(s->vhost_user);
|
||||||
|
g_free(s->vhost_user);
|
||||||
|
s->vhost_user = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cryptodev_vhost_user_set_chardev(Object *obj,
|
static void cryptodev_vhost_user_set_chardev(Object *obj,
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "qapi/qobject-input-visitor.h"
|
#include "qapi/qobject-input-visitor.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "block/crypto.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
typedef struct BlockCrypto BlockCrypto;
|
typedef struct BlockCrypto BlockCrypto;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "block/nbd-client.h"
|
#include "nbd-client.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/uri.h"
|
#include "qemu/uri.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#include "qapi/qapi-visit-block-core.h"
|
#include "qapi/qapi-visit-block-core.h"
|
||||||
#include "crypto/block.h"
|
#include "crypto/block.h"
|
||||||
#include "migration/blocker.h"
|
#include "migration/blocker.h"
|
||||||
#include "block/crypto.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* QEMU COW block driver with compression and encryption support */
|
/* QEMU COW block driver with compression and encryption support */
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
|
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "block/qcow2.h"
|
#include "qcow2.h"
|
||||||
|
|
||||||
/* NOTICE: BME here means Bitmaps Extension and used as a namespace for
|
/* NOTICE: BME here means Bitmaps Extension and used as a namespace for
|
||||||
* _internal_ constants. Please do not use this _internal_ abbreviation for
|
* _internal_ constants. Please do not use this _internal_ abbreviation for
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "block/qcow2.h"
|
#include "qcow2.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "block/qcow2.h"
|
#include "qcow2.h"
|
||||||
#include "qemu/range.h"
|
#include "qemu/range.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "block/qcow2.h"
|
#include "qcow2.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "sysemu/block-backend.h"
|
#include "sysemu/block-backend.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include "block/qcow2.h"
|
#include "qcow2.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qapi-events-block-core.h"
|
#include "qapi/qapi-events-block-core.h"
|
||||||
@ -39,7 +39,7 @@
|
|||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "qapi/qobject-input-visitor.h"
|
#include "qapi/qobject-input-visitor.h"
|
||||||
#include "qapi/qapi-visit-block-core.h"
|
#include "qapi/qapi-visit-block-core.h"
|
||||||
#include "block/crypto.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Differences with QCOW:
|
Differences with QCOW:
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "block/vhdx.h"
|
#include "vhdx.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All the VHDX formats on disk are little endian - the following
|
* All the VHDX formats on disk are little endian - the following
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "block/vhdx.h"
|
#include "vhdx.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct VHDXLogSequence {
|
typedef struct VHDXLogSequence {
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "qemu/crc32c.h"
|
#include "qemu/crc32c.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "block/vhdx.h"
|
#include "vhdx.h"
|
||||||
#include "migration/blocker.h"
|
#include "migration/blocker.h"
|
||||||
#include "qemu/uuid.h"
|
#include "qemu/uuid.h"
|
||||||
#include "qapi/qmp/qdict.h"
|
#include "qapi/qmp/qdict.h"
|
||||||
|
@ -314,11 +314,6 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
|
|||||||
msg.msg_controllen = 0;
|
msg.msg_controllen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the version in the flags when sending the reply */
|
|
||||||
vmsg->flags &= ~VHOST_USER_VERSION_MASK;
|
|
||||||
vmsg->flags |= VHOST_USER_VERSION;
|
|
||||||
vmsg->flags |= VHOST_USER_REPLY_MASK;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rc = sendmsg(conn_fd, &msg, 0);
|
rc = sendmsg(conn_fd, &msg, 0);
|
||||||
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
|
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
|
||||||
@ -341,6 +336,39 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
vu_send_reply(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
|
||||||
|
{
|
||||||
|
/* Set the version in the flags when sending the reply */
|
||||||
|
vmsg->flags &= ~VHOST_USER_VERSION_MASK;
|
||||||
|
vmsg->flags |= VHOST_USER_VERSION;
|
||||||
|
vmsg->flags |= VHOST_USER_REPLY_MASK;
|
||||||
|
|
||||||
|
return vu_message_write(dev, conn_fd, vmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
vu_process_message_reply(VuDev *dev, const VhostUserMsg *vmsg)
|
||||||
|
{
|
||||||
|
VhostUserMsg msg_reply;
|
||||||
|
|
||||||
|
if ((vmsg->flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vu_message_read(dev, dev->slave_fd, &msg_reply)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg_reply.request != vmsg->request) {
|
||||||
|
DPRINT("Received unexpected msg type. Expected %d received %d",
|
||||||
|
vmsg->request, msg_reply.request);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg_reply.payload.u64 == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Kick the log_call_fd if required. */
|
/* Kick the log_call_fd if required. */
|
||||||
static void
|
static void
|
||||||
vu_log_kick(VuDev *dev)
|
vu_log_kick(VuDev *dev)
|
||||||
@ -536,7 +564,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
|
|||||||
|
|
||||||
/* Send the message back to qemu with the addresses filled in */
|
/* Send the message back to qemu with the addresses filled in */
|
||||||
vmsg->fd_num = 0;
|
vmsg->fd_num = 0;
|
||||||
if (!vu_message_write(dev, dev->sock, vmsg)) {
|
if (!vu_send_reply(dev, dev->sock, vmsg)) {
|
||||||
vu_panic(dev, "failed to respond to set-mem-table for postcopy");
|
vu_panic(dev, "failed to respond to set-mem-table for postcopy");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -916,6 +944,41 @@ void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
|
||||||
|
int size, int offset)
|
||||||
|
{
|
||||||
|
int qidx = vq - dev->vq;
|
||||||
|
int fd_num = 0;
|
||||||
|
VhostUserMsg vmsg = {
|
||||||
|
.request = VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG,
|
||||||
|
.flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK,
|
||||||
|
.size = sizeof(vmsg.payload.area),
|
||||||
|
.payload.area = {
|
||||||
|
.u64 = qidx & VHOST_USER_VRING_IDX_MASK,
|
||||||
|
.size = size,
|
||||||
|
.offset = offset,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (fd == -1) {
|
||||||
|
vmsg.payload.area.u64 |= VHOST_USER_VRING_NOFD_MASK;
|
||||||
|
} else {
|
||||||
|
vmsg.fds[fd_num++] = fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
vmsg.fd_num = fd_num;
|
||||||
|
|
||||||
|
if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vu_message_write(dev, dev->slave_fd, &vmsg)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vu_process_message_reply(dev, &vmsg);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg)
|
vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg)
|
||||||
{
|
{
|
||||||
@ -968,7 +1031,9 @@ static bool
|
|||||||
vu_get_protocol_features_exec(VuDev *dev, VhostUserMsg *vmsg)
|
vu_get_protocol_features_exec(VuDev *dev, VhostUserMsg *vmsg)
|
||||||
{
|
{
|
||||||
uint64_t features = 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD |
|
uint64_t features = 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD |
|
||||||
1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ;
|
1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ |
|
||||||
|
1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER |
|
||||||
|
1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD;
|
||||||
|
|
||||||
if (have_userfault()) {
|
if (have_userfault()) {
|
||||||
features |= 1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT;
|
features |= 1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT;
|
||||||
@ -1252,7 +1317,7 @@ vu_dispatch(VuDev *dev)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vu_message_write(dev, dev->sock, &vmsg)) {
|
if (!vu_send_reply(dev, dev->sock, &vmsg)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ enum VhostUserProtocolFeature {
|
|||||||
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
||||||
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
||||||
VHOST_USER_PROTOCOL_F_CONFIG = 9,
|
VHOST_USER_PROTOCOL_F_CONFIG = 9,
|
||||||
|
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
|
||||||
|
VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
|
||||||
|
|
||||||
VHOST_USER_PROTOCOL_F_MAX
|
VHOST_USER_PROTOCOL_F_MAX
|
||||||
};
|
};
|
||||||
@ -92,6 +94,14 @@ typedef enum VhostUserRequest {
|
|||||||
VHOST_USER_MAX
|
VHOST_USER_MAX
|
||||||
} VhostUserRequest;
|
} VhostUserRequest;
|
||||||
|
|
||||||
|
typedef enum VhostUserSlaveRequest {
|
||||||
|
VHOST_USER_SLAVE_NONE = 0,
|
||||||
|
VHOST_USER_SLAVE_IOTLB_MSG = 1,
|
||||||
|
VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
|
||||||
|
VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG = 3,
|
||||||
|
VHOST_USER_SLAVE_MAX
|
||||||
|
} VhostUserSlaveRequest;
|
||||||
|
|
||||||
typedef struct VhostUserMemoryRegion {
|
typedef struct VhostUserMemoryRegion {
|
||||||
uint64_t guest_phys_addr;
|
uint64_t guest_phys_addr;
|
||||||
uint64_t memory_size;
|
uint64_t memory_size;
|
||||||
@ -122,6 +132,12 @@ static VhostUserConfig c __attribute__ ((unused));
|
|||||||
+ sizeof(c.size) \
|
+ sizeof(c.size) \
|
||||||
+ sizeof(c.flags))
|
+ sizeof(c.flags))
|
||||||
|
|
||||||
|
typedef struct VhostUserVringArea {
|
||||||
|
uint64_t u64;
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t offset;
|
||||||
|
} VhostUserVringArea;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# define VU_PACKED __attribute__((gcc_struct, packed))
|
# define VU_PACKED __attribute__((gcc_struct, packed))
|
||||||
#else
|
#else
|
||||||
@ -133,6 +149,7 @@ typedef struct VhostUserMsg {
|
|||||||
|
|
||||||
#define VHOST_USER_VERSION_MASK (0x3)
|
#define VHOST_USER_VERSION_MASK (0x3)
|
||||||
#define VHOST_USER_REPLY_MASK (0x1 << 2)
|
#define VHOST_USER_REPLY_MASK (0x1 << 2)
|
||||||
|
#define VHOST_USER_NEED_REPLY_MASK (0x1 << 3)
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t size; /* the following payload size */
|
uint32_t size; /* the following payload size */
|
||||||
|
|
||||||
@ -145,6 +162,7 @@ typedef struct VhostUserMsg {
|
|||||||
VhostUserMemory memory;
|
VhostUserMemory memory;
|
||||||
VhostUserLog log;
|
VhostUserLog log;
|
||||||
VhostUserConfig config;
|
VhostUserConfig config;
|
||||||
|
VhostUserVringArea area;
|
||||||
} payload;
|
} payload;
|
||||||
|
|
||||||
int fds[VHOST_MEMORY_MAX_NREGIONS];
|
int fds[VHOST_MEMORY_MAX_NREGIONS];
|
||||||
@ -368,6 +386,20 @@ VuVirtq *vu_get_queue(VuDev *dev, int qidx);
|
|||||||
void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
|
void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
|
||||||
vu_queue_handler_cb handler);
|
vu_queue_handler_cb handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vu_set_queue_host_notifier:
|
||||||
|
* @dev: a VuDev context
|
||||||
|
* @vq: a VuVirtq queue
|
||||||
|
* @fd: a file descriptor
|
||||||
|
* @size: host page size
|
||||||
|
* @offset: notifier offset in @fd file
|
||||||
|
*
|
||||||
|
* Set queue's host notifier. This function may be called several
|
||||||
|
* times for the same queue. If called with -1 @fd, the notifier
|
||||||
|
* is removed.
|
||||||
|
*/
|
||||||
|
bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
|
||||||
|
int size, int offset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vu_queue_set_notification:
|
* vu_queue_set_notification:
|
||||||
|
@ -31,6 +31,7 @@ typedef struct VubDev {
|
|||||||
VugDev parent;
|
VugDev parent;
|
||||||
int blk_fd;
|
int blk_fd;
|
||||||
struct virtio_blk_config blkcfg;
|
struct virtio_blk_config blkcfg;
|
||||||
|
bool enable_ro;
|
||||||
char *blk_name;
|
char *blk_name;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
} VubDev;
|
} VubDev;
|
||||||
@ -301,14 +302,27 @@ static void vub_queue_set_started(VuDev *vu_dev, int idx, bool started)
|
|||||||
static uint64_t
|
static uint64_t
|
||||||
vub_get_features(VuDev *dev)
|
vub_get_features(VuDev *dev)
|
||||||
{
|
{
|
||||||
return 1ull << VIRTIO_BLK_F_SIZE_MAX |
|
uint64_t features;
|
||||||
1ull << VIRTIO_BLK_F_SEG_MAX |
|
VugDev *gdev;
|
||||||
1ull << VIRTIO_BLK_F_TOPOLOGY |
|
VubDev *vdev_blk;
|
||||||
1ull << VIRTIO_BLK_F_BLK_SIZE |
|
|
||||||
1ull << VIRTIO_BLK_F_FLUSH |
|
gdev = container_of(dev, VugDev, parent);
|
||||||
1ull << VIRTIO_BLK_F_CONFIG_WCE |
|
vdev_blk = container_of(gdev, VubDev, parent);
|
||||||
1ull << VIRTIO_F_VERSION_1 |
|
|
||||||
1ull << VHOST_USER_F_PROTOCOL_FEATURES;
|
features = 1ull << VIRTIO_BLK_F_SIZE_MAX |
|
||||||
|
1ull << VIRTIO_BLK_F_SEG_MAX |
|
||||||
|
1ull << VIRTIO_BLK_F_TOPOLOGY |
|
||||||
|
1ull << VIRTIO_BLK_F_BLK_SIZE |
|
||||||
|
1ull << VIRTIO_BLK_F_FLUSH |
|
||||||
|
1ull << VIRTIO_BLK_F_CONFIG_WCE |
|
||||||
|
1ull << VIRTIO_F_VERSION_1 |
|
||||||
|
1ull << VHOST_USER_F_PROTOCOL_FEATURES;
|
||||||
|
|
||||||
|
if (vdev_blk->enable_ro) {
|
||||||
|
features |= 1ull << VIRTIO_BLK_F_RO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
@ -476,6 +490,7 @@ vub_new(char *blk_file)
|
|||||||
vub_free(vdev_blk);
|
vub_free(vdev_blk);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
vdev_blk->enable_ro = false;
|
||||||
vdev_blk->blkcfg.wce = 0;
|
vdev_blk->blkcfg.wce = 0;
|
||||||
vdev_blk->blk_name = blk_file;
|
vdev_blk->blk_name = blk_file;
|
||||||
|
|
||||||
@ -490,10 +505,11 @@ int main(int argc, char **argv)
|
|||||||
int opt;
|
int opt;
|
||||||
char *unix_socket = NULL;
|
char *unix_socket = NULL;
|
||||||
char *blk_file = NULL;
|
char *blk_file = NULL;
|
||||||
|
bool enable_ro = false;
|
||||||
int lsock = -1, csock = -1;
|
int lsock = -1, csock = -1;
|
||||||
VubDev *vdev_blk = NULL;
|
VubDev *vdev_blk = NULL;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "b:s:h")) != -1) {
|
while ((opt = getopt(argc, argv, "b:rs:h")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'b':
|
case 'b':
|
||||||
blk_file = g_strdup(optarg);
|
blk_file = g_strdup(optarg);
|
||||||
@ -501,17 +517,20 @@ int main(int argc, char **argv)
|
|||||||
case 's':
|
case 's':
|
||||||
unix_socket = g_strdup(optarg);
|
unix_socket = g_strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
enable_ro = true;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
printf("Usage: %s [-b block device or file, -s UNIX domain socket]"
|
printf("Usage: %s [ -b block device or file, -s UNIX domain socket"
|
||||||
" | [ -h ]\n", argv[0]);
|
" | -r Enable read-only ] | [ -h ]\n", argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unix_socket || !blk_file) {
|
if (!unix_socket || !blk_file) {
|
||||||
printf("Usage: %s [-b block device or file, -s UNIX domain socket] |"
|
printf("Usage: %s [ -b block device or file, -s UNIX domain socket"
|
||||||
" [ -h ]\n", argv[0]);
|
" | -r Enable read-only ] | [ -h ]\n", argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,6 +549,9 @@ int main(int argc, char **argv)
|
|||||||
if (!vdev_blk) {
|
if (!vdev_blk) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
if (enable_ro) {
|
||||||
|
vdev_blk->enable_ro = true;
|
||||||
|
}
|
||||||
|
|
||||||
vug_init(&vdev_blk->parent, csock, vub_panic_cb, &vub_iface);
|
vug_init(&vdev_blk->parent, csock, vub_panic_cb, &vub_iface);
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
|
|
||||||
#include "crypto/block-luks.h"
|
#include "block-luks.h"
|
||||||
|
|
||||||
#include "crypto/hash.h"
|
#include "crypto/hash.h"
|
||||||
#include "crypto/afsplit.h"
|
#include "crypto/afsplit.h"
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#ifndef QCRYPTO_BLOCK_LUKS_H
|
#ifndef QCRYPTO_BLOCK_LUKS_H
|
||||||
#define QCRYPTO_BLOCK_LUKS_H
|
#define QCRYPTO_BLOCK_LUKS_H
|
||||||
|
|
||||||
#include "crypto/blockpriv.h"
|
#include "blockpriv.h"
|
||||||
|
|
||||||
extern const QCryptoBlockDriver qcrypto_block_driver_luks;
|
extern const QCryptoBlockDriver qcrypto_block_driver_luks;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|
||||||
#include "crypto/block-qcow.h"
|
#include "block-qcow.h"
|
||||||
#include "crypto/secret.h"
|
#include "crypto/secret.h"
|
||||||
|
|
||||||
#define QCRYPTO_BLOCK_QCOW_SECTOR_SIZE 512
|
#define QCRYPTO_BLOCK_QCOW_SECTOR_SIZE 512
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#ifndef QCRYPTO_BLOCK_QCOW_H
|
#ifndef QCRYPTO_BLOCK_QCOW_H
|
||||||
#define QCRYPTO_BLOCK_QCOW_H
|
#define QCRYPTO_BLOCK_QCOW_H
|
||||||
|
|
||||||
#include "crypto/blockpriv.h"
|
#include "blockpriv.h"
|
||||||
|
|
||||||
extern const QCryptoBlockDriver qcrypto_block_driver_qcow;
|
extern const QCryptoBlockDriver qcrypto_block_driver_qcow;
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "crypto/blockpriv.h"
|
#include "blockpriv.h"
|
||||||
#include "crypto/block-qcow.h"
|
#include "block-qcow.h"
|
||||||
#include "crypto/block-luks.h"
|
#include "block-luks.h"
|
||||||
|
|
||||||
static const QCryptoBlockDriver *qcrypto_block_drivers[] = {
|
static const QCryptoBlockDriver *qcrypto_block_drivers[] = {
|
||||||
[Q_CRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow,
|
[Q_CRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow,
|
||||||
|
@ -150,11 +150,11 @@ qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
|
|||||||
#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */
|
#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */
|
||||||
|
|
||||||
#ifdef CONFIG_GCRYPT
|
#ifdef CONFIG_GCRYPT
|
||||||
#include "crypto/cipher-gcrypt.c"
|
#include "cipher-gcrypt.c"
|
||||||
#elif defined CONFIG_NETTLE
|
#elif defined CONFIG_NETTLE
|
||||||
#include "crypto/cipher-nettle.c"
|
#include "cipher-nettle.c"
|
||||||
#else
|
#else
|
||||||
#include "crypto/cipher-builtin.c"
|
#include "cipher-builtin.c"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "crypto/ivgen-essiv.h"
|
#include "ivgen-essiv.h"
|
||||||
|
|
||||||
typedef struct QCryptoIVGenESSIV QCryptoIVGenESSIV;
|
typedef struct QCryptoIVGenESSIV QCryptoIVGenESSIV;
|
||||||
struct QCryptoIVGenESSIV {
|
struct QCryptoIVGenESSIV {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "crypto/ivgenpriv.h"
|
#include "ivgenpriv.h"
|
||||||
|
|
||||||
#ifndef QCRYPTO_IVGEN_ESSIV_H__
|
#ifndef QCRYPTO_IVGEN_ESSIV_H__
|
||||||
#define QCRYPTO_IVGEN_ESSIV_H__
|
#define QCRYPTO_IVGEN_ESSIV_H__
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "crypto/ivgen-plain.h"
|
#include "ivgen-plain.h"
|
||||||
|
|
||||||
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
|
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
|
||||||
const uint8_t *key, size_t nkey,
|
const uint8_t *key, size_t nkey,
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "crypto/ivgenpriv.h"
|
#include "ivgenpriv.h"
|
||||||
|
|
||||||
#ifndef QCRYPTO_IVGEN_PLAIN_H__
|
#ifndef QCRYPTO_IVGEN_PLAIN_H__
|
||||||
#define QCRYPTO_IVGEN_PLAIN_H__
|
#define QCRYPTO_IVGEN_PLAIN_H__
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "crypto/ivgen-plain.h"
|
#include "ivgen-plain.h"
|
||||||
|
|
||||||
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
|
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
|
||||||
const uint8_t *key, size_t nkey,
|
const uint8_t *key, size_t nkey,
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "crypto/ivgenpriv.h"
|
#include "ivgenpriv.h"
|
||||||
|
|
||||||
#ifndef QCRYPTO_IVGEN_PLAIN64_H__
|
#ifndef QCRYPTO_IVGEN_PLAIN64_H__
|
||||||
#define QCRYPTO_IVGEN_PLAIN64_H__
|
#define QCRYPTO_IVGEN_PLAIN64_H__
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|
||||||
#include "crypto/ivgenpriv.h"
|
#include "ivgenpriv.h"
|
||||||
#include "crypto/ivgen-plain.h"
|
#include "ivgen-plain.h"
|
||||||
#include "crypto/ivgen-plain64.h"
|
#include "ivgen-plain64.h"
|
||||||
#include "crypto/ivgen-essiv.h"
|
#include "ivgen-essiv.h"
|
||||||
|
|
||||||
|
|
||||||
QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg,
|
QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg,
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "crypto/tlscredspriv.h"
|
#include "tlscredspriv.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
#define DH_BITS 2048
|
#define DH_BITS 2048
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "crypto/tlscredsanon.h"
|
#include "crypto/tlscredsanon.h"
|
||||||
#include "crypto/tlscredspriv.h"
|
#include "tlscredspriv.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "crypto/tlscredsx509.h"
|
#include "crypto/tlscredsx509.h"
|
||||||
#include "crypto/tlscredspriv.h"
|
#include "tlscredspriv.h"
|
||||||
#include "crypto/secret.h"
|
#include "crypto/secret.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
|
@ -132,6 +132,16 @@ Depending on the request type, payload can be:
|
|||||||
Payload: Size bytes array holding the contents of the virtio
|
Payload: Size bytes array holding the contents of the virtio
|
||||||
device's configuration space
|
device's configuration space
|
||||||
|
|
||||||
|
* Vring area description
|
||||||
|
-----------------------
|
||||||
|
| u64 | size | offset |
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
u64: a 64-bit integer contains vring index and flags
|
||||||
|
Size: a 64-bit size of this area
|
||||||
|
Offset: a 64-bit offset of this area from the start of the
|
||||||
|
supplied file descriptor
|
||||||
|
|
||||||
In QEMU the vhost-user message is implemented with the following struct:
|
In QEMU the vhost-user message is implemented with the following struct:
|
||||||
|
|
||||||
typedef struct VhostUserMsg {
|
typedef struct VhostUserMsg {
|
||||||
@ -146,6 +156,7 @@ typedef struct VhostUserMsg {
|
|||||||
VhostUserLog log;
|
VhostUserLog log;
|
||||||
struct vhost_iotlb_msg iotlb;
|
struct vhost_iotlb_msg iotlb;
|
||||||
VhostUserConfig config;
|
VhostUserConfig config;
|
||||||
|
VhostUserVringArea area;
|
||||||
};
|
};
|
||||||
} QEMU_PACKED VhostUserMsg;
|
} QEMU_PACKED VhostUserMsg;
|
||||||
|
|
||||||
@ -367,6 +378,10 @@ The fd is provided via VHOST_USER_SET_SLAVE_REQ_FD ancillary data.
|
|||||||
A slave may then send VHOST_USER_SLAVE_* messages to the master
|
A slave may then send VHOST_USER_SLAVE_* messages to the master
|
||||||
using this fd communication channel.
|
using this fd communication channel.
|
||||||
|
|
||||||
|
If VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD protocol feature is negotiated,
|
||||||
|
slave can send file descriptors (at most 8 descriptors in each message)
|
||||||
|
to master via ancillary data using this fd communication channel.
|
||||||
|
|
||||||
Protocol features
|
Protocol features
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
@ -380,6 +395,8 @@ Protocol features
|
|||||||
#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
|
#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
|
||||||
#define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
|
#define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
|
||||||
#define VHOST_USER_PROTOCOL_F_CONFIG 9
|
#define VHOST_USER_PROTOCOL_F_CONFIG 9
|
||||||
|
#define VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD 10
|
||||||
|
#define VHOST_USER_PROTOCOL_F_HOST_NOTIFIER 11
|
||||||
|
|
||||||
Master message types
|
Master message types
|
||||||
--------------------
|
--------------------
|
||||||
@ -777,6 +794,27 @@ Slave message types
|
|||||||
the VHOST_USER_NEED_REPLY flag, master must respond with zero when
|
the VHOST_USER_NEED_REPLY flag, master must respond with zero when
|
||||||
operation is successfully completed, or non-zero otherwise.
|
operation is successfully completed, or non-zero otherwise.
|
||||||
|
|
||||||
|
* VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG
|
||||||
|
|
||||||
|
Id: 3
|
||||||
|
Equivalent ioctl: N/A
|
||||||
|
Slave payload: vring area description
|
||||||
|
Master payload: N/A
|
||||||
|
|
||||||
|
Sets host notifier for a specified queue. The queue index is contained
|
||||||
|
in the u64 field of the vring area description. The host notifier is
|
||||||
|
described by the file descriptor (typically it's a VFIO device fd) which
|
||||||
|
is passed as ancillary data and the size (which is mmap size and should
|
||||||
|
be the same as host page size) and offset (which is mmap offset) carried
|
||||||
|
in the vring area description. QEMU can mmap the file descriptor based
|
||||||
|
on the size and offset to get a memory range. Registering a host notifier
|
||||||
|
means mapping this memory range to the VM as the specified queue's notify
|
||||||
|
MMIO region. Slave sends this request to tell QEMU to de-register the
|
||||||
|
existing notifier if any and register the new notifier if the request is
|
||||||
|
sent with a file descriptor.
|
||||||
|
This request should be sent only when VHOST_USER_PROTOCOL_F_HOST_NOTIFIER
|
||||||
|
protocol feature has been successfully negotiated.
|
||||||
|
|
||||||
VHOST_USER_PROTOCOL_F_REPLY_ACK:
|
VHOST_USER_PROTOCOL_F_REPLY_ACK:
|
||||||
-------------------------------
|
-------------------------------
|
||||||
The original vhost-user specification only demands replies for certain
|
The original vhost-user specification only demands replies for certain
|
||||||
|
@ -153,3 +153,30 @@ guest NVDIMM region mapping structure. This unarmed flag indicates
|
|||||||
guest software that this vNVDIMM device contains a region that cannot
|
guest software that this vNVDIMM device contains a region that cannot
|
||||||
accept persistent writes. In result, for example, the guest Linux
|
accept persistent writes. In result, for example, the guest Linux
|
||||||
NVDIMM driver, marks such vNVDIMM device as read-only.
|
NVDIMM driver, marks such vNVDIMM device as read-only.
|
||||||
|
|
||||||
|
Platform Capabilities
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
ACPI 6.2 Errata A added support for a new Platform Capabilities Structure
|
||||||
|
which allows the platform to communicate what features it supports related to
|
||||||
|
NVDIMM data durability. Users can provide a capabilities value to a guest via
|
||||||
|
the optional "nvdimm-cap" machine command line option:
|
||||||
|
|
||||||
|
-machine pc,accel=kvm,nvdimm,nvdimm-cap=2
|
||||||
|
|
||||||
|
This "nvdimm-cap" field is an integer, and is the combined value of the
|
||||||
|
various capability bits defined in table 5-137 of the ACPI 6.2 Errata A spec.
|
||||||
|
|
||||||
|
Here is a quick summary of the three bits that are defined as of that spec:
|
||||||
|
|
||||||
|
Bit[0] - CPU Cache Flush to NVDIMM Durability on Power Loss Capable.
|
||||||
|
Bit[1] - Memory Controller Flush to NVDIMM Durability on Power Loss Capable.
|
||||||
|
Note: If bit 0 is set to 1 then this bit shall be set to 1 as well.
|
||||||
|
Bit[2] - Byte Addressable Persistent Memory Hardware Mirroring Capable.
|
||||||
|
|
||||||
|
So, a "nvdimm-cap" value of 2 would mean that the platform supports Memory
|
||||||
|
Controller Flush on Power Loss, a value of 3 would mean that the platform
|
||||||
|
supports CPU Cache Flush and Memory Controller Flush on Power Loss, etc.
|
||||||
|
|
||||||
|
For a complete list of the flags available and for more detailed descriptions,
|
||||||
|
please consult the ACPI spec.
|
||||||
|
@ -169,6 +169,21 @@ struct NvdimmNfitControlRegion {
|
|||||||
} QEMU_PACKED;
|
} QEMU_PACKED;
|
||||||
typedef struct NvdimmNfitControlRegion NvdimmNfitControlRegion;
|
typedef struct NvdimmNfitControlRegion NvdimmNfitControlRegion;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NVDIMM Platform Capabilities Structure
|
||||||
|
*
|
||||||
|
* Defined in section 5.2.25.9 of ACPI 6.2 Errata A, September 2017
|
||||||
|
*/
|
||||||
|
struct NvdimmNfitPlatformCaps {
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t length;
|
||||||
|
uint8_t highest_cap;
|
||||||
|
uint8_t reserved[3];
|
||||||
|
uint32_t capabilities;
|
||||||
|
uint8_t reserved2[4];
|
||||||
|
} QEMU_PACKED;
|
||||||
|
typedef struct NvdimmNfitPlatformCaps NvdimmNfitPlatformCaps;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Module serial number is a unique number for each device. We use the
|
* Module serial number is a unique number for each device. We use the
|
||||||
* slot id of NVDIMM device to generate this number so that each device
|
* slot id of NVDIMM device to generate this number so that each device
|
||||||
@ -351,7 +366,23 @@ static void nvdimm_build_structure_dcr(GArray *structures, DeviceState *dev)
|
|||||||
JEDEC Annex L Release 3. */);
|
JEDEC Annex L Release 3. */);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GArray *nvdimm_build_device_structure(void)
|
/*
|
||||||
|
* ACPI 6.2 Errata A: 5.2.25.9 NVDIMM Platform Capabilities Structure
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
nvdimm_build_structure_caps(GArray *structures, uint32_t capabilities)
|
||||||
|
{
|
||||||
|
NvdimmNfitPlatformCaps *nfit_caps;
|
||||||
|
|
||||||
|
nfit_caps = acpi_data_push(structures, sizeof(*nfit_caps));
|
||||||
|
|
||||||
|
nfit_caps->type = cpu_to_le16(7 /* NVDIMM Platform Capabilities */);
|
||||||
|
nfit_caps->length = cpu_to_le16(sizeof(*nfit_caps));
|
||||||
|
nfit_caps->highest_cap = 31 - clz32(capabilities);
|
||||||
|
nfit_caps->capabilities = cpu_to_le32(capabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GArray *nvdimm_build_device_structure(AcpiNVDIMMState *state)
|
||||||
{
|
{
|
||||||
GSList *device_list = nvdimm_get_device_list();
|
GSList *device_list = nvdimm_get_device_list();
|
||||||
GArray *structures = g_array_new(false, true /* clear */, 1);
|
GArray *structures = g_array_new(false, true /* clear */, 1);
|
||||||
@ -373,6 +404,10 @@ static GArray *nvdimm_build_device_structure(void)
|
|||||||
}
|
}
|
||||||
g_slist_free(device_list);
|
g_slist_free(device_list);
|
||||||
|
|
||||||
|
if (state->capabilities) {
|
||||||
|
nvdimm_build_structure_caps(structures, state->capabilities);
|
||||||
|
}
|
||||||
|
|
||||||
return structures;
|
return structures;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,16 +416,18 @@ static void nvdimm_init_fit_buffer(NvdimmFitBuffer *fit_buf)
|
|||||||
fit_buf->fit = g_array_new(false, true /* clear */, 1);
|
fit_buf->fit = g_array_new(false, true /* clear */, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nvdimm_build_fit_buffer(NvdimmFitBuffer *fit_buf)
|
static void nvdimm_build_fit_buffer(AcpiNVDIMMState *state)
|
||||||
{
|
{
|
||||||
|
NvdimmFitBuffer *fit_buf = &state->fit_buf;
|
||||||
|
|
||||||
g_array_free(fit_buf->fit, true);
|
g_array_free(fit_buf->fit, true);
|
||||||
fit_buf->fit = nvdimm_build_device_structure();
|
fit_buf->fit = nvdimm_build_device_structure(state);
|
||||||
fit_buf->dirty = true;
|
fit_buf->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvdimm_plug(AcpiNVDIMMState *state)
|
void nvdimm_plug(AcpiNVDIMMState *state)
|
||||||
{
|
{
|
||||||
nvdimm_build_fit_buffer(&state->fit_buf);
|
nvdimm_build_fit_buffer(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nvdimm_build_nfit(AcpiNVDIMMState *state, GArray *table_offsets,
|
static void nvdimm_build_nfit(AcpiNVDIMMState *state, GArray *table_offsets,
|
||||||
|
@ -203,13 +203,11 @@ static uint64_t vhost_user_blk_get_features(VirtIODevice *vdev,
|
|||||||
virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
|
virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
|
||||||
virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
|
virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
|
||||||
virtio_add_feature(&features, VIRTIO_BLK_F_FLUSH);
|
virtio_add_feature(&features, VIRTIO_BLK_F_FLUSH);
|
||||||
|
virtio_add_feature(&features, VIRTIO_BLK_F_RO);
|
||||||
|
|
||||||
if (s->config_wce) {
|
if (s->config_wce) {
|
||||||
virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
|
virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
|
||||||
}
|
}
|
||||||
if (s->config_ro) {
|
|
||||||
virtio_add_feature(&features, VIRTIO_BLK_F_RO);
|
|
||||||
}
|
|
||||||
if (s->num_queues > 1) {
|
if (s->num_queues > 1) {
|
||||||
virtio_add_feature(&features, VIRTIO_BLK_F_MQ);
|
virtio_add_feature(&features, VIRTIO_BLK_F_MQ);
|
||||||
}
|
}
|
||||||
@ -226,6 +224,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
||||||
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
||||||
|
VhostUserState *user;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
if (!s->chardev.chr) {
|
if (!s->chardev.chr) {
|
||||||
@ -243,6 +242,15 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user = vhost_user_init();
|
||||||
|
if (!user) {
|
||||||
|
error_setg(errp, "vhost-user-blk: failed to init vhost_user");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user->chr = &s->chardev;
|
||||||
|
s->vhost_user = user;
|
||||||
|
|
||||||
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
|
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
|
||||||
sizeof(struct virtio_blk_config));
|
sizeof(struct virtio_blk_config));
|
||||||
|
|
||||||
@ -258,7 +266,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
vhost_dev_set_config_notifier(&s->dev, &blk_ops);
|
vhost_dev_set_config_notifier(&s->dev, &blk_ops);
|
||||||
|
|
||||||
ret = vhost_dev_init(&s->dev, &s->chardev, VHOST_BACKEND_TYPE_USER, 0);
|
ret = vhost_dev_init(&s->dev, s->vhost_user, VHOST_BACKEND_TYPE_USER, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg(errp, "vhost-user-blk: vhost initialization failed: %s",
|
error_setg(errp, "vhost-user-blk: vhost initialization failed: %s",
|
||||||
strerror(-ret));
|
strerror(-ret));
|
||||||
@ -283,6 +291,10 @@ vhost_err:
|
|||||||
virtio_err:
|
virtio_err:
|
||||||
g_free(s->dev.vqs);
|
g_free(s->dev.vqs);
|
||||||
virtio_cleanup(vdev);
|
virtio_cleanup(vdev);
|
||||||
|
|
||||||
|
vhost_user_cleanup(user);
|
||||||
|
g_free(user);
|
||||||
|
s->vhost_user = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
|
static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
|
||||||
@ -294,6 +306,12 @@ static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
|
|||||||
vhost_dev_cleanup(&s->dev);
|
vhost_dev_cleanup(&s->dev);
|
||||||
g_free(s->dev.vqs);
|
g_free(s->dev.vqs);
|
||||||
virtio_cleanup(vdev);
|
virtio_cleanup(vdev);
|
||||||
|
|
||||||
|
if (s->vhost_user) {
|
||||||
|
vhost_user_cleanup(s->vhost_user);
|
||||||
|
g_free(s->vhost_user);
|
||||||
|
s->vhost_user = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vhost_user_blk_instance_init(Object *obj)
|
static void vhost_user_blk_instance_init(Object *obj)
|
||||||
@ -319,7 +337,6 @@ static Property vhost_user_blk_properties[] = {
|
|||||||
DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues, 1),
|
DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues, 1),
|
||||||
DEFINE_PROP_UINT32("queue-size", VHostUserBlk, queue_size, 128),
|
DEFINE_PROP_UINT32("queue-size", VHostUserBlk, queue_size, 128),
|
||||||
DEFINE_PROP_BIT("config-wce", VHostUserBlk, config_wce, 0, true),
|
DEFINE_PROP_BIT("config-wce", VHostUserBlk, config_wce, 0, true),
|
||||||
DEFINE_PROP_BIT("config-ro", VHostUserBlk, config_ro, 0, false),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "hw/display/bcm2835_fb.h"
|
#include "hw/display/bcm2835_fb.h"
|
||||||
#include "hw/display/framebuffer.h"
|
#include "framebuffer.h"
|
||||||
#include "ui/pixel_ops.h"
|
#include "ui/pixel_ops.h"
|
||||||
#include "hw/misc/bcm2835_mbox_defs.h"
|
#include "hw/misc/bcm2835_mbox_defs.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "hw/i386/pc.h"
|
#include "hw/i386/pc.h"
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
|
|
||||||
#include "hw/hppa/hppa_hardware.h"
|
#include "hppa_hardware.h"
|
||||||
|
|
||||||
PCIBus *dino_init(MemoryRegion *, qemu_irq *, qemu_irq *);
|
PCIBus *dino_init(MemoryRegion *, qemu_irq *, qemu_irq *);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "hw/ide.h"
|
#include "hw/ide.h"
|
||||||
#include "hw/timer/i8254.h"
|
#include "hw/timer/i8254.h"
|
||||||
#include "hw/char/serial.h"
|
#include "hw/char/serial.h"
|
||||||
#include "hw/hppa/hppa_sys.h"
|
#include "hppa_sys.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
31
hw/i386/pc.c
31
hw/i386/pc.c
@ -2181,6 +2181,33 @@ static void pc_machine_set_nvdimm(Object *obj, bool value, Error **errp)
|
|||||||
pcms->acpi_nvdimm_state.is_enabled = value;
|
pcms->acpi_nvdimm_state.is_enabled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pc_machine_get_nvdimm_capabilities(Object *obj, Visitor *v,
|
||||||
|
const char *name, void *opaque,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
PCMachineState *pcms = PC_MACHINE(obj);
|
||||||
|
uint32_t value = pcms->acpi_nvdimm_state.capabilities;
|
||||||
|
|
||||||
|
visit_type_uint32(v, name, &value, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pc_machine_set_nvdimm_capabilities(Object *obj, Visitor *v,
|
||||||
|
const char *name, void *opaque,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
PCMachineState *pcms = PC_MACHINE(obj);
|
||||||
|
Error *error = NULL;
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
visit_type_uint32(v, name, &value, &error);
|
||||||
|
if (error) {
|
||||||
|
error_propagate(errp, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcms->acpi_nvdimm_state.capabilities = value;
|
||||||
|
}
|
||||||
|
|
||||||
static bool pc_machine_get_smbus(Object *obj, Error **errp)
|
static bool pc_machine_get_smbus(Object *obj, Error **errp)
|
||||||
{
|
{
|
||||||
PCMachineState *pcms = PC_MACHINE(obj);
|
PCMachineState *pcms = PC_MACHINE(obj);
|
||||||
@ -2394,6 +2421,10 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
object_class_property_add_bool(oc, PC_MACHINE_NVDIMM,
|
object_class_property_add_bool(oc, PC_MACHINE_NVDIMM,
|
||||||
pc_machine_get_nvdimm, pc_machine_set_nvdimm, &error_abort);
|
pc_machine_get_nvdimm, pc_machine_set_nvdimm, &error_abort);
|
||||||
|
|
||||||
|
object_class_property_add(oc, PC_MACHINE_NVDIMM_CAP, "uint32",
|
||||||
|
pc_machine_get_nvdimm_capabilities,
|
||||||
|
pc_machine_set_nvdimm_capabilities, NULL, NULL, &error_abort);
|
||||||
|
|
||||||
object_class_property_add_bool(oc, PC_MACHINE_SMBUS,
|
object_class_property_add_bool(oc, PC_MACHINE_SMBUS,
|
||||||
pc_machine_get_smbus, pc_machine_set_smbus, &error_abort);
|
pc_machine_get_smbus, pc_machine_set_smbus, &error_abort);
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "sysemu/dma.h"
|
#include "sysemu/dma.h"
|
||||||
#include "hw/ide/internal.h"
|
#include "hw/ide/internal.h"
|
||||||
#include "hw/ide/ahci_internal.h"
|
#include "ahci_internal.h"
|
||||||
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include "sysemu/dma.h"
|
#include "sysemu/dma.h"
|
||||||
#include "hw/ide/internal.h"
|
#include "hw/ide/internal.h"
|
||||||
#include "hw/ide/pci.h"
|
#include "hw/ide/pci.h"
|
||||||
#include "hw/ide/ahci_internal.h"
|
#include "ahci_internal.h"
|
||||||
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
#include "hw/isa/isa.h"
|
#include "hw/isa/isa.h"
|
||||||
#include "sysemu/dma.h"
|
#include "sysemu/dma.h"
|
||||||
#include "hw/ide/pci.h"
|
#include "hw/ide/pci.h"
|
||||||
#include "hw/ide/ahci_internal.h"
|
#include "ahci_internal.h"
|
||||||
|
|
||||||
#define ICH9_MSI_CAP_OFFSET 0x80
|
#define ICH9_MSI_CAP_OFFSET 0x80
|
||||||
#define ICH9_SATA_CAP_OFFSET 0xA8
|
#define ICH9_SATA_CAP_OFFSET 0xA8
|
||||||
|
@ -28,9 +28,8 @@
|
|||||||
#include "hw/i386/apic.h"
|
#include "hw/i386/apic.h"
|
||||||
#include "hw/i386/ioapic.h"
|
#include "hw/i386/ioapic.h"
|
||||||
#include "hw/i386/ioapic_internal.h"
|
#include "hw/i386/ioapic_internal.h"
|
||||||
#include "include/hw/pci/msi.h"
|
#include "hw/pci/msi.h"
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "target/i386/cpu.h"
|
|
||||||
#include "hw/i386/apic-msidef.h"
|
#include "hw/i386/apic-msidef.h"
|
||||||
#include "hw/i386/x86-iommu.h"
|
#include "hw/i386/x86-iommu.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#include "hw/pci/msi.h"
|
#include "hw/pci/msi.h"
|
||||||
#include "hw/pci/msix.h"
|
#include "hw/pci/msix.h"
|
||||||
|
|
||||||
#include "hw/net/e1000_regs.h"
|
#include "e1000_regs.h"
|
||||||
|
|
||||||
#include "e1000x_common.h"
|
#include "e1000x_common.h"
|
||||||
#include "e1000e_core.h"
|
#include "e1000e_core.h"
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "net/clients.h"
|
|
||||||
#include "qapi/qapi-types-rocker.h"
|
#include "qapi/qapi-types-rocker.h"
|
||||||
#include "rocker.h"
|
#include "rocker.h"
|
||||||
#include "rocker_hw.h"
|
#include "rocker_hw.h"
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "hw/ppc/ppc.h"
|
#include "hw/ppc/ppc.h"
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
#include "sysemu/block-backend.h"
|
#include "sysemu/block-backend.h"
|
||||||
#include "hw/ppc/ppc440.h"
|
#include "ppc440.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* L2 Cache as SRAM */
|
/* L2 Cache as SRAM */
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
#include "hw/ppc/ppc440.h"
|
#include "ppc440.h"
|
||||||
#include "hw/ppc/ppc405.h"
|
#include "ppc405.h"
|
||||||
#include "hw/block/flash.h"
|
#include "hw/block/flash.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "sysemu/qtest.h"
|
#include "sysemu/qtest.h"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "migration/migration.h"
|
|
||||||
#include "hw/virtio/vhost.h"
|
#include "hw/virtio/vhost.h"
|
||||||
#include "hw/virtio/vhost-scsi-common.h"
|
#include "hw/virtio/vhost-scsi-common.h"
|
||||||
#include "hw/virtio/virtio-scsi.h"
|
#include "hw/virtio/virtio-scsi.h"
|
||||||
|
@ -69,6 +69,7 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
|
|||||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
|
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
|
||||||
VHostUserSCSI *s = VHOST_USER_SCSI(dev);
|
VHostUserSCSI *s = VHOST_USER_SCSI(dev);
|
||||||
VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
|
VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
|
||||||
|
VhostUserState *user;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -85,19 +86,30 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user = vhost_user_init();
|
||||||
|
if (!user) {
|
||||||
|
error_setg(errp, "vhost-user-scsi: failed to init vhost_user");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
user->chr = &vs->conf.chardev;
|
||||||
|
|
||||||
vsc->dev.nvqs = 2 + vs->conf.num_queues;
|
vsc->dev.nvqs = 2 + vs->conf.num_queues;
|
||||||
vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs);
|
vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs);
|
||||||
vsc->dev.vq_index = 0;
|
vsc->dev.vq_index = 0;
|
||||||
vsc->dev.backend_features = 0;
|
vsc->dev.backend_features = 0;
|
||||||
|
|
||||||
ret = vhost_dev_init(&vsc->dev, (void *)&vs->conf.chardev,
|
ret = vhost_dev_init(&vsc->dev, user,
|
||||||
VHOST_BACKEND_TYPE_USER, 0);
|
VHOST_BACKEND_TYPE_USER, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg(errp, "vhost-user-scsi: vhost initialization failed: %s",
|
error_setg(errp, "vhost-user-scsi: vhost initialization failed: %s",
|
||||||
strerror(-ret));
|
strerror(-ret));
|
||||||
|
vhost_user_cleanup(user);
|
||||||
|
g_free(user);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->vhost_user = user;
|
||||||
|
|
||||||
/* Channel and lun both are 0 for bootable vhost-user-scsi disk */
|
/* Channel and lun both are 0 for bootable vhost-user-scsi disk */
|
||||||
vsc->channel = 0;
|
vsc->channel = 0;
|
||||||
vsc->lun = 0;
|
vsc->lun = 0;
|
||||||
@ -117,6 +129,12 @@ static void vhost_user_scsi_unrealize(DeviceState *dev, Error **errp)
|
|||||||
g_free(vsc->dev.vqs);
|
g_free(vsc->dev.vqs);
|
||||||
|
|
||||||
virtio_scsi_common_unrealize(dev, errp);
|
virtio_scsi_common_unrealize(dev, errp);
|
||||||
|
|
||||||
|
if (s->vhost_user) {
|
||||||
|
vhost_user_cleanup(s->vhost_user);
|
||||||
|
g_free(s->vhost_user);
|
||||||
|
s->vhost_user = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t vhost_user_scsi_get_features(VirtIODevice *vdev,
|
static uint64_t vhost_user_scsi_get_features(VirtIODevice *vdev,
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "include/qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "sysemu/block-backend.h"
|
#include "sysemu/block-backend.h"
|
||||||
#include "sysemu/blockdev.h"
|
#include "sysemu/blockdev.h"
|
||||||
#include "hw/sd/sd.h"
|
#include "hw/sd/sd.h"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Microsoft OS Descriptors
|
* Microsoft OS Descriptors
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "audio/audio.h"
|
#include "audio/audio.h"
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
#include "sysemu/bt.h"
|
#include "sysemu/bt.h"
|
||||||
#include "hw/bt.h"
|
#include "hw/bt.h"
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "ui/console.h"
|
#include "ui/console.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "hw/input/hid.h"
|
#include "hw/input/hid.h"
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
|
||||||
#define NUM_PORTS 8
|
#define NUM_PORTS 8
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include "qemu/iov.h"
|
#include "qemu/iov.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
#include "net/net.h"
|
#include "net/net.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
#include "chardev/char-serial.h"
|
#include "chardev/char-serial.h"
|
||||||
#include "chardev/char-fe.h"
|
#include "chardev/char-fe.h"
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
|
|
||||||
#include "ccid.h"
|
#include "ccid.h"
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
#include "hw/scsi/scsi.h"
|
#include "hw/scsi/scsi.h"
|
||||||
#include "ui/console.h"
|
#include "ui/console.h"
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
#include "hw/scsi/scsi.h"
|
#include "hw/scsi/scsi.h"
|
||||||
#include "scsi/constants.h"
|
#include "scsi/constants.h"
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "ui/console.h"
|
#include "ui/console.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/usb/desc.h"
|
#include "desc.h"
|
||||||
|
|
||||||
/* Interface requests */
|
/* Interface requests */
|
||||||
#define WACOM_GET_REPORT 0x2101
|
#define WACOM_GET_REPORT 0x2101
|
||||||
|
@ -1,7 +1,17 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/virtio/vhost.h"
|
#include "hw/virtio/vhost.h"
|
||||||
|
#include "hw/virtio/vhost-user.h"
|
||||||
|
|
||||||
bool vhost_has_free_slot(void)
|
bool vhost_has_free_slot(void)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VhostUserState *vhost_user_init(void)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vhost_user_cleanup(VhostUserState *user)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -11,7 +11,9 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "hw/virtio/vhost.h"
|
#include "hw/virtio/vhost.h"
|
||||||
|
#include "hw/virtio/vhost-user.h"
|
||||||
#include "hw/virtio/vhost-backend.h"
|
#include "hw/virtio/vhost-backend.h"
|
||||||
|
#include "hw/virtio/virtio.h"
|
||||||
#include "hw/virtio/virtio-net.h"
|
#include "hw/virtio/virtio-net.h"
|
||||||
#include "chardev/char-fe.h"
|
#include "chardev/char-fe.h"
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
@ -30,6 +32,7 @@
|
|||||||
|
|
||||||
#define VHOST_MEMORY_MAX_NREGIONS 8
|
#define VHOST_MEMORY_MAX_NREGIONS 8
|
||||||
#define VHOST_USER_F_PROTOCOL_FEATURES 30
|
#define VHOST_USER_F_PROTOCOL_FEATURES 30
|
||||||
|
#define VHOST_USER_SLAVE_MAX_FDS 8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum size of virtio device config space
|
* Maximum size of virtio device config space
|
||||||
@ -47,6 +50,8 @@ enum VhostUserProtocolFeature {
|
|||||||
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
||||||
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
||||||
VHOST_USER_PROTOCOL_F_CONFIG = 9,
|
VHOST_USER_PROTOCOL_F_CONFIG = 9,
|
||||||
|
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
|
||||||
|
VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
|
||||||
VHOST_USER_PROTOCOL_F_MAX
|
VHOST_USER_PROTOCOL_F_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,6 +96,7 @@ typedef enum VhostUserSlaveRequest {
|
|||||||
VHOST_USER_SLAVE_NONE = 0,
|
VHOST_USER_SLAVE_NONE = 0,
|
||||||
VHOST_USER_SLAVE_IOTLB_MSG = 1,
|
VHOST_USER_SLAVE_IOTLB_MSG = 1,
|
||||||
VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
|
VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
|
||||||
|
VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG = 3,
|
||||||
VHOST_USER_SLAVE_MAX
|
VHOST_USER_SLAVE_MAX
|
||||||
} VhostUserSlaveRequest;
|
} VhostUserSlaveRequest;
|
||||||
|
|
||||||
@ -135,6 +141,12 @@ static VhostUserConfig c __attribute__ ((unused));
|
|||||||
+ sizeof(c.size) \
|
+ sizeof(c.size) \
|
||||||
+ sizeof(c.flags))
|
+ sizeof(c.flags))
|
||||||
|
|
||||||
|
typedef struct VhostUserVringArea {
|
||||||
|
uint64_t u64;
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t offset;
|
||||||
|
} VhostUserVringArea;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
VhostUserRequest request;
|
VhostUserRequest request;
|
||||||
|
|
||||||
@ -156,6 +168,7 @@ typedef union {
|
|||||||
struct vhost_iotlb_msg iotlb;
|
struct vhost_iotlb_msg iotlb;
|
||||||
VhostUserConfig config;
|
VhostUserConfig config;
|
||||||
VhostUserCryptoSession session;
|
VhostUserCryptoSession session;
|
||||||
|
VhostUserVringArea area;
|
||||||
} VhostUserPayload;
|
} VhostUserPayload;
|
||||||
|
|
||||||
typedef struct VhostUserMsg {
|
typedef struct VhostUserMsg {
|
||||||
@ -173,7 +186,8 @@ static VhostUserMsg m __attribute__ ((unused));
|
|||||||
|
|
||||||
struct vhost_user {
|
struct vhost_user {
|
||||||
struct vhost_dev *dev;
|
struct vhost_dev *dev;
|
||||||
CharBackend *chr;
|
/* Shared between vhost devs of the same virtio device */
|
||||||
|
VhostUserState *user;
|
||||||
int slave_fd;
|
int slave_fd;
|
||||||
NotifierWithReturn postcopy_notifier;
|
NotifierWithReturn postcopy_notifier;
|
||||||
struct PostCopyFD postcopy_fd;
|
struct PostCopyFD postcopy_fd;
|
||||||
@ -199,7 +213,7 @@ static bool ioeventfd_enabled(void)
|
|||||||
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
|
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
|
||||||
{
|
{
|
||||||
struct vhost_user *u = dev->opaque;
|
struct vhost_user *u = dev->opaque;
|
||||||
CharBackend *chr = u->chr;
|
CharBackend *chr = u->user->chr;
|
||||||
uint8_t *p = (uint8_t *) msg;
|
uint8_t *p = (uint8_t *) msg;
|
||||||
int r, size = VHOST_USER_HDR_SIZE;
|
int r, size = VHOST_USER_HDR_SIZE;
|
||||||
|
|
||||||
@ -285,7 +299,7 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
|
|||||||
int *fds, int fd_num)
|
int *fds, int fd_num)
|
||||||
{
|
{
|
||||||
struct vhost_user *u = dev->opaque;
|
struct vhost_user *u = dev->opaque;
|
||||||
CharBackend *chr = u->chr;
|
CharBackend *chr = u->user->chr;
|
||||||
int ret, size = VHOST_USER_HDR_SIZE + msg->hdr.size;
|
int ret, size = VHOST_USER_HDR_SIZE + msg->hdr.size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -636,9 +650,37 @@ static int vhost_user_set_vring_num(struct vhost_dev *dev,
|
|||||||
return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring);
|
return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vhost_user_host_notifier_restore(struct vhost_dev *dev,
|
||||||
|
int queue_idx)
|
||||||
|
{
|
||||||
|
struct vhost_user *u = dev->opaque;
|
||||||
|
VhostUserHostNotifier *n = &u->user->notifier[queue_idx];
|
||||||
|
VirtIODevice *vdev = dev->vdev;
|
||||||
|
|
||||||
|
if (n->addr && !n->set) {
|
||||||
|
virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true);
|
||||||
|
n->set = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vhost_user_host_notifier_remove(struct vhost_dev *dev,
|
||||||
|
int queue_idx)
|
||||||
|
{
|
||||||
|
struct vhost_user *u = dev->opaque;
|
||||||
|
VhostUserHostNotifier *n = &u->user->notifier[queue_idx];
|
||||||
|
VirtIODevice *vdev = dev->vdev;
|
||||||
|
|
||||||
|
if (n->addr && n->set) {
|
||||||
|
virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false);
|
||||||
|
n->set = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int vhost_user_set_vring_base(struct vhost_dev *dev,
|
static int vhost_user_set_vring_base(struct vhost_dev *dev,
|
||||||
struct vhost_vring_state *ring)
|
struct vhost_vring_state *ring)
|
||||||
{
|
{
|
||||||
|
vhost_user_host_notifier_restore(dev, ring->index);
|
||||||
|
|
||||||
return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring);
|
return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,6 +714,8 @@ static int vhost_user_get_vring_base(struct vhost_dev *dev,
|
|||||||
.hdr.size = sizeof(msg.payload.state),
|
.hdr.size = sizeof(msg.payload.state),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vhost_user_host_notifier_remove(dev, ring->index);
|
||||||
|
|
||||||
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
|
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -845,6 +889,66 @@ static int vhost_user_slave_handle_config_change(struct vhost_dev *dev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev,
|
||||||
|
VhostUserVringArea *area,
|
||||||
|
int fd)
|
||||||
|
{
|
||||||
|
int queue_idx = area->u64 & VHOST_USER_VRING_IDX_MASK;
|
||||||
|
size_t page_size = qemu_real_host_page_size;
|
||||||
|
struct vhost_user *u = dev->opaque;
|
||||||
|
VhostUserState *user = u->user;
|
||||||
|
VirtIODevice *vdev = dev->vdev;
|
||||||
|
VhostUserHostNotifier *n;
|
||||||
|
void *addr;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
if (!virtio_has_feature(dev->protocol_features,
|
||||||
|
VHOST_USER_PROTOCOL_F_HOST_NOTIFIER) ||
|
||||||
|
vdev == NULL || queue_idx >= virtio_get_num_queues(vdev)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = &user->notifier[queue_idx];
|
||||||
|
|
||||||
|
if (n->addr) {
|
||||||
|
virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false);
|
||||||
|
object_unparent(OBJECT(&n->mr));
|
||||||
|
munmap(n->addr, page_size);
|
||||||
|
n->addr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (area->u64 & VHOST_USER_VRING_NOFD_MASK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity check. */
|
||||||
|
if (area->size != page_size) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||||
|
fd, area->offset);
|
||||||
|
if (addr == MAP_FAILED) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = g_strdup_printf("vhost-user/host-notifier@%p mmaps[%d]",
|
||||||
|
user, queue_idx);
|
||||||
|
memory_region_init_ram_device_ptr(&n->mr, OBJECT(vdev), name,
|
||||||
|
page_size, addr);
|
||||||
|
g_free(name);
|
||||||
|
|
||||||
|
if (virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true)) {
|
||||||
|
munmap(addr, page_size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
n->addr = addr;
|
||||||
|
n->set = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void slave_read(void *opaque)
|
static void slave_read(void *opaque)
|
||||||
{
|
{
|
||||||
struct vhost_dev *dev = opaque;
|
struct vhost_dev *dev = opaque;
|
||||||
@ -854,10 +958,10 @@ static void slave_read(void *opaque)
|
|||||||
int size, ret = 0;
|
int size, ret = 0;
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
struct msghdr msgh;
|
struct msghdr msgh;
|
||||||
int fd = -1;
|
int fd[VHOST_USER_SLAVE_MAX_FDS];
|
||||||
char control[CMSG_SPACE(sizeof(fd))];
|
char control[CMSG_SPACE(sizeof(fd))];
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
size_t fdsize;
|
int i, fdsize = 0;
|
||||||
|
|
||||||
memset(&msgh, 0, sizeof(msgh));
|
memset(&msgh, 0, sizeof(msgh));
|
||||||
msgh.msg_iov = &iov;
|
msgh.msg_iov = &iov;
|
||||||
@ -865,6 +969,8 @@ static void slave_read(void *opaque)
|
|||||||
msgh.msg_control = control;
|
msgh.msg_control = control;
|
||||||
msgh.msg_controllen = sizeof(control);
|
msgh.msg_controllen = sizeof(control);
|
||||||
|
|
||||||
|
memset(fd, -1, sizeof(fd));
|
||||||
|
|
||||||
/* Read header */
|
/* Read header */
|
||||||
iov.iov_base = &hdr;
|
iov.iov_base = &hdr;
|
||||||
iov.iov_len = VHOST_USER_HDR_SIZE;
|
iov.iov_len = VHOST_USER_HDR_SIZE;
|
||||||
@ -885,7 +991,7 @@ static void slave_read(void *opaque)
|
|||||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||||
cmsg->cmsg_type == SCM_RIGHTS) {
|
cmsg->cmsg_type == SCM_RIGHTS) {
|
||||||
fdsize = cmsg->cmsg_len - CMSG_LEN(0);
|
fdsize = cmsg->cmsg_len - CMSG_LEN(0);
|
||||||
memcpy(&fd, CMSG_DATA(cmsg), fdsize);
|
memcpy(fd, CMSG_DATA(cmsg), fdsize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -911,16 +1017,21 @@ static void slave_read(void *opaque)
|
|||||||
case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG :
|
case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG :
|
||||||
ret = vhost_user_slave_handle_config_change(dev);
|
ret = vhost_user_slave_handle_config_change(dev);
|
||||||
break;
|
break;
|
||||||
|
case VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG:
|
||||||
|
ret = vhost_user_slave_handle_vring_host_notifier(dev, &payload.area,
|
||||||
|
fd[0]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
error_report("Received unexpected msg type.");
|
error_report("Received unexpected msg type.");
|
||||||
if (fd != -1) {
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Message handlers need to make sure that fd will be consumed. */
|
/* Close the remaining file descriptors. */
|
||||||
fd = -1;
|
for (i = 0; i < fdsize; i++) {
|
||||||
|
if (fd[i] != -1) {
|
||||||
|
close(fd[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* REPLY_ACK feature handling. Other reply types has to be managed
|
* REPLY_ACK feature handling. Other reply types has to be managed
|
||||||
@ -954,8 +1065,10 @@ err:
|
|||||||
qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
|
qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
|
||||||
close(u->slave_fd);
|
close(u->slave_fd);
|
||||||
u->slave_fd = -1;
|
u->slave_fd = -1;
|
||||||
if (fd != -1) {
|
for (i = 0; i < fdsize; i++) {
|
||||||
close(fd);
|
if (fd[i] != -1) {
|
||||||
|
close(fd[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1083,7 +1196,7 @@ static int vhost_user_postcopy_waker(struct PostCopyFD *pcfd, RAMBlock *rb,
|
|||||||
static int vhost_user_postcopy_advise(struct vhost_dev *dev, Error **errp)
|
static int vhost_user_postcopy_advise(struct vhost_dev *dev, Error **errp)
|
||||||
{
|
{
|
||||||
struct vhost_user *u = dev->opaque;
|
struct vhost_user *u = dev->opaque;
|
||||||
CharBackend *chr = u->chr;
|
CharBackend *chr = u->user->chr;
|
||||||
int ufd;
|
int ufd;
|
||||||
VhostUserMsg msg = {
|
VhostUserMsg msg = {
|
||||||
.hdr.request = VHOST_USER_POSTCOPY_ADVISE,
|
.hdr.request = VHOST_USER_POSTCOPY_ADVISE,
|
||||||
@ -1221,7 +1334,7 @@ static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vhost_user_init(struct vhost_dev *dev, void *opaque)
|
static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
|
||||||
{
|
{
|
||||||
uint64_t features, protocol_features;
|
uint64_t features, protocol_features;
|
||||||
struct vhost_user *u;
|
struct vhost_user *u;
|
||||||
@ -1230,7 +1343,7 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
|
|||||||
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
|
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
|
||||||
|
|
||||||
u = g_new0(struct vhost_user, 1);
|
u = g_new0(struct vhost_user, 1);
|
||||||
u->chr = opaque;
|
u->user = opaque;
|
||||||
u->slave_fd = -1;
|
u->slave_fd = -1;
|
||||||
u->dev = dev;
|
u->dev = dev;
|
||||||
dev->opaque = u;
|
dev->opaque = u;
|
||||||
@ -1306,7 +1419,7 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vhost_user_cleanup(struct vhost_dev *dev)
|
static int vhost_user_backend_cleanup(struct vhost_dev *dev)
|
||||||
{
|
{
|
||||||
struct vhost_user *u;
|
struct vhost_user *u;
|
||||||
|
|
||||||
@ -1620,10 +1733,40 @@ vhost_user_crypto_close_session(struct vhost_dev *dev, uint64_t session_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool vhost_user_mem_section_filter(struct vhost_dev *dev,
|
||||||
|
MemoryRegionSection *section)
|
||||||
|
{
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
result = memory_region_get_fd(section->mr) >= 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
VhostUserState *vhost_user_init(void)
|
||||||
|
{
|
||||||
|
VhostUserState *user = g_new0(struct VhostUserState, 1);
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vhost_user_cleanup(VhostUserState *user)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
|
||||||
|
if (user->notifier[i].addr) {
|
||||||
|
object_unparent(OBJECT(&user->notifier[i].mr));
|
||||||
|
munmap(user->notifier[i].addr, qemu_real_host_page_size);
|
||||||
|
user->notifier[i].addr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const VhostOps user_ops = {
|
const VhostOps user_ops = {
|
||||||
.backend_type = VHOST_BACKEND_TYPE_USER,
|
.backend_type = VHOST_BACKEND_TYPE_USER,
|
||||||
.vhost_backend_init = vhost_user_init,
|
.vhost_backend_init = vhost_user_backend_init,
|
||||||
.vhost_backend_cleanup = vhost_user_cleanup,
|
.vhost_backend_cleanup = vhost_user_backend_cleanup,
|
||||||
.vhost_backend_memslots_limit = vhost_user_memslots_limit,
|
.vhost_backend_memslots_limit = vhost_user_memslots_limit,
|
||||||
.vhost_set_log_base = vhost_user_set_log_base,
|
.vhost_set_log_base = vhost_user_set_log_base,
|
||||||
.vhost_set_mem_table = vhost_user_set_mem_table,
|
.vhost_set_mem_table = vhost_user_set_mem_table,
|
||||||
@ -1650,4 +1793,5 @@ const VhostOps user_ops = {
|
|||||||
.vhost_set_config = vhost_user_set_config,
|
.vhost_set_config = vhost_user_set_config,
|
||||||
.vhost_crypto_create_session = vhost_user_crypto_create_session,
|
.vhost_crypto_create_session = vhost_user_crypto_create_session,
|
||||||
.vhost_crypto_close_session = vhost_user_crypto_close_session,
|
.vhost_crypto_close_session = vhost_user_crypto_close_session,
|
||||||
|
.vhost_backend_mem_section_filter = vhost_user_mem_section_filter,
|
||||||
};
|
};
|
||||||
|
@ -386,7 +386,7 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vhost_section(MemoryRegionSection *section)
|
static bool vhost_section(struct vhost_dev *dev, MemoryRegionSection *section)
|
||||||
{
|
{
|
||||||
bool result;
|
bool result;
|
||||||
bool log_dirty = memory_region_get_dirty_log_mask(section->mr) &
|
bool log_dirty = memory_region_get_dirty_log_mask(section->mr) &
|
||||||
@ -399,6 +399,11 @@ static bool vhost_section(MemoryRegionSection *section)
|
|||||||
*/
|
*/
|
||||||
result &= !log_dirty;
|
result &= !log_dirty;
|
||||||
|
|
||||||
|
if (result && dev->vhost_ops->vhost_backend_mem_section_filter) {
|
||||||
|
result &=
|
||||||
|
dev->vhost_ops->vhost_backend_mem_section_filter(dev, section);
|
||||||
|
}
|
||||||
|
|
||||||
trace_vhost_section(section->mr->name, result);
|
trace_vhost_section(section->mr->name, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -632,7 +637,7 @@ static void vhost_region_addnop(MemoryListener *listener,
|
|||||||
struct vhost_dev *dev = container_of(listener, struct vhost_dev,
|
struct vhost_dev *dev = container_of(listener, struct vhost_dev,
|
||||||
memory_listener);
|
memory_listener);
|
||||||
|
|
||||||
if (!vhost_section(section)) {
|
if (!vhost_section(dev, section)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vhost_region_add_section(dev, section);
|
vhost_region_add_section(dev, section);
|
||||||
|
@ -76,6 +76,7 @@ struct PCMachineState {
|
|||||||
#define PC_MACHINE_VMPORT "vmport"
|
#define PC_MACHINE_VMPORT "vmport"
|
||||||
#define PC_MACHINE_SMM "smm"
|
#define PC_MACHINE_SMM "smm"
|
||||||
#define PC_MACHINE_NVDIMM "nvdimm"
|
#define PC_MACHINE_NVDIMM "nvdimm"
|
||||||
|
#define PC_MACHINE_NVDIMM_CAP "nvdimm-cap"
|
||||||
#define PC_MACHINE_SMBUS "smbus"
|
#define PC_MACHINE_SMBUS "smbus"
|
||||||
#define PC_MACHINE_SATA "sata"
|
#define PC_MACHINE_SATA "sata"
|
||||||
#define PC_MACHINE_PIT "pit"
|
#define PC_MACHINE_PIT "pit"
|
||||||
|
@ -134,6 +134,11 @@ struct AcpiNVDIMMState {
|
|||||||
|
|
||||||
/* the IO region used by OSPM to transfer control to QEMU. */
|
/* the IO region used by OSPM to transfer control to QEMU. */
|
||||||
MemoryRegion io_mr;
|
MemoryRegion io_mr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Platform capabilities, section 5.2.25.9 of ACPI 6.2 Errata A
|
||||||
|
*/
|
||||||
|
int32_t capabilities;
|
||||||
};
|
};
|
||||||
typedef struct AcpiNVDIMMState AcpiNVDIMMState;
|
typedef struct AcpiNVDIMMState AcpiNVDIMMState;
|
||||||
|
|
||||||
|
@ -101,6 +101,9 @@ typedef int (*vhost_crypto_create_session_op)(struct vhost_dev *dev,
|
|||||||
typedef int (*vhost_crypto_close_session_op)(struct vhost_dev *dev,
|
typedef int (*vhost_crypto_close_session_op)(struct vhost_dev *dev,
|
||||||
uint64_t session_id);
|
uint64_t session_id);
|
||||||
|
|
||||||
|
typedef bool (*vhost_backend_mem_section_filter_op)(struct vhost_dev *dev,
|
||||||
|
MemoryRegionSection *section);
|
||||||
|
|
||||||
typedef struct VhostOps {
|
typedef struct VhostOps {
|
||||||
VhostBackendType backend_type;
|
VhostBackendType backend_type;
|
||||||
vhost_backend_init vhost_backend_init;
|
vhost_backend_init vhost_backend_init;
|
||||||
@ -138,6 +141,7 @@ typedef struct VhostOps {
|
|||||||
vhost_set_config_op vhost_set_config;
|
vhost_set_config_op vhost_set_config;
|
||||||
vhost_crypto_create_session_op vhost_crypto_create_session;
|
vhost_crypto_create_session_op vhost_crypto_create_session;
|
||||||
vhost_crypto_close_session_op vhost_crypto_close_session;
|
vhost_crypto_close_session_op vhost_crypto_close_session;
|
||||||
|
vhost_backend_mem_section_filter_op vhost_backend_mem_section_filter;
|
||||||
} VhostOps;
|
} VhostOps;
|
||||||
|
|
||||||
extern const VhostOps user_ops;
|
extern const VhostOps user_ops;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "hw/block/block.h"
|
#include "hw/block/block.h"
|
||||||
#include "chardev/char-fe.h"
|
#include "chardev/char-fe.h"
|
||||||
#include "hw/virtio/vhost.h"
|
#include "hw/virtio/vhost.h"
|
||||||
|
#include "hw/virtio/vhost-user.h"
|
||||||
|
|
||||||
#define TYPE_VHOST_USER_BLK "vhost-user-blk"
|
#define TYPE_VHOST_USER_BLK "vhost-user-blk"
|
||||||
#define VHOST_USER_BLK(obj) \
|
#define VHOST_USER_BLK(obj) \
|
||||||
@ -34,8 +35,8 @@ typedef struct VHostUserBlk {
|
|||||||
uint16_t num_queues;
|
uint16_t num_queues;
|
||||||
uint32_t queue_size;
|
uint32_t queue_size;
|
||||||
uint32_t config_wce;
|
uint32_t config_wce;
|
||||||
uint32_t config_ro;
|
|
||||||
struct vhost_dev dev;
|
struct vhost_dev dev;
|
||||||
|
VhostUserState *vhost_user;
|
||||||
} VHostUserBlk;
|
} VHostUserBlk;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "hw/qdev.h"
|
#include "hw/qdev.h"
|
||||||
#include "hw/virtio/virtio-scsi.h"
|
#include "hw/virtio/virtio-scsi.h"
|
||||||
#include "hw/virtio/vhost.h"
|
#include "hw/virtio/vhost.h"
|
||||||
|
#include "hw/virtio/vhost-user.h"
|
||||||
#include "hw/virtio/vhost-scsi-common.h"
|
#include "hw/virtio/vhost-scsi-common.h"
|
||||||
|
|
||||||
#define TYPE_VHOST_USER_SCSI "vhost-user-scsi"
|
#define TYPE_VHOST_USER_SCSI "vhost-user-scsi"
|
||||||
@ -30,6 +31,7 @@
|
|||||||
typedef struct VHostUserSCSI {
|
typedef struct VHostUserSCSI {
|
||||||
VHostSCSICommon parent_obj;
|
VHostSCSICommon parent_obj;
|
||||||
uint64_t host_features;
|
uint64_t host_features;
|
||||||
|
VhostUserState *vhost_user;
|
||||||
} VHostUserSCSI;
|
} VHostUserSCSI;
|
||||||
|
|
||||||
#endif /* VHOST_USER_SCSI_H */
|
#endif /* VHOST_USER_SCSI_H */
|
||||||
|
28
include/hw/virtio/vhost-user.h
Normal file
28
include/hw/virtio/vhost-user.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2.
|
||||||
|
* See the COPYING file in the top-level directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HW_VIRTIO_VHOST_USER_H
|
||||||
|
#define HW_VIRTIO_VHOST_USER_H
|
||||||
|
|
||||||
|
#include "chardev/char-fe.h"
|
||||||
|
#include "hw/virtio/virtio.h"
|
||||||
|
|
||||||
|
typedef struct VhostUserHostNotifier {
|
||||||
|
MemoryRegion mr;
|
||||||
|
void *addr;
|
||||||
|
bool set;
|
||||||
|
} VhostUserHostNotifier;
|
||||||
|
|
||||||
|
typedef struct VhostUserState {
|
||||||
|
CharBackend *chr;
|
||||||
|
VhostUserHostNotifier notifier[VIRTIO_QUEUE_MAX];
|
||||||
|
} VhostUserState;
|
||||||
|
|
||||||
|
VhostUserState *vhost_user_init(void);
|
||||||
|
void vhost_user_cleanup(VhostUserState *user);
|
||||||
|
|
||||||
|
#endif
|
@ -27,7 +27,7 @@
|
|||||||
#ifndef QEMU_VMSTATE_H
|
#ifndef QEMU_VMSTATE_H
|
||||||
#define QEMU_VMSTATE_H
|
#define QEMU_VMSTATE_H
|
||||||
|
|
||||||
#include "migration/qjson.h"
|
typedef struct QJSON QJSON;
|
||||||
|
|
||||||
typedef struct VMStateInfo VMStateInfo;
|
typedef struct VMStateInfo VMStateInfo;
|
||||||
typedef struct VMStateDescription VMStateDescription;
|
typedef struct VMStateDescription VMStateDescription;
|
||||||
|
@ -107,6 +107,16 @@ extern int daemon(int, int);
|
|||||||
#include "glib-compat.h"
|
#include "glib-compat.h"
|
||||||
#include "qemu/typedefs.h"
|
#include "qemu/typedefs.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* According to waitpid man page:
|
||||||
|
* WCOREDUMP
|
||||||
|
* This macro is not specified in POSIX.1-2001 and is not
|
||||||
|
* available on some UNIX implementations (e.g., AIX, SunOS).
|
||||||
|
* Therefore, enclose its use inside #ifdef WCOREDUMP ... #endif.
|
||||||
|
*/
|
||||||
|
#ifndef WCOREDUMP
|
||||||
|
#define WCOREDUMP(status) 0
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* We have a lot of unaudited code that may fail in strange ways, or
|
* We have a lot of unaudited code that may fail in strange ways, or
|
||||||
* even be a security risk during migration, if you disable assertions
|
* even be a security risk during migration, if you disable assertions
|
||||||
|
@ -66,7 +66,7 @@
|
|||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "migration/misc.h"
|
#include "migration/misc.h"
|
||||||
#include "migration/migration.h"
|
#include "migration/migration.h"
|
||||||
#include "migration/qemu-file.h"
|
#include "qemu-file.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "migration/register.h"
|
#include "migration/register.h"
|
||||||
#include "qemu/hbitmap.h"
|
#include "qemu/hbitmap.h"
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu/host-utils.h"
|
#include "qemu/host-utils.h"
|
||||||
#include "migration/page_cache.h"
|
#include "page_cache.h"
|
||||||
|
|
||||||
#ifdef DEBUG_CACHE
|
#ifdef DEBUG_CACHE
|
||||||
#define DPRINTF(fmt, ...) \
|
#define DPRINTF(fmt, ...) \
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#include "migration/misc.h"
|
#include "migration/misc.h"
|
||||||
#include "qemu-file.h"
|
#include "qemu-file.h"
|
||||||
#include "postcopy-ram.h"
|
#include "postcopy-ram.h"
|
||||||
#include "migration/page_cache.h"
|
#include "page_cache.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qapi-events-migration.h"
|
#include "qapi/qapi-events-migration.h"
|
||||||
@ -51,7 +51,7 @@
|
|||||||
#include "exec/target_page.h"
|
#include "exec/target_page.h"
|
||||||
#include "qemu/rcu_queue.h"
|
#include "qemu/rcu_queue.h"
|
||||||
#include "migration/colo.h"
|
#include "migration/colo.h"
|
||||||
#include "migration/block.h"
|
#include "block.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "qemu/uuid.h"
|
#include "qemu/uuid.h"
|
||||||
#include "savevm.h"
|
#include "savevm.h"
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include "io/channel-buffer.h"
|
#include "io/channel-buffer.h"
|
||||||
#include "io/channel-file.h"
|
#include "io/channel-file.h"
|
||||||
#include "sysemu/replay.h"
|
#include "sysemu/replay.h"
|
||||||
|
#include "qjson.h"
|
||||||
|
|
||||||
#ifndef ETH_P_RARP
|
#ifndef ETH_P_RARP
|
||||||
#define ETH_P_RARP 0x8035
|
#define ETH_P_RARP 0x8035
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "migration.h"
|
#include "migration.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "migration/savevm.h"
|
#include "savevm.h"
|
||||||
#include "qemu-file.h"
|
#include "qemu-file.h"
|
||||||
#include "qemu/bitops.h"
|
#include "qemu/bitops.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "net/queue.h"
|
#include "net/queue.h"
|
||||||
#include "chardev/char-fe.h"
|
#include "chardev/char-fe.h"
|
||||||
#include "qemu/sockets.h"
|
#include "qemu/sockets.h"
|
||||||
#include "net/colo.h"
|
#include "colo.h"
|
||||||
#include "sysemu/iothread.h"
|
#include "sysemu/iothread.h"
|
||||||
|
|
||||||
#define TYPE_COLO_COMPARE "colo-compare"
|
#define TYPE_COLO_COMPARE "colo-compare"
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "net/colo.h"
|
#include "colo.h"
|
||||||
|
|
||||||
uint32_t connection_key_hash(const void *opaque)
|
uint32_t connection_key_hash(const void *opaque)
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "net/colo.h"
|
#include "colo.h"
|
||||||
#include "net/filter.h"
|
#include "net/filter.h"
|
||||||
#include "net/net.h"
|
#include "net/net.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "clients.h"
|
#include "clients.h"
|
||||||
#include "net/vhost_net.h"
|
#include "net/vhost_net.h"
|
||||||
#include "net/vhost-user.h"
|
#include "net/vhost-user.h"
|
||||||
|
#include "hw/virtio/vhost-user.h"
|
||||||
#include "chardev/char-fe.h"
|
#include "chardev/char-fe.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qapi-commands-net.h"
|
#include "qapi/qapi-commands-net.h"
|
||||||
@ -23,6 +24,7 @@
|
|||||||
typedef struct NetVhostUserState {
|
typedef struct NetVhostUserState {
|
||||||
NetClientState nc;
|
NetClientState nc;
|
||||||
CharBackend chr; /* only queue index 0 */
|
CharBackend chr; /* only queue index 0 */
|
||||||
|
VhostUserState *vhost_user;
|
||||||
VHostNetState *vhost_net;
|
VHostNetState *vhost_net;
|
||||||
guint watch;
|
guint watch;
|
||||||
uint64_t acked_features;
|
uint64_t acked_features;
|
||||||
@ -64,7 +66,8 @@ static void vhost_user_stop(int queues, NetClientState *ncs[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vhost_user_start(int queues, NetClientState *ncs[], CharBackend *be)
|
static int vhost_user_start(int queues, NetClientState *ncs[],
|
||||||
|
VhostUserState *be)
|
||||||
{
|
{
|
||||||
VhostNetOptions options;
|
VhostNetOptions options;
|
||||||
struct vhost_net *net = NULL;
|
struct vhost_net *net = NULL;
|
||||||
@ -144,7 +147,7 @@ static ssize_t vhost_user_receive(NetClientState *nc, const uint8_t *buf,
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vhost_user_cleanup(NetClientState *nc)
|
static void net_vhost_user_cleanup(NetClientState *nc)
|
||||||
{
|
{
|
||||||
NetVhostUserState *s = DO_UPCAST(NetVhostUserState, nc, nc);
|
NetVhostUserState *s = DO_UPCAST(NetVhostUserState, nc, nc);
|
||||||
|
|
||||||
@ -159,6 +162,11 @@ static void vhost_user_cleanup(NetClientState *nc)
|
|||||||
s->watch = 0;
|
s->watch = 0;
|
||||||
}
|
}
|
||||||
qemu_chr_fe_deinit(&s->chr, true);
|
qemu_chr_fe_deinit(&s->chr, true);
|
||||||
|
if (s->vhost_user) {
|
||||||
|
vhost_user_cleanup(s->vhost_user);
|
||||||
|
g_free(s->vhost_user);
|
||||||
|
s->vhost_user = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_purge_queued_packets(nc);
|
qemu_purge_queued_packets(nc);
|
||||||
@ -182,7 +190,7 @@ static NetClientInfo net_vhost_user_info = {
|
|||||||
.type = NET_CLIENT_DRIVER_VHOST_USER,
|
.type = NET_CLIENT_DRIVER_VHOST_USER,
|
||||||
.size = sizeof(NetVhostUserState),
|
.size = sizeof(NetVhostUserState),
|
||||||
.receive = vhost_user_receive,
|
.receive = vhost_user_receive,
|
||||||
.cleanup = vhost_user_cleanup,
|
.cleanup = net_vhost_user_cleanup,
|
||||||
.has_vnet_hdr = vhost_user_has_vnet_hdr,
|
.has_vnet_hdr = vhost_user_has_vnet_hdr,
|
||||||
.has_ufo = vhost_user_has_ufo,
|
.has_ufo = vhost_user_has_ufo,
|
||||||
};
|
};
|
||||||
@ -244,7 +252,7 @@ static void net_vhost_user_event(void *opaque, int event)
|
|||||||
trace_vhost_user_event(chr->label, event);
|
trace_vhost_user_event(chr->label, event);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case CHR_EVENT_OPENED:
|
case CHR_EVENT_OPENED:
|
||||||
if (vhost_user_start(queues, ncs, &s->chr) < 0) {
|
if (vhost_user_start(queues, ncs, s->vhost_user) < 0) {
|
||||||
qemu_chr_fe_disconnect(&s->chr);
|
qemu_chr_fe_disconnect(&s->chr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -283,12 +291,19 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
|
|||||||
{
|
{
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
NetClientState *nc, *nc0 = NULL;
|
NetClientState *nc, *nc0 = NULL;
|
||||||
NetVhostUserState *s;
|
VhostUserState *user = NULL;
|
||||||
|
NetVhostUserState *s = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert(name);
|
assert(name);
|
||||||
assert(queues > 0);
|
assert(queues > 0);
|
||||||
|
|
||||||
|
user = vhost_user_init();
|
||||||
|
if (!user) {
|
||||||
|
error_report("failed to init vhost_user");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < queues; i++) {
|
for (i = 0; i < queues; i++) {
|
||||||
nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
|
nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
|
||||||
snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
|
snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
|
||||||
@ -299,17 +314,19 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
|
|||||||
s = DO_UPCAST(NetVhostUserState, nc, nc);
|
s = DO_UPCAST(NetVhostUserState, nc, nc);
|
||||||
if (!qemu_chr_fe_init(&s->chr, chr, &err)) {
|
if (!qemu_chr_fe_init(&s->chr, chr, &err)) {
|
||||||
error_report_err(err);
|
error_report_err(err);
|
||||||
return -1;
|
goto err;
|
||||||
}
|
}
|
||||||
|
user->chr = &s->chr;
|
||||||
}
|
}
|
||||||
|
s = DO_UPCAST(NetVhostUserState, nc, nc);
|
||||||
|
s->vhost_user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = DO_UPCAST(NetVhostUserState, nc, nc0);
|
s = DO_UPCAST(NetVhostUserState, nc, nc0);
|
||||||
do {
|
do {
|
||||||
if (qemu_chr_fe_wait_connected(&s->chr, &err) < 0) {
|
if (qemu_chr_fe_wait_connected(&s->chr, &err) < 0) {
|
||||||
error_report_err(err);
|
error_report_err(err);
|
||||||
return -1;
|
goto err;
|
||||||
}
|
}
|
||||||
qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
|
qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
|
||||||
net_vhost_user_event, NULL, nc0->name, NULL,
|
net_vhost_user_event, NULL, nc0->name, NULL,
|
||||||
@ -319,6 +336,17 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
|
|||||||
assert(s->vhost_net);
|
assert(s->vhost_net);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (user) {
|
||||||
|
vhost_user_cleanup(user);
|
||||||
|
g_free(user);
|
||||||
|
if (s) {
|
||||||
|
s->vhost_user = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Chardev *net_vhost_claim_chardev(
|
static Chardev *net_vhost_claim_chardev(
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/sockets.h"
|
#include "qemu/sockets.h"
|
||||||
#include "qga/channel.h"
|
#include "channel.h"
|
||||||
|
|
||||||
#ifdef CONFIG_SOLARIS
|
#ifdef CONFIG_SOLARIS
|
||||||
#include <stropts.h>
|
#include <stropts.h>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include "qga/guest-agent-core.h"
|
#include "guest-agent-core.h"
|
||||||
#include "qga/channel.h"
|
#include "channel.h"
|
||||||
|
|
||||||
typedef struct GAChannelReadState {
|
typedef struct GAChannelReadState {
|
||||||
guint thread_id;
|
guint thread_id;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include "qga/guest-agent-core.h"
|
#include "guest-agent-core.h"
|
||||||
#include "qga-qapi-commands.h"
|
#include "qga-qapi-commands.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
#include <wtsapi32.h>
|
#include <wtsapi32.h>
|
||||||
#include <wininet.h>
|
#include <wininet.h>
|
||||||
|
|
||||||
#include "qga/guest-agent-core.h"
|
#include "guest-agent-core.h"
|
||||||
#include "qga/vss-win32.h"
|
#include "vss-win32.h"
|
||||||
#include "qga-qapi-commands.h"
|
#include "qga-qapi-commands.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qga/guest-agent-core.h"
|
#include "guest-agent-core.h"
|
||||||
#include "qga-qapi-commands.h"
|
#include "qga-qapi-commands.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* See the COPYING file in the top-level directory.
|
* See the COPYING file in the top-level directory.
|
||||||
*/
|
*/
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qga/guest-agent-core.h"
|
#include "guest-agent-core.h"
|
||||||
|
|
||||||
struct GACommandState {
|
struct GACommandState {
|
||||||
GSList *groups;
|
GSList *groups;
|
||||||
|
@ -23,12 +23,12 @@
|
|||||||
#include "qapi/qmp/qdict.h"
|
#include "qapi/qmp/qdict.h"
|
||||||
#include "qapi/qmp/qjson.h"
|
#include "qapi/qmp/qjson.h"
|
||||||
#include "qapi/qmp/qstring.h"
|
#include "qapi/qmp/qstring.h"
|
||||||
#include "qga/guest-agent-core.h"
|
#include "guest-agent-core.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qga-qapi-commands.h"
|
#include "qga-qapi-commands.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qga/channel.h"
|
#include "channel.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "qemu/help_option.h"
|
#include "qemu/help_option.h"
|
||||||
#include "qemu/sockets.h"
|
#include "qemu/sockets.h"
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qga/guest-agent-core.h"
|
#include "guest-agent-core.h"
|
||||||
#include "qga/vss-win32.h"
|
#include "vss-win32.h"
|
||||||
#include "qga/vss-win32/requester.h"
|
#include "vss-win32/requester.h"
|
||||||
|
|
||||||
#define QGA_VSS_DLL "qga-vss.dll"
|
#define QGA_VSS_DLL "qga-vss.dll"
|
||||||
|
|
||||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -21,6 +21,7 @@ test-base64
|
|||||||
test-bdrv-drain
|
test-bdrv-drain
|
||||||
test-bitops
|
test-bitops
|
||||||
test-bitcnt
|
test-bitcnt
|
||||||
|
test-block-backend
|
||||||
test-blockjob
|
test-blockjob
|
||||||
test-blockjob-txn
|
test-blockjob-txn
|
||||||
test-bufferiszero
|
test-bufferiszero
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -830,7 +830,7 @@ static void test_acpi_tcg_dimm_pxm(const char *machine)
|
|||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.machine = machine;
|
data.machine = machine;
|
||||||
data.variant = ".dimmpxm";
|
data.variant = ".dimmpxm";
|
||||||
test_acpi_one(" -machine nvdimm=on"
|
test_acpi_one(" -machine nvdimm=on,nvdimm-cap=3"
|
||||||
" -smp 4,sockets=4"
|
" -smp 4,sockets=4"
|
||||||
" -m 128M,slots=3,maxmem=1G"
|
" -m 128M,slots=3,maxmem=1G"
|
||||||
" -numa node,mem=32M,nodeid=0"
|
" -numa node,mem=32M,nodeid=0"
|
||||||
|
@ -103,8 +103,15 @@ static int socket_accept(int sock)
|
|||||||
static void kill_qemu(QTestState *s)
|
static void kill_qemu(QTestState *s)
|
||||||
{
|
{
|
||||||
if (s->qemu_pid != -1) {
|
if (s->qemu_pid != -1) {
|
||||||
|
int wstatus = 0;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
kill(s->qemu_pid, SIGTERM);
|
kill(s->qemu_pid, SIGTERM);
|
||||||
waitpid(s->qemu_pid, NULL, 0);
|
pid = waitpid(s->qemu_pid, &wstatus, 0);
|
||||||
|
|
||||||
|
if (pid == s->qemu_pid && WIFSIGNALED(wstatus)) {
|
||||||
|
assert(!WCOREDUMP(wstatus));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
|
#include "qemu/atomic.h"
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/iov.h"
|
#include "qemu/iov.h"
|
||||||
#include "standard-headers/linux/virtio_net.h"
|
#include "standard-headers/linux/virtio_net.h"
|
||||||
@ -65,6 +66,11 @@ typedef struct VubrDev {
|
|||||||
int sock;
|
int sock;
|
||||||
int ready;
|
int ready;
|
||||||
int quit;
|
int quit;
|
||||||
|
struct {
|
||||||
|
int fd;
|
||||||
|
void *addr;
|
||||||
|
pthread_t thread;
|
||||||
|
} notifier;
|
||||||
} VubrDev;
|
} VubrDev;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -445,14 +451,22 @@ static uint64_t
|
|||||||
vubr_get_features(VuDev *dev)
|
vubr_get_features(VuDev *dev)
|
||||||
{
|
{
|
||||||
return 1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE |
|
return 1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE |
|
||||||
1ULL << VIRTIO_NET_F_MRG_RXBUF;
|
1ULL << VIRTIO_NET_F_MRG_RXBUF |
|
||||||
|
1ULL << VIRTIO_F_VERSION_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vubr_queue_set_started(VuDev *dev, int qidx, bool started)
|
vubr_queue_set_started(VuDev *dev, int qidx, bool started)
|
||||||
{
|
{
|
||||||
|
VubrDev *vubr = container_of(dev, VubrDev, vudev);
|
||||||
VuVirtq *vq = vu_get_queue(dev, qidx);
|
VuVirtq *vq = vu_get_queue(dev, qidx);
|
||||||
|
|
||||||
|
if (started && vubr->notifier.fd >= 0) {
|
||||||
|
vu_set_queue_host_notifier(dev, vq, vubr->notifier.fd,
|
||||||
|
getpagesize(),
|
||||||
|
qidx * getpagesize());
|
||||||
|
}
|
||||||
|
|
||||||
if (qidx % 2 == 1) {
|
if (qidx % 2 == 1) {
|
||||||
vu_set_queue_handler(dev, vq, started ? vubr_handle_tx : NULL);
|
vu_set_queue_handler(dev, vq, started ? vubr_handle_tx : NULL);
|
||||||
}
|
}
|
||||||
@ -522,6 +536,8 @@ vubr_new(const char *path, bool client)
|
|||||||
vubr_die("socket");
|
vubr_die("socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev->notifier.fd = -1;
|
||||||
|
|
||||||
un.sun_family = AF_UNIX;
|
un.sun_family = AF_UNIX;
|
||||||
strcpy(un.sun_path, path);
|
strcpy(un.sun_path, path);
|
||||||
len = sizeof(un.sun_family) + strlen(path);
|
len = sizeof(un.sun_family) + strlen(path);
|
||||||
@ -559,6 +575,73 @@ vubr_new(const char *path, bool client)
|
|||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *notifier_thread(void *arg)
|
||||||
|
{
|
||||||
|
VuDev *dev = (VuDev *)arg;
|
||||||
|
VubrDev *vubr = container_of(dev, VubrDev, vudev);
|
||||||
|
int pagesize = getpagesize();
|
||||||
|
int qidx;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
for (qidx = 0; qidx < VHOST_MAX_NR_VIRTQUEUE; qidx++) {
|
||||||
|
uint16_t *n = vubr->notifier.addr + pagesize * qidx;
|
||||||
|
|
||||||
|
if (*n == qidx) {
|
||||||
|
*n = 0xffff;
|
||||||
|
/* We won't miss notifications if we reset
|
||||||
|
* the memory first. */
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
DPRINT("Got a notification for queue%d via host notifier.\n",
|
||||||
|
qidx);
|
||||||
|
|
||||||
|
if (qidx % 2 == 1) {
|
||||||
|
vubr_handle_tx(dev, qidx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vubr_host_notifier_setup(VubrDev *dev)
|
||||||
|
{
|
||||||
|
char template[] = "/tmp/vubr-XXXXXX";
|
||||||
|
pthread_t thread;
|
||||||
|
size_t length;
|
||||||
|
void *addr;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
length = getpagesize() * VHOST_MAX_NR_VIRTQUEUE;
|
||||||
|
|
||||||
|
fd = mkstemp(template);
|
||||||
|
if (fd < 0) {
|
||||||
|
vubr_die("mkstemp()");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (posix_fallocate(fd, 0, length) != 0) {
|
||||||
|
vubr_die("posix_fallocate()");
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (addr == MAP_FAILED) {
|
||||||
|
vubr_die("mmap()");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(addr, 0xff, length);
|
||||||
|
|
||||||
|
if (pthread_create(&thread, NULL, notifier_thread, &dev->vudev) != 0) {
|
||||||
|
vubr_die("pthread_create()");
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->notifier.fd = fd;
|
||||||
|
dev->notifier.addr = addr;
|
||||||
|
dev->notifier.thread = thread;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vubr_set_host(struct sockaddr_in *saddr, const char *host)
|
vubr_set_host(struct sockaddr_in *saddr, const char *host)
|
||||||
{
|
{
|
||||||
@ -673,8 +756,9 @@ main(int argc, char *argv[])
|
|||||||
VubrDev *dev;
|
VubrDev *dev;
|
||||||
int opt;
|
int opt;
|
||||||
bool client = false;
|
bool client = false;
|
||||||
|
bool host_notifier = false;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "l:r:u:c")) != -1) {
|
while ((opt = getopt(argc, argv, "l:r:u:cH")) != -1) {
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'l':
|
case 'l':
|
||||||
@ -693,6 +777,9 @@ main(int argc, char *argv[])
|
|||||||
case 'c':
|
case 'c':
|
||||||
client = true;
|
client = true;
|
||||||
break;
|
break;
|
||||||
|
case 'H':
|
||||||
|
host_notifier = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -708,6 +795,10 @@ main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (host_notifier) {
|
||||||
|
vubr_host_notifier_setup(dev);
|
||||||
|
}
|
||||||
|
|
||||||
vubr_backend_udp_setup(dev, lhost, lport, rhost, rport);
|
vubr_backend_udp_setup(dev, lhost, lport, rhost, rport);
|
||||||
vubr_run(dev);
|
vubr_run(dev);
|
||||||
|
|
||||||
@ -717,7 +808,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
fprintf(stderr, "Usage: %s ", argv[0]);
|
fprintf(stderr, "Usage: %s ", argv[0]);
|
||||||
fprintf(stderr, "[-c] [-u ud_socket_path] [-l lhost:lport] [-r rhost:rport]\n");
|
fprintf(stderr, "[-c] [-H] [-u ud_socket_path] [-l lhost:lport] [-r rhost:rport]\n");
|
||||||
fprintf(stderr, "\t-u path to unix doman socket. default: %s\n",
|
fprintf(stderr, "\t-u path to unix doman socket. default: %s\n",
|
||||||
DEFAULT_UD_SOCKET);
|
DEFAULT_UD_SOCKET);
|
||||||
fprintf(stderr, "\t-l local host and port. default: %s:%s\n",
|
fprintf(stderr, "\t-l local host and port. default: %s:%s\n",
|
||||||
@ -725,6 +816,7 @@ out:
|
|||||||
fprintf(stderr, "\t-r remote host and port. default: %s:%s\n",
|
fprintf(stderr, "\t-r remote host and port. default: %s:%s\n",
|
||||||
DEFAULT_RHOST, DEFAULT_RPORT);
|
DEFAULT_RHOST, DEFAULT_RPORT);
|
||||||
fprintf(stderr, "\t-c client mode\n");
|
fprintf(stderr, "\t-c client mode\n");
|
||||||
|
fprintf(stderr, "\t-H use host notifier\n");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +267,6 @@ char *trace_opt_parse(const char *optarg);
|
|||||||
uint32_t trace_get_vcpu_event_count(void);
|
uint32_t trace_get_vcpu_event_count(void);
|
||||||
|
|
||||||
|
|
||||||
#include "trace/control-internal.h"
|
#include "control-internal.h"
|
||||||
|
|
||||||
#endif /* TRACE__CONTROL_H */
|
#endif /* TRACE__CONTROL_H */
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qapi-commands-trace.h"
|
#include "qapi/qapi-commands-trace.h"
|
||||||
#include "trace/control.h"
|
#include "control.h"
|
||||||
|
|
||||||
|
|
||||||
static CPUState *get_cpu(bool has_vcpu, int vcpu, Error **errp)
|
static CPUState *get_cpu(bool has_vcpu, int vcpu, Error **errp)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user