From 1c11099f09a9524b1899b713691ae5978c22833a Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 4 Jul 2014 11:47:41 +0200 Subject: [PATCH] hw: clean cache lines of altered translation table For Cortex A8, and ARM1176JZF clean cache lines of altered MMU translation tables. Fix #1194 --- .../src/core/arm/short_translation_table.h | 15 +++++++++++++++ repos/base-hw/src/core/processor_driver/arm.h | 6 ++++++ repos/base-hw/src/core/processor_driver/arm_v6.h | 14 ++++++++++++++ .../src/core/processor_driver/cortex_a15.h | 6 ++++++ .../base-hw/src/core/processor_driver/cortex_a8.h | 14 ++++++++++++++ .../base-hw/src/core/processor_driver/cortex_a9.h | 6 ++++++ .../include/platform/imx53/drivers/board_base.h | 2 +- .../include/platform/rpi/drivers/board_base.h | 2 +- 8 files changed, 63 insertions(+), 2 deletions(-) diff --git a/repos/base-hw/src/core/arm/short_translation_table.h b/repos/base-hw/src/core/arm/short_translation_table.h index 64a153b8af..85831224b1 100644 --- a/repos/base-hw/src/core/arm/short_translation_table.h +++ b/repos/base-hw/src/core/arm/short_translation_table.h @@ -272,6 +272,11 @@ class Arm::Section_table /* compose new descriptor value */ _entries[i] = Small_page::create(flags, pa); + + /* some processors need to act on changed translations */ + using Cpu = Genode::Processor_driver; + Cpu::translation_added((addr_t)&_entries[i], + sizeof(Descriptor::access_t)); } } @@ -510,6 +515,11 @@ class Arm::Section_table Page_table * pt_phys = (Page_table*) slab->phys_addr(pt); pt_phys = pt_phys ? pt_phys : pt; /* hack for core */ _entries[i] = Page_table_descriptor::create(pt_phys); + + /* some processors need to act on changed translations */ + using Cpu = Genode::Processor_driver; + Cpu::translation_added((addr_t)&_entries[i], + sizeof(Descriptor::access_t)); } case Descriptor::PAGE_TABLE: @@ -597,6 +607,11 @@ class Arm::Section_table _entries[i] != Section::create(flags, pa)) throw Double_insertion(); _entries[i] = Section::create(flags, pa); + + /* some processors need to act on changed translations */ + using Cpu = Genode::Processor_driver; + Cpu::translation_added((addr_t)&_entries[i], + sizeof(Descriptor::access_t)); break; } diff --git a/repos/base-hw/src/core/processor_driver/arm.h b/repos/base-hw/src/core/processor_driver/arm.h index 280e363672..a19a9d1fcd 100644 --- a/repos/base-hw/src/core/processor_driver/arm.h +++ b/repos/base-hw/src/core/processor_driver/arm.h @@ -622,6 +622,12 @@ namespace Arm } }; + /** + * Returns true if current execution context is running in user mode + */ + inline static bool is_user() { + return Psr::M::get(Psr::read()) == Psr::M::USER; } + /** * Invalidate all entries of all instruction caches */ diff --git a/repos/base-hw/src/core/processor_driver/arm_v6.h b/repos/base-hw/src/core/processor_driver/arm_v6.h index 660670e7ee..80c8800c22 100644 --- a/repos/base-hw/src/core/processor_driver/arm_v6.h +++ b/repos/base-hw/src/core/processor_driver/arm_v6.h @@ -230,6 +230,20 @@ namespace Arm_v6 * Return wether to retry an undefined user instruction after this call */ bool retry_undefined_instr(Processor_lazy_state *) { return false; } + + /** + * The ARM1176JZF-S processor cannot page table walk from level one cache. + * Therefore, as the page-tables lie in write-back cacheable memory we've + * to clean the corresponding cache-lines even when a page table entry is added + */ + static void translation_added(Genode::addr_t addr, Genode::size_t size) + { + /* + * only clean lines as core, the kernel adds entries + * before MMU and caches are enabled + */ + if (is_user()) Kernel::update_data_region(addr, size); + } }; } diff --git a/repos/base-hw/src/core/processor_driver/cortex_a15.h b/repos/base-hw/src/core/processor_driver/cortex_a15.h index 9588b6c7bb..e928cef54a 100644 --- a/repos/base-hw/src/core/processor_driver/cortex_a15.h +++ b/repos/base-hw/src/core/processor_driver/cortex_a15.h @@ -49,6 +49,12 @@ namespace Cortex_a15 * Return wether to retry an undefined user instruction after this call */ bool retry_undefined_instr(Processor_lazy_state *) { return false; } + + /** + * After a page-fault resolution nothing needs to be done + */ + static void translation_added(Genode::addr_t addr, + Genode::size_t size) { } }; } diff --git a/repos/base-hw/src/core/processor_driver/cortex_a8.h b/repos/base-hw/src/core/processor_driver/cortex_a8.h index 957f145b08..5c0e89c0cf 100644 --- a/repos/base-hw/src/core/processor_driver/cortex_a8.h +++ b/repos/base-hw/src/core/processor_driver/cortex_a8.h @@ -44,6 +44,20 @@ namespace Cortex_a8 * Return wether to retry an undefined user instruction after this call */ bool retry_undefined_instr(Processor_lazy_state *) { return false; } + + /** + * The Cortex A8 processor cannot page table walk from level one cache. + * Therefore, as the page-tables lie in write-back cacheable memory we've + * to clean the corresponding cache-lines even when a page table entry is added + */ + static void translation_added(Genode::addr_t addr, Genode::size_t size) + { + /* + * only clean lines as core, the kernel adds entries + * before MMU and caches are enabled + */ + if (is_user()) Kernel::update_data_region(addr, size); + } }; } diff --git a/repos/base-hw/src/core/processor_driver/cortex_a9.h b/repos/base-hw/src/core/processor_driver/cortex_a9.h index 8613c161fe..b6ef6aa48c 100644 --- a/repos/base-hw/src/core/processor_driver/cortex_a9.h +++ b/repos/base-hw/src/core/processor_driver/cortex_a9.h @@ -290,6 +290,12 @@ class Cortex_a9::Processor_driver : public Arm_v7::Processor_driver } return true; } + + /** + * After a page-fault resolution nothing needs to be done + */ + static void translation_added(Genode::addr_t addr, + Genode::size_t size) { } }; diff --git a/repos/base/include/platform/imx53/drivers/board_base.h b/repos/base/include/platform/imx53/drivers/board_base.h index 82b0025fae..94e8c476ae 100644 --- a/repos/base/include/platform/imx53/drivers/board_base.h +++ b/repos/base/include/platform/imx53/drivers/board_base.h @@ -113,7 +113,7 @@ namespace Genode SECURITY_EXTENSION = 1, /* CPU cache */ - CACHE_LINE_SIZE_LOG2 = 2, /* FIXME get correct value from board spec */ + CACHE_LINE_SIZE_LOG2 = 6, }; }; } diff --git a/repos/base/include/platform/rpi/drivers/board_base.h b/repos/base/include/platform/rpi/drivers/board_base.h index f1b44e11c2..9c04d34517 100644 --- a/repos/base/include/platform/rpi/drivers/board_base.h +++ b/repos/base/include/platform/rpi/drivers/board_base.h @@ -57,7 +57,7 @@ namespace Genode SECURITY_EXTENSION = 0, /* CPU cache */ - CACHE_LINE_SIZE_LOG2 = 2, /* FIXME get correct value from board spec */ + CACHE_LINE_SIZE_LOG2 = 5, }; enum Videocore_cache_policy { NON_COHERENT = 0,