From f2c3225ab613f849fc68b3489e03f60fcebe456e Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Fri, 13 Oct 2017 14:18:29 +0200 Subject: [PATCH] nova: enable nx bit handling for x86_64 Issue #1723 --- repos/base-nova/ports/nova.hash | 2 +- repos/base-nova/ports/nova.port | 4 +- repos/base-nova/src/core/include/ipc_pager.h | 253 ++++++++---------- repos/base-nova/src/core/ipc_pager.cc | 4 +- .../base-nova/src/core/pd_session_support.cc | 2 +- repos/base-nova/src/core/platform.cc | 4 +- repos/base-nova/src/kernel/nova/target.mk | 2 +- repos/base/run/rm_fault.run | 2 + 8 files changed, 130 insertions(+), 143 deletions(-) diff --git a/repos/base-nova/ports/nova.hash b/repos/base-nova/ports/nova.hash index abd6bf5736..fb9678ec31 100644 --- a/repos/base-nova/ports/nova.hash +++ b/repos/base-nova/ports/nova.hash @@ -1 +1 @@ -af1667f52b0d8da04bfe7b808974fb290f3e213f +4d8b81a60e34ee62ad9b6f24bfc5e0bf670a4f21 diff --git a/repos/base-nova/ports/nova.port b/repos/base-nova/ports/nova.port index 0cc2686080..d26e322017 100644 --- a/repos/base-nova/ports/nova.port +++ b/repos/base-nova/ports/nova.port @@ -4,7 +4,7 @@ DOWNLOADS := nova.git # r9 branch - use r9_debug for more verbose kernel messages URL(nova) := https://github.com/alex-ab/NOVA.git -REV(nova) := 190605f8723a2714f90f42b94bbd0757604bee06 +REV(nova) := baed84d2ebf122f112035d280170fa24abe00aaa DIR(nova) := src/kernel/nova -PATCHES := $(wildcard $(REP_DIR)/patches/*.patch) +PATCHES := $(sort $(wildcard $(REP_DIR)/patches/*.patch)) diff --git a/repos/base-nova/src/core/include/ipc_pager.h b/repos/base-nova/src/core/include/ipc_pager.h index df2329e686..e15b92caa6 100644 --- a/repos/base-nova/src/core/include/ipc_pager.h +++ b/repos/base-nova/src/core/include/ipc_pager.h @@ -23,141 +23,124 @@ #include namespace Genode { - - class Mapping - { - private: - - addr_t _dst_addr; - addr_t _core_local_addr; - Cache_attribute _attr; - size_t _size_log2; - bool _rw; - - enum { PAGE_SIZE_LOG2 = 12 }; - - public: - - /** - * Constructor - */ - Mapping(addr_t dst_addr, addr_t map_addr, - Cache_attribute c, bool io_mem, - unsigned size_log2, - bool rw, bool executable) - : - _dst_addr(dst_addr), _core_local_addr(map_addr), - _attr(c), _size_log2(size_log2), _rw(rw) - { } - - /** - * Construct invalid mapping - */ - Mapping() : _size_log2(0) { } - - void prepare_map_operation() { } - - Nova::Mem_crd mem_crd() - { - return Nova::Mem_crd(_core_local_addr >> PAGE_SIZE_LOG2, - _size_log2 - PAGE_SIZE_LOG2, - Nova::Rights(true, _rw, true)); - } - - bool dma() { return _attr != CACHED; }; - bool write_combined() { return _attr == WRITE_COMBINED; }; - - addr_t dst_addr() { return _dst_addr; } - }; - - - class Ipc_pager - { - private: - - addr_t _pd_dst; - addr_t _pd_core; - addr_t _fault_ip; - addr_t _fault_addr; - addr_t _sp; - uint8_t _fault_type; - uint8_t _syscall_res; - uint8_t _normal_ipc; - - public: - - Ipc_pager (Nova::Utcb *, addr_t pd_dst, addr_t pd_core); - - /* - * Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE - * Interrupt 14—Page-Fault Exception (#PF) - */ - enum { - ERR_I = 1 << 4, - ERR_R = 1 << 3, - ERR_U = 1 << 2, - ERR_W = 1 << 1, - ERR_P = 1 << 0, - }; - - /** - * Answer current page fault - */ - void reply_and_wait_for_fault(addr_t sm = 0UL); - - /** - * Request instruction pointer of current fault - */ - addr_t fault_ip() { return _fault_ip; } - - /** - * Request page-fault address of current fault - */ - addr_t fault_addr() { return _fault_addr; } - - /** - * Set page-fault reply parameters - */ - void set_reply_mapping(Mapping m); - - /** - * Return true if fault was a write fault - */ - bool write_fault() const { return _fault_type & ERR_W; } - - /** - * Return true if fault was a non-executable fault - */ - bool exec_fault() const { return false; } - - /** - * Return true if last fault was an exception - */ - bool exception() const - { - /* - * Reflection of exceptions is not supported on this platform. - */ - return false; - } - - /** - * Return result of delegate syscall - */ - uint8_t syscall_result() const { return _syscall_res; } - - /** - * Return low level fault type info - * Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE - * Interrupt 14—Page-Fault Exception (#PF) - */ - addr_t fault_type() { return _fault_type; } - - /** - * Return stack pointer address valid during page-fault - */ - addr_t sp() { return _sp; } - }; + class Mapping; + class Ipc_pager; } +class Genode::Mapping +{ + private: + + addr_t const _dst_addr; + Cache_attribute const _attr; + Nova::Mem_crd const _mem_crd; + + enum { PAGE_SIZE_LOG2 = 12 }; + + public: + + /** + * Constructor + */ + Mapping(addr_t dst_addr, addr_t source_addr, + Cache_attribute c, bool io_mem, + unsigned size_log2, + bool writeable, bool executable) + : + _dst_addr(dst_addr), + _attr(c), + _mem_crd(source_addr >> PAGE_SIZE_LOG2, + size_log2 - PAGE_SIZE_LOG2, + Nova::Rights(true, writeable, executable)) + { } + + void prepare_map_operation() { } + + Nova::Mem_crd mem_crd() const { return _mem_crd; } + + bool dma() { return _attr != CACHED; }; + bool write_combined() { return _attr == WRITE_COMBINED; }; + + addr_t dst_addr() { return _dst_addr; } +}; + + +class Genode::Ipc_pager +{ + private: + + addr_t _pd_dst; + addr_t _pd_core; + addr_t _fault_ip; + addr_t _fault_addr; + addr_t _sp; + uint8_t _fault_type; + uint8_t _syscall_res; + uint8_t _normal_ipc; + + public: + + Ipc_pager (Nova::Utcb *, addr_t pd_dst, addr_t pd_core); + + /* + * Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE + * Interrupt 14—Page-Fault Exception (#PF) + */ + enum { + ERR_I = 1 << 4, + ERR_R = 1 << 3, + ERR_U = 1 << 2, + ERR_W = 1 << 1, + ERR_P = 1 << 0, + }; + + /** + * Answer current page fault + */ + void reply_and_wait_for_fault(addr_t sm = 0UL); + + /** + * Request instruction pointer of current fault + */ + addr_t fault_ip() { return _fault_ip; } + + /** + * Request page-fault address of current fault + */ + addr_t fault_addr() { return _fault_addr; } + + /** + * Set page-fault reply parameters + */ + void set_reply_mapping(Mapping m); + + /** + * Return true if fault was a write fault + */ + bool write_fault() const { return _fault_type & ERR_W; } + + /** + * Return true if fault was a non-executable fault + */ + bool exec_fault() const { + return _fault_type & ERR_P && _fault_type & ERR_I; } + + /** + * Return result of delegate syscall + */ + uint8_t syscall_result() const { return _syscall_res; } + + /** + * Return low level fault type info + * Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE + * Interrupt 14—Page-Fault Exception (#PF) + */ + addr_t fault_type() { return _fault_type; } + + /** + * Return stack pointer address valid during page-fault + */ + addr_t sp() { return _sp; } +}; + #endif /* _CORE__INCLUDE__IPC_PAGER_H_ */ diff --git a/repos/base-nova/src/core/ipc_pager.cc b/repos/base-nova/src/core/ipc_pager.cc index 58f0e2996b..c772cb3262 100644 --- a/repos/base-nova/src/core/ipc_pager.cc +++ b/repos/base-nova/src/core/ipc_pager.cc @@ -55,7 +55,9 @@ void Ipc_pager::set_reply_mapping(Mapping m) /* receive window in destination pd */ Nova::Mem_crd crd_mem(m.dst_addr() >> 12, m.mem_crd().order(), - Nova::Rights(true, true, true)); + Nova::Rights(m.mem_crd().rights().readable(), + m.mem_crd().rights().writeable(), + m.mem_crd().rights().executable())); /* asynchronously map memory */ _syscall_res = Nova::delegate(_pd_core, _pd_dst, crd_mem); } diff --git a/repos/base-nova/src/core/pd_session_support.cc b/repos/base-nova/src/core/pd_session_support.cc index a543a3f7f4..84c81bae41 100644 --- a/repos/base-nova/src/core/pd_session_support.cc +++ b/repos/base-nova/src/core/pd_session_support.cc @@ -67,7 +67,7 @@ void Pd_session_component::map(addr_t virt, addr_t size) /* receive window in destination pd */ Nova::Mem_crd crd_mem(mapping.dst_addr() >> 12, mapping.mem_crd().order(), - Nova::Rights(true, dsc->writable(), true)); + Nova::Rights(true, dsc->writable(), region->executable())); err = Nova::delegate(pd_core, pd_dst, crd_mem); } while (err == Nova::NOVA_PD_OOM && diff --git a/repos/base-nova/src/core/platform.cc b/repos/base-nova/src/core/platform.cc index d9902b92c3..531be05ae3 100644 --- a/repos/base-nova/src/core/platform.cc +++ b/repos/base-nova/src/core/platform.cc @@ -83,7 +83,7 @@ addr_t Platform::_map_pages(addr_t phys_page, addr_t const pages) addr_t const core_local_addr = reinterpret_cast(core_local_ptr); int res = map_local(__main_thread_utcb, phys_addr, core_local_addr, pages, - Nova::Rights(true, true, true), true); + Nova::Rights(true, true, false), true); return res ? 0 : core_local_addr; } @@ -814,7 +814,7 @@ bool Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr, { map_local((Utcb *)Thread::myself()->utcb(), phys_addr, virt_addr, size / get_page_size(), - Rights(true, true, true), true); + Rights(true, true, false), true); return true; } diff --git a/repos/base-nova/src/kernel/nova/target.mk b/repos/base-nova/src/kernel/nova/target.mk index 65463006d6..04aec00f5f 100644 --- a/repos/base-nova/src/kernel/nova/target.mk +++ b/repos/base-nova/src/kernel/nova/target.mk @@ -29,7 +29,7 @@ CC_OPT += -mpreferred-stack-boundary=2 -mregparm=3 else ifeq ($(filter-out $(SPECS),64bit),) override CC_MARCH = -m64 -CC_WARN += -Wframe-larger-than=240 +CC_WARN += -Wframe-larger-than=256 CC_OPT += -mpreferred-stack-boundary=4 -mcmodel=kernel -mno-red-zone else $(error Unsupported environment) diff --git a/repos/base/run/rm_fault.run b/repos/base/run/rm_fault.run index 9c27b75e56..6b84037ca3 100644 --- a/repos/base/run/rm_fault.run +++ b/repos/base/run/rm_fault.run @@ -6,6 +6,8 @@ if {[have_spec linux]} { # is not supported. # proc non_executable_supported { } { + if {[have_spec nova] && [have_spec x86_64]} { return true } + return false }