2006-05-09 08:50:40

by Chris Wright

[permalink] [raw]
Subject: [RFC PATCH 16/35] subarch support for interrupt and exception gates

Abstract the code that sets up interrupt and exception gates, and
add a separate subarch implementation for Xen.

Signed-off-by: Ian Pratt <[email protected]>
Signed-off-by: Christian Limpach <[email protected]>
Signed-off-by: Chris Wright <[email protected]>
---
arch/i386/kernel/traps.c | 49 ---------------------------
include/asm-i386/mach-default/mach_idt.h | 52 +++++++++++++++++++++++++++++
include/asm-i386/mach-xen/mach_idt.h | 50 +++++++++++++++++++++++++++
include/asm-i386/mach-xen/setup_arch_pre.h | 2 +
4 files changed, 105 insertions(+), 48 deletions(-)

--- linus-2.6.orig/arch/i386/kernel/traps.c
+++ linus-2.6/arch/i386/kernel/traps.c
@@ -1086,54 +1086,7 @@ void __init trap_init_f00f_bug(void)
}
#endif

-#define _set_gate(gate_addr,type,dpl,addr,seg) \
-do { \
- int __d0, __d1; \
- __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
- "movw %4,%%dx\n\t" \
- "movl %%eax,%0\n\t" \
- "movl %%edx,%1" \
- :"=m" (*((long *) (gate_addr))), \
- "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
- :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
- "3" ((char *) (addr)),"2" ((seg) << 16)); \
-} while (0)
-
-
-/*
- * This needs to use 'idt_table' rather than 'idt', and
- * thus use the _nonmapped_ version of the IDT, as the
- * Pentium F0 0F bugfix can have resulted in the mapped
- * IDT being write-protected.
- */
-void set_intr_gate(unsigned int n, void *addr)
-{
- _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
-}
-
-/*
- * This routine sets up an interrupt gate at directory privilege level 3.
- */
-static inline void set_system_intr_gate(unsigned int n, void *addr)
-{
- _set_gate(idt_table+n, 14, 3, addr, __KERNEL_CS);
-}
-
-static void __init set_trap_gate(unsigned int n, void *addr)
-{
- _set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
-}
-
-static void __init set_system_gate(unsigned int n, void *addr)
-{
- _set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
-}
-
-static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
-{
- _set_gate(idt_table+n,5,0,0,(gdt_entry<<3));
-}
-
+#include <mach_idt.h>

void __init trap_init(void)
{
--- linus-2.6.orig/include/asm-i386/mach-xen/setup_arch_pre.h
+++ linus-2.6/include/asm-i386/mach-xen/setup_arch_pre.h
@@ -5,6 +5,8 @@
struct start_info *xen_start_info;
EXPORT_SYMBOL(xen_start_info);

+struct trap_info xen_trap_table[257];
+
/*
* Point at the empty zero page to start with. We map the real shared_info
* page as soon as fixmap is up and running.
--- /dev/null
+++ linus-2.6/include/asm-i386/mach-default/mach_idt.h
@@ -0,0 +1,52 @@
+#ifndef __ASM_MACH_IDT_H
+#define __ASM_MACH_IDT_H
+
+#define _set_gate(gate_addr,type,dpl,addr,seg) \
+do { \
+ int __d0, __d1; \
+ __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
+ "movw %4,%%dx\n\t" \
+ "movl %%eax,%0\n\t" \
+ "movl %%edx,%1" \
+ :"=m" (*((long *) (gate_addr))), \
+ "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
+ :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
+ "3" ((char *) (addr)),"2" ((seg) << 16)); \
+} while (0)
+
+
+/*
+ * This needs to use 'idt_table' rather than 'idt', and
+ * thus use the _nonmapped_ version of the IDT, as the
+ * Pentium F0 0F bugfix can have resulted in the mapped
+ * IDT being write-protected.
+ */
+void set_intr_gate(unsigned int n, void *addr)
+{
+ _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
+}
+
+/*
+ * This routine sets up an interrupt gate at directory privilege level 3.
+ */
+static inline void set_system_intr_gate(unsigned int n, void *addr)
+{
+ _set_gate(idt_table+n, 14, 3, addr, __KERNEL_CS);
+}
+
+static void __init set_trap_gate(unsigned int n, void *addr)
+{
+ _set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
+}
+
+static void __init set_system_gate(unsigned int n, void *addr)
+{
+ _set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
+}
+
+static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
+{
+ _set_gate(idt_table+n,5,0,0,(gdt_entry<<3));
+}
+
+#endif /* __ASM_MACH_IDT_H */
--- /dev/null
+++ linus-2.6/include/asm-i386/mach-xen/mach_idt.h
@@ -0,0 +1,50 @@
+#ifndef __ASM_MACH_IDT_H
+#define __ASM_MACH_IDT_H
+
+static inline void _set_gate(unsigned int vector, uint8_t type, uint8_t dpl,
+ void *addr, uint16_t seg)
+{
+ struct trap_info *t = xen_trap_table;
+
+ BUG_ON(vector > 256);
+
+ while (t->address && t->vector != vector)
+ t++;
+
+ t->vector = vector;
+ t->cs = seg;
+ TI_SET_DPL(t, dpl);
+ if (type == 14 || vector == 7)
+ TI_SET_IF(t, 1);
+ t->address = (unsigned long)addr;
+}
+
+void set_intr_gate(unsigned int n, void *addr)
+{
+ _set_gate(n, 14, 0, addr, __KERNEL_CS);
+}
+
+/*
+ * This routine sets up an interrupt gate at directory privilege level 3.
+ */
+static inline void set_system_intr_gate(unsigned int n, void *addr)
+{
+ _set_gate(n, 14, 3, addr, __KERNEL_CS);
+}
+
+static void __init set_trap_gate(unsigned int n, void *addr)
+{
+ _set_gate(n, 15, 0, addr, __KERNEL_CS);
+}
+
+static void __init set_system_gate(unsigned int n, void *addr)
+{
+ _set_gate(n, 15, 3, addr, __KERNEL_CS);
+}
+
+static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
+{
+ /* _set_gate(n, 5, 0, 0, (gdt_entry<<3)); */
+}
+
+#endif /* __ASM_MACH_IDT_H */

--


2006-05-09 11:15:28

by Andi Kleen

[permalink] [raw]
Subject: Re: [RFC PATCH 16/35] subarch support for interrupt and exception gates


> +/*
> + * This needs to use 'idt_table' rather than 'idt', and
> + * thus use the _nonmapped_ version of the IDT, as the
> + * Pentium F0 0F bugfix can have resulted in the mapped
> + * IDT being write-protected.
> + */
> +void set_intr_gate(unsigned int n, void *addr)
> +{
> + _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
> +}

No need to duplicate the various set_*_gate functions into the subarchs.


> +static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
> +{
> + /* _set_gate(n, 5, 0, 0, (gdt_entry<<3)); */
> +}

Looks weird, but can be handled in the low level function.

-Andi

2006-05-09 12:55:51

by Christian Limpach

[permalink] [raw]
Subject: Re: [RFC PATCH 16/35] subarch support for interrupt and exception gates

On Tue, May 09, 2006 at 01:09:49PM +0200, Andi Kleen wrote:
>
> > +/*
> > + * This needs to use 'idt_table' rather than 'idt', and
> > + * thus use the _nonmapped_ version of the IDT, as the
> > + * Pentium F0 0F bugfix can have resulted in the mapped
> > + * IDT being write-protected.
> > + */
> > +void set_intr_gate(unsigned int n, void *addr)
> > +{
> > + _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
> > +}
>
> No need to duplicate the various set_*_gate functions into the subarchs.

Indeed, we'll change that. Thanks.

christian

> > +static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
> > +{
> > + /* _set_gate(n, 5, 0, 0, (gdt_entry<<3)); */
> > +}
>
> Looks weird, but can be handled in the low level function.
>
> -Andi

> _______________________________________________
> Virtualization mailing list
> [email protected]
> https://lists.osdl.org/mailman/listinfo/virtualization

2006-05-13 12:30:50

by Andrew Morton

[permalink] [raw]
Subject: Re: [RFC PATCH 16/35] subarch support for interrupt and exception gates

On Tue, 09 May 2006 00:00:16 -0700
Chris Wright <[email protected]> wrote:

> --- linus-2.6.orig/include/asm-i386/mach-xen/setup_arch_pre.h
> +++ linus-2.6/include/asm-i386/mach-xen/setup_arch_pre.h
> @@ -5,6 +5,8 @@
> struct start_info *xen_start_info;
> EXPORT_SYMBOL(xen_start_info);
>
> +struct trap_info xen_trap_table[257];
> +
> /*
> * Point at the empty zero page to start with. We map the real shared_info
> * page as soon as fixmap is up and running.

Is there any particular reason why things-which-should-be-in-a-C-file are
present in a .h file?

2006-05-15 18:27:31

by Chris Wright

[permalink] [raw]
Subject: Re: [RFC PATCH 16/35] subarch support for interrupt and exception gates

* Andrew Morton ([email protected]) wrote:
> On Tue, 09 May 2006 00:00:16 -0700
> Chris Wright <[email protected]> wrote:
>
> > --- linus-2.6.orig/include/asm-i386/mach-xen/setup_arch_pre.h
> > +++ linus-2.6/include/asm-i386/mach-xen/setup_arch_pre.h
> > @@ -5,6 +5,8 @@
> > struct start_info *xen_start_info;
> > EXPORT_SYMBOL(xen_start_info);
> >
> > +struct trap_info xen_trap_table[257];
> > +
> > /*
> > * Point at the empty zero page to start with. We map the real shared_info
> > * page as soon as fixmap is up and running.
>
> Is there any particular reason why things-which-should-be-in-a-C-file are
> present in a .h file?

It's following direction of current subarch interaction with setup.c
(namely the setup_arch_post.h). It's definitely not so nice.