]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
KVM: arm64: Log an error if trapping a read-from-write-only GICv3 access
authorMarc Zyngier <marc.zyngier@arm.com>
Fri, 9 Jun 2017 11:49:55 +0000 (12:49 +0100)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Wed, 9 Aug 2017 14:48:09 +0000 (16:48 +0200)
BugLink: https://bugs.launchpad.net/bugs/1673564
A read-from-write-only GICv3 access should UNDEF at EL1. But since
we're in complete paranoia-land with broken CPUs, let's assume the
worse and gracefully handle the case.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
(backported from commit e7f1d1eef482150a64a6e6ad8faf40f8f97eed67)
[ dannf: Dropped hunk in access_pmswinc since WO check wasn't added
  until e0443230. Recoded sys_reg_descs[] entries to use pre-SYS_DESC()
  syntax. Other context changes. ]
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
arch/arm64/kvm/sys_regs.c
virt/kvm/arm/hyp/vgic-v3-sr.c

index 5bc9ede609407d8459f755630512656784a25ac8..46742039772956d1890b6718434121b46b117f4c 100644 (file)
@@ -56,7 +56,8 @@
  */
 
 static bool read_from_write_only(struct kvm_vcpu *vcpu,
-                                const struct sys_reg_params *params)
+                                struct sys_reg_params *params,
+                                const struct sys_reg_desc *r)
 {
        WARN_ONCE(1, "Unexpected sys_reg read to write-only register\n");
        print_sys_reg_instr(params);
@@ -93,7 +94,7 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
                        const struct sys_reg_desc *r)
 {
        if (!p->is_write)
-               return read_from_write_only(vcpu, p);
+               return read_from_write_only(vcpu, p, r);
 
        kvm_set_way_flush(vcpu);
        return true;
@@ -135,7 +136,7 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
                           const struct sys_reg_desc *r)
 {
        if (!p->is_write)
-               return read_from_write_only(vcpu, p);
+               return read_from_write_only(vcpu, p, r);
 
        vgic_v3_dispatch_sgi(vcpu, p->regval);
 
@@ -966,9 +967,18 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b0000), Op2(0b000),
          NULL, reset_val, VBAR_EL1, 0 },
 
+       /* ICC_EOIR0_EL1 */
+       { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1000), Op2(0b001),
+         read_from_write_only },
+       /* ICC_DIR_EL1 */
+       { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1011), Op2(0b001),
+         read_from_write_only },
        /* ICC_SGI1R_EL1 */
        { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1011), Op2(0b101),
          access_gic_sgi },
+       /* ICC_EOIR1_EL1 */
+       { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b001),
+         read_from_write_only },
        /* ICC_SRE_EL1 */
        { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b101),
          access_gic_sre },
index 6eb0d67cc528e5182bce94a78e5260e03cf2a4e3..773ebe5466e02aca40e781b1724d8f08d55d87f1 100644 (file)
@@ -1029,6 +1029,8 @@ int __hyp_text __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu)
                break;
        case ICC_EOIR0_EL1:
        case ICC_EOIR1_EL1:
+               if (unlikely(is_read))
+                       return 0;
                fn = __vgic_v3_write_eoir;
                break;
        case ICC_GRPEN1_EL1:
@@ -1088,6 +1090,8 @@ int __hyp_text __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu)
                        fn = __vgic_v3_write_bpr0;
                break;
        case ICC_DIR_EL1:
+               if (unlikely(is_read))
+                       return 0;
                fn = __vgic_v3_write_dir;
                break;
        case ICC_RPR_EL1: