From: Dmitry Voytik <[email protected]>

Syncronize I-cache with D-cache after loading the hypervisor
image or a cell image. This must be done in arm64 according to
ARMv8 ARM spec. See page 1712, D3.4.6 "Non-cacheable accesses
and instruction caches".

This patch fixes coherency problems observed on real HW targets.
On x86 this operation is a NOP.

Signed-off-by: Dmitry Voytik <[email protected]>
Signed-off-by: Antonios Motakis <[email protected]>
[[email protected]: edited comments]
---
 driver/cell.c | 9 +++++++++
 driver/main.c | 9 +++++++++
 2 files changed, 18 insertions(+)

diff --git a/driver/cell.c b/driver/cell.c
index dc1b3c8..05ac7b2 100644
--- a/driver/cell.c
+++ b/driver/cell.c
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
 
 #include "cell.h"
 #include "main.h"
@@ -323,6 +324,14 @@ static int load_image(struct cell *cell,
                           (void __user *)(unsigned long)image.source_address,
                           image.size))
                err = -EFAULT;
+       /*
+        * ARMv8 requires to clean D-cache and invalidate I-cache for memory
+        * containing new instructions. On x86 this is a NOP. On ARMv7 the
+        * firmware does its own cache maintenance, so it is an
+        * extraneous (but harmless) flush.
+        */
+       flush_icache_range((unsigned long)(image_mem + page_offs),
+                          (unsigned long)(image_mem + page_offs) + image.size);
 
        vunmap(image_mem);
 
diff --git a/driver/main.c b/driver/main.c
index ec184af..13154e6 100644
--- a/driver/main.c
+++ b/driver/main.c
@@ -257,6 +257,15 @@ static int jailhouse_cmd_enable(struct jailhouse_system 
__user *arg)
        header = (struct jailhouse_header *)hypervisor_mem;
        header->max_cpus = max_cpus;
 
+       /*
+        * ARMv8 requires to clean D-cache and invalidate I-cache for memory
+        * containing new instructions. On x86 this is a NOP. On ARMv7 the
+        * firmware does its own cache maintenance, so it is an
+        * extraneous (but harmless) flush.
+        */
+       flush_icache_range((unsigned long)hypervisor_mem,
+                          (unsigned long)(hypervisor_mem + header->core_size));
+
        config = (struct jailhouse_system *)
                (hypervisor_mem + hv_core_and_percpu_size);
        if (copy_from_user(config, arg, config_size)) {
-- 
2.8.0.rc3


-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to