[{"id":1796568,"web_url":"http://patchwork.ozlabs.org/comment/1796568/","msgid":"<874lqfinz7.fsf@linaro.org>","list_archive_url":null,"date":"2017-10-31T10:57:32","subject":"Re: [PATCH v4 02/28] arm64: KVM: Hide unsupported AArch64 CPU\n\tfeatures from guests","submitter":{"id":39532,"url":"http://patchwork.ozlabs.org/api/people/39532/","name":"Alex Bennée","email":"alex.bennee@linaro.org"},"content":"Dave Martin <Dave.Martin@arm.com> writes:\n\n> Currently, a guest kernel sees the true CPU feature registers\n> (ID_*_EL1) when it reads them using MRS instructions.  This means\n> that the guest may observe features that are present in the\n> hardware but the host doesn't understand or doesn't provide support\n> for.  A guest may legimitately try to use such a feature as per the\n> architecture, but use of the feature may trap instead of working\n> normally, triggering undef injection into the guest.\n>\n> This is not a problem for the host, but the guest may go wrong when\n> running on newer hardware than the host knows about.\n>\n> This patch hides from guest VMs any AArch64-specific CPU features\n> that the host doesn't support, by exposing to the guest the\n> sanitised versions of the registers computed by the cpufeatures\n> framework, instead of the true hardware registers.  To achieve\n> this, HCR_EL2.TID3 is now set for AArch64 guests, and emulation\n> code is added to KVM to report the sanitised versions of the\n> affected registers in response to MRS and register reads from\n> userspace.\n>\n> The affected registers are removed from invariant_sys_regs[] (since\n> the invariant_sys_regs handling is no longer quite correct for\n> them) and added to sys_reg_desgs[], with appropriate access(),\n> get_user() and set_user() methods.  No runtime vcpu storage is\n> allocated for the registers: instead, they are read on demand from\n> the cpufeatures framework.  This may need modification in the\n> future if there is a need for userspace to customise the features\n> visible to the guest.\n>\n> Attempts by userspace to write the registers are handled similarly\n> to the current invariant_sys_regs handling: writes are permitted,\n> but only if they don't attempt to change the value.  This is\n> sufficient to support VM snapshot/restore from userspace.\n>\n> Because of the additional registers, restoring a VM on an older\n> kernel may not work unless userspace knows how to handle the extra\n> VM registers exposed to the KVM user ABI by this patch.\n>\n> Under the principle of least damage, this patch makes no attempt to\n> handle any of the other registers currently in\n> invariant_sys_regs[], or to emulate registers for AArch32: however,\n> these could be handled in a similar way in future, as necessary.\n>\n> Signed-off-by: Dave Martin <Dave.Martin@arm.com>\n> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>\n> Acked-by: Catalin Marinas <catalin.marinas@arm.com>\n> Cc: Christoffer Dall <christoffer.dall@linaro.org>\n\nReviewed-by: Alex Bennée <alex.bennee@linaro.org>\n\n> ---\n>  arch/arm64/include/asm/sysreg.h |   3 +\n>  arch/arm64/kvm/hyp/switch.c     |   6 +\n>  arch/arm64/kvm/sys_regs.c       | 282 +++++++++++++++++++++++++++++++++-------\n>  3 files changed, 246 insertions(+), 45 deletions(-)\n>\n> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h\n> index 4dceb12..609d59af 100644\n> --- a/arch/arm64/include/asm/sysreg.h\n> +++ b/arch/arm64/include/asm/sysreg.h\n> @@ -149,6 +149,9 @@\n>  #define SYS_ID_AA64DFR0_EL1\t\tsys_reg(3, 0, 0, 5, 0)\n>  #define SYS_ID_AA64DFR1_EL1\t\tsys_reg(3, 0, 0, 5, 1)\n>\n> +#define SYS_ID_AA64AFR0_EL1\t\tsys_reg(3, 0, 0, 5, 4)\n> +#define SYS_ID_AA64AFR1_EL1\t\tsys_reg(3, 0, 0, 5, 5)\n> +\n>  #define SYS_ID_AA64ISAR0_EL1\t\tsys_reg(3, 0, 0, 6, 0)\n>  #define SYS_ID_AA64ISAR1_EL1\t\tsys_reg(3, 0, 0, 6, 1)\n>\n> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c\n> index 945e79c..35a90b8 100644\n> --- a/arch/arm64/kvm/hyp/switch.c\n> +++ b/arch/arm64/kvm/hyp/switch.c\n> @@ -81,11 +81,17 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)\n>  \t * it will cause an exception.\n>  \t */\n>  \tval = vcpu->arch.hcr_el2;\n> +\n>  \tif (!(val & HCR_RW) && system_supports_fpsimd()) {\n>  \t\twrite_sysreg(1 << 30, fpexc32_el2);\n>  \t\tisb();\n>  \t}\n> +\n> +\tif (val & HCR_RW) /* for AArch64 only: */\n> +\t\tval |= HCR_TID3; /* TID3: trap feature register accesses */\n> +\n>  \twrite_sysreg(val, hcr_el2);\n> +\n>  \t/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */\n>  \twrite_sysreg(1 << 15, hstr_el2);\n>  \t/*\n> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c\n> index 2e070d3..b1f7552 100644\n> --- a/arch/arm64/kvm/sys_regs.c\n> +++ b/arch/arm64/kvm/sys_regs.c\n> @@ -892,6 +892,137 @@ static bool access_cntp_cval(struct kvm_vcpu *vcpu,\n>  \treturn true;\n>  }\n>\n> +/* Read a sanitised cpufeature ID register by sys_reg_desc */\n> +static u64 read_id_reg(struct sys_reg_desc const *r, bool raz)\n> +{\n> +\tu32 id = sys_reg((u32)r->Op0, (u32)r->Op1,\n> +\t\t\t (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);\n> +\n> +\treturn raz ? 0 : read_sanitised_ftr_reg(id);\n> +}\n> +\n> +/* cpufeature ID register access trap handlers */\n> +\n> +static bool __access_id_reg(struct kvm_vcpu *vcpu,\n> +\t\t\t    struct sys_reg_params *p,\n> +\t\t\t    const struct sys_reg_desc *r,\n> +\t\t\t    bool raz)\n> +{\n> +\tif (p->is_write)\n> +\t\treturn write_to_read_only(vcpu, p, r);\n> +\n> +\tp->regval = read_id_reg(r, raz);\n> +\treturn true;\n> +}\n> +\n> +static bool access_id_reg(struct kvm_vcpu *vcpu,\n> +\t\t\t  struct sys_reg_params *p,\n> +\t\t\t  const struct sys_reg_desc *r)\n> +{\n> +\treturn __access_id_reg(vcpu, p, r, false);\n> +}\n> +\n> +static bool access_raz_id_reg(struct kvm_vcpu *vcpu,\n> +\t\t\t      struct sys_reg_params *p,\n> +\t\t\t      const struct sys_reg_desc *r)\n> +{\n> +\treturn __access_id_reg(vcpu, p, r, true);\n> +}\n> +\n> +static int reg_from_user(u64 *val, const void __user *uaddr, u64 id);\n> +static int reg_to_user(void __user *uaddr, const u64 *val, u64 id);\n> +static u64 sys_reg_to_index(const struct sys_reg_desc *reg);\n> +\n> +/*\n> + * cpufeature ID register user accessors\n> + *\n> + * For now, these registers are immutable for userspace, so no values\n> + * are stored, and for set_id_reg() we don't allow the effective value\n> + * to be changed.\n> + */\n> +static int __get_id_reg(const struct sys_reg_desc *rd, void __user *uaddr,\n> +\t\t\tbool raz)\n> +{\n> +\tconst u64 id = sys_reg_to_index(rd);\n> +\tconst u64 val = read_id_reg(rd, raz);\n> +\n> +\treturn reg_to_user(uaddr, &val, id);\n> +}\n> +\n> +static int __set_id_reg(const struct sys_reg_desc *rd, void __user *uaddr,\n> +\t\t\tbool raz)\n> +{\n> +\tconst u64 id = sys_reg_to_index(rd);\n> +\tint err;\n> +\tu64 val;\n> +\n> +\terr = reg_from_user(&val, uaddr, id);\n> +\tif (err)\n> +\t\treturn err;\n> +\n> +\t/* This is what we mean by invariant: you can't change it. */\n> +\tif (val != read_id_reg(rd, raz))\n> +\t\treturn -EINVAL;\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int get_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,\n> +\t\t      const struct kvm_one_reg *reg, void __user *uaddr)\n> +{\n> +\treturn __get_id_reg(rd, uaddr, false);\n> +}\n> +\n> +static int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,\n> +\t\t      const struct kvm_one_reg *reg, void __user *uaddr)\n> +{\n> +\treturn __set_id_reg(rd, uaddr, false);\n> +}\n> +\n> +static int get_raz_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,\n> +\t\t\t  const struct kvm_one_reg *reg, void __user *uaddr)\n> +{\n> +\treturn __get_id_reg(rd, uaddr, true);\n> +}\n> +\n> +static int set_raz_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,\n> +\t\t\t  const struct kvm_one_reg *reg, void __user *uaddr)\n> +{\n> +\treturn __set_id_reg(rd, uaddr, true);\n> +}\n> +\n> +/* sys_reg_desc initialiser for known cpufeature ID registers */\n> +#define ID_SANITISED(name) {\t\t\t\\\n> +\tSYS_DESC(SYS_##name),\t\t\t\\\n> +\t.access\t= access_id_reg,\t\t\\\n> +\t.get_user = get_id_reg,\t\t\t\\\n> +\t.set_user = set_id_reg,\t\t\t\\\n> +}\n> +\n> +/*\n> + * sys_reg_desc initialiser for architecturally unallocated cpufeature ID\n> + * register with encoding Op0=3, Op1=0, CRn=0, CRm=crm, Op2=op2\n> + * (1 <= crm < 8, 0 <= Op2 < 8).\n> + */\n> +#define ID_UNALLOCATED(crm, op2) {\t\t\t\\\n> +\tOp0(3), Op1(0), CRn(0), CRm(crm), Op2(op2),\t\\\n> +\t.access = access_raz_id_reg,\t\t\t\\\n> +\t.get_user = get_raz_id_reg,\t\t\t\\\n> +\t.set_user = set_raz_id_reg,\t\t\t\\\n> +}\n> +\n> +/*\n> + * sys_reg_desc initialiser for known ID registers that we hide from guests.\n> + * For now, these are exposed just like unallocated ID regs: they appear\n> + * RAZ for the guest.\n> + */\n> +#define ID_HIDDEN(name) {\t\t\t\\\n> +\tSYS_DESC(SYS_##name),\t\t\t\\\n> +\t.access = access_raz_id_reg,\t\t\\\n> +\t.get_user = get_raz_id_reg,\t\t\\\n> +\t.set_user = set_raz_id_reg,\t\t\\\n> +}\n> +\n>  /*\n>   * Architected system registers.\n>   * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2\n> @@ -944,6 +1075,84 @@ static const struct sys_reg_desc sys_reg_descs[] = {\n>  \t{ SYS_DESC(SYS_DBGVCR32_EL2), NULL, reset_val, DBGVCR32_EL2, 0 },\n>\n>  \t{ SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1 },\n> +\n> +\t/*\n> +\t * ID regs: all ID_SANITISED() entries here must have corresponding\n> +\t * entries in arm64_ftr_regs[].\n> +\t */\n> +\n> +\t/* AArch64 mappings of the AArch32 ID registers */\n> +\t/* CRm=1 */\n> +\tID_SANITISED(ID_PFR0_EL1),\n> +\tID_SANITISED(ID_PFR1_EL1),\n> +\tID_SANITISED(ID_DFR0_EL1),\n> +\tID_HIDDEN(ID_AFR0_EL1),\n> +\tID_SANITISED(ID_MMFR0_EL1),\n> +\tID_SANITISED(ID_MMFR1_EL1),\n> +\tID_SANITISED(ID_MMFR2_EL1),\n> +\tID_SANITISED(ID_MMFR3_EL1),\n> +\n> +\t/* CRm=2 */\n> +\tID_SANITISED(ID_ISAR0_EL1),\n> +\tID_SANITISED(ID_ISAR1_EL1),\n> +\tID_SANITISED(ID_ISAR2_EL1),\n> +\tID_SANITISED(ID_ISAR3_EL1),\n> +\tID_SANITISED(ID_ISAR4_EL1),\n> +\tID_SANITISED(ID_ISAR5_EL1),\n> +\tID_SANITISED(ID_MMFR4_EL1),\n> +\tID_UNALLOCATED(2,7),\n> +\n> +\t/* CRm=3 */\n> +\tID_SANITISED(MVFR0_EL1),\n> +\tID_SANITISED(MVFR1_EL1),\n> +\tID_SANITISED(MVFR2_EL1),\n> +\tID_UNALLOCATED(3,3),\n> +\tID_UNALLOCATED(3,4),\n> +\tID_UNALLOCATED(3,5),\n> +\tID_UNALLOCATED(3,6),\n> +\tID_UNALLOCATED(3,7),\n> +\n> +\t/* AArch64 ID registers */\n> +\t/* CRm=4 */\n> +\tID_SANITISED(ID_AA64PFR0_EL1),\n> +\tID_SANITISED(ID_AA64PFR1_EL1),\n> +\tID_UNALLOCATED(4,2),\n> +\tID_UNALLOCATED(4,3),\n> +\tID_UNALLOCATED(4,4),\n> +\tID_UNALLOCATED(4,5),\n> +\tID_UNALLOCATED(4,6),\n> +\tID_UNALLOCATED(4,7),\n> +\n> +\t/* CRm=5 */\n> +\tID_SANITISED(ID_AA64DFR0_EL1),\n> +\tID_SANITISED(ID_AA64DFR1_EL1),\n> +\tID_UNALLOCATED(5,2),\n> +\tID_UNALLOCATED(5,3),\n> +\tID_HIDDEN(ID_AA64AFR0_EL1),\n> +\tID_HIDDEN(ID_AA64AFR1_EL1),\n> +\tID_UNALLOCATED(5,6),\n> +\tID_UNALLOCATED(5,7),\n> +\n> +\t/* CRm=6 */\n> +\tID_SANITISED(ID_AA64ISAR0_EL1),\n> +\tID_SANITISED(ID_AA64ISAR1_EL1),\n> +\tID_UNALLOCATED(6,2),\n> +\tID_UNALLOCATED(6,3),\n> +\tID_UNALLOCATED(6,4),\n> +\tID_UNALLOCATED(6,5),\n> +\tID_UNALLOCATED(6,6),\n> +\tID_UNALLOCATED(6,7),\n> +\n> +\t/* CRm=7 */\n> +\tID_SANITISED(ID_AA64MMFR0_EL1),\n> +\tID_SANITISED(ID_AA64MMFR1_EL1),\n> +\tID_SANITISED(ID_AA64MMFR2_EL1),\n> +\tID_UNALLOCATED(7,3),\n> +\tID_UNALLOCATED(7,4),\n> +\tID_UNALLOCATED(7,5),\n> +\tID_UNALLOCATED(7,6),\n> +\tID_UNALLOCATED(7,7),\n> +\n>  \t{ SYS_DESC(SYS_SCTLR_EL1), access_vm_reg, reset_val, SCTLR_EL1, 0x00C50078 },\n>  \t{ SYS_DESC(SYS_CPACR_EL1), NULL, reset_val, CPACR_EL1, 0 },\n>  \t{ SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },\n> @@ -1790,8 +1999,8 @@ static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu,\n>  \tif (!r)\n>  \t\tr = find_reg(&params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));\n>\n> -\t/* Not saved in the sys_reg array? */\n> -\tif (r && !r->reg)\n> +\t/* Not saved in the sys_reg array and not otherwise accessible? */\n> +\tif (r && !(r->reg || r->get_user))\n>  \t\tr = NULL;\n>\n>  \treturn r;\n> @@ -1815,20 +2024,6 @@ static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu,\n>  FUNCTION_INVARIANT(midr_el1)\n>  FUNCTION_INVARIANT(ctr_el0)\n>  FUNCTION_INVARIANT(revidr_el1)\n> -FUNCTION_INVARIANT(id_pfr0_el1)\n> -FUNCTION_INVARIANT(id_pfr1_el1)\n> -FUNCTION_INVARIANT(id_dfr0_el1)\n> -FUNCTION_INVARIANT(id_afr0_el1)\n> -FUNCTION_INVARIANT(id_mmfr0_el1)\n> -FUNCTION_INVARIANT(id_mmfr1_el1)\n> -FUNCTION_INVARIANT(id_mmfr2_el1)\n> -FUNCTION_INVARIANT(id_mmfr3_el1)\n> -FUNCTION_INVARIANT(id_isar0_el1)\n> -FUNCTION_INVARIANT(id_isar1_el1)\n> -FUNCTION_INVARIANT(id_isar2_el1)\n> -FUNCTION_INVARIANT(id_isar3_el1)\n> -FUNCTION_INVARIANT(id_isar4_el1)\n> -FUNCTION_INVARIANT(id_isar5_el1)\n>  FUNCTION_INVARIANT(clidr_el1)\n>  FUNCTION_INVARIANT(aidr_el1)\n>\n> @@ -1836,20 +2031,6 @@ FUNCTION_INVARIANT(aidr_el1)\n>  static struct sys_reg_desc invariant_sys_regs[] = {\n>  \t{ SYS_DESC(SYS_MIDR_EL1), NULL, get_midr_el1 },\n>  \t{ SYS_DESC(SYS_REVIDR_EL1), NULL, get_revidr_el1 },\n> -\t{ SYS_DESC(SYS_ID_PFR0_EL1), NULL, get_id_pfr0_el1 },\n> -\t{ SYS_DESC(SYS_ID_PFR1_EL1), NULL, get_id_pfr1_el1 },\n> -\t{ SYS_DESC(SYS_ID_DFR0_EL1), NULL, get_id_dfr0_el1 },\n> -\t{ SYS_DESC(SYS_ID_AFR0_EL1), NULL, get_id_afr0_el1 },\n> -\t{ SYS_DESC(SYS_ID_MMFR0_EL1), NULL, get_id_mmfr0_el1 },\n> -\t{ SYS_DESC(SYS_ID_MMFR1_EL1), NULL, get_id_mmfr1_el1 },\n> -\t{ SYS_DESC(SYS_ID_MMFR2_EL1), NULL, get_id_mmfr2_el1 },\n> -\t{ SYS_DESC(SYS_ID_MMFR3_EL1), NULL, get_id_mmfr3_el1 },\n> -\t{ SYS_DESC(SYS_ID_ISAR0_EL1), NULL, get_id_isar0_el1 },\n> -\t{ SYS_DESC(SYS_ID_ISAR1_EL1), NULL, get_id_isar1_el1 },\n> -\t{ SYS_DESC(SYS_ID_ISAR2_EL1), NULL, get_id_isar2_el1 },\n> -\t{ SYS_DESC(SYS_ID_ISAR3_EL1), NULL, get_id_isar3_el1 },\n> -\t{ SYS_DESC(SYS_ID_ISAR4_EL1), NULL, get_id_isar4_el1 },\n> -\t{ SYS_DESC(SYS_ID_ISAR5_EL1), NULL, get_id_isar5_el1 },\n>  \t{ SYS_DESC(SYS_CLIDR_EL1), NULL, get_clidr_el1 },\n>  \t{ SYS_DESC(SYS_AIDR_EL1), NULL, get_aidr_el1 },\n>  \t{ SYS_DESC(SYS_CTR_EL0), NULL, get_ctr_el0 },\n> @@ -2079,12 +2260,31 @@ static bool copy_reg_to_user(const struct sys_reg_desc *reg, u64 __user **uind)\n>  \treturn true;\n>  }\n>\n> +static int walk_one_sys_reg(const struct sys_reg_desc *rd,\n> +\t\t\t    u64 __user **uind,\n> +\t\t\t    unsigned int *total)\n> +{\n> +\t/*\n> +\t * Ignore registers we trap but don't save,\n> +\t * and for which no custom user accessor is provided.\n> +\t */\n> +\tif (!(rd->reg || rd->get_user))\n> +\t\treturn 0;\n> +\n> +\tif (!copy_reg_to_user(rd, uind))\n> +\t\treturn -EFAULT;\n> +\n> +\t(*total)++;\n> +\treturn 0;\n> +}\n> +\n>  /* Assumed ordered tables, see kvm_sys_reg_table_init. */\n>  static int walk_sys_regs(struct kvm_vcpu *vcpu, u64 __user *uind)\n>  {\n>  \tconst struct sys_reg_desc *i1, *i2, *end1, *end2;\n>  \tunsigned int total = 0;\n>  \tsize_t num;\n> +\tint err;\n>\n>  \t/* We check for duplicates here, to allow arch-specific overrides. */\n>  \ti1 = get_target_table(vcpu->arch.target, true, &num);\n> @@ -2098,21 +2298,13 @@ static int walk_sys_regs(struct kvm_vcpu *vcpu, u64 __user *uind)\n>  \twhile (i1 || i2) {\n>  \t\tint cmp = cmp_sys_reg(i1, i2);\n>  \t\t/* target-specific overrides generic entry. */\n> -\t\tif (cmp <= 0) {\n> -\t\t\t/* Ignore registers we trap but don't save. */\n> -\t\t\tif (i1->reg) {\n> -\t\t\t\tif (!copy_reg_to_user(i1, &uind))\n> -\t\t\t\t\treturn -EFAULT;\n> -\t\t\t\ttotal++;\n> -\t\t\t}\n> -\t\t} else {\n> -\t\t\t/* Ignore registers we trap but don't save. */\n> -\t\t\tif (i2->reg) {\n> -\t\t\t\tif (!copy_reg_to_user(i2, &uind))\n> -\t\t\t\t\treturn -EFAULT;\n> -\t\t\t\ttotal++;\n> -\t\t\t}\n> -\t\t}\n> +\t\tif (cmp <= 0)\n> +\t\t\terr = walk_one_sys_reg(i1, &uind, &total);\n> +\t\telse\n> +\t\t\terr = walk_one_sys_reg(i2, &uind, &total);\n> +\n> +\t\tif (err)\n> +\t\t\treturn err;\n>\n>  \t\tif (cmp <= 0 && ++i1 == end1)\n>  \t\t\ti1 = NULL;\n\n\n--\nAlex Bennée","headers":{"Return-Path":"<libc-alpha-return-86568-incoming=patchwork.ozlabs.org@sourceware.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":["patchwork-incoming@bilbo.ozlabs.org","mailing list libc-alpha@sourceware.org"],"Authentication-Results":["ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=sourceware.org\n\t(client-ip=209.132.180.131; helo=sourceware.org;\n\tenvelope-from=libc-alpha-return-86568-incoming=patchwork.ozlabs.org@sourceware.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tsecure) header.d=sourceware.org header.i=@sourceware.org\n\theader.b=\"I7vVq2PB\"; dkim-atps=neutral","sourceware.org; auth=none"],"Received":["from sourceware.org (server1.sourceware.org [209.132.180.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3yR7bx55Tyz9t2l\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 31 Oct 2017 21:57:49 +1100 (AEDT)","(qmail 23635 invoked by alias); 31 Oct 2017 10:57:39 -0000","(qmail 22071 invoked by uid 89); 31 Oct 2017 10:57:38 -0000"],"DomainKey-Signature":"a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id\n\t:list-unsubscribe:list-subscribe:list-archive:list-post\n\t:list-help:sender:references:from:to:cc:subject:in-reply-to:date\n\t:message-id:mime-version:content-type:content-transfer-encoding;\n\tq=dns; s=default; b=BeXVIEK3hYi2loTAlutFEZrRxaU6WbYSY4h/SNCI7o6\n\t6tB+6lL0gQ/0WoifzqGMxgHls3cbMetQBfF51gm0p3wC6jKZ2GAiY5M8kkyKNbUb\n\tvL5yZn8X2jX2hE5s9NrRSt6ikt6IO73PhGJpTIYneGBZJMExl4nzU6nLOzdgSjnA\n\t=","DKIM-Signature":"v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id\n\t:list-unsubscribe:list-subscribe:list-archive:list-post\n\t:list-help:sender:references:from:to:cc:subject:in-reply-to:date\n\t:message-id:mime-version:content-type:content-transfer-encoding;\n\ts=default; bh=KsP3+zyLUkU7DzrtJPVdDsuqtnU=; b=I7vVq2PBHTDElZSKy\n\tTzPC0+vJ5roGbraGxbkSCt2L8zyHvpS+/eXNBHtk7mChZ92PBF3ZxQoDDrrQoxl2\n\tAhUAdLa6CyVvRgxcAMiWF3YYI9PW0pHDhXSXSoDJy6cyrNhpA8s4E5WgaWJ+nMH8\n\tdXOReLKfx3G6LxALhMArGCzzck=","Mailing-List":"contact libc-alpha-help@sourceware.org; run by ezmlm","Precedence":"bulk","List-Id":"<libc-alpha.sourceware.org>","List-Unsubscribe":"<mailto:libc-alpha-unsubscribe-incoming=patchwork.ozlabs.org@sourceware.org>","List-Subscribe":"<mailto:libc-alpha-subscribe@sourceware.org>","List-Archive":"<http://sourceware.org/ml/libc-alpha/>","List-Post":"<mailto:libc-alpha@sourceware.org>","List-Help":"<mailto:libc-alpha-help@sourceware.org>,\n\t<http://sourceware.org/ml/#faqs>","Sender":"libc-alpha-owner@sourceware.org","X-Virus-Found":"No","X-Spam-SWARE-Status":"No, score=-26.0 required=5.0 tests=AWL, BAYES_00,\n\tGIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3,\n\tRCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM,\n\tSPF_PASS autolearn=ham version=3.3.2 spammy=Important, MRS,\n\tcrm, Hx-spam-relays-external:74.125.82.66","X-HELO":"mail-wm0-f66.google.com","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:references:user-agent:from:to:cc:subject\n\t:in-reply-to:date:message-id:mime-version:content-transfer-encoding; \n\tbh=psYG7tgtemxOYP8w4tlfgmGuXZf6ngv0D9AOVQEewwI=;\n\tb=Mm6lb5OY5hTy9MxAyN0UEp/NTQHckQU8S8v68mcSLGxlpmImusdG/NgEAlnnCNr4rc\n\tPdIlYvaZ81jPdMgpizG0qSZIL3kY0U4iTXY3mgZQKdW9SGh0TFpoa99BfcBEGDwXBg/z\n\tjvpGFmR35VxdS+o5sFlMkjhGrvDns8XLFKGdlfHB6Sf+ssTgNIFSE0zx8tnisnOoJGs3\n\t3moeRwoYkEQIxl9b8tod0kMrnTfVpwTlQmMU+JTJGl6ZSzRBUXFhbkDbTGEYYUG9Y0za\n\ttunfYgyknlrMlH4Y0+iF71I5GEeKV4K0cKRtjREr9e15cA3cg0sgvrY5HK638sxLKHtU\n\tCZnA==","X-Gm-Message-State":"AMCzsaWI2oOpDwqtMb1a2QX4IMOr6f7PhJJ3fj0lEo6uUseB01atX70G\n\tQwZhHYznSMXmZeDjbZLVRu7vAw==","X-Google-Smtp-Source":"ABhQp+TzQdtUiEwcxdJQEe1Vea7/H+0RYahiWj3U+WDU0pldNqab7x/nkdqVGySbfFIzHwn0n7sFoQ==","X-Received":"by 10.28.30.151 with SMTP id e145mr352075wme.8.1509447453472;\n\tTue, 31 Oct 2017 03:57:33 -0700 (PDT)","References":"<1509101470-7881-1-git-send-email-Dave.Martin@arm.com>\n\t<1509101470-7881-3-git-send-email-Dave.Martin@arm.com>","User-agent":"mu4e 1.0-alpha0; emacs 26.0.90","From":"Alex =?utf-8?q?Benn=C3=A9e?= <alex.bennee@linaro.org>","To":"Dave Martin <Dave.Martin@arm.com>","Cc":"linux-arm-kernel@lists.infradead.org,\n\tCatalin Marinas <catalin.marinas@arm.com>,\n\tWill Deacon <will.deacon@arm.com>,\n\tArd Biesheuvel <ard.biesheuvel@linaro.org>,\n\tSzabolcs Nagy <szabolcs.nagy@arm.com>,\n\tOkamoto Takayuki <tokamoto@jp.fujitsu.com>,\n\tkvmarm@lists.cs.columbia.edu, libc-alpha@sourceware.org,\n\tlinux-arch@vger.kernel.org,\n\tChristoffer Dall <christoffer.dall@linaro.org>","Subject":"Re: [PATCH v4 02/28] arm64: KVM: Hide unsupported AArch64 CPU\n\tfeatures from guests","In-reply-to":"<1509101470-7881-3-git-send-email-Dave.Martin@arm.com>","Date":"Tue, 31 Oct 2017 10:57:32 +0000","Message-ID":"<874lqfinz7.fsf@linaro.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Transfer-Encoding":"quoted-printable"}}]