On Thu, Aug 16, 2012 at 10:56 AM, Marc Zyngier <marc.zyngier@xxxxxxx> wrote: > The MIDR register is used, among other things, to find out the > CPU revision, and select matching errata. > > Letting userspace set the MIDR register prevents the guest from > selecting errata that apply to the underlying CPU, with possibly > deadly consequences. > > Turn MIDR to an invariant register, and only expose the HW one > to the guest. We still keep it stored in a per-vcpu variable in > case we come up with a better scheme some day. > > Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx> > --- > arch/arm/include/asm/kvm_host.h | 6 ++++-- > arch/arm/kernel/asm-offsets.c | 2 +- > arch/arm/kvm/coproc.c | 5 ++--- > arch/arm/kvm/reset.c | 2 ++ > 4 files changed, 9 insertions(+), 6 deletions(-) > > diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h > index 3d4ce42..0956808 100644 > --- a/arch/arm/include/asm/kvm_host.h > +++ b/arch/arm/include/asm/kvm_host.h > @@ -95,8 +95,7 @@ struct kvm_vcpu_regs { > > /* 0 is reserved as an invalid value. */ > enum cp15_regs { > - c0_MIDR=1, /* Main ID Register */ > - c0_MPIDR, /* MultiProcessor ID Register */ > + c0_MPIDR=1, /* MultiProcessor ID Register */ > c1_SCTLR, /* System Control Register */ > c1_ACTLR, /* Auxilliary Control Register */ > c1_CPACR, /* Coprocessor Access Control */ > @@ -133,6 +132,9 @@ struct kvm_vcpu_arch { > /* System control coprocessor (cp15) */ > u32 cp15[nr_cp15_regs]; > > + /* The CPU type we expose to the VM */ > + u32 midr; > + > /* Exception Information */ > u32 hsr; /* Hyp Syndrom Register */ > u32 hdfar; /* Hyp Data Fault Address Register */ > diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c > index e8d8bba..76c373a 100644 > --- a/arch/arm/kernel/asm-offsets.c > +++ b/arch/arm/kernel/asm-offsets.c > @@ -147,7 +147,7 @@ int main(void) > DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE); > #ifdef CONFIG_KVM_ARM_HOST > DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm)); > - DEFINE(VCPU_MIDR, offsetof(struct kvm_vcpu, arch.cp15[c0_MIDR])); > + DEFINE(VCPU_MIDR, offsetof(struct kvm_vcpu, arch.midr)); > DEFINE(VCPU_MPIDR, offsetof(struct kvm_vcpu, arch.cp15[c0_MPIDR])); > DEFINE(VCPU_SCTLR, offsetof(struct kvm_vcpu, arch.cp15[c1_SCTLR])); > DEFINE(VCPU_CPACR, offsetof(struct kvm_vcpu, arch.cp15[c1_CPACR])); > diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c > index 89089fd..bd56dfb 100644 > --- a/arch/arm/kvm/coproc.c > +++ b/arch/arm/kvm/coproc.c > @@ -390,9 +390,6 @@ static const struct coproc_reg cp15_regs[] = { > * Important: Must sorted ascending by CRn, CRM, Op1, Op2 > */ > static const struct coproc_reg cp15_cortex_a15_regs[] = { > - /* MIDR: we use VPIDR for guest access. */ > - { CRn( 0), CRm( 0), Op1( 0), Op2( 0), is32, > - NULL, reset_val, c0_MIDR, 0x412FC0F0 }, > /* MPIDR: we use VMPIDR for guest access. */ > { CRn( 0), CRm( 0), Op1( 0), Op2( 5), is32, > NULL, reset_mpidr, c0_MPIDR }, > @@ -646,6 +643,7 @@ static const struct coproc_reg *index_to_coproc_reg(struct kvm_vcpu *vcpu, > ((struct coproc_reg *)r)->val = val; \ > } > > +FUNCTION_FOR32(0, 0, 0, 0, MIDR) > FUNCTION_FOR32(0, 0, 0, 1, CTR) > FUNCTION_FOR32(0, 0, 0, 2, TCMTR) > FUNCTION_FOR32(0, 0, 0, 3, TLBTR) > @@ -670,6 +668,7 @@ FUNCTION_FOR32(0, 0, 1, 7, AIDR) > > /* ->val is filled in by kvm_invariant_coproc_table_init() */ > static struct coproc_reg invariant_cp15[] = { > + { CRn( 0), CRm( 0), Op1( 0), Op2( 0), is32, NULL, get_MIDR }, > { CRn( 0), CRm( 0), Op1( 0), Op2( 1), is32, NULL, get_CTR }, > { CRn( 0), CRm( 0), Op1( 0), Op2( 2), is32, NULL, get_TCMTR }, > { CRn( 0), CRm( 0), Op1( 0), Op2( 3), is32, NULL, get_TLBTR }, > diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c > index 8eb0a56..33625c6 100644 > --- a/arch/arm/kvm/reset.c > +++ b/arch/arm/kvm/reset.c > @@ -23,6 +23,7 @@ > > #include <asm/unified.h> > #include <asm/ptrace.h> > +#include <asm/cputype.h> > #include <asm/kvm_arm.h> > > /****************************************************************************** > @@ -56,6 +57,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) > if (vcpu->vcpu_id > a15_max_cpu_idx) > return -EINVAL; > cpu_reset = &a15_regs_reset; > + vcpu->arch.midr = read_cpuid_id(); > break; > default: > return -ENODEV; > -- > 1.7.11.4 > Looks good, thanks. -Christoffer _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm