First pile of s390x patches for 2.4, including:

- some cleanup patches
 - sort most of the s390x devices into categories
 - support for the new STSI post handler, used to insert vm name and
   friends
 - support for the new MEM_OP ioctl (including access register mode)
   for accessing guest memory
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJVQhiKAAoJEN7Pa5PG8C+v9fQQAJh+vHKZF1soi7u8Em1RZAKV
 TiuvGwTfEF1ajSpPxRd6JQjKAIAoCJ7yuDJUzJbQOg1fo1EOJHAJHpBz10Cuk0FD
 8ves9+ZirOjAwPNGjC697mqKWzaoxeDFxHyf1HUlstpiYkRR1iaAMUWAdWIz2WE7
 6mvwFV/gNGulyFKjKT47vaela4DTVyymsp8yu37/njNav0bEIF+7zBDiXi1z05lE
 LlzjoDJcRUhk5mnbEnxSszZ2ndSdKSY/xsk+/Ykofapz00F+Bpg85m/+9TNNjSBm
 RfgsmFTD5Qyp0UehawbINejOhTjuIRO5AZVyq3upc5TJy7oGTP/ueFad0HHsM7Nk
 1RrFr7pEVOKVY6a1VMqX2O8w28PTKUzHi5SCmJTyr5ryBGGW3SqeA0742uwQDCDU
 ejm3F97jKgLvpX135zoBUtfu4KbeARmrCiL2x1OPCP7XDEWkz/k2UfP1iR+11BFR
 GQ3cfid3JXKS/5qGfFwJVWPJbMyZbxRn6qCh4ywUMVcKr22KOM653pCfJ65IYbJO
 O0ZMuddHMoOt6TlTlIJ4/V13ZtoPhmGVnfP43I3V4Y4ByFQacDB+JL9n2fxWq/Yk
 loSd/5lhH+HJCWjg6psm9oT1vVd1AgL9GqltFXHTaG8hJHQqwzBUrKNW8DpS/PIj
 ViR0oEPmV+dZQxYM22tR
 =z0Lu
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20150430' into staging

First pile of s390x patches for 2.4, including:
- some cleanup patches
- sort most of the s390x devices into categories
- support for the new STSI post handler, used to insert vm name and
  friends
- support for the new MEM_OP ioctl (including access register mode)
  for accessing guest memory

# gpg: Signature made Thu Apr 30 12:56:58 2015 BST 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-20150430:
  kvm: better advice for failed s390x startup
  s390x/kvm: Support access register mode for KVM_S390_MEM_OP ioctl
  s390x/mmu: Use ioctl for reading and writing from/to guest memory
  s390x/kvm: Put vm name, extended name and UUID into STSI322 SYSIB
  linux-headers: update
  s390x/mmu: Use access type definitions instead of magic values
  s390x/ipl: sort into categories
  sclp: sort into categories
  s390-virtio: sort into categories
  virtio-ccw: sort into categories

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-04-30 14:15:56 +01:00
commit 498147529d
27 changed files with 552 additions and 126 deletions

View file

@ -364,6 +364,7 @@ static void console_class_init(ObjectClass *klass, void *data)
ec->can_handle_event = can_handle_event;
ec->read_event_data = read_event_data;
ec->write_event_data = write_event_data;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo sclp_console_info = {

View file

@ -266,6 +266,7 @@ static void console_class_init(ObjectClass *klass, void *data)
ec->can_handle_event = can_handle_event;
ec->read_event_data = read_event_data;
ec->write_event_data = write_event_data;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo sclp_console_info = {

View file

@ -362,6 +362,7 @@ static void init_event_facility_class(ObjectClass *klass, void *data)
dc->reset = reset_event_facility;
dc->vmsd = &vmstate_event_facility;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
k->init = init_event_facility;
k->command_handler = command_handler;
k->event_pending = event_pending;

View file

@ -315,6 +315,7 @@ static void s390_ipl_class_init(ObjectClass *klass, void *data)
dc->props = s390_ipl_properties;
dc->reset = s390_ipl_reset;
dc->vmsd = &vmstate_ipl;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo s390_ipl_info = {

View file

@ -155,7 +155,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], buffer, sizeof(*reqh))) {
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer, sizeof(*reqh))) {
return 0;
}
reqh = (ClpReqHdr *)buffer;
@ -165,7 +165,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], buffer,
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,
req_len + sizeof(*resh))) {
return 0;
}
@ -180,7 +180,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], buffer,
if (s390_cpu_virt_mem_read(cpu, env->regs[r2], r2, buffer,
req_len + res_len)) {
return 0;
}
@ -277,7 +277,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2)
}
out:
if (s390_cpu_virt_mem_write(cpu, env->regs[r2], buffer,
if (s390_cpu_virt_mem_write(cpu, env->regs[r2], r2, buffer,
req_len + res_len)) {
return 0;
}
@ -546,7 +546,8 @@ out:
return 0;
}
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr)
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
uint8_t ar)
{
CPUS390XState *env = &cpu->env;
S390PCIBusDevice *pbdev;
@ -603,7 +604,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, gaddr, buffer, len)) {
if (s390_cpu_virt_mem_read(cpu, gaddr, ar, buffer, len)) {
return 0;
}
@ -698,7 +699,7 @@ static void dereg_ioat(S390PCIBusDevice *pbdev)
pbdev->g_iota = 0;
}
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
{
CPUS390XState *env = &cpu->env;
uint8_t oc;
@ -727,7 +728,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
return 0;
}
if (s390_cpu_virt_mem_read(cpu, fiba, (uint8_t *)&fib, sizeof(fib))) {
if (s390_cpu_virt_mem_read(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
return 0;
}
@ -773,7 +774,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
return 0;
}
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar)
{
CPUS390XState *env = &cpu->env;
uint32_t fh;
@ -829,7 +830,7 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba)
fib.fc |= 0x10;
}
if (s390_cpu_virt_mem_write(cpu, fiba, (uint8_t *)&fib, sizeof(fib))) {
if (s390_cpu_virt_mem_write(cpu, fiba, ar, (uint8_t *)&fib, sizeof(fib))) {
return 0;
}

View file

@ -281,8 +281,9 @@ int clp_service_call(S390CPU *cpu, uint8_t r2);
int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr);
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba);
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
uint8_t ar);
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar);
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar);
#endif

View file

@ -542,6 +542,7 @@ static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
k->realize = s390_virtio_net_realize;
dc->props = s390_virtio_net_properties;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static const TypeInfo s390_virtio_net = {
@ -555,8 +556,10 @@ static const TypeInfo s390_virtio_net = {
static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
{
VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->realize = s390_virtio_blk_realize;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo s390_virtio_blk = {
@ -578,6 +581,7 @@ static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
k->realize = s390_virtio_serial_realize;
dc->props = s390_virtio_serial_properties;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo s390_virtio_serial = {
@ -600,6 +604,7 @@ static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
k->realize = s390_virtio_rng_realize;
dc->props = s390_virtio_rng_properties;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo s390_virtio_rng = {
@ -658,6 +663,7 @@ static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data)
k->realize = s390_virtio_scsi_realize;
dc->props = s390_virtio_scsi_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo s390_virtio_scsi = {
@ -681,6 +687,7 @@ static void s390_vhost_scsi_class_init(ObjectClass *klass, void *data)
k->realize = s390_vhost_scsi_realize;
dc->props = s390_vhost_scsi_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo s390_vhost_scsi = {
@ -704,8 +711,10 @@ static int s390_virtio_bridge_init(SysBusDevice *dev)
static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = s390_virtio_bridge_init;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
static const TypeInfo s390_virtio_bridge_info = {

View file

@ -457,10 +457,19 @@ sclpMemoryHotplugDev *get_sclp_memory_hotplug_dev(void)
TYPE_SCLP_MEMORY_HOTPLUG_DEV, NULL));
}
static void sclp_memory_hotplug_dev_class_init(ObjectClass *klass,
void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static TypeInfo sclp_memory_hotplug_dev_info = {
.name = TYPE_SCLP_MEMORY_HOTPLUG_DEV,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(sclpMemoryHotplugDev),
.class_init = sclp_memory_hotplug_dev_class_init,
};
static void register_types(void)

View file

@ -88,12 +88,14 @@ static int irq_cpu_hotplug_init(SCLPEvent *event)
static void cpu_class_init(ObjectClass *oc, void *data)
{
SCLPEventClass *k = SCLP_EVENT_CLASS(oc);
DeviceClass *dc = DEVICE_CLASS(oc);
k->init = irq_cpu_hotplug_init;
k->get_send_mask = send_mask;
k->get_receive_mask = receive_mask;
k->read_event_data = read_event_data;
k->write_event_data = NULL;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo sclp_cpu_info = {

View file

@ -116,6 +116,7 @@ static void quiesce_class_init(ObjectClass *klass, void *data)
dc->reset = quiesce_reset;
dc->vmsd = &vmstate_sclpquiesce;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
k->init = quiesce_init;
k->get_send_mask = send_mask;

View file

@ -1453,6 +1453,7 @@ static void virtio_ccw_net_class_init(ObjectClass *klass, void *data)
k->exit = virtio_ccw_exit;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_net_properties;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static const TypeInfo virtio_ccw_net = {
@ -1479,6 +1480,7 @@ static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data)
k->exit = virtio_ccw_exit;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_blk_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo virtio_ccw_blk = {
@ -1505,6 +1507,7 @@ static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data)
k->exit = virtio_ccw_exit;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_serial_properties;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}
static const TypeInfo virtio_ccw_serial = {
@ -1531,6 +1534,7 @@ static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data)
k->exit = virtio_ccw_exit;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_balloon_properties;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo virtio_ccw_balloon = {
@ -1558,6 +1562,7 @@ static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data)
k->exit = virtio_ccw_exit;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_scsi_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo virtio_ccw_scsi = {
@ -1583,6 +1588,7 @@ static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data)
k->exit = virtio_ccw_exit;
dc->reset = virtio_ccw_reset;
dc->props = vhost_ccw_scsi_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo vhost_ccw_scsi = {
@ -1620,6 +1626,7 @@ static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data)
k->exit = virtio_ccw_exit;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_rng_properties;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static const TypeInfo virtio_ccw_rng = {
@ -1706,9 +1713,11 @@ static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = virtual_css_bridge_init;
hc->unplug = virtio_ccw_busdev_unplug;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
static const TypeInfo virtual_css_bridge_info = {

View file

@ -25,6 +25,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. */
#include "standard-headers/linux/types.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_config.h"
@ -51,9 +52,32 @@ struct virtio_balloon_config {
#define VIRTIO_BALLOON_S_MEMTOT 5 /* Total amount of memory */
#define VIRTIO_BALLOON_S_NR 6
/*
* Memory statistics structure.
* Driver fills an array of these structures and passes to device.
*
* NOTE: fields are laid out in a way that would make compiler add padding
* between and after fields, so we have to use compiler-specific attributes to
* pack it, to disable this padding. This also often causes compiler to
* generate suboptimal code.
*
* We maintain this statistics structure format for backwards compatibility,
* but don't follow this example.
*
* If implementing a similar structure, do something like the below instead:
* struct virtio_balloon_stat {
* __virtio16 tag;
* uint8_t reserved[6];
* __virtio64 val;
* };
*
* In other words, add explicit reserved fields to align field and
* structure boundaries at field size, avoiding compiler padding
* without the packed attribute.
*/
struct virtio_balloon_stat {
uint16_t tag;
uint64_t val;
__virtio16 tag;
__virtio64 val;
} QEMU_PACKED;
#endif /* _LINUX_VIRTIO_BALLOON_H */

View file

@ -39,5 +39,6 @@
#define VIRTIO_ID_9P 9 /* 9p virtio console */
#define VIRTIO_ID_RPROC_SERIAL 11 /* virtio remoteproc serial link */
#define VIRTIO_ID_CAIF 12 /* Virtio caif */
#define VIRTIO_ID_INPUT 18 /* virtio input */
#endif /* _LINUX_VIRTIO_IDS_H */

View file

@ -0,0 +1,76 @@
#ifndef _LINUX_VIRTIO_INPUT_H
#define _LINUX_VIRTIO_INPUT_H
/* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of IBM nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. */
#include "standard-headers/linux/types.h"
enum virtio_input_config_select {
VIRTIO_INPUT_CFG_UNSET = 0x00,
VIRTIO_INPUT_CFG_ID_NAME = 0x01,
VIRTIO_INPUT_CFG_ID_SERIAL = 0x02,
VIRTIO_INPUT_CFG_ID_DEVIDS = 0x03,
VIRTIO_INPUT_CFG_PROP_BITS = 0x10,
VIRTIO_INPUT_CFG_EV_BITS = 0x11,
VIRTIO_INPUT_CFG_ABS_INFO = 0x12,
};
struct virtio_input_absinfo {
uint32_t min;
uint32_t max;
uint32_t fuzz;
uint32_t flat;
uint32_t res;
};
struct virtio_input_devids {
uint16_t bustype;
uint16_t vendor;
uint16_t product;
uint16_t version;
};
struct virtio_input_config {
uint8_t select;
uint8_t subsel;
uint8_t size;
uint8_t reserved[5];
union {
char string[128];
uint8_t bitmap[128];
struct virtio_input_absinfo abs;
struct virtio_input_devids ids;
} u;
};
struct virtio_input_event {
uint16_t type;
uint16_t code;
uint32_t value;
};
#endif /* _LINUX_VIRTIO_INPUT_H */

View file

@ -1544,8 +1544,17 @@ static int kvm_init(MachineState *ms)
strerror(-ret));
#ifdef TARGET_S390X
fprintf(stderr, "Please add the 'switch_amode' kernel parameter to "
"your host kernel command line\n");
if (ret == -EINVAL) {
fprintf(stderr,
"Host kernel setup problem detected. Please verify:\n");
fprintf(stderr, "- for kernels supporting the switch_amode or"
" user_mode parameters, whether\n");
fprintf(stderr,
" user space is running in primary address space\n");
fprintf(stderr,
"- for kernels supporting the vm.allocate_pgste sysctl, "
"whether it is enabled\n");
}
#endif
goto err;
}

View file

@ -195,9 +195,16 @@ struct kvm_arch_memory_slot {
#define KVM_ARM_IRQ_CPU_IRQ 0
#define KVM_ARM_IRQ_CPU_FIQ 1
/* Highest supported SPI, from VGIC_NR_IRQS */
/*
* This used to hold the highest supported SPI, but it is now obsolete
* and only here to provide source code level compatibility with older
* userland. The highest SPI number can be set via KVM_DEV_ARM_VGIC_GRP_NR_IRQS.
*/
#define KVM_ARM_IRQ_GIC_MAX 127
/* One single KVM irqchip, ie. the VGIC */
#define KVM_NR_IRQCHIPS 1
/* PSCI interface */
#define KVM_PSCI_FN_BASE 0x95c1ba5e
#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))

View file

@ -188,9 +188,16 @@ struct kvm_arch_memory_slot {
#define KVM_ARM_IRQ_CPU_IRQ 0
#define KVM_ARM_IRQ_CPU_FIQ 1
/* Highest supported SPI, from VGIC_NR_IRQS */
/*
* This used to hold the highest supported SPI, but it is now obsolete
* and only here to provide source code level compatibility with older
* userland. The highest SPI number can be set via KVM_DEV_ARM_VGIC_GRP_NR_IRQS.
*/
#define KVM_ARM_IRQ_GIC_MAX 127
/* One single KVM irqchip, ie. the VGIC */
#define KVM_NR_IRQCHIPS 1
/* PSCI interface */
#define KVM_PSCI_FN_BASE 0x95c1ba5e
#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))

View file

@ -36,77 +36,85 @@ struct kvm_regs {
/*
* for KVM_GET_FPU and KVM_SET_FPU
*
* If Status[FR] is zero (32-bit FPU), the upper 32-bits of the FPRs
* are zero filled.
*/
struct kvm_fpu {
__u64 fpr[32];
__u32 fir;
__u32 fccr;
__u32 fexr;
__u32 fenr;
__u32 fcsr;
__u32 pad;
};
/*
* For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access CP0
* For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various
* registers. The id field is broken down as follows:
*
* bits[2..0] - Register 'sel' index.
* bits[7..3] - Register 'rd' index.
* bits[15..8] - Must be zero.
* bits[31..16] - 1 -> CP0 registers.
* bits[51..32] - Must be zero.
* bits[63..52] - As per linux/kvm.h
* bits[51..32] - Must be zero.
* bits[31..16] - Register set.
*
* Register set = 0: GP registers from kvm_regs (see definitions below).
*
* Register set = 1: CP0 registers.
* bits[15..8] - Must be zero.
* bits[7..3] - Register 'rd' index.
* bits[2..0] - Register 'sel' index.
*
* Register set = 2: KVM specific registers (see definitions below).
*
* Register set = 3: FPU / MSA registers (see definitions below).
*
* Other sets registers may be added in the future. Each set would
* have its own identifier in bits[31..16].
*
* The registers defined in struct kvm_regs are also accessible, the
* id values for these are below.
*/
#define KVM_REG_MIPS_R0 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0)
#define KVM_REG_MIPS_R1 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 1)
#define KVM_REG_MIPS_R2 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 2)
#define KVM_REG_MIPS_R3 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 3)
#define KVM_REG_MIPS_R4 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 4)
#define KVM_REG_MIPS_R5 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 5)
#define KVM_REG_MIPS_R6 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 6)
#define KVM_REG_MIPS_R7 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 7)
#define KVM_REG_MIPS_R8 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 8)
#define KVM_REG_MIPS_R9 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 9)
#define KVM_REG_MIPS_R10 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 10)
#define KVM_REG_MIPS_R11 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 11)
#define KVM_REG_MIPS_R12 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 12)
#define KVM_REG_MIPS_R13 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 13)
#define KVM_REG_MIPS_R14 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 14)
#define KVM_REG_MIPS_R15 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 15)
#define KVM_REG_MIPS_R16 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 16)
#define KVM_REG_MIPS_R17 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 17)
#define KVM_REG_MIPS_R18 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 18)
#define KVM_REG_MIPS_R19 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 19)
#define KVM_REG_MIPS_R20 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 20)
#define KVM_REG_MIPS_R21 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 21)
#define KVM_REG_MIPS_R22 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 22)
#define KVM_REG_MIPS_R23 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 23)
#define KVM_REG_MIPS_R24 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 24)
#define KVM_REG_MIPS_R25 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 25)
#define KVM_REG_MIPS_R26 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 26)
#define KVM_REG_MIPS_R27 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 27)
#define KVM_REG_MIPS_R28 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 28)
#define KVM_REG_MIPS_R29 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 29)
#define KVM_REG_MIPS_R30 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 30)
#define KVM_REG_MIPS_R31 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 31)
#define KVM_REG_MIPS_GP (KVM_REG_MIPS | 0x0000000000000000ULL)
#define KVM_REG_MIPS_CP0 (KVM_REG_MIPS | 0x0000000000010000ULL)
#define KVM_REG_MIPS_KVM (KVM_REG_MIPS | 0x0000000000020000ULL)
#define KVM_REG_MIPS_FPU (KVM_REG_MIPS | 0x0000000000030000ULL)
#define KVM_REG_MIPS_HI (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 32)
#define KVM_REG_MIPS_LO (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 33)
#define KVM_REG_MIPS_PC (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 34)
/* KVM specific control registers */
/*
* KVM_REG_MIPS_GP - General purpose registers from kvm_regs.
*/
#define KVM_REG_MIPS_R0 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 0)
#define KVM_REG_MIPS_R1 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 1)
#define KVM_REG_MIPS_R2 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 2)
#define KVM_REG_MIPS_R3 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 3)
#define KVM_REG_MIPS_R4 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 4)
#define KVM_REG_MIPS_R5 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 5)
#define KVM_REG_MIPS_R6 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 6)
#define KVM_REG_MIPS_R7 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 7)
#define KVM_REG_MIPS_R8 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 8)
#define KVM_REG_MIPS_R9 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 9)
#define KVM_REG_MIPS_R10 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 10)
#define KVM_REG_MIPS_R11 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 11)
#define KVM_REG_MIPS_R12 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 12)
#define KVM_REG_MIPS_R13 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 13)
#define KVM_REG_MIPS_R14 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 14)
#define KVM_REG_MIPS_R15 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 15)
#define KVM_REG_MIPS_R16 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 16)
#define KVM_REG_MIPS_R17 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 17)
#define KVM_REG_MIPS_R18 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 18)
#define KVM_REG_MIPS_R19 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 19)
#define KVM_REG_MIPS_R20 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 20)
#define KVM_REG_MIPS_R21 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 21)
#define KVM_REG_MIPS_R22 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 22)
#define KVM_REG_MIPS_R23 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 23)
#define KVM_REG_MIPS_R24 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 24)
#define KVM_REG_MIPS_R25 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 25)
#define KVM_REG_MIPS_R26 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 26)
#define KVM_REG_MIPS_R27 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 27)
#define KVM_REG_MIPS_R28 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 28)
#define KVM_REG_MIPS_R29 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 29)
#define KVM_REG_MIPS_R30 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 30)
#define KVM_REG_MIPS_R31 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 31)
#define KVM_REG_MIPS_HI (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 32)
#define KVM_REG_MIPS_LO (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 33)
#define KVM_REG_MIPS_PC (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 34)
/*
* KVM_REG_MIPS_KVM - KVM specific control registers.
*/
/*
* CP0_Count control
@ -118,8 +126,7 @@ struct kvm_fpu {
* safely without losing time or guest timer interrupts.
* Other: Reserved, do not change.
*/
#define KVM_REG_MIPS_COUNT_CTL (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
0x20000 | 0)
#define KVM_REG_MIPS_COUNT_CTL (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 0)
#define KVM_REG_MIPS_COUNT_CTL_DC 0x00000001
/*
@ -131,15 +138,46 @@ struct kvm_fpu {
* emulated.
* Modifications to times in the future are rejected.
*/
#define KVM_REG_MIPS_COUNT_RESUME (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
0x20000 | 1)
#define KVM_REG_MIPS_COUNT_RESUME (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 1)
/*
* CP0_Count rate in Hz
* Specifies the rate of the CP0_Count timer in Hz. Modifications occur without
* discontinuities in CP0_Count.
*/
#define KVM_REG_MIPS_COUNT_HZ (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
0x20000 | 2)
#define KVM_REG_MIPS_COUNT_HZ (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 2)
/*
* KVM_REG_MIPS_FPU - Floating Point and MIPS SIMD Architecture (MSA) registers.
*
* bits[15..8] - Register subset (see definitions below).
* bits[7..5] - Must be zero.
* bits[4..0] - Register number within register subset.
*/
#define KVM_REG_MIPS_FPR (KVM_REG_MIPS_FPU | 0x0000000000000000ULL)
#define KVM_REG_MIPS_FCR (KVM_REG_MIPS_FPU | 0x0000000000000100ULL)
#define KVM_REG_MIPS_MSACR (KVM_REG_MIPS_FPU | 0x0000000000000200ULL)
/*
* KVM_REG_MIPS_FPR - Floating point / Vector registers.
*/
#define KVM_REG_MIPS_FPR_32(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U32 | (n))
#define KVM_REG_MIPS_FPR_64(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U64 | (n))
#define KVM_REG_MIPS_VEC_128(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U128 | (n))
/*
* KVM_REG_MIPS_FCR - Floating point control registers.
*/
#define KVM_REG_MIPS_FCR_IR (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 0)
#define KVM_REG_MIPS_FCR_CSR (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 31)
/*
* KVM_REG_MIPS_MSACR - MIPS SIMD Architecture (MSA) control registers.
*/
#define KVM_REG_MIPS_MSA_IR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 | 0)
#define KVM_REG_MIPS_MSA_CSR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 | 1)
/*
* KVM MIPS specific structures and definitions

View file

@ -150,6 +150,7 @@ struct kvm_guest_debug_arch {
#define KVM_SYNC_CRS (1UL << 3)
#define KVM_SYNC_ARCH0 (1UL << 4)
#define KVM_SYNC_PFAULT (1UL << 5)
#define KVM_SYNC_VRS (1UL << 6)
/* definition of registers in kvm_run */
struct kvm_sync_regs {
__u64 prefix; /* prefix register */
@ -164,6 +165,9 @@ struct kvm_sync_regs {
__u64 pft; /* pfault token [PFAULT] */
__u64 pfs; /* pfault select [PFAULT] */
__u64 pfc; /* pfault compare [PFAULT] */
__u64 vrs[32][2]; /* vector registers */
__u8 reserved[512]; /* for future vector expansion */
__u32 fpc; /* only valid with vector registers */
};
#define KVM_REG_S390_TODPR (KVM_REG_S390 | KVM_REG_SIZE_U32 | 0x1)

View file

@ -225,6 +225,8 @@
#define HV_STATUS_INVALID_HYPERCALL_CODE 2
#define HV_STATUS_INVALID_HYPERCALL_INPUT 3
#define HV_STATUS_INVALID_ALIGNMENT 4
#define HV_STATUS_INSUFFICIENT_MEMORY 11
#define HV_STATUS_INVALID_CONNECTION_ID 18
#define HV_STATUS_INSUFFICIENT_BUFFERS 19
typedef struct _HV_REFERENCE_TSC_PAGE {

View file

@ -147,6 +147,16 @@ struct kvm_pit_config {
#define KVM_PIT_SPEAKER_DUMMY 1
struct kvm_s390_skeys {
__u64 start_gfn;
__u64 count;
__u64 skeydata_addr;
__u32 flags;
__u32 reserved[9];
};
#define KVM_S390_GET_SKEYS_NONE 1
#define KVM_S390_SKEYS_MAX 1048576
#define KVM_EXIT_UNKNOWN 0
#define KVM_EXIT_EXCEPTION 1
#define KVM_EXIT_IO 2
@ -172,6 +182,7 @@ struct kvm_pit_config {
#define KVM_EXIT_S390_TSCH 22
#define KVM_EXIT_EPR 23
#define KVM_EXIT_SYSTEM_EVENT 24
#define KVM_EXIT_S390_STSI 25
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@ -309,6 +320,15 @@ struct kvm_run {
__u32 type;
__u64 flags;
} system_event;
/* KVM_EXIT_S390_STSI */
struct {
__u64 addr;
__u8 ar;
__u8 reserved;
__u8 fc;
__u8 sel1;
__u16 sel2;
} s390_stsi;
/* Fix the size of the union. */
char padding[256];
};
@ -324,7 +344,7 @@ struct kvm_run {
__u64 kvm_dirty_regs;
union {
struct kvm_sync_regs regs;
char padding[1024];
char padding[2048];
} s;
};
@ -365,6 +385,24 @@ struct kvm_translation {
__u8 pad[5];
};
/* for KVM_S390_MEM_OP */
struct kvm_s390_mem_op {
/* in */
__u64 gaddr; /* the guest address */
__u64 flags; /* flags */
__u32 size; /* amount of bytes */
__u32 op; /* type of operation */
__u64 buf; /* buffer in userspace */
__u8 ar; /* the access register number */
__u8 reserved[31]; /* should be set to 0 */
};
/* types for kvm_s390_mem_op->op */
#define KVM_S390_MEMOP_LOGICAL_READ 0
#define KVM_S390_MEMOP_LOGICAL_WRITE 1
/* flags for kvm_s390_mem_op->flags */
#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
/* for KVM_INTERRUPT */
struct kvm_interrupt {
/* in */
@ -520,6 +558,13 @@ struct kvm_s390_irq {
} u;
};
struct kvm_s390_irq_state {
__u64 buf;
__u32 flags;
__u32 len;
__u32 reserved[4];
};
/* for KVM_SET_GUEST_DEBUG */
#define KVM_GUESTDBG_ENABLE 0x00000001
@ -760,6 +805,15 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_PPC_ENABLE_HCALL 104
#define KVM_CAP_CHECK_EXTENSION_VM 105
#define KVM_CAP_S390_USER_SIGP 106
#define KVM_CAP_S390_VECTOR_REGISTERS 107
#define KVM_CAP_S390_MEM_OP 108
#define KVM_CAP_S390_USER_STSI 109
#define KVM_CAP_S390_SKEYS 110
#define KVM_CAP_MIPS_FPU 111
#define KVM_CAP_MIPS_MSA 112
#define KVM_CAP_S390_INJECT_IRQ 113
#define KVM_CAP_S390_IRQ_STATE 114
#define KVM_CAP_PPC_HWRNG 115
#ifdef KVM_CAP_IRQ_ROUTING
@ -1135,6 +1189,16 @@ struct kvm_s390_ucas_mapping {
#define KVM_ARM_VCPU_INIT _IOW(KVMIO, 0xae, struct kvm_vcpu_init)
#define KVM_ARM_PREFERRED_TARGET _IOR(KVMIO, 0xaf, struct kvm_vcpu_init)
#define KVM_GET_REG_LIST _IOWR(KVMIO, 0xb0, struct kvm_reg_list)
/* Available with KVM_CAP_S390_MEM_OP */
#define KVM_S390_MEM_OP _IOW(KVMIO, 0xb1, struct kvm_s390_mem_op)
/* Available with KVM_CAP_S390_SKEYS */
#define KVM_S390_GET_SKEYS _IOW(KVMIO, 0xb2, struct kvm_s390_skeys)
#define KVM_S390_SET_SKEYS _IOW(KVMIO, 0xb3, struct kvm_s390_skeys)
/* Available with KVM_CAP_S390_INJECT_IRQ */
#define KVM_S390_IRQ _IOW(KVMIO, 0xb4, struct kvm_s390_irq)
/* Available with KVM_CAP_S390_IRQ_STATE */
#define KVM_S390_SET_IRQ_STATE _IOW(KVMIO, 0xb5, struct kvm_s390_irq_state)
#define KVM_S390_GET_IRQ_STATE _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state)
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)

View file

@ -160,6 +160,8 @@ struct vfio_device_info {
__u32 flags;
#define VFIO_DEVICE_FLAGS_RESET (1 << 0) /* Device supports reset */
#define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */
#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2) /* vfio-platform device */
#define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */
__u32 num_regions; /* Max region index + 1 */
__u32 num_irqs; /* Max IRQ index + 1 */
};

View file

@ -356,7 +356,8 @@ int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
#ifndef CONFIG_USER_ONLY
void do_restart_interrupt(CPUS390XState *env);
static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb)
static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb,
uint8_t *ar)
{
hwaddr addr = 0;
uint8_t reg;
@ -366,6 +367,9 @@ static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb)
addr = env->regs[reg];
}
addr += (ipb >> 16) & 0xfff;
if (ar) {
*ar = reg;
}
return addr;
}
@ -401,6 +405,8 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq);
int kvm_s390_inject_flic(struct kvm_s390_irq *irq);
void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
int len, bool is_write);
int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_clock);
int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_clock);
#else
@ -418,6 +424,11 @@ static inline int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_low)
{
return -ENOSYS;
}
static inline int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar,
void *hostbuf, int len, bool is_write)
{
return -ENOSYS;
}
static inline void kvm_s390_access_exception(S390CPU *cpu, uint16_t code,
uint64_t te_code)
{
@ -865,9 +876,13 @@ struct sysib_322 {
uint8_t name[8];
uint32_t caf;
uint8_t cpi[16];
uint8_t res3[24];
uint8_t res5[3];
uint8_t ext_name_encoding;
uint32_t res3;
uint8_t uuid[16];
} vm[8];
uint8_t res4[3552];
uint8_t res4[1504];
uint8_t ext_names[8][256];
};
/* MMU defines */
@ -952,15 +967,15 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code);
uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
uint64_t vr);
int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, void *hostbuf, int len,
bool is_write);
int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
int len, bool is_write);
#define s390_cpu_virt_mem_read(cpu, laddr, dest, len) \
s390_cpu_virt_mem_rw(cpu, laddr, dest, len, false)
#define s390_cpu_virt_mem_write(cpu, laddr, dest, len) \
s390_cpu_virt_mem_rw(cpu, laddr, dest, len, true)
#define s390_cpu_virt_mem_check_write(cpu, laddr, len) \
s390_cpu_virt_mem_rw(cpu, laddr, NULL, len, true)
#define s390_cpu_virt_mem_read(cpu, laddr, ar, dest, len) \
s390_cpu_virt_mem_rw(cpu, laddr, ar, dest, len, false)
#define s390_cpu_virt_mem_write(cpu, laddr, ar, dest, len) \
s390_cpu_virt_mem_rw(cpu, laddr, ar, dest, len, true)
#define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len) \
s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true)
/* The value of the TOD clock for 1.1.1970. */
#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL

View file

@ -162,7 +162,7 @@ hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
vaddr &= 0x7fffffff;
}
mmu_translate(env, vaddr, 2, asc, &raddr, &prot, false);
mmu_translate(env, vaddr, MMU_INST_FETCH, asc, &raddr, &prot, false);
return raddr;
}

View file

@ -149,13 +149,14 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
int ret = -ENODEV;
int cc;
CPUS390XState *env = &cpu->env;
uint8_t ar;
addr = decode_basedisp_s(env, ipb);
addr = decode_basedisp_s(env, ipb, &ar);
if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2);
return;
}
if (s390_cpu_virt_mem_read(cpu, addr, &schib, sizeof(schib))) {
if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
return;
}
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
@ -215,13 +216,14 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
int ret = -ENODEV;
int cc;
CPUS390XState *env = &cpu->env;
uint8_t ar;
addr = decode_basedisp_s(env, ipb);
addr = decode_basedisp_s(env, ipb, &ar);
if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2);
return;
}
if (s390_cpu_virt_mem_read(cpu, addr, &orig_orb, sizeof(orb))) {
if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
return;
}
copy_orb_from_guest(&orb, &orig_orb);
@ -258,8 +260,9 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb)
uint64_t addr;
int cc;
CPUS390XState *env = &cpu->env;
uint8_t ar;
addr = decode_basedisp_s(env, ipb);
addr = decode_basedisp_s(env, ipb, &ar);
if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2);
return;
@ -268,7 +271,7 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb)
cc = css_do_stcrw(&crw);
/* 0 - crw stored, 1 - zeroes stored */
if (s390_cpu_virt_mem_write(cpu, addr, &crw, sizeof(crw)) == 0) {
if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
setcc(cpu, cc);
} else if (cc == 0) {
/* Write failed: requeue CRW since STCRW is a suppressing instruction */
@ -284,8 +287,9 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
int cc;
SCHIB schib;
CPUS390XState *env = &cpu->env;
uint8_t ar;
addr = decode_basedisp_s(env, ipb);
addr = decode_basedisp_s(env, ipb, &ar);
if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2);
return;
@ -297,7 +301,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
* we check whether the memory area is writeable (injecting the
* access execption if it is not) first.
*/
if (!s390_cpu_virt_mem_check_write(cpu, addr, sizeof(schib))) {
if (!s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib))) {
program_interrupt(env, PGM_OPERAND, 2);
}
return;
@ -322,12 +326,13 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
}
}
if (cc != 3) {
if (s390_cpu_virt_mem_write(cpu, addr, &schib, sizeof(schib)) != 0) {
if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
sizeof(schib)) != 0) {
return;
}
} else {
/* Access exceptions have a higher priority than cc3 */
if (s390_cpu_virt_mem_check_write(cpu, addr, sizeof(schib)) != 0) {
if (s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
return;
}
}
@ -342,13 +347,14 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
IRB irb;
uint64_t addr;
int cc, irb_len;
uint8_t ar;
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
program_interrupt(env, PGM_OPERAND, 2);
return -EIO;
}
trace_ioinst_sch_id("tsch", cssid, ssid, schid);
addr = decode_basedisp_s(env, ipb);
addr = decode_basedisp_s(env, ipb, &ar);
if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2);
return -EIO;
@ -362,14 +368,14 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
}
/* 0 - status pending, 1 - not status pending, 3 - not operational */
if (cc != 3) {
if (s390_cpu_virt_mem_write(cpu, addr, &irb, irb_len) != 0) {
if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
return -EFAULT;
}
css_do_tsch_update_subch(sch);
} else {
irb_len = sizeof(irb) - sizeof(irb.emw);
/* Access exceptions have a higher priority than cc3 */
if (s390_cpu_virt_mem_check_write(cpu, addr, irb_len) != 0) {
if (s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
return -EFAULT;
}
}
@ -645,7 +651,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb)
* present CHSC sub-handlers ... if we ever need more, we should take
* care of req->len here first.
*/
if (s390_cpu_virt_mem_read(cpu, addr, buf, sizeof(ChscReq))) {
if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
return;
}
req = (ChscReq *)buf;
@ -677,7 +683,8 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb)
break;
}
if (!s390_cpu_virt_mem_write(cpu, addr + len, res, be16_to_cpu(res->len))) {
if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
be16_to_cpu(res->len))) {
setcc(cpu, 0); /* Command execution complete */
}
}
@ -690,9 +697,10 @@ int ioinst_handle_tpi(S390CPU *cpu, uint32_t ipb)
IOIntCode int_code;
hwaddr len;
int ret;
uint8_t ar;
trace_ioinst("tpi");
addr = decode_basedisp_s(env, ipb);
addr = decode_basedisp_s(env, ipb, &ar);
if (addr & 3) {
program_interrupt(env, PGM_SPECIFICATION, 2);
return -EIO;
@ -702,7 +710,7 @@ int ioinst_handle_tpi(S390CPU *cpu, uint32_t ipb)
len = lowcore ? 8 /* two words */ : 12 /* three words */;
ret = css_do_tpi(&int_code, lowcore);
if (ret == 1) {
s390_cpu_virt_mem_write(cpu, lowcore ? 184 : addr, &int_code, len);
s390_cpu_virt_mem_write(cpu, lowcore ? 184 : addr, ar, &int_code, len);
}
return ret;
}

View file

@ -44,6 +44,7 @@
#include "hw/s390x/s390-pci-inst.h"
#include "hw/s390x/s390-pci-bus.h"
#include "hw/s390x/ipl.h"
#include "hw/s390x/ebcdic.h"
/* #define DEBUG_KVM */
@ -122,6 +123,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
static int cap_sync_regs;
static int cap_async_pf;
static int cap_mem_op;
static void *legacy_s390_alloc(size_t size, uint64_t *align);
@ -246,6 +248,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
{
cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
kvm_s390_enable_cmma(s);
@ -255,6 +258,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
}
kvm_vm_enable_cap(s, KVM_CAP_S390_USER_SIGP, 0);
kvm_vm_enable_cap(s, KVM_CAP_S390_USER_STSI, 0);
return 0;
}
@ -548,6 +552,46 @@ int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_low)
return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
}
/**
* kvm_s390_mem_op:
* @addr: the logical start address in guest memory
* @ar: the access register number
* @hostbuf: buffer in host memory. NULL = do only checks w/o copying
* @len: length that should be transfered
* @is_write: true = write, false = read
* Returns: 0 on success, non-zero if an exception or error occured
*
* Use KVM ioctl to read/write from/to guest memory. An access exception
* is injected into the vCPU in case of translation errors.
*/
int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
int len, bool is_write)
{
struct kvm_s390_mem_op mem_op = {
.gaddr = addr,
.flags = KVM_S390_MEMOP_F_INJECT_EXCEPTION,
.size = len,
.op = is_write ? KVM_S390_MEMOP_LOGICAL_WRITE
: KVM_S390_MEMOP_LOGICAL_READ,
.buf = (uint64_t)hostbuf,
.ar = ar,
};
int ret;
if (!cap_mem_op) {
return -ENOSYS;
}
if (!hostbuf) {
mem_op.flags |= KVM_S390_MEMOP_F_CHECK_ONLY;
}
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op);
if (ret < 0) {
error_printf("KVM_S390_MEM_OP failed: %s\n", strerror(-ret));
}
return ret;
}
/*
* Legacy layout for s390:
* Older S390 KVM requires the topmost vma of the RAM to be
@ -975,7 +1019,8 @@ static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
return rc;
}
static uint64_t get_base_disp_rxy(S390CPU *cpu, struct kvm_run *run)
static uint64_t get_base_disp_rxy(S390CPU *cpu, struct kvm_run *run,
uint8_t *ar)
{
CPUS390XState *env = &cpu->env;
uint32_t x2 = (run->s390_sieic.ipa & 0x000f);
@ -986,12 +1031,16 @@ static uint64_t get_base_disp_rxy(S390CPU *cpu, struct kvm_run *run)
if (disp2 & 0x80000) {
disp2 += 0xfff00000;
}
if (ar) {
*ar = base2;
}
return (base2 ? env->regs[base2] : 0) +
(x2 ? env->regs[x2] : 0) + (long)(int)disp2;
}
static uint64_t get_base_disp_rsy(S390CPU *cpu, struct kvm_run *run)
static uint64_t get_base_disp_rsy(S390CPU *cpu, struct kvm_run *run,
uint8_t *ar)
{
CPUS390XState *env = &cpu->env;
uint32_t base2 = run->s390_sieic.ipb >> 28;
@ -1001,6 +1050,9 @@ static uint64_t get_base_disp_rsy(S390CPU *cpu, struct kvm_run *run)
if (disp2 & 0x80000) {
disp2 += 0xfff00000;
}
if (ar) {
*ar = base2;
}
return (base2 ? env->regs[base2] : 0) + (long)(int)disp2;
}
@ -1032,11 +1084,12 @@ static int kvm_stpcifc_service_call(S390CPU *cpu, struct kvm_run *run)
{
uint8_t r1 = (run->s390_sieic.ipa & 0x00f0) >> 4;
uint64_t fiba;
uint8_t ar;
cpu_synchronize_state(CPU(cpu));
fiba = get_base_disp_rxy(cpu, run);
fiba = get_base_disp_rxy(cpu, run, &ar);
return stpcifc_service_call(cpu, r1, fiba);
return stpcifc_service_call(cpu, r1, fiba, ar);
}
static int kvm_sic_service_call(S390CPU *cpu, struct kvm_run *run)
@ -1058,22 +1111,24 @@ static int kvm_pcistb_service_call(S390CPU *cpu, struct kvm_run *run)
uint8_t r1 = (run->s390_sieic.ipa & 0x00f0) >> 4;
uint8_t r3 = run->s390_sieic.ipa & 0x000f;
uint64_t gaddr;
uint8_t ar;
cpu_synchronize_state(CPU(cpu));
gaddr = get_base_disp_rsy(cpu, run);
gaddr = get_base_disp_rsy(cpu, run, &ar);
return pcistb_service_call(cpu, r1, r3, gaddr);
return pcistb_service_call(cpu, r1, r3, gaddr, ar);
}
static int kvm_mpcifc_service_call(S390CPU *cpu, struct kvm_run *run)
{
uint8_t r1 = (run->s390_sieic.ipa & 0x00f0) >> 4;
uint64_t fiba;
uint8_t ar;
cpu_synchronize_state(CPU(cpu));
fiba = get_base_disp_rxy(cpu, run);
fiba = get_base_disp_rxy(cpu, run, &ar);
return mpcifc_service_call(cpu, r1, fiba);
return mpcifc_service_call(cpu, r1, fiba, ar);
}
static int handle_b9(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
@ -1202,7 +1257,7 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb)
* For any diagnose call we support, bits 48-63 of the resulting
* address specify the function code; the remainder is ignored.
*/
func_code = decode_basedisp_rs(&cpu->env, ipb) & DIAG_KVM_CODE_MASK;
func_code = decode_basedisp_rs(&cpu->env, ipb, NULL) & DIAG_KVM_CODE_MASK;
switch (func_code) {
case DIAG_IPL:
kvm_handle_diag_308(cpu, run);
@ -1549,7 +1604,8 @@ static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
cpu_synchronize_state(CPU(cpu));
/* get order code */
order = decode_basedisp_rs(env, run->s390_sieic.ipb) & SIGP_ORDER_MASK;
order = decode_basedisp_rs(env, run->s390_sieic.ipb, NULL)
& SIGP_ORDER_MASK;
status_reg = &env->regs[r1];
param = (r1 % 2) ? env->regs[r1] : env->regs[r1 + 1];
@ -1723,6 +1779,72 @@ static int handle_tsch(S390CPU *cpu)
return ret;
}
static void insert_stsi_3_2_2(S390CPU *cpu, __u64 addr, uint8_t ar)
{
struct sysib_322 sysib;
int del;
if (s390_cpu_virt_mem_read(cpu, addr, ar, &sysib, sizeof(sysib))) {
return;
}
/* Shift the stack of Extended Names to prepare for our own data */
memmove(&sysib.ext_names[1], &sysib.ext_names[0],
sizeof(sysib.ext_names[0]) * (sysib.count - 1));
/* First virt level, that doesn't provide Ext Names delimits stack. It is
* assumed it's not capable of managing Extended Names for lower levels.
*/
for (del = 1; del < sysib.count; del++) {
if (!sysib.vm[del].ext_name_encoding || !sysib.ext_names[del][0]) {
break;
}
}
if (del < sysib.count) {
memset(sysib.ext_names[del], 0,
sizeof(sysib.ext_names[0]) * (sysib.count - del));
}
/* Insert short machine name in EBCDIC, padded with blanks */
if (qemu_name) {
memset(sysib.vm[0].name, 0x40, sizeof(sysib.vm[0].name));
ebcdic_put(sysib.vm[0].name, qemu_name, MIN(sizeof(sysib.vm[0].name),
strlen(qemu_name)));
}
sysib.vm[0].ext_name_encoding = 2; /* 2 = UTF-8 */
memset(sysib.ext_names[0], 0, sizeof(sysib.ext_names[0]));
/* If hypervisor specifies zero Extended Name in STSI322 SYSIB, it's
* considered by s390 as not capable of providing any Extended Name.
* Therefore if no name was specified on qemu invocation, we go with the
* same "KVMguest" default, which KVM has filled into short name field.
*/
if (qemu_name) {
strncpy((char *)sysib.ext_names[0], qemu_name,
sizeof(sysib.ext_names[0]));
} else {
strcpy((char *)sysib.ext_names[0], "KVMguest");
}
/* Insert UUID */
memcpy(sysib.vm[0].uuid, qemu_uuid, sizeof(sysib.vm[0].uuid));
s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, sizeof(sysib));
}
static int handle_stsi(S390CPU *cpu)
{
CPUState *cs = CPU(cpu);
struct kvm_run *run = cs->kvm_run;
switch (run->s390_stsi.fc) {
case 3:
if (run->s390_stsi.sel1 != 2 || run->s390_stsi.sel2 != 2) {
return 0;
}
/* Only sysib 3.2.2 needs post-handling for now. */
insert_stsi_3_2_2(cpu, run->s390_stsi.addr, run->s390_stsi.ar);
return 0;
default:
return 0;
}
}
static int kvm_arch_handle_debug_exit(S390CPU *cpu)
{
CPUState *cs = CPU(cpu);
@ -1772,6 +1894,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
case KVM_EXIT_S390_TSCH:
ret = handle_tsch(cpu);
break;
case KVM_EXIT_S390_STSI:
ret = handle_stsi(cpu);
break;
case KVM_EXIT_DEBUG:
ret = kvm_arch_handle_debug_exit(cpu);
break;

View file

@ -68,7 +68,7 @@ static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
{
uint64_t tec;
tec = vaddr | (rw == 1 ? FS_WRITE : FS_READ) | 4 | asc >> 46;
tec = vaddr | (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ) | 4 | asc >> 46;
DPRINTF("%s: trans_exc_code=%016" PRIx64 "\n", __func__, tec);
@ -85,7 +85,7 @@ static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
int ilen = ILEN_LATER;
uint64_t tec;
tec = vaddr | (rw == 1 ? FS_WRITE : FS_READ) | asc >> 46;
tec = vaddr | (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ) | asc >> 46;
DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
@ -94,7 +94,7 @@ static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
}
/* Code accesses have an undefined ilc. */
if (rw == 2) {
if (rw == MMU_INST_FETCH) {
ilen = 2;
}
@ -288,7 +288,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
r = mmu_translate_region(env, vaddr, asc, asce, level, raddr, flags, rw,
exc);
if ((rw == 1) && !(*flags & PAGE_WRITE)) {
if (rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE)) {
trigger_prot_fault(env, vaddr, asc, rw, exc);
return -1;
}
@ -338,7 +338,7 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
* Instruction: Primary
* Data: Secondary
*/
if (rw == 2) {
if (rw == MMU_INST_FETCH) {
r = mmu_translate_asce(env, vaddr, PSW_ASC_PRIMARY, env->cregs[1],
raddr, flags, rw, exc);
*flags &= ~(PAGE_READ | PAGE_WRITE);
@ -435,6 +435,7 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
/**
* s390_cpu_virt_mem_rw:
* @laddr: the logical start address
* @ar: the access register number
* @hostbuf: buffer in host memory. NULL = do only checks w/o copying
* @len: length that should be transfered
* @is_write: true = write, false = read
@ -443,13 +444,20 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
* Copy from/to guest memory using logical addresses. Note that we inject a
* program interrupt in case there is an error while accessing the memory.
*/
int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, void *hostbuf,
int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
int len, bool is_write)
{
int currlen, nr_pages, i;
target_ulong *pages;
int ret;
if (kvm_enabled()) {
ret = kvm_s390_mem_op(cpu, laddr, ar, hostbuf, len, is_write);
if (ret >= 0) {
return ret;
}
}
nr_pages = (((laddr & ~TARGET_PAGE_MASK) + len - 1) >> TARGET_PAGE_BITS)
+ 1;
pages = g_malloc(nr_pages * sizeof(*pages));