Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/i86pc/io/amd_iommu/amd_iommu.c
+++ new/usr/src/uts/i86pc/io/amd_iommu/amd_iommu.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 #include <sys/types.h>
28 28 #include <sys/file.h>
29 29 #include <sys/errno.h>
30 30 #include <sys/open.h>
31 31 #include <sys/stat.h>
32 32 #include <sys/cred.h>
33 33 #include <sys/modctl.h>
34 34 #include <sys/conf.h>
35 35 #include <sys/devops.h>
36 36 #include <sys/ddi.h>
37 37 #include <sys/x86_archext.h>
38 38
39 39 #include <sys/amd_iommu.h>
40 40 #include "amd_iommu_impl.h"
41 41 #include "amd_iommu_acpi.h"
42 42
43 43
44 44 #define AMD_IOMMU_MINOR2INST(x) (x)
45 45 #define AMD_IOMMU_INST2MINOR(x) (x)
46 46 #define AMD_IOMMU_NODETYPE "ddi_iommu"
47 47 #define AMD_IOMMU_MINOR_NAME "amd-iommu"
48 48
49 49 static int amd_iommu_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
50 50 void **result);
51 51 static int amd_iommu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
52 52 static int amd_iommu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
53 53 static int amd_iommu_open(dev_t *devp, int flag, int otyp, cred_t *credp);
54 54 static int amd_iommu_close(dev_t dev, int flag, int otyp, cred_t *credp);
55 55 static int amd_iommu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
56 56 cred_t *credp, int *rvalp);
57 57 static int amd_iommu_quiesce(dev_info_t *dip);
58 58
59 59 static struct cb_ops amd_iommu_cb_ops = {
60 60 amd_iommu_open, /* cb_open */
61 61 amd_iommu_close, /* cb_close */
62 62 nodev, /* cb_strategy */
63 63 nodev, /* cb_print */
64 64 nodev, /* cb_dump */
65 65 nodev, /* cb_read */
66 66 nodev, /* cb_write */
67 67 amd_iommu_ioctl, /* cb_ioctl */
68 68 nodev, /* cb_devmap */
69 69 nodev, /* cb_mmap */
70 70 nodev, /* cb_segmap */
71 71 nochpoll, /* cb_chpoll */
72 72 ddi_prop_op, /* cb_prop_op */
73 73 NULL, /* cb_str */
74 74 D_NEW | D_MP, /* cb_flag */
75 75 CB_REV, /* cb_rev */
76 76 nodev, /* cb_aread */
77 77 nodev /* cb_awrite */
78 78 };
79 79
80 80 static struct dev_ops amd_iommu_dev_ops = {
81 81 DEVO_REV, /* devo_rev */
82 82 0, /* devo_refcnt */
83 83 amd_iommu_getinfo, /* devo_getinfo */
84 84 nulldev, /* devo_identify */
85 85 nulldev, /* devo_probe */
86 86 amd_iommu_attach, /* devo_attach */
87 87 amd_iommu_detach, /* devo_detach */
88 88 nodev, /* devo_reset */
89 89 &amd_iommu_cb_ops, /* devo_cb_ops */
90 90 NULL, /* devo_bus_ops */
91 91 nulldev, /* devo_power */
92 92 amd_iommu_quiesce, /* devo_quiesce */
↓ open down ↓ |
92 lines elided |
↑ open up ↑ |
93 93 };
94 94
95 95 static struct modldrv modldrv = {
96 96 &mod_driverops,
97 97 "AMD IOMMU 0.1",
98 98 &amd_iommu_dev_ops
99 99 };
100 100
101 101 static struct modlinkage modlinkage = {
102 102 MODREV_1,
103 - (void *)&modldrv,
104 - NULL
103 + { (void *)&modldrv, NULL }
105 104 };
106 105
107 106 amd_iommu_debug_t amd_iommu_debug;
108 107 kmutex_t amd_iommu_global_lock;
109 108 const char *amd_iommu_modname = "amd_iommu";
110 109 amd_iommu_alias_t **amd_iommu_alias;
111 110 amd_iommu_page_table_hash_t amd_iommu_page_table_hash;
112 111 static void *amd_iommu_statep;
113 112 int amd_iommu_64bit_bug;
114 113 int amd_iommu_unity_map;
115 114 int amd_iommu_no_RW_perms;
116 115 int amd_iommu_no_unmap;
117 116 int amd_iommu_pageva_inval_all;
118 117 int amd_iommu_disable; /* disable IOMMU */
119 118 char *amd_iommu_disable_list; /* list of drivers bypassing IOMMU */
120 119
121 120 int
122 121 _init(void)
123 122 {
124 123 int error = ENOTSUP;
125 124
126 125 #if defined(__amd64) && !defined(__xpv)
127 126
128 127 if (get_hwenv() != HW_NATIVE)
129 128 return (ENOTSUP);
130 129
131 130 error = ddi_soft_state_init(&amd_iommu_statep,
132 131 sizeof (struct amd_iommu_state), 1);
133 132 if (error) {
134 133 cmn_err(CE_WARN, "%s: _init: failed to init soft state.",
135 134 amd_iommu_modname);
136 135 return (error);
137 136 }
138 137
139 138 if (amd_iommu_acpi_init() != DDI_SUCCESS) {
140 139 if (amd_iommu_debug) {
141 140 cmn_err(CE_WARN, "%s: _init: ACPI init failed.",
142 141 amd_iommu_modname);
143 142 }
144 143 ddi_soft_state_fini(&amd_iommu_statep);
145 144 return (ENOTSUP);
146 145 }
147 146
148 147 amd_iommu_read_boot_props();
149 148
150 149 if (amd_iommu_page_table_hash_init(&amd_iommu_page_table_hash)
151 150 != DDI_SUCCESS) {
152 151 cmn_err(CE_WARN, "%s: _init: Page table hash init failed.",
153 152 amd_iommu_modname);
154 153 if (amd_iommu_disable_list) {
155 154 kmem_free(amd_iommu_disable_list,
156 155 strlen(amd_iommu_disable_list) + 1);
157 156 amd_iommu_disable_list = NULL;
158 157 }
159 158 amd_iommu_acpi_fini();
160 159 ddi_soft_state_fini(&amd_iommu_statep);
161 160 amd_iommu_statep = NULL;
162 161 return (EFAULT);
163 162 }
164 163
165 164 error = mod_install(&modlinkage);
166 165 if (error) {
167 166 cmn_err(CE_WARN, "%s: _init: mod_install failed.",
168 167 amd_iommu_modname);
169 168 amd_iommu_page_table_hash_fini(&amd_iommu_page_table_hash);
170 169 if (amd_iommu_disable_list) {
171 170 kmem_free(amd_iommu_disable_list,
172 171 strlen(amd_iommu_disable_list) + 1);
173 172 amd_iommu_disable_list = NULL;
174 173 }
175 174 amd_iommu_acpi_fini();
176 175 ddi_soft_state_fini(&amd_iommu_statep);
177 176 amd_iommu_statep = NULL;
178 177 return (error);
179 178 }
180 179 error = 0;
181 180 #endif
182 181
183 182 return (error);
184 183 }
185 184
186 185 int
187 186 _info(struct modinfo *modinfop)
188 187 {
189 188 return (mod_info(&modlinkage, modinfop));
190 189 }
191 190
192 191 int
193 192 _fini(void)
194 193 {
195 194 int error;
196 195
197 196 error = mod_remove(&modlinkage);
198 197 if (error)
199 198 return (error);
200 199
201 200 amd_iommu_page_table_hash_fini(&amd_iommu_page_table_hash);
202 201 if (amd_iommu_disable_list) {
203 202 kmem_free(amd_iommu_disable_list,
204 203 strlen(amd_iommu_disable_list) + 1);
205 204 amd_iommu_disable_list = NULL;
206 205 }
207 206 amd_iommu_acpi_fini();
208 207 ddi_soft_state_fini(&amd_iommu_statep);
209 208 amd_iommu_statep = NULL;
210 209
211 210 return (0);
212 211 }
213 212
214 213 /*ARGSUSED*/
215 214 static int
216 215 amd_iommu_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
217 216 {
218 217 struct amd_iommu_state *statep;
219 218
220 219 ASSERT(result);
221 220
222 221 *result = NULL;
223 222
224 223 switch (cmd) {
225 224 case DDI_INFO_DEVT2DEVINFO:
226 225 statep = ddi_get_soft_state(amd_iommu_statep,
227 226 AMD_IOMMU_MINOR2INST(getminor((dev_t)arg)));
228 227 if (statep) {
229 228 *result = statep->aioms_devi;
230 229 return (DDI_SUCCESS);
231 230 }
232 231 break;
233 232 case DDI_INFO_DEVT2INSTANCE:
234 233 *result = (void *)(uintptr_t)
235 234 AMD_IOMMU_MINOR2INST(getminor((dev_t)arg));
236 235 return (DDI_SUCCESS);
237 236 }
238 237
239 238 return (DDI_FAILURE);
240 239 }
241 240
242 241 static int
243 242 amd_iommu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
244 243 {
245 244 int instance = ddi_get_instance(dip);
246 245 const char *driver = ddi_driver_name(dip);
247 246 struct amd_iommu_state *statep;
248 247
249 248 ASSERT(instance >= 0);
250 249 ASSERT(driver);
251 250
252 251 switch (cmd) {
253 252 case DDI_ATTACH:
254 253 if (ddi_soft_state_zalloc(amd_iommu_statep, instance)
255 254 != DDI_SUCCESS) {
256 255 cmn_err(CE_WARN, "Unable to allocate soft state for "
257 256 "%s%d", driver, instance);
258 257 return (DDI_FAILURE);
259 258 }
260 259
261 260 statep = ddi_get_soft_state(amd_iommu_statep, instance);
262 261 if (statep == NULL) {
263 262 cmn_err(CE_WARN, "Unable to get soft state for "
264 263 "%s%d", driver, instance);
265 264 ddi_soft_state_free(amd_iommu_statep, instance);
266 265 return (DDI_FAILURE);
267 266 }
268 267
269 268 if (ddi_create_minor_node(dip, AMD_IOMMU_MINOR_NAME, S_IFCHR,
270 269 AMD_IOMMU_INST2MINOR(instance), AMD_IOMMU_NODETYPE,
271 270 0) != DDI_SUCCESS) {
272 271 cmn_err(CE_WARN, "Unable to create minor node for "
273 272 "%s%d", driver, instance);
274 273 ddi_remove_minor_node(dip, NULL);
275 274 ddi_soft_state_free(amd_iommu_statep, instance);
276 275 return (DDI_FAILURE);
277 276 }
278 277
279 278 statep->aioms_devi = dip;
280 279 statep->aioms_instance = instance;
281 280 statep->aioms_iommu_start = NULL;
282 281 statep->aioms_iommu_end = NULL;
283 282
284 283 amd_iommu_lookup_conf_props(dip);
285 284
286 285 if (amd_iommu_disable_list) {
287 286 cmn_err(CE_NOTE, "AMD IOMMU disabled for the following"
288 287 " drivers:\n%s", amd_iommu_disable_list);
289 288 }
290 289
291 290 if (amd_iommu_disable) {
292 291 cmn_err(CE_NOTE, "AMD IOMMU disabled by user");
293 292 } else if (amd_iommu_setup(dip, statep) != DDI_SUCCESS) {
294 293 cmn_err(CE_WARN, "Unable to initialize AMD IOMMU "
295 294 "%s%d", driver, instance);
296 295 ddi_remove_minor_node(dip, NULL);
297 296 ddi_soft_state_free(amd_iommu_statep, instance);
298 297 return (DDI_FAILURE);
299 298 }
300 299
301 300 ddi_report_dev(dip);
302 301
303 302 return (DDI_SUCCESS);
304 303
305 304 case DDI_RESUME:
306 305 return (DDI_SUCCESS);
307 306 default:
308 307 return (DDI_FAILURE);
309 308 }
310 309 }
311 310
312 311 static int
313 312 amd_iommu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
314 313 {
315 314 int instance = ddi_get_instance(dip);
316 315 const char *driver = ddi_driver_name(dip);
317 316 struct amd_iommu_state *statep;
318 317
319 318 ASSERT(instance >= 0);
320 319 ASSERT(driver);
321 320
322 321 switch (cmd) {
323 322 case DDI_DETACH:
324 323 statep = ddi_get_soft_state(amd_iommu_statep, instance);
325 324 if (statep == NULL) {
326 325 cmn_err(CE_WARN, "%s%d: Cannot get soft state",
327 326 driver, instance);
328 327 return (DDI_FAILURE);
329 328 }
330 329 return (DDI_FAILURE);
331 330 case DDI_SUSPEND:
332 331 return (DDI_SUCCESS);
333 332 default:
334 333 return (DDI_FAILURE);
335 334 }
336 335 }
337 336
338 337 /*ARGSUSED*/
339 338 static int
340 339 amd_iommu_open(dev_t *devp, int flag, int otyp, cred_t *credp)
341 340 {
342 341 int instance = AMD_IOMMU_MINOR2INST(getminor(*devp));
343 342 struct amd_iommu_state *statep;
344 343 const char *f = "amd_iommu_open";
345 344
346 345 if (instance < 0) {
347 346 cmn_err(CE_WARN, "%s: invalid instance %d",
348 347 f, instance);
349 348 return (ENXIO);
350 349 }
351 350
352 351 if (!(flag & (FREAD|FWRITE))) {
353 352 cmn_err(CE_WARN, "%s: invalid flags %d", f, flag);
354 353 return (EINVAL);
355 354 }
356 355
357 356 if (otyp != OTYP_CHR) {
358 357 cmn_err(CE_WARN, "%s: invalid otyp %d", f, otyp);
359 358 return (EINVAL);
360 359 }
361 360
362 361 statep = ddi_get_soft_state(amd_iommu_statep, instance);
363 362 if (statep == NULL) {
364 363 cmn_err(CE_WARN, "%s: cannot get soft state: instance %d",
365 364 f, instance);
366 365 return (ENXIO);
367 366 }
368 367
369 368 ASSERT(statep->aioms_instance == instance);
370 369
371 370 return (0);
372 371 }
373 372
374 373 /*ARGSUSED*/
375 374 static int
376 375 amd_iommu_close(dev_t dev, int flag, int otyp, cred_t *credp)
377 376 {
378 377 int instance = AMD_IOMMU_MINOR2INST(getminor(dev));
379 378 struct amd_iommu_state *statep;
380 379 const char *f = "amd_iommu_close";
381 380
382 381 if (instance < 0) {
383 382 cmn_err(CE_WARN, "%s: invalid instance %d", f, instance);
384 383 return (ENXIO);
385 384 }
386 385
387 386 if (!(flag & (FREAD|FWRITE))) {
388 387 cmn_err(CE_WARN, "%s: invalid flags %d", f, flag);
389 388 return (EINVAL);
390 389 }
391 390
392 391 if (otyp != OTYP_CHR) {
393 392 cmn_err(CE_WARN, "%s: invalid otyp %d", f, otyp);
394 393 return (EINVAL);
395 394 }
396 395
397 396 statep = ddi_get_soft_state(amd_iommu_statep, instance);
398 397 if (statep == NULL) {
399 398 cmn_err(CE_WARN, "%s: cannot get soft state: instance %d",
400 399 f, instance);
401 400 return (ENXIO);
402 401 }
403 402
404 403 ASSERT(statep->aioms_instance == instance);
405 404 return (0);
406 405
407 406 }
408 407
409 408 /*ARGSUSED*/
410 409 static int
411 410 amd_iommu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
412 411 int *rvalp)
413 412 {
414 413 int instance = AMD_IOMMU_MINOR2INST(getminor(dev));
415 414 struct amd_iommu_state *statep;
416 415 const char *f = "amd_iommu_ioctl";
417 416
418 417 ASSERT(*rvalp);
419 418
420 419 if (instance < 0) {
421 420 cmn_err(CE_WARN, "%s: invalid instance %d", f, instance);
422 421 return (ENXIO);
423 422 }
424 423
425 424
426 425 if (!(mode & (FREAD|FWRITE))) {
427 426 cmn_err(CE_WARN, "%s: invalid mode %d", f, mode);
428 427 return (EINVAL);
429 428 }
430 429
431 430 if (mode & FKIOCTL) {
432 431 cmn_err(CE_WARN, "%s: FKIOCTL unsupported mode %d", f, mode);
433 432 return (EINVAL);
434 433 }
435 434
436 435 statep = ddi_get_soft_state(amd_iommu_statep, instance);
437 436 if (statep == NULL) {
438 437 cmn_err(CE_WARN, "%s: cannot get soft state: instance %d",
439 438 f, instance);
440 439 return (ENXIO);
441 440 }
442 441
443 442 ASSERT(statep->aioms_instance == instance);
444 443
445 444 return (ENOTTY);
446 445 }
447 446
448 447 static int
449 448 amd_iommu_quiesce(dev_info_t *dip)
450 449 {
451 450 int instance = ddi_get_instance(dip);
452 451 struct amd_iommu_state *statep;
453 452 const char *f = "amd_iommu_quiesce";
454 453
455 454 statep = ddi_get_soft_state(amd_iommu_statep, instance);
456 455 if (statep == NULL) {
457 456 cmn_err(CE_WARN, "%s: cannot get soft state: instance %d",
458 457 f, instance);
459 458 return (DDI_FAILURE);
460 459 }
461 460
462 461 if (amd_iommu_teardown(dip, statep, AMD_IOMMU_QUIESCE) != DDI_SUCCESS) {
463 462 cmn_err(CE_WARN, "%s: Unable to quiesce AMD IOMMU "
464 463 "%s%d", f, ddi_driver_name(dip), instance);
465 464 return (DDI_FAILURE);
466 465 }
467 466
468 467 return (DDI_SUCCESS);
469 468 }
↓ open down ↓ |
355 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX