| H. Peter Anvin | 1965aae | 2008-10-22 22:26:29 -0700 | [diff] [blame] | 1 | #ifndef _ASM_X86_PARAVIRT_H | 
|  | 2 | #define _ASM_X86_PARAVIRT_H | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 3 | /* Various instructions on x86 need to be replaced for | 
|  | 4 | * para-virtualization: those hooks are defined here. */ | 
| Jeremy Fitzhardinge | b239fb2 | 2007-05-02 19:27:13 +0200 | [diff] [blame] | 5 |  | 
|  | 6 | #ifdef CONFIG_PARAVIRT | 
| Jeremy Fitzhardinge | 54321d9 | 2009-02-11 10:20:05 -0800 | [diff] [blame] | 7 | #include <asm/pgtable_types.h> | 
| Glauber de Oliveira Costa | 658be9d | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 8 | #include <asm/asm.h> | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 9 |  | 
| Jeremy Fitzhardinge | ac5672f | 2009-04-14 14:29:44 -0700 | [diff] [blame] | 10 | #include <asm/paravirt_types.h> | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 11 |  | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 12 | #ifndef __ASSEMBLY__ | 
| Paul Gortmaker | 187f188 | 2011-11-23 20:12:59 -0500 | [diff] [blame] | 13 | #include <linux/bug.h> | 
| Jeremy Fitzhardinge | 3dc494e | 2007-05-02 19:27:13 +0200 | [diff] [blame] | 14 | #include <linux/types.h> | 
| Jeremy Fitzhardinge | d4c1047 | 2007-05-02 19:27:15 +0200 | [diff] [blame] | 15 | #include <linux/cpumask.h> | 
| Jeremy Fitzhardinge | 1a45b7a | 2007-05-02 19:27:15 +0200 | [diff] [blame] | 16 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 17 | static inline int paravirt_enabled(void) | 
|  | 18 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 19 | return pv_info.paravirt_enabled; | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 20 | } | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 21 |  | 
| H. Peter Anvin | faca622 | 2008-01-30 13:31:02 +0100 | [diff] [blame] | 22 | static inline void load_sp0(struct tss_struct *tss, | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 23 | struct thread_struct *thread) | 
|  | 24 | { | 
| H. Peter Anvin | faca622 | 2008-01-30 13:31:02 +0100 | [diff] [blame] | 25 | PVOP_VCALL2(pv_cpu_ops.load_sp0, tss, thread); | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 26 | } | 
|  | 27 |  | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 28 | /* The paravirtualized CPUID instruction. */ | 
|  | 29 | static inline void __cpuid(unsigned int *eax, unsigned int *ebx, | 
|  | 30 | unsigned int *ecx, unsigned int *edx) | 
|  | 31 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 32 | PVOP_VCALL4(pv_cpu_ops.cpuid, eax, ebx, ecx, edx); | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 33 | } | 
|  | 34 |  | 
|  | 35 | /* | 
|  | 36 | * These special macros can be used to get or set a debugging register | 
|  | 37 | */ | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 38 | static inline unsigned long paravirt_get_debugreg(int reg) | 
|  | 39 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 40 | return PVOP_CALL1(unsigned long, pv_cpu_ops.get_debugreg, reg); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 41 | } | 
|  | 42 | #define get_debugreg(var, reg) var = paravirt_get_debugreg(reg) | 
|  | 43 | static inline void set_debugreg(unsigned long val, int reg) | 
|  | 44 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 45 | PVOP_VCALL2(pv_cpu_ops.set_debugreg, reg, val); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 46 | } | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 47 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 48 | static inline void clts(void) | 
|  | 49 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 50 | PVOP_VCALL0(pv_cpu_ops.clts); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 51 | } | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 52 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 53 | static inline unsigned long read_cr0(void) | 
|  | 54 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 55 | return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr0); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 56 | } | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 57 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 58 | static inline void write_cr0(unsigned long x) | 
|  | 59 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 60 | PVOP_VCALL1(pv_cpu_ops.write_cr0, x); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 61 | } | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 62 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 63 | static inline unsigned long read_cr2(void) | 
|  | 64 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 65 | return PVOP_CALL0(unsigned long, pv_mmu_ops.read_cr2); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 66 | } | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 67 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 68 | static inline void write_cr2(unsigned long x) | 
|  | 69 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 70 | PVOP_VCALL1(pv_mmu_ops.write_cr2, x); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 71 | } | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 72 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 73 | static inline unsigned long read_cr3(void) | 
|  | 74 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 75 | return PVOP_CALL0(unsigned long, pv_mmu_ops.read_cr3); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 76 | } | 
|  | 77 |  | 
|  | 78 | static inline void write_cr3(unsigned long x) | 
|  | 79 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 80 | PVOP_VCALL1(pv_mmu_ops.write_cr3, x); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 81 | } | 
|  | 82 |  | 
|  | 83 | static inline unsigned long read_cr4(void) | 
|  | 84 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 85 | return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 86 | } | 
|  | 87 | static inline unsigned long read_cr4_safe(void) | 
|  | 88 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 89 | return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4_safe); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 90 | } | 
|  | 91 |  | 
|  | 92 | static inline void write_cr4(unsigned long x) | 
|  | 93 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 94 | PVOP_VCALL1(pv_cpu_ops.write_cr4, x); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 95 | } | 
| Jeremy Fitzhardinge | 3dc494e | 2007-05-02 19:27:13 +0200 | [diff] [blame] | 96 |  | 
| Glauber de Oliveira Costa | 94ea03c | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 97 | #ifdef CONFIG_X86_64 | 
| Glauber de Oliveira Costa | 4c9890c | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 98 | static inline unsigned long read_cr8(void) | 
|  | 99 | { | 
|  | 100 | return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr8); | 
|  | 101 | } | 
|  | 102 |  | 
|  | 103 | static inline void write_cr8(unsigned long x) | 
|  | 104 | { | 
|  | 105 | PVOP_VCALL1(pv_cpu_ops.write_cr8, x); | 
|  | 106 | } | 
| Glauber de Oliveira Costa | 94ea03c | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 107 | #endif | 
| Glauber de Oliveira Costa | 4c9890c | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 108 |  | 
| David Howells | df9ee29 | 2010-10-07 14:08:55 +0100 | [diff] [blame] | 109 | static inline void arch_safe_halt(void) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 110 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 111 | PVOP_VCALL0(pv_irq_ops.safe_halt); | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 112 | } | 
|  | 113 |  | 
|  | 114 | static inline void halt(void) | 
|  | 115 | { | 
| Cliff Wickman | c8217b8 | 2010-12-13 10:51:57 -0600 | [diff] [blame] | 116 | PVOP_VCALL0(pv_irq_ops.halt); | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 117 | } | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 118 |  | 
|  | 119 | static inline void wbinvd(void) | 
|  | 120 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 121 | PVOP_VCALL0(pv_cpu_ops.wbinvd); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 122 | } | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 123 |  | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 124 | #define get_kernel_rpl()  (pv_info.kernel_rpl) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 125 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 126 | static inline u64 paravirt_read_msr(unsigned msr, int *err) | 
|  | 127 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 128 | return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 129 | } | 
| Borislav Petkov | 132ec92 | 2009-08-31 09:50:09 +0200 | [diff] [blame] | 130 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 131 | static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) | 
|  | 132 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 133 | return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 134 | } | 
|  | 135 |  | 
| Rusty Russell | 90a0a06 | 2007-05-02 19:27:10 +0200 | [diff] [blame] | 136 | /* These should all do BUG_ON(_err), but our headers are too tangled. */ | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 137 | #define rdmsr(msr, val1, val2)			\ | 
|  | 138 | do {						\ | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 139 | int _err;				\ | 
|  | 140 | u64 _l = paravirt_read_msr(msr, &_err);	\ | 
|  | 141 | val1 = (u32)_l;				\ | 
|  | 142 | val2 = _l >> 32;			\ | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 143 | } while (0) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 144 |  | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 145 | #define wrmsr(msr, val1, val2)			\ | 
|  | 146 | do {						\ | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 147 | paravirt_write_msr(msr, val1, val2);	\ | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 148 | } while (0) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 149 |  | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 150 | #define rdmsrl(msr, val)			\ | 
|  | 151 | do {						\ | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 152 | int _err;				\ | 
|  | 153 | val = paravirt_read_msr(msr, &_err);	\ | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 154 | } while (0) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 155 |  | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 156 | #define wrmsrl(msr, val)	wrmsr(msr, (u32)((u64)(val)), ((u64)(val))>>32) | 
|  | 157 | #define wrmsr_safe(msr, a, b)	paravirt_write_msr(msr, a, b) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 158 |  | 
|  | 159 | /* rdmsr with exception handling */ | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 160 | #define rdmsr_safe(msr, a, b)			\ | 
|  | 161 | ({						\ | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 162 | int _err;				\ | 
|  | 163 | u64 _l = paravirt_read_msr(msr, &_err);	\ | 
|  | 164 | (*a) = (u32)_l;				\ | 
|  | 165 | (*b) = _l >> 32;			\ | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 166 | _err;					\ | 
|  | 167 | }) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 168 |  | 
| Andi Kleen | 1de87bd | 2008-03-22 10:59:28 +0100 | [diff] [blame] | 169 | static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) | 
|  | 170 | { | 
|  | 171 | int err; | 
|  | 172 |  | 
|  | 173 | *p = paravirt_read_msr(msr, &err); | 
|  | 174 | return err; | 
|  | 175 | } | 
| Borislav Petkov | 177fed1 | 2009-08-31 09:50:10 +0200 | [diff] [blame] | 176 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 177 | static inline u64 paravirt_read_tsc(void) | 
|  | 178 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 179 | return PVOP_CALL0(u64, pv_cpu_ops.read_tsc); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 180 | } | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 181 |  | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 182 | #define rdtscl(low)				\ | 
|  | 183 | do {						\ | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 184 | u64 _l = paravirt_read_tsc();		\ | 
|  | 185 | low = (int)_l;				\ | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 186 | } while (0) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 187 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 188 | #define rdtscll(val) (val = paravirt_read_tsc()) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 189 |  | 
| Jeremy Fitzhardinge | 688340e | 2007-07-17 18:37:04 -0700 | [diff] [blame] | 190 | static inline unsigned long long paravirt_sched_clock(void) | 
|  | 191 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 192 | return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock); | 
| Jeremy Fitzhardinge | 688340e | 2007-07-17 18:37:04 -0700 | [diff] [blame] | 193 | } | 
| Zachary Amsden | 6cb9a83 | 2007-03-05 00:30:35 -0800 | [diff] [blame] | 194 |  | 
| Ingo Molnar | c5905af | 2012-02-24 08:31:31 +0100 | [diff] [blame] | 195 | struct static_key; | 
|  | 196 | extern struct static_key paravirt_steal_enabled; | 
|  | 197 | extern struct static_key paravirt_steal_rq_enabled; | 
| Glauber Costa | 3c404b5 | 2011-07-11 15:28:15 -0400 | [diff] [blame] | 198 |  | 
|  | 199 | static inline u64 paravirt_steal_clock(int cpu) | 
|  | 200 | { | 
|  | 201 | return PVOP_CALL1(u64, pv_time_ops.steal_clock, cpu); | 
|  | 202 | } | 
|  | 203 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 204 | static inline unsigned long long paravirt_read_pmc(int counter) | 
|  | 205 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 206 | return PVOP_CALL1(u64, pv_cpu_ops.read_pmc, counter); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 207 | } | 
|  | 208 |  | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 209 | #define rdpmc(counter, low, high)		\ | 
|  | 210 | do {						\ | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 211 | u64 _l = paravirt_read_pmc(counter);	\ | 
|  | 212 | low = (u32)_l;				\ | 
|  | 213 | high = _l >> 32;			\ | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 214 | } while (0) | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 215 |  | 
| Andi Kleen | 1ff4d58 | 2012-06-05 17:56:50 -0700 | [diff] [blame] | 216 | #define rdpmcl(counter, val) ((val) = paravirt_read_pmc(counter)) | 
|  | 217 |  | 
| Glauber de Oliveira Costa | e5aaac4 | 2008-01-30 13:32:05 +0100 | [diff] [blame] | 218 | static inline unsigned long long paravirt_rdtscp(unsigned int *aux) | 
|  | 219 | { | 
|  | 220 | return PVOP_CALL1(u64, pv_cpu_ops.read_tscp, aux); | 
|  | 221 | } | 
|  | 222 |  | 
|  | 223 | #define rdtscp(low, high, aux)				\ | 
|  | 224 | do {							\ | 
|  | 225 | int __aux;					\ | 
|  | 226 | unsigned long __val = paravirt_rdtscp(&__aux);	\ | 
|  | 227 | (low) = (u32)__val;				\ | 
|  | 228 | (high) = (u32)(__val >> 32);			\ | 
|  | 229 | (aux) = __aux;					\ | 
|  | 230 | } while (0) | 
|  | 231 |  | 
|  | 232 | #define rdtscpll(val, aux)				\ | 
|  | 233 | do {							\ | 
|  | 234 | unsigned long __aux; 				\ | 
|  | 235 | val = paravirt_rdtscp(&__aux);			\ | 
|  | 236 | (aux) = __aux;					\ | 
|  | 237 | } while (0) | 
|  | 238 |  | 
| Jeremy Fitzhardinge | 38ffbe6 | 2008-07-23 14:21:18 -0700 | [diff] [blame] | 239 | static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries) | 
|  | 240 | { | 
|  | 241 | PVOP_VCALL2(pv_cpu_ops.alloc_ldt, ldt, entries); | 
|  | 242 | } | 
|  | 243 |  | 
|  | 244 | static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries) | 
|  | 245 | { | 
|  | 246 | PVOP_VCALL2(pv_cpu_ops.free_ldt, ldt, entries); | 
|  | 247 | } | 
|  | 248 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 249 | static inline void load_TR_desc(void) | 
|  | 250 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 251 | PVOP_VCALL0(pv_cpu_ops.load_tr_desc); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 252 | } | 
| Glauber de Oliveira Costa | 6b68f01 | 2008-01-30 13:31:12 +0100 | [diff] [blame] | 253 | static inline void load_gdt(const struct desc_ptr *dtr) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 254 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 255 | PVOP_VCALL1(pv_cpu_ops.load_gdt, dtr); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 256 | } | 
| Glauber de Oliveira Costa | 6b68f01 | 2008-01-30 13:31:12 +0100 | [diff] [blame] | 257 | static inline void load_idt(const struct desc_ptr *dtr) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 258 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 259 | PVOP_VCALL1(pv_cpu_ops.load_idt, dtr); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 260 | } | 
|  | 261 | static inline void set_ldt(const void *addr, unsigned entries) | 
|  | 262 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 263 | PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 264 | } | 
| Glauber de Oliveira Costa | 6b68f01 | 2008-01-30 13:31:12 +0100 | [diff] [blame] | 265 | static inline void store_gdt(struct desc_ptr *dtr) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 266 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 267 | PVOP_VCALL1(pv_cpu_ops.store_gdt, dtr); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 268 | } | 
| Glauber de Oliveira Costa | 6b68f01 | 2008-01-30 13:31:12 +0100 | [diff] [blame] | 269 | static inline void store_idt(struct desc_ptr *dtr) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 270 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 271 | PVOP_VCALL1(pv_cpu_ops.store_idt, dtr); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 272 | } | 
|  | 273 | static inline unsigned long paravirt_store_tr(void) | 
|  | 274 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 275 | return PVOP_CALL0(unsigned long, pv_cpu_ops.store_tr); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 276 | } | 
|  | 277 | #define store_tr(tr)	((tr) = paravirt_store_tr()) | 
|  | 278 | static inline void load_TLS(struct thread_struct *t, unsigned cpu) | 
|  | 279 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 280 | PVOP_VCALL2(pv_cpu_ops.load_tls, t, cpu); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 281 | } | 
| Glauber de Oliveira Costa | 75b8bb3 | 2008-01-30 13:31:13 +0100 | [diff] [blame] | 282 |  | 
| Jeremy Fitzhardinge | 9f9d489 | 2008-06-25 00:19:32 -0400 | [diff] [blame] | 283 | #ifdef CONFIG_X86_64 | 
|  | 284 | static inline void load_gs_index(unsigned int gs) | 
|  | 285 | { | 
|  | 286 | PVOP_VCALL1(pv_cpu_ops.load_gs_index, gs); | 
|  | 287 | } | 
|  | 288 | #endif | 
|  | 289 |  | 
| Glauber de Oliveira Costa | 75b8bb3 | 2008-01-30 13:31:13 +0100 | [diff] [blame] | 290 | static inline void write_ldt_entry(struct desc_struct *dt, int entry, | 
|  | 291 | const void *desc) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 292 | { | 
| Glauber de Oliveira Costa | 75b8bb3 | 2008-01-30 13:31:13 +0100 | [diff] [blame] | 293 | PVOP_VCALL3(pv_cpu_ops.write_ldt_entry, dt, entry, desc); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 294 | } | 
| Glauber de Oliveira Costa | 014b15b | 2008-01-30 13:31:13 +0100 | [diff] [blame] | 295 |  | 
|  | 296 | static inline void write_gdt_entry(struct desc_struct *dt, int entry, | 
|  | 297 | void *desc, int type) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 298 | { | 
| Glauber de Oliveira Costa | 014b15b | 2008-01-30 13:31:13 +0100 | [diff] [blame] | 299 | PVOP_VCALL4(pv_cpu_ops.write_gdt_entry, dt, entry, desc, type); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 300 | } | 
| Glauber de Oliveira Costa | 014b15b | 2008-01-30 13:31:13 +0100 | [diff] [blame] | 301 |  | 
| Glauber de Oliveira Costa | 8d94734 | 2008-01-30 13:31:12 +0100 | [diff] [blame] | 302 | static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 303 | { | 
| Glauber de Oliveira Costa | 8d94734 | 2008-01-30 13:31:12 +0100 | [diff] [blame] | 304 | PVOP_VCALL3(pv_cpu_ops.write_idt_entry, dt, entry, g); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 305 | } | 
|  | 306 | static inline void set_iopl_mask(unsigned mask) | 
|  | 307 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 308 | PVOP_VCALL1(pv_cpu_ops.set_iopl_mask, mask); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 309 | } | 
| Jeremy Fitzhardinge | 3dc494e | 2007-05-02 19:27:13 +0200 | [diff] [blame] | 310 |  | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 311 | /* The paravirtualized I/O functions */ | 
| Joe Perches | 49cd740 | 2008-03-23 01:03:00 -0700 | [diff] [blame] | 312 | static inline void slow_down_io(void) | 
|  | 313 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 314 | pv_cpu_ops.io_delay(); | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 315 | #ifdef REALLY_SLOW_IO | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 316 | pv_cpu_ops.io_delay(); | 
|  | 317 | pv_cpu_ops.io_delay(); | 
|  | 318 | pv_cpu_ops.io_delay(); | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 319 | #endif | 
|  | 320 | } | 
|  | 321 |  | 
| Zachary Amsden | ae5da27 | 2007-02-13 13:26:21 +0100 | [diff] [blame] | 322 | #ifdef CONFIG_SMP | 
|  | 323 | static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip, | 
|  | 324 | unsigned long start_esp) | 
|  | 325 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 326 | PVOP_VCALL3(pv_apic_ops.startup_ipi_hook, | 
|  | 327 | phys_apicid, start_eip, start_esp); | 
| Zachary Amsden | ae5da27 | 2007-02-13 13:26:21 +0100 | [diff] [blame] | 328 | } | 
|  | 329 | #endif | 
| Rusty Russell | 13623d7 | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 330 |  | 
| Jeremy Fitzhardinge | d6dd61c | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 331 | static inline void paravirt_activate_mm(struct mm_struct *prev, | 
|  | 332 | struct mm_struct *next) | 
|  | 333 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 334 | PVOP_VCALL2(pv_mmu_ops.activate_mm, prev, next); | 
| Jeremy Fitzhardinge | d6dd61c | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 335 | } | 
|  | 336 |  | 
|  | 337 | static inline void arch_dup_mmap(struct mm_struct *oldmm, | 
|  | 338 | struct mm_struct *mm) | 
|  | 339 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 340 | PVOP_VCALL2(pv_mmu_ops.dup_mmap, oldmm, mm); | 
| Jeremy Fitzhardinge | d6dd61c | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 341 | } | 
|  | 342 |  | 
|  | 343 | static inline void arch_exit_mmap(struct mm_struct *mm) | 
|  | 344 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 345 | PVOP_VCALL1(pv_mmu_ops.exit_mmap, mm); | 
| Jeremy Fitzhardinge | d6dd61c | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 346 | } | 
|  | 347 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 348 | static inline void __flush_tlb(void) | 
|  | 349 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 350 | PVOP_VCALL0(pv_mmu_ops.flush_tlb_user); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 351 | } | 
|  | 352 | static inline void __flush_tlb_global(void) | 
|  | 353 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 354 | PVOP_VCALL0(pv_mmu_ops.flush_tlb_kernel); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 355 | } | 
|  | 356 | static inline void __flush_tlb_single(unsigned long addr) | 
|  | 357 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 358 | PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 359 | } | 
| Rusty Russell | da181a8 | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 360 |  | 
| Rusty Russell | 4595f96 | 2009-01-10 21:58:09 -0800 | [diff] [blame] | 361 | static inline void flush_tlb_others(const struct cpumask *cpumask, | 
|  | 362 | struct mm_struct *mm, | 
| Alex Shi | e7b52ff | 2012-06-28 09:02:17 +0800 | [diff] [blame] | 363 | unsigned long start, | 
|  | 364 | unsigned long end) | 
| Jeremy Fitzhardinge | d4c1047 | 2007-05-02 19:27:15 +0200 | [diff] [blame] | 365 | { | 
| Alex Shi | e7b52ff | 2012-06-28 09:02:17 +0800 | [diff] [blame] | 366 | PVOP_VCALL4(pv_mmu_ops.flush_tlb_others, cpumask, mm, start, end); | 
| Jeremy Fitzhardinge | d4c1047 | 2007-05-02 19:27:15 +0200 | [diff] [blame] | 367 | } | 
|  | 368 |  | 
| Jeremy Fitzhardinge | eba0045 | 2008-06-25 00:19:12 -0400 | [diff] [blame] | 369 | static inline int paravirt_pgd_alloc(struct mm_struct *mm) | 
|  | 370 | { | 
|  | 371 | return PVOP_CALL1(int, pv_mmu_ops.pgd_alloc, mm); | 
|  | 372 | } | 
|  | 373 |  | 
|  | 374 | static inline void paravirt_pgd_free(struct mm_struct *mm, pgd_t *pgd) | 
|  | 375 | { | 
|  | 376 | PVOP_VCALL2(pv_mmu_ops.pgd_free, mm, pgd); | 
|  | 377 | } | 
|  | 378 |  | 
| Eduardo Habkost | f863993 | 2008-07-30 18:32:27 -0300 | [diff] [blame] | 379 | static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned long pfn) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 380 | { | 
| Jeremy Fitzhardinge | 6944a9c | 2008-03-17 16:37:01 -0700 | [diff] [blame] | 381 | PVOP_VCALL2(pv_mmu_ops.alloc_pte, mm, pfn); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 382 | } | 
| Eduardo Habkost | f863993 | 2008-07-30 18:32:27 -0300 | [diff] [blame] | 383 | static inline void paravirt_release_pte(unsigned long pfn) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 384 | { | 
| Jeremy Fitzhardinge | 6944a9c | 2008-03-17 16:37:01 -0700 | [diff] [blame] | 385 | PVOP_VCALL1(pv_mmu_ops.release_pte, pfn); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 386 | } | 
| Zachary Amsden | c119ecc | 2007-02-13 13:26:21 +0100 | [diff] [blame] | 387 |  | 
| Eduardo Habkost | f863993 | 2008-07-30 18:32:27 -0300 | [diff] [blame] | 388 | static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 389 | { | 
| Jeremy Fitzhardinge | 6944a9c | 2008-03-17 16:37:01 -0700 | [diff] [blame] | 390 | PVOP_VCALL2(pv_mmu_ops.alloc_pmd, mm, pfn); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 391 | } | 
|  | 392 |  | 
| Eduardo Habkost | f863993 | 2008-07-30 18:32:27 -0300 | [diff] [blame] | 393 | static inline void paravirt_release_pmd(unsigned long pfn) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 394 | { | 
| Jeremy Fitzhardinge | 6944a9c | 2008-03-17 16:37:01 -0700 | [diff] [blame] | 395 | PVOP_VCALL1(pv_mmu_ops.release_pmd, pfn); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 396 | } | 
|  | 397 |  | 
| Eduardo Habkost | f863993 | 2008-07-30 18:32:27 -0300 | [diff] [blame] | 398 | static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned long pfn) | 
| Jeremy Fitzhardinge | 2761fa0 | 2008-03-17 16:37:02 -0700 | [diff] [blame] | 399 | { | 
|  | 400 | PVOP_VCALL2(pv_mmu_ops.alloc_pud, mm, pfn); | 
|  | 401 | } | 
| Eduardo Habkost | f863993 | 2008-07-30 18:32:27 -0300 | [diff] [blame] | 402 | static inline void paravirt_release_pud(unsigned long pfn) | 
| Jeremy Fitzhardinge | 2761fa0 | 2008-03-17 16:37:02 -0700 | [diff] [blame] | 403 | { | 
|  | 404 | PVOP_VCALL1(pv_mmu_ops.release_pud, pfn); | 
|  | 405 | } | 
|  | 406 |  | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 407 | static inline void pte_update(struct mm_struct *mm, unsigned long addr, | 
|  | 408 | pte_t *ptep) | 
|  | 409 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 410 | PVOP_VCALL3(pv_mmu_ops.pte_update, mm, addr, ptep); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 411 | } | 
| Andrea Arcangeli | 331127f | 2011-01-13 15:46:36 -0800 | [diff] [blame] | 412 | static inline void pmd_update(struct mm_struct *mm, unsigned long addr, | 
|  | 413 | pmd_t *pmdp) | 
|  | 414 | { | 
|  | 415 | PVOP_VCALL3(pv_mmu_ops.pmd_update, mm, addr, pmdp); | 
|  | 416 | } | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 417 |  | 
|  | 418 | static inline void pte_update_defer(struct mm_struct *mm, unsigned long addr, | 
|  | 419 | pte_t *ptep) | 
|  | 420 | { | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 421 | PVOP_VCALL3(pv_mmu_ops.pte_update_defer, mm, addr, ptep); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 422 | } | 
|  | 423 |  | 
| Andrea Arcangeli | 331127f | 2011-01-13 15:46:36 -0800 | [diff] [blame] | 424 | static inline void pmd_update_defer(struct mm_struct *mm, unsigned long addr, | 
|  | 425 | pmd_t *pmdp) | 
|  | 426 | { | 
|  | 427 | PVOP_VCALL3(pv_mmu_ops.pmd_update_defer, mm, addr, pmdp); | 
|  | 428 | } | 
|  | 429 |  | 
| Jeremy Fitzhardinge | 773221f | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 430 | static inline pte_t __pte(pteval_t val) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 431 | { | 
| Jeremy Fitzhardinge | 773221f | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 432 | pteval_t ret; | 
|  | 433 |  | 
|  | 434 | if (sizeof(pteval_t) > sizeof(long)) | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 435 | ret = PVOP_CALLEE2(pteval_t, | 
|  | 436 | pv_mmu_ops.make_pte, | 
|  | 437 | val, (u64)val >> 32); | 
| Jeremy Fitzhardinge | 773221f | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 438 | else | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 439 | ret = PVOP_CALLEE1(pteval_t, | 
|  | 440 | pv_mmu_ops.make_pte, | 
|  | 441 | val); | 
| Jeremy Fitzhardinge | 773221f | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 442 |  | 
| Jeremy Fitzhardinge | c8e5393 | 2008-01-30 13:32:57 +0100 | [diff] [blame] | 443 | return (pte_t) { .pte = ret }; | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 444 | } | 
|  | 445 |  | 
| Jeremy Fitzhardinge | 773221f | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 446 | static inline pteval_t pte_val(pte_t pte) | 
|  | 447 | { | 
|  | 448 | pteval_t ret; | 
|  | 449 |  | 
|  | 450 | if (sizeof(pteval_t) > sizeof(long)) | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 451 | ret = PVOP_CALLEE2(pteval_t, pv_mmu_ops.pte_val, | 
|  | 452 | pte.pte, (u64)pte.pte >> 32); | 
| Jeremy Fitzhardinge | 773221f | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 453 | else | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 454 | ret = PVOP_CALLEE1(pteval_t, pv_mmu_ops.pte_val, | 
|  | 455 | pte.pte); | 
| Jeremy Fitzhardinge | 773221f | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 456 |  | 
|  | 457 | return ret; | 
|  | 458 | } | 
|  | 459 |  | 
| Jeremy Fitzhardinge | ef38503 | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 460 | static inline pgd_t __pgd(pgdval_t val) | 
|  | 461 | { | 
|  | 462 | pgdval_t ret; | 
|  | 463 |  | 
|  | 464 | if (sizeof(pgdval_t) > sizeof(long)) | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 465 | ret = PVOP_CALLEE2(pgdval_t, pv_mmu_ops.make_pgd, | 
|  | 466 | val, (u64)val >> 32); | 
| Jeremy Fitzhardinge | ef38503 | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 467 | else | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 468 | ret = PVOP_CALLEE1(pgdval_t, pv_mmu_ops.make_pgd, | 
|  | 469 | val); | 
| Jeremy Fitzhardinge | ef38503 | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 470 |  | 
|  | 471 | return (pgd_t) { ret }; | 
|  | 472 | } | 
|  | 473 |  | 
|  | 474 | static inline pgdval_t pgd_val(pgd_t pgd) | 
|  | 475 | { | 
|  | 476 | pgdval_t ret; | 
|  | 477 |  | 
|  | 478 | if (sizeof(pgdval_t) > sizeof(long)) | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 479 | ret =  PVOP_CALLEE2(pgdval_t, pv_mmu_ops.pgd_val, | 
|  | 480 | pgd.pgd, (u64)pgd.pgd >> 32); | 
| Jeremy Fitzhardinge | ef38503 | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 481 | else | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 482 | ret =  PVOP_CALLEE1(pgdval_t, pv_mmu_ops.pgd_val, | 
|  | 483 | pgd.pgd); | 
| Jeremy Fitzhardinge | ef38503 | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 484 |  | 
|  | 485 | return ret; | 
|  | 486 | } | 
|  | 487 |  | 
| Jeremy Fitzhardinge | 08b882c | 2008-06-16 04:30:01 -0700 | [diff] [blame] | 488 | #define  __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION | 
|  | 489 | static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, | 
|  | 490 | pte_t *ptep) | 
|  | 491 | { | 
|  | 492 | pteval_t ret; | 
|  | 493 |  | 
|  | 494 | ret = PVOP_CALL3(pteval_t, pv_mmu_ops.ptep_modify_prot_start, | 
|  | 495 | mm, addr, ptep); | 
|  | 496 |  | 
|  | 497 | return (pte_t) { .pte = ret }; | 
|  | 498 | } | 
|  | 499 |  | 
|  | 500 | static inline void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | 
|  | 501 | pte_t *ptep, pte_t pte) | 
|  | 502 | { | 
|  | 503 | if (sizeof(pteval_t) > sizeof(long)) | 
|  | 504 | /* 5 arg words */ | 
|  | 505 | pv_mmu_ops.ptep_modify_prot_commit(mm, addr, ptep, pte); | 
|  | 506 | else | 
|  | 507 | PVOP_VCALL4(pv_mmu_ops.ptep_modify_prot_commit, | 
|  | 508 | mm, addr, ptep, pte.pte); | 
|  | 509 | } | 
|  | 510 |  | 
| Jeremy Fitzhardinge | 4eed80c | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 511 | static inline void set_pte(pte_t *ptep, pte_t pte) | 
|  | 512 | { | 
|  | 513 | if (sizeof(pteval_t) > sizeof(long)) | 
|  | 514 | PVOP_VCALL3(pv_mmu_ops.set_pte, ptep, | 
|  | 515 | pte.pte, (u64)pte.pte >> 32); | 
|  | 516 | else | 
|  | 517 | PVOP_VCALL2(pv_mmu_ops.set_pte, ptep, | 
|  | 518 | pte.pte); | 
|  | 519 | } | 
|  | 520 |  | 
|  | 521 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | 
|  | 522 | pte_t *ptep, pte_t pte) | 
|  | 523 | { | 
|  | 524 | if (sizeof(pteval_t) > sizeof(long)) | 
|  | 525 | /* 5 arg words */ | 
|  | 526 | pv_mmu_ops.set_pte_at(mm, addr, ptep, pte); | 
|  | 527 | else | 
|  | 528 | PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pte.pte); | 
|  | 529 | } | 
|  | 530 |  | 
| Andrea Arcangeli | 331127f | 2011-01-13 15:46:36 -0800 | [diff] [blame] | 531 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 
|  | 532 | static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, | 
|  | 533 | pmd_t *pmdp, pmd_t pmd) | 
|  | 534 | { | 
| Andrea Arcangeli | 331127f | 2011-01-13 15:46:36 -0800 | [diff] [blame] | 535 | if (sizeof(pmdval_t) > sizeof(long)) | 
|  | 536 | /* 5 arg words */ | 
|  | 537 | pv_mmu_ops.set_pmd_at(mm, addr, pmdp, pmd); | 
|  | 538 | else | 
| Andrea Arcangeli | cacf061 | 2011-01-25 15:07:09 -0800 | [diff] [blame] | 539 | PVOP_VCALL4(pv_mmu_ops.set_pmd_at, mm, addr, pmdp, | 
|  | 540 | native_pmd_val(pmd)); | 
| Andrea Arcangeli | 331127f | 2011-01-13 15:46:36 -0800 | [diff] [blame] | 541 | } | 
|  | 542 | #endif | 
|  | 543 |  | 
| Jeremy Fitzhardinge | 60b3f62 | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 544 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) | 
|  | 545 | { | 
|  | 546 | pmdval_t val = native_pmd_val(pmd); | 
|  | 547 |  | 
|  | 548 | if (sizeof(pmdval_t) > sizeof(long)) | 
|  | 549 | PVOP_VCALL3(pv_mmu_ops.set_pmd, pmdp, val, (u64)val >> 32); | 
|  | 550 | else | 
|  | 551 | PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, val); | 
|  | 552 | } | 
|  | 553 |  | 
| Glauber de Oliveira Costa | 1fe9151 | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 554 | #if PAGETABLE_LEVELS >= 3 | 
|  | 555 | static inline pmd_t __pmd(pmdval_t val) | 
|  | 556 | { | 
|  | 557 | pmdval_t ret; | 
|  | 558 |  | 
|  | 559 | if (sizeof(pmdval_t) > sizeof(long)) | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 560 | ret = PVOP_CALLEE2(pmdval_t, pv_mmu_ops.make_pmd, | 
|  | 561 | val, (u64)val >> 32); | 
| Glauber de Oliveira Costa | 1fe9151 | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 562 | else | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 563 | ret = PVOP_CALLEE1(pmdval_t, pv_mmu_ops.make_pmd, | 
|  | 564 | val); | 
| Glauber de Oliveira Costa | 1fe9151 | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 565 |  | 
|  | 566 | return (pmd_t) { ret }; | 
|  | 567 | } | 
|  | 568 |  | 
|  | 569 | static inline pmdval_t pmd_val(pmd_t pmd) | 
|  | 570 | { | 
|  | 571 | pmdval_t ret; | 
|  | 572 |  | 
|  | 573 | if (sizeof(pmdval_t) > sizeof(long)) | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 574 | ret =  PVOP_CALLEE2(pmdval_t, pv_mmu_ops.pmd_val, | 
|  | 575 | pmd.pmd, (u64)pmd.pmd >> 32); | 
| Glauber de Oliveira Costa | 1fe9151 | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 576 | else | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 577 | ret =  PVOP_CALLEE1(pmdval_t, pv_mmu_ops.pmd_val, | 
|  | 578 | pmd.pmd); | 
| Glauber de Oliveira Costa | 1fe9151 | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 579 |  | 
|  | 580 | return ret; | 
|  | 581 | } | 
|  | 582 |  | 
|  | 583 | static inline void set_pud(pud_t *pudp, pud_t pud) | 
|  | 584 | { | 
|  | 585 | pudval_t val = native_pud_val(pud); | 
|  | 586 |  | 
|  | 587 | if (sizeof(pudval_t) > sizeof(long)) | 
|  | 588 | PVOP_VCALL3(pv_mmu_ops.set_pud, pudp, | 
|  | 589 | val, (u64)val >> 32); | 
|  | 590 | else | 
|  | 591 | PVOP_VCALL2(pv_mmu_ops.set_pud, pudp, | 
|  | 592 | val); | 
|  | 593 | } | 
| Eduardo Habkost | 9042219 | 2008-01-30 13:33:20 +0100 | [diff] [blame] | 594 | #if PAGETABLE_LEVELS == 4 | 
|  | 595 | static inline pud_t __pud(pudval_t val) | 
|  | 596 | { | 
|  | 597 | pudval_t ret; | 
|  | 598 |  | 
|  | 599 | if (sizeof(pudval_t) > sizeof(long)) | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 600 | ret = PVOP_CALLEE2(pudval_t, pv_mmu_ops.make_pud, | 
|  | 601 | val, (u64)val >> 32); | 
| Eduardo Habkost | 9042219 | 2008-01-30 13:33:20 +0100 | [diff] [blame] | 602 | else | 
| Jeremy Fitzhardinge | da5de7c | 2009-01-28 14:35:07 -0800 | [diff] [blame] | 603 | ret = PVOP_CALLEE1(pudval_t, pv_mmu_ops.make_pud, | 
|  | 604 | val); | 
| Eduardo Habkost | 9042219 | 2008-01-30 13:33:20 +0100 | [diff] [blame] | 605 |  | 
|  | 606 | return (pud_t) { ret }; | 
|  | 607 | } | 
|  | 608 |  | 
|  | 609 | static inline pudval_t pud_val(pud_t pud) | 
|  | 610 | { | 
|  | 611 | pudval_t ret; | 
|  | 612 |  | 
|  | 613 | if (sizeof(pudval_t) > sizeof(long)) | 
| Jeremy Fitzhardinge | 4767afb | 2009-01-29 01:51:34 -0800 | [diff] [blame] | 614 | ret =  PVOP_CALLEE2(pudval_t, pv_mmu_ops.pud_val, | 
|  | 615 | pud.pud, (u64)pud.pud >> 32); | 
| Eduardo Habkost | 9042219 | 2008-01-30 13:33:20 +0100 | [diff] [blame] | 616 | else | 
| Jeremy Fitzhardinge | 4767afb | 2009-01-29 01:51:34 -0800 | [diff] [blame] | 617 | ret =  PVOP_CALLEE1(pudval_t, pv_mmu_ops.pud_val, | 
|  | 618 | pud.pud); | 
| Eduardo Habkost | 9042219 | 2008-01-30 13:33:20 +0100 | [diff] [blame] | 619 |  | 
|  | 620 | return ret; | 
|  | 621 | } | 
|  | 622 |  | 
|  | 623 | static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) | 
|  | 624 | { | 
|  | 625 | pgdval_t val = native_pgd_val(pgd); | 
|  | 626 |  | 
|  | 627 | if (sizeof(pgdval_t) > sizeof(long)) | 
|  | 628 | PVOP_VCALL3(pv_mmu_ops.set_pgd, pgdp, | 
|  | 629 | val, (u64)val >> 32); | 
|  | 630 | else | 
|  | 631 | PVOP_VCALL2(pv_mmu_ops.set_pgd, pgdp, | 
|  | 632 | val); | 
|  | 633 | } | 
|  | 634 |  | 
|  | 635 | static inline void pgd_clear(pgd_t *pgdp) | 
|  | 636 | { | 
|  | 637 | set_pgd(pgdp, __pgd(0)); | 
|  | 638 | } | 
|  | 639 |  | 
|  | 640 | static inline void pud_clear(pud_t *pudp) | 
|  | 641 | { | 
|  | 642 | set_pud(pudp, __pud(0)); | 
|  | 643 | } | 
|  | 644 |  | 
|  | 645 | #endif	/* PAGETABLE_LEVELS == 4 */ | 
|  | 646 |  | 
| Glauber de Oliveira Costa | 1fe9151 | 2008-01-30 13:33:19 +0100 | [diff] [blame] | 647 | #endif	/* PAGETABLE_LEVELS >= 3 */ | 
|  | 648 |  | 
| Jeremy Fitzhardinge | 4eed80c | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 649 | #ifdef CONFIG_X86_PAE | 
|  | 650 | /* Special-case pte-setting operations for PAE, which can't update a | 
|  | 651 | 64-bit pte atomically */ | 
|  | 652 | static inline void set_pte_atomic(pte_t *ptep, pte_t pte) | 
|  | 653 | { | 
|  | 654 | PVOP_VCALL3(pv_mmu_ops.set_pte_atomic, ptep, | 
|  | 655 | pte.pte, pte.pte >> 32); | 
|  | 656 | } | 
|  | 657 |  | 
| Jeremy Fitzhardinge | 4eed80c | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 658 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, | 
|  | 659 | pte_t *ptep) | 
|  | 660 | { | 
|  | 661 | PVOP_VCALL3(pv_mmu_ops.pte_clear, mm, addr, ptep); | 
|  | 662 | } | 
| Jeremy Fitzhardinge | 60b3f62 | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 663 |  | 
|  | 664 | static inline void pmd_clear(pmd_t *pmdp) | 
|  | 665 | { | 
|  | 666 | PVOP_VCALL1(pv_mmu_ops.pmd_clear, pmdp); | 
|  | 667 | } | 
| Jeremy Fitzhardinge | 4eed80c | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 668 | #else  /* !CONFIG_X86_PAE */ | 
|  | 669 | static inline void set_pte_atomic(pte_t *ptep, pte_t pte) | 
|  | 670 | { | 
|  | 671 | set_pte(ptep, pte); | 
|  | 672 | } | 
|  | 673 |  | 
| Jeremy Fitzhardinge | 4eed80c | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 674 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, | 
|  | 675 | pte_t *ptep) | 
|  | 676 | { | 
|  | 677 | set_pte_at(mm, addr, ptep, __pte(0)); | 
|  | 678 | } | 
| Jeremy Fitzhardinge | 60b3f62 | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 679 |  | 
|  | 680 | static inline void pmd_clear(pmd_t *pmdp) | 
|  | 681 | { | 
|  | 682 | set_pmd(pmdp, __pmd(0)); | 
|  | 683 | } | 
| Jeremy Fitzhardinge | 4eed80c | 2008-01-30 13:33:15 +0100 | [diff] [blame] | 684 | #endif	/* CONFIG_X86_PAE */ | 
|  | 685 |  | 
| Jeremy Fitzhardinge | 7fd7d83 | 2009-02-17 23:24:03 -0800 | [diff] [blame] | 686 | #define  __HAVE_ARCH_START_CONTEXT_SWITCH | 
| Jeremy Fitzhardinge | 224101e | 2009-02-18 11:18:57 -0800 | [diff] [blame] | 687 | static inline void arch_start_context_switch(struct task_struct *prev) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 688 | { | 
| Jeremy Fitzhardinge | 224101e | 2009-02-18 11:18:57 -0800 | [diff] [blame] | 689 | PVOP_VCALL1(pv_cpu_ops.start_context_switch, prev); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 690 | } | 
|  | 691 |  | 
| Jeremy Fitzhardinge | 224101e | 2009-02-18 11:18:57 -0800 | [diff] [blame] | 692 | static inline void arch_end_context_switch(struct task_struct *next) | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 693 | { | 
| Jeremy Fitzhardinge | 224101e | 2009-02-18 11:18:57 -0800 | [diff] [blame] | 694 | PVOP_VCALL1(pv_cpu_ops.end_context_switch, next); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 695 | } | 
|  | 696 |  | 
| Zachary Amsden | 9226d12 | 2007-02-13 13:26:21 +0100 | [diff] [blame] | 697 | #define  __HAVE_ARCH_ENTER_LAZY_MMU_MODE | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 698 | static inline void arch_enter_lazy_mmu_mode(void) | 
|  | 699 | { | 
| Jeremy Fitzhardinge | 8965c1c | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 700 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.enter); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 701 | } | 
|  | 702 |  | 
|  | 703 | static inline void arch_leave_lazy_mmu_mode(void) | 
|  | 704 | { | 
| Jeremy Fitzhardinge | 8965c1c | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 705 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 706 | } | 
|  | 707 |  | 
| Jeremy Fitzhardinge | d85cf93 | 2009-02-12 10:02:56 -0800 | [diff] [blame] | 708 | void arch_flush_lazy_mmu_mode(void); | 
| Zachary Amsden | 9226d12 | 2007-02-13 13:26:21 +0100 | [diff] [blame] | 709 |  | 
| Jeremy Fitzhardinge | aeaaa59 | 2008-06-17 11:42:01 -0700 | [diff] [blame] | 710 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, | 
| Masami Hiramatsu | 3b3809a | 2009-04-09 10:55:33 -0700 | [diff] [blame] | 711 | phys_addr_t phys, pgprot_t flags) | 
| Jeremy Fitzhardinge | aeaaa59 | 2008-06-17 11:42:01 -0700 | [diff] [blame] | 712 | { | 
|  | 713 | pv_mmu_ops.set_fixmap(idx, phys, flags); | 
|  | 714 | } | 
|  | 715 |  | 
| Jeremy Fitzhardinge | b4ecc12 | 2009-05-13 17:16:55 -0700 | [diff] [blame] | 716 | #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) | 
| Ingo Molnar | 4bb689e | 2008-07-09 14:33:33 +0200 | [diff] [blame] | 717 |  | 
| Thomas Gleixner | 0199c4e | 2009-12-02 20:01:25 +0100 | [diff] [blame] | 718 | static inline int arch_spin_is_locked(struct arch_spinlock *lock) | 
| Jeremy Fitzhardinge | 74d4aff | 2008-07-07 12:07:50 -0700 | [diff] [blame] | 719 | { | 
|  | 720 | return PVOP_CALL1(int, pv_lock_ops.spin_is_locked, lock); | 
|  | 721 | } | 
|  | 722 |  | 
| Thomas Gleixner | 0199c4e | 2009-12-02 20:01:25 +0100 | [diff] [blame] | 723 | static inline int arch_spin_is_contended(struct arch_spinlock *lock) | 
| Jeremy Fitzhardinge | 74d4aff | 2008-07-07 12:07:50 -0700 | [diff] [blame] | 724 | { | 
|  | 725 | return PVOP_CALL1(int, pv_lock_ops.spin_is_contended, lock); | 
|  | 726 | } | 
| Thomas Gleixner | 0199c4e | 2009-12-02 20:01:25 +0100 | [diff] [blame] | 727 | #define arch_spin_is_contended	arch_spin_is_contended | 
| Jeremy Fitzhardinge | 74d4aff | 2008-07-07 12:07:50 -0700 | [diff] [blame] | 728 |  | 
| Thomas Gleixner | 0199c4e | 2009-12-02 20:01:25 +0100 | [diff] [blame] | 729 | static __always_inline void arch_spin_lock(struct arch_spinlock *lock) | 
| Jeremy Fitzhardinge | 74d4aff | 2008-07-07 12:07:50 -0700 | [diff] [blame] | 730 | { | 
| Harvey Harrison | 3217256 | 2008-07-17 14:22:34 -0700 | [diff] [blame] | 731 | PVOP_VCALL1(pv_lock_ops.spin_lock, lock); | 
| Jeremy Fitzhardinge | 74d4aff | 2008-07-07 12:07:50 -0700 | [diff] [blame] | 732 | } | 
|  | 733 |  | 
| Thomas Gleixner | 0199c4e | 2009-12-02 20:01:25 +0100 | [diff] [blame] | 734 | static __always_inline void arch_spin_lock_flags(struct arch_spinlock *lock, | 
| Jeremy Fitzhardinge | 63d3a75 | 2008-08-19 13:19:36 -0700 | [diff] [blame] | 735 | unsigned long flags) | 
|  | 736 | { | 
|  | 737 | PVOP_VCALL2(pv_lock_ops.spin_lock_flags, lock, flags); | 
|  | 738 | } | 
|  | 739 |  | 
| Thomas Gleixner | 0199c4e | 2009-12-02 20:01:25 +0100 | [diff] [blame] | 740 | static __always_inline int arch_spin_trylock(struct arch_spinlock *lock) | 
| Jeremy Fitzhardinge | 74d4aff | 2008-07-07 12:07:50 -0700 | [diff] [blame] | 741 | { | 
|  | 742 | return PVOP_CALL1(int, pv_lock_ops.spin_trylock, lock); | 
|  | 743 | } | 
|  | 744 |  | 
| Thomas Gleixner | 0199c4e | 2009-12-02 20:01:25 +0100 | [diff] [blame] | 745 | static __always_inline void arch_spin_unlock(struct arch_spinlock *lock) | 
| Jeremy Fitzhardinge | 74d4aff | 2008-07-07 12:07:50 -0700 | [diff] [blame] | 746 | { | 
| Harvey Harrison | 3217256 | 2008-07-17 14:22:34 -0700 | [diff] [blame] | 747 | PVOP_VCALL1(pv_lock_ops.spin_unlock, lock); | 
| Jeremy Fitzhardinge | 74d4aff | 2008-07-07 12:07:50 -0700 | [diff] [blame] | 748 | } | 
|  | 749 |  | 
| Ingo Molnar | 4bb689e | 2008-07-09 14:33:33 +0200 | [diff] [blame] | 750 | #endif | 
|  | 751 |  | 
| Glauber de Oliveira Costa | 2e47d3e | 2008-01-30 13:32:07 +0100 | [diff] [blame] | 752 | #ifdef CONFIG_X86_32 | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 753 | #define PV_SAVE_REGS "pushl %ecx; pushl %edx;" | 
|  | 754 | #define PV_RESTORE_REGS "popl %edx; popl %ecx;" | 
|  | 755 |  | 
|  | 756 | /* save and restore all caller-save registers, except return value */ | 
| Jeremy Fitzhardinge | e584f55 | 2009-01-30 23:17:23 -0800 | [diff] [blame] | 757 | #define PV_SAVE_ALL_CALLER_REGS		"pushl %ecx;" | 
|  | 758 | #define PV_RESTORE_ALL_CALLER_REGS	"popl  %ecx;" | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 759 |  | 
| Glauber de Oliveira Costa | 2e47d3e | 2008-01-30 13:32:07 +0100 | [diff] [blame] | 760 | #define PV_FLAGS_ARG "0" | 
|  | 761 | #define PV_EXTRA_CLOBBERS | 
|  | 762 | #define PV_VEXTRA_CLOBBERS | 
|  | 763 | #else | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 764 | /* save and restore all caller-save registers, except return value */ | 
|  | 765 | #define PV_SAVE_ALL_CALLER_REGS						\ | 
|  | 766 | "push %rcx;"							\ | 
|  | 767 | "push %rdx;"							\ | 
|  | 768 | "push %rsi;"							\ | 
|  | 769 | "push %rdi;"							\ | 
|  | 770 | "push %r8;"							\ | 
|  | 771 | "push %r9;"							\ | 
|  | 772 | "push %r10;"							\ | 
|  | 773 | "push %r11;" | 
|  | 774 | #define PV_RESTORE_ALL_CALLER_REGS					\ | 
|  | 775 | "pop %r11;"							\ | 
|  | 776 | "pop %r10;"							\ | 
|  | 777 | "pop %r9;"							\ | 
|  | 778 | "pop %r8;"							\ | 
|  | 779 | "pop %rdi;"							\ | 
|  | 780 | "pop %rsi;"							\ | 
|  | 781 | "pop %rdx;"							\ | 
|  | 782 | "pop %rcx;" | 
|  | 783 |  | 
| Glauber de Oliveira Costa | 2e47d3e | 2008-01-30 13:32:07 +0100 | [diff] [blame] | 784 | /* We save some registers, but all of them, that's too much. We clobber all | 
|  | 785 | * caller saved registers but the argument parameter */ | 
|  | 786 | #define PV_SAVE_REGS "pushq %%rdi;" | 
|  | 787 | #define PV_RESTORE_REGS "popq %%rdi;" | 
| Jeremy Fitzhardinge | c24481e | 2008-07-08 15:07:12 -0700 | [diff] [blame] | 788 | #define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx", "rsi" | 
|  | 789 | #define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx", "rsi" | 
| Glauber de Oliveira Costa | 2e47d3e | 2008-01-30 13:32:07 +0100 | [diff] [blame] | 790 | #define PV_FLAGS_ARG "D" | 
|  | 791 | #endif | 
|  | 792 |  | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 793 | /* | 
|  | 794 | * Generate a thunk around a function which saves all caller-save | 
|  | 795 | * registers except for the return value.  This allows C functions to | 
|  | 796 | * be called from assembler code where fewer than normal registers are | 
|  | 797 | * available.  It may also help code generation around calls from C | 
|  | 798 | * code if the common case doesn't use many registers. | 
|  | 799 | * | 
|  | 800 | * When a callee is wrapped in a thunk, the caller can assume that all | 
|  | 801 | * arg regs and all scratch registers are preserved across the | 
|  | 802 | * call. The return value in rax/eax will not be saved, even for void | 
|  | 803 | * functions. | 
|  | 804 | */ | 
|  | 805 | #define PV_CALLEE_SAVE_REGS_THUNK(func)					\ | 
|  | 806 | extern typeof(func) __raw_callee_save_##func;			\ | 
|  | 807 | static void *__##func##__ __used = func;			\ | 
|  | 808 | \ | 
|  | 809 | asm(".pushsection .text;"					\ | 
|  | 810 | "__raw_callee_save_" #func ": "				\ | 
|  | 811 | PV_SAVE_ALL_CALLER_REGS					\ | 
|  | 812 | "call " #func ";"						\ | 
|  | 813 | PV_RESTORE_ALL_CALLER_REGS					\ | 
|  | 814 | "ret;"							\ | 
|  | 815 | ".popsection") | 
|  | 816 |  | 
|  | 817 | /* Get a reference to a callee-save function */ | 
|  | 818 | #define PV_CALLEE_SAVE(func)						\ | 
|  | 819 | ((struct paravirt_callee_save) { __raw_callee_save_##func }) | 
|  | 820 |  | 
|  | 821 | /* Promise that "func" already uses the right calling convention */ | 
|  | 822 | #define __PV_IS_CALLEE_SAVE(func)			\ | 
|  | 823 | ((struct paravirt_callee_save) { func }) | 
|  | 824 |  | 
| Steven Rostedt | b590854 | 2010-11-10 22:29:49 -0500 | [diff] [blame] | 825 | static inline notrace unsigned long arch_local_save_flags(void) | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 826 | { | 
| Jeremy Fitzhardinge | 71999d9 | 2009-10-12 16:32:43 -0700 | [diff] [blame] | 827 | return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl); | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 828 | } | 
|  | 829 |  | 
| Steven Rostedt | b590854 | 2010-11-10 22:29:49 -0500 | [diff] [blame] | 830 | static inline notrace void arch_local_irq_restore(unsigned long f) | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 831 | { | 
| Jeremy Fitzhardinge | 71999d9 | 2009-10-12 16:32:43 -0700 | [diff] [blame] | 832 | PVOP_VCALLEE1(pv_irq_ops.restore_fl, f); | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 833 | } | 
|  | 834 |  | 
| Steven Rostedt | b590854 | 2010-11-10 22:29:49 -0500 | [diff] [blame] | 835 | static inline notrace void arch_local_irq_disable(void) | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 836 | { | 
| Jeremy Fitzhardinge | 71999d9 | 2009-10-12 16:32:43 -0700 | [diff] [blame] | 837 | PVOP_VCALLEE0(pv_irq_ops.irq_disable); | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 838 | } | 
|  | 839 |  | 
| Steven Rostedt | b590854 | 2010-11-10 22:29:49 -0500 | [diff] [blame] | 840 | static inline notrace void arch_local_irq_enable(void) | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 841 | { | 
| Jeremy Fitzhardinge | 71999d9 | 2009-10-12 16:32:43 -0700 | [diff] [blame] | 842 | PVOP_VCALLEE0(pv_irq_ops.irq_enable); | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 843 | } | 
|  | 844 |  | 
| Steven Rostedt | b590854 | 2010-11-10 22:29:49 -0500 | [diff] [blame] | 845 | static inline notrace unsigned long arch_local_irq_save(void) | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 846 | { | 
|  | 847 | unsigned long f; | 
|  | 848 |  | 
| David Howells | df9ee29 | 2010-10-07 14:08:55 +0100 | [diff] [blame] | 849 | f = arch_local_save_flags(); | 
|  | 850 | arch_local_irq_disable(); | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 851 | return f; | 
|  | 852 | } | 
|  | 853 |  | 
| Jeremy Fitzhardinge | 74d4aff | 2008-07-07 12:07:50 -0700 | [diff] [blame] | 854 |  | 
| Jeremy Fitzhardinge | 294688c | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 855 | /* Make sure as little as possible of this mess escapes. */ | 
| Jeremy Fitzhardinge | d582203 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 856 | #undef PARAVIRT_CALL | 
| Jeremy Fitzhardinge | 1a45b7a | 2007-05-02 19:27:15 +0200 | [diff] [blame] | 857 | #undef __PVOP_CALL | 
|  | 858 | #undef __PVOP_VCALL | 
| Jeremy Fitzhardinge | f8822f4 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 859 | #undef PVOP_VCALL0 | 
|  | 860 | #undef PVOP_CALL0 | 
|  | 861 | #undef PVOP_VCALL1 | 
|  | 862 | #undef PVOP_CALL1 | 
|  | 863 | #undef PVOP_VCALL2 | 
|  | 864 | #undef PVOP_CALL2 | 
|  | 865 | #undef PVOP_VCALL3 | 
|  | 866 | #undef PVOP_CALL3 | 
|  | 867 | #undef PVOP_VCALL4 | 
|  | 868 | #undef PVOP_CALL4 | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 869 |  | 
| Thomas Gleixner | 6f30c1a | 2009-08-20 13:19:57 +0200 | [diff] [blame] | 870 | extern void default_banner(void); | 
|  | 871 |  | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 872 | #else  /* __ASSEMBLY__ */ | 
|  | 873 |  | 
| Glauber de Oliveira Costa | 658be9d | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 874 | #define _PVSITE(ptype, clobbers, ops, word, algn)	\ | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 875 | 771:;						\ | 
|  | 876 | ops;					\ | 
|  | 877 | 772:;						\ | 
|  | 878 | .pushsection .parainstructions,"a";	\ | 
| Glauber de Oliveira Costa | 658be9d | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 879 | .align	algn;				\ | 
|  | 880 | word 771b;				\ | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 881 | .byte ptype;				\ | 
|  | 882 | .byte 772b-771b;			\ | 
|  | 883 | .short clobbers;			\ | 
|  | 884 | .popsection | 
|  | 885 |  | 
| Glauber de Oliveira Costa | 658be9d | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 886 |  | 
| Jeremy Fitzhardinge | 9104a18 | 2009-01-28 14:35:04 -0800 | [diff] [blame] | 887 | #define COND_PUSH(set, mask, reg)			\ | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 888 | .if ((~(set)) & mask); push %reg; .endif | 
| Jeremy Fitzhardinge | 9104a18 | 2009-01-28 14:35:04 -0800 | [diff] [blame] | 889 | #define COND_POP(set, mask, reg)			\ | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 890 | .if ((~(set)) & mask); pop %reg; .endif | 
| Jeremy Fitzhardinge | 9104a18 | 2009-01-28 14:35:04 -0800 | [diff] [blame] | 891 |  | 
| Glauber de Oliveira Costa | 658be9d | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 892 | #ifdef CONFIG_X86_64 | 
| Jeremy Fitzhardinge | 9104a18 | 2009-01-28 14:35:04 -0800 | [diff] [blame] | 893 |  | 
|  | 894 | #define PV_SAVE_REGS(set)			\ | 
|  | 895 | COND_PUSH(set, CLBR_RAX, rax);		\ | 
|  | 896 | COND_PUSH(set, CLBR_RCX, rcx);		\ | 
|  | 897 | COND_PUSH(set, CLBR_RDX, rdx);		\ | 
|  | 898 | COND_PUSH(set, CLBR_RSI, rsi);		\ | 
|  | 899 | COND_PUSH(set, CLBR_RDI, rdi);		\ | 
|  | 900 | COND_PUSH(set, CLBR_R8, r8);		\ | 
|  | 901 | COND_PUSH(set, CLBR_R9, r9);		\ | 
|  | 902 | COND_PUSH(set, CLBR_R10, r10);		\ | 
|  | 903 | COND_PUSH(set, CLBR_R11, r11) | 
|  | 904 | #define PV_RESTORE_REGS(set)			\ | 
|  | 905 | COND_POP(set, CLBR_R11, r11);		\ | 
|  | 906 | COND_POP(set, CLBR_R10, r10);		\ | 
|  | 907 | COND_POP(set, CLBR_R9, r9);		\ | 
|  | 908 | COND_POP(set, CLBR_R8, r8);		\ | 
|  | 909 | COND_POP(set, CLBR_RDI, rdi);		\ | 
|  | 910 | COND_POP(set, CLBR_RSI, rsi);		\ | 
|  | 911 | COND_POP(set, CLBR_RDX, rdx);		\ | 
|  | 912 | COND_POP(set, CLBR_RCX, rcx);		\ | 
|  | 913 | COND_POP(set, CLBR_RAX, rax) | 
|  | 914 |  | 
| Glauber de Oliveira Costa | 6057fc8 | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 915 | #define PARA_PATCH(struct, off)        ((PARAVIRT_PATCH_##struct + (off)) / 8) | 
| Glauber de Oliveira Costa | 658be9d | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 916 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8) | 
| Jeremy Fitzhardinge | 491eccb | 2008-06-25 00:19:15 -0400 | [diff] [blame] | 917 | #define PARA_INDIRECT(addr)	*addr(%rip) | 
| Glauber de Oliveira Costa | 658be9d | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 918 | #else | 
| Jeremy Fitzhardinge | 9104a18 | 2009-01-28 14:35:04 -0800 | [diff] [blame] | 919 | #define PV_SAVE_REGS(set)			\ | 
|  | 920 | COND_PUSH(set, CLBR_EAX, eax);		\ | 
|  | 921 | COND_PUSH(set, CLBR_EDI, edi);		\ | 
|  | 922 | COND_PUSH(set, CLBR_ECX, ecx);		\ | 
|  | 923 | COND_PUSH(set, CLBR_EDX, edx) | 
|  | 924 | #define PV_RESTORE_REGS(set)			\ | 
|  | 925 | COND_POP(set, CLBR_EDX, edx);		\ | 
|  | 926 | COND_POP(set, CLBR_ECX, ecx);		\ | 
|  | 927 | COND_POP(set, CLBR_EDI, edi);		\ | 
|  | 928 | COND_POP(set, CLBR_EAX, eax) | 
|  | 929 |  | 
| Glauber de Oliveira Costa | 6057fc8 | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 930 | #define PARA_PATCH(struct, off)        ((PARAVIRT_PATCH_##struct + (off)) / 4) | 
| Glauber de Oliveira Costa | 658be9d | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 931 | #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) | 
| Jeremy Fitzhardinge | 491eccb | 2008-06-25 00:19:15 -0400 | [diff] [blame] | 932 | #define PARA_INDIRECT(addr)	*%cs:addr | 
| Glauber de Oliveira Costa | 658be9d | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 933 | #endif | 
|  | 934 |  | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 935 | #define INTERRUPT_RETURN						\ | 
|  | 936 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE,	\ | 
| Jeremy Fitzhardinge | 491eccb | 2008-06-25 00:19:15 -0400 | [diff] [blame] | 937 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret)) | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 938 |  | 
| Jeremy Fitzhardinge | d582203 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 939 | #define DISABLE_INTERRUPTS(clobbers)					\ | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 940 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 941 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);		\ | 
| Jeremy Fitzhardinge | 491eccb | 2008-06-25 00:19:15 -0400 | [diff] [blame] | 942 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable);	\ | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 943 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 944 |  | 
| Jeremy Fitzhardinge | d582203 | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 945 | #define ENABLE_INTERRUPTS(clobbers)					\ | 
| Jeremy Fitzhardinge | 93b1eab | 2007-10-16 11:51:29 -0700 | [diff] [blame] | 946 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers,	\ | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 947 | PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);		\ | 
| Jeremy Fitzhardinge | 491eccb | 2008-06-25 00:19:15 -0400 | [diff] [blame] | 948 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable);	\ | 
| Jeremy Fitzhardinge | ecb93d1 | 2009-01-28 14:35:05 -0800 | [diff] [blame] | 949 | PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);) | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 950 |  | 
| Jeremy Fitzhardinge | 2be2998 | 2008-06-25 00:19:28 -0400 | [diff] [blame] | 951 | #define USERGS_SYSRET32							\ | 
|  | 952 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret32),	\ | 
| Glauber de Oliveira Costa | 6abcd98 | 2008-01-30 13:30:33 +0100 | [diff] [blame] | 953 | CLBR_NONE,						\ | 
| Jeremy Fitzhardinge | 2be2998 | 2008-06-25 00:19:28 -0400 | [diff] [blame] | 954 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret32)) | 
| Glauber de Oliveira Costa | 2e47d3e | 2008-01-30 13:32:07 +0100 | [diff] [blame] | 955 |  | 
| Glauber de Oliveira Costa | 6057fc8 | 2008-01-30 13:32:06 +0100 | [diff] [blame] | 956 | #ifdef CONFIG_X86_32 | 
| Jeremy Fitzhardinge | 491eccb | 2008-06-25 00:19:15 -0400 | [diff] [blame] | 957 | #define GET_CR0_INTO_EAX				\ | 
|  | 958 | push %ecx; push %edx;				\ | 
|  | 959 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0);	\ | 
| Jeremy Fitzhardinge | 42c24fa | 2007-05-02 19:27:14 +0200 | [diff] [blame] | 960 | pop %edx; pop %ecx | 
| Jeremy Fitzhardinge | 2be2998 | 2008-06-25 00:19:28 -0400 | [diff] [blame] | 961 |  | 
|  | 962 | #define ENABLE_INTERRUPTS_SYSEXIT					\ | 
|  | 963 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit),	\ | 
|  | 964 | CLBR_NONE,						\ | 
|  | 965 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit)) | 
|  | 966 |  | 
|  | 967 |  | 
|  | 968 | #else	/* !CONFIG_X86_32 */ | 
| Jeremy Fitzhardinge | a00394f | 2008-06-25 00:19:30 -0400 | [diff] [blame] | 969 |  | 
|  | 970 | /* | 
|  | 971 | * If swapgs is used while the userspace stack is still current, | 
|  | 972 | * there's no way to call a pvop.  The PV replacement *must* be | 
|  | 973 | * inlined, or the swapgs instruction must be trapped and emulated. | 
|  | 974 | */ | 
|  | 975 | #define SWAPGS_UNSAFE_STACK						\ | 
|  | 976 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE,	\ | 
|  | 977 | swapgs) | 
|  | 978 |  | 
| Jeremy Fitzhardinge | 9104a18 | 2009-01-28 14:35:04 -0800 | [diff] [blame] | 979 | /* | 
|  | 980 | * Note: swapgs is very special, and in practise is either going to be | 
|  | 981 | * implemented with a single "swapgs" instruction or something very | 
|  | 982 | * special.  Either way, we don't need to save any registers for | 
|  | 983 | * it. | 
|  | 984 | */ | 
| Glauber de Oliveira Costa | e801f86 | 2008-01-30 13:32:08 +0100 | [diff] [blame] | 985 | #define SWAPGS								\ | 
|  | 986 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE,	\ | 
| Jeremy Fitzhardinge | 9104a18 | 2009-01-28 14:35:04 -0800 | [diff] [blame] | 987 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs)		\ | 
| Glauber de Oliveira Costa | e801f86 | 2008-01-30 13:32:08 +0100 | [diff] [blame] | 988 | ) | 
|  | 989 |  | 
| H. Peter Anvin | ffc4bc9 | 2012-04-18 17:16:48 -0700 | [diff] [blame] | 990 | #define GET_CR2_INTO_RAX				\ | 
|  | 991 | call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) | 
| Glauber de Oliveira Costa | 4a8c4c4 | 2008-01-30 13:32:07 +0100 | [diff] [blame] | 992 |  | 
| Jeremy Fitzhardinge | fab5842 | 2008-06-25 00:19:31 -0400 | [diff] [blame] | 993 | #define PARAVIRT_ADJUST_EXCEPTION_FRAME					\ | 
|  | 994 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \ | 
|  | 995 | CLBR_NONE,						\ | 
|  | 996 | call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame)) | 
|  | 997 |  | 
| Jeremy Fitzhardinge | 2be2998 | 2008-06-25 00:19:28 -0400 | [diff] [blame] | 998 | #define USERGS_SYSRET64							\ | 
|  | 999 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64),	\ | 
| Jeremy Fitzhardinge | d75cd22 | 2008-06-25 00:19:26 -0400 | [diff] [blame] | 1000 | CLBR_NONE,						\ | 
| Jeremy Fitzhardinge | 2be2998 | 2008-06-25 00:19:28 -0400 | [diff] [blame] | 1001 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64)) | 
|  | 1002 |  | 
|  | 1003 | #define ENABLE_INTERRUPTS_SYSEXIT32					\ | 
|  | 1004 | PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit),	\ | 
|  | 1005 | CLBR_NONE,						\ | 
|  | 1006 | jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit)) | 
|  | 1007 | #endif	/* CONFIG_X86_32 */ | 
| Rusty Russell | 139ec7c | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 1008 |  | 
| Rusty Russell | d3561b7 | 2006-12-07 02:14:07 +0100 | [diff] [blame] | 1009 | #endif /* __ASSEMBLY__ */ | 
| Thomas Gleixner | 6f30c1a | 2009-08-20 13:19:57 +0200 | [diff] [blame] | 1010 | #else  /* CONFIG_PARAVIRT */ | 
|  | 1011 | # define default_banner x86_init_noop | 
|  | 1012 | #endif /* !CONFIG_PARAVIRT */ | 
| H. Peter Anvin | 1965aae | 2008-10-22 22:26:29 -0700 | [diff] [blame] | 1013 | #endif /* _ASM_X86_PARAVIRT_H */ |