[PATCH] [10/40] i386: Use patch site IDs computed from offset in paravirt_ops structure

2007-04-30 Thread Andi Kleen

From: Jeremy Fitzhardinge <[EMAIL PROTECTED]>
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.

Also, since the identifier is derived from the offset into
paravirt_ops, the offset can be derived from the identifier.  This is
used to remove replicated information in the various callsite macros,
which has been a source of bugs in the past.

This patch also drops the fused save_fl+cli operation, which doesn't
really add much and makes things more complex - specifically because
it breaks the 1:1 relationship between identifiers and offsets.  If
this operation turns out to be particularly beneficial, then the right
answer is to define a new entrypoint for it.

Signed-off-by: Jeremy Fitzhardinge <[EMAIL PROTECTED]>
Signed-off-by: Andi Kleen <[EMAIL PROTECTED]>
Cc: Rusty Russell <[EMAIL PROTECTED]>
Cc: Zachary Amsden <[EMAIL PROTECTED]>

---
 arch/i386/kernel/paravirt.c |   14 +--
 arch/i386/kernel/vmi.c  |   39 +
 include/asm-i386/paravirt.h |  179 ++--
 3 files changed, 105 insertions(+), 127 deletions(-)

===
Index: linux/arch/i386/kernel/paravirt.c
===
--- linux.orig/arch/i386/kernel/paravirt.c
+++ linux/arch/i386/kernel/paravirt.c
@@ -58,7 +58,6 @@ DEF_NATIVE(cli, "cli");
 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");
 
@@ -66,13 +65,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)
Index: linux/arch/i386/kernel/vmi.c
===
--- linux.orig/arch/i386/kernel/vmi.c
+++ linux/arch/i386/kernel/vmi.c
@@ -83,11 +83,6 @@ extern struct paravirt_patch __start_par
 #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
 
@@ -135,33 +130,17 @@ static unsigned patch_internal(int call,
 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;
-   }

[PATCH] [10/40] i386: Use patch site IDs computed from offset in paravirt_ops structure

2007-04-30 Thread Andi Kleen

From: Jeremy Fitzhardinge [EMAIL PROTECTED]
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.

Also, since the identifier is derived from the offset into
paravirt_ops, the offset can be derived from the identifier.  This is
used to remove replicated information in the various callsite macros,
which has been a source of bugs in the past.

This patch also drops the fused save_fl+cli operation, which doesn't
really add much and makes things more complex - specifically because
it breaks the 1:1 relationship between identifiers and offsets.  If
this operation turns out to be particularly beneficial, then the right
answer is to define a new entrypoint for it.

Signed-off-by: Jeremy Fitzhardinge [EMAIL PROTECTED]
Signed-off-by: Andi Kleen [EMAIL PROTECTED]
Cc: Rusty Russell [EMAIL PROTECTED]
Cc: Zachary Amsden [EMAIL PROTECTED]

---
 arch/i386/kernel/paravirt.c |   14 +--
 arch/i386/kernel/vmi.c  |   39 +
 include/asm-i386/paravirt.h |  179 ++--
 3 files changed, 105 insertions(+), 127 deletions(-)

===
Index: linux/arch/i386/kernel/paravirt.c
===
--- linux.orig/arch/i386/kernel/paravirt.c
+++ linux/arch/i386/kernel/paravirt.c
@@ -58,7 +58,6 @@ DEF_NATIVE(cli, cli);
 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);
 
@@ -66,13 +65,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)
Index: linux/arch/i386/kernel/vmi.c
===
--- linux.orig/arch/i386/kernel/vmi.c
+++ linux/arch/i386/kernel/vmi.c
@@ -83,11 +83,6 @@ extern struct paravirt_patch __start_par
 #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
 
@@ -135,33 +130,17 @@ static unsigned patch_internal(int call,
 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