]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
arm: ignore writes to the ACTLR register
authorJean-Philippe Brucker <jean-philippe.brucker@arm.com>
Fri, 1 Aug 2014 16:00:34 +0000 (17:00 +0100)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 19 Dec 2014 10:04:07 +0000 (11:04 +0100)
The Auxiliary Control Register may be used on some platforms to disable
memory coherency between the cores, for instance when unplugging a CPU.
This patch ensures that ACTLR is never modified, by trapping its accesses
with the HCR.TAC bit.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/arm/control.c
hypervisor/arch/arm/setup.c
hypervisor/arch/arm/traps.c

index 47acf4ac036400376705da01764bf3ffd94190a8..71df67ba8252cf5481df47d9497d995882ab48c2 100644 (file)
@@ -56,7 +56,6 @@ static void arch_reset_el1(struct registers *regs)
        arm_read_sysreg(SCTLR_EL1, sctlr);
        sctlr = sctlr & ~SCTLR_MASK;
        arm_write_sysreg(SCTLR_EL1, sctlr);
-       arm_write_sysreg(ACTLR_EL1, 0);
        arm_write_sysreg(CPACR_EL1, 0);
        arm_write_sysreg(CONTEXTIDR_EL1, 0);
        arm_write_sysreg(PAR_EL1, 0);
index c11b8aa927b65789c0d4a3958a2bf912a76b6bc9..279b7037adf44a961f1eba97396b918e50cf3186 100644 (file)
@@ -60,7 +60,7 @@ int arch_cpu_init(struct per_cpu *cpu_data)
 {
        int err = 0;
        unsigned long hcr = HCR_VM_BIT | HCR_IMO_BIT | HCR_FMO_BIT
-                         | HCR_TSC_BIT;
+                         | HCR_TSC_BIT | HCR_TAC_BIT;
 
        cpu_data->psci_mbox.entry = 0;
        cpu_data->virt_id = cpu_data->cpu_id;
index d88dc7f542ed34b351a88e9399d63267f02026b5..b0bd0299caccd42589dc22206f507a7477507c87 100644 (file)
@@ -231,6 +231,30 @@ static int arch_handle_hvc(struct per_cpu *cpu_data, struct trap_context *ctx)
        return TRAP_HANDLED;
 }
 
+static int arch_handle_cp15_32(struct per_cpu *cpu_data, struct trap_context *ctx)
+{
+       u32 opc2        = ctx->esr >> 17 & 0x7;
+       u32 opc1        = ctx->esr >> 14 & 0x7;
+       u32 crn         = ctx->esr >> 10 & 0xf;
+       u32 rt          = ctx->esr >> 5 & 0xf;
+       u32 crm         = ctx->esr >> 1 & 0xf;
+       u32 read        = ctx->esr & 1;
+
+       if (opc1 == 0 && crn == 1 && crm == 0 && opc2 == 1) {
+               /* Do not let the guest disable coherency by writing ACTLR... */
+               if (read) {
+                       unsigned long val;
+                       arm_read_sysreg(ACTLR_EL1, val);
+                       access_cell_reg(ctx, rt, &val, false);
+               }
+               arch_skip_instruction(ctx);
+
+               return TRAP_HANDLED;
+       }
+
+       return TRAP_UNHANDLED;
+}
+
 static int arch_handle_cp15_64(struct per_cpu *cpu_data, struct trap_context *ctx)
 {
        unsigned long rt_val, rt2_val;
@@ -263,6 +287,7 @@ static int arch_handle_cp15_64(struct per_cpu *cpu_data, struct trap_context *ct
 
 static const trap_handler trap_handlers[38] =
 {
+       [ESR_EC_CP15_32]        = arch_handle_cp15_32,
        [ESR_EC_CP15_64]        = arch_handle_cp15_64,
        [ESR_EC_HVC]            = arch_handle_hvc,
        [ESR_EC_SMC]            = arch_handle_smc,