Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20150316' int…
Browse files Browse the repository at this point in the history
…o staging

Final batch of s390x enhancements/fixes for 2.3:
- handle TOD clock during migration
- CPACF key wrap options
- limit amount of pci device code we build
- ensure big endian accesses for ccws
- various fixes and cleanups

# gpg: Signature made Mon Mar 16 10:01:44 2015 GMT using RSA key ID C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>"

* remotes/cohuck/tags/s390x-20150316:
  s390x/config: Do not include full pci.mak
  s390x/pci: fix length in sei_nt2 event
  s390x/ipl: remove dead code
  s390x/virtio-bus: Remove unused function s390_virtio_bus_console()
  s390x: CPACF: Handle key wrap machine options
  s390x/kvm: make use of generic vm attribute check
  kvm: encapsulate HAS_DEVICE for vm attrs
  virtio-ccw: assure BE accesses
  s390x/kvm: Guest Migration TOD clock synchronization
  s390x: Replace unchecked qdev_init() by qdev_init_nofail()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Mar 16, 2015
2 parents f421f05 + be0b608 commit 2dfe7d0
Show file tree
Hide file tree
Showing 14 changed files with 311 additions and 60 deletions.
3 changes: 2 additions & 1 deletion default-configs/s390x-softmmu.mak
@@ -1,4 +1,5 @@
include pci.mak
CONFIG_PCI=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO=y
CONFIG_SCLPCONSOLE=y
CONFIG_S390_FLIC=y
Expand Down
6 changes: 1 addition & 5 deletions hw/intc/s390_flic.c
Expand Up @@ -30,18 +30,14 @@ S390FLICState *s390_get_flic(void)
void s390_flic_init(void)
{
DeviceState *dev;
int r;

dev = s390_flic_kvm_create();
if (!dev) {
dev = qdev_create(NULL, TYPE_QEMU_S390_FLIC);
object_property_add_child(qdev_get_machine(), TYPE_QEMU_S390_FLIC,
OBJECT(dev), NULL);
}
r = qdev_init(dev);
if (r) {
error_report("flic: couldn't create qdev");
}
qdev_init_nofail(dev);
}

static int qemu_s390_register_io_adapter(S390FLICState *fs, uint32_t id,
Expand Down
3 changes: 0 additions & 3 deletions hw/s390x/ipl.c
Expand Up @@ -142,9 +142,6 @@ static int s390_ipl_init(SysBusDevice *dev)
bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,
4096);
ipl->bios_start_addr = ZIPL_IMAGE_START;
if (bios_size > 4096) {
hw_error("stage1 bootloader is > 4k\n");
}
}
g_free(bios_filename);

Expand Down
1 change: 1 addition & 0 deletions hw/s390x/s390-pci-bus.c
Expand Up @@ -44,6 +44,7 @@ int chsc_sei_nt2_get_event(void *res)
QTAILQ_REMOVE(&s->pending_sei, sei_cont, link);
nt2_res->nt = 2;
nt2_res->cc = sei_cont->cc;
nt2_res->length = cpu_to_be16(sizeof(ChscSeiNt2Res));
switch (sei_cont->cc) {
case 1: /* error event */
eccdf = (PciCcdfErr *)nt2_res->ccdf;
Expand Down
5 changes: 0 additions & 5 deletions hw/s390x/s390-virtio-bus.c
Expand Up @@ -435,11 +435,6 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev)
virtio_set_features(vdev, features);
}

VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
{
return bus->console;
}

/* Find a device by vring address */
VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
ram_addr_t mem,
Expand Down
1 change: 0 additions & 1 deletion hw/s390x/s390-virtio-bus.h
Expand Up @@ -108,7 +108,6 @@ typedef struct VirtIOS390Bus {

void s390_virtio_device_update_status(VirtIOS390Device *dev);

VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus);
VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size);

VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
Expand Down
67 changes: 67 additions & 0 deletions hw/s390x/s390-virtio-ccw.c
Expand Up @@ -22,6 +22,18 @@

#define TYPE_S390_CCW_MACHINE "s390-ccw-machine"

#define S390_CCW_MACHINE(obj) \
OBJECT_CHECK(S390CcwMachineState, (obj), TYPE_S390_CCW_MACHINE)

typedef struct S390CcwMachineState {
/*< private >*/
MachineState parent_obj;

/*< public >*/
bool aes_key_wrap;
bool dea_key_wrap;
} S390CcwMachineState;

void io_subsystem_reset(void)
{
DeviceState *css, *sclp, *flic;
Expand Down Expand Up @@ -181,6 +193,10 @@ static void ccw_init(MachineState *machine)

/* Create VirtIO network adapters */
s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");

/* Register savevm handler for guest TOD clock */
register_savevm(NULL, "todclock", 0, 1,
gtod_save, gtod_load, kvm_state);
}

static void ccw_machine_class_init(ObjectClass *oc, void *data)
Expand All @@ -203,9 +219,60 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
nc->nmi_monitor_handler = s390_nmi;
}

static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
{
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);

return ms->aes_key_wrap;
}

static inline void machine_set_aes_key_wrap(Object *obj, bool value,
Error **errp)
{
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);

ms->aes_key_wrap = value;
}

static inline bool machine_get_dea_key_wrap(Object *obj, Error **errp)
{
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);

return ms->dea_key_wrap;
}

static inline void machine_set_dea_key_wrap(Object *obj, bool value,
Error **errp)
{
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);

ms->dea_key_wrap = value;
}

static inline void s390_machine_initfn(Object *obj)
{
object_property_add_bool(obj, "aes-key-wrap",
machine_get_aes_key_wrap,
machine_set_aes_key_wrap, NULL);
object_property_set_description(obj, "aes-key-wrap",
"enable/disable AES key wrapping using the CPACF wrapping key",
NULL);
object_property_set_bool(obj, true, "aes-key-wrap", NULL);

object_property_add_bool(obj, "dea-key-wrap",
machine_get_dea_key_wrap,
machine_set_dea_key_wrap, NULL);
object_property_set_description(obj, "dea-key-wrap",
"enable/disable DEA key wrapping using the CPACF wrapping key",
NULL);
object_property_set_bool(obj, true, "dea-key-wrap", NULL);
}

static const TypeInfo ccw_machine_info = {
.name = TYPE_S390_CCW_MACHINE,
.parent = TYPE_MACHINE,
.instance_size = sizeof(S390CcwMachineState),
.instance_init = s390_machine_initfn,
.class_init = ccw_machine_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_NMI },
Expand Down
52 changes: 52 additions & 0 deletions hw/s390x/s390-virtio.c
Expand Up @@ -38,6 +38,7 @@
#include "hw/s390x/sclp.h"
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/s390-virtio.h"
#include "cpu.h"

//#define DEBUG_S390

Expand All @@ -53,6 +54,9 @@
#define ZIPL_FILENAME "s390-zipl.rom"
#define TYPE_S390_MACHINE "s390-machine"

#define S390_TOD_CLOCK_VALUE_MISSING 0x00
#define S390_TOD_CLOCK_VALUE_PRESENT 0x01

static VirtIOS390Bus *s390_bus;
static S390CPU **ipi_states;

Expand Down Expand Up @@ -196,6 +200,51 @@ void s390_create_virtio_net(BusState *bus, const char *name)
}
}

void gtod_save(QEMUFile *f, void *opaque)
{
uint64_t tod_low;
uint8_t tod_high;
int r;

r = s390_get_clock(&tod_high, &tod_low);
if (r) {
fprintf(stderr, "WARNING: Unable to get guest clock for migration. "
"Error code %d. Guest clock will not be migrated "
"which could cause the guest to hang.\n", r);
qemu_put_byte(f, S390_TOD_CLOCK_VALUE_MISSING);
return;
}

qemu_put_byte(f, S390_TOD_CLOCK_VALUE_PRESENT);
qemu_put_byte(f, tod_high);
qemu_put_be64(f, tod_low);
}

int gtod_load(QEMUFile *f, void *opaque, int version_id)
{
uint64_t tod_low;
uint8_t tod_high;
int r;

if (qemu_get_byte(f) == S390_TOD_CLOCK_VALUE_MISSING) {
fprintf(stderr, "WARNING: Guest clock was not migrated. This could "
"cause the guest to hang.\n");
return 0;
}

tod_high = qemu_get_byte(f);
tod_low = qemu_get_be64(f);

r = s390_set_clock(&tod_high, &tod_low);
if (r) {
fprintf(stderr, "WARNING: Unable to set guest clock value. "
"s390_get_clock returned error %d. This could cause "
"the guest to hang.\n", r);
}

return 0;
}

/* PC hardware initialisation */
static void s390_init(MachineState *machine)
{
Expand Down Expand Up @@ -253,6 +302,9 @@ static void s390_init(MachineState *machine)

/* Create VirtIO network adapters */
s390_create_virtio_net((BusState *)s390_bus, "virtio-net-s390");

/* Register savevm handler for guest TOD clock */
register_savevm(NULL, "todclock", 0, 1, gtod_save, gtod_load, NULL);
}

void s390_nmi(NMIState *n, int cpu_index, Error **errp)
Expand Down
22 changes: 13 additions & 9 deletions hw/s390x/virtio-ccw.c
Expand Up @@ -508,7 +508,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
if (!ccw.cda) {
ret = -EFAULT;
} else {
indicators = ldq_phys(&address_space_memory, ccw.cda);
indicators = ldq_be_phys(&address_space_memory, ccw.cda);
dev->indicators = get_indicator(indicators, sizeof(uint64_t));
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
ret = 0;
Expand All @@ -528,7 +528,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
if (!ccw.cda) {
ret = -EFAULT;
} else {
indicators = ldq_phys(&address_space_memory, ccw.cda);
indicators = ldq_be_phys(&address_space_memory, ccw.cda);
dev->indicators2 = get_indicator(indicators, sizeof(uint64_t));
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
ret = 0;
Expand All @@ -548,11 +548,11 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
if (!ccw.cda) {
ret = -EFAULT;
} else {
vq_config.index = lduw_phys(&address_space_memory, ccw.cda);
vq_config.index = lduw_be_phys(&address_space_memory, ccw.cda);
vq_config.num_max = virtio_queue_get_num(vdev,
vq_config.index);
stw_phys(&address_space_memory,
ccw.cda + sizeof(vq_config.index), vq_config.num_max);
stw_be_phys(&address_space_memory,
ccw.cda + sizeof(vq_config.index), vq_config.num_max);
sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
ret = 0;
}
Expand Down Expand Up @@ -580,13 +580,17 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
if (!thinint) {
ret = -EFAULT;
} else {
uint64_t ind_bit = ldq_be_p(&thinint->ind_bit);

len = hw_len;
dev->summary_indicator =
get_indicator(thinint->summary_indicator, sizeof(uint8_t));
dev->indicators = get_indicator(thinint->device_indicator,
thinint->ind_bit / 8 + 1);
get_indicator(ldq_be_p(&thinint->summary_indicator),
sizeof(uint8_t));
dev->indicators =
get_indicator(ldq_be_p(&thinint->device_indicator),
ind_bit / 8 + 1);
dev->thinint_isc = thinint->isc;
dev->routes.adapter.ind_offset = thinint->ind_bit;
dev->routes.adapter.ind_offset = ind_bit;
dev->routes.adapter.summary_offset = 7;
cpu_physical_memory_unmap(thinint, hw_len, 0, hw_len);
ret = css_register_io_adapter(CSS_IO_ADAPTER_VIRTIO,
Expand Down
12 changes: 12 additions & 0 deletions include/sysemu/kvm.h
Expand Up @@ -224,6 +224,18 @@ int kvm_vcpu_ioctl(CPUState *cpu, int type, ...);
*/
int kvm_device_ioctl(int fd, int type, ...);

/**
* kvm_vm_check_attr - check for existence of a specific vm attribute
* @s: The KVMState pointer
* @group: the group
* @attr: the attribute of that group to query for
*
* Returns: 1 if the attribute exists
* 0 if the attribute either does not exist or if the vm device
* interface is unavailable
*/
int kvm_vm_check_attr(KVMState *s, uint32_t group, uint64_t attr);

/**
* kvm_create_device - create a KVM device for the device control API
* @KVMState: The KVMState pointer
Expand Down
21 changes: 21 additions & 0 deletions kvm-all.c
Expand Up @@ -126,6 +126,7 @@ bool kvm_gsi_routing_allowed;
bool kvm_gsi_direct_mapping;
bool kvm_allowed;
bool kvm_readonly_mem_allowed;
bool kvm_vm_attributes_allowed;

static const KVMCapabilityInfo kvm_required_capabilites[] = {
KVM_CAP_INFO(USER_MEMORY),
Expand Down Expand Up @@ -1598,6 +1599,9 @@ static int kvm_init(MachineState *ms)
kvm_resamplefds_allowed =
(kvm_check_extension(s, KVM_CAP_IRQFD_RESAMPLE) > 0);

kvm_vm_attributes_allowed =
(kvm_check_extension(s, KVM_CAP_VM_ATTRIBUTES) > 0);

ret = kvm_arch_init(ms, s);
if (ret < 0) {
goto err;
Expand Down Expand Up @@ -1936,6 +1940,23 @@ int kvm_device_ioctl(int fd, int type, ...)
return ret;
}

int kvm_vm_check_attr(KVMState *s, uint32_t group, uint64_t attr)
{
int ret;
struct kvm_device_attr attribute = {
.group = group,
.attr = attr,
};

if (!kvm_vm_attributes_allowed) {
return 0;
}

ret = kvm_vm_ioctl(s, KVM_HAS_DEVICE_ATTR, &attribute);
/* kvm returns 0 on success for HAS_DEVICE_ATTR */
return ret ? 0 : 1;
}

int kvm_has_sync_mmu(void)
{
return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU);
Expand Down
12 changes: 11 additions & 1 deletion qemu-options.hx
Expand Up @@ -37,7 +37,9 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" kvm_shadow_mem=size of KVM shadow MMU\n"
" dump-guest-core=on|off include guest memory in a core dump (default=on)\n"
" mem-merge=on|off controls memory merge support (default: on)\n"
" iommu=on|off controls emulated Intel IOMMU (VT-d) support (default=off)\n",
" iommu=on|off controls emulated Intel IOMMU (VT-d) support (default=off)\n"
" aes-key-wrap=on|off controls support for AES key wrapping (default=on)\n"
" dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n",
QEMU_ARCH_ALL)
STEXI
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
Expand Down Expand Up @@ -66,6 +68,14 @@ the host, de-duplicates identical memory pages among VMs instances
(enabled by default).
@item iommu=on|off
Enables or disables emulated Intel IOMMU (VT-d) support. The default is off.
@item aes-key-wrap=on|off
Enables or disables AES key wrapping support on s390-ccw hosts. This feature
controls whether AES wrapping keys will be created to allow
execution of AES cryptographic functions. The default is on.
@item dea-key-wrap=on|off
Enables or disables DEA key wrapping support on s390-ccw hosts. This feature
controls whether DEA wrapping keys will be created to allow
execution of DEA cryptographic functions. The default is on.
@end table
ETEXI

Expand Down

0 comments on commit 2dfe7d0

Please sign in to comment.