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
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel