/* Hyp Configuration Register (HCR) bits */
 #define HCR_TEA                (UL(1) << 37)
 #define HCR_TERR       (UL(1) << 36)
+#define HCR_TLOR       (UL(1) << 35)
 #define HCR_E2H                (UL(1) << 34)
 #define HCR_ID         (UL(1) << 33)
 #define HCR_CD         (UL(1) << 32)
 
 /*
  * The bits we set in HCR:
+ * TLOR:       Trap LORegion register accesses
  * RW:         64bit by default, can be overridden for 32bit VMs
  * TAC:                Trap ACTLR
  * TSC:                Trap SMC
  */
 #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
                         HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \
-                        HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW)
+                        HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR)
 #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
 #define HCR_INT_OVERRIDE   (HCR_FMO | HCR_IMO)
 #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
 
 #define SYS_MAIR_EL1                   sys_reg(3, 0, 10, 2, 0)
 #define SYS_AMAIR_EL1                  sys_reg(3, 0, 10, 3, 0)
 
+#define SYS_LORSA_EL1                  sys_reg(3, 0, 10, 4, 0)
+#define SYS_LOREA_EL1                  sys_reg(3, 0, 10, 4, 1)
+#define SYS_LORN_EL1                   sys_reg(3, 0, 10, 4, 2)
+#define SYS_LORC_EL1                   sys_reg(3, 0, 10, 4, 3)
+#define SYS_LORID_EL1                  sys_reg(3, 0, 10, 4, 7)
+
 #define SYS_VBAR_EL1                   sys_reg(3, 0, 12, 0, 0)
 #define SYS_DISR_EL1                   sys_reg(3, 0, 12, 1, 1)
 
 
 7:
        msr     mdcr_el2, x3                    // Configure debug traps
 
+       /* LORegions */
+       mrs     x1, id_aa64mmfr1_el1
+       ubfx    x0, x1, #ID_AA64MMFR1_LOR_SHIFT, 4
+       cbz     x0, 1f
+       msr_s   SYS_LORC_EL1, xzr
+1:
+
        /* Stage-2 translation */
        msr     vttbr_el2, xzr
 
 
                return read_zero(vcpu, p);
 }
 
+static bool trap_undef(struct kvm_vcpu *vcpu,
+                      struct sys_reg_params *p,
+                      const struct sys_reg_desc *r)
+{
+       kvm_inject_undefined(vcpu);
+       return false;
+}
+
 static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
                           struct sys_reg_params *p,
                           const struct sys_reg_desc *r)
                                    task_pid_nr(current));
 
                val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
+       } else if (id == SYS_ID_AA64MMFR1_EL1) {
+               if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))
+                       pr_err_once("kvm [%i]: LORegions unsupported for guests, suppressing\n",
+                                   task_pid_nr(current));
+
+               val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT);
        }
 
        return val;
        { SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
        { SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
 
+       { SYS_DESC(SYS_LORSA_EL1), trap_undef },
+       { SYS_DESC(SYS_LOREA_EL1), trap_undef },
+       { SYS_DESC(SYS_LORN_EL1), trap_undef },
+       { SYS_DESC(SYS_LORC_EL1), trap_undef },
+       { SYS_DESC(SYS_LORID_EL1), trap_undef },
+
        { SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
        { SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },