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:
Peter Maydell 2018-06-04 10:15:16 +01:00
commit f67c9b693a
104 changed files with 807 additions and 166 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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"

View File

@ -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 */

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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:

View File

@ -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

View File

@ -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 {

View File

@ -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"

View File

@ -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;
} }

View File

@ -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:

View File

@ -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);

View File

@ -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"

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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 {

View File

@ -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__

View File

@ -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,

View File

@ -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__

View File

@ -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,

View File

@ -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__

View File

@ -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,

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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.

View File

@ -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,

View File

@ -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(),
}; };

View File

@ -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"

View File

@ -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 *);

View File

@ -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"

View File

@ -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);

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 */

View File

@ -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"

View File

@ -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"

View File

@ -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,

View File

@ -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"

View File

@ -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

View File

@ -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"
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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"
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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)
{
}

View File

@ -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,
}; };

View File

@ -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);

View File

@ -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"

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 */

View 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

View File

@ -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;

View File

@ -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

View File

@ -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"

View File

@ -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, ...) \

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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)
{ {

View File

@ -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"

View File

@ -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(

View File

@ -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>

View File

@ -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;

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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;

View File

@ -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"

View File

@ -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
View File

@ -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.

View File

@ -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"

View File

@ -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));
}
} }
} }

View File

@ -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;
} }

View File

@ -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 */

View File

@ -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