aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-ia64
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2008-05-19 09:13:34 -0400
committerTony Luck <tony.luck@intel.com>2008-05-27 17:40:18 -0400
commit1ff730b52f0c3e4e3846c3ff345c5526b2633ba9 (patch)
tree59a614eaa0679ba0ccd99e1f910ceeb22fc31948 /include/asm-ia64
parent3e0879deb700f322f6c81ab34f056fc72d15ec02 (diff)
[IA64] pvops: introduce pv_cpu_ops to paravirtualize privileged instructions.
introduce pv_cpu_ops to paravirtualize privleged instructions which are defined by ia64 intrinsics. make them indirect C function calls by introducing function tables, pv_cpu_ops. Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com> Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'include/asm-ia64')
-rw-r--r--include/asm-ia64/Kbuild2
-rw-r--r--include/asm-ia64/gcc_intrin.h24
-rw-r--r--include/asm-ia64/intel_intrin.h41
-rw-r--r--include/asm-ia64/intrinsics.h62
-rw-r--r--include/asm-ia64/paravirt_privop.h91
5 files changed, 178 insertions, 42 deletions
diff --git a/include/asm-ia64/Kbuild b/include/asm-ia64/Kbuild
index eb24a3f47caa..ccbe8ae47a61 100644
--- a/include/asm-ia64/Kbuild
+++ b/include/asm-ia64/Kbuild
@@ -5,12 +5,12 @@ header-y += fpu.h
5header-y += fpswa.h 5header-y += fpswa.h
6header-y += ia64regs.h 6header-y += ia64regs.h
7header-y += intel_intrin.h 7header-y += intel_intrin.h
8header-y += intrinsics.h
9header-y += perfmon_default_smpl.h 8header-y += perfmon_default_smpl.h
10header-y += ptrace_offsets.h 9header-y += ptrace_offsets.h
11header-y += rse.h 10header-y += rse.h
12header-y += ucontext.h 11header-y += ucontext.h
13 12
14unifdef-y += gcc_intrin.h 13unifdef-y += gcc_intrin.h
14unifdef-y += intrinsics.h
15unifdef-y += perfmon.h 15unifdef-y += perfmon.h
16unifdef-y += ustack.h 16unifdef-y += ustack.h
diff --git a/include/asm-ia64/gcc_intrin.h b/include/asm-ia64/gcc_intrin.h
index 2fe292c275fe..0f5b55921758 100644
--- a/include/asm-ia64/gcc_intrin.h
+++ b/include/asm-ia64/gcc_intrin.h
@@ -32,7 +32,7 @@ extern void ia64_bad_param_for_getreg (void);
32register unsigned long ia64_r13 asm ("r13") __used; 32register unsigned long ia64_r13 asm ("r13") __used;
33#endif 33#endif
34 34
35#define ia64_setreg(regnum, val) \ 35#define ia64_native_setreg(regnum, val) \
36({ \ 36({ \
37 switch (regnum) { \ 37 switch (regnum) { \
38 case _IA64_REG_PSR_L: \ 38 case _IA64_REG_PSR_L: \
@@ -61,7 +61,7 @@ register unsigned long ia64_r13 asm ("r13") __used;
61 } \ 61 } \
62}) 62})
63 63
64#define ia64_getreg(regnum) \ 64#define ia64_native_getreg(regnum) \
65({ \ 65({ \
66 __u64 ia64_intri_res; \ 66 __u64 ia64_intri_res; \
67 \ 67 \
@@ -385,7 +385,7 @@ register unsigned long ia64_r13 asm ("r13") __used;
385 385
386#define ia64_invala() asm volatile ("invala" ::: "memory") 386#define ia64_invala() asm volatile ("invala" ::: "memory")
387 387
388#define ia64_thash(addr) \ 388#define ia64_native_thash(addr) \
389({ \ 389({ \
390 __u64 ia64_intri_res; \ 390 __u64 ia64_intri_res; \
391 asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \ 391 asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
@@ -438,10 +438,10 @@ register unsigned long ia64_r13 asm ("r13") __used;
438#define ia64_set_pmd(index, val) \ 438#define ia64_set_pmd(index, val) \
439 asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory") 439 asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
440 440
441#define ia64_set_rr(index, val) \ 441#define ia64_native_set_rr(index, val) \
442 asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory"); 442 asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
443 443
444#define ia64_get_cpuid(index) \ 444#define ia64_native_get_cpuid(index) \
445({ \ 445({ \
446 __u64 ia64_intri_res; \ 446 __u64 ia64_intri_res; \
447 asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index)); \ 447 asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index)); \
@@ -477,33 +477,33 @@ register unsigned long ia64_r13 asm ("r13") __used;
477}) 477})
478 478
479 479
480#define ia64_get_pmd(index) \ 480#define ia64_native_get_pmd(index) \
481({ \ 481({ \
482 __u64 ia64_intri_res; \ 482 __u64 ia64_intri_res; \
483 asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ 483 asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
484 ia64_intri_res; \ 484 ia64_intri_res; \
485}) 485})
486 486
487#define ia64_get_rr(index) \ 487#define ia64_native_get_rr(index) \
488({ \ 488({ \
489 __u64 ia64_intri_res; \ 489 __u64 ia64_intri_res; \
490 asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index)); \ 490 asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index)); \
491 ia64_intri_res; \ 491 ia64_intri_res; \
492}) 492})
493 493
494#define ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory") 494#define ia64_native_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
495 495
496 496
497#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory") 497#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
498 498
499#define ia64_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory") 499#define ia64_native_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory")
500#define ia64_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory") 500#define ia64_native_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory")
501#define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory") 501#define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory")
502#define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory") 502#define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory")
503 503
504#define ia64_ptce(addr) asm volatile ("ptc.e %0" :: "r"(addr)) 504#define ia64_ptce(addr) asm volatile ("ptc.e %0" :: "r"(addr))
505 505
506#define ia64_ptcga(addr, size) \ 506#define ia64_native_ptcga(addr, size) \
507do { \ 507do { \
508 asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory"); \ 508 asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory"); \
509 ia64_dv_serialize_data(); \ 509 ia64_dv_serialize_data(); \
@@ -608,7 +608,7 @@ do { \
608 } \ 608 } \
609}) 609})
610 610
611#define ia64_intrin_local_irq_restore(x) \ 611#define ia64_native_intrin_local_irq_restore(x) \
612do { \ 612do { \
613 asm volatile (";; cmp.ne p6,p7=%0,r0;;" \ 613 asm volatile (";; cmp.ne p6,p7=%0,r0;;" \
614 "(p6) ssm psr.i;" \ 614 "(p6) ssm psr.i;" \
diff --git a/include/asm-ia64/intel_intrin.h b/include/asm-ia64/intel_intrin.h
index a520d103d808..53cec577558a 100644
--- a/include/asm-ia64/intel_intrin.h
+++ b/include/asm-ia64/intel_intrin.h
@@ -16,8 +16,8 @@
16 * intrinsic 16 * intrinsic
17 */ 17 */
18 18
19#define ia64_getreg __getReg 19#define ia64_native_getreg __getReg
20#define ia64_setreg __setReg 20#define ia64_native_setreg __setReg
21 21
22#define ia64_hint __hint 22#define ia64_hint __hint
23#define ia64_hint_pause __hint_pause 23#define ia64_hint_pause __hint_pause
@@ -39,10 +39,10 @@
39#define ia64_invala_fr __invala_fr 39#define ia64_invala_fr __invala_fr
40#define ia64_nop __nop 40#define ia64_nop __nop
41#define ia64_sum __sum 41#define ia64_sum __sum
42#define ia64_ssm __ssm 42#define ia64_native_ssm __ssm
43#define ia64_rum __rum 43#define ia64_rum __rum
44#define ia64_rsm __rsm 44#define ia64_native_rsm __rsm
45#define ia64_fc __fc 45#define ia64_native_fc __fc
46 46
47#define ia64_ldfs __ldfs 47#define ia64_ldfs __ldfs
48#define ia64_ldfd __ldfd 48#define ia64_ldfd __ldfd
@@ -88,16 +88,17 @@
88 __setIndReg(_IA64_REG_INDR_PMC, index, val) 88 __setIndReg(_IA64_REG_INDR_PMC, index, val)
89#define ia64_set_pmd(index, val) \ 89#define ia64_set_pmd(index, val) \
90 __setIndReg(_IA64_REG_INDR_PMD, index, val) 90 __setIndReg(_IA64_REG_INDR_PMD, index, val)
91#define ia64_set_rr(index, val) \ 91#define ia64_native_set_rr(index, val) \
92 __setIndReg(_IA64_REG_INDR_RR, index, val) 92 __setIndReg(_IA64_REG_INDR_RR, index, val)
93 93
94#define ia64_get_cpuid(index) __getIndReg(_IA64_REG_INDR_CPUID, index) 94#define ia64_native_get_cpuid(index) \
95#define __ia64_get_dbr(index) __getIndReg(_IA64_REG_INDR_DBR, index) 95 __getIndReg(_IA64_REG_INDR_CPUID, index)
96#define ia64_get_ibr(index) __getIndReg(_IA64_REG_INDR_IBR, index) 96#define __ia64_get_dbr(index) __getIndReg(_IA64_REG_INDR_DBR, index)
97#define ia64_get_pkr(index) __getIndReg(_IA64_REG_INDR_PKR, index) 97#define ia64_get_ibr(index) __getIndReg(_IA64_REG_INDR_IBR, index)
98#define ia64_get_pmc(index) __getIndReg(_IA64_REG_INDR_PMC, index) 98#define ia64_get_pkr(index) __getIndReg(_IA64_REG_INDR_PKR, index)
99#define ia64_get_pmd(index) __getIndReg(_IA64_REG_INDR_PMD, index) 99#define ia64_get_pmc(index) __getIndReg(_IA64_REG_INDR_PMC, index)
100#define ia64_get_rr(index) __getIndReg(_IA64_REG_INDR_RR, index) 100#define ia64_native_get_pmd(index) __getIndReg(_IA64_REG_INDR_PMD, index)
101#define ia64_native_get_rr(index) __getIndReg(_IA64_REG_INDR_RR, index)
101 102
102#define ia64_srlz_d __dsrlz 103#define ia64_srlz_d __dsrlz
103#define ia64_srlz_i __isrlz 104#define ia64_srlz_i __isrlz
@@ -119,16 +120,16 @@
119#define ia64_ld8_acq __ld8_acq 120#define ia64_ld8_acq __ld8_acq
120 121
121#define ia64_sync_i __synci 122#define ia64_sync_i __synci
122#define ia64_thash __thash 123#define ia64_native_thash __thash
123#define ia64_ttag __ttag 124#define ia64_native_ttag __ttag
124#define ia64_itcd __itcd 125#define ia64_itcd __itcd
125#define ia64_itci __itci 126#define ia64_itci __itci
126#define ia64_itrd __itrd 127#define ia64_itrd __itrd
127#define ia64_itri __itri 128#define ia64_itri __itri
128#define ia64_ptce __ptce 129#define ia64_ptce __ptce
129#define ia64_ptcl __ptcl 130#define ia64_ptcl __ptcl
130#define ia64_ptcg __ptcg 131#define ia64_native_ptcg __ptcg
131#define ia64_ptcga __ptcga 132#define ia64_native_ptcga __ptcga
132#define ia64_ptri __ptri 133#define ia64_ptri __ptri
133#define ia64_ptrd __ptrd 134#define ia64_ptrd __ptrd
134#define ia64_dep_mi _m64_dep_mi 135#define ia64_dep_mi _m64_dep_mi
@@ -145,13 +146,13 @@
145#define ia64_lfetch_fault __lfetch_fault 146#define ia64_lfetch_fault __lfetch_fault
146#define ia64_lfetch_fault_excl __lfetch_fault_excl 147#define ia64_lfetch_fault_excl __lfetch_fault_excl
147 148
148#define ia64_intrin_local_irq_restore(x) \ 149#define ia64_native_intrin_local_irq_restore(x) \
149do { \ 150do { \
150 if ((x) != 0) { \ 151 if ((x) != 0) { \
151 ia64_ssm(IA64_PSR_I); \ 152 ia64_native_ssm(IA64_PSR_I); \
152 ia64_srlz_d(); \ 153 ia64_srlz_d(); \
153 } else { \ 154 } else { \
154 ia64_rsm(IA64_PSR_I); \ 155 ia64_native_rsm(IA64_PSR_I); \
155 } \ 156 } \
156} while (0) 157} while (0)
157 158
diff --git a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h
index a3b96892f83f..47d686dba1eb 100644
--- a/include/asm-ia64/intrinsics.h
+++ b/include/asm-ia64/intrinsics.h
@@ -18,15 +18,15 @@
18# include <asm/gcc_intrin.h> 18# include <asm/gcc_intrin.h>
19#endif 19#endif
20 20
21#define ia64_get_psr_i() (ia64_getreg(_IA64_REG_PSR) & IA64_PSR_I) 21#define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
22 22
23#define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \ 23#define ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4) \
24do { \ 24do { \
25 ia64_set_rr(0x0000000000000000UL, (val0)); \ 25 ia64_native_set_rr(0x0000000000000000UL, (val0)); \
26 ia64_set_rr(0x2000000000000000UL, (val1)); \ 26 ia64_native_set_rr(0x2000000000000000UL, (val1)); \
27 ia64_set_rr(0x4000000000000000UL, (val2)); \ 27 ia64_native_set_rr(0x4000000000000000UL, (val2)); \
28 ia64_set_rr(0x6000000000000000UL, (val3)); \ 28 ia64_native_set_rr(0x6000000000000000UL, (val3)); \
29 ia64_set_rr(0x8000000000000000UL, (val4)); \ 29 ia64_native_set_rr(0x8000000000000000UL, (val4)); \
30} while (0) 30} while (0)
31 31
32/* 32/*
@@ -194,4 +194,48 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void);
194#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ 194#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
195 195
196#endif 196#endif
197
198#ifdef __KERNEL__
199#include <asm/paravirt_privop.h>
200#endif
201
202#ifndef __ASSEMBLY__
203#if defined(CONFIG_PARAVIRT) && defined(__KERNEL__)
204#define IA64_INTRINSIC_API(name) pv_cpu_ops.name
205#define IA64_INTRINSIC_MACRO(name) paravirt_ ## name
206#else
207#define IA64_INTRINSIC_API(name) ia64_native_ ## name
208#define IA64_INTRINSIC_MACRO(name) ia64_native_ ## name
209#endif
210
211/************************************************/
212/* Instructions paravirtualized for correctness */
213/************************************************/
214/* fc, thash, get_cpuid, get_pmd, get_eflags, set_eflags */
215/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
216 * is not currently used (though it may be in a long-format VHPT system!)
217 */
218#define ia64_fc IA64_INTRINSIC_API(fc)
219#define ia64_thash IA64_INTRINSIC_API(thash)
220#define ia64_get_cpuid IA64_INTRINSIC_API(get_cpuid)
221#define ia64_get_pmd IA64_INTRINSIC_API(get_pmd)
222
223
224/************************************************/
225/* Instructions paravirtualized for performance */
226/************************************************/
227#define ia64_ssm IA64_INTRINSIC_MACRO(ssm)
228#define ia64_rsm IA64_INTRINSIC_MACRO(rsm)
229#define ia64_getreg IA64_INTRINSIC_API(getreg)
230#define ia64_setreg IA64_INTRINSIC_API(setreg)
231#define ia64_set_rr IA64_INTRINSIC_API(set_rr)
232#define ia64_get_rr IA64_INTRINSIC_API(get_rr)
233#define ia64_ptcga IA64_INTRINSIC_API(ptcga)
234#define ia64_get_psr_i IA64_INTRINSIC_API(get_psr_i)
235#define ia64_intrin_local_irq_restore \
236 IA64_INTRINSIC_API(intrin_local_irq_restore)
237#define ia64_set_rr0_to_rr4 IA64_INTRINSIC_API(set_rr0_to_rr4)
238
239#endif /* !__ASSEMBLY__ */
240
197#endif /* _ASM_IA64_INTRINSICS_H */ 241#endif /* _ASM_IA64_INTRINSICS_H */
diff --git a/include/asm-ia64/paravirt_privop.h b/include/asm-ia64/paravirt_privop.h
new file mode 100644
index 000000000000..7b133ae86df0
--- /dev/null
+++ b/include/asm-ia64/paravirt_privop.h
@@ -0,0 +1,91 @@
1/******************************************************************************
2 * include/asm-ia64/paravirt_privops.h
3 *
4 * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
5 * VA Linux Systems Japan K.K.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef _ASM_IA64_PARAVIRT_PRIVOP_H
24#define _ASM_IA64_PARAVIRT_PRIVOP_H
25
26#ifdef CONFIG_PARAVIRT
27
28#ifndef __ASSEMBLY__
29
30#include <linux/types.h>
31#include <asm/kregs.h> /* for IA64_PSR_I */
32
33/******************************************************************************
34 * replacement of intrinsics operations.
35 */
36
37struct pv_cpu_ops {
38 void (*fc)(unsigned long addr);
39 unsigned long (*thash)(unsigned long addr);
40 unsigned long (*get_cpuid)(int index);
41 unsigned long (*get_pmd)(int index);
42 unsigned long (*getreg)(int reg);
43 void (*setreg)(int reg, unsigned long val);
44 void (*ptcga)(unsigned long addr, unsigned long size);
45 unsigned long (*get_rr)(unsigned long index);
46 void (*set_rr)(unsigned long index, unsigned long val);
47 void (*set_rr0_to_rr4)(unsigned long val0, unsigned long val1,
48 unsigned long val2, unsigned long val3,
49 unsigned long val4);
50 void (*ssm_i)(void);
51 void (*rsm_i)(void);
52 unsigned long (*get_psr_i)(void);
53 void (*intrin_local_irq_restore)(unsigned long flags);
54};
55
56extern struct pv_cpu_ops pv_cpu_ops;
57
58extern void ia64_native_setreg_func(int regnum, unsigned long val);
59extern unsigned long ia64_native_getreg_func(int regnum);
60
61/************************************************/
62/* Instructions paravirtualized for performance */
63/************************************************/
64
65/* mask for ia64_native_ssm/rsm() must be constant.("i" constraing).
66 * static inline function doesn't satisfy it. */
67#define paravirt_ssm(mask) \
68 do { \
69 if ((mask) == IA64_PSR_I) \
70 pv_cpu_ops.ssm_i(); \
71 else \
72 ia64_native_ssm(mask); \
73 } while (0)
74
75#define paravirt_rsm(mask) \
76 do { \
77 if ((mask) == IA64_PSR_I) \
78 pv_cpu_ops.rsm_i(); \
79 else \
80 ia64_native_rsm(mask); \
81 } while (0)
82
83#endif /* __ASSEMBLY__ */
84
85#else
86
87/* fallback for native case */
88
89#endif /* CONFIG_PARAVIRT */
90
91#endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */