680 *allocations[i].al_ptr = (void *)mem;
681 mem += allocations[i].al_size;
682 }
683 }
684
685 /*
686 * Set up and enable SMAP now before we start other CPUs, but after the kernel's
687 * VM has been set up so we can use hot_patch_kernel_text().
688 *
689 * We can only patch 1, 2, or 4 bytes, but not three bytes. So instead, we
690 * replace the four byte word at the patch point. See uts/intel/ia32/ml/copy.s
691 * for more information on what's going on here.
692 */
693 static void
694 startup_smap(void)
695 {
696 int i;
697 uint32_t inst;
698 uint8_t *instp;
699 char sym[128];
700
701 extern int _smap_enable_patch_count;
702 extern int _smap_disable_patch_count;
703
704 if (disable_smap != 0)
705 remove_x86_feature(x86_featureset, X86FSET_SMAP);
706
707 if (is_x86_feature(x86_featureset, X86FSET_SMAP) == B_FALSE)
708 return;
709
710 for (i = 0; i < _smap_enable_patch_count; i++) {
711 int sizep;
712
713 VERIFY3U(i, <, _smap_enable_patch_count);
714 VERIFY(snprintf(sym, sizeof (sym), "_smap_enable_patch_%d", i) <
715 sizeof (sym));
716 instp = (uint8_t *)(void *)kobj_getelfsym(sym, NULL, &sizep);
717 VERIFY(instp != 0);
718 inst = (instp[3] << 24) | (SMAP_CLAC_INSTR & 0x00ffffff);
719 hot_patch_kernel_text((caddr_t)instp, inst, 4);
720 }
721
722 for (i = 0; i < _smap_disable_patch_count; i++) {
723 int sizep;
724
725 VERIFY(snprintf(sym, sizeof (sym), "_smap_disable_patch_%d",
726 i) < sizeof (sym));
727 instp = (uint8_t *)(void *)kobj_getelfsym(sym, NULL, &sizep);
728 VERIFY(instp != 0);
729 inst = (instp[3] << 24) | (SMAP_STAC_INSTR & 0x00ffffff);
730 hot_patch_kernel_text((caddr_t)instp, inst, 4);
731 }
732
733 hot_patch_kernel_text((caddr_t)smap_enable, SMAP_CLAC_INSTR, 4);
734 hot_patch_kernel_text((caddr_t)smap_disable, SMAP_STAC_INSTR, 4);
735 setcr4(getcr4() | CR4_SMAP);
736 smap_enable();
737 }
738
739 /*
740 * Our world looks like this at startup time.
741 *
742 * In a 32-bit OS, boot loads the kernel text at 0xfe800000 and kernel data
743 * at 0xfec00000. On a 64-bit OS, kernel text and data are loaded at
744 * 0xffffffff.fe800000 and 0xffffffff.fec00000 respectively. Those
745 * addresses are fixed in the binary at link time.
746 *
747 * On the text page:
748 * unix/genunix/krtld/module text loads.
749 *
750 * On the data page:
751 * unix/genunix/krtld/module data loads.
752 *
753 * Machine-dependent startup code
754 */
|
680 *allocations[i].al_ptr = (void *)mem;
681 mem += allocations[i].al_size;
682 }
683 }
684
685 /*
686 * Set up and enable SMAP now before we start other CPUs, but after the kernel's
687 * VM has been set up so we can use hot_patch_kernel_text().
688 *
689 * We can only patch 1, 2, or 4 bytes, but not three bytes. So instead, we
690 * replace the four byte word at the patch point. See uts/intel/ia32/ml/copy.s
691 * for more information on what's going on here.
692 */
693 static void
694 startup_smap(void)
695 {
696 int i;
697 uint32_t inst;
698 uint8_t *instp;
699 char sym[128];
700 struct modctl *modp;
701
702 extern int _smap_enable_patch_count;
703 extern int _smap_disable_patch_count;
704
705 if (disable_smap != 0)
706 remove_x86_feature(x86_featureset, X86FSET_SMAP);
707
708 if (is_x86_feature(x86_featureset, X86FSET_SMAP) == B_FALSE)
709 return;
710
711 for (i = 0; i < _smap_enable_patch_count; i++) {
712 int sizep;
713
714 VERIFY3U(i, <, _smap_enable_patch_count);
715 VERIFY(snprintf(sym, sizeof (sym), "_smap_enable_patch_%d", i) <
716 sizeof (sym));
717 instp = (uint8_t *)(void *)kobj_getelfsym(sym, NULL, &sizep);
718 VERIFY(instp != 0);
719 inst = (instp[3] << 24) | (SMAP_CLAC_INSTR & 0x00ffffff);
720 hot_patch_kernel_text((caddr_t)instp, inst, 4);
721 }
722
723 for (i = 0; i < _smap_disable_patch_count; i++) {
724 int sizep;
725
726 VERIFY(snprintf(sym, sizeof (sym), "_smap_disable_patch_%d",
727 i) < sizeof (sym));
728 instp = (uint8_t *)(void *)kobj_getelfsym(sym, NULL, &sizep);
729 VERIFY(instp != 0);
730 inst = (instp[3] << 24) | (SMAP_STAC_INSTR & 0x00ffffff);
731 hot_patch_kernel_text((caddr_t)instp, inst, 4);
732 }
733
734 /*
735 * Hotinline calls to smap_enable and smap_disable within
736 * unix module. Hotinlines in other modules are done on
737 * mod_load().
738 */
739 modp = mod_hold_by_name("unix");
740 do_hotinlines(modp->mod_mp);
741 mod_release_mod(modp);
742
743 setcr4(getcr4() | CR4_SMAP);
744 smap_enable();
745 }
746
747 /*
748 * Our world looks like this at startup time.
749 *
750 * In a 32-bit OS, boot loads the kernel text at 0xfe800000 and kernel data
751 * at 0xfec00000. On a 64-bit OS, kernel text and data are loaded at
752 * 0xffffffff.fe800000 and 0xffffffff.fec00000 respectively. Those
753 * addresses are fixed in the binary at link time.
754 *
755 * On the text page:
756 * unix/genunix/krtld/module text loads.
757 *
758 * On the data page:
759 * unix/genunix/krtld/module data loads.
760 *
761 * Machine-dependent startup code
762 */
|