[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 8/8] s390: Add new channel I/O based virtio tran
From: |
Cornelia Huck |
Subject: |
Re: [Qemu-devel] [PATCH 8/8] s390: Add new channel I/O based virtio transport. |
Date: |
Wed, 16 Jan 2013 14:58:17 +0100 |
On Wed, 16 Jan 2013 14:53:06 +0100
Alexander Graf <address@hidden> wrote:
>
> On 16.01.2013, at 14:24, Alexander Graf wrote:
>
> >
> > On 07.12.2012, at 13:50, Cornelia Huck wrote:
> >
> >> Add a new virtio transport that uses channel commands to perform
> >> virtio operations.
> >>
> >> Add a new machine type s390-ccw that uses this virtio-ccw transport
> >> and make it the default machine for s390.
> >>
> >> Signed-off-by: Cornelia Huck <address@hidden>
> >> ---
> >> hw/s390-virtio.c | 149 ++++++--
> >> hw/s390x/Makefile.objs | 1 +
> >> hw/s390x/virtio-ccw.c | 909
> >> +++++++++++++++++++++++++++++++++++++++++++++++++
> >> hw/s390x/virtio-ccw.h | 81 +++++
> >> trace-events | 4 +
> >> 5 files changed, 1124 insertions(+), 20 deletions(-)
> >> create mode 100644 hw/s390x/virtio-ccw.c
> >> create mode 100644 hw/s390x/virtio-ccw.h
> >>
> >> diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
> >> index 9e1afb2..f29ff74 100644
> >> --- a/hw/s390-virtio.c
> >> +++ b/hw/s390-virtio.c
> >> @@ -33,6 +33,8 @@
> >>
> >> #include "hw/s390-virtio-bus.h"
> >> #include "hw/s390x/sclp.h"
> >> +#include "hw/s390x/css.h"
> >> +#include "hw/s390x/virtio-ccw.h"
> >>
> >> //#define DEBUG_S390
> >>
> >> @@ -47,6 +49,7 @@
> >> #define KVM_S390_VIRTIO_NOTIFY 0
> >> #define KVM_S390_VIRTIO_RESET 1
> >> #define KVM_S390_VIRTIO_SET_STATUS 2
> >> +#define KVM_S390_VIRTIO_CCW_NOTIFY 3
> >>
> >> #define KERN_IMAGE_START 0x010000UL
> >> #define KERN_PARM_AREA 0x010480UL
> >> @@ -63,6 +66,7 @@
> >>
> >> static VirtIOS390Bus *s390_bus;
> >> static S390CPU **ipi_states;
> >> +VirtioCcwBus *ccw_bus;
> >>
> >> S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
> >> {
> >> @@ -76,15 +80,21 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
> >> int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t
> >> hypercall)
> >> {
> >> int r = 0, i;
> >> + int cssid, ssid, schid, m;
> >> + SubchDev *sch;
> >>
> >> dprintf("KVM hypercall: %ld\n", hypercall);
> >> switch (hypercall) {
> >> case KVM_S390_VIRTIO_NOTIFY:
> >> if (mem > ram_size) {
> >> - VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
> >> - mem, &i);
> >> - if (dev) {
> >> - virtio_queue_notify(dev->vdev, i);
> >> + if (s390_bus) {
> >> + VirtIOS390Device *dev =
> >> s390_virtio_bus_find_vring(s390_bus,
> >> + mem,
> >> &i);
> >> + if (dev) {
> >> + virtio_queue_notify(dev->vdev, i);
> >> + } else {
> >> + r = -EINVAL;
> >> + }
> >> } else {
> >> r = -EINVAL;
> >> }
> >> @@ -93,28 +103,49 @@ int s390_virtio_hypercall(CPUS390XState *env,
> >> uint64_t mem, uint64_t hypercall)
> >> }
> >> break;
> >> case KVM_S390_VIRTIO_RESET:
> >> - {
> >> - VirtIOS390Device *dev;
> >> -
> >> - dev = s390_virtio_bus_find_mem(s390_bus, mem);
> >> - virtio_reset(dev->vdev);
> >> - stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
> >> - s390_virtio_device_sync(dev);
> >> - s390_virtio_reset_idx(dev);
> >> + if (s390_bus) {
> >> + VirtIOS390Device *dev;
> >> +
> >> + dev = s390_virtio_bus_find_mem(s390_bus, mem);
> >> + virtio_reset(dev->vdev);
> >> + stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
> >> + s390_virtio_device_sync(dev);
> >> + s390_virtio_reset_idx(dev);
> >> + } else {
> >> + r = -EINVAL;
> >> + }
> >> break;
> >> - }
> >> case KVM_S390_VIRTIO_SET_STATUS:
> >> - {
> >> - VirtIOS390Device *dev;
> >> + if (s390_bus) {
> >> + VirtIOS390Device *dev;
> >>
> >> - dev = s390_virtio_bus_find_mem(s390_bus, mem);
> >> - if (dev) {
> >> - s390_virtio_device_update_status(dev);
> >> + dev = s390_virtio_bus_find_mem(s390_bus, mem);
> >> + if (dev) {
> >> + s390_virtio_device_update_status(dev);
> >> + } else {
> >> + r = -EINVAL;
> >> + }
> >> } else {
> >> r = -EINVAL;
> >> }
> >> break;
> >> - }
> >> + case KVM_S390_VIRTIO_CCW_NOTIFY:
> >> + if (ccw_bus) {
> >> + if (ioinst_disassemble_sch_ident(env->regs[2], &m, &cssid,
> >> &ssid,
> >> + &schid)) {
> >> + r = -EINVAL;
> >> + } else {
> >> + sch = css_find_subch(m, cssid, ssid, schid);
> >> + if (sch && css_subch_visible(sch)) {
> >> + virtio_queue_notify(virtio_ccw_get_vdev(sch),
> >> env->regs[3]);
> >> + } else {
> >> + r = -EINVAL;
> >> + }
> >> + }
> >> + } else {
> >> + r = -EINVAL;
> >> + }
> >> + break;
> >> default:
> >> r = -EINVAL;
> >> break;
> >> @@ -370,7 +401,6 @@ static QEMUMachine s390_machine = {
> >> .no_sdcard = 1,
> >> .use_virtcon = 1,
> >> .max_cpus = 255,
> >> - .is_default = 1,
> >> };
> >>
> >> static void s390_machine_init(void)
> >> @@ -379,3 +409,82 @@ static void s390_machine_init(void)
> >> }
> >>
> >> machine_init(s390_machine_init);
> >> +
> >> +static void ccw_init(QEMUMachineInitArgs *args)
> >> +{
> >> + ram_addr_t my_ram_size = args->ram_size;
> >> + ram_addr_t ram_size = args->ram_size;
> >> + const char *cpu_model = args->cpu_model;
> >> + const char *kernel_filename = args->kernel_filename;
> >> + const char *kernel_cmdline = args->kernel_cmdline;
> >> + const char *initrd_filename = args->initrd_filename;
> >> + CPUS390XState *env = NULL;
> >> + MemoryRegion *sysmem = get_system_memory();
> >> + MemoryRegion *ram = g_new(MemoryRegion, 1);
> >> + int shift = 0;
> >> + uint8_t *storage_keys;
> >> + int ret;
> >> +
> >> + /* s390x ram size detection needs a 16bit multiplier + an increment.
> >> So
> >> + guests > 64GB can be specified in 2MB steps etc. */
> >> + while ((my_ram_size >> (20 + shift)) > 65535) {
> >> + shift++;
> >> + }
> >> + my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);
> >> +
> >> + /* lets propagate the changed ram size into the global variable. */
> >> + ram_size = my_ram_size;
> >> +
> >> + /* get a BUS */
> >> + ccw_bus = virtio_ccw_bus_init();
> >> + s390_sclp_init();
> >> +
> >> + /* allocate RAM */
> >> + memory_region_init_ram(ram, "s390.ram", my_ram_size);
> >> + vmstate_register_ram_global(ram);
> >> + memory_region_add_subregion(sysmem, 0, ram);
> >> +
> >> + /* allocate storage keys */
> >> + storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);
> >> +
> >> + /* init CPUs */
> >> + env = s390_init_cpus(cpu_model, storage_keys);
> >> +
> >> + kvm_s390_enable_css_support(env);
> >> +
> >> + /*
> >> + * Create virtual css and set it as default so that non mcss-e
> >> + * enabled guests only see virtio devices.
> >> + */
> >> + ret = css_create_css_image(VIRTUAL_CSSID, true);
> >> + assert(ret == 0);
> >> +
> >> +
> >> + s390_set_up_kernel(env, kernel_filename, kernel_cmdline,
> >> initrd_filename);
> >> +
> >> + /* Create VirtIO network adapters */
> >> + s390_create_virtio_net((BusState *)ccw_bus, "virtio-net-ccw");
> >> +
> >> +}
> >> +
> >> +static QEMUMachine ccw_machine = {
> >> + .name = "s390-ccw-virtio",
> >> + .alias = "s390-ccw",
> >> + .desc = "VirtIO-ccw based S390 machine",
> >> + .init = ccw_init,
> >> + .no_cdrom = 1,
> >> + .no_floppy = 1,
> >> + .no_serial = 1,
> >> + .no_parallel = 1,
> >> + .no_sdcard = 1,
> >> + .use_virtcon = 1,
> >
> > The ccw machine should use the ASCII console as default.
>
> In fact, here is a patch doing this based on the code base that this patch
> set was on. It would be nice to include this for the next round of the
> virtio-ccw machine.
Yes. It's sometimes a bit hard to keep track of things :)
>
>
> Alex
>
> diff --git a/hw/boards.h b/hw/boards.h
> index 813d0e5..7ab634a 100644
> --- a/hw/boards.h
> +++ b/hw/boards.h
> @@ -29,6 +29,7 @@ typedef struct QEMUMachine {
> unsigned int no_serial:1,
> no_parallel:1,
> use_virtcon:1,
> + use_sclp:1,
> no_floppy:1,
> no_cdrom:1,
> no_sdcard:1;
> diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
> index e03ac52..3b908d6 100644
> --- a/hw/s390-virtio.c
> +++ b/hw/s390-virtio.c
> @@ -483,7 +483,7 @@ static QEMUMachine ccw_machine = {
> .no_serial = 1,
> .no_parallel = 1,
> .no_sdcard = 1,
> - .use_virtcon = 1,
> + .use_sclp = 1,
> .max_cpus = 255,
> .is_default = 1,
> };
> diff --git a/vl.c b/vl.c
> index bee122e..803463e 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -176,6 +176,7 @@ int main(int argc, char **argv)
> #define DEFAULT_RAM_SIZE 512
>
> #define MAX_VIRTIO_CONSOLES 1
> +#define MAX_SCLP_CONSOLES 1
>
> static const char *data_dir;
> const char *bios_name = NULL;
> @@ -203,6 +204,7 @@ int no_quit = 0;
> CharDriverState *serial_hds[MAX_SERIAL_PORTS];
> CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
> CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
> +CharDriverState *sclp_hds[MAX_SCLP_CONSOLES];
> int win2k_install_hack = 0;
> int singlestep = 0;
> int smp_cpus = 1;
> @@ -272,6 +274,7 @@ static int tcg_tb_size;
> static int default_serial = 1;
> static int default_parallel = 1;
> static int default_virtcon = 1;
> +static int default_sclp = 1;
> static int default_monitor = 1;
> static int default_floppy = 1;
> static int default_cdrom = 1;
> @@ -2157,6 +2160,7 @@ struct device_config {
> DEV_VIRTCON, /* -virtioconsole */
> DEV_DEBUGCON, /* -debugcon */
> DEV_GDB, /* -gdb, -s */
> + DEV_SCLP, /* s390 sclp */
> } type;
> const char *cmdline;
> Location loc;
> @@ -2275,6 +2279,39 @@ static int virtcon_parse(const char *devname)
> return 0;
> }
>
> +static int sclp_parse(const char *devname)
> +{
> + QemuOptsList *device = qemu_find_opts("device");
> + static int index = 0;
> + char label[32];
> + QemuOpts *dev_opts;
> +
> + if (strcmp(devname, "none") == 0) {
> + return 0;
> + }
> + if (index == MAX_SCLP_CONSOLES) {
> + fprintf(stderr, "qemu: too many sclp consoles\n");
> + exit(1);
> + }
> +
> + assert(arch_type == QEMU_ARCH_S390X);
> +
> + dev_opts = qemu_opts_create(device, NULL, 0, NULL);
> + qemu_opt_set(dev_opts, "driver", "sclpconsole");
> +
> + snprintf(label, sizeof(label), "sclpcon%d", index);
> + sclp_hds[index] = qemu_chr_new(label, devname, NULL);
> + if (!sclp_hds[index]) {
> + fprintf(stderr, "qemu: could not connect sclp console"
> + " to character backend '%s'\n", devname);
> + return -1;
> + }
> + qemu_opt_set(dev_opts, "chardev", label);
> +
> + index++;
> + return 0;
> +}
> +
> static int debugcon_parse(const char *devname)
> {
> QemuOpts *opts;
> @@ -3654,6 +3691,9 @@ int main(int argc, char **argv, char **envp)
> if (!machine->use_virtcon) {
> default_virtcon = 0;
> }
> + if (!machine->use_sclp) {
> + default_sclp = 0;
> + }
> if (machine->no_floppy) {
> default_floppy = 0;
> }
> @@ -3671,11 +3711,15 @@ int main(int argc, char **argv, char **envp)
> add_device_config(DEV_SERIAL, "mon:stdio");
> } else if (default_virtcon && default_monitor) {
> add_device_config(DEV_VIRTCON, "mon:stdio");
> + } else if (default_sclp && default_monitor) {
> + add_device_config(DEV_SCLP, "mon:stdio");
> } else {
> if (default_serial)
> add_device_config(DEV_SERIAL, "stdio");
> if (default_virtcon)
> add_device_config(DEV_VIRTCON, "stdio");
> + if (default_sclp)
> + add_device_config(DEV_SCLP, "stdio");
> if (default_monitor)
> monitor_parse("stdio", "readline");
> }
> @@ -3688,6 +3732,8 @@ int main(int argc, char **argv, char **envp)
> monitor_parse("vc:80Cx24C", "readline");
> if (default_virtcon)
> add_device_config(DEV_VIRTCON, "vc:80Cx24C");
> + if (default_sclp)
> + add_device_config(DEV_SCLP, "vc:80Cx24C");
> }
>
> socket_init();
> @@ -3855,6 +3901,8 @@ int main(int argc, char **argv, char **envp)
> exit(1);
> if (foreach_device_config(DEV_VIRTCON, virtcon_parse) < 0)
> exit(1);
> + if (foreach_device_config(DEV_SCLP, sclp_parse) < 0)
> + exit(1);
> if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
> exit(1);
>