public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* preview of in kernel irqchip live migration support
@ 2007-07-24  5:48 Dong, Eddie
       [not found] ` <10EA09EFD8728347A513008B6B0DA77A01D15BAB-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
  0 siblings, 1 reply; 4+ messages in thread
From: Dong, Eddie @ 2007-07-24  5:48 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

[-- Attachment #1: Type: text/plain, Size: 7027 bytes --]


This patch is only for idea collection so far.
The dilemma is that how to export the pic/IOAPIC/apic state data
structure
to user and make sure it has same/similar structure in user level.
Otherwise a
convert is a must and we must maintain the converter.

With this, PIC only guest can do live migration successfully. We can
extend
APIC side seamlessly.

BTW, there is potential issue in IDT_Vectoring. The fix IMO is to retry
vm_stop at user level
to make sure no pending IDT_vectoring.

Pls comments. Also I will temply off this week, Qing He may continue.

Thx,eddie



diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index 4237e17..17b836d 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -115,6 +115,13 @@ static void pic_update_irq(struct kvm_pic *s)
 	irq = pic_get_irq(&s->pics[0]);
 	if (irq >= 0)
 		s->irq_request(s->irq_request_opaque, 1);
+	else
+		s->irq_request(s->irq_request_opaque, 0);
+}
+
+void kvm_pic_update_irq(struct kvm_pic *s)
+{
+	pic_update_irq(s);
 }
 
 void kvm_pic_set_irq(void *opaque, int irq, int level)
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 6cfc19f..217e969 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -26,25 +26,6 @@
 
 typedef void irq_request_func(void *opaque, int level);
 
-struct kvm_pic_state {
-	u8 last_irr;	/* edge detection */
-	u8 irr;		/* interrupt request register */
-	u8 imr;		/* interrupt mask register */
-	u8 isr;		/* interrupt service register */
-	u8 priority_add;	/* highest irq priority */
-	u8 irq_base;
-	u8 read_reg_select;
-	u8 poll;
-	u8 special_mask;
-	u8 init_state;
-	u8 auto_eoi;
-	u8 rotate_on_auto_eoi;
-	u8 special_fully_nested_mode;
-	u8 init4;		/* true if 4 byte init */
-	u8 elcr;		/* PIIX edge/trigger selection */
-	u8 elcr_mask;
-	struct kvm_pic *pics_state;
-};
 
 struct kvm_pic {
 	struct kvm_pic_state pics[2]; /* 0 is master pic, 1 is slave pic
*/
@@ -59,6 +40,7 @@ void kvm_pic_set_irq(void *opaque, int irq, int
level);
 int kvm_pic_read_irq(struct kvm_pic *s);
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
+void kvm_pic_update_irq(struct kvm_pic *s);
 
 #define IOAPIC_NUM_PINS  24
 #define IOAPIC_VERSION_ID 0x11	/* IOAPIC version */
@@ -79,11 +61,8 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
 #define IOAPIC_REG_ARB_ID  0x02	/* x86 IOAPIC only */
 
 struct kvm_ioapic {
-	struct kvm_io_device dev;
-	unsigned long base_address;
-	struct kvm *kvm;
-	u32 ioregsel;
 	u32 id;
+	u32 ioregsel;
 	u32 irr;
 	union ioapic_redir_entry {
 		u64 bits;
@@ -101,6 +80,9 @@ struct kvm_ioapic {
 			u8 dest_id;
 		} fields;
 	} redirtbl[IOAPIC_NUM_PINS];
+	struct kvm_io_device dev;
+	unsigned long base_address;
+	struct kvm *kvm;
 };
 
 struct kvm_lapic {
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 0c75fef..805ca47 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -935,6 +935,57 @@ out:
 	return r;
 }
 
+static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip
*chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[0],
+			KVM_IRQCHIP_SAVE_LEN);
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[1],
+			KVM_IRQCHIP_SAVE_LEN);
+		break;
+	case KVM_IRQCHIP_IOAPIC:
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	return r;
+}
+
+static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip
*chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&pic_irqchip(kvm)->pics[0],
+			&chip->chip.pic,
+			KVM_IRQCHIP_SAVE_LEN);
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&pic_irqchip(kvm)->pics[1],
+			&chip->chip.pic,
+			KVM_IRQCHIP_SAVE_LEN);
+		break;
+	case KVM_IRQCHIP_IOAPIC:
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	kvm_pic_update_irq(pic_irqchip(kvm));
+	return r;
+}
+
 static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
 	int i;
@@ -2896,6 +2947,35 @@ static long kvm_vm_ioctl(struct file *filp,
 		}
 		break;
 	}
+	case KVM_GET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
+		if (r)
+			goto out;
+		r = -EFAULT;
+		if (copy_to_user(argp, &chip, sizeof chip - sizeof(void
*)))
+			goto out;
+		r = 0;
+		break;
+	}
+	case KVM_SET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
+		if (r)
+			goto out;
+		r = 0;
+		break;
+	}
 	default:
 		;
 	}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 5307ba3..4eee80d 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -51,6 +51,44 @@ struct kvm_irq_level {
 	__u32 level;
 };
 
+/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
+struct kvm_pic_state {
+	__u8 last_irr;	/* edge detection */
+	__u8 irr;		/* interrupt request register */
+	__u8 imr;		/* interrupt mask register */
+	__u8 isr;		/* interrupt service register */
+	__u8 priority_add;	/* highest irq priority */
+	__u8 irq_base;
+	__u8 read_reg_select;
+	__u8 poll;
+	__u8 special_mask;
+	__u8 init_state;
+	__u8 auto_eoi;
+	__u8 rotate_on_auto_eoi;
+	__u8 special_fully_nested_mode;
+	__u8 init4;		/* true if 4 byte init */
+	__u8 elcr;		/* PIIX edge/trigger selection */
+	__u8 elcr_mask;
+	struct kvm_pic *pics_state;
+};
+#define KVM_IRQCHIP_SAVE_LEN	\
+	(sizeof(struct kvm_pic_state) - sizeof(struct kvm_pic *))
+
+struct kvm_irqchip {
+	__u8  chip_id;
+	__u8  pad1;
+        __u16 pad2;
+        union {
+		struct kvm_pic_state pic;
+	} chip;
+};
+
+enum kvm_irqchip_id {
+	KVM_IRQCHIP_PIC_MASTER	 = 0,
+	KVM_IRQCHIP_PIC_SLAVE	 = 1,
+	KVM_IRQCHIP_IOAPIC	 = 2,
+};
+
 enum kvm_exit_reason {
 	KVM_EXIT_UNKNOWN          = 0,
 	KVM_EXIT_EXCEPTION        = 1,
@@ -304,6 +342,8 @@ struct kvm_signal_mask {
 /* Device model IOC */
 #define KVM_CREATE_PIC		  _IO(KVMIO,  0x60)
 #define KVM_IRQ_LINE		  _IOW(KVMIO, 0x61, struct
kvm_irq_level)
+#define KVM_GET_IRQCHIP		  _IOWR(KVMIO, 0x62, struct
kvm_irqchip)
+#define KVM_SET_IRQCHIP		  _IOR(KVMIO,  0x63, struct
kvm_irqchip)
 
 /*
  * ioctls for vcpu fds
@@ -322,5 +362,7 @@ struct kvm_signal_mask {
 #define KVM_SET_SIGNAL_MASK       _IOW(KVMIO,  0x8b, struct
kvm_signal_mask)
 #define KVM_GET_FPU               _IOR(KVMIO,  0x8c, struct kvm_fpu)
 #define KVM_SET_FPU               _IOW(KVMIO,  0x8d, struct kvm_fpu)
+#define KVM_GET_LAPIC             _IOW(KVMIO,  0x8e, struct kvm_lapic)
+#define KVM_SET_LAPIC             _IOW(KVMIO,  0x8f, struct kvm_lapic)
 
 #endif

[-- Attachment #2: live_k1.patch --]
[-- Type: application/octet-stream, Size: 6179 bytes --]

diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index 4237e17..17b836d 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -115,6 +115,13 @@ static void pic_update_irq(struct kvm_pic *s)
 	irq = pic_get_irq(&s->pics[0]);
 	if (irq >= 0)
 		s->irq_request(s->irq_request_opaque, 1);
+	else
+		s->irq_request(s->irq_request_opaque, 0);
+}
+
+void kvm_pic_update_irq(struct kvm_pic *s)
+{
+	pic_update_irq(s);
 }
 
 void kvm_pic_set_irq(void *opaque, int irq, int level)
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 6cfc19f..217e969 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -26,25 +26,6 @@
 
 typedef void irq_request_func(void *opaque, int level);
 
-struct kvm_pic_state {
-	u8 last_irr;	/* edge detection */
-	u8 irr;		/* interrupt request register */
-	u8 imr;		/* interrupt mask register */
-	u8 isr;		/* interrupt service register */
-	u8 priority_add;	/* highest irq priority */
-	u8 irq_base;
-	u8 read_reg_select;
-	u8 poll;
-	u8 special_mask;
-	u8 init_state;
-	u8 auto_eoi;
-	u8 rotate_on_auto_eoi;
-	u8 special_fully_nested_mode;
-	u8 init4;		/* true if 4 byte init */
-	u8 elcr;		/* PIIX edge/trigger selection */
-	u8 elcr_mask;
-	struct kvm_pic *pics_state;
-};
 
 struct kvm_pic {
 	struct kvm_pic_state pics[2]; /* 0 is master pic, 1 is slave pic */
@@ -59,6 +40,7 @@ void kvm_pic_set_irq(void *opaque, int irq, int level);
 int kvm_pic_read_irq(struct kvm_pic *s);
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
+void kvm_pic_update_irq(struct kvm_pic *s);
 
 #define IOAPIC_NUM_PINS  24
 #define IOAPIC_VERSION_ID 0x11	/* IOAPIC version */
@@ -79,11 +61,8 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
 #define IOAPIC_REG_ARB_ID  0x02	/* x86 IOAPIC only */
 
 struct kvm_ioapic {
-	struct kvm_io_device dev;
-	unsigned long base_address;
-	struct kvm *kvm;
-	u32 ioregsel;
 	u32 id;
+	u32 ioregsel;
 	u32 irr;
 	union ioapic_redir_entry {
 		u64 bits;
@@ -101,6 +80,9 @@ struct kvm_ioapic {
 			u8 dest_id;
 		} fields;
 	} redirtbl[IOAPIC_NUM_PINS];
+	struct kvm_io_device dev;
+	unsigned long base_address;
+	struct kvm *kvm;
 };
 
 struct kvm_lapic {
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 0c75fef..805ca47 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -935,6 +935,57 @@ out:
 	return r;
 }
 
+static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[0],
+			KVM_IRQCHIP_SAVE_LEN);
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&chip->chip.pic,
+			&pic_irqchip(kvm)->pics[1],
+			KVM_IRQCHIP_SAVE_LEN);
+		break;
+	case KVM_IRQCHIP_IOAPIC:
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	return r;
+}
+
+static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
+{
+	int r;
+
+	r = 0;
+	switch (chip->chip_id) {
+	case KVM_IRQCHIP_PIC_MASTER:
+		memcpy (&pic_irqchip(kvm)->pics[0],
+			&chip->chip.pic,
+			KVM_IRQCHIP_SAVE_LEN);
+		break;
+	case KVM_IRQCHIP_PIC_SLAVE:
+		memcpy (&pic_irqchip(kvm)->pics[1],
+			&chip->chip.pic,
+			KVM_IRQCHIP_SAVE_LEN);
+		break;
+	case KVM_IRQCHIP_IOAPIC:
+		break;
+	default:
+		r = -EINVAL;
+		break;
+	}
+	kvm_pic_update_irq(pic_irqchip(kvm));
+	return r;
+}
+
 static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
 	int i;
@@ -2896,6 +2947,35 @@ static long kvm_vm_ioctl(struct file *filp,
 		}
 		break;
 	}
+	case KVM_GET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
+		if (r)
+			goto out;
+		r = -EFAULT;
+		if (copy_to_user(argp, &chip, sizeof chip - sizeof(void *)))
+			goto out;
+		r = 0;
+		break;
+	}
+	case KVM_SET_IRQCHIP: {
+		/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
+		struct kvm_irqchip chip;
+
+		r = -EFAULT;
+		if (copy_from_user(&chip, argp, sizeof chip))
+			goto out;
+		r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
+		if (r)
+			goto out;
+		r = 0;
+		break;
+	}
 	default:
 		;
 	}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 5307ba3..4eee80d 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -51,6 +51,44 @@ struct kvm_irq_level {
 	__u32 level;
 };
 
+/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
+struct kvm_pic_state {
+	__u8 last_irr;	/* edge detection */
+	__u8 irr;		/* interrupt request register */
+	__u8 imr;		/* interrupt mask register */
+	__u8 isr;		/* interrupt service register */
+	__u8 priority_add;	/* highest irq priority */
+	__u8 irq_base;
+	__u8 read_reg_select;
+	__u8 poll;
+	__u8 special_mask;
+	__u8 init_state;
+	__u8 auto_eoi;
+	__u8 rotate_on_auto_eoi;
+	__u8 special_fully_nested_mode;
+	__u8 init4;		/* true if 4 byte init */
+	__u8 elcr;		/* PIIX edge/trigger selection */
+	__u8 elcr_mask;
+	struct kvm_pic *pics_state;
+};
+#define KVM_IRQCHIP_SAVE_LEN	\
+	(sizeof(struct kvm_pic_state) - sizeof(struct kvm_pic *))
+
+struct kvm_irqchip {
+	__u8  chip_id;
+	__u8  pad1;
+        __u16 pad2;
+        union {
+		struct kvm_pic_state pic;
+	} chip;
+};
+
+enum kvm_irqchip_id {
+	KVM_IRQCHIP_PIC_MASTER	 = 0,
+	KVM_IRQCHIP_PIC_SLAVE	 = 1,
+	KVM_IRQCHIP_IOAPIC	 = 2,
+};
+
 enum kvm_exit_reason {
 	KVM_EXIT_UNKNOWN          = 0,
 	KVM_EXIT_EXCEPTION        = 1,
@@ -304,6 +342,8 @@ struct kvm_signal_mask {
 /* Device model IOC */
 #define KVM_CREATE_PIC		  _IO(KVMIO,  0x60)
 #define KVM_IRQ_LINE		  _IOW(KVMIO, 0x61, struct kvm_irq_level)
+#define KVM_GET_IRQCHIP		  _IOWR(KVMIO, 0x62, struct kvm_irqchip)
+#define KVM_SET_IRQCHIP		  _IOR(KVMIO,  0x63, struct kvm_irqchip)
 
 /*
  * ioctls for vcpu fds
@@ -322,5 +362,7 @@ struct kvm_signal_mask {
 #define KVM_SET_SIGNAL_MASK       _IOW(KVMIO,  0x8b, struct kvm_signal_mask)
 #define KVM_GET_FPU               _IOR(KVMIO,  0x8c, struct kvm_fpu)
 #define KVM_SET_FPU               _IOW(KVMIO,  0x8d, struct kvm_fpu)
+#define KVM_GET_LAPIC             _IOW(KVMIO,  0x8e, struct kvm_lapic)
+#define KVM_SET_LAPIC             _IOW(KVMIO,  0x8f, struct kvm_lapic)
 
 #endif

[-- Attachment #3: live_u1.patch --]
[-- Type: application/octet-stream, Size: 4797 bytes --]

diff --git a/kernel/Kbuild b/kernel/Kbuild
index ceb6e4b..a502c02 100644
--- a/kernel/Kbuild
+++ b/kernel/Kbuild
@@ -1,5 +1,5 @@
 EXTRA_CFLAGS := -I$(src)/include -include $(src)/external-module-compat.h
 obj-m := kvm.o kvm-intel.o kvm-amd.o
-kvm-objs := kvm_main.o mmu.o x86_emulate.o anon_inodes.o irq.o i8259.o lapic.o
+kvm-objs := kvm_main.o mmu.o x86_emulate.o anon_inodes.o irq.o i8259.o lapic.o ioapic.o
 kvm-intel-objs := vmx.o vmx-debug.o
 kvm-amd-objs := svm.o
diff --git a/qemu/hw/i8259.c b/qemu/hw/i8259.c
index 117340c..2dcaf7a 100644
--- a/qemu/hw/i8259.c
+++ b/qemu/hw/i8259.c
@@ -581,3 +581,26 @@ void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
     s->alt_irq_func = alt_irq_func;
     s->alt_irq_opaque = alt_irq_opaque;
 }
+
+void pic_k2u(void *s, int id, void *buf, int len)
+{
+    PicState *pic = &((PicState2*)s)->pics[id];
+    if (len != sizeof(PicState)) {
+	printf("Kernel/User PIC device model state different\n");
+	return;
+    }
+    len -= sizeof(PicState2 *);
+    memcpy(pic, buf, len);
+}
+
+void pic_u2k(void *s, int id, void *buf, int len)
+{
+    PicState *pic = &((PicState2*)s)->pics[id];
+    if (len != sizeof(PicState)) {
+	printf("Kernel/User PIC device model state different\n");
+	return;
+    }
+    len -= sizeof(PicState2 *);
+    memcpy(buf, pic, len);
+}
+
diff --git a/qemu/migration.c b/qemu/migration.c
index 6053c98..f60fe6d 100644
--- a/qemu/migration.c
+++ b/qemu/migration.c
@@ -29,6 +29,8 @@
 #endif
 
 #include <sys/wait.h>
+extern void kvm_irqchip_k2u(void);
+extern void kvm_irqchip_u2k(void);
 
 #define MIN_FINALIZE_SIZE	(200 << 10)
 #define MAX_ITERATIONS           30
@@ -180,6 +182,7 @@ static void migrate_finish(MigrationState *s)
         bdrv_flush_all();
         vm_stop(0);
         qemu_put_be32(f, 1);
+	kvm_irqchip_k2u();
         ret = qemu_live_savevm_state(f);
 #ifdef MIGRATION_VERIFY
         save_verify_memory(f, NULL);
@@ -840,6 +843,7 @@ static int migrate_incoming_fd(int fd)
     vm_stop(0);
     if (qemu_live_loadvm_state(f))
         ret = MIG_STAT_DST_LOADVM_FAILED;
+    kvm_irqchip_u2k();
 #ifdef MIGRATION_VERIFY
     if (ret==0) ret=load_verify_memory(f, NULL, 1);
 #endif /* MIGRATION_VERIFY */
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index 1c7c14e..1c864b7 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -140,6 +140,35 @@ static void fix_realmode_dataseg(struct kvm_segment *seg)
 	seg->s = 1;
 }
 
+extern void *isa_pic;
+extern void pic_k2u(void *s, int id, void *buf, int len);
+extern void pic_u2k(void *s, int id, void *buf, int len);
+void kvm_irqchip_u2k()
+{
+    struct kvm_irqchip chip;
+
+    pic_u2k (isa_pic, 1, &chip.chip, sizeof(chip.chip));
+    chip.chip_id = KVM_IRQCHIP_PIC_MASTER;
+    kvm_set_irqchip(kvm_context, &chip);
+
+    pic_u2k (isa_pic, 0, &chip.chip, sizeof(chip.chip));
+    chip.chip_id = KVM_IRQCHIP_PIC_SLAVE;
+    kvm_set_irqchip(kvm_context, &chip);
+}
+
+void kvm_irqchip_k2u()
+{
+    struct kvm_irqchip chip;
+
+    chip.chip_id = KVM_IRQCHIP_PIC_MASTER;
+    kvm_get_irqchip(kvm_context, &chip);
+    pic_k2u (isa_pic, 1, &chip.chip, sizeof(chip.chip));
+
+    chip.chip_id = KVM_IRQCHIP_PIC_SLAVE;
+    kvm_get_irqchip(kvm_context, &chip);
+    pic_k2u (isa_pic, 0, &chip.chip, sizeof(chip.chip));
+}
+
 static void load_regs(CPUState *env)
 {
     struct kvm_regs regs;
diff --git a/user/kvmctl.c b/user/kvmctl.c
index d610111..00a6131 100644
--- a/user/kvmctl.c
+++ b/user/kvmctl.c
@@ -428,10 +428,34 @@ int kvm_set_irq_level(kvm_context_t kvm, int irq, int level)
 	event.irq = irq;
 	r = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &event);
 	if (r == -1)
-		perror("kvm_set_irq_level");
+		perror("kvm_set_irq_level\n");
 	return 1;
 }
 
+int kvm_get_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip)
+{
+    int r;
+
+    if (!kvm->irqchip_in_kernel)
+	return 0;
+    r = ioctl(kvm->vm_fd, KVM_GET_IRQCHIP, chip);
+    if (r == -1)
+	perror("kvm_get_irqchip\n");
+    return 1;
+}
+
+int kvm_set_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip)
+{
+    int r;
+
+    if (!kvm->irqchip_in_kernel)
+	return 0;
+    r = ioctl(kvm->vm_fd, KVM_SET_IRQCHIP, chip);
+    if (r == -1)
+	perror("kvm_set_irqchip\n");
+    return 1;
+}
+
 static int handle_io_abi10(kvm_context_t kvm, struct kvm_run_abi10 *run,
 			   int vcpu)
 {
diff --git a/user/kvmctl.h b/user/kvmctl.h
index 68e1664..1bcfd15 100644
--- a/user/kvmctl.h
+++ b/user/kvmctl.h
@@ -413,5 +413,8 @@ int kvm_dirty_pages_log_enable_all(kvm_context_t kvm);
  * \param kvm Pointer to the current kvm_context
  */
 int kvm_dirty_pages_log_reset(kvm_context_t kvm);
+int kvm_get_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip);
+int kvm_set_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip);
+int kvm_set_irq_level(kvm_context_t kvm, int irq, int level);
 
 #endif

[-- Attachment #4: Type: text/plain, Size: 315 bytes --]

-------------------------------------------------------------------------
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/

[-- Attachment #5: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: preview of in kernel irqchip live migration support
       [not found] ` <10EA09EFD8728347A513008B6B0DA77A01D15BAB-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
@ 2007-07-24  9:46   ` Avi Kivity
  2007-07-25  7:12   ` Dor Laor
  1 sibling, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2007-07-24  9:46 UTC (permalink / raw)
  To: Dong, Eddie; +Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Dong, Eddie wrote:
> This patch is only for idea collection so far.
> The dilemma is that how to export the pic/IOAPIC/apic state data
> structure
> to user and make sure it has same/similar structure in user level.
> Otherwise a
> convert is a must and we must maintain the converter.
>
>   

I think we have to have a converter, we can't tie the kernel to qemu or 
vice versa.

It's just a series of assignments, I don't see an issue with it.


> With this, PIC only guest can do live migration successfully. We can
> extend
> APIC side seamlessly.
>
> BTW, there is potential issue in IDT_Vectoring. The fix IMO is to retry
> vm_stop at user level
> to make sure no pending IDT_vectoring.
>   

I agree.  How do we tell userspace we need to retry, though?  A field in 
kvm_run?  A field in the lapic state?

> Pls comments. Also I will temply off this week, Qing He may continue.
>
> Thx,eddie
>
>
> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> index 5307ba3..4eee80d 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -51,6 +51,44 @@ struct kvm_irq_level {
>  	__u32 level;
>  };
>  
> +/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
> +struct kvm_pic_state {
> +	__u8 last_irr;	/* edge detection */
> +	__u8 irr;		/* interrupt request register */
> +	__u8 imr;		/* interrupt mask register */
> +	__u8 isr;		/* interrupt service register */
> +	__u8 priority_add;	/* highest irq priority */
> +	__u8 irq_base;
> +	__u8 read_reg_select;
> +	__u8 poll;
> +	__u8 special_mask;
> +	__u8 init_state;
> +	__u8 auto_eoi;
> +	__u8 rotate_on_auto_eoi;
> +	__u8 special_fully_nested_mode;
> +	__u8 init4;		/* true if 4 byte init */
> +	__u8 elcr;		/* PIIX edge/trigger selection */
> +	__u8 elcr_mask;
> +	struct kvm_pic *pics_state;
> +};
>   

You can't have this pointer in the userspace interface.

Also, please ensure that sizeof(struct kvm_pic_state) does not change in 
32/64 bit environments, since it gets embedded in the ioctl number.


-- 
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
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/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: preview of in kernel irqchip live migration support
       [not found] ` <10EA09EFD8728347A513008B6B0DA77A01D15BAB-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
  2007-07-24  9:46   ` Avi Kivity
@ 2007-07-25  7:12   ` Dor Laor
       [not found]     ` <64F9B87B6B770947A9F8391472E032160CD8CAD6-yEcIvxbTEBqsx+V+t5oei8rau4O3wl8o3fe8/T/H7NteoWH0uzbU5w@public.gmane.org>
  1 sibling, 1 reply; 4+ messages in thread
From: Dor Laor @ 2007-07-25  7:12 UTC (permalink / raw)
  To: Dong, Eddie, kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

>This patch is only for idea collection so far.
>The dilemma is that how to export the pic/IOAPIC/apic state data
>structure to user and make sure it has same/similar structure in user
>level.
>Otherwise a
>convert is a must and we must maintain the converter.

IMHO  there is no need of supporting migration from/to kernel/user.
The main point of maintaining pic/apic/ioapic in to test our
implementation against
a stable working implementation. Once the kernel implementation will be
stable 
there is no need to support the userspace. 

btw: Why don't you use the standard qemu's register_savev//loadvm for
saving the state?
I think it's better than adding code in migration.c


>With this, PIC only guest can do live migration successfully. We can
>extend APIC side seamlessly.
>
>BTW, there is potential issue in IDT_Vectoring. The fix IMO is to retry
>vm_stop at user level to make sure no pending IDT_vectoring.

Isn't it possible to serialize the pending IDT_vectoring too?
If the answer is no, the solution is to add an ioctl that will test the
pending
statis in migration.c::migrate_check_convergence. If it's pending, add
another 
migrate_write loop iteration.

>
>Pls comments. Also I will temply off this week, Qing He may continue.
>
>Thx,eddie



-------------------------------------------------------------------------
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/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: preview of in kernel irqchip live migration support
       [not found]     ` <64F9B87B6B770947A9F8391472E032160CD8CAD6-yEcIvxbTEBqsx+V+t5oei8rau4O3wl8o3fe8/T/H7NteoWH0uzbU5w@public.gmane.org>
@ 2007-07-25  7:30       ` Avi Kivity
  0 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2007-07-25  7:30 UTC (permalink / raw)
  To: Dor Laor; +Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Dor Laor wrote:
>> This patch is only for idea collection so far.
>> The dilemma is that how to export the pic/IOAPIC/apic state data
>> structure to user and make sure it has same/similar structure in user
>> level.
>> Otherwise a
>> convert is a must and we must maintain the converter.
>>     
>
> IMHO  there is no need of supporting migration from/to kernel/user.
> The main point of maintaining pic/apic/ioapic in to test our
> implementation against
> a stable working implementation. Once the kernel implementation will be
> stable 
> there is no need to support the userspace. 
>
>   

No, we have to support 2.6.22 and 2.6.23 which don't have in-kernel apic.

We need to avoid multiple migration (and state save) formats.

>   
>> With this, PIC only guest can do live migration successfully. We can
>> extend APIC side seamlessly.
>>
>> BTW, there is potential issue in IDT_Vectoring. The fix IMO is to retry
>> vm_stop at user level to make sure no pending IDT_vectoring.
>>     
>
> Isn't it possible to serialize the pending IDT_vectoring too?
> If the answer is no, the solution is to add an ioctl that will test the
> pending
> statis in migration.c::migrate_check_convergence. If it's pending, add
> another 
> migrate_write loop iteration.
>   

IDT_vectoring is am implementation detail, we don't want to expose it in
the migration protocol because it ties us up.  Best to avoid it.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
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/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-07-25  7:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-24  5:48 preview of in kernel irqchip live migration support Dong, Eddie
     [not found] ` <10EA09EFD8728347A513008B6B0DA77A01D15BAB-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-07-24  9:46   ` Avi Kivity
2007-07-25  7:12   ` Dor Laor
     [not found]     ` <64F9B87B6B770947A9F8391472E032160CD8CAD6-yEcIvxbTEBqsx+V+t5oei8rau4O3wl8o3fe8/T/H7NteoWH0uzbU5w@public.gmane.org>
2007-07-25  7:30       ` Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox