Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into…
Browse files Browse the repository at this point in the history
… staging

Mostly bugfixes, plus a patch to mark accelerator MemoryRegions in "info
mtree" that has been lingering for too long.

# gpg: Signature made Fri 19 Jul 2019 22:45:46 BST
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  target/i386: sev: fix failed message typos
  i386: indicate that 'pconfig' feature was removed intentionally
  build-sys: do no support modules on Windows
  qmp: don't emit the RESET event on wakeup
  hmp: Print if memory section is registered with an accelerator
  test-bitmap: add test for bitmap_set
  scsi-generic: Check sense key before request snooping and patching
  vhost-user-scsi: Call virtio_scsi_common_unrealize() when device realize failed
  vhost-scsi: Call virtio_scsi_common_unrealize() when device realize failed
  virtio-scsi: remove unused argument to virtio_scsi_common_realize
  target/i386: skip KVM_GET/SET_NESTED_STATE if VMX disabled, or for SVM
  target/i386: kvm: Demand nested migration kernel capabilities only when vCPU may have enabled VMX

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jul 22, 2019
2 parents b9e02bb + d4b976c commit 9d2e1fc
Show file tree
Hide file tree
Showing 17 changed files with 220 additions and 79 deletions.
38 changes: 38 additions & 0 deletions accel/kvm/kvm-all.c
Expand Up @@ -111,6 +111,13 @@ struct KVMState
/* memory encryption */
void *memcrypt_handle;
int (*memcrypt_encrypt_data)(void *handle, uint8_t *ptr, uint64_t len);

/* For "info mtree -f" to tell if an MR is registered in KVM */
int nr_as;
struct KVMAs {
KVMMemoryListener *ml;
AddressSpace *as;
} *as;
};

KVMState *kvm_state;
Expand Down Expand Up @@ -1159,6 +1166,14 @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
kml->listener.priority = 10;

memory_listener_register(&kml->listener, as);

for (i = 0; i < s->nr_as; ++i) {
if (!s->as[i].as) {
s->as[i].as = as;
s->as[i].ml = kml;
break;
}
}
}

static MemoryListener kvm_io_listener = {
Expand Down Expand Up @@ -1809,6 +1824,12 @@ static int kvm_init(MachineState *ms)
s->nr_slots = 32;
}

s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE);
if (s->nr_as <= 1) {
s->nr_as = 1;
}
s->as = g_new0(struct KVMAs, s->nr_as);

kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
if (mc->kvm_type) {
type = mc->kvm_type(ms, kvm_type);
Expand Down Expand Up @@ -2828,11 +2849,28 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target)
return r;
}

static bool kvm_accel_has_memory(MachineState *ms, AddressSpace *as,
hwaddr start_addr, hwaddr size)
{
KVMState *kvm = KVM_STATE(ms->accelerator);
int i;

for (i = 0; i < kvm->nr_as; ++i) {
if (kvm->as[i].as == as && kvm->as[i].ml) {
return NULL != kvm_lookup_matching_slot(kvm->as[i].ml,
start_addr, size);
}
}

return false;
}

static void kvm_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "KVM";
ac->init_machine = kvm_init;
ac->has_memory = kvm_accel_has_memory;
ac->allowed = &kvm_allowed;
}

Expand Down
7 changes: 6 additions & 1 deletion configure
Expand Up @@ -1752,7 +1752,7 @@ disabled with --disable-FEATURE, default is enabled if available:
guest-agent build the QEMU Guest Agent
guest-agent-msi build guest agent Windows MSI installation package
pie Position Independent Executables
modules modules support
modules modules support (non-Windows)
debug-tcg TCG debugging (default is disabled)
debug-info debugging information
sparse sparse checker
Expand Down Expand Up @@ -2007,6 +2007,11 @@ else
QEMU_CFLAGS="$QEMU_CFLAGS -Wno-missing-braces"
fi

# Our module code doesn't support Windows
if test "$modules" = "yes" && test "$mingw32" = "yes" ; then
error_exit "Modules are not available for Windows"
fi

# Static linking is not possible with modules or PIE
if test "$static" = "yes" ; then
if test "$modules" = "yes" ; then
Expand Down
28 changes: 16 additions & 12 deletions hw/scsi/scsi-generic.c
Expand Up @@ -254,24 +254,28 @@ static void scsi_read_complete(void * opaque, int ret)

r->len = -1;

/*
* Check if this is a VPD Block Limits request that
* resulted in sense error but would need emulation.
* In this case, emulate a valid VPD response.
*/
if (s->needs_vpd_bl_emulation && ret == 0 &&
(r->io_header.driver_status & SG_ERR_DRIVER_SENSE) &&
r->req.cmd.buf[0] == INQUIRY &&
(r->req.cmd.buf[1] & 0x01) &&
r->req.cmd.buf[2] == 0xb0) {
if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
SCSISense sense =
scsi_parse_sense_buf(r->req.sense, r->io_header.sb_len_wr);
if (sense.key == ILLEGAL_REQUEST) {

/*
* Check if this is a VPD Block Limits request that
* resulted in sense error but would need emulation.
* In this case, emulate a valid VPD response.
*/
if (sense.key == ILLEGAL_REQUEST &&
s->needs_vpd_bl_emulation &&
r->req.cmd.buf[0] == INQUIRY &&
(r->req.cmd.buf[1] & 0x01) &&
r->req.cmd.buf[2] == 0xb0) {
len = scsi_generic_emulate_block_limits(r, s);
/*
* No need to let scsi_read_complete go on and handle an
* It's okay to jup to req_complete: no need to
* let scsi_handle_inquiry_reply handle an
* INQUIRY VPD BL request we created manually.
*/
}
if (sense.key) {
goto req_complete;
}
}
Expand Down
6 changes: 4 additions & 2 deletions hw/scsi/vhost-scsi.c
Expand Up @@ -210,7 +210,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
if (err) {
error_propagate(errp, err);
error_free(vsc->migration_blocker);
goto close_fd;
goto free_virtio;
}
}

Expand Down Expand Up @@ -240,6 +240,8 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
migrate_del_blocker(vsc->migration_blocker);
}
g_free(vsc->dev.vqs);
free_virtio:
virtio_scsi_common_unrealize(dev);
close_fd:
close(vhostfd);
return;
Expand All @@ -262,7 +264,7 @@ static void vhost_scsi_unrealize(DeviceState *dev, Error **errp)
vhost_dev_cleanup(&vsc->dev);
g_free(vqs);

virtio_scsi_common_unrealize(dev, errp);
virtio_scsi_common_unrealize(dev);
}

static Property vhost_scsi_properties[] = {
Expand Down
16 changes: 11 additions & 5 deletions hw/scsi/vhost-user-scsi.c
Expand Up @@ -87,7 +87,7 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
}

if (!vhost_user_init(&s->vhost_user, &vs->conf.chardev, errp)) {
return;
goto free_virtio;
}

vsc->dev.nvqs = 2 + vs->conf.num_queues;
Expand All @@ -101,15 +101,21 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
if (ret < 0) {
error_setg(errp, "vhost-user-scsi: vhost initialization failed: %s",
strerror(-ret));
vhost_user_cleanup(&s->vhost_user);
g_free(vqs);
return;
goto free_vhost;
}

/* Channel and lun both are 0 for bootable vhost-user-scsi disk */
vsc->channel = 0;
vsc->lun = 0;
vsc->target = vs->conf.boot_tpgt;

return;

free_vhost:
vhost_user_cleanup(&s->vhost_user);
g_free(vqs);
free_virtio:
virtio_scsi_common_unrealize(dev);
}

static void vhost_user_scsi_unrealize(DeviceState *dev, Error **errp)
Expand All @@ -125,7 +131,7 @@ static void vhost_user_scsi_unrealize(DeviceState *dev, Error **errp)
vhost_dev_cleanup(&vsc->dev);
g_free(vqs);

virtio_scsi_common_unrealize(dev, errp);
virtio_scsi_common_unrealize(dev);
vhost_user_cleanup(&s->vhost_user);
}

Expand Down
4 changes: 2 additions & 2 deletions hw/scsi/virtio-scsi.c
Expand Up @@ -922,7 +922,7 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
virtio_scsi_dataplane_setup(s, errp);
}

void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp)
void virtio_scsi_common_unrealize(DeviceState *dev)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
Expand All @@ -936,7 +936,7 @@ static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp)
VirtIOSCSI *s = VIRTIO_SCSI(dev);

qbus_set_hotplug_handler(BUS(&s->bus), NULL, &error_abort);
virtio_scsi_common_unrealize(dev, errp);
virtio_scsi_common_unrealize(dev);
}

static Property virtio_scsi_properties[] = {
Expand Down
2 changes: 1 addition & 1 deletion include/hw/virtio/virtio-scsi.h
Expand Up @@ -145,7 +145,7 @@ void virtio_scsi_common_realize(DeviceState *dev,
VirtIOHandleOutput cmd,
Error **errp);

void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
void virtio_scsi_common_unrealize(DeviceState *dev);
bool virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq);
bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq);
bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq);
Expand Down
3 changes: 3 additions & 0 deletions include/sysemu/accel.h
Expand Up @@ -25,6 +25,7 @@

#include "qom/object.h"
#include "hw/qdev-properties.h"
#include "exec/hwaddr.h"

typedef struct AccelState {
/*< private >*/
Expand All @@ -39,6 +40,8 @@ typedef struct AccelClass {
const char *name;
int (*init_machine)(MachineState *ms);
void (*setup_post)(MachineState *ms, AccelState *accel);
bool (*has_memory)(MachineState *ms, AddressSpace *as,
hwaddr start_addr, hwaddr size);
bool *allowed;
/*
* Array of global properties that would be applied when specific
Expand Down
22 changes: 22 additions & 0 deletions memory.c
Expand Up @@ -30,7 +30,9 @@
#include "sysemu/kvm.h"
#include "sysemu/sysemu.h"
#include "sysemu/tcg.h"
#include "sysemu/accel.h"
#include "hw/qdev-properties.h"
#include "hw/boards.h"
#include "migration/vmstate.h"

//#define DEBUG_UNASSIGNED
Expand Down Expand Up @@ -2999,6 +3001,8 @@ struct FlatViewInfo {
int counter;
bool dispatch_tree;
bool owner;
AccelClass *ac;
const char *ac_name;
};

static void mtree_print_flatview(gpointer key, gpointer value,
Expand Down Expand Up @@ -3061,6 +3065,17 @@ static void mtree_print_flatview(gpointer key, gpointer value,
if (fvi->owner) {
mtree_print_mr_owner(mr);
}

if (fvi->ac) {
for (i = 0; i < fv_address_spaces->len; ++i) {
as = g_array_index(fv_address_spaces, AddressSpace*, i);
if (fvi->ac->has_memory(current_machine, as,
int128_get64(range->addr.start),
MR_SIZE(range->addr.size) + 1)) {
qemu_printf(" %s", fvi->ac_name);
}
}
}
qemu_printf("\n");
range++;
}
Expand Down Expand Up @@ -3101,6 +3116,13 @@ void mtree_info(bool flatview, bool dispatch_tree, bool owner)
};
GArray *fv_address_spaces;
GHashTable *views = g_hash_table_new(g_direct_hash, g_direct_equal);
AccelClass *ac = ACCEL_GET_CLASS(current_machine->accelerator);

if (ac->has_memory) {
fvi.ac = ac;
fvi.ac_name = current_machine->accel ? current_machine->accel :
object_class_get_name(OBJECT_CLASS(ac));
}

/* Gather all FVs in one table */
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
Expand Down
2 changes: 1 addition & 1 deletion target/i386/cpu.c
Expand Up @@ -1083,7 +1083,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
NULL, NULL, NULL, NULL,
NULL, NULL, "md-clear", NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL /* pconfig */, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, "spec-ctrl", "stibp",
NULL, "arch-capabilities", "core-capability", "ssbd",
Expand Down
22 changes: 22 additions & 0 deletions target/i386/cpu.h
Expand Up @@ -1877,6 +1877,28 @@ static inline bool cpu_has_vmx(CPUX86State *env)
return env->features[FEAT_1_ECX] & CPUID_EXT_VMX;
}

/*
* In order for a vCPU to enter VMX operation it must have CR4.VMXE set.
* Since it was set, CR4.VMXE must remain set as long as vCPU is in
* VMX operation. This is because CR4.VMXE is one of the bits set
* in MSR_IA32_VMX_CR4_FIXED1.
*
* There is one exception to above statement when vCPU enters SMM mode.
* When a vCPU enters SMM mode, it temporarily exit VMX operation and
* may also reset CR4.VMXE during execution in SMM mode.
* When vCPU exits SMM mode, vCPU state is restored to be in VMX operation
* and CR4.VMXE is restored to it's original value of being set.
*
* Therefore, when vCPU is not in SMM mode, we can infer whether
* VMX is being used by examining CR4.VMXE. Otherwise, we cannot
* know for certain.
*/
static inline bool cpu_vmx_maybe_enabled(CPUX86State *env)
{
return cpu_has_vmx(env) &&
((env->cr[4] & CR4_VMXE_MASK) || (env->hflags & HF_SMM_MASK));
}

/* fpu_helper.c */
void update_fp_status(CPUX86State *env);
void update_mxcsr_status(CPUX86State *env);
Expand Down

0 comments on commit 9d2e1fc

Please sign in to comment.