lkml.org 
[lkml]   [2012]   [Mar]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/3] x86: add io_apic_ops to allow interception
    Date
    From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>

    Xen dom0 needs to paravirtualize IO operations to the IO APIC, so add
    a io_apic_ops for it to intercept. Do this as ops structure because
    there's at least some chance that another paravirtualized environment
    may want to intercept these.

    [ Impact: indirect IO APIC access via io_apic_ops ]

    Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
    Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
    ---
    arch/x86/include/asm/io_apic.h | 9 +++++++
    arch/x86/kernel/apic/io_apic.c | 50 +++++++++++++++++++++++++++++++++++++--
    2 files changed, 56 insertions(+), 3 deletions(-)

    diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
    index 690d1cc..190d8c2 100644
    --- a/arch/x86/include/asm/io_apic.h
    +++ b/arch/x86/include/asm/io_apic.h
    @@ -21,6 +21,15 @@
    #define IO_APIC_REDIR_LEVEL_TRIGGER (1 << 15)
    #define IO_APIC_REDIR_MASKED (1 << 16)

    +struct io_apic_ops {
    + void (*init)(void);
    + unsigned int (*read)(unsigned int apic, unsigned int reg);
    + void (*write)(unsigned int apic, unsigned int reg, unsigned int value);
    + void (*modify)(unsigned int apic, unsigned int reg, unsigned int value);
    +};
    +
    +void __init set_io_apic_ops(const struct io_apic_ops *);
    +
    /*
    * The structure of the IO-APIC:
    */
    diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
    index fb07275..bf120234 100644
    --- a/arch/x86/kernel/apic/io_apic.c
    +++ b/arch/x86/kernel/apic/io_apic.c
    @@ -67,6 +67,25 @@
    #define for_each_irq_pin(entry, head) \
    for (entry = head; entry; entry = entry->next)

    +static void __init __ioapic_init_mappings(void);
    +static unsigned int __io_apic_read(unsigned int apic, unsigned int reg);
    +static void __io_apic_write(unsigned int apic, unsigned int reg,
    + unsigned int val);
    +static void __io_apic_modify(unsigned int apic, unsigned int reg,
    + unsigned int val);
    +
    +static struct io_apic_ops io_apic_ops = {
    + .init = __ioapic_init_mappings,
    + .read = __io_apic_read,
    + .write = __io_apic_write,
    + .modify = __io_apic_modify,
    +};
    +
    +void __init set_io_apic_ops(const struct io_apic_ops *ops)
    +{
    + io_apic_ops = *ops;
    +}
    +
    /*
    * Is the SiS APIC rmw bug present ?
    * -1 = don't know, 0 = no, 1 = yes
    @@ -294,6 +313,24 @@ static void free_irq_at(unsigned int at, struct irq_cfg *cfg)
    irq_free_desc(at);
    }

    +static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
    +{
    + return io_apic_ops.read(apic, reg);
    +}
    +
    +static inline void io_apic_write(unsigned int apic, unsigned int reg,
    + unsigned int value)
    +{
    + io_apic_ops.write(apic, reg, value);
    +}
    +
    +static inline void io_apic_modify(unsigned int apic, unsigned int reg,
    + unsigned int value)
    +{
    + io_apic_ops.modify(apic, reg, value);
    +}
    +
    +
    struct io_apic {
    unsigned int index;
    unsigned int unused[3];
    @@ -314,14 +351,15 @@ static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
    writel(vector, &io_apic->eoi);
    }

    -static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
    +static unsigned int __io_apic_read(unsigned int apic, unsigned int reg)
    {
    struct io_apic __iomem *io_apic = io_apic_base(apic);
    writel(reg, &io_apic->index);
    return readl(&io_apic->data);
    }

    -static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
    +static void __io_apic_write(unsigned int apic, unsigned int reg,
    + unsigned int value)
    {
    struct io_apic __iomem *io_apic = io_apic_base(apic);
    writel(reg, &io_apic->index);
    @@ -334,7 +372,8 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i
    *
    * Older SiS APIC requires we rewrite the index register
    */
    -static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
    +static void __io_apic_modify(unsigned int apic, unsigned int reg,
    + unsigned int value)
    {
    struct io_apic __iomem *io_apic = io_apic_base(apic);

    @@ -3873,6 +3912,11 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics)

    void __init ioapic_and_gsi_init(void)
    {
    + io_apic_ops.init();
    +}
    +
    +static void __init __ioapic_init_mappings(void)
    +{
    unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
    struct resource *ioapic_res;
    int i;
    --
    1.7.7.5


    \
     
     \ /
      Last update: 2012-03-22 04:05    [W:0.056 / U:31.448 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site