Loading arch/arm64/kvm/sys_regs.c +71 −57 Original line number Diff line number Diff line Loading @@ -64,11 +64,8 @@ static bool write_to_read_only(struct kvm_vcpu *vcpu, return false; } u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg) static bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val) { if (!vcpu->arch.sysregs_loaded_on_cpu) goto immediate_read; /* * System registers listed in the switch are not saved on every * exit from the guest but are only saved on vcpu_put. Loading @@ -79,40 +76,37 @@ u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg) * thread when emulating cross-VCPU communication. */ switch (reg) { case CSSELR_EL1: return read_sysreg_s(SYS_CSSELR_EL1); case SCTLR_EL1: return read_sysreg_s(SYS_SCTLR_EL12); case ACTLR_EL1: return read_sysreg_s(SYS_ACTLR_EL1); case CPACR_EL1: return read_sysreg_s(SYS_CPACR_EL12); case TTBR0_EL1: return read_sysreg_s(SYS_TTBR0_EL12); case TTBR1_EL1: return read_sysreg_s(SYS_TTBR1_EL12); case TCR_EL1: return read_sysreg_s(SYS_TCR_EL12); case ESR_EL1: return read_sysreg_s(SYS_ESR_EL12); case AFSR0_EL1: return read_sysreg_s(SYS_AFSR0_EL12); case AFSR1_EL1: return read_sysreg_s(SYS_AFSR1_EL12); case FAR_EL1: return read_sysreg_s(SYS_FAR_EL12); case MAIR_EL1: return read_sysreg_s(SYS_MAIR_EL12); case VBAR_EL1: return read_sysreg_s(SYS_VBAR_EL12); case CONTEXTIDR_EL1: return read_sysreg_s(SYS_CONTEXTIDR_EL12); case TPIDR_EL0: return read_sysreg_s(SYS_TPIDR_EL0); case TPIDRRO_EL0: return read_sysreg_s(SYS_TPIDRRO_EL0); case TPIDR_EL1: return read_sysreg_s(SYS_TPIDR_EL1); case AMAIR_EL1: return read_sysreg_s(SYS_AMAIR_EL12); case CNTKCTL_EL1: return read_sysreg_s(SYS_CNTKCTL_EL12); case PAR_EL1: return read_sysreg_s(SYS_PAR_EL1); case DACR32_EL2: return read_sysreg_s(SYS_DACR32_EL2); case IFSR32_EL2: return read_sysreg_s(SYS_IFSR32_EL2); case DBGVCR32_EL2: return read_sysreg_s(SYS_DBGVCR32_EL2); } immediate_read: return __vcpu_sys_reg(vcpu, reg); case CSSELR_EL1: *val = read_sysreg_s(SYS_CSSELR_EL1); break; case SCTLR_EL1: *val = read_sysreg_s(SYS_SCTLR_EL12); break; case ACTLR_EL1: *val = read_sysreg_s(SYS_ACTLR_EL1); break; case CPACR_EL1: *val = read_sysreg_s(SYS_CPACR_EL12); break; case TTBR0_EL1: *val = read_sysreg_s(SYS_TTBR0_EL12); break; case TTBR1_EL1: *val = read_sysreg_s(SYS_TTBR1_EL12); break; case TCR_EL1: *val = read_sysreg_s(SYS_TCR_EL12); break; case ESR_EL1: *val = read_sysreg_s(SYS_ESR_EL12); break; case AFSR0_EL1: *val = read_sysreg_s(SYS_AFSR0_EL12); break; case AFSR1_EL1: *val = read_sysreg_s(SYS_AFSR1_EL12); break; case FAR_EL1: *val = read_sysreg_s(SYS_FAR_EL12); break; case MAIR_EL1: *val = read_sysreg_s(SYS_MAIR_EL12); break; case VBAR_EL1: *val = read_sysreg_s(SYS_VBAR_EL12); break; case CONTEXTIDR_EL1: *val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break; case TPIDR_EL0: *val = read_sysreg_s(SYS_TPIDR_EL0); break; case TPIDRRO_EL0: *val = read_sysreg_s(SYS_TPIDRRO_EL0); break; case TPIDR_EL1: *val = read_sysreg_s(SYS_TPIDR_EL1); break; case AMAIR_EL1: *val = read_sysreg_s(SYS_AMAIR_EL12); break; case CNTKCTL_EL1: *val = read_sysreg_s(SYS_CNTKCTL_EL12); break; case PAR_EL1: *val = read_sysreg_s(SYS_PAR_EL1); break; case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break; case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break; case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break; default: return false; } void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) { if (!vcpu->arch.sysregs_loaded_on_cpu) goto immediate_write; return true; } static bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg) { /* * System registers listed in the switch are not restored on every * entry to the guest but are only restored on vcpu_load. Loading @@ -122,32 +116,52 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) * once, before running the VCPU, and never changed later. */ switch (reg) { case CSSELR_EL1: write_sysreg_s(val, SYS_CSSELR_EL1); return; case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); return; case ACTLR_EL1: write_sysreg_s(val, SYS_ACTLR_EL1); return; case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); return; case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); return; case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); return; case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); return; case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); return; case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); return; case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); return; case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); return; case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); return; case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); return; case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12); return; case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); return; case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); return; case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); return; case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); return; case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); return; case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); return; case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); return; case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); return; case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); return; } immediate_write: case CSSELR_EL1: write_sysreg_s(val, SYS_CSSELR_EL1); break; case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); break; case ACTLR_EL1: write_sysreg_s(val, SYS_ACTLR_EL1); break; case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); break; case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); break; case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); break; case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); break; case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break; case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break; case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break; case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); break; case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); break; case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); break; case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break; case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); break; case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); break; case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); break; case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); break; case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); break; case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); break; case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); break; case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); break; case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); break; default: return false; } return true; } u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg) { u64 val = 0x8badf00d8badf00d; if (vcpu->arch.sysregs_loaded_on_cpu && __vcpu_read_sys_reg_from_cpu(reg, &val)) return val; return __vcpu_sys_reg(vcpu, reg); } void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) { if (vcpu->arch.sysregs_loaded_on_cpu && __vcpu_write_sys_reg_to_cpu(val, reg)) return; __vcpu_sys_reg(vcpu, reg) = val; } Loading Loading
arch/arm64/kvm/sys_regs.c +71 −57 Original line number Diff line number Diff line Loading @@ -64,11 +64,8 @@ static bool write_to_read_only(struct kvm_vcpu *vcpu, return false; } u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg) static bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val) { if (!vcpu->arch.sysregs_loaded_on_cpu) goto immediate_read; /* * System registers listed in the switch are not saved on every * exit from the guest but are only saved on vcpu_put. Loading @@ -79,40 +76,37 @@ u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg) * thread when emulating cross-VCPU communication. */ switch (reg) { case CSSELR_EL1: return read_sysreg_s(SYS_CSSELR_EL1); case SCTLR_EL1: return read_sysreg_s(SYS_SCTLR_EL12); case ACTLR_EL1: return read_sysreg_s(SYS_ACTLR_EL1); case CPACR_EL1: return read_sysreg_s(SYS_CPACR_EL12); case TTBR0_EL1: return read_sysreg_s(SYS_TTBR0_EL12); case TTBR1_EL1: return read_sysreg_s(SYS_TTBR1_EL12); case TCR_EL1: return read_sysreg_s(SYS_TCR_EL12); case ESR_EL1: return read_sysreg_s(SYS_ESR_EL12); case AFSR0_EL1: return read_sysreg_s(SYS_AFSR0_EL12); case AFSR1_EL1: return read_sysreg_s(SYS_AFSR1_EL12); case FAR_EL1: return read_sysreg_s(SYS_FAR_EL12); case MAIR_EL1: return read_sysreg_s(SYS_MAIR_EL12); case VBAR_EL1: return read_sysreg_s(SYS_VBAR_EL12); case CONTEXTIDR_EL1: return read_sysreg_s(SYS_CONTEXTIDR_EL12); case TPIDR_EL0: return read_sysreg_s(SYS_TPIDR_EL0); case TPIDRRO_EL0: return read_sysreg_s(SYS_TPIDRRO_EL0); case TPIDR_EL1: return read_sysreg_s(SYS_TPIDR_EL1); case AMAIR_EL1: return read_sysreg_s(SYS_AMAIR_EL12); case CNTKCTL_EL1: return read_sysreg_s(SYS_CNTKCTL_EL12); case PAR_EL1: return read_sysreg_s(SYS_PAR_EL1); case DACR32_EL2: return read_sysreg_s(SYS_DACR32_EL2); case IFSR32_EL2: return read_sysreg_s(SYS_IFSR32_EL2); case DBGVCR32_EL2: return read_sysreg_s(SYS_DBGVCR32_EL2); } immediate_read: return __vcpu_sys_reg(vcpu, reg); case CSSELR_EL1: *val = read_sysreg_s(SYS_CSSELR_EL1); break; case SCTLR_EL1: *val = read_sysreg_s(SYS_SCTLR_EL12); break; case ACTLR_EL1: *val = read_sysreg_s(SYS_ACTLR_EL1); break; case CPACR_EL1: *val = read_sysreg_s(SYS_CPACR_EL12); break; case TTBR0_EL1: *val = read_sysreg_s(SYS_TTBR0_EL12); break; case TTBR1_EL1: *val = read_sysreg_s(SYS_TTBR1_EL12); break; case TCR_EL1: *val = read_sysreg_s(SYS_TCR_EL12); break; case ESR_EL1: *val = read_sysreg_s(SYS_ESR_EL12); break; case AFSR0_EL1: *val = read_sysreg_s(SYS_AFSR0_EL12); break; case AFSR1_EL1: *val = read_sysreg_s(SYS_AFSR1_EL12); break; case FAR_EL1: *val = read_sysreg_s(SYS_FAR_EL12); break; case MAIR_EL1: *val = read_sysreg_s(SYS_MAIR_EL12); break; case VBAR_EL1: *val = read_sysreg_s(SYS_VBAR_EL12); break; case CONTEXTIDR_EL1: *val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break; case TPIDR_EL0: *val = read_sysreg_s(SYS_TPIDR_EL0); break; case TPIDRRO_EL0: *val = read_sysreg_s(SYS_TPIDRRO_EL0); break; case TPIDR_EL1: *val = read_sysreg_s(SYS_TPIDR_EL1); break; case AMAIR_EL1: *val = read_sysreg_s(SYS_AMAIR_EL12); break; case CNTKCTL_EL1: *val = read_sysreg_s(SYS_CNTKCTL_EL12); break; case PAR_EL1: *val = read_sysreg_s(SYS_PAR_EL1); break; case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break; case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break; case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break; default: return false; } void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) { if (!vcpu->arch.sysregs_loaded_on_cpu) goto immediate_write; return true; } static bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg) { /* * System registers listed in the switch are not restored on every * entry to the guest but are only restored on vcpu_load. Loading @@ -122,32 +116,52 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) * once, before running the VCPU, and never changed later. */ switch (reg) { case CSSELR_EL1: write_sysreg_s(val, SYS_CSSELR_EL1); return; case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); return; case ACTLR_EL1: write_sysreg_s(val, SYS_ACTLR_EL1); return; case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); return; case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); return; case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); return; case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); return; case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); return; case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); return; case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); return; case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); return; case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); return; case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); return; case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12); return; case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); return; case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); return; case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); return; case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); return; case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); return; case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); return; case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); return; case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); return; case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); return; } immediate_write: case CSSELR_EL1: write_sysreg_s(val, SYS_CSSELR_EL1); break; case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); break; case ACTLR_EL1: write_sysreg_s(val, SYS_ACTLR_EL1); break; case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); break; case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); break; case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); break; case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); break; case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break; case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break; case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break; case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); break; case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); break; case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); break; case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break; case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); break; case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); break; case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); break; case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); break; case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); break; case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); break; case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); break; case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); break; case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); break; default: return false; } return true; } u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg) { u64 val = 0x8badf00d8badf00d; if (vcpu->arch.sysregs_loaded_on_cpu && __vcpu_read_sys_reg_from_cpu(reg, &val)) return val; return __vcpu_sys_reg(vcpu, reg); } void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) { if (vcpu->arch.sysregs_loaded_on_cpu && __vcpu_write_sys_reg_to_cpu(val, reg)) return; __vcpu_sys_reg(vcpu, reg) = val; } Loading