mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-09 04:15:52 +00:00
hw: enable nx bit handling for arm
This commit is contained in:
parent
aa1d5a7dd1
commit
4dd5e6b266
@ -139,9 +139,10 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu
|
||||
* Return if the context is in a page fault due to translation miss
|
||||
*
|
||||
* \param va holds the virtual fault-address if call returns 1
|
||||
* \param w holds wether it's a write fault if call returns 1
|
||||
* \param w holds whether it's a write fault if call returns 1
|
||||
* \param p holds whether it's a permission fault if call returns 1
|
||||
*/
|
||||
bool in_fault(addr_t & va, addr_t & w) const
|
||||
bool in_fault(addr_t & va, addr_t & w, bool & p) const
|
||||
{
|
||||
/* translation fault on section */
|
||||
static constexpr Fsr::access_t section = 5;
|
||||
@ -156,12 +157,21 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu
|
||||
{
|
||||
/* check if fault was caused by a translation miss */
|
||||
Ifsr::access_t const fs = Fsr::Fs::get(Ifsr::read());
|
||||
|
||||
if (fs == permission) {
|
||||
w = 0;
|
||||
va = regs->ip;
|
||||
p = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fs != section && fs != page)
|
||||
return false;
|
||||
|
||||
/* fetch fault data */
|
||||
w = 0;
|
||||
va = regs->ip;
|
||||
p = false;
|
||||
return true;
|
||||
}
|
||||
case Context::DATA_ABORT:
|
||||
@ -175,6 +185,7 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu
|
||||
Dfsr::access_t const dfsr = Dfsr::read();
|
||||
w = Dfsr::Wnr::get(dfsr);
|
||||
va = Dfar::read();
|
||||
p = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ void Thread::exception(unsigned const cpu)
|
||||
void Thread::_mmu_exception()
|
||||
{
|
||||
_become_inactive(AWAITS_RESTART);
|
||||
if (in_fault(_fault_addr, _fault_writes)) {
|
||||
if (in_fault(_fault_addr, _fault_writes, _fault_exec)) {
|
||||
_fault_pd = (addr_t)_pd->platform_pd();
|
||||
|
||||
/*
|
||||
@ -73,14 +73,21 @@ void Thread::_mmu_exception()
|
||||
if (_pager) _pager->submit(1);
|
||||
return;
|
||||
}
|
||||
bool da = regs->cpu_exception == Cpu::Context::DATA_ABORT;
|
||||
|
||||
char const *abort_type = "unknown";
|
||||
if (regs->cpu_exception == Cpu::Context::DATA_ABORT)
|
||||
abort_type = "data";
|
||||
if (regs->cpu_exception == Cpu::Context::PREFETCH_ABORT)
|
||||
abort_type = "prefetch";
|
||||
|
||||
Genode::error(*this, ": raised unhandled ",
|
||||
da ? "data abort" : "prefetch abort", " "
|
||||
abort_type, " abort ",
|
||||
"DFSR=", Genode::Hex(Cpu::Dfsr::read()), " "
|
||||
"ISFR=", Genode::Hex(Cpu::Ifsr::read()), " "
|
||||
"DFAR=", Genode::Hex(Cpu::Dfar::read()), " "
|
||||
"ip=", Genode::Hex(regs->ip), " "
|
||||
"sp=", Genode::Hex(regs->sp));
|
||||
"sp=", Genode::Hex(regs->sp), " "
|
||||
"exception=", Genode::Hex(regs->cpu_exception));
|
||||
}
|
||||
|
||||
|
||||
|
@ -195,9 +195,10 @@ class Genode::Cpu : public Arm_v7_cpu
|
||||
* Return if the context is in a page fault due to translation miss
|
||||
*
|
||||
* \param va holds the virtual fault-address if call returns 1
|
||||
* \param w holds wether it's a write fault if call returns 1
|
||||
* \param w holds whether it's a write fault if call returns 1
|
||||
* \param p holds whether it's a permission fault if call returns 1
|
||||
*/
|
||||
bool in_fault(addr_t & va, addr_t & w) const
|
||||
bool in_fault(addr_t & va, addr_t & w, bool &p) const
|
||||
{
|
||||
/* permission fault on page, 2nd level */
|
||||
static constexpr Fsr::access_t permission = 0b1111;
|
||||
@ -208,11 +209,19 @@ class Genode::Cpu : public Arm_v7_cpu
|
||||
{
|
||||
/* check if fault was caused by a translation miss */
|
||||
Fsr::access_t const fs = Fsr::Fs::get(Ifsr::read());
|
||||
if (fs == permission) {
|
||||
w = 0;
|
||||
va = regs->ip;
|
||||
p = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((fs & 0b11100) != 0b100) return false;
|
||||
|
||||
/* fetch fault data */
|
||||
w = 0;
|
||||
va = regs->ip;
|
||||
p = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -227,6 +236,7 @@ class Genode::Cpu : public Arm_v7_cpu
|
||||
Dfsr::access_t const dfsr = Dfsr::read();
|
||||
w = Dfsr::Wnr::get(dfsr);
|
||||
va = Dfar::read();
|
||||
p = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -240,6 +240,8 @@ class Hw::Long_translation_table
|
||||
|
||||
struct Privileged_execute_never : Base::template Bitfield<53,1> { };
|
||||
|
||||
struct Execute_never : Base::template Bitfield<54,1> { };
|
||||
|
||||
static typename Descriptor::access_t create(Page_flags const &f,
|
||||
addr_t const pa)
|
||||
{
|
||||
@ -250,7 +252,8 @@ class Hw::Long_translation_table
|
||||
Base::Shareability::OUTER_SHAREABLE)
|
||||
| Base::Output_address::masked(pa)
|
||||
| Base::Access_flag::bits(1)
|
||||
| Descriptor::Valid::bits(1);
|
||||
| Descriptor::Valid::bits(1)
|
||||
| Execute_never::bits(!f.executable);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@ if {[have_spec linux]} {
|
||||
proc non_executable_supported { } {
|
||||
|
||||
if {[have_spec hw] && [have_spec x86_64]} { return true }
|
||||
if {[have_spec hw] && [have_spec arm]} { return true }
|
||||
if {[have_spec nova] && [have_spec x86_64]} { return true }
|
||||
if {[have_spec foc] && [have_spec x86_64]} { return true }
|
||||
if {[have_spec foc] && [have_spec arm]} { return true }
|
||||
|
Loading…
x
Reference in New Issue
Block a user