Cam, is it somehow possible to generate a local APIC interrupt from one VM to 
another? I guess it shouldn't be as the LAPIC interrupts generated in one VM 
will go to the VCPUs of the same VM...
Regards,
Bhaskar.

-----Original Message-----
From: kvm-ow...@vger.kernel.org [mailto:kvm-ow...@vger.kernel.org] On Behalf Of 
Kumar, Venkat
Sent: Tuesday, May 19, 2009 9:22 AM
To: Cam Macdonell
Cc: kvm@vger.kernel.org list
Subject: RE: [PATCH v2] Shared memory device with interrupt support

I had tried all syntaxes other than this :).
Interrupts work now.

Thx,

Venkat

-----Original Message-----
From: Cam Macdonell [mailto:c...@cs.ualberta.ca]
Sent: Monday, May 18, 2009 9:51 PM
To: Kumar, Venkat
Cc: kvm@vger.kernel.org list
Subject: Re: [PATCH v2] Shared memory device with interrupt support

Kumar, Venkat wrote:
> Cam - I got your patch to work but without notifications. I could share 
> memory using the patch but notifications aren't working.
>
> I bring up two VM's with option "-ivshmem shrmem,1024,/dev/shm/shrmem,server" 
> and "-ivshmem shrmem,1024,/dev/shm/shrmem" respectively.

Ok, I guess I need to do more error checking of arguments :)  You need
to specify "unix:" on the path.  So your options should look like this

"-ivshmem shrmem,1024,unix:/dev/shm/shrmem,server"

"-ivshmem shrmem,1024,unix:/dev/shm/shrmem"

That should help.

Cam

>
> When I make an "ioctl" from one of the VM's to inject an interrupt to the 
> other VM, I get an error in "qemu_chr_write" and return value is "-1". 
> "write" call in "send_all" is failing with return value "-1".
>
> Am I missing something here?
>
> Thx,
>
> Venkat
>
>
> -----Original Message-----
> From: Cam Macdonell [mailto:c...@cs.ualberta.ca]
> Sent: Saturday, May 16, 2009 9:01 AM
> To: Kumar, Venkat
> Cc: kvm@vger.kernel.org list
> Subject: Re: [PATCH v2] Shared memory device with interrupt support
>
>
> On 15-May-09, at 8:54 PM, Kumar, Venkat wrote:
>
>> Cam,
>>
>> A questions on interrupts as well.
>> What is "unix:path" that needs to be passed in the argument list?
>> Can it be any string?
>
> It has to be a valid path on the host.  It will create a unix domain
> socket on that path.
>
>> If my understanding is correct both the VM's who wants to
>> communicate would gives this path in the command line with one of
>> them specifying as "server".
>
> Exactly, the one with the "server" in the parameter list will wait for
> a connection before booting.
>
> Cam
>
>> Thx,
>> Venkat
>>
>>
>>
>>
>>
>>
>>    Support an inter-vm shared memory device that maps a shared-
>> memory object
>> as a PCI device in the guest.  This patch also supports interrupts
>> between
>> guest by communicating over a unix domain socket.  This patch
>> applies to the
>> qemu-kvm repository.
>>
>> This device now creates a qemu character device and sends 1-bytes
>> messages to
>> trigger interrupts.  Writes are trigger by writing to the "Doorbell"
>> register
>> on the shared memory PCI device.  The lower 8-bits of the value
>> written to this
>> register are sent as the 1-byte message so different meanings of
>> interrupts can
>> be supported.
>>
>> Interrupts are only supported between 2 VMs currently.  One VM must
>> act as the
>> server by adding "server" to the command-line argument.  Shared
>> memory devices
>> are created with the following command-line:
>>
>> -ivhshmem <shm object>,<size in MB>,[unix:<path>][,server]
>>
>> Interrupts can also be used between host and guest as well by
>> implementing a
>> listener on the host.
>>
>> Cam
>>
>> ---
>> Makefile.target |    3 +
>> hw/ivshmem.c    |  421 ++++++++++++++++++++++++++++++++++++++++++++++
>> +++++++++
>> hw/pc.c         |    6 +
>> hw/pc.h         |    3 +
>> qemu-options.hx |   14 ++
>> sysemu.h        |    8 +
>> vl.c            |   14 ++
>> 7 files changed, 469 insertions(+), 0 deletions(-)
>> create mode 100644 hw/ivshmem.c
>>
>> diff --git a/Makefile.target b/Makefile.target
>> index b68a689..3190bba 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -643,6 +643,9 @@ OBJS += pcnet.o
>> OBJS += rtl8139.o
>> OBJS += e1000.o
>>
>> +# Inter-VM PCI shared memory
>> +OBJS += ivshmem.o
>> +
>> # Generic watchdog support and some watchdog devices
>> OBJS += watchdog.o
>> OBJS += wdt_ib700.o wdt_i6300esb.o
>> diff --git a/hw/ivshmem.c b/hw/ivshmem.c
>> new file mode 100644
>> index 0000000..95e2268
>> --- /dev/null
>> +++ b/hw/ivshmem.c
>> @@ -0,0 +1,421 @@
>> +/*
>> + * Inter-VM Shared Memory PCI device.
>> + *
>> + * Author:
>> + *      Cam Macdonell <c...@cs.ualberta.ca>
>> + *
>> + * Based On: cirrus_vga.c and rtl8139.c
>> + *
>> + * This code is licensed under the GNU GPL v2.
>> + */
>> +
>> +#include "hw.h"
>> +#include "console.h"
>> +#include "pc.h"
>> +#include "pci.h"
>> +#include "sysemu.h"
>> +
>> +#include "qemu-common.h"
>> +#include <sys/mman.h>
>> +
>> +#define PCI_COMMAND_IOACCESS                0x0001
>> +#define PCI_COMMAND_MEMACCESS               0x0002
>> +#define PCI_COMMAND_BUSMASTER               0x0004
>> +
>> +//#define DEBUG_IVSHMEM
>> +
>> +#ifdef DEBUG_IVSHMEM
>> +#define IVSHMEM_DPRINTF(fmt, args...)        \
>> +    do {printf("IVSHMEM: " fmt, ##args); } while (0)
>> +#else
>> +#define IVSHMEM_DPRINTF(fmt, args...)
>> +#endif
>> +
>> +typedef struct IVShmemState {
>> +    uint16_t intrmask;
>> +    uint16_t intrstatus;
>> +    uint16_t doorbell;
>> +    uint8_t *ivshmem_ptr;
>> +    unsigned long ivshmem_offset;
>> +    unsigned int ivshmem_size;
>> +    unsigned long bios_offset;
>> +    unsigned int bios_size;
>> +    target_phys_addr_t base_ctrl;
>> +    int it_shift;
>> +    PCIDevice *pci_dev;
>> +    CharDriverState * chr;
>> +    unsigned long map_addr;
>> +    unsigned long map_end;
>> +    int ivshmem_mmio_io_addr;
>> +} IVShmemState;
>> +
>> +typedef struct PCI_IVShmemState {
>> +    PCIDevice dev;
>> +    IVShmemState ivshmem_state;
>> +} PCI_IVShmemState;
>> +
>> +typedef struct IVShmemDesc {
>> +    char name[1024];
>> +    char * chrdev;
>> +    int size;
>> +} IVShmemDesc;
>> +
>> +
>> +/* registers for the Inter-VM shared memory device */
>> +enum ivshmem_registers {
>> +    IntrMask = 0,
>> +    IntrStatus = 16,
>> +    Doorbell = 32
>> +};
>> +
>> +static int num_ivshmem_devices = 0;
>> +static IVShmemDesc ivshmem_desc;
>> +
>> +static void ivshmem_map(PCIDevice *pci_dev, int region_num,
>> +                    uint32_t addr, uint32_t size, int type)
>> +{
>> +    PCI_IVShmemState *d = (PCI_IVShmemState *)pci_dev;
>> +    IVShmemState *s = &d->ivshmem_state;
>> +
>> +    IVSHMEM_DPRINTF("addr = %u size = %u\n", addr, size);
>> +    cpu_register_physical_memory(addr, s->ivshmem_size, s-
>>> ivshmem_offset);
>> +
>> +}
>> +
>> +void ivshmem_init(const char * optarg) {
>> +
>> +    char * temp;
>> +    char * ivshmem_sz;
>> +    int size;
>> +
>> +    num_ivshmem_devices++;
>> +
>> +    /* currently we only support 1 device */
>> +    if (num_ivshmem_devices > MAX_IVSHMEM_DEVICES) {
>> +        return;
>> +    }
>> +
>> +    temp = strdup(optarg);
>> +    snprintf(ivshmem_desc.name, 1024, "/%s", strsep(&temp,","));
>> +    ivshmem_sz=strsep(&temp,",");
>> +    if (ivshmem_sz != NULL){
>> +        size = atol(ivshmem_sz);
>> +    } else {
>> +        size = -1;
>> +    }
>> +
>> +    ivshmem_desc.chrdev = strsep(&temp,"\0");
>> +
>> +    if ( size == -1) {
>> +        ivshmem_desc.size = TARGET_PAGE_SIZE;
>> +    } else {
>> +        ivshmem_desc.size = size*1024*1024;
>> +    }
>> +    IVSHMEM_DPRINTF("optarg is %s, name is %s, size is %d, chrdev
>> is %s\n",
>> +                                        optarg, ivshmem_desc.name,
>> +                                        ivshmem_desc.size,
>> ivshmem_desc.chrdev);
>> +}
>> +
>> +int ivshmem_get_size(void) {
>> +    return ivshmem_desc.size;
>> +}
>> +
>> +/* accessing registers - based on rtl8139 */
>> +static void ivshmem_update_irq(IVShmemState *s)
>> +{
>> +    int isr;
>> +    isr = (s->intrstatus & s->intrmask) & 0xffff;
>> +
>> +    /* don't print ISR resets */
>> +    if (isr) {
>> +        IVSHMEM_DPRINTF("Set IRQ to %d (%04x %04x)\n",
>> +           isr ? 1 : 0, s->intrstatus, s->intrmask);
>> +    }
>> +
>> +    qemu_set_irq(s->pci_dev->irq[0], (isr != 0));
>> +}
>> +
>> +static void ivshmem_mmio_map(PCIDevice *pci_dev, int region_num,
>> +                       uint32_t addr, uint32_t size, int type)
>> +{
>> +    PCI_IVShmemState *d = (PCI_IVShmemState *)pci_dev;
>> +    IVShmemState *s = &d->ivshmem_state;
>> +
>> +    cpu_register_physical_memory(addr + 0, 0x100, s-
>>> ivshmem_mmio_io_addr);
>> +}
>> +
>> +static void ivshmem_IntrMask_write(IVShmemState *s, uint32_t val)
>> +{
>> +    IVSHMEM_DPRINTF("IntrMask write(w) val = 0x%04x\n", val);
>> +
>> +    s->intrmask = val;
>> +
>> +    ivshmem_update_irq(s);
>> +}
>> +
>> +static uint32_t ivshmem_IntrMask_read(IVShmemState *s)
>> +{
>> +    uint32_t ret = s->intrmask;
>> +
>> +    IVSHMEM_DPRINTF("intrmask read(w) val = 0x%04x\n", ret);
>> +
>> +    return ret;
>> +}
>> +
>> +static void ivshmem_IntrStatus_write(IVShmemState *s, uint32_t val)
>> +{
>> +    IVSHMEM_DPRINTF("IntrStatus write(w) val = 0x%04x\n", val);
>> +
>> +    s->intrstatus = val;
>> +
>> +    ivshmem_update_irq(s);
>> +    return;
>> +}
>> +
>> +static uint32_t ivshmem_IntrStatus_read(IVShmemState *s)
>> +{
>> +    uint32_t ret = s->intrstatus;
>> +
>> +    /* reading ISR clears all interrupts */
>> +    s->intrstatus = 0;
>> +
>> +    ivshmem_update_irq(s);
>> +
>> +    return ret;
>> +}
>> +
>> +static void ivshmem_io_writew(void *opaque, uint8_t addr, uint32_t
>> val)
>> +{
>> +    IVShmemState *s = opaque;
>> +
>> +    IVSHMEM_DPRINTF("writing 0x%x to 0x%lx\n", addr, (unsigned
>> long) opaque);
>> +
>> +    addr &= 0xfe;
>> +
>> +    switch (addr)
>> +    {
>> +        case IntrMask:
>> +            ivshmem_IntrMask_write(s, val);
>> +            break;
>> +
>> +        case IntrStatus:
>> +            ivshmem_IntrStatus_write(s, val);
>> +            break;
>> +
>> +        default:
>> +            IVSHMEM_DPRINTF("why are we writing 0x%x\n", addr);
>> +    }
>> +}
>> +
>> +static void ivshmem_io_writel(void *opaque, uint8_t addr, uint32_t
>> val)
>> +{
>> +    IVSHMEM_DPRINTF("We shouldn't be writing longs\n");
>> +}
>> +
>> +static void ivshmem_io_writeb(void *opaque, uint8_t addr, uint32_t
>> val)
>> +{
>> +    IVShmemState *s = opaque;
>> +    uint8_t writebyte = val & 0xff; //write the lower 8-bits of 'val'
>> +
>> +    switch (addr)
>> +    {   // in future, we will probably want to support more types
>> of doorbells
>> +        case Doorbell:
>> +            // wake up the other side
>> +            qemu_chr_write(s->chr, &writebyte, 1);
>> +            IVSHMEM_DPRINTF("Writing to the other side 0x%x\n",
>> writebyte);
>> +            break;
>> +        default:
>> +            IVSHMEM_DPRINTF("Unhandled write (0x%x)\n", addr);
>> +    }
>> +}
>> +
>> +static uint32_t ivshmem_io_readw(void *opaque, uint8_t addr)
>> +{
>> +
>> +    IVShmemState *s = opaque;
>> +    uint32_t ret;
>> +
>> +    switch (addr)
>> +    {
>> +        case IntrMask:
>> +            ret = ivshmem_IntrMask_read(s);
>> +            break;
>> +        case IntrStatus:
>> +            ret = ivshmem_IntrStatus_read(s);
>> +            break;
>> +        default:
>> +            IVSHMEM_DPRINTF("why are we reading 0x%x\n", addr);
>> +            ret = 0;
>> +    }
>> +
>> +    return ret;
>> +}
>> +
>> +static uint32_t ivshmem_io_readl(void *opaque, uint8_t addr)
>> +{
>> +    IVSHMEM_DPRINTF("We shouldn't be reading longs\n");
>> +    return 0;
>> +}
>> +
>> +static uint32_t ivshmem_io_readb(void *opaque, uint8_t addr)
>> +{
>> +    IVSHMEM_DPRINTF("We shouldn't be reading bytes\n");
>> +
>> +    return 0;
>> +}
>> +
>> +static void ivshmem_mmio_writeb(void *opaque,
>> +                                target_phys_addr_t addr, uint32_t
>> val)
>> +{
>> +    ivshmem_io_writeb(opaque, addr & 0xFF, val);
>> +}
>> +
>> +static void ivshmem_mmio_writew(void *opaque,
>> +                                target_phys_addr_t addr, uint32_t
>> val)
>> +{
>> +    ivshmem_io_writew(opaque, addr & 0xFF, val);
>> +}
>> +
>> +static void ivshmem_mmio_writel(void *opaque,
>> +                                target_phys_addr_t addr, uint32_t
>> val)
>> +{
>> +    ivshmem_io_writel(opaque, addr & 0xFF, val);
>> +}
>> +
>> +static uint32_t ivshmem_mmio_readb(void *opaque, target_phys_addr_t
>> addr)
>> +{
>> +    return ivshmem_io_readb(opaque, addr & 0xFF);
>> +}
>> +
>> +static uint32_t ivshmem_mmio_readw(void *opaque, target_phys_addr_t
>> addr)
>> +{
>> +    uint32_t val = ivshmem_io_readw(opaque, addr & 0xFF);
>> +    return val;
>> +}
>> +
>> +static uint32_t ivshmem_mmio_readl(void *opaque, target_phys_addr_t
>> addr)
>> +{
>> +    uint32_t val = ivshmem_io_readl(opaque, addr & 0xFF);
>> +    return val;
>> +}
>> +
>> +static CPUReadMemoryFunc *ivshmem_mmio_read[3] = {
>> +    ivshmem_mmio_readb,
>> +    ivshmem_mmio_readw,
>> +    ivshmem_mmio_readl,
>> +};
>> +
>> +static CPUWriteMemoryFunc *ivshmem_mmio_write[3] = {
>> +    ivshmem_mmio_writeb,
>> +    ivshmem_mmio_writew,
>> +    ivshmem_mmio_writel,
>> +};
>> +
>> +static int ivshmem_can_receive(void * opaque)
>> +{
>> +    return 1;
>> +}
>> +
>> +static void ivshmem_receive(void *opaque, const uint8_t *buf, int
>> size)
>> +{
>> +    IVShmemState *s = opaque;
>> +
>> +    ivshmem_IntrStatus_write(s, *buf);
>> +
>> +    IVSHMEM_DPRINTF("ivshmem_receive 0x%02x\n", *buf);
>> +}
>> +
>> +static void ivshmem_event(void *opaque, int event)
>> +{
>> +    IVShmemState *s = opaque;
>> +    IVSHMEM_DPRINTF("ivshmem_event %d\n", event);
>> +}
>> +
>> +int pci_ivshmem_init(PCIBus *bus)
>> +{
>> +    PCI_IVShmemState *d;
>> +    IVShmemState *s;
>> +    uint8_t *pci_conf;
>> +    int ivshmem_fd;
>> +
>> +    IVSHMEM_DPRINTF("shared file is %s\n", ivshmem_desc.name);
>> +    d = (PCI_IVShmemState *)pci_register_device(bus, "kvm_ivshmem",
>> +                                           sizeof(PCI_IVShmemState),
>> +                                           -1, NULL, NULL);
>> +    if (!d) {
>> +        return -1;
>> +    }
>> +
>> +    s = &d->ivshmem_state;
>> +
>> +    /* allocate shared memory RAM */
>> +    s->ivshmem_offset = qemu_ram_alloc(ivshmem_desc.size);
>> +    IVSHMEM_DPRINTF("size is = %d\n", ivshmem_desc.size);
>> +    IVSHMEM_DPRINTF("ivshmem ram offset = %ld\n", s->ivshmem_offset);
>> +
>> +    s->ivshmem_ptr = qemu_get_ram_ptr(s->ivshmem_offset);
>> +
>> +    s->pci_dev = &d->dev;
>> +    s->ivshmem_size = ivshmem_desc.size;
>> +
>> +    pci_conf = d->dev.config;
>> +    pci_conf[0x00] = 0xf4; // Qumranet vendor ID 0x5002
>> +    pci_conf[0x01] = 0x1a;
>> +    pci_conf[0x02] = 0x10;
>> +    pci_conf[0x03] = 0x11;
>> +    pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
>> +    pci_conf[0x0a] = 0x00; // RAM controller
>> +    pci_conf[0x0b] = 0x05;
>> +    pci_conf[0x0e] = 0x00; // header_type
>> +
>> +    pci_conf[PCI_INTERRUPT_PIN] = 1; // we are going to support
>> interrupts
>> +
>> +    /* XXX: ivshmem_desc.size must be a power of two */
>> +
>> +    s->ivshmem_mmio_io_addr = cpu_register_io_memory(0,
>> ivshmem_mmio_read,
>> +                                    ivshmem_mmio_write, s);
>> +
>> +    /* region for registers*/
>> +    pci_register_io_region(&d->dev, 0, 0x100,
>> +                           PCI_ADDRESS_SPACE_MEM, ivshmem_mmio_map);
>> +
>> +    /* region for shared memory */
>> +    pci_register_io_region(&d->dev, 1, ivshmem_desc.size,
>> +                           PCI_ADDRESS_SPACE_MEM, ivshmem_map);
>> +
>> +    /* open shared memory file  */
>> +    if ((ivshmem_fd = shm_open(ivshmem_desc.name, O_CREAT|O_RDWR,
>> S_IRWXU)) <
>> 0)
>> +    {
>> +        fprintf(stderr, "kvm_ivshmem: could not open shared file\n");
>> +        exit(-1);
>> +    }
>> +
>> +    ftruncate(ivshmem_fd, ivshmem_desc.size);
>> +
>> +    /* mmap onto PCI device's memory */
>> +    if (mmap(s->ivshmem_ptr, ivshmem_desc.size, PROT_READ|PROT_WRITE,
>> +                        MAP_SHARED|MAP_FIXED, ivshmem_fd, 0) ==
>> MAP_FAILED)
>> +    {
>> +        fprintf(stderr, "kvm_ivshmem: could not mmap shared file\n");
>> +        exit(-1);
>> +    }
>> +
>> +    IVSHMEM_DPRINTF("shared object mapped to 0x%p\n", s-
>>> ivshmem_ptr);
>> +
>> +    /* setup character device channel */
>> +
>> +    if (ivshmem_desc.chrdev != NULL) {
>> +        char label[32];
>> +        snprintf(label, 32, "ivshmem_chardev");
>> +        s->chr = qemu_chr_open(label, ivshmem_desc.chrdev, NULL);
>> +        if (s->chr == NULL) {
>> +            fprintf(stderr, "No server listening on %s\n",
>> ivshmem_desc.chrdev);
>> +            exit(-1);
>> +        }
>> +        qemu_chr_add_handlers(s->chr, ivshmem_can_receive,
>> ivshmem_receive,
>> +                          ivshmem_event, s);
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> diff --git a/hw/pc.c b/hw/pc.c
>> index 34a4d25..7d0cff2 100644
>> --- a/hw/pc.c
>> +++ b/hw/pc.c
>> @@ -67,6 +67,8 @@ static PITState *pit;
>> static IOAPICState *ioapic;
>> static PCIDevice *i440fx_state;
>>
>> +extern int ivshmem_enabled;
>> +
>> static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
>> {
>> }
>> @@ -1040,6 +1042,10 @@ static void pc_init1(ram_addr_t ram_size, int
>> vga_ram_size,
>>         }
>>     }
>>
>> +    if (pci_enabled && ivshmem_enabled) {
>> +        pci_ivshmem_init(pci_bus);
>> +    }
>> +
>>     rtc_state = rtc_init(0x70, i8259[8], 2000);
>>
>>     qemu_register_boot_set(pc_boot_set, rtc_state);
>> diff --git a/hw/pc.h b/hw/pc.h
>> index 885c918..0ae0493 100644
>> --- a/hw/pc.h
>> +++ b/hw/pc.h
>> @@ -185,4 +185,7 @@ void isa_ne2000_init(int base, qemu_irq irq,
>> NICInfo *nd);
>>
>> void extboot_init(BlockDriverState *bs, int cmd);
>>
>> +/* ivshmem.c */
>> +int pci_ivshmem_init(PCIBus *bus);
>> +
>> #endif
>> diff --git a/qemu-options.hx b/qemu-options.hx
>> index 173f458..9ab3e2d 100644
>> --- a/qemu-options.hx
>> +++ b/qemu-options.hx
>> @@ -1243,6 +1243,20 @@ The default device is @code{vc} in graphical
>> mode and
>> @code{stdio} in
>> non graphical mode.
>> ETEXI
>>
>> +DEF("ivshmem", HAS_ARG, QEMU_OPTION_ivshmem, \
>> +    "-ivshmem name,size[,unix:path][,server]  creates or opens a
>> shared file
>> 'name' of size \
>> +    'size' (in MB) and exposes it as a PCI device in the guest\n")
>> +STEXI
>> +...@item -ivshmem @var{file},@var{size}
>> +Creates a POSIX shared file named @var{file} of size @var{size} and
>> creates a
>> +PCI device of the same size that maps the shared file into the
>> device for
>> guests
>> +to access.  The created file on the host is located in /dev/shm/
>> +
>> +...@item unix:@var{path}[,server]
>> +A unix domain socket is used to send and receive interrupts between
>> VMs.  The
>> unix domain socket
>> +...@var{path} is used for connections.
>> +ETEXI
>> +
>> DEF("pidfile", HAS_ARG, QEMU_OPTION_pidfile, \
>>     "-pidfile file   write PID to 'file'\n")
>> STEXI
>> diff --git a/sysemu.h b/sysemu.h
>> index 1f45fd6..862b79e 100644
>> --- a/sysemu.h
>> +++ b/sysemu.h
>> @@ -217,6 +217,14 @@ extern CharDriverState
>> *parallel_hds[MAX_PARALLEL_PORTS];
>>
>> extern CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
>>
>> +/* inter-VM shared memory devices */
>> +
>> +#define MAX_IVSHMEM_DEVICES 1
>> +
>> +extern CharDriverState * ivshmem_chardev;
>> +void ivshmem_init(const char * optarg);
>> +int ivshmem_get_size(void);
>> +
>> #define TFR(expr) do { if ((expr) != -1) break; } while (errno ==
>> EINTR)
>>
>> #ifdef NEED_CPU_H
>> diff --git a/vl.c b/vl.c
>> index 0420634..7260fa1 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -221,6 +221,7 @@ static int rtc_date_offset = -1; /* -1 means no
>> change */
>> int cirrus_vga_enabled = 1;
>> int std_vga_enabled = 0;
>> int vmsvga_enabled = 0;
>> +int ivshmem_enabled = 0;
>> int xenfb_enabled = 0;
>> #ifdef TARGET_SPARC
>> int graphic_width = 1024;
>> @@ -239,6 +240,8 @@ int no_quit = 0;
>> CharDriverState *serial_hds[MAX_SERIAL_PORTS];
>> CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
>> CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
>> +CharDriverState *ivshmem_chardev;
>> +const char * ivshmem_device;
>> #ifdef TARGET_I386
>> int win2k_install_hack = 0;
>> int rtc_td_hack = 0;
>> @@ -5063,6 +5066,8 @@ int main(int argc, char **argv, char **envp)
>>     cyls = heads = secs = 0;
>>     translation = BIOS_ATA_TRANSLATION_AUTO;
>>     monitor_device = "vc:80Cx24C";
>> +    ivshmem_device = NULL;
>> +    ivshmem_chardev = NULL;
>>
>>     serial_devices[0] = "vc:80Cx24C";
>>     for(i = 1; i < MAX_SERIAL_PORTS; i++)
>> @@ -5518,6 +5523,10 @@ int main(int argc, char **argv, char **envp)
>>                 parallel_devices[parallel_device_index] = optarg;
>>                 parallel_device_index++;
>>                 break;
>> +            case QEMU_OPTION_ivshmem:
>> +                ivshmem_device = optarg;
>> +                ivshmem_enabled = 1;
>> +                break;
>>            case QEMU_OPTION_loadvm:
>>                loadvm = optarg;
>>                break;
>> @@ -5984,6 +5993,11 @@ int main(int argc, char **argv, char **envp)
>>            }
>>     }
>>
>> +    if (ivshmem_enabled) {
>> +        ivshmem_init(ivshmem_device);
>> +        ram_size += ivshmem_get_size();
>> +    }
>> +
>> #ifdef CONFIG_KQEMU
>>     /* FIXME: This is a nasty hack because kqemu can't cope with
>> dynamic
>>        guest ram allocation.  It needs to go away.  */
>> Thx,
>>
>> Venkat
>
>
>
> -----------------------------------------------
> A. Cameron Macdonell
> Ph.D. Student
> Department of Computing Science
> University of Alberta
> c...@cs.ualberta.ca

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to