]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
KVM: arm64: Log an error if trapping a write-to-read-only GICv3 access
authorMarc Zyngier <marc.zyngier@arm.com>
Fri, 9 Jun 2017 11:49:56 +0000 (12:49 +0100)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Wed, 9 Aug 2017 14:48:10 +0000 (16:48 +0200)
BugLink: https://bugs.launchpad.net/bugs/1673564
A write-to-read-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 picked from commit 7b1dba1f7325629427c0e5bdf014159b229d16c8)
[ dannf: Recoded sys_reg_descs[] entries to use pre-SYS_DESC() syntax and
  minor 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 46742039772956d1890b6718434121b46b117f4c..6808defa3da817782e4f20258dfde7e87b21111e 100644 (file)
@@ -65,6 +65,16 @@ static bool read_from_write_only(struct kvm_vcpu *vcpu,
        return false;
 }
 
+static bool write_to_read_only(struct kvm_vcpu *vcpu,
+                              struct sys_reg_params *params,
+                              const struct sys_reg_desc *r)
+{
+       WARN_ONCE(1, "Unexpected sys_reg write to read-only register\n");
+       print_sys_reg_instr(params);
+       kvm_inject_undefined(vcpu);
+       return false;
+}
+
 /* 3 bits per cache level, as per CLIDR, but non-existent caches always 0 */
 static u32 cache_levels;
 
@@ -967,18 +977,33 @@ 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_IAR0_EL1 */
+       { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1000), Op2(0b000),
+         write_to_read_only },
        /* ICC_EOIR0_EL1 */
        { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1000), Op2(0b001),
          read_from_write_only },
+       /* ICC_HPPIR0_EL1 */
+       { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1000), Op2(0b010),
+         write_to_read_only },
        /* ICC_DIR_EL1 */
        { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1011), Op2(0b001),
          read_from_write_only },
+       /* ICC_RPR_EL1 */
+       { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1011), Op2(0b011),
+         write_to_read_only },
        /* ICC_SGI1R_EL1 */
        { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1011), Op2(0b101),
          access_gic_sgi },
+       /* ICC_IAR1_EL1 */
+       { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b000),
+         write_to_read_only },
        /* ICC_EOIR1_EL1 */
        { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b001),
          read_from_write_only },
+       /* ICC_HPPIR1_EL1 */
+       { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b010),
+         write_to_read_only },
        /* ICC_SRE_EL1 */
        { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b101),
          access_gic_sre },
index 773ebe5466e02aca40e781b1724d8f08d55d87f1..2164ed639139a18ae340c88dba07c03312d78c33 100644 (file)
@@ -1025,6 +1025,8 @@ int __hyp_text __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu)
        switch (sysreg) {
        case ICC_IAR0_EL1:
        case ICC_IAR1_EL1:
+               if (unlikely(!is_read))
+                       return 0;
                fn = __vgic_v3_read_iar;
                break;
        case ICC_EOIR0_EL1:
@@ -1075,6 +1077,8 @@ int __hyp_text __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu)
                break;
        case ICC_HPPIR0_EL1:
        case ICC_HPPIR1_EL1:
+               if (unlikely(!is_read))
+                       return 0;
                fn = __vgic_v3_read_hppir;
                break;
        case ICC_GRPEN0_EL1:
@@ -1095,6 +1099,8 @@ int __hyp_text __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu)
                fn = __vgic_v3_write_dir;
                break;
        case ICC_RPR_EL1:
+               if (unlikely(!is_read))
+                       return 0;
                fn = __vgic_v3_read_rpr;
                break;
        case ICC_CTLR_EL1: