From: rusty@rustcorp.com.au (Rusty Russell)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 4/8] ARM: KVM: split cp15 mrc/mcr and mrrc/mcrr handling.
Date: Fri, 09 Mar 2012 14:56:52 +1030 [thread overview]
Message-ID: <1331267212.23398.rusty@rustcorp.com.au> (raw)
From: Rusty Russell <rusty@rustcorp.com.au>
The hardware has separate traps for the two cases, so don't prematurely
unify them.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
arch/arm/include/asm/kvm_emulate.h | 3 +
arch/arm/kvm/arm.c | 4 +
arch/arm/kvm/emulate.c | 102 ++++++++++++++++++++----------------
3 files changed, 62 insertions(+), 47 deletions(-)
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h
index 029f45f..fa54247 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -44,7 +44,8 @@ int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run);
int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
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_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_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run);
int kvm_emulate_mmio_ls(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
unsigned long instr);
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index f27a96b..a6cf02b 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -377,8 +377,8 @@ static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
static int (*arm_exit_handlers[])(struct kvm_vcpu *vcpu, struct kvm_run *r) = {
[HSR_EC_WFI] = kvm_handle_wfi,
- [HSR_EC_CP15_32] = kvm_handle_cp15_access,
- [HSR_EC_CP15_64] = kvm_handle_cp15_access,
+ [HSR_EC_CP15_32] = kvm_handle_cp15_32,
+ [HSR_EC_CP15_64] = kvm_handle_cp15_64,
[HSR_EC_CP14_MR] = kvm_handle_cp14_access,
[HSR_EC_CP14_LS] = kvm_handle_cp14_load_store,
[HSR_EC_CP14_64] = kvm_handle_cp14_access,
diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c
index 87a1141..88c6493 100644
--- a/arch/arm/kvm/emulate.c
+++ b/arch/arm/kvm/emulate.c
@@ -304,62 +304,31 @@ static int emulate_cp15_c15_access(struct kvm_vcpu *vcpu,
return 0;
}
-/**
- * kvm_handle_cp15_access -- handles a trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run: The kvm_run struct
- *
- * Investigates the CRn/CRm and wether this was mcr/mrc or mcrr/mrrc and either
- * simply errors out if the operation was not supported (should maybe raise
- * undefined to guest instead?) and otherwise emulated access.
- */
-int kvm_handle_cp15_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static int emulate_cp15(struct kvm_vcpu *vcpu,
+ const struct coproc_params *params)
{
- unsigned long hsr_ec, instr_len;
- struct coproc_params params;
- int ret = 0;
-
- hsr_ec = vcpu->arch.hsr >> HSR_EC_SHIFT;
- params.CRm = (vcpu->arch.hsr >> 1) & 0xf;
- params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf;
- BUG_ON(params.Rt1 >= 15);
- params.is_write = ((vcpu->arch.hsr & 1) == 0);
- params.is_64bit = (hsr_ec == HSR_EC_CP15_64);
-
- if (params.is_64bit) {
- /* mrrc, mccr operation */
- params.Op1 = (vcpu->arch.hsr >> 16) & 0xf;
- params.Op2 = 0;
- params.Rt2 = (vcpu->arch.hsr >> 10) & 0xf;
- BUG_ON(params.Rt2 >= 15);
- params.CRn = 0;
- } else {
- params.CRn = (vcpu->arch.hsr >> 10) & 0xf;
- params.Op1 = (vcpu->arch.hsr >> 14) & 0x7;
- params.Op2 = (vcpu->arch.hsr >> 17) & 0x7;
- params.Rt2 = 0;
- }
+ unsigned long instr_len;
+ int ret;
/* So far no mrrc/mcrr accesses are emulated */
- if (params.is_64bit)
+ if (params->is_64bit)
goto unsupp_err_out;
- switch (params.CRn) {
+ switch (params->CRn) {
case 9:
- ret = emulate_cp15_c9_access(vcpu, ¶ms);
+ ret = emulate_cp15_c9_access(vcpu, params);
break;
case 10:
- ret = emulate_cp15_c10_access(vcpu, ¶ms);
+ ret = emulate_cp15_c10_access(vcpu, params);
break;
case 15:
- ret = emulate_cp15_c15_access(vcpu, ¶ms);
+ ret = emulate_cp15_c15_access(vcpu, params);
break;
default:
ret = -EINVAL;
- break;
}
- if (ret)
+ if (ret != 0)
goto unsupp_err_out;
/* Skip instruction, since it was emulated */
@@ -367,10 +336,55 @@ int kvm_handle_cp15_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
*vcpu_reg(vcpu, 15) += instr_len;
return ret;
-unsupp_err_out:
+
+unsupp_err_out:
kvm_err("Unsupported guest CP15 access at: %08x\n", vcpu->arch.regs.pc);
- print_cp_instr(¶ms);
- return -EINVAL;
+ print_cp_instr(params);
+ return ret;
+}
+
+/**
+ * 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 coproc_params params;
+
+ params.CRm = (vcpu->arch.hsr >> 1) & 0xf;
+ params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf;
+ params.is_write = ((vcpu->arch.hsr & 1) == 0);
+ params.is_64bit = true;
+
+ params.Op1 = (vcpu->arch.hsr >> 16) & 0xf;
+ params.Op2 = 0;
+ params.Rt2 = (vcpu->arch.hsr >> 10) & 0xf;
+ params.CRn = 0;
+
+ return emulate_cp15(vcpu, ¶ms);
+}
+
+/**
+ * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run: The kvm_run struct
+ */
+int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ struct coproc_params params;
+
+ params.CRm = (vcpu->arch.hsr >> 1) & 0xf;
+ params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf;
+ params.is_write = ((vcpu->arch.hsr & 1) == 0);
+ params.is_64bit = false;
+
+ params.CRn = (vcpu->arch.hsr >> 10) & 0xf;
+ params.Op1 = (vcpu->arch.hsr >> 14) & 0x7;
+ params.Op2 = (vcpu->arch.hsr >> 17) & 0x7;
+ params.Rt2 = 0;
+
+ return emulate_cp15(vcpu, ¶ms);
}
/**
WARNING: multiple messages have this Message-ID (diff)
From: Rusty Russell <rusty@rustcorp.com.au>
To: Russell King <linux@arm.linux.org.uk>,
linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 4/8] ARM: KVM: split cp15 mrc/mcr and mrrc/mcrr handling.
Date: Fri, 09 Mar 2012 14:56:52 +1030 [thread overview]
Message-ID: <1331267212.23398.rusty@rustcorp.com.au> (raw)
From: Rusty Russell <rusty@rustcorp.com.au>
The hardware has separate traps for the two cases, so don't prematurely
unify them.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
arch/arm/include/asm/kvm_emulate.h | 3 +
arch/arm/kvm/arm.c | 4 +
arch/arm/kvm/emulate.c | 102 ++++++++++++++++++++----------------
3 files changed, 62 insertions(+), 47 deletions(-)
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h
index 029f45f..fa54247 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -44,7 +44,8 @@ int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run);
int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
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_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_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run);
int kvm_emulate_mmio_ls(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
unsigned long instr);
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index f27a96b..a6cf02b 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -377,8 +377,8 @@ static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
static int (*arm_exit_handlers[])(struct kvm_vcpu *vcpu, struct kvm_run *r) = {
[HSR_EC_WFI] = kvm_handle_wfi,
- [HSR_EC_CP15_32] = kvm_handle_cp15_access,
- [HSR_EC_CP15_64] = kvm_handle_cp15_access,
+ [HSR_EC_CP15_32] = kvm_handle_cp15_32,
+ [HSR_EC_CP15_64] = kvm_handle_cp15_64,
[HSR_EC_CP14_MR] = kvm_handle_cp14_access,
[HSR_EC_CP14_LS] = kvm_handle_cp14_load_store,
[HSR_EC_CP14_64] = kvm_handle_cp14_access,
diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c
index 87a1141..88c6493 100644
--- a/arch/arm/kvm/emulate.c
+++ b/arch/arm/kvm/emulate.c
@@ -304,62 +304,31 @@ static int emulate_cp15_c15_access(struct kvm_vcpu *vcpu,
return 0;
}
-/**
- * kvm_handle_cp15_access -- handles a trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run: The kvm_run struct
- *
- * Investigates the CRn/CRm and wether this was mcr/mrc or mcrr/mrrc and either
- * simply errors out if the operation was not supported (should maybe raise
- * undefined to guest instead?) and otherwise emulated access.
- */
-int kvm_handle_cp15_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static int emulate_cp15(struct kvm_vcpu *vcpu,
+ const struct coproc_params *params)
{
- unsigned long hsr_ec, instr_len;
- struct coproc_params params;
- int ret = 0;
-
- hsr_ec = vcpu->arch.hsr >> HSR_EC_SHIFT;
- params.CRm = (vcpu->arch.hsr >> 1) & 0xf;
- params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf;
- BUG_ON(params.Rt1 >= 15);
- params.is_write = ((vcpu->arch.hsr & 1) == 0);
- params.is_64bit = (hsr_ec == HSR_EC_CP15_64);
-
- if (params.is_64bit) {
- /* mrrc, mccr operation */
- params.Op1 = (vcpu->arch.hsr >> 16) & 0xf;
- params.Op2 = 0;
- params.Rt2 = (vcpu->arch.hsr >> 10) & 0xf;
- BUG_ON(params.Rt2 >= 15);
- params.CRn = 0;
- } else {
- params.CRn = (vcpu->arch.hsr >> 10) & 0xf;
- params.Op1 = (vcpu->arch.hsr >> 14) & 0x7;
- params.Op2 = (vcpu->arch.hsr >> 17) & 0x7;
- params.Rt2 = 0;
- }
+ unsigned long instr_len;
+ int ret;
/* So far no mrrc/mcrr accesses are emulated */
- if (params.is_64bit)
+ if (params->is_64bit)
goto unsupp_err_out;
- switch (params.CRn) {
+ switch (params->CRn) {
case 9:
- ret = emulate_cp15_c9_access(vcpu, ¶ms);
+ ret = emulate_cp15_c9_access(vcpu, params);
break;
case 10:
- ret = emulate_cp15_c10_access(vcpu, ¶ms);
+ ret = emulate_cp15_c10_access(vcpu, params);
break;
case 15:
- ret = emulate_cp15_c15_access(vcpu, ¶ms);
+ ret = emulate_cp15_c15_access(vcpu, params);
break;
default:
ret = -EINVAL;
- break;
}
- if (ret)
+ if (ret != 0)
goto unsupp_err_out;
/* Skip instruction, since it was emulated */
@@ -367,10 +336,55 @@ int kvm_handle_cp15_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
*vcpu_reg(vcpu, 15) += instr_len;
return ret;
-unsupp_err_out:
+
+unsupp_err_out:
kvm_err("Unsupported guest CP15 access at: %08x\n", vcpu->arch.regs.pc);
- print_cp_instr(¶ms);
- return -EINVAL;
+ print_cp_instr(params);
+ return ret;
+}
+
+/**
+ * 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 coproc_params params;
+
+ params.CRm = (vcpu->arch.hsr >> 1) & 0xf;
+ params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf;
+ params.is_write = ((vcpu->arch.hsr & 1) == 0);
+ params.is_64bit = true;
+
+ params.Op1 = (vcpu->arch.hsr >> 16) & 0xf;
+ params.Op2 = 0;
+ params.Rt2 = (vcpu->arch.hsr >> 10) & 0xf;
+ params.CRn = 0;
+
+ return emulate_cp15(vcpu, ¶ms);
+}
+
+/**
+ * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run: The kvm_run struct
+ */
+int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+ struct coproc_params params;
+
+ params.CRm = (vcpu->arch.hsr >> 1) & 0xf;
+ params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf;
+ params.is_write = ((vcpu->arch.hsr & 1) == 0);
+ params.is_64bit = false;
+
+ params.CRn = (vcpu->arch.hsr >> 10) & 0xf;
+ params.Op1 = (vcpu->arch.hsr >> 14) & 0x7;
+ params.Op2 = (vcpu->arch.hsr >> 17) & 0x7;
+ params.Rt2 = 0;
+
+ return emulate_cp15(vcpu, ¶ms);
}
/**
next reply other threads:[~2012-03-09 4:26 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-09 4:26 Rusty Russell [this message]
2012-03-09 4:26 ` [PATCH 4/8] ARM: KVM: split cp15 mrc/mcr and mrrc/mcrr handling Rusty Russell
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=1331267212.23398.rusty@rustcorp.com.au \
--to=rusty@rustcorp.com.au \
--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.