[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 02/17] xen: hook io_apic read/write operations
In Xen, writes to the IO APIC are paravirtualized via hypercalls, so implement the appropriate operations. This version of the patch just hooks the io_apic read/write functions directly, rather than introducing another layer of indirection. The xen_initial_domain() tests compile to 0 if CONFIG_XEN_DOM0 isn't set, and are cheap if it is. (An alternative would be to add io_apic_ops, and point them to the Xen implementation as needed. HPA deemed this extra level of indirection to be excessive.) Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx> --- arch/x86/include/asm/io_apic.h | 6 ++++ arch/x86/kernel/apic/io_apic.c | 32 ++++++++++++++++++++-- arch/x86/xen/Makefile | 2 +- arch/x86/xen/apic.c | 57 ++++++++++++++++++++++++++++++++++++++++ arch/x86/xen/enlighten.c | 2 + arch/x86/xen/xen-ops.h | 6 ++++ 6 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 arch/x86/xen/apic.c diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 59cb4a1..20b543a 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -183,4 +183,10 @@ static inline void ioapic_init_mappings(void) { } static inline void probe_nr_irqs_gsi(void) { } #endif +void xen_io_apic_init(void); +unsigned int xen_io_apic_read(unsigned apic, unsigned reg); +void xen_io_apic_write(unsigned int apic, + unsigned int reg, unsigned int value); + + #endif /* _ASM_X86_IO_APIC_H */ diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 00e6071..6d14ff9 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -62,8 +62,10 @@ #include <asm/uv/uv_hub.h> #include <asm/uv/uv_irq.h> +#include <asm/xen/hypervisor.h> #include <asm/apic.h> + #define __apicdebuginit(type) static type __init /* @@ -399,14 +401,26 @@ static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) { - struct io_apic __iomem *io_apic = io_apic_base(apic); + struct io_apic __iomem *io_apic; + + if (xen_initial_domain()) + return xen_io_apic_read(apic, reg); + + 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) { - struct io_apic __iomem *io_apic = io_apic_base(apic); + struct io_apic __iomem *io_apic; + + if (xen_initial_domain()) { + xen_io_apic_write(apic, reg, value); + return; + } + + io_apic = io_apic_base(apic); writel(reg, &io_apic->index); writel(value, &io_apic->data); } @@ -419,7 +433,14 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i */ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) { - struct io_apic __iomem *io_apic = io_apic_base(apic); + struct io_apic __iomem *io_apic; + + if (xen_initial_domain()) { + xen_io_apic_write(apic, reg, value); + return; + } + + io_apic = io_apic_base(apic); if (sis_apic_bug) writel(reg, &io_apic->index); @@ -4099,6 +4120,11 @@ void __init ioapic_init_mappings(void) struct resource *ioapic_res; int i; + if (xen_initial_domain()) { + xen_io_apic_init(); + return; + } + ioapic_res = ioapic_setup_resources(); for (i = 0; i < nr_ioapics; i++) { if (smp_found_config) { diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index c4cda96..73ecb74 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile @@ -11,4 +11,4 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ obj-$(CONFIG_SMP) += smp.o spinlock.o obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o -obj-$(CONFIG_XEN_DOM0) += vga.o +obj-$(CONFIG_XEN_DOM0) += vga.o apic.o diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c new file mode 100644 index 0000000..17736a0 --- /dev/null +++ b/arch/x86/xen/apic.c @@ -0,0 +1,57 @@ +#include <linux/kernel.h> +#include <linux/threads.h> +#include <linux/bitmap.h> + +#include <asm/io_apic.h> +#include <asm/acpi.h> + +#include <asm/xen/hypervisor.h> +#include <asm/xen/hypercall.h> + +#include <xen/interface/xen.h> +#include <xen/interface/physdev.h> + +void __init xen_io_apic_init(void) +{ + printk("xen apic init\n"); + dump_stack(); +} + +unsigned int xen_io_apic_read(unsigned apic, unsigned reg) +{ + struct physdev_apic apic_op; + int ret; + + apic_op.apic_physbase = mp_ioapics[apic].apicaddr; + apic_op.reg = reg; + ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op); + if (ret) + BUG(); + return apic_op.value; +} + + +void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) +{ + struct physdev_apic apic_op; + + apic_op.apic_physbase = mp_ioapics[apic].apicaddr; + apic_op.reg = reg; + apic_op.value = value; + if (HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op)) + BUG(); +} + +void xen_init_apic(void) +{ + if (!xen_initial_domain()) + return; + +#ifdef CONFIG_ACPI + /* + * Pretend ACPI found our lapic even though we've disabled it, + * to prevent MP tables from setting up lapics. + */ + acpi_lapic = 1; +#endif +} diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index f673cd8..a9a7d15 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1027,6 +1027,8 @@ asmlinkage void __init xen_start_kernel(void) set_iopl.iopl = 1; if (HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl) == -1) BUG(); + + xen_init_apic(); } /* set the limit of our address space */ diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 4dad0ad..8f4d9a8 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h @@ -85,6 +85,12 @@ static inline void xen_init_vga(const struct dom0_vga_console_info *info, } #endif +#ifdef CONFIG_XEN_DOM0 +void xen_init_apic(void); +#else +static inline void xen_init_apic(void) {} +#endif + /* Declare an asm function, along with symbols needed to make it inlineable */ #define DECL_ASM(ret, name, ...) \ -- 1.6.0.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |