1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * This file contains the functions for performing Fast Reboot -- a 29 * reboot which bypasses the firmware and bootloader, considerably 30 * reducing downtime. 31 * 32 * load_kernel(): This function is invoked by mdpreboot() in the reboot 33 * path. It loads the new kernel and boot archive into memory, builds 34 * the data structure containing sufficient information about the new 35 * kernel and boot archive to be passed to the fast reboot switcher 36 * (see fb_swtch_src.s for details). When invoked the switcher relocates 37 * the new kernel and boot archive to physically contiguous low memory, 38 * similar to where the boot loader would have loaded them, and jumps to 39 * the new kernel. 40 * 41 * The physical addresses of the memory allocated for the new kernel, boot 42 * archive and their page tables must be above where the boot archive ends 43 * after it has been relocated by the switcher, otherwise the new files 44 * and their page tables could be overridden during relocation. 45 * 46 * fast_reboot(): This function is invoked by mdboot() once it's determined 47 * that the system is capable of fast reboot. It jumps to the fast reboot 48 * switcher with the data structure built by load_kernel() as the argument. 49 */ 50 51 #include <sys/types.h> 52 #include <sys/param.h> 53 #include <sys/segments.h> 54 #include <sys/sysmacros.h> 55 #include <sys/vm.h> 56 57 #include <sys/proc.h> 58 #include <sys/buf.h> 59 #include <sys/kmem.h> 60 61 #include <sys/reboot.h> 62 #include <sys/uadmin.h> 63 64 #include <sys/cred.h> 65 #include <sys/vnode.h> 66 #include <sys/file.h> 67 68 #include <sys/cmn_err.h> 69 #include <sys/dumphdr.h> 70 #include <sys/bootconf.h> 71 #include <sys/ddidmareq.h> 72 #include <sys/varargs.h> 73 #include <sys/promif.h> 74 #include <sys/modctl.h> 75 76 #include <vm/hat.h> 77 #include <vm/as.h> 78 #include <vm/page.h> 79 #include <vm/seg.h> 80 #include <vm/hat_i86.h> 81 #include <sys/vm_machparam.h> 82 #include <sys/archsystm.h> 83 #include <sys/machsystm.h> 84 #include <sys/mman.h> 85 #include <sys/x86_archext.h> 86 87 #include <sys/fastboot.h> 88 #include <sys/machelf.h> 89 #include <sys/kobj.h> 90 #include <sys/multiboot.h> 91 92 /* 93 * Data structure containing necessary information for the fast reboot 94 * switcher to jump to the new kernel. 95 */ 96 fastboot_info_t newkernel = { 0 }; 97 98 static char fastboot_filename[2][OBP_MAXPATHLEN] = { { 0 }, { 0 }}; 99 static x86pte_t ptp_bits = PT_VALID | PT_REF | PT_USER | PT_WRITABLE; 100 static x86pte_t pte_bits = 101 PT_VALID | PT_REF | PT_MOD | PT_NOCONSIST | PT_WRITABLE; 102 static uint_t fastboot_shift_amt_pae[] = {12, 21, 30, 39}; 103 104 int fastboot_debug = 0; 105 int fastboot_contig = 0; 106 107 /* 108 * Fake starting va for new kernel and boot archive. 109 */ 110 static uintptr_t fake_va = FASTBOOT_FAKE_VA; 111 112 /* 113 * Below 1G for page tables as we are using 2G as the fake virtual address for 114 * the new kernel and boot archive. 115 */ 116 static ddi_dma_attr_t fastboot_below_1G_dma_attr = { 117 DMA_ATTR_V0, 118 0x0000000008000000ULL, /* dma_attr_addr_lo: 128MB */ 119 0x000000003FFFFFFFULL, /* dma_attr_addr_hi: 1G */ 120 0x00000000FFFFFFFFULL, /* dma_attr_count_max */ 121 0x0000000000001000ULL, /* dma_attr_align: 4KB */ 122 1, /* dma_attr_burstsize */ 123 1, /* dma_attr_minxfer */ 124 0x00000000FFFFFFFFULL, /* dma_attr_maxxfer */ 125 0x00000000FFFFFFFFULL, /* dma_attr_seg */ 126 1, /* dma_attr_sgllen */ 127 0x1000ULL, /* dma_attr_granular */ 128 0, /* dma_attr_flags */ 129 }; 130 131 static ddi_dma_attr_t fastboot_dma_attr = { 132 DMA_ATTR_V0, 133 0x0000000008000000ULL, /* dma_attr_addr_lo: 128MB */ 134 #ifdef __amd64 135 0xFFFFFFFFFFFFFFFFULL, /* dma_attr_addr_hi: 2^64B */ 136 #else 137 0x0000000FFFFFFFFFULL, /* dma_attr_addr_hi: 64GB */ 138 #endif /* __amd64 */ 139 0x00000000FFFFFFFFULL, /* dma_attr_count_max */ 140 0x0000000000001000ULL, /* dma_attr_align: 4KB */ 141 1, /* dma_attr_burstsize */ 142 1, /* dma_attr_minxfer */ 143 0x00000000FFFFFFFFULL, /* dma_attr_maxxfer */ 144 0x00000000FFFFFFFFULL, /* dma_attr_seg */ 145 1, /* dma_attr_sgllen */ 146 0x1000ULL, /* dma_attr_granular */ 147 0, /* dma_attr_flags */ 148 }; 149 150 /* 151 * Various information saved from the previous boot to reconstruct 152 * multiboot_info. 153 */ 154 extern multiboot_info_t saved_mbi; 155 extern mb_memory_map_t saved_mmap[FASTBOOT_SAVED_MMAP_COUNT]; 156 extern struct sol_netinfo saved_drives[FASTBOOT_SAVED_DRIVES_COUNT]; 157 extern char saved_cmdline[FASTBOOT_SAVED_CMDLINE_LEN]; 158 extern int saved_cmdline_len; 159 160 extern void* contig_alloc(size_t size, ddi_dma_attr_t *attr, 161 uintptr_t align, int cansleep); 162 extern void contig_free(void *addr, size_t size); 163 164 165 /* PRINTLIKE */ 166 extern void vprintf(const char *, va_list); 167 168 169 /* 170 * Need to be able to get boot_archives from other places 171 */ 172 #define BOOTARCHIVE64 "/platform/i86pc/amd64/boot_archive" 173 #define BOOTARCHIVE32 "/platform/i86pc/boot_archive" 174 #define BOOTARCHIVE_FAILSAFE "/boot/x86.miniroot-safe" 175 #define FAILSAFE_BOOTFILE "/boot/platform/i86pc/kernel/unix" 176 177 static uint_t fastboot_vatoindex(fastboot_info_t *, uintptr_t, int); 178 static void fastboot_map_with_size(fastboot_info_t *, uintptr_t, 179 paddr_t, size_t, int); 180 static void fastboot_build_pagetables(fastboot_info_t *); 181 static int fastboot_build_mbi(char *, fastboot_info_t *); 182 183 static const char fastboot_enomem_msg[] = "Fastboot: Couldn't allocate 0x%" 184 PRIx64" bytes below %s to do fast reboot"; 185 186 static void 187 dprintf(char *fmt, ...) 188 { 189 va_list adx; 190 191 if (!fastboot_debug) 192 return; 193 194 va_start(adx, fmt); 195 vprintf(fmt, adx); 196 va_end(adx); 197 } 198 199 200 /* 201 * Return the index corresponding to a virt address at a given page table level. 202 */ 203 static uint_t 204 fastboot_vatoindex(fastboot_info_t *nk, uintptr_t va, int level) 205 { 206 return ((va >> nk->fi_shift_amt[level]) & (nk->fi_ptes_per_table - 1)); 207 } 208 209 210 /* 211 * Add mapping from vstart to pstart for the specified size. 212 * vstart, pstart and size should all have been aligned at 2M boundaries. 213 */ 214 static void 215 fastboot_map_with_size(fastboot_info_t *nk, uintptr_t vstart, paddr_t pstart, 216 size_t size, int level) 217 { 218 x86pte_t pteval, *table; 219 uintptr_t vaddr; 220 paddr_t paddr; 221 int index, l; 222 223 table = (x86pte_t *)(nk->fi_pagetable_va); 224 225 for (l = nk->fi_top_level; l >= level; l--) { 226 227 index = fastboot_vatoindex(nk, vstart, l); 228 229 if (l == level) { 230 /* 231 * Last level. Program the page table entries. 232 */ 233 for (vaddr = vstart, paddr = pstart; 234 vaddr < vstart + size; 235 vaddr += (1ULL << nk->fi_shift_amt[l]), 236 paddr += (1ULL << nk->fi_shift_amt[l])) { 237 238 uint_t index = fastboot_vatoindex(nk, vaddr, l); 239 240 if (l > 0) 241 pteval = paddr | pte_bits | PT_PAGESIZE; 242 else 243 pteval = paddr | pte_bits; 244 245 table[index] = pteval; 246 } 247 } else if (table[index] & PT_VALID) { 248 249 table = (x86pte_t *) 250 ((uintptr_t)(((paddr_t)table[index] & MMU_PAGEMASK) 251 - nk->fi_pagetable_pa) + nk->fi_pagetable_va); 252 } else { 253 /* 254 * Intermediate levels. 255 * Program with either valid bit or PTP bits. 256 */ 257 if (l == nk->fi_top_level) { 258 #ifdef __amd64 259 ASSERT(nk->fi_top_level == 3); 260 table[index] = nk->fi_next_table_pa | ptp_bits; 261 #else 262 table[index] = nk->fi_next_table_pa | PT_VALID; 263 #endif /* __amd64 */ 264 } else { 265 table[index] = nk->fi_next_table_pa | ptp_bits; 266 } 267 table = (x86pte_t *)(nk->fi_next_table_va); 268 nk->fi_next_table_va += MMU_PAGESIZE; 269 nk->fi_next_table_pa += MMU_PAGESIZE; 270 } 271 } 272 } 273 274 /* 275 * Build page tables for the lower 1G of physical memory using 2M 276 * pages, and prepare page tables for mapping new kernel and boot 277 * archive pages using 4K pages. 278 */ 279 static void 280 fastboot_build_pagetables(fastboot_info_t *nk) 281 { 282 /* 283 * Map lower 1G physical memory. Use large pages. 284 */ 285 fastboot_map_with_size(nk, 0, 0, ONE_GIG, 1); 286 287 /* 288 * Map one 4K page to get the middle page tables set up. 289 */ 290 fake_va = P2ALIGN_TYPED(fake_va, nk->fi_lpagesize, uintptr_t); 291 fastboot_map_with_size(nk, fake_va, 292 nk->fi_files[0].fb_pte_list_va[0] & MMU_PAGEMASK, PAGESIZE, 0); 293 } 294 295 296 /* 297 * Sanity check. Look for dboot offset. 298 */ 299 static int 300 fastboot_elf64_find_dboot_load_offset(void *img, off_t imgsz, uint32_t *offp) 301 { 302 Elf64_Ehdr *ehdr = (Elf64_Ehdr *)img; 303 Elf64_Phdr *phdr; 304 uint8_t *phdrbase; 305 int i; 306 307 if ((ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize) >= imgsz) 308 return (-1); 309 310 phdrbase = (uint8_t *)img + ehdr->e_phoff; 311 312 for (i = 0; i < ehdr->e_phnum; i++) { 313 phdr = (Elf64_Phdr *)(phdrbase + ehdr->e_phentsize * i); 314 315 if (phdr->p_type == PT_LOAD) { 316 if (phdr->p_vaddr == phdr->p_paddr && 317 phdr->p_vaddr == DBOOT_ENTRY_ADDRESS) { 318 ASSERT(phdr->p_offset <= UINT32_MAX); 319 *offp = (uint32_t)phdr->p_offset; 320 return (0); 321 } 322 } 323 } 324 325 return (-1); 326 } 327 328 329 /* 330 * Initialize text and data section information for 32-bit kernel. 331 * sectcntp - is both input/output parameter. 332 * On entry, *sectcntp contains maximum allowable number of sections; 333 * on return, it contains the actual number of sections filled. 334 */ 335 static int 336 fastboot_elf32_find_loadables(void *img, off_t imgsz, fastboot_section_t *sectp, 337 int *sectcntp, uint32_t *offp) 338 { 339 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)img; 340 Elf32_Phdr *phdr; 341 uint8_t *phdrbase; 342 int i; 343 int used_sections = 0; 344 const int max_sectcnt = *sectcntp; 345 346 if ((ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize) >= imgsz) 347 return (-1); 348 349 phdrbase = (uint8_t *)img + ehdr->e_phoff; 350 351 for (i = 0; i < ehdr->e_phnum; i++) { 352 phdr = (Elf32_Phdr *)(phdrbase + ehdr->e_phentsize * i); 353 354 if (phdr->p_type == PT_INTERP) 355 return (-1); 356 357 if (phdr->p_type != PT_LOAD) 358 continue; 359 360 if (phdr->p_vaddr == phdr->p_paddr && 361 phdr->p_paddr == DBOOT_ENTRY_ADDRESS) { 362 *offp = (uint32_t)phdr->p_offset; 363 } else { 364 if (max_sectcnt <= used_sections) 365 return (-1); 366 367 sectp[used_sections].fb_sec_offset = phdr->p_offset; 368 sectp[used_sections].fb_sec_paddr = phdr->p_paddr; 369 sectp[used_sections].fb_sec_size = phdr->p_filesz; 370 sectp[used_sections].fb_sec_bss_size = 371 (phdr->p_filesz < phdr->p_memsz) ? 372 (phdr->p_memsz - phdr->p_filesz) : 0; 373 374 /* Extra sanity check for the input object file */ 375 if (sectp[used_sections].fb_sec_paddr + 376 sectp[used_sections].fb_sec_size + 377 sectp[used_sections].fb_sec_bss_size >= 378 DBOOT_ENTRY_ADDRESS) 379 return (-1); 380 381 used_sections++; 382 } 383 } 384 385 *sectcntp = used_sections; 386 return (0); 387 } 388 389 /* 390 * Create multiboot info structure 391 */ 392 static int 393 fastboot_build_mbi(char *mdep, fastboot_info_t *nk) 394 { 395 mb_module_t *mbp; 396 uintptr_t next_addr; 397 uintptr_t new_mbi_pa; 398 size_t size; 399 void *buf = NULL; 400 size_t arglen; 401 char bootargs[OBP_MAXPATHLEN]; 402 403 bzero(bootargs, OBP_MAXPATHLEN); 404 405 if (mdep != NULL && strlen(mdep) != 0) { 406 arglen = strlen(mdep) + 1; 407 } else { 408 arglen = saved_cmdline_len; 409 } 410 411 size = PAGESIZE + P2ROUNDUP(arglen, PAGESIZE); 412 buf = contig_alloc(size, &fastboot_below_1G_dma_attr, PAGESIZE, 0); 413 if (buf == NULL) { 414 cmn_err(CE_WARN, fastboot_enomem_msg, (uint64_t)size, "1G"); 415 return (-1); 416 } 417 418 bzero(buf, size); 419 420 new_mbi_pa = mmu_ptob((uint64_t)hat_getpfnum(kas.a_hat, (caddr_t)buf)); 421 422 hat_devload(kas.a_hat, (caddr_t)new_mbi_pa, size, 423 mmu_btop(new_mbi_pa), PROT_READ | PROT_WRITE, HAT_LOAD_NOCONSIST); 424 425 nk->fi_new_mbi_pa = (paddr_t)new_mbi_pa; 426 427 bcopy(&saved_mbi, (void *)new_mbi_pa, sizeof (multiboot_info_t)); 428 429 next_addr = new_mbi_pa + sizeof (multiboot_info_t); 430 ((multiboot_info_t *)new_mbi_pa)->mods_addr = next_addr; 431 mbp = (mb_module_t *)(uintptr_t)next_addr; 432 mbp->mod_start = newkernel.fi_files[FASTBOOT_BOOTARCHIVE].fb_dest_pa; 433 mbp->mod_end = newkernel.fi_files[FASTBOOT_BOOTARCHIVE].fb_next_pa; 434 435 next_addr += sizeof (mb_module_t); 436 bcopy(fastboot_filename[FASTBOOT_NAME_BOOTARCHIVE], (void *)next_addr, 437 strlen(fastboot_filename[FASTBOOT_NAME_BOOTARCHIVE])); 438 439 mbp->mod_name = next_addr; 440 mbp->reserved = 0; 441 next_addr += strlen(fastboot_filename[FASTBOOT_NAME_BOOTARCHIVE]); 442 *(char *)next_addr = '\0'; 443 next_addr++; 444 next_addr = P2ROUNDUP_TYPED(next_addr, 16, uintptr_t); 445 446 ((multiboot_info_t *)new_mbi_pa)->mmap_addr = next_addr; 447 bcopy((void *)(uintptr_t)saved_mmap, (void *)next_addr, 448 saved_mbi.mmap_length); 449 next_addr += saved_mbi.mmap_length; 450 451 ((multiboot_info_t *)new_mbi_pa)->drives_addr = next_addr; 452 bcopy((void *)(uintptr_t)saved_drives, (void *)next_addr, 453 saved_mbi.drives_length); 454 next_addr += saved_mbi.drives_length; 455 456 ((multiboot_info_t *)new_mbi_pa)->cmdline = next_addr; 457 458 if (mdep != NULL && strlen(mdep) != 0) { 459 bcopy(mdep, (void *)(uintptr_t) 460 (((multiboot_info_t *)new_mbi_pa)->cmdline), (arglen - 1)); 461 } else { 462 bcopy((void *)saved_cmdline, (void *)next_addr, (arglen - 1)); 463 } 464 /* Terminate the string */ 465 ((char *)(intptr_t)next_addr)[arglen - 1] = '\0'; 466 467 return (0); 468 } 469 470 /* 471 * Initialize HAT related fields 472 */ 473 static void 474 fastboot_init_fields(fastboot_info_t *nk) 475 { 476 if (x86_feature & X86_PAE) { 477 nk->fi_has_pae = 1; 478 nk->fi_shift_amt = fastboot_shift_amt_pae; 479 nk->fi_ptes_per_table = 512; 480 nk->fi_lpagesize = (2 << 20); /* 2M */ 481 #ifdef __amd64 482 nk->fi_top_level = 3; 483 #else 484 nk->fi_top_level = 2; 485 #endif /* __amd64 */ 486 } 487 } 488 489 /* 490 * Process boot argument 491 */ 492 static void 493 fastboot_parse_mdep(char *mdep, char *kern_bootpath, int *bootpath_len, 494 char *bootargs) 495 { 496 int i; 497 498 /* 499 * If mdep is not NULL, it comes in the format of 500 * mountpoint unix args 501 */ 502 if (mdep != NULL && strlen(mdep) != 0) { 503 if (mdep[0] != '-') { 504 /* First get the root argument */ 505 i = 0; 506 while (mdep[i] != '\0' && mdep[i] != ' ') { 507 i++; 508 } 509 510 if (i < 4 || strncmp(&mdep[i-4], "unix", 4) != 0) { 511 /* mount point */ 512 bcopy(mdep, kern_bootpath, i); 513 kern_bootpath[i] = '\0'; 514 *bootpath_len = i; 515 516 /* 517 * Get the next argument. It should be unix as 518 * we have validated in in halt.c. 519 */ 520 if (strlen(mdep) > i) { 521 mdep += (i + 1); 522 i = 0; 523 while (mdep[i] != '\0' && 524 mdep[i] != ' ') { 525 i++; 526 } 527 } 528 529 } 530 bcopy(mdep, kern_bootfile, i); 531 kern_bootfile[i] = '\0'; 532 bcopy(mdep, bootargs, strlen(mdep)); 533 } else { 534 int off = strlen(kern_bootfile); 535 bcopy(kern_bootfile, bootargs, off); 536 bcopy(" ", &bootargs[off++], 1); 537 bcopy(mdep, &bootargs[off], strlen(mdep)); 538 off += strlen(mdep); 539 bootargs[off] = '\0'; 540 } 541 } 542 } 543 544 /* 545 * Free up the memory we have allocated for this file 546 */ 547 static void 548 fastboot_free_file(fastboot_file_t *fb) 549 { 550 size_t fsize_roundup, pt_size; 551 int pt_entry_count; 552 553 fsize_roundup = P2ROUNDUP_TYPED(fb->fb_size, PAGESIZE, size_t); 554 contig_free((void *)fb->fb_va, fsize_roundup); 555 556 pt_entry_count = (fsize_roundup >> PAGESHIFT) + 1; 557 pt_size = P2ROUNDUP(pt_entry_count * 8, PAGESIZE); 558 contig_free((void *)fb->fb_pte_list_va, pt_size); 559 } 560 561 /* 562 * This function performs the following tasks: 563 * - Read the sizes of the new kernel and boot archive. 564 * - Allocate memory for the new kernel and boot archive. 565 * - Allocate memory for page tables necessary for mapping the memory 566 * allocated for the files. 567 * - Read the new kernel and boot archive into memory. 568 * - Map in the fast reboot switcher. 569 * - Load the fast reboot switcher to FASTBOOT_SWTCH_PA. 570 * - Build the new multiboot_info structure 571 * - Build page tables for the low 1G of physical memory. 572 * - Mark the data structure as valid if all steps have succeeded. 573 */ 574 void 575 load_kernel(char *mdep) 576 { 577 void *buf = NULL; 578 int i; 579 fastboot_file_t *fb; 580 uint32_t dboot_start_offset; 581 char kern_bootpath[OBP_MAXPATHLEN]; 582 char bootargs[OBP_MAXPATHLEN]; 583 extern uintptr_t postbootkernelbase; 584 extern char fb_swtch_image[]; 585 int bootpath_len = 0; 586 int is_failsafe = 0; 587 int is_retry = 0; 588 uint64_t end_addr; 589 590 ASSERT(fastreboot_capable); 591 592 postbootkernelbase = 0; 593 594 /* 595 * Initialize various HAT related fields in the data structure 596 */ 597 fastboot_init_fields(&newkernel); 598 599 bzero(kern_bootpath, OBP_MAXPATHLEN); 600 601 /* 602 * Process the boot argument 603 */ 604 bzero(bootargs, OBP_MAXPATHLEN); 605 fastboot_parse_mdep(mdep, kern_bootpath, &bootpath_len, bootargs); 606 607 /* 608 * Make sure we get the null character 609 */ 610 bcopy(kern_bootpath, fastboot_filename[FASTBOOT_NAME_UNIX], 611 bootpath_len); 612 bcopy(kern_bootfile, 613 &fastboot_filename[FASTBOOT_NAME_UNIX][bootpath_len], 614 strlen(kern_bootfile) + 1); 615 616 bcopy(kern_bootpath, fastboot_filename[FASTBOOT_NAME_BOOTARCHIVE], 617 bootpath_len); 618 619 if (bcmp(kern_bootfile, FAILSAFE_BOOTFILE, 620 (sizeof (FAILSAFE_BOOTFILE) - 1)) == 0) { 621 is_failsafe = 1; 622 } 623 624 load_kernel_retry: 625 /* 626 * Read in unix and boot_archive 627 */ 628 end_addr = DBOOT_ENTRY_ADDRESS; 629 for (i = 0; i < FASTBOOT_MAX_FILES_MAP; i++) { 630 struct _buf *file; 631 uintptr_t va; 632 uint64_t fsize; 633 size_t fsize_roundup, pt_size; 634 int page_index; 635 uintptr_t offset; 636 int pt_entry_count; 637 ddi_dma_attr_t dma_attr = fastboot_dma_attr; 638 639 640 dprintf("fastboot_filename[%d] = %s\n", 641 i, fastboot_filename[i]); 642 643 if ((file = kobj_open_file(fastboot_filename[i])) == 644 (struct _buf *)-1) { 645 cmn_err(CE_WARN, "Fastboot: Couldn't open %s", 646 fastboot_filename[i]); 647 goto err_out; 648 } 649 650 if (kobj_get_filesize(file, &fsize) != 0) { 651 cmn_err(CE_WARN, 652 "Fastboot: Couldn't get filesize for %s", 653 fastboot_filename[i]); 654 goto err_out; 655 } 656 657 fsize_roundup = P2ROUNDUP_TYPED(fsize, PAGESIZE, size_t); 658 659 /* 660 * Where the files end in physical memory after being 661 * relocated by the fast boot switcher. 662 */ 663 end_addr += fsize_roundup; 664 if (end_addr > fastboot_below_1G_dma_attr.dma_attr_addr_hi) { 665 cmn_err(CE_WARN, "Fastboot: boot archive is too big"); 666 goto err_out; 667 } 668 669 /* 670 * Adjust dma_attr_addr_lo so that the new kernel and boot 671 * archive will not be overridden during relocation. 672 */ 673 if (end_addr > fastboot_dma_attr.dma_attr_addr_lo || 674 end_addr > fastboot_below_1G_dma_attr.dma_attr_addr_lo) { 675 676 if (is_retry) { 677 /* 678 * If we have already tried and didn't succeed, 679 * just give up. 680 */ 681 cmn_err(CE_WARN, 682 "Fastboot: boot archive is too big"); 683 goto err_out; 684 } else { 685 int j; 686 687 /* Set the flag so we don't keep retrying */ 688 is_retry++; 689 690 /* Adjust dma_attr_addr_lo */ 691 fastboot_dma_attr.dma_attr_addr_lo = end_addr; 692 fastboot_below_1G_dma_attr.dma_attr_addr_lo = 693 end_addr; 694 695 /* 696 * Free the memory we have already allocated 697 * whose physical addresses might not fit 698 * the new lo and hi constraints. 699 */ 700 for (j = 0; j < i; j++) 701 fastboot_free_file( 702 &newkernel.fi_files[j]); 703 goto load_kernel_retry; 704 } 705 } 706 707 708 if (!fastboot_contig) 709 dma_attr.dma_attr_sgllen = (fsize / PAGESIZE) + 710 (((fsize % PAGESIZE) == 0) ? 0 : 1); 711 712 if ((buf = contig_alloc(fsize, &dma_attr, PAGESIZE, 0)) 713 == NULL) { 714 cmn_err(CE_WARN, fastboot_enomem_msg, fsize, "64G"); 715 goto err_out; 716 } 717 718 va = P2ROUNDUP_TYPED((uintptr_t)buf, PAGESIZE, uintptr_t); 719 720 if (kobj_read_file(file, (char *)va, fsize, 0) < 0) { 721 cmn_err(CE_WARN, "Fastboot: Couldn't read %s", 722 fastboot_filename[i]); 723 goto err_out; 724 } 725 726 fb = &newkernel.fi_files[i]; 727 fb->fb_va = va; 728 fb->fb_size = fsize; 729 fb->fb_sectcnt = 0; 730 731 /* 732 * Allocate one extra page table entry for terminating 733 * the list. 734 */ 735 pt_entry_count = (fsize_roundup >> PAGESHIFT) + 1; 736 pt_size = P2ROUNDUP(pt_entry_count * 8, PAGESIZE); 737 738 if ((fb->fb_pte_list_va = 739 (x86pte_t *)contig_alloc(pt_size, 740 &fastboot_below_1G_dma_attr, PAGESIZE, 0)) == NULL) { 741 cmn_err(CE_WARN, fastboot_enomem_msg, 742 (uint64_t)pt_size, "1G"); 743 goto err_out; 744 } 745 746 bzero((void *)(fb->fb_pte_list_va), pt_size); 747 748 fb->fb_pte_list_pa = mmu_ptob((uint64_t)hat_getpfnum(kas.a_hat, 749 (caddr_t)fb->fb_pte_list_va)); 750 751 for (page_index = 0, offset = 0; offset < fb->fb_size; 752 offset += PAGESIZE) { 753 uint64_t paddr; 754 755 paddr = mmu_ptob((uint64_t)hat_getpfnum(kas.a_hat, 756 (caddr_t)fb->fb_va + offset)); 757 758 ASSERT(paddr >= fastboot_dma_attr.dma_attr_addr_lo); 759 760 /* 761 * Include the pte_bits so we don't have to make 762 * it in assembly. 763 */ 764 fb->fb_pte_list_va[page_index++] = (x86pte_t) 765 (paddr | pte_bits); 766 } 767 768 fb->fb_pte_list_va[page_index] = FASTBOOT_TERMINATE; 769 770 if (i == FASTBOOT_UNIX) { 771 Ehdr *ehdr = (Ehdr *)va; 772 int j; 773 774 /* 775 * Sanity checks: 776 */ 777 for (j = 0; j < SELFMAG; j++) { 778 if (ehdr->e_ident[j] != ELFMAG[j]) { 779 cmn_err(CE_WARN, "Fastboot: Bad ELF " 780 "signature"); 781 goto err_out; 782 } 783 } 784 785 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32 && 786 ehdr->e_ident[EI_DATA] == ELFDATA2LSB && 787 ehdr->e_machine == EM_386) { 788 789 fb->fb_sectcnt = sizeof (fb->fb_sections) / 790 sizeof (fb->fb_sections[0]); 791 792 if (fastboot_elf32_find_loadables((void *)va, 793 fsize, &fb->fb_sections[0], 794 &fb->fb_sectcnt, &dboot_start_offset) < 0) { 795 cmn_err(CE_WARN, "Fastboot: ELF32 " 796 "program section failure"); 797 goto err_out; 798 } 799 800 if (fb->fb_sectcnt == 0) { 801 cmn_err(CE_WARN, "Fastboot: No ELF32 " 802 "program sections found"); 803 goto err_out; 804 } 805 806 if (is_failsafe) { 807 /* Failsafe boot_archive */ 808 bcopy(BOOTARCHIVE_FAILSAFE, 809 &fastboot_filename 810 [FASTBOOT_NAME_BOOTARCHIVE] 811 [bootpath_len], 812 sizeof (BOOTARCHIVE_FAILSAFE)); 813 } else { 814 bcopy(BOOTARCHIVE32, 815 &fastboot_filename 816 [FASTBOOT_NAME_BOOTARCHIVE] 817 [bootpath_len], 818 sizeof (BOOTARCHIVE32)); 819 } 820 821 } else if (ehdr->e_ident[EI_CLASS] == ELFCLASS64 && 822 ehdr->e_ident[EI_DATA] == ELFDATA2LSB && 823 ehdr->e_machine == EM_AMD64) { 824 825 if (fastboot_elf64_find_dboot_load_offset( 826 (void *)va, fsize, &dboot_start_offset) 827 != 0) { 828 cmn_err(CE_WARN, "Fastboot: Couldn't " 829 "find ELF64 dboot entry offset"); 830 goto err_out; 831 } 832 833 if ((x86_feature & X86_64) == 0 || 834 (x86_feature & X86_PAE) == 0) { 835 cmn_err(CE_WARN, "Fastboot: Cannot " 836 "reboot to %s: " 837 "not a 64-bit capable system", 838 kern_bootfile); 839 goto err_out; 840 } 841 842 bcopy(BOOTARCHIVE64, 843 &fastboot_filename 844 [FASTBOOT_NAME_BOOTARCHIVE][bootpath_len], 845 sizeof (BOOTARCHIVE64)); 846 } else { 847 cmn_err(CE_WARN, "Fastboot: Unknown ELF type"); 848 goto err_out; 849 } 850 851 fb->fb_dest_pa = DBOOT_ENTRY_ADDRESS - 852 dboot_start_offset; 853 854 fb->fb_next_pa = DBOOT_ENTRY_ADDRESS + fsize_roundup; 855 } else { 856 fb->fb_dest_pa = newkernel.fi_files[i - 1].fb_next_pa; 857 fb->fb_next_pa = fb->fb_dest_pa + fsize_roundup; 858 } 859 860 kobj_close_file(file); 861 862 } 863 864 /* 865 * Set fb_va to fake_va 866 */ 867 for (i = 0; i < FASTBOOT_MAX_FILES_MAP; i++) { 868 newkernel.fi_files[i].fb_va = fake_va; 869 870 } 871 872 /* 873 * Add the function that will switch us to 32-bit protected mode 874 */ 875 fb = &newkernel.fi_files[FASTBOOT_SWTCH]; 876 fb->fb_va = fb->fb_dest_pa = FASTBOOT_SWTCH_PA; 877 fb->fb_size = MMU_PAGESIZE; 878 879 /* 880 * Map in FASTBOOT_SWTCH_PA 881 */ 882 hat_devload(kas.a_hat, (caddr_t)fb->fb_va, MMU_PAGESIZE, 883 mmu_btop(fb->fb_dest_pa), 884 PROT_READ | PROT_WRITE | PROT_EXEC, HAT_LOAD_NOCONSIST); 885 886 bcopy((void *)fb_swtch_image, (void *)fb->fb_va, fb->fb_size); 887 888 /* 889 * Build the new multiboot_info structure 890 */ 891 if (fastboot_build_mbi(bootargs, &newkernel) != 0) { 892 goto err_out; 893 } 894 895 /* 896 * Build page table for low 1G physical memory. Use big pages. 897 * Allocate 4 (5 for amd64) pages for the page tables. 898 * 1 page for PML4 (amd64) 899 * 1 page for Page-Directory-Pointer Table 900 * 2 pages for Page Directory 901 * 1 page for Page Table. 902 * The page table entry will be rewritten to map the physical 903 * address as we do the copying. 904 */ 905 if (newkernel.fi_has_pae) { 906 #ifdef __amd64 907 size_t size = MMU_PAGESIZE * 5; 908 #else 909 size_t size = MMU_PAGESIZE * 4; 910 #endif /* __amd64 */ 911 912 if ((newkernel.fi_pagetable_va = (uintptr_t) 913 contig_alloc(size, &fastboot_below_1G_dma_attr, 914 MMU_PAGESIZE, 0)) == NULL) { 915 cmn_err(CE_WARN, fastboot_enomem_msg, 916 (uint64_t)size, "1G"); 917 goto err_out; 918 } 919 920 bzero((void *)(newkernel.fi_pagetable_va), size); 921 922 newkernel.fi_pagetable_pa = 923 mmu_ptob((uint64_t)hat_getpfnum(kas.a_hat, 924 (caddr_t)newkernel.fi_pagetable_va)); 925 926 newkernel.fi_last_table_pa = newkernel.fi_pagetable_pa + 927 size - MMU_PAGESIZE; 928 929 newkernel.fi_next_table_va = newkernel.fi_pagetable_va + 930 MMU_PAGESIZE; 931 newkernel.fi_next_table_pa = newkernel.fi_pagetable_pa + 932 MMU_PAGESIZE; 933 934 fastboot_build_pagetables(&newkernel); 935 } 936 937 938 /* Mark it as valid */ 939 newkernel.fi_valid = 1; 940 newkernel.fi_magic = FASTBOOT_MAGIC; 941 942 return; 943 944 err_out: 945 newkernel.fi_valid = 0; 946 } 947 948 /* 949 * Jump to the fast reboot switcher. This function never returns. 950 */ 951 void 952 fast_reboot() 953 { 954 void (*fastboot_func)(fastboot_info_t *); 955 956 fastboot_func = (void (*)())(newkernel.fi_files[FASTBOOT_SWTCH].fb_va); 957 (*fastboot_func)(&newkernel); 958 } 959