xen/arm: Trap the ACTLR register

On Cortex-A15 ACTLR is used to set the SMP bit. If the guest has the control on
this register, it can disable SMP support and so TLB broadcast.

Implement the access to ACTRL as read-only register with SMP bit set to one
if the guest has multiple VCPUs.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Julien Grall authored and Ian Campbell committed 2013-07-17 16:55:24 +01:00
1 parent 8f46b1cb99
commit d4435fe5e2
2 files changed
+14 -3

No files matched your search

+7 -2
View File
@@ -28,6 +28,7 @@
#include <asm/irq.h>
#include <asm/cpufeature.h>
#include <asm/vfp.h>
#include <asm/processor-ca15.h>
#include <asm/gic.h>
#include "vtimer.h"
@@ -61,7 +62,6 @@ static void ctxt_switch_from(struct vcpu *p)
p->arch.csselr = READ_SYSREG(CSSELR_EL1);
/* Control Registers */
p->arch.actlr = READ_SYSREG(ACTLR_EL1);
p->arch.sctlr = READ_SYSREG(SCTLR_EL1);
p->arch.cpacr = READ_SYSREG(CPACR_EL1);
@@ -182,7 +182,6 @@ static void ctxt_switch_to(struct vcpu *n)
isb();
/* Control Registers */
WRITE_SYSREG(n->arch.actlr, ACTLR_EL1);
WRITE_SYSREG(n->arch.sctlr, SCTLR_EL1);
WRITE_SYSREG(n->arch.cpacr, CPACR_EL1);
@@ -452,6 +451,12 @@ int vcpu_initialise(struct vcpu *v)
return rc;
v->arch.sctlr = SCTLR_BASE;
v->arch.actlr = READ_SYSREG32(ACTLR_EL1);
/* XXX: Handle other than CA15 cpus */
if ( v->domain->max_vcpus > 1 )
v->arch.actlr |= ACTLR_CA15_SMP;
else
v->arch.actlr &= ~ACTLR_CA15_SMP;
if ( (rc = vcpu_vgic_init(v)) != 0 )
return rc;
+7 -1
View File
@@ -62,7 +62,8 @@ void __cpuinit init_traps(void)
WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);
/* Setup hypervisor traps */
WRITE_SYSREG(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_VM|HCR_TWI|HCR_TSC, HCR_EL2);
WRITE_SYSREG(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_VM|HCR_TWI|HCR_TSC|
HCR_TAC, HCR_EL2);
isb();
}
@@ -836,6 +837,7 @@ static void do_cp15_32(struct cpu_user_regs *regs,
{
struct hsr_cp32 cp32 = hsr.cp32;
uint32_t *r = (uint32_t*)select_user_reg(regs, cp32.reg);
struct vcpu *v = current;
if ( !cp32.ccvalid ) {
dprintk(XENLOG_ERR, "cp_15(32): need to handle invalid condition codes\n");
@@ -889,6 +891,10 @@ static void do_cp15_32(struct cpu_user_regs *regs,
domain_crash_synchronous();
}
break;
case HSR_CPREG32(ACTLR):
if ( cp32.read )
*r = v->arch.actlr;
break;
default:
printk("%s p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
cp32.read ? "mrc" : "mcr",
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.