WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [patch 11/26] Xen-paravirt_ops: Use patch site IDs computed

To: Andi Kleen <ak@xxxxxx>
Subject: [Xen-devel] [patch 11/26] Xen-paravirt_ops: Use patch site IDs computed from offset in paravirt_ops structure
From: Jeremy Fitzhardinge <jeremy@xxxxxxxx>
Date: Tue, 27 Feb 2007 00:13:48 -0800
Cc: Zachary Amsden <zach@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx, Rusty Russell <rusty@xxxxxxxxxxxxxxx>, linux-kernel@xxxxxxxxxxxxxxx, Chris Wright <chrisw@xxxxxxxxxxxx>, virtualization@xxxxxxxxxxxxxx, Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Delivery-date: Tue, 27 Feb 2007 00:47:48 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20070227081337.434798469@xxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: quilt/0.46-1
Use patch type identifiers derived from the offset of the operation in
the paravirt_ops structure.  This avoids having to maintain a separate
enum for patch site types.

This patch also drops the fused save_fl+cli operation, which doesn't
really add much and makes things more complex.

Signed-off-by: Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx>
Cc: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Cc: Zachary Amsden <zach@xxxxxxxxxx>

---
 arch/i386/kernel/asm-offsets.c |    5 +
 arch/i386/kernel/paravirt.c    |   14 ++---
 arch/i386/kernel/vmi.c         |   38 ++------------
 include/asm-i386/paravirt.h    |  106 ++++++++++++++++++++--------------------
 4 files changed, 70 insertions(+), 93 deletions(-)

===================================================================
--- a/arch/i386/kernel/asm-offsets.c
+++ b/arch/i386/kernel/asm-offsets.c
@@ -110,5 +110,10 @@ void foo(void)
        OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
        OFFSET(PARAVIRT_iret, paravirt_ops, iret);
        OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
+
+       DEFINE(PARAVIRT_IRQ_DISABLE, PARAVIRT_PATCH(irq_disable));
+       DEFINE(PARAVIRT_IRQ_ENABLE, PARAVIRT_PATCH(irq_enable));
+       DEFINE(PARAVIRT_STI_SYSEXIT, PARAVIRT_PATCH(irq_enable_sysexit));
+       DEFINE(PARAVIRT_INTERRUPT_RETURN, PARAVIRT_PATCH(iret));
 #endif
 }
===================================================================
--- a/arch/i386/kernel/paravirt.c
+++ b/arch/i386/kernel/paravirt.c
@@ -57,7 +57,6 @@ DEF_NATIVE(sti, "sti");
 DEF_NATIVE(sti, "sti");
 DEF_NATIVE(popf, "push %eax; popf");
 DEF_NATIVE(pushf, "pushf; pop %eax");
-DEF_NATIVE(pushf_cli, "pushf; pop %eax; cli");
 DEF_NATIVE(iret, "iret");
 DEF_NATIVE(sti_sysexit, "sti; sysexit");
 
@@ -65,13 +64,12 @@ static const struct native_insns
 {
        const char *start, *end;
 } native_insns[] = {
-       [PARAVIRT_IRQ_DISABLE] = { start_cli, end_cli },
-       [PARAVIRT_IRQ_ENABLE] = { start_sti, end_sti },
-       [PARAVIRT_RESTORE_FLAGS] = { start_popf, end_popf },
-       [PARAVIRT_SAVE_FLAGS] = { start_pushf, end_pushf },
-       [PARAVIRT_SAVE_FLAGS_IRQ_DISABLE] = { start_pushf_cli, end_pushf_cli },
-       [PARAVIRT_INTERRUPT_RETURN] = { start_iret, end_iret },
-       [PARAVIRT_STI_SYSEXIT] = { start_sti_sysexit, end_sti_sysexit },
+       [PARAVIRT_PATCH(irq_disable)] = { start_cli, end_cli },
+       [PARAVIRT_PATCH(irq_enable)] = { start_sti, end_sti },
+       [PARAVIRT_PATCH(restore_fl)] = { start_popf, end_popf },
+       [PARAVIRT_PATCH(save_fl)] = { start_pushf, end_pushf },
+       [PARAVIRT_PATCH(iret)] = { start_iret, end_iret },
+       [PARAVIRT_PATCH(irq_enable_sysexit)] = { start_sti_sysexit, 
end_sti_sysexit },
 };
 
 static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len)
===================================================================
--- a/arch/i386/kernel/vmi.c
+++ b/arch/i386/kernel/vmi.c
@@ -78,11 +78,6 @@ struct {
 #define MNEM_JMP  0xe9
 #define MNEM_RET  0xc3
 
-static char irq_save_disable_callout[] = {
-       MNEM_CALL, 0, 0, 0, 0,
-       MNEM_CALL, 0, 0, 0, 0,
-       MNEM_RET
-};
 #define IRQ_PATCH_INT_MASK 0
 #define IRQ_PATCH_DISABLE  5
 
@@ -130,33 +125,17 @@ static unsigned vmi_patch(u8 type, u16 c
 static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len)
 {
        switch (type) {
-               case PARAVIRT_IRQ_DISABLE:
+               case PARAVIRT_PATCH(irq_disable):
                        return patch_internal(VMI_CALL_DisableInterrupts, len, 
insns);
-               case PARAVIRT_IRQ_ENABLE:
+               case PARAVIRT_PATCH(irq_enable):
                        return patch_internal(VMI_CALL_EnableInterrupts, len, 
insns);
-               case PARAVIRT_RESTORE_FLAGS:
+               case PARAVIRT_PATCH(restore_fl):
                        return patch_internal(VMI_CALL_SetInterruptMask, len, 
insns);
-               case PARAVIRT_SAVE_FLAGS:
+               case PARAVIRT_PATCH(save_fl):
                        return patch_internal(VMI_CALL_GetInterruptMask, len, 
insns);
-               case PARAVIRT_SAVE_FLAGS_IRQ_DISABLE:
-                       if (len >= 10) {
-                               patch_internal(VMI_CALL_GetInterruptMask, len, 
insns);
-                               patch_internal(VMI_CALL_DisableInterrupts, 
len-5, insns+5);
-                               return 10;
-                       } else {
-                               /*
-                                * You bastards didn't leave enough room to
-                                * patch save_flags_irq_disable inline.  Patch
-                                * to a helper
-                                */
-                               BUG_ON(len < 5);
-                               *(char *)insns = MNEM_CALL;
-                               patch_offset(insns, irq_save_disable_callout);
-                               return 5;
-                       }
-               case PARAVIRT_INTERRUPT_RETURN:
+               case PARAVIRT_PATCH(iret):
                        return patch_internal(VMI_CALL_IRET, len, insns);
-               case PARAVIRT_STI_SYSEXIT:
+               case PARAVIRT_PATCH(irq_enable_sysexit):
                        return patch_internal(VMI_CALL_SYSEXIT, len, insns);
                default:
                        break;
@@ -733,11 +712,6 @@ static inline int __init activate_vmi(vo
        para_fill(restore_fl, SetInterruptMask);
        para_fill(irq_disable, DisableInterrupts);
        para_fill(irq_enable, EnableInterrupts);
-       /* irq_save_disable !!! sheer pain */
-       patch_offset(&irq_save_disable_callout[IRQ_PATCH_INT_MASK],
-                    (char *)paravirt_ops.save_fl);
-       patch_offset(&irq_save_disable_callout[IRQ_PATCH_DISABLE],
-                    (char *)paravirt_ops.irq_disable);
 #ifndef CONFIG_NO_IDLE_HZ
        para_fill(safe_halt, Halt);
 #else
===================================================================
--- a/include/asm-i386/paravirt.h
+++ b/include/asm-i386/paravirt.h
@@ -3,19 +3,9 @@
 /* Various instructions on x86 need to be replaced for
  * para-virtualization: those hooks are defined here. */
 #include <linux/linkage.h>
-#include <linux/stringify.h>
 #include <asm/page.h>
 
 #ifdef CONFIG_PARAVIRT
-/* These are the most performance critical ops, so we want to be able to patch
- * callers */
-#define PARAVIRT_IRQ_DISABLE 0
-#define PARAVIRT_IRQ_ENABLE 1
-#define PARAVIRT_RESTORE_FLAGS 2
-#define PARAVIRT_SAVE_FLAGS 3
-#define PARAVIRT_SAVE_FLAGS_IRQ_DISABLE 4
-#define PARAVIRT_INTERRUPT_RETURN 5
-#define PARAVIRT_STI_SYSEXIT 6
 
 /* Bitmask of what can be clobbered: usually at least eax. */
 #define CLBR_NONE 0x0
@@ -26,6 +16,23 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
+
+#define paravirt_type(type)            [paravirt_typenum] "i" (type)
+#define paravirt_clobber(clobber)      [paravirt_clobber] "i" (clobber)
+
+#define PARAVIRT_PATCH(x)              (offsetof(struct paravirt_ops, x) / 
sizeof(void *))
+
+#define _paravirt_alt(insn_string, type, clobber)      \
+       "771:\n\t" insn_string "\n" "772:\n"            \
+       ".pushsection .parainstructions,\"a\"\n"        \
+       "  .long 771b\n"                                \
+       "  .byte " type "\n"                            \
+       "  .byte 772b-771b\n"                           \
+       "  .short " clobber "\n"                        \
+       ".popsection\n"
+
+#define paravirt_alt(insn_string)                              \
+       _paravirt_alt(insn_string, "%c[paravirt_typenum]", 
"%c[paravirt_clobber]")
 
 struct thread_struct;
 struct Xgt_desc_struct;
@@ -540,24 +547,16 @@ extern struct paravirt_patch_site __star
 extern struct paravirt_patch_site __start_parainstructions[],
        __stop_parainstructions[];
 
-#define paravirt_alt(insn_string, typenum, clobber)    \
-       "771:\n\t" insn_string "\n" "772:\n"            \
-       ".pushsection .parainstructions,\"a\"\n"        \
-       "  .long 771b\n"                                \
-       "  .byte " __stringify(typenum) "\n"            \
-       "  .byte 772b-771b\n"                           \
-       "  .short " __stringify(clobber) "\n"           \
-       ".popsection"
-
 static inline unsigned long __raw_local_save_flags(void)
 {
        unsigned long f;
 
        __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;"
                                           "call *%1;"
-                                          "popl %%edx; popl %%ecx",
-                                         PARAVIRT_SAVE_FLAGS, CLBR_NONE)
-                            : "=a"(f): "m"(paravirt_ops.save_fl)
+                                          "popl %%edx; popl %%ecx")
+                            : "=a"(f): "m"(paravirt_ops.save_fl),
+                              paravirt_type(PARAVIRT_PATCH(save_fl)),
+                              paravirt_clobber(CLBR_NONE)
                             : "memory", "cc");
        return f;
 }
@@ -566,9 +565,10 @@ static inline void raw_local_irq_restore
 {
        __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;"
                                           "call *%1;"
-                                          "popl %%edx; popl %%ecx",
-                                         PARAVIRT_RESTORE_FLAGS, CLBR_EAX)
-                            : "=a"(f) : "m" (paravirt_ops.restore_fl), "0"(f)
+                                          "popl %%edx; popl %%ecx")
+                            : "=a"(f) : "m" (paravirt_ops.restore_fl), "0"(f),
+                              paravirt_type(PARAVIRT_PATCH(restore_fl)),
+                              paravirt_clobber(CLBR_EAX)
                             : "memory", "cc");
 }
 
@@ -576,9 +576,10 @@ static inline void raw_local_irq_disable
 {
        __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;"
                                           "call *%0;"
-                                          "popl %%edx; popl %%ecx",
-                                         PARAVIRT_IRQ_DISABLE, CLBR_EAX)
-                            : : "m" (paravirt_ops.irq_disable)
+                                          "popl %%edx; popl %%ecx")
+                            : : "m" (paravirt_ops.irq_disable),
+                              paravirt_type(PARAVIRT_PATCH(irq_disable)),
+                              paravirt_clobber(CLBR_EAX)
                             : "memory", "eax", "cc");
 }
 
@@ -586,9 +587,10 @@ static inline void raw_local_irq_enable(
 {
        __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;"
                                           "call *%0;"
-                                          "popl %%edx; popl %%ecx",
-                                         PARAVIRT_IRQ_ENABLE, CLBR_EAX)
-                            : : "m" (paravirt_ops.irq_enable)
+                                          "popl %%edx; popl %%ecx")
+                            : : "m" (paravirt_ops.irq_enable),
+                              paravirt_type(PARAVIRT_PATCH(irq_enable)),
+                              paravirt_clobber(CLBR_EAX)
                             : "memory", "eax", "cc");
 }
 
@@ -596,33 +598,31 @@ static inline unsigned long __raw_local_
 {
        unsigned long f;
 
-       __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;"
-                                          "call *%1; pushl %%eax;"
-                                          "call *%2; popl %%eax;"
-                                          "popl %%edx; popl %%ecx",
-                                         PARAVIRT_SAVE_FLAGS_IRQ_DISABLE,
-                                         CLBR_NONE)
-                            : "=a"(f)
-                            : "m" (paravirt_ops.save_fl),
-                              "m" (paravirt_ops.irq_disable)
-                            : "memory", "cc");
+       f = __raw_local_save_flags();
+       raw_local_irq_disable();
+
        return f;
 }
 
-#define CLI_STRING paravirt_alt("pushl %%ecx; pushl %%edx;"            \
-                    "call *paravirt_ops+%c[irq_disable];"              \
-                    "popl %%edx; popl %%ecx",                          \
-                    PARAVIRT_IRQ_DISABLE, CLBR_EAX)
-
-#define STI_STRING paravirt_alt("pushl %%ecx; pushl %%edx;"            \
-                    "call *paravirt_ops+%c[irq_enable];"               \
-                    "popl %%edx; popl %%ecx",                          \
-                    PARAVIRT_IRQ_ENABLE, CLBR_EAX)
+#define CLI_STRING _paravirt_alt("pushl %%ecx; pushl %%edx;"           \
+                                "call *paravirt_ops+%c[irq_disable];"  \
+                                "popl %%edx; popl %%ecx",              \
+                                "%c[paravirt_cli_type]", 
"%c[paravirt_clobber]")
+
+#define STI_STRING _paravirt_alt("pushl %%ecx; pushl %%edx;"           \
+                               "call *paravirt_ops+%c[irq_enable];"    \
+                                "popl %%edx; popl %%ecx",              \
+                                "%c[paravirt_cli_type]", 
"%c[paravirt_clobber]")
+
+
 #define CLI_STI_CLOBBERS , "%eax"
-#define CLI_STI_INPUT_ARGS \
+#define CLI_STI_INPUT_ARGS                                             \
        ,                                                               \
-       [irq_disable] "i" (offsetof(struct paravirt_ops, irq_disable)), \
-       [irq_enable] "i" (offsetof(struct paravirt_ops, irq_enable))
+               [irq_disable] "i" (offsetof(struct paravirt_ops, irq_disable)), 
\
+               [irq_enable] "i" (offsetof(struct paravirt_ops, irq_enable)), \
+               [paravirt_cli_type] "i" (PARAVIRT_PATCH(irq_disable)),  \
+               [paravirt_sti_type] "i" (PARAVIRT_PATCH(irq_disable)),  \
+               paravirt_clobber(CLBR_NONE)
 
 #else  /* __ASSEMBLY__ */
 

-- 


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>