mirror of https://github.com/xemu-project/xemu.git
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
|
||||
#elif defined(TARGET_CRIS)
|
||||
#define QEMU_ARCH QEMU_ARCH_CRIS
|
||||
#elif defined(TARGET_I386)
|
||||
#define QEMU_ARCH QEMU_ARCH_I386
|
||||
#elif defined(TARGET_HPPA)
|
||||
#define QEMU_ARCH QEMU_ARCH_HPPA
|
||||
#elif defined(TARGET_M68K)
|
||||
#define QEMU_ARCH QEMU_ARCH_M68K
|
||||
#elif defined(TARGET_I386)
|
||||
#define QEMU_ARCH QEMU_ARCH_I386
|
||||
#elif defined(TARGET_LM32)
|
||||
#define QEMU_ARCH QEMU_ARCH_LM32
|
||||
#elif defined(TARGET_M68K)
|
||||
#define QEMU_ARCH QEMU_ARCH_M68K
|
||||
#elif defined(TARGET_MICROBLAZE)
|
||||
#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
|
||||
#elif defined(TARGET_MIPS)
|
||||
|
@ -80,12 +80,12 @@ int graphic_depth = 32;
|
|||
#define QEMU_ARCH QEMU_ARCH_SH4
|
||||
#elif defined(TARGET_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)
|
||||
#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
|
||||
|
||||
const uint32_t arch_type = QEMU_ARCH;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/virtio/vhost-user.h"
|
||||
#include "standard-headers/linux/virtio_crypto.h"
|
||||
#include "sysemu/cryptodev-vhost.h"
|
||||
#include "chardev/char-fe.h"
|
||||
|
@ -46,6 +47,7 @@
|
|||
typedef struct CryptoDevBackendVhostUser {
|
||||
CryptoDevBackend parent_obj;
|
||||
|
||||
VhostUserState *vhost_user;
|
||||
CharBackend chr;
|
||||
char *chr_name;
|
||||
bool opened;
|
||||
|
@ -102,7 +104,7 @@ cryptodev_vhost_user_start(int queues,
|
|||
continue;
|
||||
}
|
||||
|
||||
options.opaque = &s->chr;
|
||||
options.opaque = s->vhost_user;
|
||||
options.backend_type = VHOST_BACKEND_TYPE_USER;
|
||||
options.cc = b->conf.peers.ccs[i];
|
||||
s->vhost_crypto[i] = cryptodev_vhost_init(&options);
|
||||
|
@ -185,6 +187,7 @@ static void cryptodev_vhost_user_init(
|
|||
size_t i;
|
||||
Error *local_err = NULL;
|
||||
Chardev *chr;
|
||||
VhostUserState *user;
|
||||
CryptoDevBackendClient *cc;
|
||||
CryptoDevBackendVhostUser *s =
|
||||
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,
|
||||
cryptodev_vhost_user_event, NULL, s, NULL, true);
|
||||
|
||||
|
@ -299,6 +311,12 @@ static void cryptodev_vhost_user_cleanup(
|
|||
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,
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "qapi/qobject-input-visitor.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/option.h"
|
||||
#include "block/crypto.h"
|
||||
#include "crypto.h"
|
||||
|
||||
typedef struct BlockCrypto BlockCrypto;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/nbd-client.h"
|
||||
#include "nbd-client.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/uri.h"
|
||||
#include "block/block_int.h"
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "qapi/qapi-visit-block-core.h"
|
||||
#include "crypto/block.h"
|
||||
#include "migration/blocker.h"
|
||||
#include "block/crypto.h"
|
||||
#include "crypto.h"
|
||||
|
||||
/**************************************************************/
|
||||
/* QEMU COW block driver with compression and encryption support */
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "qemu/cutils.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
|
||||
* _internal_ constants. Please do not use this _internal_ abbreviation for
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qcow2.h"
|
||||
#include "qcow2.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "trace.h"
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qcow2.h"
|
||||
#include "qcow2.h"
|
||||
#include "qemu/range.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qcow2.h"
|
||||
#include "qcow2.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "sysemu/block-backend.h"
|
||||
#include "qemu/module.h"
|
||||
#include <zlib.h>
|
||||
#include "block/qcow2.h"
|
||||
#include "qcow2.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-events-block-core.h"
|
||||
|
@ -39,7 +39,7 @@
|
|||
#include "qemu/bswap.h"
|
||||
#include "qapi/qobject-input-visitor.h"
|
||||
#include "qapi/qapi-visit-block-core.h"
|
||||
#include "block/crypto.h"
|
||||
#include "crypto.h"
|
||||
|
||||
/*
|
||||
Differences with QCOW:
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "qemu-common.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "block/vhdx.h"
|
||||
#include "vhdx.h"
|
||||
|
||||
/*
|
||||
* All the VHDX formats on disk are little endian - the following
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "block/vhdx.h"
|
||||
#include "vhdx.h"
|
||||
|
||||
|
||||
typedef struct VHDXLogSequence {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "qemu/option.h"
|
||||
#include "qemu/crc32c.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "block/vhdx.h"
|
||||
#include "vhdx.h"
|
||||
#include "migration/blocker.h"
|
||||
#include "qemu/uuid.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
|
|
|
@ -314,11 +314,6 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
|
|||
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 {
|
||||
rc = sendmsg(conn_fd, &msg, 0);
|
||||
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
|
@ -341,6 +336,39 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
|
|||
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. */
|
||||
static void
|
||||
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 */
|
||||
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");
|
||||
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
|
||||
vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg)
|
||||
{
|
||||
|
@ -968,7 +1031,9 @@ static bool
|
|||
vu_get_protocol_features_exec(VuDev *dev, VhostUserMsg *vmsg)
|
||||
{
|
||||
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()) {
|
||||
features |= 1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT;
|
||||
|
@ -1252,7 +1317,7 @@ vu_dispatch(VuDev *dev)
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (!vu_message_write(dev, dev->sock, &vmsg)) {
|
||||
if (!vu_send_reply(dev, dev->sock, &vmsg)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ enum VhostUserProtocolFeature {
|
|||
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
||||
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
||||
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
|
||||
};
|
||||
|
@ -92,6 +94,14 @@ typedef enum VhostUserRequest {
|
|||
VHOST_USER_MAX
|
||||
} 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 {
|
||||
uint64_t guest_phys_addr;
|
||||
uint64_t memory_size;
|
||||
|
@ -122,6 +132,12 @@ static VhostUserConfig c __attribute__ ((unused));
|
|||
+ sizeof(c.size) \
|
||||
+ sizeof(c.flags))
|
||||
|
||||
typedef struct VhostUserVringArea {
|
||||
uint64_t u64;
|
||||
uint64_t size;
|
||||
uint64_t offset;
|
||||
} VhostUserVringArea;
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define VU_PACKED __attribute__((gcc_struct, packed))
|
||||
#else
|
||||
|
@ -133,6 +149,7 @@ typedef struct VhostUserMsg {
|
|||
|
||||
#define VHOST_USER_VERSION_MASK (0x3)
|
||||
#define VHOST_USER_REPLY_MASK (0x1 << 2)
|
||||
#define VHOST_USER_NEED_REPLY_MASK (0x1 << 3)
|
||||
uint32_t flags;
|
||||
uint32_t size; /* the following payload size */
|
||||
|
||||
|
@ -145,6 +162,7 @@ typedef struct VhostUserMsg {
|
|||
VhostUserMemory memory;
|
||||
VhostUserLog log;
|
||||
VhostUserConfig config;
|
||||
VhostUserVringArea area;
|
||||
} payload;
|
||||
|
||||
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,
|
||||
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:
|
||||
|
|
|
@ -31,6 +31,7 @@ typedef struct VubDev {
|
|||
VugDev parent;
|
||||
int blk_fd;
|
||||
struct virtio_blk_config blkcfg;
|
||||
bool enable_ro;
|
||||
char *blk_name;
|
||||
GMainLoop *loop;
|
||||
} VubDev;
|
||||
|
@ -301,14 +302,27 @@ static void vub_queue_set_started(VuDev *vu_dev, int idx, bool started)
|
|||
static uint64_t
|
||||
vub_get_features(VuDev *dev)
|
||||
{
|
||||
return 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;
|
||||
uint64_t features;
|
||||
VugDev *gdev;
|
||||
VubDev *vdev_blk;
|
||||
|
||||
gdev = container_of(dev, VugDev, parent);
|
||||
vdev_blk = container_of(gdev, VubDev, parent);
|
||||
|
||||
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
|
||||
|
@ -476,6 +490,7 @@ vub_new(char *blk_file)
|
|||
vub_free(vdev_blk);
|
||||
return NULL;
|
||||
}
|
||||
vdev_blk->enable_ro = false;
|
||||
vdev_blk->blkcfg.wce = 0;
|
||||
vdev_blk->blk_name = blk_file;
|
||||
|
||||
|
@ -490,10 +505,11 @@ int main(int argc, char **argv)
|
|||
int opt;
|
||||
char *unix_socket = NULL;
|
||||
char *blk_file = NULL;
|
||||
bool enable_ro = false;
|
||||
int lsock = -1, csock = -1;
|
||||
VubDev *vdev_blk = NULL;
|
||||
|
||||
while ((opt = getopt(argc, argv, "b:s:h")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "b:rs:h")) != -1) {
|
||||
switch (opt) {
|
||||
case 'b':
|
||||
blk_file = g_strdup(optarg);
|
||||
|
@ -501,17 +517,20 @@ int main(int argc, char **argv)
|
|||
case 's':
|
||||
unix_socket = g_strdup(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
enable_ro = true;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
printf("Usage: %s [-b block device or file, -s UNIX domain socket]"
|
||||
" | [ -h ]\n", argv[0]);
|
||||
printf("Usage: %s [ -b block device or file, -s UNIX domain socket"
|
||||
" | -r Enable read-only ] | [ -h ]\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!unix_socket || !blk_file) {
|
||||
printf("Usage: %s [-b block device or file, -s UNIX domain socket] |"
|
||||
" [ -h ]\n", argv[0]);
|
||||
printf("Usage: %s [ -b block device or file, -s UNIX domain socket"
|
||||
" | -r Enable read-only ] | [ -h ]\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -530,6 +549,9 @@ int main(int argc, char **argv)
|
|||
if (!vdev_blk) {
|
||||
goto err;
|
||||
}
|
||||
if (enable_ro) {
|
||||
vdev_blk->enable_ro = true;
|
||||
}
|
||||
|
||||
vug_init(&vdev_blk->parent, csock, vub_panic_cb, &vub_iface);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "qapi/error.h"
|
||||
#include "qemu/bswap.h"
|
||||
|
||||
#include "crypto/block-luks.h"
|
||||
#include "block-luks.h"
|
||||
|
||||
#include "crypto/hash.h"
|
||||
#include "crypto/afsplit.h"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef QCRYPTO_BLOCK_LUKS_H
|
||||
#define QCRYPTO_BLOCK_LUKS_H
|
||||
|
||||
#include "crypto/blockpriv.h"
|
||||
#include "blockpriv.h"
|
||||
|
||||
extern const QCryptoBlockDriver qcrypto_block_driver_luks;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
#include "crypto/block-qcow.h"
|
||||
#include "block-qcow.h"
|
||||
#include "crypto/secret.h"
|
||||
|
||||
#define QCRYPTO_BLOCK_QCOW_SECTOR_SIZE 512
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef QCRYPTO_BLOCK_QCOW_H
|
||||
#define QCRYPTO_BLOCK_QCOW_H
|
||||
|
||||
#include "crypto/blockpriv.h"
|
||||
#include "blockpriv.h"
|
||||
|
||||
extern const QCryptoBlockDriver qcrypto_block_driver_qcow;
|
||||
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "crypto/blockpriv.h"
|
||||
#include "crypto/block-qcow.h"
|
||||
#include "crypto/block-luks.h"
|
||||
#include "blockpriv.h"
|
||||
#include "block-qcow.h"
|
||||
#include "block-luks.h"
|
||||
|
||||
static const QCryptoBlockDriver *qcrypto_block_drivers[] = {
|
||||
[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 */
|
||||
|
||||
#ifdef CONFIG_GCRYPT
|
||||
#include "crypto/cipher-gcrypt.c"
|
||||
#include "cipher-gcrypt.c"
|
||||
#elif defined CONFIG_NETTLE
|
||||
#include "crypto/cipher-nettle.c"
|
||||
#include "cipher-nettle.c"
|
||||
#else
|
||||
#include "crypto/cipher-builtin.c"
|
||||
#include "cipher-builtin.c"
|
||||
#endif
|
||||
|
||||
QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "crypto/ivgen-essiv.h"
|
||||
#include "ivgen-essiv.h"
|
||||
|
||||
typedef struct QCryptoIVGenESSIV QCryptoIVGenESSIV;
|
||||
struct QCryptoIVGenESSIV {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "crypto/ivgenpriv.h"
|
||||
#include "ivgenpriv.h"
|
||||
|
||||
#ifndef QCRYPTO_IVGEN_ESSIV_H__
|
||||
#define QCRYPTO_IVGEN_ESSIV_H__
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "crypto/ivgen-plain.h"
|
||||
#include "ivgen-plain.h"
|
||||
|
||||
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
|
||||
const uint8_t *key, size_t nkey,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "crypto/ivgenpriv.h"
|
||||
#include "ivgenpriv.h"
|
||||
|
||||
#ifndef QCRYPTO_IVGEN_PLAIN_H__
|
||||
#define QCRYPTO_IVGEN_PLAIN_H__
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "crypto/ivgen-plain.h"
|
||||
#include "ivgen-plain.h"
|
||||
|
||||
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
|
||||
const uint8_t *key, size_t nkey,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "crypto/ivgenpriv.h"
|
||||
#include "ivgenpriv.h"
|
||||
|
||||
#ifndef QCRYPTO_IVGEN_PLAIN64_H__
|
||||
#define QCRYPTO_IVGEN_PLAIN64_H__
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
#include "crypto/ivgenpriv.h"
|
||||
#include "crypto/ivgen-plain.h"
|
||||
#include "crypto/ivgen-plain64.h"
|
||||
#include "crypto/ivgen-essiv.h"
|
||||
#include "ivgenpriv.h"
|
||||
#include "ivgen-plain.h"
|
||||
#include "ivgen-plain64.h"
|
||||
#include "ivgen-essiv.h"
|
||||
|
||||
|
||||
QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg,
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "crypto/tlscredspriv.h"
|
||||
#include "tlscredspriv.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define DH_BITS 2048
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "crypto/tlscredsanon.h"
|
||||
#include "crypto/tlscredspriv.h"
|
||||
#include "tlscredspriv.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "trace.h"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "crypto/tlscredsx509.h"
|
||||
#include "crypto/tlscredspriv.h"
|
||||
#include "tlscredspriv.h"
|
||||
#include "crypto/secret.h"
|
||||
#include "qapi/error.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
|
||||
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:
|
||||
|
||||
typedef struct VhostUserMsg {
|
||||
|
@ -146,6 +156,7 @@ typedef struct VhostUserMsg {
|
|||
VhostUserLog log;
|
||||
struct vhost_iotlb_msg iotlb;
|
||||
VhostUserConfig config;
|
||||
VhostUserVringArea area;
|
||||
};
|
||||
} 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
|
||||
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
|
||||
-----------------
|
||||
|
||||
|
@ -380,6 +395,8 @@ Protocol features
|
|||
#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
|
||||
#define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
|
||||
#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
|
||||
--------------------
|
||||
|
@ -777,6 +794,27 @@ Slave message types
|
|||
the VHOST_USER_NEED_REPLY flag, master must respond with zero when
|
||||
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:
|
||||
-------------------------------
|
||||
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
|
||||
accept persistent writes. In result, for example, the guest Linux
|
||||
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;
|
||||
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
|
||||
* 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. */);
|
||||
}
|
||||
|
||||
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();
|
||||
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);
|
||||
|
||||
if (state->capabilities) {
|
||||
nvdimm_build_structure_caps(structures, state->capabilities);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
fit_buf->fit = nvdimm_build_device_structure();
|
||||
fit_buf->fit = nvdimm_build_device_structure(state);
|
||||
fit_buf->dirty = true;
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
@ -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_BLK_SIZE);
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_FLUSH);
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_RO);
|
||||
|
||||
if (s->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) {
|
||||
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);
|
||||
VHostUserBlk *s = VHOST_USER_BLK(vdev);
|
||||
VhostUserState *user;
|
||||
int i, ret;
|
||||
|
||||
if (!s->chardev.chr) {
|
||||
|
@ -243,6 +242,15 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
|
|||
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,
|
||||
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);
|
||||
|
||||
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) {
|
||||
error_setg(errp, "vhost-user-blk: vhost initialization failed: %s",
|
||||
strerror(-ret));
|
||||
|
@ -283,6 +291,10 @@ vhost_err:
|
|||
virtio_err:
|
||||
g_free(s->dev.vqs);
|
||||
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)
|
||||
|
@ -294,6 +306,12 @@ static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
|
|||
vhost_dev_cleanup(&s->dev);
|
||||
g_free(s->dev.vqs);
|
||||
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)
|
||||
|
@ -319,7 +337,6 @@ static Property vhost_user_blk_properties[] = {
|
|||
DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues, 1),
|
||||
DEFINE_PROP_UINT32("queue-size", VHostUserBlk, queue_size, 128),
|
||||
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(),
|
||||
};
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "hw/display/bcm2835_fb.h"
|
||||
#include "hw/display/framebuffer.h"
|
||||
#include "framebuffer.h"
|
||||
#include "ui/pixel_ops.h"
|
||||
#include "hw/misc/bcm2835_mbox_defs.h"
|
||||
#include "qemu/log.h"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "hw/i386/pc.h"
|
||||
#include "hw/irq.h"
|
||||
|
||||
#include "hw/hppa/hppa_hardware.h"
|
||||
#include "hppa_hardware.h"
|
||||
|
||||
PCIBus *dino_init(MemoryRegion *, qemu_irq *, qemu_irq *);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "hw/ide.h"
|
||||
#include "hw/timer/i8254.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/hppa/hppa_sys.h"
|
||||
#include "hppa_sys.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qapi/error.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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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,
|
||||
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,
|
||||
pc_machine_get_smbus, pc_machine_set_smbus, &error_abort);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "qemu/error-report.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "hw/ide/internal.h"
|
||||
#include "hw/ide/ahci_internal.h"
|
||||
#include "ahci_internal.h"
|
||||
|
||||
#include "trace.h"
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "sysemu/dma.h"
|
||||
#include "hw/ide/internal.h"
|
||||
#include "hw/ide/pci.h"
|
||||
#include "hw/ide/ahci_internal.h"
|
||||
#include "ahci_internal.h"
|
||||
|
||||
#include "trace.h"
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
#include "hw/isa/isa.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "hw/ide/pci.h"
|
||||
#include "hw/ide/ahci_internal.h"
|
||||
#include "ahci_internal.h"
|
||||
|
||||
#define ICH9_MSI_CAP_OFFSET 0x80
|
||||
#define ICH9_SATA_CAP_OFFSET 0xA8
|
||||
|
|
|
@ -28,9 +28,8 @@
|
|||
#include "hw/i386/apic.h"
|
||||
#include "hw/i386/ioapic.h"
|
||||
#include "hw/i386/ioapic_internal.h"
|
||||
#include "include/hw/pci/msi.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "target/i386/cpu.h"
|
||||
#include "hw/i386/apic-msidef.h"
|
||||
#include "hw/i386/x86-iommu.h"
|
||||
#include "trace.h"
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "hw/pci/msi.h"
|
||||
#include "hw/pci/msix.h"
|
||||
|
||||
#include "hw/net/e1000_regs.h"
|
||||
#include "e1000_regs.h"
|
||||
|
||||
#include "e1000x_common.h"
|
||||
#include "e1000e_core.h"
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "net/clients.h"
|
||||
#include "qapi/qapi-types-rocker.h"
|
||||
#include "rocker.h"
|
||||
#include "rocker_hw.h"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "hw/ppc/ppc.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "hw/ppc/ppc440.h"
|
||||
#include "ppc440.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* L2 Cache as SRAM */
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#include "elf.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "exec/memory.h"
|
||||
#include "hw/ppc/ppc440.h"
|
||||
#include "hw/ppc/ppc405.h"
|
||||
#include "ppc440.h"
|
||||
#include "ppc405.h"
|
||||
#include "hw/block/flash.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/qtest.h"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "migration/migration.h"
|
||||
#include "hw/virtio/vhost.h"
|
||||
#include "hw/virtio/vhost-scsi-common.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);
|
||||
VHostUserSCSI *s = VHOST_USER_SCSI(dev);
|
||||
VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
|
||||
VhostUserState *user;
|
||||
Error *err = NULL;
|
||||
int ret;
|
||||
|
||||
|
@ -85,19 +86,30 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
|
|||
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.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs);
|
||||
vsc->dev.vq_index = 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);
|
||||
if (ret < 0) {
|
||||
error_setg(errp, "vhost-user-scsi: vhost initialization failed: %s",
|
||||
strerror(-ret));
|
||||
vhost_user_cleanup(user);
|
||||
g_free(user);
|
||||
return;
|
||||
}
|
||||
|
||||
s->vhost_user = user;
|
||||
|
||||
/* Channel and lun both are 0 for bootable vhost-user-scsi disk */
|
||||
vsc->channel = 0;
|
||||
vsc->lun = 0;
|
||||
|
@ -117,6 +129,12 @@ static void vhost_user_scsi_unrealize(DeviceState *dev, Error **errp)
|
|||
g_free(vsc->dev.vqs);
|
||||
|
||||
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,
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "hw/sysbus.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "trace.h"
|
||||
#include "include/qapi/error.h"
|
||||
#include "qapi/error.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "hw/sd/sd.h"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
|
||||
/*
|
||||
* Microsoft OS Descriptors
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "qemu/osdep.h"
|
||||
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
#include "hw/hw.h"
|
||||
#include "audio/audio.h"
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "qemu-common.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
#include "sysemu/bt.h"
|
||||
#include "hw/bt.h"
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "hw/hw.h"
|
||||
#include "ui/console.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "hw/input/hid.h"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "qemu-common.h"
|
||||
#include "trace.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
#define NUM_PORTS 8
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "qemu/iov.h"
|
||||
#include "trace.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
#include "net/net.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/queue.h"
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "qemu/cutils.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
#include "chardev/char-serial.h"
|
||||
#include "chardev/char-fe.h"
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "qemu-common.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
|
||||
#include "ccid.h"
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "qemu/option.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
#include "hw/scsi/scsi.h"
|
||||
#include "ui/console.h"
|
||||
#include "monitor/monitor.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "qemu/error-report.h"
|
||||
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
#include "hw/scsi/scsi.h"
|
||||
#include "scsi/constants.h"
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "hw/hw.h"
|
||||
#include "ui/console.h"
|
||||
#include "hw/usb.h"
|
||||
#include "hw/usb/desc.h"
|
||||
#include "desc.h"
|
||||
|
||||
/* Interface requests */
|
||||
#define WACOM_GET_REPORT 0x2101
|
||||
|
|
|
@ -1,7 +1,17 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "hw/virtio/vhost.h"
|
||||
#include "hw/virtio/vhost-user.h"
|
||||
|
||||
bool vhost_has_free_slot(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
VhostUserState *vhost_user_init(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vhost_user_cleanup(VhostUserState *user)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "hw/virtio/vhost.h"
|
||||
#include "hw/virtio/vhost-user.h"
|
||||
#include "hw/virtio/vhost-backend.h"
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "hw/virtio/virtio-net.h"
|
||||
#include "chardev/char-fe.h"
|
||||
#include "sysemu/kvm.h"
|
||||
|
@ -30,6 +32,7 @@
|
|||
|
||||
#define VHOST_MEMORY_MAX_NREGIONS 8
|
||||
#define VHOST_USER_F_PROTOCOL_FEATURES 30
|
||||
#define VHOST_USER_SLAVE_MAX_FDS 8
|
||||
|
||||
/*
|
||||
* Maximum size of virtio device config space
|
||||
|
@ -47,6 +50,8 @@ enum VhostUserProtocolFeature {
|
|||
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
||||
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
||||
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
|
||||
};
|
||||
|
||||
|
@ -91,6 +96,7 @@ 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;
|
||||
|
||||
|
@ -135,6 +141,12 @@ static VhostUserConfig c __attribute__ ((unused));
|
|||
+ sizeof(c.size) \
|
||||
+ sizeof(c.flags))
|
||||
|
||||
typedef struct VhostUserVringArea {
|
||||
uint64_t u64;
|
||||
uint64_t size;
|
||||
uint64_t offset;
|
||||
} VhostUserVringArea;
|
||||
|
||||
typedef struct {
|
||||
VhostUserRequest request;
|
||||
|
||||
|
@ -156,6 +168,7 @@ typedef union {
|
|||
struct vhost_iotlb_msg iotlb;
|
||||
VhostUserConfig config;
|
||||
VhostUserCryptoSession session;
|
||||
VhostUserVringArea area;
|
||||
} VhostUserPayload;
|
||||
|
||||
typedef struct VhostUserMsg {
|
||||
|
@ -173,7 +186,8 @@ static VhostUserMsg m __attribute__ ((unused));
|
|||
|
||||
struct vhost_user {
|
||||
struct vhost_dev *dev;
|
||||
CharBackend *chr;
|
||||
/* Shared between vhost devs of the same virtio device */
|
||||
VhostUserState *user;
|
||||
int slave_fd;
|
||||
NotifierWithReturn postcopy_notifier;
|
||||
struct PostCopyFD postcopy_fd;
|
||||
|
@ -199,7 +213,7 @@ static bool ioeventfd_enabled(void)
|
|||
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
|
||||
{
|
||||
struct vhost_user *u = dev->opaque;
|
||||
CharBackend *chr = u->chr;
|
||||
CharBackend *chr = u->user->chr;
|
||||
uint8_t *p = (uint8_t *) msg;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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,
|
||||
struct vhost_vring_state *ring)
|
||||
{
|
||||
vhost_user_host_notifier_restore(dev, ring->index);
|
||||
|
||||
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),
|
||||
};
|
||||
|
||||
vhost_user_host_notifier_remove(dev, ring->index);
|
||||
|
||||
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -845,6 +889,66 @@ static int vhost_user_slave_handle_config_change(struct vhost_dev *dev)
|
|||
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)
|
||||
{
|
||||
struct vhost_dev *dev = opaque;
|
||||
|
@ -854,10 +958,10 @@ static void slave_read(void *opaque)
|
|||
int size, ret = 0;
|
||||
struct iovec iov;
|
||||
struct msghdr msgh;
|
||||
int fd = -1;
|
||||
int fd[VHOST_USER_SLAVE_MAX_FDS];
|
||||
char control[CMSG_SPACE(sizeof(fd))];
|
||||
struct cmsghdr *cmsg;
|
||||
size_t fdsize;
|
||||
int i, fdsize = 0;
|
||||
|
||||
memset(&msgh, 0, sizeof(msgh));
|
||||
msgh.msg_iov = &iov;
|
||||
|
@ -865,6 +969,8 @@ static void slave_read(void *opaque)
|
|||
msgh.msg_control = control;
|
||||
msgh.msg_controllen = sizeof(control);
|
||||
|
||||
memset(fd, -1, sizeof(fd));
|
||||
|
||||
/* Read header */
|
||||
iov.iov_base = &hdr;
|
||||
iov.iov_len = VHOST_USER_HDR_SIZE;
|
||||
|
@ -885,7 +991,7 @@ static void slave_read(void *opaque)
|
|||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SCM_RIGHTS) {
|
||||
fdsize = cmsg->cmsg_len - CMSG_LEN(0);
|
||||
memcpy(&fd, CMSG_DATA(cmsg), fdsize);
|
||||
memcpy(fd, CMSG_DATA(cmsg), fdsize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -911,16 +1017,21 @@ static void slave_read(void *opaque)
|
|||
case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG :
|
||||
ret = vhost_user_slave_handle_config_change(dev);
|
||||
break;
|
||||
case VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG:
|
||||
ret = vhost_user_slave_handle_vring_host_notifier(dev, &payload.area,
|
||||
fd[0]);
|
||||
break;
|
||||
default:
|
||||
error_report("Received unexpected msg type.");
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
/* Message handlers need to make sure that fd will be consumed. */
|
||||
fd = -1;
|
||||
/* Close the remaining file descriptors. */
|
||||
for (i = 0; i < fdsize; i++) {
|
||||
if (fd[i] != -1) {
|
||||
close(fd[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
close(u->slave_fd);
|
||||
u->slave_fd = -1;
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
for (i = 0; i < fdsize; i++) {
|
||||
if (fd[i] != -1) {
|
||||
close(fd[i]);
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
struct vhost_user *u = dev->opaque;
|
||||
CharBackend *chr = u->chr;
|
||||
CharBackend *chr = u->user->chr;
|
||||
int ufd;
|
||||
VhostUserMsg msg = {
|
||||
.hdr.request = VHOST_USER_POSTCOPY_ADVISE,
|
||||
|
@ -1221,7 +1334,7 @@ static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier,
|
|||
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;
|
||||
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);
|
||||
|
||||
u = g_new0(struct vhost_user, 1);
|
||||
u->chr = opaque;
|
||||
u->user = opaque;
|
||||
u->slave_fd = -1;
|
||||
u->dev = dev;
|
||||
dev->opaque = u;
|
||||
|
@ -1306,7 +1419,7 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
|
|||
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;
|
||||
|
||||
|
@ -1620,10 +1733,40 @@ vhost_user_crypto_close_session(struct vhost_dev *dev, uint64_t session_id)
|
|||
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 = {
|
||||
.backend_type = VHOST_BACKEND_TYPE_USER,
|
||||
.vhost_backend_init = vhost_user_init,
|
||||
.vhost_backend_cleanup = vhost_user_cleanup,
|
||||
.vhost_backend_init = vhost_user_backend_init,
|
||||
.vhost_backend_cleanup = vhost_user_backend_cleanup,
|
||||
.vhost_backend_memslots_limit = vhost_user_memslots_limit,
|
||||
.vhost_set_log_base = vhost_user_set_log_base,
|
||||
.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_crypto_create_session = vhost_user_crypto_create_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;
|
||||
}
|
||||
|
||||
static bool vhost_section(MemoryRegionSection *section)
|
||||
static bool vhost_section(struct vhost_dev *dev, MemoryRegionSection *section)
|
||||
{
|
||||
bool result;
|
||||
bool log_dirty = memory_region_get_dirty_log_mask(section->mr) &
|
||||
|
@ -399,6 +399,11 @@ static bool vhost_section(MemoryRegionSection *section)
|
|||
*/
|
||||
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);
|
||||
return result;
|
||||
}
|
||||
|
@ -632,7 +637,7 @@ static void vhost_region_addnop(MemoryListener *listener,
|
|||
struct vhost_dev *dev = container_of(listener, struct vhost_dev,
|
||||
memory_listener);
|
||||
|
||||
if (!vhost_section(section)) {
|
||||
if (!vhost_section(dev, section)) {
|
||||
return;
|
||||
}
|
||||
vhost_region_add_section(dev, section);
|
||||
|
|
|
@ -76,6 +76,7 @@ struct PCMachineState {
|
|||
#define PC_MACHINE_VMPORT "vmport"
|
||||
#define PC_MACHINE_SMM "smm"
|
||||
#define PC_MACHINE_NVDIMM "nvdimm"
|
||||
#define PC_MACHINE_NVDIMM_CAP "nvdimm-cap"
|
||||
#define PC_MACHINE_SMBUS "smbus"
|
||||
#define PC_MACHINE_SATA "sata"
|
||||
#define PC_MACHINE_PIT "pit"
|
||||
|
|
|
@ -134,6 +134,11 @@ struct AcpiNVDIMMState {
|
|||
|
||||
/* the IO region used by OSPM to transfer control to QEMU. */
|
||||
MemoryRegion io_mr;
|
||||
|
||||
/*
|
||||
* Platform capabilities, section 5.2.25.9 of ACPI 6.2 Errata A
|
||||
*/
|
||||
int32_t capabilities;
|
||||
};
|
||||
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,
|
||||
uint64_t session_id);
|
||||
|
||||
typedef bool (*vhost_backend_mem_section_filter_op)(struct vhost_dev *dev,
|
||||
MemoryRegionSection *section);
|
||||
|
||||
typedef struct VhostOps {
|
||||
VhostBackendType backend_type;
|
||||
vhost_backend_init vhost_backend_init;
|
||||
|
@ -138,6 +141,7 @@ typedef struct VhostOps {
|
|||
vhost_set_config_op vhost_set_config;
|
||||
vhost_crypto_create_session_op vhost_crypto_create_session;
|
||||
vhost_crypto_close_session_op vhost_crypto_close_session;
|
||||
vhost_backend_mem_section_filter_op vhost_backend_mem_section_filter;
|
||||
} VhostOps;
|
||||
|
||||
extern const VhostOps user_ops;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "hw/block/block.h"
|
||||
#include "chardev/char-fe.h"
|
||||
#include "hw/virtio/vhost.h"
|
||||
#include "hw/virtio/vhost-user.h"
|
||||
|
||||
#define TYPE_VHOST_USER_BLK "vhost-user-blk"
|
||||
#define VHOST_USER_BLK(obj) \
|
||||
|
@ -34,8 +35,8 @@ typedef struct VHostUserBlk {
|
|||
uint16_t num_queues;
|
||||
uint32_t queue_size;
|
||||
uint32_t config_wce;
|
||||
uint32_t config_ro;
|
||||
struct vhost_dev dev;
|
||||
VhostUserState *vhost_user;
|
||||
} VHostUserBlk;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "hw/qdev.h"
|
||||
#include "hw/virtio/virtio-scsi.h"
|
||||
#include "hw/virtio/vhost.h"
|
||||
#include "hw/virtio/vhost-user.h"
|
||||
#include "hw/virtio/vhost-scsi-common.h"
|
||||
|
||||
#define TYPE_VHOST_USER_SCSI "vhost-user-scsi"
|
||||
|
@ -30,6 +31,7 @@
|
|||
typedef struct VHostUserSCSI {
|
||||
VHostSCSICommon parent_obj;
|
||||
uint64_t host_features;
|
||||
VhostUserState *vhost_user;
|
||||
} VHostUserSCSI;
|
||||
|
||||
#endif /* VHOST_USER_SCSI_H */
|
||||
|
|
|
@ -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
|
||||
#define QEMU_VMSTATE_H
|
||||
|
||||
#include "migration/qjson.h"
|
||||
typedef struct QJSON QJSON;
|
||||
|
||||
typedef struct VMStateInfo VMStateInfo;
|
||||
typedef struct VMStateDescription VMStateDescription;
|
||||
|
|
|
@ -107,6 +107,16 @@ extern int daemon(int, int);
|
|||
#include "glib-compat.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
|
||||
* even be a security risk during migration, if you disable assertions
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
#include "qemu/error-report.h"
|
||||
#include "migration/misc.h"
|
||||
#include "migration/migration.h"
|
||||
#include "migration/qemu-file.h"
|
||||
#include "qemu-file.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "migration/register.h"
|
||||
#include "qemu/hbitmap.h"
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "migration/page_cache.h"
|
||||
#include "page_cache.h"
|
||||
|
||||
#ifdef DEBUG_CACHE
|
||||
#define DPRINTF(fmt, ...) \
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "migration/misc.h"
|
||||
#include "qemu-file.h"
|
||||
#include "postcopy-ram.h"
|
||||
#include "migration/page_cache.h"
|
||||
#include "page_cache.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-events-migration.h"
|
||||
|
@ -51,7 +51,7 @@
|
|||
#include "exec/target_page.h"
|
||||
#include "qemu/rcu_queue.h"
|
||||
#include "migration/colo.h"
|
||||
#include "migration/block.h"
|
||||
#include "block.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qemu/uuid.h"
|
||||
#include "savevm.h"
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "io/channel-buffer.h"
|
||||
#include "io/channel-file.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "qjson.h"
|
||||
|
||||
#ifndef ETH_P_RARP
|
||||
#define ETH_P_RARP 0x8035
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "qemu-common.h"
|
||||
#include "migration.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "migration/savevm.h"
|
||||
#include "savevm.h"
|
||||
#include "qemu-file.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "net/queue.h"
|
||||
#include "chardev/char-fe.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "net/colo.h"
|
||||
#include "colo.h"
|
||||
#include "sysemu/iothread.h"
|
||||
|
||||
#define TYPE_COLO_COMPARE "colo-compare"
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "trace.h"
|
||||
#include "net/colo.h"
|
||||
#include "colo.h"
|
||||
|
||||
uint32_t connection_key_hash(const void *opaque)
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "trace.h"
|
||||
#include "net/colo.h"
|
||||
#include "colo.h"
|
||||
#include "net/filter.h"
|
||||
#include "net/net.h"
|
||||
#include "qemu-common.h"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "clients.h"
|
||||
#include "net/vhost_net.h"
|
||||
#include "net/vhost-user.h"
|
||||
#include "hw/virtio/vhost-user.h"
|
||||
#include "chardev/char-fe.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-commands-net.h"
|
||||
|
@ -23,6 +24,7 @@
|
|||
typedef struct NetVhostUserState {
|
||||
NetClientState nc;
|
||||
CharBackend chr; /* only queue index 0 */
|
||||
VhostUserState *vhost_user;
|
||||
VHostNetState *vhost_net;
|
||||
guint watch;
|
||||
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;
|
||||
struct vhost_net *net = NULL;
|
||||
|
@ -144,7 +147,7 @@ static ssize_t vhost_user_receive(NetClientState *nc, const uint8_t *buf,
|
|||
return size;
|
||||
}
|
||||
|
||||
static void vhost_user_cleanup(NetClientState *nc)
|
||||
static void net_vhost_user_cleanup(NetClientState *nc)
|
||||
{
|
||||
NetVhostUserState *s = DO_UPCAST(NetVhostUserState, nc, nc);
|
||||
|
||||
|
@ -159,6 +162,11 @@ static void vhost_user_cleanup(NetClientState *nc)
|
|||
s->watch = 0;
|
||||
}
|
||||
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);
|
||||
|
@ -182,7 +190,7 @@ static NetClientInfo net_vhost_user_info = {
|
|||
.type = NET_CLIENT_DRIVER_VHOST_USER,
|
||||
.size = sizeof(NetVhostUserState),
|
||||
.receive = vhost_user_receive,
|
||||
.cleanup = vhost_user_cleanup,
|
||||
.cleanup = net_vhost_user_cleanup,
|
||||
.has_vnet_hdr = vhost_user_has_vnet_hdr,
|
||||
.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);
|
||||
switch (event) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
@ -283,12 +291,19 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
|
|||
{
|
||||
Error *err = NULL;
|
||||
NetClientState *nc, *nc0 = NULL;
|
||||
NetVhostUserState *s;
|
||||
VhostUserState *user = NULL;
|
||||
NetVhostUserState *s = NULL;
|
||||
int i;
|
||||
|
||||
assert(name);
|
||||
assert(queues > 0);
|
||||
|
||||
user = vhost_user_init();
|
||||
if (!user) {
|
||||
error_report("failed to init vhost_user");
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < queues; i++) {
|
||||
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",
|
||||
|
@ -299,17 +314,19 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
|
|||
s = DO_UPCAST(NetVhostUserState, nc, nc);
|
||||
if (!qemu_chr_fe_init(&s->chr, chr, &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);
|
||||
do {
|
||||
if (qemu_chr_fe_wait_connected(&s->chr, &err) < 0) {
|
||||
error_report_err(err);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
qemu_chr_fe_set_handlers(&s->chr, NULL, 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);
|
||||
|
||||
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(
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <termios.h>
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "qga/channel.h"
|
||||
#include "channel.h"
|
||||
|
||||
#ifdef CONFIG_SOLARIS
|
||||
#include <stropts.h>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include "qga/guest-agent-core.h"
|
||||
#include "qga/channel.h"
|
||||
#include "guest-agent-core.h"
|
||||
#include "channel.h"
|
||||
|
||||
typedef struct GAChannelReadState {
|
||||
guint thread_id;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <dirent.h>
|
||||
#include "qga/guest-agent-core.h"
|
||||
#include "guest-agent-core.h"
|
||||
#include "qga-qapi-commands.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
#include <wtsapi32.h>
|
||||
#include <wininet.h>
|
||||
|
||||
#include "qga/guest-agent-core.h"
|
||||
#include "qga/vss-win32.h"
|
||||
#include "guest-agent-core.h"
|
||||
#include "vss-win32.h"
|
||||
#include "qga-qapi-commands.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qga/guest-agent-core.h"
|
||||
#include "guest-agent-core.h"
|
||||
#include "qga-qapi-commands.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qga/guest-agent-core.h"
|
||||
#include "guest-agent-core.h"
|
||||
|
||||
struct GACommandState {
|
||||
GSList *groups;
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qjson.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
#include "qga/guest-agent-core.h"
|
||||
#include "guest-agent-core.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qga-qapi-commands.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qga/channel.h"
|
||||
#include "channel.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "qemu/help_option.h"
|
||||
#include "qemu/sockets.h"
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
#include <windows.h>
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qga/guest-agent-core.h"
|
||||
#include "qga/vss-win32.h"
|
||||
#include "qga/vss-win32/requester.h"
|
||||
#include "guest-agent-core.h"
|
||||
#include "vss-win32.h"
|
||||
#include "vss-win32/requester.h"
|
||||
|
||||
#define QGA_VSS_DLL "qga-vss.dll"
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ test-base64
|
|||
test-bdrv-drain
|
||||
test-bitops
|
||||
test-bitcnt
|
||||
test-block-backend
|
||||
test-blockjob
|
||||
test-blockjob-txn
|
||||
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));
|
||||
data.machine = machine;
|
||||
data.variant = ".dimmpxm";
|
||||
test_acpi_one(" -machine nvdimm=on"
|
||||
test_acpi_one(" -machine nvdimm=on,nvdimm-cap=3"
|
||||
" -smp 4,sockets=4"
|
||||
" -m 128M,slots=3,maxmem=1G"
|
||||
" -numa node,mem=32M,nodeid=0"
|
||||
|
|
|
@ -103,8 +103,15 @@ static int socket_accept(int sock)
|
|||
static void kill_qemu(QTestState *s)
|
||||
{
|
||||
if (s->qemu_pid != -1) {
|
||||
int wstatus = 0;
|
||||
pid_t pid;
|
||||
|
||||
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
|
||||
|
||||
#include "qemu/atomic.h"
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "standard-headers/linux/virtio_net.h"
|
||||
|
@ -65,6 +66,11 @@ typedef struct VubrDev {
|
|||
int sock;
|
||||
int ready;
|
||||
int quit;
|
||||
struct {
|
||||
int fd;
|
||||
void *addr;
|
||||
pthread_t thread;
|
||||
} notifier;
|
||||
} VubrDev;
|
||||
|
||||
static void
|
||||
|
@ -445,14 +451,22 @@ static uint64_t
|
|||
vubr_get_features(VuDev *dev)
|
||||
{
|
||||
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
|
||||
vubr_queue_set_started(VuDev *dev, int qidx, bool started)
|
||||
{
|
||||
VubrDev *vubr = container_of(dev, VubrDev, vudev);
|
||||
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) {
|
||||
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");
|
||||
}
|
||||
|
||||
dev->notifier.fd = -1;
|
||||
|
||||
un.sun_family = AF_UNIX;
|
||||
strcpy(un.sun_path, path);
|
||||
len = sizeof(un.sun_family) + strlen(path);
|
||||
|
@ -559,6 +575,73 @@ vubr_new(const char *path, bool client)
|
|||
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
|
||||
vubr_set_host(struct sockaddr_in *saddr, const char *host)
|
||||
{
|
||||
|
@ -673,8 +756,9 @@ main(int argc, char *argv[])
|
|||
VubrDev *dev;
|
||||
int opt;
|
||||
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) {
|
||||
case 'l':
|
||||
|
@ -693,6 +777,9 @@ main(int argc, char *argv[])
|
|||
case 'c':
|
||||
client = true;
|
||||
break;
|
||||
case 'H':
|
||||
host_notifier = true;
|
||||
break;
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
|
@ -708,6 +795,10 @@ main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (host_notifier) {
|
||||
vubr_host_notifier_setup(dev);
|
||||
}
|
||||
|
||||
vubr_backend_udp_setup(dev, lhost, lport, rhost, rport);
|
||||
vubr_run(dev);
|
||||
|
||||
|
@ -717,7 +808,7 @@ main(int argc, char *argv[])
|
|||
|
||||
out:
|
||||
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",
|
||||
DEFAULT_UD_SOCKET);
|
||||
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",
|
||||
DEFAULT_RHOST, DEFAULT_RPORT);
|
||||
fprintf(stderr, "\t-c client mode\n");
|
||||
fprintf(stderr, "\t-H use host notifier\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -267,6 +267,6 @@ char *trace_opt_parse(const char *optarg);
|
|||
uint32_t trace_get_vcpu_event_count(void);
|
||||
|
||||
|
||||
#include "trace/control-internal.h"
|
||||
#include "control-internal.h"
|
||||
|
||||
#endif /* TRACE__CONTROL_H */
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.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)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue