From: He, Qing <[EMAIL PROTECTED]>

This patch adds support for in-kernel ioapic save and restore (to
and from userspace). It uses the same get/set_irqchip ioctl as
in-kernel PIC.

Signed-off-by: Qing He <[EMAIL PROTECTED]>
Signed-off-by: Yaozu (Eddie) Dong <[EMAIL PROTECTED]>
Signed-off-by: Avi Kivity <[EMAIL PROTECTED]>
---
 drivers/kvm/irq.h      |    9 +++++----
 drivers/kvm/kvm.h      |    5 +++++
 drivers/kvm/kvm_main.c |   10 ++++++++++
 include/linux/kvm.h    |   29 ++++++++++++++++++++++++++++-
 4 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index e0133e6..30adddc 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -61,7 +61,7 @@ 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_NUM_PINS  KVM_IOAPIC_NUM_PINS
 #define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */
 #define IOAPIC_EDGE_TRIG  0
 #define IOAPIC_LEVEL_TRIG 1
@@ -80,12 +80,11 @@ void kvm_pic_update_irq(struct kvm_pic *s);
 #define IOAPIC_REG_ARB_ID  0x02        /* x86 IOAPIC only */
 
 struct kvm_ioapic {
-       struct kvm_io_device dev;
-       unsigned long base_address;
-       struct kvm *kvm;
+       u64 base_address;
        u32 ioregsel;
        u32 id;
        u32 irr;
+       u32 pad;
        union ioapic_redir_entry {
                u64 bits;
                struct {
@@ -102,6 +101,8 @@ struct kvm_ioapic {
                        u8 dest_id;
                } fields;
        } redirtbl[IOAPIC_NUM_PINS];
+       struct kvm_io_device dev;
+       struct kvm *kvm;
 };
 
 struct kvm_lapic {
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index f69b482..bb506b7 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -420,6 +420,11 @@ static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
        return kvm->vpic;
 }
 
+static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
+{
+       return kvm->vioapic;
+}
+
 static inline int irqchip_in_kernel(struct kvm *kvm)
 {
        return pic_irqchip(kvm) != 0;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index c270e4a..61dff55 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -913,6 +913,11 @@ static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, 
struct kvm_irqchip *chip)
                        &pic_irqchip(kvm)->pics[1],
                        sizeof(struct kvm_pic_state));
                break;
+       case KVM_IRQCHIP_IOAPIC:
+               memcpy (&chip->chip.ioapic,
+                       ioapic_irqchip(kvm),
+                       sizeof(struct kvm_ioapic_state));
+               break;
        default:
                r = -EINVAL;
                break;
@@ -936,6 +941,11 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, 
struct kvm_irqchip *chip)
                        &chip->chip.pic,
                        sizeof(struct kvm_pic_state));
                break;
+       case KVM_IRQCHIP_IOAPIC:
+               memcpy (ioapic_irqchip(kvm),
+                       &chip->chip.ioapic,
+                       sizeof(struct kvm_ioapic_state));
+               break;
        default:
                r = -EINVAL;
                break;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 6560f11..42d1515 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -45,7 +45,7 @@ struct kvm_irq_level {
        __u32 level;
 };
 
-/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
+/* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */
 struct kvm_pic_state {
        __u8 last_irr;  /* edge detection */
        __u8 irr;               /* interrupt request register */
@@ -65,9 +65,35 @@ struct kvm_pic_state {
        __u8 elcr_mask;
 };
 
+#define KVM_IOAPIC_NUM_PINS  24
+struct kvm_ioapic_state {
+       __u64 base_address;
+       __u32 ioregsel;
+       __u32 id;
+       __u32 irr;
+       __u32 pad;
+       union {
+               __u64 bits;
+               struct {
+                       __u8 vector;
+                       __u8 delivery_mode:3;
+                       __u8 dest_mode:1;
+                       __u8 delivery_status:1;
+                       __u8 polarity:1;
+                       __u8 remote_irr:1;
+                       __u8 trig_mode:1;
+                       __u8 mask:1;
+                       __u8 reserve:7;
+                       __u8 reserved[4];
+                       __u8 dest_id;
+               } fields;
+       } redirtbl[KVM_IOAPIC_NUM_PINS];
+};
+
 enum kvm_irqchip_id {
        KVM_IRQCHIP_PIC_MASTER   = 0,
        KVM_IRQCHIP_PIC_SLAVE    = 1,
+       KVM_IRQCHIP_IOAPIC       = 2,
 };
 
 struct kvm_irqchip {
@@ -76,6 +102,7 @@ struct kvm_irqchip {
         union {
                char dummy[512];  /* reserving space */
                struct kvm_pic_state pic;
+               struct kvm_ioapic_state ioapic;
        } chip;
 };
 
-- 
1.5.3


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to