Except for compile stuff there are to interesting things: 1. Call paravirt_net_poll on the main_loop_wait so the tap can be polled for incoming packets for virtio. 2. Ugly hack (that won't stay forever) to ignore virtio tap fd for regular qemu handlers.
Signed-off-by: Dor Laor <[EMAIL PROTECTED]> --- qemu/Makefile.target | 5 ++++- qemu/hw/pci.c | 2 ++ qemu/qemu-kvm.c | 19 ++++++++++++++++++- qemu/vl.c | 26 +++++++++++++++++++++++++- qemu/vl.h | 7 +++++++ 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/qemu/Makefile.target b/qemu/Makefile.target index aeee2af..7fee36e 100644 --- a/qemu/Makefile.target +++ b/qemu/Makefile.target @@ -371,8 +371,11 @@ VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o # USB layer VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o +# VIRTIO layer +VL_OBJS += virtio.o + # PCI network cards -VL_OBJS+= ne2000.o rtl8139.o pcnet.o +VL_OBJS+= ne2000.o rtl8139.o pcnet.o paravirt_net.o # PCI Hypercall VL_OBJS+= hypercall.o diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c index b895f98..94d1208 100644 --- a/qemu/hw/pci.c +++ b/qemu/hw/pci.c @@ -552,6 +552,8 @@ void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn) pci_rtl8139_init(bus, nd, devfn); } else if (strcmp(nd->model, "pcnet") == 0) { pci_pcnet_init(bus, nd, devfn); + } else if (strcmp(nd->model, "pv") == 0) { + pci_paranet_init(bus, nd, devfn); } else { fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model); exit (1); diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c index 491c32c..d330f41 100644 --- a/qemu/qemu-kvm.c +++ b/qemu/qemu-kvm.c @@ -15,7 +15,7 @@ static int lm_capable_kernel; #include <string.h> #include "vl.h" - +#include "virtio.h" #include "qemu-kvm.h" #include <kvmctl.h> #include <pthread.h> @@ -953,6 +953,21 @@ static int kvm_shutdown(void *opaque, int vcpu) qemu_system_reset_request(); return 1; } + +static int kvm_pv_register(unsigned long memstart, unsigned long key, + unsigned long out, unsigned long in) +{ + virtio_register_mem(memstart, key, out, in); + printf("%s:registered, memstart=%lx, in addr %lx, out addr %lx\n", + __FUNCTION__, memstart, in, out); + return 0; +} + +static int kvm_pv_notify(unsigned long key, unsigned long iotype) +{ + handle_notify(key, iotype); + return 0; +} static struct kvm_callbacks qemu_kvm_ops = { .debug = kvm_debug, @@ -976,6 +991,8 @@ static struct kvm_callbacks qemu_kvm_ops = { .try_push_interrupts = try_push_interrupts, .post_kvm_run = post_kvm_run, .pre_kvm_run = pre_kvm_run, + .pv_register = kvm_pv_register, + .pv_notify = kvm_pv_notify, }; int kvm_qemu_init() diff --git a/qemu/vl.c b/qemu/vl.c index fcc899b..42d3e8e 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -3191,6 +3191,21 @@ typedef struct TAPState { int fd; } TAPState; + +static int fd_unset_tap = -1; + +int get_tap_fd(void *opaque) +{ + TAPState *s = opaque; + + if (s) { + printf("fd_unset_tap = %d\n", s->fd); + fd_unset_tap = s->fd; + return s->fd; + } + return -1; +} + static void tap_receive(void *opaque, const uint8_t *buf, int size) { TAPState *s = opaque; @@ -3204,6 +3219,12 @@ static void tap_receive(void *opaque, const uint8_t *buf, int size) } } +static int tap_read_poll(void *opaque) +{ + TAPState *s = opaque; + return (s->fd != fd_unset_tap); +} + static void tap_send(void *opaque) { TAPState *s = opaque; @@ -3227,7 +3248,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan, int fd) return NULL; s->fd = fd; s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s); - qemu_set_fd_handler(s->fd, tap_send, NULL, s); + qemu_set_fd_handler2(s->fd, tap_read_poll, tap_send, NULL, s); snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd); return s; } @@ -6262,6 +6283,9 @@ void main_loop_wait(int timeout) slirp_select_poll(&rfds, &wfds, &xfds); } #endif + + paravirt_net_poll(); + qemu_aio_poll(); qemu_bh_poll(); diff --git a/qemu/vl.h b/qemu/vl.h index dcc1003..319f59b 100644 --- a/qemu/vl.h +++ b/qemu/vl.h @@ -37,6 +37,7 @@ #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> +#include <sys/uio.h> #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -401,6 +402,8 @@ void qemu_handler_true(void *opaque); void do_info_network(void); +int get_tap_fd(void *opaque); + /* TAP win32 */ int tap_win32_init(VLANState *vlan, const char *ifname); @@ -1017,6 +1020,8 @@ void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn); void pcnet_h_reset(void *opaque); void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque); +void pci_paranet_init(PCIBus *bus, NICInfo *nd, int devfn); +void paravirt_net_poll(void); /* pckbd.c */ @@ -1050,6 +1055,7 @@ typedef struct PicState2 PicState2; extern PicState2 *isa_pic; void pic_set_irq(int irq, int level); void pic_set_irq_new(void *opaque, int irq, int level); +void paravirt_set_irq(int irq); PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque); void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func, void *alt_irq_opaque); @@ -1067,6 +1073,7 @@ int apic_get_interrupt(CPUState *env); int apic_accept_pic_intr(CPUState *env); IOAPICState *ioapic_init(void); void ioapic_set_irq(void *opaque, int vector, int level); +void ioapic_mark_as_edge_triggered(void *opaque, int vector); /* i8254.c */ ----- In simplicity there is elegance. Dor Laor ;) ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel