diff --git a/hermit/arch/x86/kernel/apic.c b/hermit/arch/x86/kernel/apic.c index 117b115c8..208fc26f9 100644 --- a/hermit/arch/x86/kernel/apic.c +++ b/hermit/arch/x86/kernel/apic.c @@ -309,9 +309,14 @@ int apic_enable_timer(void) static apic_mp_t* search_mptable(size_t base, size_t limit) { size_t ptr=PAGE_CEIL(base), vptr=0; + size_t flags = PG_GLOBAL | PG_RW | PG_PCD; apic_mp_t* tmp; uint32_t i; + // protec apic by the NX flags + if (has_nx()) + flags |= PG_XD; + while(ptr<=limit-sizeof(apic_mp_t)) { if (vptr) { // unmap page via mapping a zero page @@ -319,7 +324,7 @@ static apic_mp_t* search_mptable(size_t base, size_t limit) { vptr = 0; } - if (BUILTIN_EXPECT(!page_map(ptr & PAGE_MASK, ptr & PAGE_MASK, 1, PG_GLOBAL | PG_RW | PG_PCD), 1)) + if (BUILTIN_EXPECT(!page_map(ptr & PAGE_MASK, ptr & PAGE_MASK, 1, flags), 1)) vptr = ptr & PAGE_MASK; else return NULL; @@ -472,6 +477,11 @@ static int apic_probe(void) size_t addr; uint32_t i, j, count; int isa_bus = -1; + size_t flags = PG_GLOBAL | PG_RW | PG_PCD; + + // protect apic by NX flags + if (has_nx()) + flags |= PG_XD; apic_mp = search_mptable(0xF0000, 0x100000); if (apic_mp) @@ -500,7 +510,7 @@ found_mp: apic_config = (apic_config_table_t*) ((size_t) apic_mp->mp_config); if (((size_t) apic_config & PAGE_MASK) != ((size_t) apic_mp & PAGE_MASK)) { - page_map((size_t) apic_config & PAGE_MASK, (size_t) apic_config & PAGE_MASK, 1, PG_GLOBAL | PG_RW | PG_PCD); + page_map((size_t) apic_config & PAGE_MASK, (size_t) apic_config & PAGE_MASK, 1, flags); vma_add( (size_t) apic_config & PAGE_MASK, ((size_t) apic_config & PAGE_MASK) + PAGE_SIZE, VMA_READ|VMA_WRITE); } @@ -515,7 +525,7 @@ found_mp: // does the apic table raise the page boundary? => map additional page if (apic_config->entry_count * 20 + addr > ((size_t) apic_config & PAGE_MASK) + PAGE_SIZE) { - page_map(((size_t) apic_config & PAGE_MASK) + PAGE_SIZE, ((size_t) apic_config & PAGE_MASK) + PAGE_SIZE, 1, PG_GLOBAL | PG_RW | PG_PCD); + page_map(((size_t) apic_config & PAGE_MASK) + PAGE_SIZE, ((size_t) apic_config & PAGE_MASK) + PAGE_SIZE, 1, flags); vma_add( ((size_t) apic_config & PAGE_MASK) + PAGE_SIZE, ((size_t) apic_config & PAGE_MASK) + 2*PAGE_SIZE, VMA_READ|VMA_WRITE); } @@ -563,7 +573,7 @@ found_mp: ioapic = (ioapic_t*) ((size_t) io_entry->addr); kprintf("Found IOAPIC at 0x%x\n", ioapic); #if 0 - page_map(IOAPIC_ADDR, (size_t)ioapic & PAGE_MASK, 1, PG_GLOBAL | PG_RW | PG_PCD); + page_map(IOAPIC_ADDR, (size_t)ioapic & PAGE_MASK, 1, flags); vma_add(IOAPIC_ADDR, IOAPIC_ADDR + PAGE_SIZE, VMA_READ|VMA_WRITE); ioapic = (ioapic_t*) IOAPIC_ADDR; kprintf("Map IOAPIC to 0x%x\n", ioapic); @@ -599,7 +609,7 @@ check_lapic: if (has_x2apic()) { x2apic_enable(); } else { - if (page_map(LAPIC_ADDR, (size_t)lapic & PAGE_MASK, 1, PG_GLOBAL | PG_RW | PG_PCD)) { + if (page_map(LAPIC_ADDR, (size_t)lapic & PAGE_MASK, 1, flags)) { kprintf("Failed to map APIC to 0x%x\n", LAPIC_ADDR); goto out; } else { diff --git a/hermit/drivers/net/mmnif.c b/hermit/drivers/net/mmnif.c index 6ed024364..fde6803d4 100644 --- a/hermit/drivers/net/mmnif.c +++ b/hermit/drivers/net/mmnif.c @@ -550,6 +550,7 @@ err_t mmnif_init(struct netif *netif) int num = 0; int err; uint32_t nodes = possible_isles + 1; + size_t flags; DEBUGPRINTF("Initialize mmnif\n"); @@ -598,8 +599,13 @@ err_t mmnif_init(struct netif *netif) goto out; } + // protect mmnif shared segments by the NX flag + flags = PG_RW|PG_GLOBAL; + if (has_nx()) + flags |= PG_XD; + // map physical address in the virtual address space - err = page_map((size_t) header_start_address, (size_t) header_phy_start_address, (nodes * header_size) >> PAGE_BITS, PG_RW|PG_GLOBAL); + err = page_map((size_t) header_start_address, (size_t) header_phy_start_address, (nodes * header_size) >> PAGE_BITS, flags); if (BUILTIN_EXPECT(err, 0)) { DEBUGPRINTF("mmnif init(): page_map failed\n"); goto out; @@ -621,7 +627,7 @@ err_t mmnif_init(struct netif *netif) } // map physical address in the virtual address space - err = page_map((size_t) heap_start_address, (size_t) heap_phy_start_address, (nodes * heap_size) >> PAGE_BITS, PG_RW|PG_GLOBAL); + err = page_map((size_t) heap_start_address, (size_t) heap_phy_start_address, (nodes * heap_size) >> PAGE_BITS, flags); if (BUILTIN_EXPECT(err, 0)) { DEBUGPRINTF("mmnif init(): page_map failed\n"); goto out; @@ -641,7 +647,7 @@ err_t mmnif_init(struct netif *netif) } // map physical address in the virtual address space - err = page_map((size_t) isle_locks, (size_t) phy_isle_locks, (((nodes+1) * sizeof(islelock_t) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) >> PAGE_BITS, PG_RW|PG_GLOBAL); + err = page_map((size_t) isle_locks, (size_t) phy_isle_locks, (((nodes+1) * sizeof(islelock_t) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) >> PAGE_BITS, flags); if (BUILTIN_EXPECT(err, 0)) { DEBUGPRINTF("mmnif init(): page_map failed\n"); goto out; diff --git a/hermit/kernel/main.c b/hermit/kernel/main.c index 09ae2a475..8d2b2fa5d 100644 --- a/hermit/kernel/main.c +++ b/hermit/kernel/main.c @@ -240,12 +240,14 @@ int smp_main(void) static int init_rcce(void) { - size_t addr; + size_t addr, flags = PG_GLOBAL|PG_RW; addr = vma_alloc(PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE); if (BUILTIN_EXPECT(!addr, 0)) return -ENOMEM; - if (page_map(addr, phy_rcce_internals, 1, PG_GLOBAL|PG_RW)) { + if (has_nx()) + flags |= PG_XD; + if (page_map(addr, phy_rcce_internals, 1, flags)) { vma_free(addr, addr + PAGE_SIZE); return -ENOMEM; } diff --git a/hermit/mm/malloc.c b/hermit/mm/malloc.c index 1c846d404..9e1aeba31 100644 --- a/hermit/mm/malloc.c +++ b/hermit/mm/malloc.c @@ -78,7 +78,7 @@ static buddy_t* buddy_get(int exp) else if ((exp >= BUDDY_ALLOC) && !buddy_large_avail(exp)) // theres no free buddy larger than exp => // we can allocate new memory - buddy = (buddy_t*) palloc(1<> PAGE_BITS; int err; //kprintf("palloc(%lu) (%lu pages)\n", sz, npages); // get free virtual address space - viraddr = vma_alloc(npages*PAGE_SIZE, VMA_HEAP); + viraddr = vma_alloc(npages*PAGE_SIZE, flags); if (BUILTIN_EXPECT(!viraddr, 0)) return NULL; @@ -150,8 +150,14 @@ void* palloc(size_t sz, uint32_t flags) return NULL; } + //TODO: interpretation of from (vma) flags is missing + bits = PG_RW|PG_GLOBAL; + // protect heap by the NX flag + if (has_nx()) + bits |= PG_XD; + // map physical pages to VMA - err = page_map(viraddr, phyaddr, npages, PG_RW|PG_GLOBAL); + err = page_map(viraddr, phyaddr, npages, bits); if (BUILTIN_EXPECT(err, 0)) { vma_free(viraddr, viraddr+npages*PAGE_SIZE); put_pages(phyaddr, npages);