Hi,
        The argument of in-kernel irqchip save/restore IOCTL uses a
separate data structure (struct kvm_irqchip and struct kvm_ioctl_pic in
include/linux/kvm.h) different from functional data structure (struct
kvm_pic_state and struct kvm_ioapic in driver/kvm/irq.h), this is
because while most data are used at both side, there are certain
internal data in functional data structure which should not be exposed
to the user.
        Current code has some duplication between these two, and these
duplicated parts are copied back and forth when save and restore. This
seems a maintenance pain.
        I have come to two different possible solutions, but there are
some coding style concerns:
        1. use macro definitions to sort out the common part,. The
problem is that this is not so elegant and I hardly find anything
similar in kernel code.
        2. organize the common part into a new struct, and include this
struct into ioctl argument and functional data structure. The problem of
this approach is that we have to re-write many codes to make things like
`s->irr' changing to `s->state.irr'.

        The preliminary patches are attached. Parts of them are against
an IOAPIC save/restore patch which is not committed in the lapic3
branch, but the ideas are there.

Any comments and suggestions?

Thanks,
Qing


-------- cleanup-irqchip-struct-alt1.diff ----
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index b744ac4..e1aaafb 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -27,22 +27,7 @@
 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;
+       KVM_DEFINE_PIC_STATE
        struct kvm_pic *pics_state;
 };
 
@@ -80,27 +65,7 @@ void kvm_pic_update_irq(struct kvm_pic *s);
 #define IOAPIC_REG_ARB_ID  0x02        /* x86 IOAPIC only */
 
 struct kvm_ioapic {
-       u64 base_address;
-       u32 ioregsel;
-       u32 id;
-       u32 irr;
-       u32 pad;
-       union ioapic_redir_entry {
-               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[IOAPIC_NUM_PINS];
+       KVM_DEFINE_IOAPIC_STATE
        struct kvm_io_device dev;
        struct kvm *kvm;
 };
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index df58a9d..31df8f6 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -45,49 +45,56 @@ struct kvm_irq_level {
        __u32 level;
 };
 
-/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
-struct kvm_ioctl_pic {
-       __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 */
+/* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */
+#define KVM_DEFINE_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_ioctl_pic {
+       KVM_DEFINE_PIC_STATE
 };
 
 #define KVM_IOAPIC_NUM_PINS  24
+union ioapic_redir_entry {
+       __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;
+};
+#define KVM_DEFINE_IOAPIC_STATE        \
+       __u64 base_address;                                     \
+       __u32 ioregsel;                                         \
+       __u32 id;                                               \
+       __u32 irr;                                              \
+       __u32 pad;                                              \
+       union ioapic_redir_entry redirtbl[KVM_IOAPIC_NUM_PINS];
+
 struct kvm_ioctl_ioapic {
-       __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];
+       KVM_DEFINE_IOAPIC_STATE
 };
 
 enum kvm_irqchip_id {



------cleanup-irqchip-struct-alt2.diff ----

diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index 8c417f6..dd91543 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -31,8 +31,9 @@
 /*
  * set irq level. If an edge is detected, then the IRR is set to 1
  */
-static inline void pic_set_irq1(struct kvm_pic_state *s, int irq, int
level)
+static inline void pic_set_irq1(struct kvm_pic_chip *c, int irq, int
level)
 {
+       struct kvm_pic_state *s = &c->state;
        int mask;
        mask = 1 << irq;
        if (s->elcr & mask)     /* level triggered */
@@ -56,13 +57,13 @@ static inline void pic_set_irq1(struct kvm_pic_state
*s, int irq, int level)
  * return the highest priority found in mask (highest = smallest
  * number). Return 8 if no irq
  */
-static inline int get_priority(struct kvm_pic_state *s, int mask)
+static inline int get_priority(struct kvm_pic_chip *c, int mask)
 {
        int priority;
        if (mask == 0)
                return 8;
        priority = 0;
-       while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
+       while ((mask & (1 << ((priority + c->state.priority_add) & 7)))
== 0)
                priority++;
        return priority;
 }
@@ -70,12 +71,13 @@ static inline int get_priority(struct kvm_pic_state
*s, int mask)
 /*
  * return the pic wanted interrupt. return -1 if none
  */
-static int pic_get_irq(struct kvm_pic_state *s)
+static int pic_get_irq(struct kvm_pic_chip *c)
 {
+       struct kvm_pic_state *s = &c->state;
        int mask, cur_priority, priority;
 
        mask = s->irr & ~s->imr;
-       priority = get_priority(s, mask);
+       priority = get_priority(c, mask);
        if (priority == 8)
                return -1;
        /*
@@ -84,9 +86,9 @@ static int pic_get_irq(struct kvm_pic_state *s)
         * for the priority computation.
         */
        mask = s->isr;
-       if (s->special_fully_nested_mode && s ==
&s->pics_state->pics[0])
+       if (s->special_fully_nested_mode && c ==
&c->pics_state->pics[0])
                mask &= ~(1 << 2);
-       cur_priority = get_priority(s, mask);
+       cur_priority = get_priority(c, mask);
        if (priority < cur_priority)
                /*
                 * higher priority found: an irq should be generated
@@ -135,8 +137,10 @@ void kvm_pic_set_irq(void *opaque, int irq, int
level)
 /*
  * acknowledge interrupt 'irq'
  */
-static inline void pic_intack(struct kvm_pic_state *s, int irq)
+static inline void pic_intack(struct kvm_pic_chip *c, int irq)
 {
+       struct kvm_pic_state *s = &c->state;
+
        if (s->auto_eoi) {
                if (s->rotate_on_auto_eoi)
                        s->priority_add = (irq + 1) & 7;
@@ -165,16 +169,16 @@ int kvm_pic_read_irq(struct kvm_pic *s)
                                 * spurious IRQ on slave controller
                                 */
                                irq2 = 7;
-                       intno = s->pics[1].irq_base + irq2;
+                       intno = s->pics[1].state.irq_base + irq2;
                        irq = irq2 + 8;
                } else
-                       intno = s->pics[0].irq_base + irq;
+                       intno = s->pics[0].state.irq_base + irq;
        } else {
                /*
                 * spurious IRQ on host controller
                 */
                irq = 7;
-               intno = s->pics[0].irq_base + irq;
+               intno = s->pics[0].state.irq_base + irq;
        }
        pic_update_irq(s);
 
@@ -183,7 +187,7 @@ int kvm_pic_read_irq(struct kvm_pic *s)
 
 static void pic_reset(void *opaque)
 {
-       struct kvm_pic_state *s = opaque;
+       struct kvm_pic_state *s = &((struct kvm_pic_chip *)
opaque)->state;
 
        s->last_irr = 0;
        s->irr = 0;
@@ -203,17 +207,18 @@ static void pic_reset(void *opaque)
 
 static void pic_ioport_write(void *opaque, u32 addr, u32 val)
 {
-       struct kvm_pic_state *s = opaque;
+       struct kvm_pic_chip *c = opaque;
+       struct kvm_pic_state *s = &c->state;
        int priority, cmd, irq;
 
        addr &= 1;
        if (addr == 0) {
                if (val & 0x10) {
-                       pic_reset(s);   /* init */
+                       pic_reset(c);   /* init */
                        /*
                         * deassert a pending interrupt
                         */
-                       s->pics_state->irq_request(s->pics_state->
+                       c->pics_state->irq_request(c->pics_state->
                                                   irq_request_opaque,
0);
                        s->init_state = 1;
                        s->init4 = val & 1;
@@ -238,29 +243,29 @@ static void pic_ioport_write(void *opaque, u32
addr, u32 val)
                                break;
                        case 1: /* end of interrupt */
                        case 5:
-                               priority = get_priority(s, s->isr);
+                               priority = get_priority(c, s->isr);
                                if (priority != 8) {
                                        irq = (priority +
s->priority_add) & 7;
                                        s->isr &= ~(1 << irq);
                                        if (cmd == 5)
                                                s->priority_add = (irq +
1) & 7;
-                                       pic_update_irq(s->pics_state);
+                                       pic_update_irq(c->pics_state);
                                }
                                break;
                        case 3:
                                irq = val & 7;
                                s->isr &= ~(1 << irq);
-                               pic_update_irq(s->pics_state);
+                               pic_update_irq(c->pics_state);
                                break;
                        case 6:
                                s->priority_add = (val + 1) & 7;
-                               pic_update_irq(s->pics_state);
+                               pic_update_irq(c->pics_state);
                                break;
                        case 7:
                                irq = val & 7;
                                s->isr &= ~(1 << irq);
                                s->priority_add = (irq + 1) & 7;
-                               pic_update_irq(s->pics_state);
+                               pic_update_irq(c->pics_state);
                                break;
                        default:
                                break;  /* no operation */
@@ -270,7 +275,7 @@ static void pic_ioport_write(void *opaque, u32 addr,
u32 val)
                switch (s->init_state) {
                case 0:         /* normal mode */
                        s->imr = val;
-                       pic_update_irq(s->pics_state);
+                       pic_update_irq(c->pics_state);
                        break;
                case 1:
                        s->irq_base = val & 0xf8;
@@ -290,23 +295,24 @@ static void pic_ioport_write(void *opaque, u32
addr, u32 val)
                }
 }
 
-static u32 pic_poll_read(struct kvm_pic_state *s, u32 addr1)
+static u32 pic_poll_read(struct kvm_pic_chip *c, u32 addr1)
 {
+       struct kvm_pic_state *s = &c->state;
        int ret;
 
-       ret = pic_get_irq(s);
+       ret = pic_get_irq(c);
        if (ret >= 0) {
                if (addr1 >> 7) {
-                       s->pics_state->pics[0].isr &= ~(1 << 2);
-                       s->pics_state->pics[0].irr &= ~(1 << 2);
+                       c->pics_state->pics[0].state.isr &= ~(1 << 2);
+                       c->pics_state->pics[0].state.irr &= ~(1 << 2);
                }
                s->irr &= ~(1 << ret);
                s->isr &= ~(1 << ret);
                if (addr1 >> 7 || ret != 2)
-                       pic_update_irq(s->pics_state);
+                       pic_update_irq(c->pics_state);
        } else {
                ret = 0x07;
-               pic_update_irq(s->pics_state);
+               pic_update_irq(c->pics_state);
        }
 
        return ret;
@@ -314,14 +320,15 @@ static u32 pic_poll_read(struct kvm_pic_state *s,
u32 addr1)
 
 static u32 pic_ioport_read(void *opaque, u32 addr1)
 {
-       struct kvm_pic_state *s = opaque;
+       struct kvm_pic_chip *c = opaque;
+       struct kvm_pic_state *s = &c->state;
        unsigned int addr;
        int ret;
 
        addr = addr1;
        addr &= 1;
        if (s->poll) {
-               ret = pic_poll_read(s, addr1);
+               ret = pic_poll_read(c, addr1);
                s->poll = 0;
        } else
                if (addr == 0)
@@ -336,14 +343,14 @@ static u32 pic_ioport_read(void *opaque, u32
addr1)
 
 static void elcr_ioport_write(void *opaque, u32 addr, u32 val)
 {
-       struct kvm_pic_state *s = opaque;
-       s->elcr = val & s->elcr_mask;
+       struct kvm_pic_chip *c = opaque;
+       c->state.elcr = val & c->state.elcr_mask;
 }
 
 static u32 elcr_ioport_read(void *opaque, u32 addr1)
 {
-       struct kvm_pic_state *s = opaque;
-       return s->elcr;
+       struct kvm_pic_chip *c = opaque;
+       return c->state.elcr;
 }
 
 static int picdev_in_range(struct kvm_io_device *this, gpa_t addr)
@@ -431,8 +438,8 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
        s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
        if (!s)
                return NULL;
-       s->pics[0].elcr_mask = 0xf8;
-       s->pics[1].elcr_mask = 0xde;
+       s->pics[0].state.elcr_mask = 0xf8;
+       s->pics[1].state.elcr_mask = 0xde;
        s->irq_request = pic_irq_request;
        s->irq_request_opaque = kvm;
        s->pics[0].pics_state = s;
diff --git a/drivers/kvm/ioapic.c b/drivers/kvm/ioapic.c
index 3ee13c3..cc336dc 100644
--- a/drivers/kvm/ioapic.c
+++ b/drivers/kvm/ioapic.c
@@ -49,7 +49,7 @@ static unsigned long ioapic_read_indirect(struct
kvm_ioapic *ioapic,
 {
        unsigned long result = 0;
 
-       switch (ioapic->ioregsel) {
+       switch (ioapic->state.ioregsel) {
        case IOAPIC_REG_VERSION:
                result = ((((IOAPIC_NUM_PINS - 1) & 0xff) << 16)
                          | (IOAPIC_VERSION_ID & 0xff));
@@ -57,18 +57,18 @@ static unsigned long ioapic_read_indirect(struct
kvm_ioapic *ioapic,
 
        case IOAPIC_REG_APIC_ID:
        case IOAPIC_REG_ARB_ID:
-               result = ((ioapic->id & 0xf) << 24);
+               result = ((ioapic->state.id & 0xf) << 24);
                break;
 
        default:
                {
-                       u32 redir_index = (ioapic->ioregsel - 0x10) >>
1;
+                       u32 redir_index = (ioapic->state.ioregsel -
0x10) >> 1;
                        u64 redir_content;
 
                        ASSERT(redir_index < IOAPIC_NUM_PINS);
 
-                       redir_content =
ioapic->redirtbl[redir_index].bits;
-                       result = (ioapic->ioregsel & 0x1) ?
+                       redir_content =
ioapic->state.redirtbl[redir_index].bits;
+                       result = (ioapic->state.ioregsel & 0x1) ?
                            (redir_content >> 32) & 0xffffffff :
                            redir_content & 0xffffffff;
                        break;
@@ -82,7 +82,7 @@ static void ioapic_service(struct kvm_ioapic *ioapic,
unsigned int idx)
 {
        union ioapic_redir_entry *pent;
 
-       pent = &ioapic->redirtbl[idx];
+       pent = &ioapic->state.redirtbl[idx];
 
        if (!pent->fields.mask) {
                ioapic_deliver(ioapic, idx);
@@ -95,30 +95,30 @@ static void ioapic_write_indirect(struct kvm_ioapic
*ioapic, u32 val)
 {
        int index;
 
-       switch (ioapic->ioregsel) {
+       switch (ioapic->state.ioregsel) {
        case IOAPIC_REG_VERSION:
                /* Writes are ignored. */
                break;
 
        case IOAPIC_REG_APIC_ID:
-               ioapic->id = (val >> 24) & 0xf;
+               ioapic->state.id = (val >> 24) & 0xf;
                break;
 
        case IOAPIC_REG_ARB_ID:
                break;
 
        default:
-               index = (ioapic->ioregsel - 0x10) >> 1;
+               index = (ioapic->state.ioregsel - 0x10) >> 1;
 
                ioapic_debug("change redir index %x val %x", index,
val);
                ASSERT(irq < IOAPIC_NUM_PINS);
-               if (ioapic->ioregsel & 1) {
-                       ioapic->redirtbl[index].bits &= 0xffffffff;
-                       ioapic->redirtbl[index].bits |= (u64) val << 32;
+               if (ioapic->state.ioregsel & 1) {
+                       ioapic->state.redirtbl[index].bits &=
0xffffffff;
+                       ioapic->state.redirtbl[index].bits |= (u64) val
<< 32;
                } else {
-                       ioapic->redirtbl[index].bits &= ~0xffffffffULL;
-                       ioapic->redirtbl[index].bits |= (u32) val;
-                       ioapic->redirtbl[index].fields.remote_irr = 0;
+                       ioapic->state.redirtbl[index].bits &=
~0xffffffffULL;
+                       ioapic->state.redirtbl[index].bits |= (u32) val;
+                       ioapic->state.redirtbl[index].fields.remote_irr
= 0;
                }
                ioapic_service(ioapic, index);
                break;
@@ -180,11 +180,11 @@ static u32 ioapic_get_delivery_bitmask(struct
kvm_ioapic *ioapic, u8 dest,
 
 static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
 {
-       u8 dest = ioapic->redirtbl[irq].fields.dest_id;
-       u8 dest_mode = ioapic->redirtbl[irq].fields.dest_mode;
-       u8 delivery_mode = ioapic->redirtbl[irq].fields.delivery_mode;
-       u8 vector = ioapic->redirtbl[irq].fields.vector;
-       u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode;
+       u8 dest = ioapic->state.redirtbl[irq].fields.dest_id;
+       u8 dest_mode = ioapic->state.redirtbl[irq].fields.dest_mode;
+       u8 delivery_mode =
ioapic->state.redirtbl[irq].fields.delivery_mode;
+       u8 vector = ioapic->state.redirtbl[irq].fields.vector;
+       u8 trig_mode = ioapic->state.redirtbl[irq].fields.trig_mode;
        u32 deliver_bitmask;
        struct kvm_lapic *target;
        struct kvm_vcpu *vcpu;
@@ -240,19 +240,19 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic,
int irq, int level)
        union ioapic_redir_entry entry;
 
        if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
-               entry = ioapic->redirtbl[irq];
+               entry = ioapic->state.redirtbl[irq];
                if (!level)
-                       ioapic->irr &= ~mask;
+                       ioapic->state.irr &= ~mask;
                if (entry.fields.trig_mode) {   /* level triggered */
                        if (level && !entry.fields.remote_irr) {
-                               ioapic->irr |= mask;
+                               ioapic->state.irr |= mask;
                                ioapic_service(ioapic, irq);
                        }
-               } else if (level && !(ioapic->irr & mask)) {
+               } else if (level && !(ioapic->state.irr & mask)) {
                        /*
                         * edge triggered
                         */
-                       ioapic->irr |= mask;
+                       ioapic->state.irr |= mask;
                        ioapic_service(ioapic, irq);
                }
        }
@@ -263,7 +263,7 @@ static int get_eoi_gsi(struct kvm_ioapic *ioapic,
int vector)
        int i;
 
        for (i = 0; i < IOAPIC_NUM_PINS; i++)
-               if (ioapic->redirtbl[i].fields.vector == vector)
+               if (ioapic->state.redirtbl[i].fields.vector == vector)
                        return i;
        return -1;
 }
@@ -281,7 +281,7 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int
vector)
                return;
        }
 
-       ent = &ioapic->redirtbl[gsi];
+       ent = &ioapic->state.redirtbl[gsi];
        ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
 
        ent->fields.remote_irr = 0;
@@ -303,8 +303,8 @@ static int ioapic_in_range(struct kvm_io_device
*this, gpa_t addr)
 {
        struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
 
-       return ((addr >= ioapic->base_address &&
-                (addr < ioapic->base_address + IOAPIC_MEM_LENGTH)));
+       return ((addr >= ioapic->state.base_address &&
+                (addr < ioapic->state.base_address +
IOAPIC_MEM_LENGTH)));
 }
 
 static void ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr,
int len,
@@ -319,7 +319,7 @@ static void ioapic_mmio_read(struct kvm_io_device
*this, gpa_t addr, int len,
        addr &= 0xff;
        switch (addr) {
        case IOAPIC_REG_SELECT:
-               result = ioapic->ioregsel;
+               result = ioapic->state.ioregsel;
                break;
 
        case IOAPIC_REG_WINDOW:
@@ -363,7 +363,7 @@ static void ioapic_mmio_write(struct kvm_io_device
*this, gpa_t addr, int len,
        addr &= 0xff;
        switch (addr) {
        case IOAPIC_REG_SELECT:
-               ioapic->ioregsel = data;
+               ioapic->state.ioregsel = data;
                break;
 
        case IOAPIC_REG_WINDOW:
@@ -385,8 +385,8 @@ int kvm_ioapic_init(struct kvm *kvm)
                return -ENOMEM;
        kvm->vioapic = ioapic;
        for (i = 0; i < IOAPIC_NUM_PINS; i++)
-               ioapic->redirtbl[i].fields.mask = 1;
-       ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS;
+               ioapic->state.redirtbl[i].fields.mask = 1;
+       ioapic->state.base_address = IOAPIC_DEFAULT_BASE_ADDRESS;
        ioapic->dev.read = ioapic_mmio_read;
        ioapic->dev.write = ioapic_mmio_write;
        ioapic->dev.in_range = ioapic_in_range;
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index b744ac4..0d59cd8 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -26,28 +26,13 @@
 
 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_chip {
+       struct kvm_pic_state state;
        struct kvm_pic *pics_state;
 };
 
 struct kvm_pic {
-       struct kvm_pic_state pics[2]; /* 0 is master pic, 1 is slave pic
*/
+       struct kvm_pic_chip pics[2]; /* 0 is master pic, 1 is slave pic
*/
        irq_request_func *irq_request;
        void *irq_request_opaque;
        int output;             /* intr from master PIC */
@@ -80,27 +65,7 @@ void kvm_pic_update_irq(struct kvm_pic *s);
 #define IOAPIC_REG_ARB_ID  0x02        /* x86 IOAPIC only */
 
 struct kvm_ioapic {
-       u64 base_address;
-       u32 ioregsel;
-       u32 id;
-       u32 irr;
-       u32 pad;
-       union ioapic_redir_entry {
-               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[IOAPIC_NUM_PINS];
+       struct kvm_ioapic_state state;
        struct kvm_io_device dev;
        struct kvm *kvm;
 };
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 7d06f6d..efce884 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -915,18 +915,18 @@ static int kvm_vm_ioctl_get_irqchip(struct kvm
*kvm, struct kvm_irqchip *chip)
        switch (chip->chip_id) {
        case KVM_IRQCHIP_PIC_MASTER:
                memcpy (&chip->chip.pic,
-                       &pic_irqchip(kvm)->pics[0],
-                       sizeof(struct kvm_ioctl_pic));
+                       &pic_irqchip(kvm)->pics[0].state,
+                       sizeof(struct kvm_pic_state));
                break;
        case KVM_IRQCHIP_PIC_SLAVE:
                memcpy (&chip->chip.pic,
-                       &pic_irqchip(kvm)->pics[1],
-                       sizeof(struct kvm_ioctl_pic));
+                       &pic_irqchip(kvm)->pics[1].state,
+                       sizeof(struct kvm_pic_state));
                break;
        case KVM_IRQCHIP_IO_APIC:
                memcpy (&chip->chip.ioapic,
-                       ioapic_irqchip(kvm),
-                       sizeof(struct kvm_ioctl_ioapic));
+                       &ioapic_irqchip(kvm)->state,
+                       sizeof(struct kvm_ioapic_state));
                break;
        default:
                r = -EINVAL;
@@ -942,19 +942,19 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm
*kvm, struct kvm_irqchip *chip)
        r = 0;
        switch (chip->chip_id) {
        case KVM_IRQCHIP_PIC_MASTER:
-               memcpy (&pic_irqchip(kvm)->pics[0],
+               memcpy (&pic_irqchip(kvm)->pics[0].state,
                        &chip->chip.pic,
-                       sizeof(struct kvm_ioctl_pic));
+                       sizeof(struct kvm_pic_state));
                break;
        case KVM_IRQCHIP_PIC_SLAVE:
-               memcpy (&pic_irqchip(kvm)->pics[1],
+               memcpy (&pic_irqchip(kvm)->pics[1].state,
                        &chip->chip.pic,
-                       sizeof(struct kvm_ioctl_pic));
+                       sizeof(struct kvm_pic_state));
                break;
        case KVM_IRQCHIP_IO_APIC:
-               memcpy (ioapic_irqchip(kvm),
+               memcpy (&ioapic_irqchip(kvm)->state,
                        &chip->chip.ioapic,
-                       sizeof(struct kvm_ioctl_ioapic));
+                       sizeof(struct kvm_ioapic_state));
                break;
        default:
                r = -EINVAL;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index df58a9d..6d3d60c 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -45,8 +45,8 @@ struct kvm_irq_level {
        __u32 level;
 };
 
-/* for KVM_GET_IRQCHIP / KVM_SET_IRQCHIP */
-struct kvm_ioctl_pic {
+/* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */
+struct kvm_pic_state {
        __u8 last_irr;  /* edge detection */
        __u8 irr;               /* interrupt request register */
        __u8 imr;               /* interrupt mask register */
@@ -66,13 +66,13 @@ struct kvm_ioctl_pic {
 };
 
 #define KVM_IOAPIC_NUM_PINS  24
-struct kvm_ioctl_ioapic {
+struct kvm_ioapic_state {
        __u64 base_address;
        __u32 ioregsel;
        __u32 id;
        __u32 irr;
        __u32 pad;
-       union {
+       union ioapic_redir_entry {
                __u64 bits;
                struct {
                        __u8 vector;
@@ -101,8 +101,8 @@ struct kvm_irqchip {
        __u32 pad;
         union {
                char dummy[512];  /* reserving space */
-               struct kvm_ioctl_pic pic;
-               struct kvm_ioctl_ioapic ioapic;
+               struct kvm_pic_state pic;
+               struct kvm_ioapic_state ioapic;
        } chip;
 };

Attachment: cleanup-irqchip-struct-alt1.diff
Description: cleanup-irqchip-struct-alt1.diff

Attachment: cleanup-irqchip-struct-alt2.diff
Description: cleanup-irqchip-struct-alt2.diff

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

Reply via email to