Print this page
9059 Simplify SMAP relocations with krtld
Portions contributed by: John Levon <john.levon@joyent.com>


 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  */