diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-06-25 00:19:15 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-08 07:11:04 -0400 |
commit | 491eccb721c2ee67250273a96e4515fb5b423337 (patch) | |
tree | d8edfed0da04376d68fd6a8c6f2f95085ab5da8b /include | |
parent | 97349135fea7f0ba8464534433df3bfd1dc0e9a6 (diff) |
x86/paravirt: define PARA_INDIRECT for indirect asm calls
On 32-bit it's best to use a %cs: prefix to access memory where the
other segments may not bet set up properly yet. On 64-bit it's best
to use a rip-relative addressing mode. Define PARA_INDIRECT() to
abstract this and generate the proper addressing mode in each case.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Cc: xen-devel <xen-devel@lists.xensource.com>
Cc: Stephen Tweedie <sct@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-x86/paravirt.h | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 198293bed46f..82cdcde4b222 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h | |||
@@ -1455,51 +1455,53 @@ static inline unsigned long __raw_local_irq_save(void) | |||
1455 | #define PV_RESTORE_REGS popq %rdx; popq %rcx; popq %rdi; popq %rax | 1455 | #define PV_RESTORE_REGS popq %rdx; popq %rcx; popq %rdi; popq %rax |
1456 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 8) | 1456 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 8) |
1457 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8) | 1457 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8) |
1458 | #define PARA_INDIRECT(addr) *addr(%rip) | ||
1458 | #else | 1459 | #else |
1459 | #define PV_SAVE_REGS pushl %eax; pushl %edi; pushl %ecx; pushl %edx | 1460 | #define PV_SAVE_REGS pushl %eax; pushl %edi; pushl %ecx; pushl %edx |
1460 | #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax | 1461 | #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax |
1461 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) | 1462 | #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) |
1462 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) | 1463 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) |
1464 | #define PARA_INDIRECT(addr) *%cs:addr | ||
1463 | #endif | 1465 | #endif |
1464 | 1466 | ||
1465 | #define INTERRUPT_RETURN \ | 1467 | #define INTERRUPT_RETURN \ |
1466 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \ | 1468 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \ |
1467 | jmp *%cs:pv_cpu_ops+PV_CPU_iret) | 1469 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret)) |
1468 | 1470 | ||
1469 | #define DISABLE_INTERRUPTS(clobbers) \ | 1471 | #define DISABLE_INTERRUPTS(clobbers) \ |
1470 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ | 1472 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ |
1471 | PV_SAVE_REGS; \ | 1473 | PV_SAVE_REGS; \ |
1472 | call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \ | 1474 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable); \ |
1473 | PV_RESTORE_REGS;) \ | 1475 | PV_RESTORE_REGS;) \ |
1474 | 1476 | ||
1475 | #define ENABLE_INTERRUPTS(clobbers) \ | 1477 | #define ENABLE_INTERRUPTS(clobbers) \ |
1476 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ | 1478 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ |
1477 | PV_SAVE_REGS; \ | 1479 | PV_SAVE_REGS; \ |
1478 | call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \ | 1480 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \ |
1479 | PV_RESTORE_REGS;) | 1481 | PV_RESTORE_REGS;) |
1480 | 1482 | ||
1481 | #define ENABLE_INTERRUPTS_SYSCALL_RET \ | 1483 | #define ENABLE_INTERRUPTS_SYSCALL_RET \ |
1482 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\ | 1484 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\ |
1483 | CLBR_NONE, \ | 1485 | CLBR_NONE, \ |
1484 | jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret) | 1486 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)) |
1485 | 1487 | ||
1486 | 1488 | ||
1487 | #ifdef CONFIG_X86_32 | 1489 | #ifdef CONFIG_X86_32 |
1488 | #define GET_CR0_INTO_EAX \ | 1490 | #define GET_CR0_INTO_EAX \ |
1489 | push %ecx; push %edx; \ | 1491 | push %ecx; push %edx; \ |
1490 | call *pv_cpu_ops+PV_CPU_read_cr0; \ | 1492 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \ |
1491 | pop %edx; pop %ecx | 1493 | pop %edx; pop %ecx |
1492 | #else | 1494 | #else |
1493 | #define SWAPGS \ | 1495 | #define SWAPGS \ |
1494 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ | 1496 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \ |
1495 | PV_SAVE_REGS; \ | 1497 | PV_SAVE_REGS; \ |
1496 | call *pv_cpu_ops+PV_CPU_swapgs; \ | 1498 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs); \ |
1497 | PV_RESTORE_REGS \ | 1499 | PV_RESTORE_REGS \ |
1498 | ) | 1500 | ) |
1499 | 1501 | ||
1500 | #define GET_CR2_INTO_RCX \ | 1502 | #define GET_CR2_INTO_RCX \ |
1501 | call *pv_mmu_ops+PV_MMU_read_cr2; \ | 1503 | call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2); \ |
1502 | movq %rax, %rcx; \ | 1504 | movq %rax, %rcx; \ |
1503 | xorq %rax, %rax; | 1505 | xorq %rax, %rax; |
1504 | 1506 | ||
1505 | #endif | 1507 | #endif |