aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-06-25 00:19:15 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-08 07:11:04 -0400
commit491eccb721c2ee67250273a96e4515fb5b423337 (patch)
treed8edfed0da04376d68fd6a8c6f2f95085ab5da8b
parent97349135fea7f0ba8464534433df3bfd1dc0e9a6 (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>
-rw-r--r--include/asm-x86/paravirt.h28
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