aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2008-10-16 22:18:13 -0400
committerTony Luck <tony.luck@intel.com>2008-10-17 13:12:54 -0400
commitf8d1f99f3958c46cdc983743d75d0b31b9accb80 (patch)
treeef91c20de242e67db557e831aa28f9e9597dabef /arch/ia64
parent98c99d7c27973538081a809c114b8d5c6195ecfa (diff)
ia64/pv_ops: paravirtualized instruction checker.
This patch implements a checker to detect instructions which should be paravirtualized instead of direct writing raw instruction. This patch does rough check so that it doesn't fully cover all cases, but it can detects most cases of paravirtualization breakage of hand written assembly codes. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/include/asm/native/pvchk_inst.h263
-rw-r--r--arch/ia64/kernel/Makefile18
-rw-r--r--arch/ia64/kernel/paravirt_inst.h4
-rw-r--r--arch/ia64/scripts/pvcheck.sed32
4 files changed, 316 insertions, 1 deletions
diff --git a/arch/ia64/include/asm/native/pvchk_inst.h b/arch/ia64/include/asm/native/pvchk_inst.h
new file mode 100644
index 000000000000..b8e6eb1090d7
--- /dev/null
+++ b/arch/ia64/include/asm/native/pvchk_inst.h
@@ -0,0 +1,263 @@
1#ifndef _ASM_NATIVE_PVCHK_INST_H
2#define _ASM_NATIVE_PVCHK_INST_H
3
4/******************************************************************************
5 * arch/ia64/include/asm/native/pvchk_inst.h
6 * Checker for paravirtualizations of privileged operations.
7 *
8 * Copyright (C) 2005 Hewlett-Packard Co
9 * Dan Magenheimer <dan.magenheimer@hp.com>
10 *
11 * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
12 * VA Linux Systems Japan K.K.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30/**********************************************
31 * Instructions paravirtualized for correctness
32 **********************************************/
33
34/* "fc" and "thash" are privilege-sensitive instructions, meaning they
35 * may have different semantics depending on whether they are executed
36 * at PL0 vs PL!=0. When paravirtualized, these instructions mustn't
37 * be allowed to execute directly, lest incorrect semantics result.
38 */
39
40#define fc .error "fc should not be used directly."
41#define thash .error "thash should not be used directly."
42
43/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
44 * is not currently used (though it may be in a long-format VHPT system!)
45 * and the semantics of cover only change if psr.ic is off which is very
46 * rare (and currently non-existent outside of assembly code
47 */
48#define ttag .error "ttag should not be used directly."
49#define cover .error "cover should not be used directly."
50
51/* There are also privilege-sensitive registers. These registers are
52 * readable at any privilege level but only writable at PL0.
53 */
54#define cpuid .error "cpuid should not be used directly."
55#define pmd .error "pmd should not be used directly."
56
57/*
58 * mov ar.eflag =
59 * mov = ar.eflag
60 */
61
62/**********************************************
63 * Instructions paravirtualized for performance
64 **********************************************/
65/*
66 * Those instructions include '.' which can't be handled by cpp.
67 * or can't be handled by cpp easily.
68 * They are handled by sed instead of cpp.
69 */
70
71/* for .S
72 * itc.i
73 * itc.d
74 *
75 * bsw.0
76 * bsw.1
77 *
78 * ssm psr.ic | PSR_DEFAULT_BITS
79 * ssm psr.ic
80 * rsm psr.ic
81 * ssm psr.i
82 * rsm psr.i
83 * rsm psr.i | psr.ic
84 * rsm psr.dt
85 * ssm psr.dt
86 *
87 * mov = cr.ifa
88 * mov = cr.itir
89 * mov = cr.isr
90 * mov = cr.iha
91 * mov = cr.ipsr
92 * mov = cr.iim
93 * mov = cr.iip
94 * mov = cr.ivr
95 * mov = psr
96 *
97 * mov cr.ifa =
98 * mov cr.itir =
99 * mov cr.iha =
100 * mov cr.ipsr =
101 * mov cr.ifs =
102 * mov cr.iip =
103 * mov cr.kr =
104 */
105
106/* for intrinsics
107 * ssm psr.i
108 * rsm psr.i
109 * mov = psr
110 * mov = ivr
111 * mov = tpr
112 * mov cr.itm =
113 * mov eoi =
114 * mov rr[] =
115 * mov = rr[]
116 * mov = kr
117 * mov kr =
118 * ptc.ga
119 */
120
121/*************************************************************
122 * define paravirtualized instrcution macros as nop to ingore.
123 * and check whether arguments are appropriate.
124 *************************************************************/
125
126/* check whether reg is a regular register */
127.macro is_rreg_in reg
128 .ifc "\reg", "r0"
129 nop 0
130 .exitm
131 .endif
132 ;;
133 mov \reg = r0
134 ;;
135.endm
136#define IS_RREG_IN(reg) is_rreg_in reg ;
137
138#define IS_RREG_OUT(reg) \
139 ;; \
140 mov reg = r0 \
141 ;;
142
143#define IS_RREG_CLOB(reg) IS_RREG_OUT(reg)
144
145/* check whether pred is a predicate register */
146#define IS_PRED_IN(pred) \
147 ;; \
148 (pred) nop 0 \
149 ;;
150
151#define IS_PRED_OUT(pred) \
152 ;; \
153 cmp.eq pred, p0 = r0, r0 \
154 ;;
155
156#define IS_PRED_CLOB(pred) IS_PRED_OUT(pred)
157
158
159#define DO_SAVE_MIN(__COVER, SAVE_IFS, EXTRA, WORKAROUND) \
160 nop 0
161#define MOV_FROM_IFA(reg) \
162 IS_RREG_OUT(reg)
163#define MOV_FROM_ITIR(reg) \
164 IS_RREG_OUT(reg)
165#define MOV_FROM_ISR(reg) \
166 IS_RREG_OUT(reg)
167#define MOV_FROM_IHA(reg) \
168 IS_RREG_OUT(reg)
169#define MOV_FROM_IPSR(pred, reg) \
170 IS_PRED_IN(pred) \
171 IS_RREG_OUT(reg)
172#define MOV_FROM_IIM(reg) \
173 IS_RREG_OUT(reg)
174#define MOV_FROM_IIP(reg) \
175 IS_RREG_OUT(reg)
176#define MOV_FROM_IVR(reg, clob) \
177 IS_RREG_OUT(reg) \
178 IS_RREG_CLOB(clob)
179#define MOV_FROM_PSR(pred, reg, clob) \
180 IS_PRED_IN(pred) \
181 IS_RREG_OUT(reg) \
182 IS_RREG_CLOB(clob)
183#define MOV_TO_IFA(reg, clob) \
184 IS_RREG_IN(reg) \
185 IS_RREG_CLOB(clob)
186#define MOV_TO_ITIR(pred, reg, clob) \
187 IS_PRED_IN(pred) \
188 IS_RREG_IN(reg) \
189 IS_RREG_CLOB(clob)
190#define MOV_TO_IHA(pred, reg, clob) \
191 IS_PRED_IN(pred) \
192 IS_RREG_IN(reg) \
193 IS_RREG_CLOB(clob)
194#define MOV_TO_IPSR(pred, reg, clob) \
195 IS_PRED_IN(pred) \
196 IS_RREG_IN(reg) \
197 IS_RREG_CLOB(clob)
198#define MOV_TO_IFS(pred, reg, clob) \
199 IS_PRED_IN(pred) \
200 IS_RREG_IN(reg) \
201 IS_RREG_CLOB(clob)
202#define MOV_TO_IIP(reg, clob) \
203 IS_RREG_IN(reg) \
204 IS_RREG_CLOB(clob)
205#define MOV_TO_KR(kr, reg, clob0, clob1) \
206 IS_RREG_IN(reg) \
207 IS_RREG_CLOB(clob0) \
208 IS_RREG_CLOB(clob1)
209#define ITC_I(pred, reg, clob) \
210 IS_PRED_IN(pred) \
211 IS_RREG_IN(reg) \
212 IS_RREG_CLOB(clob)
213#define ITC_D(pred, reg, clob) \
214 IS_PRED_IN(pred) \
215 IS_RREG_IN(reg) \
216 IS_RREG_CLOB(clob)
217#define ITC_I_AND_D(pred_i, pred_d, reg, clob) \
218 IS_PRED_IN(pred_i) \
219 IS_PRED_IN(pred_d) \
220 IS_RREG_IN(reg) \
221 IS_RREG_CLOB(clob)
222#define THASH(pred, reg0, reg1, clob) \
223 IS_PRED_IN(pred) \
224 IS_RREG_OUT(reg0) \
225 IS_RREG_IN(reg1) \
226 IS_RREG_CLOB(clob)
227#define SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(clob0, clob1) \
228 IS_RREG_CLOB(clob0) \
229 IS_RREG_CLOB(clob1)
230#define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1) \
231 IS_RREG_CLOB(clob0) \
232 IS_RREG_CLOB(clob1)
233#define RSM_PSR_IC(clob) \
234 IS_RREG_CLOB(clob)
235#define SSM_PSR_I(pred, pred_clob, clob) \
236 IS_PRED_IN(pred) \
237 IS_PRED_CLOB(pred_clob) \
238 IS_RREG_CLOB(clob)
239#define RSM_PSR_I(pred, clob0, clob1) \
240 IS_PRED_IN(pred) \
241 IS_RREG_CLOB(clob0) \
242 IS_RREG_CLOB(clob1)
243#define RSM_PSR_I_IC(clob0, clob1, clob2) \
244 IS_RREG_CLOB(clob0) \
245 IS_RREG_CLOB(clob1) \
246 IS_RREG_CLOB(clob2)
247#define RSM_PSR_DT \
248 nop 0
249#define SSM_PSR_DT_AND_SRLZ_I \
250 nop 0
251#define BSW_0(clob0, clob1, clob2) \
252 IS_RREG_CLOB(clob0) \
253 IS_RREG_CLOB(clob1) \
254 IS_RREG_CLOB(clob2)
255#define BSW_1(clob0, clob1) \
256 IS_RREG_CLOB(clob0) \
257 IS_RREG_CLOB(clob1)
258#define COVER \
259 nop 0
260#define RFI \
261 br.ret.sptk.many rp /* defining nop causes dependency error */
262
263#endif /* _ASM_NATIVE_PVCHK_INST_H */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 87fea11aecb7..55e6ca8eebda 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -112,5 +112,23 @@ clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
112ASM_PARAVIRT_OBJS = ivt.o entry.o 112ASM_PARAVIRT_OBJS = ivt.o entry.o
113define paravirtualized_native 113define paravirtualized_native
114AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE 114AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
115AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK
116extra-y += pvchk-$(1)
115endef 117endef
116$(foreach obj,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_native,$(obj)))) 118$(foreach obj,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_native,$(obj))))
119
120#
121# Checker for paravirtualizations of privileged operations.
122#
123quiet_cmd_pv_check_sed = PVCHK $@
124define cmd_pv_check_sed
125 sed -f $(srctree)/arch/$(SRCARCH)/scripts/pvcheck.sed $< > $@
126endef
127
128$(obj)/pvchk-sed-%.s: $(src)/%.S $(srctree)/arch/$(SRCARCH)/scripts/pvcheck.sed FORCE
129 $(call if_changed_dep,as_s_S)
130$(obj)/pvchk-%.s: $(obj)/pvchk-sed-%.s FORCE
131 $(call if_changed,pv_check_sed)
132$(obj)/pvchk-%.o: $(obj)/pvchk-%.s FORCE
133 $(call if_changed,as_o_S)
134.PRECIOUS: $(obj)/pvchk-sed-%.s $(obj)/pvchk-%.s $(obj)/pvchk-%.o
diff --git a/arch/ia64/kernel/paravirt_inst.h b/arch/ia64/kernel/paravirt_inst.h
index 5cad6fb2ed19..64d6d810c64b 100644
--- a/arch/ia64/kernel/paravirt_inst.h
+++ b/arch/ia64/kernel/paravirt_inst.h
@@ -20,7 +20,9 @@
20 * 20 *
21 */ 21 */
22 22
23#ifdef __IA64_ASM_PARAVIRTUALIZED_XEN 23#ifdef __IA64_ASM_PARAVIRTUALIZED_PVCHECK
24#include <asm/native/pvchk_inst.h>
25#elif defined(__IA64_ASM_PARAVIRTUALIZED_XEN)
24#include <asm/xen/inst.h> 26#include <asm/xen/inst.h>
25#include <asm/xen/minstate.h> 27#include <asm/xen/minstate.h>
26#else 28#else
diff --git a/arch/ia64/scripts/pvcheck.sed b/arch/ia64/scripts/pvcheck.sed
new file mode 100644
index 000000000000..ba66ac2e4c60
--- /dev/null
+++ b/arch/ia64/scripts/pvcheck.sed
@@ -0,0 +1,32 @@
1#
2# Checker for paravirtualizations of privileged operations.
3#
4s/ssm.*psr\.ic.*/.warning \"ssm psr.ic should not be used directly\"/g
5s/rsm.*psr\.ic.*/.warning \"rsm psr.ic should not be used directly\"/g
6s/ssm.*psr\.i.*/.warning \"ssm psr.i should not be used directly\"/g
7s/rsm.*psr\.i.*/.warning \"rsm psr.i should not be used directly\"/g
8s/ssm.*psr\.dt.*/.warning \"ssm psr.dt should not be used directly\"/g
9s/rsm.*psr\.dt.*/.warning \"rsm psr.dt should not be used directly\"/g
10s/mov.*=.*cr\.ifa/.warning \"cr.ifa should not used directly\"/g
11s/mov.*=.*cr\.itir/.warning \"cr.itir should not used directly\"/g
12s/mov.*=.*cr\.isr/.warning \"cr.isr should not used directly\"/g
13s/mov.*=.*cr\.iha/.warning \"cr.iha should not used directly\"/g
14s/mov.*=.*cr\.ipsr/.warning \"cr.ipsr should not used directly\"/g
15s/mov.*=.*cr\.iim/.warning \"cr.iim should not used directly\"/g
16s/mov.*=.*cr\.iip/.warning \"cr.iip should not used directly\"/g
17s/mov.*=.*cr\.ivr/.warning \"cr.ivr should not used directly\"/g
18s/mov.*=[^\.]*psr/.warning \"psr should not used directly\"/g # avoid ar.fpsr
19s/mov.*=.*ar\.eflags/.warning \"ar.eflags should not used directly\"/g
20s/mov.*cr\.ifa.*=.*/.warning \"cr.ifa should not used directly\"/g
21s/mov.*cr\.itir.*=.*/.warning \"cr.itir should not used directly\"/g
22s/mov.*cr\.iha.*=.*/.warning \"cr.iha should not used directly\"/g
23s/mov.*cr\.ipsr.*=.*/.warning \"cr.ipsr should not used directly\"/g
24s/mov.*cr\.ifs.*=.*/.warning \"cr.ifs should not used directly\"/g
25s/mov.*cr\.iip.*=.*/.warning \"cr.iip should not used directly\"/g
26s/mov.*cr\.kr.*=.*/.warning \"cr.kr should not used directly\"/g
27s/mov.*ar\.eflags.*=.*/.warning \"ar.eflags should not used directly\"/g
28s/itc\.i.*/.warning \"itc.i should not be used directly.\"/g
29s/itc\.d.*/.warning \"itc.d should not be used directly.\"/g
30s/bsw\.0/.warning \"bsw.0 should not be used directly.\"/g
31s/bsw\.1/.warning \"bsw.1 should not be used directly.\"/g
32s/ptc\.ga.*/.warning \"ptc.ga should not be used directly.\"/g