This is one of the last users of uvm_km_alloc(9) in the tree.
Converting to km_alloc(9) is a bit tricky though since we deliberately
don't allow making the allocated memory executable through uvm
interfaces. But since km_alloc(9) uses pmap_kenter_pa(9) anyway, we
can just use that to change to protection bits later. Maintaining W^X
of course!
ok?
Index: dev/ic/sti.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/sti.c,v
retrieving revision 1.80
diff -u -p -r1.80 sti.c
--- dev/ic/sti.c 25 May 2020 09:55:48 -0000 1.80
+++ dev/ic/sti.c 25 Apr 2021 20:15:13 -0000
@@ -211,7 +211,9 @@ sti_rom_setup(struct sti_rom *rom, bus_s
bus_space_handle_t romh, bus_addr_t *bases, u_int codebase)
{
struct sti_dd *dd;
- int error, size, i;
+ int size, i;
+ vaddr_t va;
+ paddr_t pa;
STI_ENABLE_ROM(rom->rom_softc);
@@ -315,12 +317,13 @@ sti_rom_setup(struct sti_rom *rom, bus_s
return (EINVAL);
}
- if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size)))) {
+ if (!(rom->rom_code = km_alloc(round_page(size), &kv_any,
+ &kp_zero, &kd_waitok))) {
printf(": cannot allocate %u bytes for code\n", size);
return (ENOMEM);
}
#ifdef STIDEBUG
- printf("code=0x%lx[%x]\n", rom->rom_code, size);
+ printf("code=%p[%x]\n", rom->rom_code, size);
#endif
/*
@@ -330,7 +333,7 @@ sti_rom_setup(struct sti_rom *rom, bus_s
STI_ENABLE_ROM(rom->rom_softc);
if (rom->rom_devtype == STI_DEVTYPE1) {
- u_int8_t *p = (u_int8_t *)rom->rom_code;
+ u_int8_t *p = rom->rom_code;
u_int32_t addr, eaddr;
for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4;
@@ -339,17 +342,24 @@ sti_rom_setup(struct sti_rom *rom, bus_s
} else /* STI_DEVTYPE4 */
bus_space_read_raw_region_4(memt, romh,
- dd->dd_pacode[STI_BEGIN], (u_int8_t *)rom->rom_code,
- size);
+ dd->dd_pacode[STI_BEGIN], rom->rom_code, size);
STI_DISABLE_ROM(rom->rom_softc);
- if ((error = uvm_map_protect(kernel_map, rom->rom_code,
- rom->rom_code + round_page(size), PROT_READ | PROT_EXEC, FALSE))) {
- printf(": uvm_map_protect failed (%d)\n", error);
- uvm_km_free(kernel_map, rom->rom_code, round_page(size));
- return (error);
+ /*
+ * Remap the ROM code as executable. This happens to be the
+ * only place in the OpenBSD kernel where we need to do this.
+ * Since the kernel (deliberately) doesn't provide a
+ * high-level interface to map kernel memory as executable we
+ * use low-level pmap calls for this.
+ */
+ for (va = (vaddr_t)rom->rom_code;
+ va < (vaddr_t)rom->rom_code + round_page(size);
+ va += PAGE_SIZE) {
+ pmap_extract(pmap_kernel(), va, &pa);
+ pmap_kenter_pa(va, pa, PROT_READ | PROT_EXEC);
}
+ pmap_update(pmap_kernel());
/*
* Setup code function pointers.
Index: dev/ic/stivar.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/stivar.h,v
retrieving revision 1.25
diff -u -p -r1.25 stivar.h
--- dev/ic/stivar.h 5 Apr 2015 23:25:57 -0000 1.25
+++ dev/ic/stivar.h 25 Apr 2021 20:15:13 -0000
@@ -45,7 +45,7 @@ struct sti_rom {
bus_addr_t *bases;
struct sti_dd rom_dd; /* in word format */
- vaddr_t rom_code;
+ u_int8_t *rom_code;
/*
* ROM-provided function pointers