1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 1998 Michael Smith 5 * All rights reserved. 6 * Copyright (c) 2020 NetApp Inc. 7 * Copyright (c) 2020 Klara Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/linker.h> 34 #include <sys/sbuf.h> 35 #include <sys/sysctl.h> 36 37 #include <machine/metadata.h> 38 39 #include <vm/vm.h> 40 #include <vm/vm_extern.h> 41 42 /* 43 * Preloaded module support 44 */ 45 46 vm_offset_t preload_addr_relocate = 0; 47 caddr_t preload_metadata, preload_kmdp; 48 49 const char preload_modtype[] = MODTYPE; 50 const char preload_kerntype[] = KERNTYPE; 51 const char preload_modtype_obj[] = MODTYPE_OBJ; 52 53 void 54 preload_initkmdp(bool fatal) 55 { 56 preload_kmdp = preload_search_by_type(preload_kerntype); 57 58 if (preload_kmdp == NULL && fatal) 59 panic("unable to find kernel metadata"); 60 } 61 62 /* 63 * Search for the preloaded module (name) 64 */ 65 caddr_t 66 preload_search_by_name(const char *name) 67 { 68 caddr_t curp; 69 uint32_t *hdr; 70 int next; 71 72 if (preload_metadata != NULL) { 73 curp = preload_metadata; 74 for (;;) { 75 hdr = (uint32_t *)curp; 76 if (hdr[0] == 0 && hdr[1] == 0) 77 break; 78 79 /* Search for a MODINFO_NAME field */ 80 if ((hdr[0] == MODINFO_NAME) && 81 !strcmp(name, curp + sizeof(uint32_t) * 2)) 82 return(curp); 83 84 /* skip to next field */ 85 next = sizeof(uint32_t) * 2 + hdr[1]; 86 next = roundup(next, sizeof(u_long)); 87 curp += next; 88 } 89 } 90 return(NULL); 91 } 92 93 /* 94 * Search for the first preloaded module of (type) 95 */ 96 caddr_t 97 preload_search_by_type(const char *type) 98 { 99 caddr_t curp, lname; 100 uint32_t *hdr; 101 int next; 102 103 if (preload_metadata != NULL) { 104 curp = preload_metadata; 105 lname = NULL; 106 for (;;) { 107 hdr = (uint32_t *)curp; 108 if (hdr[0] == 0 && hdr[1] == 0) 109 break; 110 111 /* remember the start of each record */ 112 if (hdr[0] == MODINFO_NAME) 113 lname = curp; 114 115 /* Search for a MODINFO_TYPE field */ 116 if ((hdr[0] == MODINFO_TYPE) && 117 !strcmp(type, curp + sizeof(uint32_t) * 2)) 118 return(lname); 119 120 /* skip to next field */ 121 next = sizeof(uint32_t) * 2 + hdr[1]; 122 next = roundup(next, sizeof(u_long)); 123 curp += next; 124 } 125 } 126 return(NULL); 127 } 128 129 /* 130 * Walk through the preloaded module list 131 */ 132 caddr_t 133 preload_search_next_name(caddr_t base) 134 { 135 caddr_t curp; 136 uint32_t *hdr; 137 int next; 138 139 if (preload_metadata != NULL) { 140 /* Pick up where we left off last time */ 141 if (base) { 142 /* skip to next field */ 143 curp = base; 144 hdr = (uint32_t *)curp; 145 next = sizeof(uint32_t) * 2 + hdr[1]; 146 next = roundup(next, sizeof(u_long)); 147 curp += next; 148 } else 149 curp = preload_metadata; 150 151 for (;;) { 152 hdr = (uint32_t *)curp; 153 if (hdr[0] == 0 && hdr[1] == 0) 154 break; 155 156 /* Found a new record? */ 157 if (hdr[0] == MODINFO_NAME) 158 return curp; 159 160 /* skip to next field */ 161 next = sizeof(uint32_t) * 2 + hdr[1]; 162 next = roundup(next, sizeof(u_long)); 163 curp += next; 164 } 165 } 166 return(NULL); 167 } 168 169 /* 170 * Given a preloaded module handle (mod), return a pointer 171 * to the data for the attribute (inf). 172 */ 173 caddr_t 174 preload_search_info(caddr_t mod, int inf) 175 { 176 caddr_t curp; 177 uint32_t *hdr; 178 uint32_t type = 0; 179 int next; 180 181 if (mod == NULL) 182 return (NULL); 183 184 curp = mod; 185 for (;;) { 186 hdr = (uint32_t *)curp; 187 /* end of module data? */ 188 if (hdr[0] == 0 && hdr[1] == 0) 189 break; 190 /* 191 * We give up once we've looped back to what we were looking at 192 * first - this should normally be a MODINFO_NAME field. 193 */ 194 if (type == 0) { 195 type = hdr[0]; 196 } else { 197 if (hdr[0] == type) 198 break; 199 } 200 201 /* 202 * Attribute match? Return pointer to data. 203 * Consumer may safely assume that size value precedes 204 * data. 205 */ 206 if (hdr[0] == inf) 207 return(curp + (sizeof(uint32_t) * 2)); 208 209 /* skip to next field */ 210 next = sizeof(uint32_t) * 2 + hdr[1]; 211 next = roundup(next, sizeof(u_long)); 212 curp += next; 213 } 214 return(NULL); 215 } 216 217 /* 218 * Delete a preload record by name. 219 */ 220 void 221 preload_delete_name(const char *name) 222 { 223 caddr_t addr, curp; 224 uint32_t *hdr, sz; 225 int next; 226 int clearing; 227 228 addr = 0; 229 sz = 0; 230 231 if (preload_metadata != NULL) { 232 clearing = 0; 233 curp = preload_metadata; 234 for (;;) { 235 hdr = (uint32_t *)curp; 236 if (hdr[0] == MODINFO_NAME || (hdr[0] == 0 && hdr[1] == 0)) { 237 /* Free memory used to store the file. */ 238 if (addr != 0 && sz != 0) 239 kmem_bootstrap_free((vm_offset_t)addr, sz); 240 addr = 0; 241 sz = 0; 242 243 if (hdr[0] == 0) 244 break; 245 if (!strcmp(name, curp + sizeof(uint32_t) * 2)) 246 clearing = 1; /* got it, start clearing */ 247 else if (clearing) { 248 clearing = 0; /* at next one now.. better stop */ 249 } 250 } 251 if (clearing) { 252 if (hdr[0] == MODINFO_ADDR) 253 addr = *(caddr_t *)(curp + sizeof(uint32_t) * 2); 254 else if (hdr[0] == MODINFO_SIZE) 255 sz = *(uint32_t *)(curp + sizeof(uint32_t) * 2); 256 hdr[0] = MODINFO_EMPTY; 257 } 258 259 /* skip to next field */ 260 next = sizeof(uint32_t) * 2 + hdr[1]; 261 next = roundup(next, sizeof(u_long)); 262 curp += next; 263 } 264 } 265 } 266 267 void * 268 preload_fetch_addr(caddr_t mod) 269 { 270 caddr_t *mdp; 271 272 mdp = (caddr_t *)preload_search_info(mod, MODINFO_ADDR); 273 if (mdp == NULL) 274 return (NULL); 275 return (*mdp + preload_addr_relocate); 276 } 277 278 size_t 279 preload_fetch_size(caddr_t mod) 280 { 281 size_t *mdp; 282 283 mdp = (size_t *)preload_search_info(mod, MODINFO_SIZE); 284 if (mdp == NULL) 285 return (0); 286 return (*mdp); 287 } 288 289 /* Called from locore. Convert physical pointers to kvm. Sigh. */ 290 void 291 preload_bootstrap_relocate(vm_offset_t offset) 292 { 293 caddr_t curp; 294 uint32_t *hdr; 295 vm_offset_t *ptr; 296 int next; 297 298 if (preload_metadata != NULL) { 299 curp = preload_metadata; 300 for (;;) { 301 hdr = (uint32_t *)curp; 302 if (hdr[0] == 0 && hdr[1] == 0) 303 break; 304 305 /* Deal with the ones that we know we have to fix */ 306 switch (hdr[0]) { 307 case MODINFO_ADDR: 308 case MODINFO_METADATA|MODINFOMD_FONT: 309 case MODINFO_METADATA|MODINFOMD_SPLASH: 310 case MODINFO_METADATA|MODINFOMD_SHTDWNSPLASH: 311 case MODINFO_METADATA|MODINFOMD_SSYM: 312 case MODINFO_METADATA|MODINFOMD_ESYM: 313 ptr = (vm_offset_t *)(curp + (sizeof(uint32_t) * 2)); 314 *ptr += offset; 315 break; 316 } 317 /* The rest is beyond us for now */ 318 319 /* skip to next field */ 320 next = sizeof(uint32_t) * 2 + hdr[1]; 321 next = roundup(next, sizeof(u_long)); 322 curp += next; 323 } 324 } 325 } 326 327 /* 328 * Parse the modinfo type and append to the provided sbuf. 329 */ 330 static void 331 preload_modinfo_type(struct sbuf *sbp, int type) 332 { 333 334 if ((type & MODINFO_METADATA) == 0) { 335 switch (type) { 336 case MODINFO_END: 337 sbuf_cat(sbp, "MODINFO_END"); 338 break; 339 case MODINFO_NAME: 340 sbuf_cat(sbp, "MODINFO_NAME"); 341 break; 342 case MODINFO_TYPE: 343 sbuf_cat(sbp, "MODINFO_TYPE"); 344 break; 345 case MODINFO_ADDR: 346 sbuf_cat(sbp, "MODINFO_ADDR"); 347 break; 348 case MODINFO_SIZE: 349 sbuf_cat(sbp, "MODINFO_SIZE"); 350 break; 351 case MODINFO_EMPTY: 352 sbuf_cat(sbp, "MODINFO_EMPTY"); 353 break; 354 case MODINFO_ARGS: 355 sbuf_cat(sbp, "MODINFO_ARGS"); 356 break; 357 default: 358 sbuf_cat(sbp, "unrecognized modinfo attribute"); 359 } 360 361 return; 362 } 363 364 sbuf_cat(sbp, "MODINFO_METADATA | "); 365 switch (type & ~MODINFO_METADATA) { 366 case MODINFOMD_ELFHDR: 367 sbuf_cat(sbp, "MODINFOMD_ELFHDR"); 368 break; 369 case MODINFOMD_SSYM: 370 sbuf_cat(sbp, "MODINFOMD_SSYM"); 371 break; 372 case MODINFOMD_ESYM: 373 sbuf_cat(sbp, "MODINFOMD_ESYM"); 374 break; 375 case MODINFOMD_DYNAMIC: 376 sbuf_cat(sbp, "MODINFOMD_DYNAMIC"); 377 break; 378 case MODINFOMD_ENVP: 379 sbuf_cat(sbp, "MODINFOMD_ENVP"); 380 break; 381 case MODINFOMD_HOWTO: 382 sbuf_cat(sbp, "MODINFOMD_HOWTO"); 383 break; 384 case MODINFOMD_KERNEND: 385 sbuf_cat(sbp, "MODINFOMD_KERNEND"); 386 break; 387 case MODINFOMD_SHDR: 388 sbuf_cat(sbp, "MODINFOMD_SHDR"); 389 break; 390 case MODINFOMD_CTORS_ADDR: 391 sbuf_cat(sbp, "MODINFOMD_CTORS_ADDR"); 392 break; 393 case MODINFOMD_CTORS_SIZE: 394 sbuf_cat(sbp, "MODINFOMD_CTORS_SIZE"); 395 break; 396 case MODINFOMD_FW_HANDLE: 397 sbuf_cat(sbp, "MODINFOMD_FW_HANDLE"); 398 break; 399 case MODINFOMD_KEYBUF: 400 sbuf_cat(sbp, "MODINFOMD_KEYBUF"); 401 break; 402 #ifdef MODINFOMD_SMAP 403 case MODINFOMD_SMAP: 404 sbuf_cat(sbp, "MODINFOMD_SMAP"); 405 break; 406 #endif 407 #ifdef MODINFOMD_SMAP_XATTR 408 case MODINFOMD_SMAP_XATTR: 409 sbuf_cat(sbp, "MODINFOMD_SMAP_XATTR"); 410 break; 411 #endif 412 #ifdef MODINFOMD_DTBP 413 case MODINFOMD_DTBP: 414 sbuf_cat(sbp, "MODINFOMD_DTBP"); 415 break; 416 #endif 417 #ifdef MODINFOMD_EFI_MAP 418 case MODINFOMD_EFI_MAP: 419 sbuf_cat(sbp, "MODINFOMD_EFI_MAP"); 420 break; 421 #endif 422 #ifdef MODINFOMD_EFI_FB 423 case MODINFOMD_EFI_FB: 424 sbuf_cat(sbp, "MODINFOMD_EFI_FB"); 425 break; 426 #endif 427 #ifdef MODINFOMD_MODULEP 428 case MODINFOMD_MODULEP: 429 sbuf_cat(sbp, "MODINFOMD_MODULEP"); 430 break; 431 #endif 432 #ifdef MODINFOMD_VBE_FB 433 case MODINFOMD_VBE_FB: 434 sbuf_cat(sbp, "MODINFOMD_VBE_FB"); 435 break; 436 #endif 437 case MODINFOMD_FONT: 438 sbuf_cat(sbp, "MODINFOMD_FONT"); 439 break; 440 case MODINFOMD_SPLASH: 441 sbuf_cat(sbp, "MODINFOMD_SPLASH"); 442 break; 443 case MODINFOMD_SHTDWNSPLASH: 444 sbuf_cat(sbp, "MODINFOMD_SHTDWNSPLASH"); 445 break; 446 #ifdef MODINFOMD_BOOT_HARTID 447 case MODINFOMD_BOOT_HARTID: 448 sbuf_cat(sbp, "MODINFOMD_BOOT_HARTID"); 449 break; 450 #endif 451 #ifdef MODINFOMD_EFI_ARCH 452 case MODINFOMD_EFI_ARCH: 453 sbuf_cat(sbp, "MODINFOMD_EFI_ARCH"); 454 break; 455 #endif 456 default: 457 sbuf_cat(sbp, "unrecognized metadata type"); 458 } 459 } 460 461 /* 462 * Print the modinfo value, depending on type. 463 */ 464 static void 465 preload_modinfo_value(struct sbuf *sbp, uint32_t *bptr, int type, int len) 466 { 467 #ifdef __LP64__ 468 #define sbuf_print_vmoffset(sb, o) sbuf_printf(sb, "0x%016lx", o); 469 #else 470 #define sbuf_print_vmoffset(sb, o) sbuf_printf(sb, "0x%08x", o); 471 #endif 472 473 switch (type) { 474 case MODINFO_NAME: 475 case MODINFO_TYPE: 476 case MODINFO_ARGS: 477 #ifdef MODINFOMD_EFI_ARCH 478 case MODINFO_METADATA | MODINFOMD_EFI_ARCH: 479 #endif 480 sbuf_printf(sbp, "%s", (char *)bptr); 481 break; 482 case MODINFO_SIZE: 483 case MODINFO_METADATA | MODINFOMD_CTORS_SIZE: 484 sbuf_printf(sbp, "%lu", *(u_long *)bptr); 485 break; 486 case MODINFO_ADDR: 487 case MODINFO_METADATA | MODINFOMD_SSYM: 488 case MODINFO_METADATA | MODINFOMD_ESYM: 489 case MODINFO_METADATA | MODINFOMD_DYNAMIC: 490 case MODINFO_METADATA | MODINFOMD_KERNEND: 491 case MODINFO_METADATA | MODINFOMD_ENVP: 492 case MODINFO_METADATA | MODINFOMD_CTORS_ADDR: 493 #ifdef MODINFOMD_SMAP 494 case MODINFO_METADATA | MODINFOMD_SMAP: 495 #endif 496 #ifdef MODINFOMD_SMAP_XATTR 497 case MODINFO_METADATA | MODINFOMD_SMAP_XATTR: 498 #endif 499 #ifdef MODINFOMD_DTBP 500 case MODINFO_METADATA | MODINFOMD_DTBP: 501 #endif 502 #ifdef MODINFOMD_EFI_FB 503 case MODINFO_METADATA | MODINFOMD_EFI_FB: 504 #endif 505 #ifdef MODINFOMD_VBE_FB 506 case MODINFO_METADATA | MODINFOMD_VBE_FB: 507 #endif 508 case MODINFO_METADATA | MODINFOMD_FONT: 509 case MODINFO_METADATA | MODINFOMD_SPLASH: 510 case MODINFO_METADATA | MODINFOMD_SHTDWNSPLASH: 511 sbuf_print_vmoffset(sbp, *(vm_offset_t *)bptr); 512 break; 513 case MODINFO_METADATA | MODINFOMD_HOWTO: 514 sbuf_printf(sbp, "0x%08x", *bptr); 515 break; 516 #ifdef MODINFOMD_BOOT_HARTID 517 case MODINFO_METADATA | MODINFOMD_BOOT_HARTID: 518 sbuf_printf(sbp, "0x%lu", *(uint64_t *)bptr); 519 break; 520 #endif 521 case MODINFO_METADATA | MODINFOMD_SHDR: 522 case MODINFO_METADATA | MODINFOMD_ELFHDR: 523 case MODINFO_METADATA | MODINFOMD_FW_HANDLE: 524 case MODINFO_METADATA | MODINFOMD_KEYBUF: 525 #ifdef MODINFOMD_EFI_MAP 526 case MODINFO_METADATA | MODINFOMD_EFI_MAP: 527 #endif 528 /* Don't print data buffers. */ 529 sbuf_cat(sbp, "buffer contents omitted"); 530 break; 531 default: 532 break; 533 } 534 #undef sbuf_print_vmoffset 535 } 536 537 static void 538 preload_dump_internal(struct sbuf *sbp) 539 { 540 uint32_t *bptr, type, len; 541 542 KASSERT(preload_metadata != NULL, 543 ("%s called without setting up preload_metadata", __func__)); 544 545 /* 546 * Iterate through the TLV-encoded sections. 547 */ 548 bptr = (uint32_t *)preload_metadata; 549 sbuf_putc(sbp, '\n'); 550 while (bptr[0] != MODINFO_END || bptr[1] != MODINFO_END) { 551 sbuf_printf(sbp, " %p:\n", bptr); 552 type = *bptr++; 553 len = *bptr++; 554 555 sbuf_printf(sbp, "\ttype:\t(%#04x) ", type); 556 preload_modinfo_type(sbp, type); 557 sbuf_putc(sbp, '\n'); 558 sbuf_printf(sbp, "\tlen:\t%u\n", len); 559 sbuf_cat(sbp, "\tvalue:\t"); 560 preload_modinfo_value(sbp, bptr, type, len); 561 sbuf_putc(sbp, '\n'); 562 563 bptr += roundup(len, sizeof(u_long)) / sizeof(uint32_t); 564 } 565 } 566 567 /* 568 * Print the preloaded data to the console. Called from the machine-dependent 569 * initialization routines, e.g. hammer_time(). 570 */ 571 void 572 preload_dump(void) 573 { 574 char buf[512]; 575 struct sbuf sb; 576 577 /* 578 * This function is expected to be called before malloc is available, 579 * so use a static buffer and struct sbuf. 580 */ 581 sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN); 582 sbuf_set_drain(&sb, sbuf_printf_drain, NULL); 583 preload_dump_internal(&sb); 584 585 sbuf_finish(&sb); 586 sbuf_delete(&sb); 587 } 588 589 static int 590 sysctl_preload_dump(SYSCTL_HANDLER_ARGS) 591 { 592 struct sbuf sb; 593 int error; 594 595 if (preload_metadata == NULL) 596 return (EINVAL); 597 598 sbuf_new_for_sysctl(&sb, NULL, 512, req); 599 preload_dump_internal(&sb); 600 601 error = sbuf_finish(&sb); 602 sbuf_delete(&sb); 603 604 return (error); 605 } 606 SYSCTL_PROC(_debug, OID_AUTO, dump_modinfo, 607 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 608 NULL, 0, sysctl_preload_dump, "A", 609 "pretty-print the bootloader metadata"); 610