qemu-devel
[Top][All Lists]
Advanced

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]