[PATCH 3/7] ARM: KVM: Turn L2CTLR and ACTLR into proper registers.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This means we generate the value at reset time.  ACTLR already had a spot
in the cp15 array (unused), but L2CTLR needs a new one.

In particular, this means that qemu must create all the registers before
calling KVM_SET_SREGS to set the target.

Signed-off-by: Rusty Russell <rusty.russell@xxxxxxxxxx>

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 91e40e7..045eb3a 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -90,6 +90,7 @@ enum cp15_regs {
 	c5_AIFSR,		/* Auxilary Instruction Fault Status Register */
 	c6_DFAR,		/* Data Fault Address Register */
 	c6_IFAR,		/* Instruction Fault Address Register */
+	c9_L2CTLR,		/* Cortex A15 L2 Control Register */
 	c10_PRRR,		/* Primary Region Remap Register */
 	c10_NMRR,		/* Normal Memory Remap Register */
 	c12_VBAR,		/* Vector Base Address Register */
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index fd5b515..8724c3f 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -127,17 +127,23 @@ static bool access_l2ctlr(struct kvm_vcpu *vcpu,
 			  const struct coproc_params *p,
 			  const struct coproc_reg *r)
 {
-	u32 l2ctlr, ncores;
-
 	if (p->is_write)
 		return ignore_write(vcpu, p, false);
 
+	*vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c9_L2CTLR];
+	return true;
+}
+
+static void reset_l2ctlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
+{
+	u32 l2ctlr, ncores;
+
 	asm volatile("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
 	l2ctlr &= ~(3 << 24);
 	ncores = atomic_read(&vcpu->kvm->online_vcpus) - 1;
 	l2ctlr |= (ncores & 3) << 24;
-	*vcpu_reg(vcpu, p->Rt1) = l2ctlr;
-	return true;
+
+	vcpu->arch.cp15[c9_L2CTLR] = l2ctlr;
 }
 
 /* A15 TRM 4.3.49: R/O WI (even if NSACR.NS_L2ERR, a write of 1 is ignored). */
@@ -167,11 +173,18 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
 			 const struct coproc_params *p,
 			 const struct coproc_reg *r)
 {
-	u32 actlr;
-
 	if (p->is_write)
 		return ignore_write(vcpu, p, false);
 
+	*vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c1_ACTLR];
+	return true;
+}
+
+static void reset_actlr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
+{
+	u32 actlr;
+
+	/* ACTLR contains SMP bit: make sure you create all cpus first! */
 	asm volatile("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
 	/* Make the SMP bit consistent with the guest configuration */
 	if (atomic_read(&vcpu->kvm->online_vcpus) > 1)
@@ -179,8 +192,7 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
 	else
 		actlr &= ~(1U << 6);
 
-	*vcpu_reg(vcpu, p->Rt1) = actlr;
-	return true;
+	vcpu->arch.cp15[c1_ACTLR] = actlr;
 }
 
 /* See note at ARM ARM B1.14.4 */
@@ -375,15 +387,17 @@ static const struct coproc_reg cp15_cortex_a15_regs[] = {
 	{ CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32,
 			NULL, reset_val, c1_SCTLR, 0x00C50078 },
 	/* ACTLR: trapped by HCR.TAC bit. */
-	{ CRn( 1), CRm( 0), Op1( 0), Op2( 1), is32, access_actlr},
+	{ CRn( 1), CRm( 0), Op1( 0), Op2( 1), is32,
+			access_actlr, reset_actlr, c1_ACTLR },
 	/* CPACR: swapped by interrupt.S. */
 	{ CRn( 1), CRm( 0), Op1( 0), Op2( 2), is32,
 			NULL, reset_val, c1_CPACR, 0x00000000 },
 
 	/*
 	 * L2CTLR access (guest wants to know #CPUs).
 	 */
-	{ CRn( 9), CRm( 0), Op1( 1), Op2( 2), is32, access_l2ctlr},
+	{ CRn( 9), CRm( 0), Op1( 1), Op2( 2), is32,
+			access_l2ctlr, reset_l2ctlr, c9_L2CTLR },
 	{ CRn( 9), CRm( 0), Op1( 1), Op2( 3), is32, access_l2ectlr},
 
 	/* The Configuration Base Address Register. */
_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux