Skip to content

Commit 7ea90bd

Browse files
author
Marc Zyngier
committed
KVM: arm64: Refactor vcpu_{read,write}_sys_reg
Extract the direct HW accessors for later reuse. Reviewed-by: James Morse <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent fc5d1f1 commit 7ea90bd

File tree

1 file changed

+71
-57
lines changed

1 file changed

+71
-57
lines changed

arch/arm64/kvm/sys_regs.c

Lines changed: 71 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,8 @@ static bool write_to_read_only(struct kvm_vcpu *vcpu,
6464
return false;
6565
}
6666

67-
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
67+
static bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val)
6868
{
69-
if (!vcpu->arch.sysregs_loaded_on_cpu)
70-
goto immediate_read;
71-
7269
/*
7370
* System registers listed in the switch are not saved on every
7471
* exit from the guest but are only saved on vcpu_put.
@@ -79,40 +76,37 @@ u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
7976
* thread when emulating cross-VCPU communication.
8077
*/
8178
switch (reg) {
82-
case CSSELR_EL1: return read_sysreg_s(SYS_CSSELR_EL1);
83-
case SCTLR_EL1: return read_sysreg_s(SYS_SCTLR_EL12);
84-
case ACTLR_EL1: return read_sysreg_s(SYS_ACTLR_EL1);
85-
case CPACR_EL1: return read_sysreg_s(SYS_CPACR_EL12);
86-
case TTBR0_EL1: return read_sysreg_s(SYS_TTBR0_EL12);
87-
case TTBR1_EL1: return read_sysreg_s(SYS_TTBR1_EL12);
88-
case TCR_EL1: return read_sysreg_s(SYS_TCR_EL12);
89-
case ESR_EL1: return read_sysreg_s(SYS_ESR_EL12);
90-
case AFSR0_EL1: return read_sysreg_s(SYS_AFSR0_EL12);
91-
case AFSR1_EL1: return read_sysreg_s(SYS_AFSR1_EL12);
92-
case FAR_EL1: return read_sysreg_s(SYS_FAR_EL12);
93-
case MAIR_EL1: return read_sysreg_s(SYS_MAIR_EL12);
94-
case VBAR_EL1: return read_sysreg_s(SYS_VBAR_EL12);
95-
case CONTEXTIDR_EL1: return read_sysreg_s(SYS_CONTEXTIDR_EL12);
96-
case TPIDR_EL0: return read_sysreg_s(SYS_TPIDR_EL0);
97-
case TPIDRRO_EL0: return read_sysreg_s(SYS_TPIDRRO_EL0);
98-
case TPIDR_EL1: return read_sysreg_s(SYS_TPIDR_EL1);
99-
case AMAIR_EL1: return read_sysreg_s(SYS_AMAIR_EL12);
100-
case CNTKCTL_EL1: return read_sysreg_s(SYS_CNTKCTL_EL12);
101-
case PAR_EL1: return read_sysreg_s(SYS_PAR_EL1);
102-
case DACR32_EL2: return read_sysreg_s(SYS_DACR32_EL2);
103-
case IFSR32_EL2: return read_sysreg_s(SYS_IFSR32_EL2);
104-
case DBGVCR32_EL2: return read_sysreg_s(SYS_DBGVCR32_EL2);
79+
case CSSELR_EL1: *val = read_sysreg_s(SYS_CSSELR_EL1); break;
80+
case SCTLR_EL1: *val = read_sysreg_s(SYS_SCTLR_EL12); break;
81+
case ACTLR_EL1: *val = read_sysreg_s(SYS_ACTLR_EL1); break;
82+
case CPACR_EL1: *val = read_sysreg_s(SYS_CPACR_EL12); break;
83+
case TTBR0_EL1: *val = read_sysreg_s(SYS_TTBR0_EL12); break;
84+
case TTBR1_EL1: *val = read_sysreg_s(SYS_TTBR1_EL12); break;
85+
case TCR_EL1: *val = read_sysreg_s(SYS_TCR_EL12); break;
86+
case ESR_EL1: *val = read_sysreg_s(SYS_ESR_EL12); break;
87+
case AFSR0_EL1: *val = read_sysreg_s(SYS_AFSR0_EL12); break;
88+
case AFSR1_EL1: *val = read_sysreg_s(SYS_AFSR1_EL12); break;
89+
case FAR_EL1: *val = read_sysreg_s(SYS_FAR_EL12); break;
90+
case MAIR_EL1: *val = read_sysreg_s(SYS_MAIR_EL12); break;
91+
case VBAR_EL1: *val = read_sysreg_s(SYS_VBAR_EL12); break;
92+
case CONTEXTIDR_EL1: *val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break;
93+
case TPIDR_EL0: *val = read_sysreg_s(SYS_TPIDR_EL0); break;
94+
case TPIDRRO_EL0: *val = read_sysreg_s(SYS_TPIDRRO_EL0); break;
95+
case TPIDR_EL1: *val = read_sysreg_s(SYS_TPIDR_EL1); break;
96+
case AMAIR_EL1: *val = read_sysreg_s(SYS_AMAIR_EL12); break;
97+
case CNTKCTL_EL1: *val = read_sysreg_s(SYS_CNTKCTL_EL12); break;
98+
case PAR_EL1: *val = read_sysreg_s(SYS_PAR_EL1); break;
99+
case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break;
100+
case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break;
101+
case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break;
102+
default: return false;
105103
}
106104

107-
immediate_read:
108-
return __vcpu_sys_reg(vcpu, reg);
105+
return true;
109106
}
110107

111-
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
108+
static bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)
112109
{
113-
if (!vcpu->arch.sysregs_loaded_on_cpu)
114-
goto immediate_write;
115-
116110
/*
117111
* System registers listed in the switch are not restored on every
118112
* entry to the guest but are only restored on vcpu_load.
@@ -122,32 +116,52 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
122116
* once, before running the VCPU, and never changed later.
123117
*/
124118
switch (reg) {
125-
case CSSELR_EL1: write_sysreg_s(val, SYS_CSSELR_EL1); return;
126-
case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); return;
127-
case ACTLR_EL1: write_sysreg_s(val, SYS_ACTLR_EL1); return;
128-
case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); return;
129-
case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); return;
130-
case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); return;
131-
case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); return;
132-
case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); return;
133-
case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); return;
134-
case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); return;
135-
case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); return;
136-
case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); return;
137-
case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); return;
138-
case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12); return;
139-
case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); return;
140-
case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); return;
141-
case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); return;
142-
case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); return;
143-
case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); return;
144-
case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); return;
145-
case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); return;
146-
case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); return;
147-
case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); return;
119+
case CSSELR_EL1: write_sysreg_s(val, SYS_CSSELR_EL1); break;
120+
case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); break;
121+
case ACTLR_EL1: write_sysreg_s(val, SYS_ACTLR_EL1); break;
122+
case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); break;
123+
case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); break;
124+
case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); break;
125+
case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); break;
126+
case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break;
127+
case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break;
128+
case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break;
129+
case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); break;
130+
case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); break;
131+
case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); break;
132+
case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break;
133+
case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); break;
134+
case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); break;
135+
case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); break;
136+
case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); break;
137+
case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); break;
138+
case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); break;
139+
case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); break;
140+
case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); break;
141+
case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); break;
142+
default: return false;
148143
}
149144

150-
immediate_write:
145+
return true;
146+
}
147+
148+
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
149+
{
150+
u64 val = 0x8badf00d8badf00d;
151+
152+
if (vcpu->arch.sysregs_loaded_on_cpu &&
153+
__vcpu_read_sys_reg_from_cpu(reg, &val))
154+
return val;
155+
156+
return __vcpu_sys_reg(vcpu, reg);
157+
}
158+
159+
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
160+
{
161+
if (vcpu->arch.sysregs_loaded_on_cpu &&
162+
__vcpu_write_sys_reg_to_cpu(val, reg))
163+
return;
164+
151165
__vcpu_sys_reg(vcpu, reg) = val;
152166
}
153167

0 commit comments

Comments
 (0)