* 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