Skip to content

Commit cc33c4e

Browse files
mrutland-armchazy
authored andcommitted
arm64/kvm: Prohibit guest LOR accesses
We don't currently limit guest accesses to the LOR registers, which we neither virtualize nor context-switch. As such, guests are provided with unusable information/controls, and are not isolated from each other (or the host). To prevent these issues, we can trap register accesses and present the illusion LORegions are unssupported by the CPU. To do this, we mask ID_AA64MMFR1.LO, and set HCR_EL2.TLOR to trap accesses to the following registers: * LORC_EL1 * LOREA_EL1 * LORID_EL1 * LORN_EL1 * LORSA_EL1 ... when trapped, we inject an UNDEFINED exception to EL1, simulating their non-existence. As noted in D7.2.67, when no LORegions are implemented, LoadLOAcquire and StoreLORelease must behave as LoadAcquire and StoreRelease respectively. We can ensure this by clearing LORC_EL1.EN when a CPU's EL2 is first initialized, as the host kernel will not modify this. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Christoffer Dall <christoffer.dall@linaro.org> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: kvmarm@lists.cs.columbia.edu Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
1 parent 4a3928c commit cc33c4e

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

arch/arm64/include/asm/kvm_arm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
/* Hyp Configuration Register (HCR) bits */
2626
#define HCR_TEA (UL(1) << 37)
2727
#define HCR_TERR (UL(1) << 36)
28+
#define HCR_TLOR (UL(1) << 35)
2829
#define HCR_E2H (UL(1) << 34)
2930
#define HCR_ID (UL(1) << 33)
3031
#define HCR_CD (UL(1) << 32)
@@ -64,6 +65,7 @@
6465

6566
/*
6667
* The bits we set in HCR:
68+
* TLOR: Trap LORegion register accesses
6769
* RW: 64bit by default, can be overridden for 32bit VMs
6870
* TAC: Trap ACTLR
6971
* TSC: Trap SMC
@@ -81,7 +83,7 @@
8183
*/
8284
#define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
8385
HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \
84-
HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW)
86+
HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR)
8587
#define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
8688
#define HCR_INT_OVERRIDE (HCR_FMO | HCR_IMO)
8789
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)

arch/arm64/include/asm/sysreg.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,12 @@
288288
#define SYS_MAIR_EL1 sys_reg(3, 0, 10, 2, 0)
289289
#define SYS_AMAIR_EL1 sys_reg(3, 0, 10, 3, 0)
290290

291+
#define SYS_LORSA_EL1 sys_reg(3, 0, 10, 4, 0)
292+
#define SYS_LOREA_EL1 sys_reg(3, 0, 10, 4, 1)
293+
#define SYS_LORN_EL1 sys_reg(3, 0, 10, 4, 2)
294+
#define SYS_LORC_EL1 sys_reg(3, 0, 10, 4, 3)
295+
#define SYS_LORID_EL1 sys_reg(3, 0, 10, 4, 7)
296+
291297
#define SYS_VBAR_EL1 sys_reg(3, 0, 12, 0, 0)
292298
#define SYS_DISR_EL1 sys_reg(3, 0, 12, 1, 1)
293299

arch/arm64/kernel/head.S

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,13 @@ set_hcr:
577577
7:
578578
msr mdcr_el2, x3 // Configure debug traps
579579

580+
/* LORegions */
581+
mrs x1, id_aa64mmfr1_el1
582+
ubfx x0, x1, #ID_AA64MMFR1_LOR_SHIFT, 4
583+
cbz x0, 1f
584+
msr_s SYS_LORC_EL1, xzr
585+
1:
586+
580587
/* Stage-2 translation */
581588
msr vttbr_el2, xzr
582589

arch/arm64/kvm/sys_regs.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
175175
return read_zero(vcpu, p);
176176
}
177177

178+
static bool trap_undef(struct kvm_vcpu *vcpu,
179+
struct sys_reg_params *p,
180+
const struct sys_reg_desc *r)
181+
{
182+
kvm_inject_undefined(vcpu);
183+
return false;
184+
}
185+
178186
static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
179187
struct sys_reg_params *p,
180188
const struct sys_reg_desc *r)
@@ -893,6 +901,12 @@ static u64 read_id_reg(struct sys_reg_desc const *r, bool raz)
893901
task_pid_nr(current));
894902

895903
val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
904+
} else if (id == SYS_ID_AA64MMFR1_EL1) {
905+
if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))
906+
pr_err_once("kvm [%i]: LORegions unsupported for guests, suppressing\n",
907+
task_pid_nr(current));
908+
909+
val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT);
896910
}
897911

898912
return val;
@@ -1178,6 +1192,12 @@ static const struct sys_reg_desc sys_reg_descs[] = {
11781192
{ SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
11791193
{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
11801194

1195+
{ SYS_DESC(SYS_LORSA_EL1), trap_undef },
1196+
{ SYS_DESC(SYS_LOREA_EL1), trap_undef },
1197+
{ SYS_DESC(SYS_LORN_EL1), trap_undef },
1198+
{ SYS_DESC(SYS_LORC_EL1), trap_undef },
1199+
{ SYS_DESC(SYS_LORID_EL1), trap_undef },
1200+
11811201
{ SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
11821202
{ SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
11831203

0 commit comments

Comments
 (0)