Re: [PATCH] ARM: KVM: Do not let userspace mess with MIDR

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

 



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


[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