From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 26/32] arm64: KVM: 32bit handling of coprocessor traps
Date: Wed, 24 Apr 2013 14:42:04 +0100 [thread overview]
Message-ID: <5177E12C.8020909@arm.com> (raw)
In-Reply-To: <20130423230159.GL20569@gmail.com>
On 24/04/13 00:01, Christoffer Dall wrote:
> On Mon, Apr 08, 2013 at 05:17:28PM +0100, Marc Zyngier wrote:
>> Provide the necessary infrastructure to trap coprocessor accesses that
>> occur when running 32bit guests.
>>
>> Also wire SMC and HVC trapped in 32bit mode while were at it.
>>
>> Reviewed-by: Christopher Covington <cov@codeaurora.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>> arch/arm64/include/asm/kvm_coproc.h | 5 +
>> arch/arm64/kvm/handle_exit.c | 7 ++
>> arch/arm64/kvm/sys_regs.c | 178 ++++++++++++++++++++++++++++++++++--
>> 3 files changed, 183 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/kvm_coproc.h b/arch/arm64/include/asm/kvm_coproc.h
>> index 9b4477a..9a59301 100644
>> --- a/arch/arm64/include/asm/kvm_coproc.h
>> +++ b/arch/arm64/include/asm/kvm_coproc.h
>> @@ -32,11 +32,16 @@ struct kvm_sys_reg_table {
>>
>> struct kvm_sys_reg_target_table {
>> struct kvm_sys_reg_table table64;
>> + struct kvm_sys_reg_table table32;
>> };
>>
>> void kvm_register_target_sys_reg_table(unsigned int target,
>> struct kvm_sys_reg_target_table *table);
>>
>> +int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> +int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> +int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> +int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run);
>>
>> #define kvm_coproc_table_init kvm_sys_reg_table_init
>> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
>> index 4766b7f..9beaca03 100644
>> --- a/arch/arm64/kvm/handle_exit.c
>> +++ b/arch/arm64/kvm/handle_exit.c
>> @@ -62,6 +62,13 @@ static int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>
>> static exit_handle_fn arm_exit_handlers[] = {
>> [ESR_EL2_EC_WFI] = kvm_handle_wfi,
>> + [ESR_EL2_EC_CP15_32] = kvm_handle_cp15_32,
>> + [ESR_EL2_EC_CP15_64] = kvm_handle_cp15_64,
>> + [ESR_EL2_EC_CP14_MR] = kvm_handle_cp14_access,
>> + [ESR_EL2_EC_CP14_LS] = kvm_handle_cp14_load_store,
>> + [ESR_EL2_EC_CP14_64] = kvm_handle_cp14_access,
>> + [ESR_EL2_EC_HVC32] = handle_hvc,
>> + [ESR_EL2_EC_SMC32] = handle_smc,
>> [ESR_EL2_EC_HVC64] = handle_hvc,
>> [ESR_EL2_EC_SMC64] = handle_smc,
>> [ESR_EL2_EC_SYS64] = kvm_handle_sys_reg,
>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>> index 9df3b32..0303218 100644
>> --- a/arch/arm64/kvm/sys_regs.c
>> +++ b/arch/arm64/kvm/sys_regs.c
>> @@ -38,6 +38,10 @@
>> * types are different. My gut feeling is that it should be pretty
>> * easy to merge, but that would be an ABI breakage -- again. VFP
>> * would also need to be abstracted.
>> + *
>> + * For AArch32, we only take care of what is being trapped. Anything
>> + * that has to do with init and userspace access has to go via the
>> + * 64bit interface.
>> */
>>
>> /* 3 bits per cache level, as per CLIDR, but non-existent caches always 0 */
>> @@ -163,6 +167,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>> { Op0(0b01), Op1(0b000), CRn(0b0111), CRm(0b1110), Op2(0b010),
>> access_dcsw },
>>
>> + /* TEECR32_EL1 */
>> + { Op0(0b10), Op1(0b010), CRn(0b0000), CRm(0b0000), Op2(0b000),
>> + NULL, reset_val, TEECR32_EL1, 0 },
>> + /* TEEHBR32_EL1 */
>> + { Op0(0b10), Op1(0b010), CRn(0b0001), CRm(0b0000), Op2(0b000),
>> + NULL, reset_val, TEEHBR32_EL1, 0 },
>> + /* DBGVCR32_EL2 */
>> + { Op0(0b10), Op1(0b100), CRn(0b0000), CRm(0b0111), Op2(0b000),
>> + NULL, reset_val, DBGVCR32_EL2, 0 },
>> +
>> /* MPIDR_EL1 */
>> { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0000), Op2(0b101),
>> NULL, reset_mpidr, MPIDR_EL1 },
>> @@ -273,6 +287,39 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>> /* TPIDRRO_EL0 */
>> { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b011),
>> NULL, reset_unknown, TPIDRRO_EL0 },
>> +
>> + /* DACR32_EL2 */
>> + { Op0(0b11), Op1(0b100), CRn(0b0011), CRm(0b0000), Op2(0b000),
>> + NULL, reset_unknown, DACR32_EL2 },
>> + /* IFSR32_EL2 */
>> + { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0000), Op2(0b001),
>> + NULL, reset_unknown, IFSR32_EL2 },
>> + /* FPEXC32_EL2 */
>> + { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0011), Op2(0b000),
>> + NULL, reset_val, FPEXC32_EL2, 0x70 },
>> +};
>> +
>> +/* Trapped cp15 registers */
>> +static const struct sys_reg_desc cp15_regs[] = {
>> + /*
>> + * DC{C,I,CI}SW operations:
>> + */
>> + { Op1( 0), CRn( 7), CRm( 6), Op2( 2), access_dcsw },
>> + { Op1( 0), CRn( 7), CRm(10), Op2( 2), access_dcsw },
>> + { Op1( 0), CRn( 7), CRm(14), Op2( 2), access_dcsw },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 0), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 1), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 2), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 3), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 5), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 6), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 7), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(13), Op2( 0), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(13), Op2( 1), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(13), Op2( 2), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(14), Op2( 0), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(14), Op2( 1), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(14), Op2( 2), pm_fake },
>> };
>>
>> /* Target specific emulation tables */
>> @@ -285,13 +332,20 @@ void kvm_register_target_sys_reg_table(unsigned int target,
>> }
>>
>> /* Get specific register table for this target. */
>> -static const struct sys_reg_desc *get_target_table(unsigned target, size_t *num)
>> +static const struct sys_reg_desc *get_target_table(unsigned target,
>> + bool mode_is_64,
>> + size_t *num)
>> {
>> struct kvm_sys_reg_target_table *table;
>>
>> table = target_tables[target];
>> - *num = table->table64.num;
>> - return table->table64.table;
>> + if (mode_is_64) {
>> + *num = table->table64.num;
>> + return table->table64.table;
>> + } else {
>> + *num = table->table32.num;
>> + return table->table32.table;
>> + }
>> }
>>
>> static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params,
>> @@ -319,13 +373,123 @@ static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params,
>> return NULL;
>> }
>>
>> +int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +{
>> + kvm_inject_undefined(vcpu);
>> + return 1;
>> +}
>> +
>> +int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +{
>> + kvm_inject_undefined(vcpu);
>> + return 1;
>> +}
>> +
>> +static int emulate_cp15(struct kvm_vcpu *vcpu,
>> + const struct sys_reg_params *params)
>> +{
>> + size_t num;
>> + const struct sys_reg_desc *table, *r;
>> +
>> + table = get_target_table(vcpu->arch.target, false, &num);
>> +
>> + /* Search target-specific then generic table. */
>> + r = find_reg(params, table, num);
>> + if (!r)
>> + r = find_reg(params, cp15_regs, ARRAY_SIZE(cp15_regs));
>> +
>> + if (likely(r)) {
>> + /* If we don't have an accessor, we should never get here! */
>> + BUG_ON(!r->access);
>
> again not quite sure if this warrants a crash of the entire host.
>
>> +
>> + if (likely(r->access(vcpu, params, r))) {
>> + /* Skip instruction, since it was emulated */
>> + kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
>> + return 1;
>> + }
>> + /* If access function fails, it should complain. */
>> + } else {
>> + kvm_err("Unsupported guest CP15 access at: %08lx\n",
>> + *vcpu_pc(vcpu));
>> + print_sys_reg_instr(params);
>> + }
>> + kvm_inject_undefined(vcpu);
>> + return 1;
>> +}
>> +
>> +/**
>> + * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
>> + * @vcpu: The VCPU pointer
>> + * @run: The kvm_run struct
>> + */
>> +int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +{
>> + struct sys_reg_params params;
>> + u32 hsr = kvm_vcpu_get_hsr(vcpu);
>> + int Rt2 = (hsr >> 10) & 0xf;
>> + int ret;
>> +
>> + params.CRm = (hsr >> 1) & 0xf;
>> + params.Rt = (hsr >> 5) & 0xf;
>> + params.is_write = ((hsr & 1) == 0);
>> +
>> + params.Op0 = 0;
>> + params.Op1 = (hsr >> 16) & 0xf;
>> + params.Op2 = 0;
>> + params.CRn = 0;
>> +
>> + /*
>> + * Massive hack here. Store Rt2 in the top 32bits so we only
>> + * have one register to deal with. As we use the same trap
>> + * backends between AArch32 and AArch64, we get away with it.
>> + */
>> + if (params.is_write) {
>> + u64 val = *vcpu_reg(vcpu, params.Rt);
>> + val &= 0xffffffff;
>> + val |= *vcpu_reg(vcpu, Rt2) << 32;
>> + *vcpu_reg(vcpu, params.Rt) = val;
>> + }
>> +
>> + ret = emulate_cp15(vcpu, ¶ms);
>> +
>> + /* Reverse hack here */
>
> nit: consider changing the wording to something like 'Similar hack for
> reads here', so readers don't think you are trying to reverse the hack
> you did above.
Sure.
>> + if (ret && !params.is_write) {
>> + u64 val = *vcpu_reg(vcpu, params.Rt);
>> + val >>= 32;
>> + *vcpu_reg(vcpu, Rt2) = val;
>
> actually the emulate_cp15 should probably be turned into a void and the
> ret check could go away, same thing on the 32-bit side.
Well, if we don't BUG_ON() in emulate_cp15, then we do want to return
something that meaningfully shown that we failed to handle the trap.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
WARNING: multiple messages have this Message-ID (diff)
From: Marc Zyngier <marc.zyngier@arm.com>
To: Christoffer Dall <cdall@cs.columbia.edu>
Cc: "linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>,
"kvmarm@lists.cs.columbia.edu" <kvmarm@lists.cs.columbia.edu>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
Catalin Marinas <Catalin.Marinas@arm.com>,
Will Deacon <Will.Deacon@arm.com>,
Christopher Covington <cov@codeaurora.org>
Subject: Re: [PATCH v3 26/32] arm64: KVM: 32bit handling of coprocessor traps
Date: Wed, 24 Apr 2013 14:42:04 +0100 [thread overview]
Message-ID: <5177E12C.8020909@arm.com> (raw)
In-Reply-To: <20130423230159.GL20569@gmail.com>
On 24/04/13 00:01, Christoffer Dall wrote:
> On Mon, Apr 08, 2013 at 05:17:28PM +0100, Marc Zyngier wrote:
>> Provide the necessary infrastructure to trap coprocessor accesses that
>> occur when running 32bit guests.
>>
>> Also wire SMC and HVC trapped in 32bit mode while were at it.
>>
>> Reviewed-by: Christopher Covington <cov@codeaurora.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>> arch/arm64/include/asm/kvm_coproc.h | 5 +
>> arch/arm64/kvm/handle_exit.c | 7 ++
>> arch/arm64/kvm/sys_regs.c | 178 ++++++++++++++++++++++++++++++++++--
>> 3 files changed, 183 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/kvm_coproc.h b/arch/arm64/include/asm/kvm_coproc.h
>> index 9b4477a..9a59301 100644
>> --- a/arch/arm64/include/asm/kvm_coproc.h
>> +++ b/arch/arm64/include/asm/kvm_coproc.h
>> @@ -32,11 +32,16 @@ struct kvm_sys_reg_table {
>>
>> struct kvm_sys_reg_target_table {
>> struct kvm_sys_reg_table table64;
>> + struct kvm_sys_reg_table table32;
>> };
>>
>> void kvm_register_target_sys_reg_table(unsigned int target,
>> struct kvm_sys_reg_target_table *table);
>>
>> +int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> +int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> +int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> +int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run);
>>
>> #define kvm_coproc_table_init kvm_sys_reg_table_init
>> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
>> index 4766b7f..9beaca03 100644
>> --- a/arch/arm64/kvm/handle_exit.c
>> +++ b/arch/arm64/kvm/handle_exit.c
>> @@ -62,6 +62,13 @@ static int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>
>> static exit_handle_fn arm_exit_handlers[] = {
>> [ESR_EL2_EC_WFI] = kvm_handle_wfi,
>> + [ESR_EL2_EC_CP15_32] = kvm_handle_cp15_32,
>> + [ESR_EL2_EC_CP15_64] = kvm_handle_cp15_64,
>> + [ESR_EL2_EC_CP14_MR] = kvm_handle_cp14_access,
>> + [ESR_EL2_EC_CP14_LS] = kvm_handle_cp14_load_store,
>> + [ESR_EL2_EC_CP14_64] = kvm_handle_cp14_access,
>> + [ESR_EL2_EC_HVC32] = handle_hvc,
>> + [ESR_EL2_EC_SMC32] = handle_smc,
>> [ESR_EL2_EC_HVC64] = handle_hvc,
>> [ESR_EL2_EC_SMC64] = handle_smc,
>> [ESR_EL2_EC_SYS64] = kvm_handle_sys_reg,
>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>> index 9df3b32..0303218 100644
>> --- a/arch/arm64/kvm/sys_regs.c
>> +++ b/arch/arm64/kvm/sys_regs.c
>> @@ -38,6 +38,10 @@
>> * types are different. My gut feeling is that it should be pretty
>> * easy to merge, but that would be an ABI breakage -- again. VFP
>> * would also need to be abstracted.
>> + *
>> + * For AArch32, we only take care of what is being trapped. Anything
>> + * that has to do with init and userspace access has to go via the
>> + * 64bit interface.
>> */
>>
>> /* 3 bits per cache level, as per CLIDR, but non-existent caches always 0 */
>> @@ -163,6 +167,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>> { Op0(0b01), Op1(0b000), CRn(0b0111), CRm(0b1110), Op2(0b010),
>> access_dcsw },
>>
>> + /* TEECR32_EL1 */
>> + { Op0(0b10), Op1(0b010), CRn(0b0000), CRm(0b0000), Op2(0b000),
>> + NULL, reset_val, TEECR32_EL1, 0 },
>> + /* TEEHBR32_EL1 */
>> + { Op0(0b10), Op1(0b010), CRn(0b0001), CRm(0b0000), Op2(0b000),
>> + NULL, reset_val, TEEHBR32_EL1, 0 },
>> + /* DBGVCR32_EL2 */
>> + { Op0(0b10), Op1(0b100), CRn(0b0000), CRm(0b0111), Op2(0b000),
>> + NULL, reset_val, DBGVCR32_EL2, 0 },
>> +
>> /* MPIDR_EL1 */
>> { Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0000), Op2(0b101),
>> NULL, reset_mpidr, MPIDR_EL1 },
>> @@ -273,6 +287,39 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>> /* TPIDRRO_EL0 */
>> { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b011),
>> NULL, reset_unknown, TPIDRRO_EL0 },
>> +
>> + /* DACR32_EL2 */
>> + { Op0(0b11), Op1(0b100), CRn(0b0011), CRm(0b0000), Op2(0b000),
>> + NULL, reset_unknown, DACR32_EL2 },
>> + /* IFSR32_EL2 */
>> + { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0000), Op2(0b001),
>> + NULL, reset_unknown, IFSR32_EL2 },
>> + /* FPEXC32_EL2 */
>> + { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0011), Op2(0b000),
>> + NULL, reset_val, FPEXC32_EL2, 0x70 },
>> +};
>> +
>> +/* Trapped cp15 registers */
>> +static const struct sys_reg_desc cp15_regs[] = {
>> + /*
>> + * DC{C,I,CI}SW operations:
>> + */
>> + { Op1( 0), CRn( 7), CRm( 6), Op2( 2), access_dcsw },
>> + { Op1( 0), CRn( 7), CRm(10), Op2( 2), access_dcsw },
>> + { Op1( 0), CRn( 7), CRm(14), Op2( 2), access_dcsw },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 0), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 1), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 2), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 3), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 5), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 6), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(12), Op2( 7), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(13), Op2( 0), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(13), Op2( 1), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(13), Op2( 2), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(14), Op2( 0), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(14), Op2( 1), pm_fake },
>> + { Op1( 0), CRn( 9), CRm(14), Op2( 2), pm_fake },
>> };
>>
>> /* Target specific emulation tables */
>> @@ -285,13 +332,20 @@ void kvm_register_target_sys_reg_table(unsigned int target,
>> }
>>
>> /* Get specific register table for this target. */
>> -static const struct sys_reg_desc *get_target_table(unsigned target, size_t *num)
>> +static const struct sys_reg_desc *get_target_table(unsigned target,
>> + bool mode_is_64,
>> + size_t *num)
>> {
>> struct kvm_sys_reg_target_table *table;
>>
>> table = target_tables[target];
>> - *num = table->table64.num;
>> - return table->table64.table;
>> + if (mode_is_64) {
>> + *num = table->table64.num;
>> + return table->table64.table;
>> + } else {
>> + *num = table->table32.num;
>> + return table->table32.table;
>> + }
>> }
>>
>> static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params,
>> @@ -319,13 +373,123 @@ static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params,
>> return NULL;
>> }
>>
>> +int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +{
>> + kvm_inject_undefined(vcpu);
>> + return 1;
>> +}
>> +
>> +int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +{
>> + kvm_inject_undefined(vcpu);
>> + return 1;
>> +}
>> +
>> +static int emulate_cp15(struct kvm_vcpu *vcpu,
>> + const struct sys_reg_params *params)
>> +{
>> + size_t num;
>> + const struct sys_reg_desc *table, *r;
>> +
>> + table = get_target_table(vcpu->arch.target, false, &num);
>> +
>> + /* Search target-specific then generic table. */
>> + r = find_reg(params, table, num);
>> + if (!r)
>> + r = find_reg(params, cp15_regs, ARRAY_SIZE(cp15_regs));
>> +
>> + if (likely(r)) {
>> + /* If we don't have an accessor, we should never get here! */
>> + BUG_ON(!r->access);
>
> again not quite sure if this warrants a crash of the entire host.
>
>> +
>> + if (likely(r->access(vcpu, params, r))) {
>> + /* Skip instruction, since it was emulated */
>> + kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
>> + return 1;
>> + }
>> + /* If access function fails, it should complain. */
>> + } else {
>> + kvm_err("Unsupported guest CP15 access at: %08lx\n",
>> + *vcpu_pc(vcpu));
>> + print_sys_reg_instr(params);
>> + }
>> + kvm_inject_undefined(vcpu);
>> + return 1;
>> +}
>> +
>> +/**
>> + * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
>> + * @vcpu: The VCPU pointer
>> + * @run: The kvm_run struct
>> + */
>> +int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +{
>> + struct sys_reg_params params;
>> + u32 hsr = kvm_vcpu_get_hsr(vcpu);
>> + int Rt2 = (hsr >> 10) & 0xf;
>> + int ret;
>> +
>> + params.CRm = (hsr >> 1) & 0xf;
>> + params.Rt = (hsr >> 5) & 0xf;
>> + params.is_write = ((hsr & 1) == 0);
>> +
>> + params.Op0 = 0;
>> + params.Op1 = (hsr >> 16) & 0xf;
>> + params.Op2 = 0;
>> + params.CRn = 0;
>> +
>> + /*
>> + * Massive hack here. Store Rt2 in the top 32bits so we only
>> + * have one register to deal with. As we use the same trap
>> + * backends between AArch32 and AArch64, we get away with it.
>> + */
>> + if (params.is_write) {
>> + u64 val = *vcpu_reg(vcpu, params.Rt);
>> + val &= 0xffffffff;
>> + val |= *vcpu_reg(vcpu, Rt2) << 32;
>> + *vcpu_reg(vcpu, params.Rt) = val;
>> + }
>> +
>> + ret = emulate_cp15(vcpu, ¶ms);
>> +
>> + /* Reverse hack here */
>
> nit: consider changing the wording to something like 'Similar hack for
> reads here', so readers don't think you are trying to reverse the hack
> you did above.
Sure.
>> + if (ret && !params.is_write) {
>> + u64 val = *vcpu_reg(vcpu, params.Rt);
>> + val >>= 32;
>> + *vcpu_reg(vcpu, Rt2) = val;
>
> actually the emulate_cp15 should probably be turned into a void and the
> ret check could go away, same thing on the 32-bit side.
Well, if we don't BUG_ON() in emulate_cp15, then we do want to return
something that meaningfully shown that we failed to handle the trap.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
next prev parent reply other threads:[~2013-04-24 13:42 UTC|newest]
Thread overview: 232+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-08 16:17 [PATCH v3 00/32] Port of KVM to arm64 Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 01/32] arm64: add explicit symbols to ESR_EL1 decoding Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 02/32] arm64: KVM: define HYP and Stage-2 translation page flags Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-10 14:07 ` Will Deacon
2013-04-10 14:07 ` Will Deacon
2013-04-12 15:22 ` Marc Zyngier
2013-04-12 15:22 ` Marc Zyngier
2013-04-26 17:01 ` Catalin Marinas
2013-04-26 17:01 ` Catalin Marinas
2013-04-26 17:11 ` Marc Zyngier
2013-04-26 17:11 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 03/32] arm64: KVM: HYP mode idmap support Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 22:57 ` Christoffer Dall
2013-04-23 22:57 ` Christoffer Dall
2013-04-24 9:36 ` Marc Zyngier
2013-04-24 9:36 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 04/32] arm64: KVM: EL2 register definitions Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 05/32] arm64: KVM: system register definitions for 64bit guests Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 06/32] arm64: KVM: Basic ESR_EL2 helpers and vcpu register access Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 07/32] arm64: KVM: fault injection into a guest Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-10 16:40 ` Will Deacon
2013-04-10 16:40 ` Will Deacon
2013-04-12 15:29 ` Marc Zyngier
2013-04-12 15:29 ` Marc Zyngier
2013-04-23 22:57 ` Christoffer Dall
2013-04-23 22:57 ` Christoffer Dall
2013-04-24 10:04 ` Marc Zyngier
2013-04-24 10:04 ` Marc Zyngier
2013-04-24 16:46 ` Christoffer Dall
2013-04-24 16:46 ` Christoffer Dall
2013-04-29 16:26 ` Catalin Marinas
2013-04-29 16:26 ` Catalin Marinas
2013-05-07 16:29 ` Marc Zyngier
2013-05-07 16:29 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 08/32] arm64: KVM: architecture specific MMU backend Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 22:58 ` Christoffer Dall
2013-04-23 22:58 ` Christoffer Dall
2013-04-24 11:03 ` Marc Zyngier
2013-04-24 11:03 ` Marc Zyngier
2013-04-24 11:10 ` Will Deacon
2013-04-24 11:10 ` Will Deacon
2013-04-24 16:50 ` Christoffer Dall
2013-04-24 16:50 ` Christoffer Dall
2013-04-24 16:55 ` Christoffer Dall
2013-04-24 16:55 ` Christoffer Dall
2013-04-25 12:59 ` Marc Zyngier
2013-04-25 12:59 ` Marc Zyngier
2013-04-25 15:13 ` Christoffer Dall
2013-04-25 15:13 ` Christoffer Dall
2013-04-29 17:35 ` Catalin Marinas
2013-04-29 17:35 ` Catalin Marinas
2013-04-30 10:23 ` Marc Zyngier
2013-04-30 10:23 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 09/32] arm64: KVM: user space interface Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-10 16:45 ` Will Deacon
2013-04-10 16:45 ` Will Deacon
2013-04-12 15:31 ` Marc Zyngier
2013-04-12 15:31 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 10/32] arm64: KVM: system register handling Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-10 17:04 ` Will Deacon
2013-04-10 17:04 ` Will Deacon
2013-04-12 15:48 ` Marc Zyngier
2013-04-12 15:48 ` Marc Zyngier
2013-04-23 23:01 ` Christoffer Dall
2013-04-23 23:01 ` Christoffer Dall
2013-04-24 13:37 ` Marc Zyngier
2013-04-24 13:37 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 11/32] arm64: KVM: CPU specific system registers handling Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-10 17:06 ` Will Deacon
2013-04-10 17:06 ` Will Deacon
2013-04-12 16:04 ` Marc Zyngier
2013-04-12 16:04 ` Marc Zyngier
2013-04-23 22:59 ` Christoffer Dall
2013-04-23 22:59 ` Christoffer Dall
2013-04-24 9:33 ` Marc Zyngier
2013-04-24 9:33 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 12/32] arm64: KVM: virtual CPU reset Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-10 17:07 ` Will Deacon
2013-04-10 17:07 ` Will Deacon
2013-04-12 16:04 ` Marc Zyngier
2013-04-12 16:04 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 13/32] arm64: KVM: kvm_arch and kvm_vcpu_arch definitions Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 14/32] arm64: KVM: MMIO access backend Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 15/32] arm64: KVM: guest one-reg interface Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-10 17:13 ` Will Deacon
2013-04-10 17:13 ` Will Deacon
2013-04-12 16:35 ` Marc Zyngier
2013-04-12 16:35 ` Marc Zyngier
2013-04-23 22:59 ` Christoffer Dall
2013-04-23 22:59 ` Christoffer Dall
2013-04-24 11:27 ` Marc Zyngier
2013-04-24 11:27 ` Marc Zyngier
2013-04-24 17:05 ` Christoffer Dall
2013-04-24 17:05 ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 16/32] arm64: KVM: hypervisor initialization code Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-05-02 11:03 ` Catalin Marinas
2013-05-02 11:03 ` Catalin Marinas
2013-05-02 13:28 ` Marc Zyngier
2013-05-02 13:28 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 17/32] arm64: KVM: HYP mode world switch implementation Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 22:59 ` Christoffer Dall
2013-04-23 22:59 ` Christoffer Dall
2013-04-24 11:39 ` Marc Zyngier
2013-04-24 11:39 ` Marc Zyngier
2013-04-24 17:08 ` Christoffer Dall
2013-04-24 17:08 ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 18/32] arm64: KVM: Exit handling Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 19/32] arm64: KVM: Plug the VGIC Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 23:00 ` Christoffer Dall
2013-04-23 23:00 ` Christoffer Dall
2013-04-24 11:43 ` Marc Zyngier
2013-04-24 11:43 ` Marc Zyngier
2013-05-02 14:38 ` Catalin Marinas
2013-05-02 14:38 ` Catalin Marinas
2013-04-08 16:17 ` [PATCH v3 20/32] arm64: KVM: Plug the arch timer Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 23:00 ` Christoffer Dall
2013-04-23 23:00 ` Christoffer Dall
2013-04-24 11:43 ` Marc Zyngier
2013-04-24 11:43 ` Marc Zyngier
2013-05-02 15:31 ` Catalin Marinas
2013-05-02 15:31 ` Catalin Marinas
2013-04-08 16:17 ` [PATCH v3 21/32] arm64: KVM: PSCI implementation Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 22/32] arm64: KVM: Build system integration Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 23/32] arm64: KVM: define 32bit specific registers Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 24/32] arm64: KVM: 32bit GP register access Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 23:00 ` Christoffer Dall
2013-04-23 23:00 ` Christoffer Dall
2013-04-24 13:06 ` Marc Zyngier
2013-04-24 13:06 ` Marc Zyngier
2013-04-24 17:09 ` Christoffer Dall
2013-04-24 17:09 ` Christoffer Dall
2013-05-02 16:09 ` Catalin Marinas
2013-05-02 16:09 ` Catalin Marinas
2013-05-07 16:28 ` Marc Zyngier
2013-05-07 16:28 ` Marc Zyngier
2013-05-07 16:33 ` Catalin Marinas
2013-05-07 16:33 ` Catalin Marinas
2013-05-11 0:36 ` Christoffer Dall
2013-05-11 0:36 ` Christoffer Dall
2013-05-11 7:51 ` Peter Maydell
2013-05-11 7:51 ` Peter Maydell
2013-05-11 9:43 ` Catalin Marinas
2013-05-11 9:43 ` Catalin Marinas
2013-05-12 18:51 ` Christoffer Dall
2013-05-12 18:51 ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 25/32] arm64: KVM: 32bit conditional execution emulation Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 23:00 ` Christoffer Dall
2013-04-23 23:00 ` Christoffer Dall
2013-04-24 13:13 ` Marc Zyngier
2013-04-24 13:13 ` Marc Zyngier
2013-04-24 17:11 ` Christoffer Dall
2013-04-24 17:11 ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 26/32] arm64: KVM: 32bit handling of coprocessor traps Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 23:01 ` Christoffer Dall
2013-04-23 23:01 ` Christoffer Dall
2013-04-24 13:42 ` Marc Zyngier [this message]
2013-04-24 13:42 ` Marc Zyngier
2013-04-24 17:14 ` Christoffer Dall
2013-04-24 17:14 ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 27/32] arm64: KVM: CPU specific 32bit coprocessor access Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 28/32] arm64: KVM: 32bit specific register world switch Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 29/32] arm64: KVM: 32bit guest fault injection Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 23:02 ` Christoffer Dall
2013-04-23 23:02 ` Christoffer Dall
2013-04-24 13:46 ` Marc Zyngier
2013-04-24 13:46 ` Marc Zyngier
2013-04-24 17:15 ` Christoffer Dall
2013-04-24 17:15 ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 30/32] arm64: KVM: enable initialization of a 32bit vcpu Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 23:02 ` Christoffer Dall
2013-04-23 23:02 ` Christoffer Dall
2013-04-24 13:49 ` Marc Zyngier
2013-04-24 13:49 ` Marc Zyngier
2013-04-24 17:17 ` Christoffer Dall
2013-04-24 17:17 ` Christoffer Dall
2013-05-07 16:36 ` Marc Zyngier
2013-05-07 16:36 ` Marc Zyngier
2013-05-11 0:38 ` Christoffer Dall
2013-05-11 0:38 ` Christoffer Dall
2013-05-11 8:04 ` Peter Maydell
2013-05-11 8:04 ` Peter Maydell
2013-05-11 16:26 ` Christoffer Dall
2013-05-11 16:26 ` Christoffer Dall
2013-05-11 16:31 ` Peter Maydell
2013-05-11 16:31 ` Peter Maydell
2013-05-13 9:01 ` Marc Zyngier
2013-05-13 9:01 ` Marc Zyngier
2013-05-13 15:46 ` Christoffer Dall
2013-05-13 15:46 ` Christoffer Dall
2013-04-08 16:17 ` [PATCH v3 31/32] arm64: KVM: userspace API documentation Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 23:02 ` Christoffer Dall
2013-04-23 23:02 ` Christoffer Dall
2013-04-24 13:52 ` Marc Zyngier
2013-04-24 13:52 ` Marc Zyngier
2013-04-08 16:17 ` [PATCH v3 32/32] arm64: KVM: MAINTAINERS update Marc Zyngier
2013-04-08 16:17 ` Marc Zyngier
2013-04-23 23:04 ` [PATCH v3 00/32] Port of KVM to arm64 Christoffer Dall
2013-04-23 23:04 ` Christoffer Dall
2013-05-03 13:17 ` Catalin Marinas
2013-05-03 13:17 ` Catalin Marinas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5177E12C.8020909@arm.com \
--to=marc.zyngier@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.