]>
Commit | Line | Data |
---|---|---|
6a930a95 BS |
1 | From: Dean Nelson <dcn@sgi.com> |
2 | Subject: Define xp_expand_memprotect() and xp_restrict_memprotect() | |
3 | References: bnc#442461 | |
4 | ||
5 | Define xp_expand_memprotect() and xp_restrict_memprotect() so they can be | |
6 | tailered to the hardware they are run on. | |
7 | ||
8 | Signed-off-by: Dean Nelson <dcn@sgi.com> | |
9 | Acked-by: Bernhard Walle <bwalle@suse.de> | |
10 | ||
11 | --- | |
12 | ||
13 | drivers/misc/sgi-xp/xp.h | 7 +++- | |
14 | drivers/misc/sgi-xp/xp_main.c | 7 ++++ | |
15 | drivers/misc/sgi-xp/xp_sn2.c | 34 +++++++++++++++++++++ | |
16 | drivers/misc/sgi-xp/xp_uv.c | 66 ++++++++++++++++++++++++++++++++++++++++++ | |
17 | drivers/misc/sgi-xp/xpc_sn2.c | 15 +++------ | |
18 | 5 files changed, 117 insertions(+), 12 deletions(-) | |
19 | ||
20 | --- a/drivers/misc/sgi-xp/xp.h | |
21 | +++ b/drivers/misc/sgi-xp/xp.h | |
22 | @@ -190,9 +190,10 @@ enum xp_retval { | |
23 | xpGruSendMqError, /* 59: gru send message queue related error */ | |
24 | ||
25 | xpBadChannelNumber, /* 60: invalid channel number */ | |
26 | - xpBadMsgType, /* 60: invalid message type */ | |
27 | + xpBadMsgType, /* 61: invalid message type */ | |
28 | + xpBiosError, /* 62: BIOS error */ | |
29 | ||
30 | - xpUnknownReason /* 61: unknown reason - must be last in enum */ | |
31 | + xpUnknownReason /* 63: unknown reason - must be last in enum */ | |
32 | }; | |
33 | ||
34 | /* | |
35 | @@ -341,6 +342,8 @@ extern unsigned long (*xp_pa) (void *); | |
36 | extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long, | |
37 | size_t); | |
38 | extern int (*xp_cpu_to_nasid) (int); | |
39 | +extern enum xp_retval (*xp_expand_memprotect) (unsigned long, unsigned long); | |
40 | +extern enum xp_retval (*xp_restrict_memprotect) (unsigned long, unsigned long); | |
41 | ||
42 | extern u64 xp_nofault_PIOR_target; | |
43 | extern int xp_nofault_PIOR(void *); | |
44 | --- a/drivers/misc/sgi-xp/xp_main.c | |
45 | +++ b/drivers/misc/sgi-xp/xp_main.c | |
46 | @@ -51,6 +51,13 @@ EXPORT_SYMBOL_GPL(xp_remote_memcpy); | |
47 | int (*xp_cpu_to_nasid) (int cpuid); | |
48 | EXPORT_SYMBOL_GPL(xp_cpu_to_nasid); | |
49 | ||
50 | +enum xp_retval (*xp_expand_memprotect) (unsigned long phys_addr, | |
51 | + unsigned long size); | |
52 | +EXPORT_SYMBOL_GPL(xp_expand_memprotect); | |
53 | +enum xp_retval (*xp_restrict_memprotect) (unsigned long phys_addr, | |
54 | + unsigned long size); | |
55 | +EXPORT_SYMBOL_GPL(xp_restrict_memprotect); | |
56 | + | |
57 | /* | |
58 | * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level | |
59 | * users of XPC. | |
60 | --- a/drivers/misc/sgi-xp/xp_sn2.c | |
61 | +++ b/drivers/misc/sgi-xp/xp_sn2.c | |
62 | @@ -120,6 +120,38 @@ xp_cpu_to_nasid_sn2(int cpuid) | |
63 | return cpuid_to_nasid(cpuid); | |
64 | } | |
65 | ||
66 | +static enum xp_retval | |
67 | +xp_expand_memprotect_sn2(unsigned long phys_addr, unsigned long size) | |
68 | +{ | |
69 | + u64 nasid_array = 0; | |
70 | + int ret; | |
71 | + | |
72 | + ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1, | |
73 | + &nasid_array); | |
74 | + if (ret != 0) { | |
75 | + dev_err(xp, "sn_change_memprotect(,, " | |
76 | + "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret); | |
77 | + return xpSalError; | |
78 | + } | |
79 | + return xpSuccess; | |
80 | +} | |
81 | + | |
82 | +static enum xp_retval | |
83 | +xp_restrict_memprotect_sn2(unsigned long phys_addr, unsigned long size) | |
84 | +{ | |
85 | + u64 nasid_array = 0; | |
86 | + int ret; | |
87 | + | |
88 | + ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0, | |
89 | + &nasid_array); | |
90 | + if (ret != 0) { | |
91 | + dev_err(xp, "sn_change_memprotect(,, " | |
92 | + "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret); | |
93 | + return xpSalError; | |
94 | + } | |
95 | + return xpSuccess; | |
96 | +} | |
97 | + | |
98 | enum xp_retval | |
99 | xp_init_sn2(void) | |
100 | { | |
101 | @@ -132,6 +164,8 @@ xp_init_sn2(void) | |
102 | xp_pa = xp_pa_sn2; | |
103 | xp_remote_memcpy = xp_remote_memcpy_sn2; | |
104 | xp_cpu_to_nasid = xp_cpu_to_nasid_sn2; | |
105 | + xp_expand_memprotect = xp_expand_memprotect_sn2; | |
106 | + xp_restrict_memprotect = xp_restrict_memprotect_sn2; | |
107 | ||
108 | return xp_register_nofault_code_sn2(); | |
109 | } | |
110 | --- a/drivers/misc/sgi-xp/xp_uv.c | |
111 | +++ b/drivers/misc/sgi-xp/xp_uv.c | |
112 | @@ -15,6 +15,11 @@ | |
113 | ||
114 | #include <linux/device.h> | |
115 | #include <asm/uv/uv_hub.h> | |
116 | +#if defined CONFIG_X86_64 | |
117 | +#include <asm/uv/bios.h> | |
118 | +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV | |
119 | +#include <asm/sn/sn_sal.h> | |
120 | +#endif | |
121 | #include "../sgi-gru/grukservices.h" | |
122 | #include "xp.h" | |
123 | ||
124 | @@ -49,6 +54,65 @@ xp_cpu_to_nasid_uv(int cpuid) | |
125 | return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid)); | |
126 | } | |
127 | ||
128 | +static enum xp_retval | |
129 | +xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size) | |
130 | +{ | |
131 | + int ret; | |
132 | + | |
133 | +#if defined CONFIG_X86_64 | |
134 | + ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW); | |
135 | + if (ret != BIOS_STATUS_SUCCESS) { | |
136 | + dev_err(xp, "uv_bios_change_memprotect(,, " | |
137 | + "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret); | |
138 | + return xpBiosError; | |
139 | + } | |
140 | + | |
141 | +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV | |
142 | + u64 nasid_array; | |
143 | + | |
144 | + ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1, | |
145 | + &nasid_array); | |
146 | + if (ret != 0) { | |
147 | + dev_err(xp, "sn_change_memprotect(,, " | |
148 | + "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret); | |
149 | + return xpSalError; | |
150 | + } | |
151 | +#else | |
152 | + #error not a supported configuration | |
153 | +#endif | |
154 | + return xpSuccess; | |
155 | +} | |
156 | + | |
157 | +static enum xp_retval | |
158 | +xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size) | |
159 | +{ | |
160 | + int ret; | |
161 | + | |
162 | +#if defined CONFIG_X86_64 | |
163 | + ret = uv_bios_change_memprotect(phys_addr, size, | |
164 | + UV_MEMPROT_RESTRICT_ACCESS); | |
165 | + if (ret != BIOS_STATUS_SUCCESS) { | |
166 | + dev_err(xp, "uv_bios_change_memprotect(,, " | |
167 | + "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret); | |
168 | + return xpBiosError; | |
169 | + } | |
170 | + | |
171 | +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV | |
172 | + u64 nasid_array; | |
173 | + | |
174 | + ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0, | |
175 | + &nasid_array); | |
176 | + if (ret != 0) { | |
177 | + dev_err(xp, "sn_change_memprotect(,, " | |
178 | + "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret); | |
179 | + return xpSalError; | |
180 | + } | |
181 | +#else | |
182 | + #error not a supported configuration | |
183 | +#endif | |
184 | + return xpSuccess; | |
185 | +} | |
186 | + | |
187 | enum xp_retval | |
188 | xp_init_uv(void) | |
189 | { | |
190 | @@ -61,6 +125,8 @@ xp_init_uv(void) | |
191 | xp_pa = xp_pa_uv; | |
192 | xp_remote_memcpy = xp_remote_memcpy_uv; | |
193 | xp_cpu_to_nasid = xp_cpu_to_nasid_uv; | |
194 | + xp_expand_memprotect = xp_expand_memprotect_uv; | |
195 | + xp_restrict_memprotect = xp_restrict_memprotect_uv; | |
196 | ||
197 | return xpSuccess; | |
198 | } | |
199 | --- a/drivers/misc/sgi-xp/xpc_sn2.c | |
200 | +++ b/drivers/misc/sgi-xp/xpc_sn2.c | |
201 | @@ -553,22 +553,17 @@ static u64 xpc_prot_vec_sn2[MAX_NUMNODES | |
202 | static enum xp_retval | |
203 | xpc_allow_amo_ops_sn2(struct amo *amos_page) | |
204 | { | |
205 | - u64 nasid_array = 0; | |
206 | - int ret; | |
207 | + enum xp_retval ret = xpSuccess; | |
208 | ||
209 | /* | |
210 | * On SHUB 1.1, we cannot call sn_change_memprotect() since the BIST | |
211 | * collides with memory operations. On those systems we call | |
212 | * xpc_allow_amo_ops_shub_wars_1_1_sn2() instead. | |
213 | */ | |
214 | - if (!enable_shub_wars_1_1()) { | |
215 | - ret = sn_change_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE, | |
216 | - SN_MEMPROT_ACCESS_CLASS_1, | |
217 | - &nasid_array); | |
218 | - if (ret != 0) | |
219 | - return xpSalError; | |
220 | - } | |
221 | - return xpSuccess; | |
222 | + if (!enable_shub_wars_1_1()) | |
223 | + ret = xp_expand_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE); | |
224 | + | |
225 | + return ret; | |
226 | } | |
227 | ||
228 | /* |