From: Marc Zyngier <maz@kernel.org>
To: James Morse <james.morse@arm.com>
Cc: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 3/3] KVM: arm64: Add emulation for 32bit guests accessing ACTLR2
Date: Thu, 28 May 2020 13:51:33 +0100 [thread overview]
Message-ID: <1da83682a9ba3704601cb2071e8b638d@kernel.org> (raw)
In-Reply-To: <20200526161834.29165-4-james.morse@arm.com>
Hi James,
On 2020-05-26 17:18, James Morse wrote:
> ACTLR_EL1 is a 64bit register while the 32bit ACTLR is obviously 32bit.
> For 32bit software, the extra bits are accessible via ACTLR2... which
> KVM doesn't emulate.
>
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
> I'm not convinced this is endian safe, but it does match what
> kvm_inject_undef32() do.
>
> The alternative would be to always read the 64bit value, and generate
> the 32bit offets like access_vm_reg() does.
>
> arch/arm64/include/asm/kvm_host.h | 1 +
> arch/arm64/kvm/sys_regs_generic_v8.c | 16 +++++++++++++++-
> 2 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h
> b/arch/arm64/include/asm/kvm_host.h
> index 32c8a675e5a4..5b7538663a8e 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -185,6 +185,7 @@ enum vcpu_sysreg {
> #define c0_CSSELR (CSSELR_EL1 * 2)/* Cache Size Selection Register */
> #define c1_SCTLR (SCTLR_EL1 * 2) /* System Control Register */
> #define c1_ACTLR (ACTLR_EL1 * 2) /* Auxiliary Control Register */
> +#define c1_ACTLR2 (c1_ACTLR + 1) /* ACTLR top 32 bits */
> #define c1_CPACR (CPACR_EL1 * 2) /* Coprocessor Access Control */
> #define c2_TTBR0 (TTBR0_EL1 * 2) /* Translation Table Base Register 0
> */
> #define c2_TTBR0_high (c2_TTBR0 + 1) /* TTBR0 top 32 bits */
> diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c
> b/arch/arm64/kvm/sys_regs_generic_v8.c
> index 9cb6b4c8355a..ed77bbb48e64 100644
> --- a/arch/arm64/kvm/sys_regs_generic_v8.c
> +++ b/arch/arm64/kvm/sys_regs_generic_v8.c
> @@ -30,6 +30,18 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
> return true;
> }
>
> +static bool access_cp15_actlr(struct kvm_vcpu *vcpu,
> + struct sys_reg_params *p,
> + const struct sys_reg_desc *r)
> +{
> + if (p->is_write)
> + return ignore_write(vcpu, p);
> +
> + p->regval = vcpu_cp15(vcpu, r->reg);
> + return true;
> +
> +}
> +
> static void reset_actlr(struct kvm_vcpu *vcpu, const struct
> sys_reg_desc *r)
> {
> __vcpu_sys_reg(vcpu, ACTLR_EL1) = read_sysreg(actlr_el1);
> @@ -46,7 +58,9 @@ static const struct sys_reg_desc genericv8_sys_regs[]
> = {
> static const struct sys_reg_desc genericv8_cp15_regs[] = {
> /* ACTLR */
> { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001),
> - access_actlr },
> + access_cp15_actlr, NULL, c1_ACTLR },
> + { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b011),
> + access_cp15_actlr, NULL, c1_ACTLR2 },
> };
>
> static struct kvm_sys_reg_target_table genericv8_target_table = {
I'd get rid of any form of storage, and go with something like
(untested, again):
diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c
b/arch/arm64/kvm/sys_regs_generic_v8.c
index 9cb6b4c8355a..1b2bf2d37612 100644
--- a/arch/arm64/kvm/sys_regs_generic_v8.c
+++ b/arch/arm64/kvm/sys_regs_generic_v8.c
@@ -26,13 +26,16 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
if (p->is_write)
return ignore_write(vcpu, p);
- p->regval = vcpu_read_sys_reg(vcpu, ACTLR_EL1);
- return true;
-}
+ p->regval = read_sysreg(actlr_el1);
-static void reset_actlr(struct kvm_vcpu *vcpu, const struct
sys_reg_desc *r)
-{
- __vcpu_sys_reg(vcpu, ACTLR_EL1) = read_sysreg(actlr_el1);
+ if (p->aarch32) {
+ if (r->Op2 & 2)
+ p->regval = upper_32_bit(p->regval);
+ else
+ p->regval = lower_32_bit(p->regval);
+ }
+
+ return true;
}
/*
@@ -40,13 +43,13 @@ static void reset_actlr(struct kvm_vcpu *vcpu, const
struct sys_reg_desc *r)
* Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
*/
static const struct sys_reg_desc genericv8_sys_regs[] = {
- { SYS_DESC(SYS_ACTLR_EL1), access_actlr, reset_actlr, ACTLR_EL1 },
+ { SYS_DESC(SYS_ACTLR_EL1), access_actlr, },
};
static const struct sys_reg_desc genericv8_cp15_regs[] = {
/* ACTLR */
- { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001),
- access_actlr },
+ { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001), access_actlr },
+ { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b011), access_actlr },
};
static struct kvm_sys_reg_target_table genericv8_target_table = {
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
WARNING: multiple messages have this Message-ID (diff)
From: Marc Zyngier <maz@kernel.org>
To: James Morse <james.morse@arm.com>
Cc: Julien Thierry <julien.thierry.kdev@gmail.com>,
kvmarm@lists.cs.columbia.edu,
linux-arm-kernel@lists.infradead.org,
Suzuki K Poulose <suzuki.poulose@arm.com>
Subject: Re: [PATCH 3/3] KVM: arm64: Add emulation for 32bit guests accessing ACTLR2
Date: Thu, 28 May 2020 13:51:33 +0100 [thread overview]
Message-ID: <1da83682a9ba3704601cb2071e8b638d@kernel.org> (raw)
In-Reply-To: <20200526161834.29165-4-james.morse@arm.com>
Hi James,
On 2020-05-26 17:18, James Morse wrote:
> ACTLR_EL1 is a 64bit register while the 32bit ACTLR is obviously 32bit.
> For 32bit software, the extra bits are accessible via ACTLR2... which
> KVM doesn't emulate.
>
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
> I'm not convinced this is endian safe, but it does match what
> kvm_inject_undef32() do.
>
> The alternative would be to always read the 64bit value, and generate
> the 32bit offets like access_vm_reg() does.
>
> arch/arm64/include/asm/kvm_host.h | 1 +
> arch/arm64/kvm/sys_regs_generic_v8.c | 16 +++++++++++++++-
> 2 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h
> b/arch/arm64/include/asm/kvm_host.h
> index 32c8a675e5a4..5b7538663a8e 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -185,6 +185,7 @@ enum vcpu_sysreg {
> #define c0_CSSELR (CSSELR_EL1 * 2)/* Cache Size Selection Register */
> #define c1_SCTLR (SCTLR_EL1 * 2) /* System Control Register */
> #define c1_ACTLR (ACTLR_EL1 * 2) /* Auxiliary Control Register */
> +#define c1_ACTLR2 (c1_ACTLR + 1) /* ACTLR top 32 bits */
> #define c1_CPACR (CPACR_EL1 * 2) /* Coprocessor Access Control */
> #define c2_TTBR0 (TTBR0_EL1 * 2) /* Translation Table Base Register 0
> */
> #define c2_TTBR0_high (c2_TTBR0 + 1) /* TTBR0 top 32 bits */
> diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c
> b/arch/arm64/kvm/sys_regs_generic_v8.c
> index 9cb6b4c8355a..ed77bbb48e64 100644
> --- a/arch/arm64/kvm/sys_regs_generic_v8.c
> +++ b/arch/arm64/kvm/sys_regs_generic_v8.c
> @@ -30,6 +30,18 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
> return true;
> }
>
> +static bool access_cp15_actlr(struct kvm_vcpu *vcpu,
> + struct sys_reg_params *p,
> + const struct sys_reg_desc *r)
> +{
> + if (p->is_write)
> + return ignore_write(vcpu, p);
> +
> + p->regval = vcpu_cp15(vcpu, r->reg);
> + return true;
> +
> +}
> +
> static void reset_actlr(struct kvm_vcpu *vcpu, const struct
> sys_reg_desc *r)
> {
> __vcpu_sys_reg(vcpu, ACTLR_EL1) = read_sysreg(actlr_el1);
> @@ -46,7 +58,9 @@ static const struct sys_reg_desc genericv8_sys_regs[]
> = {
> static const struct sys_reg_desc genericv8_cp15_regs[] = {
> /* ACTLR */
> { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001),
> - access_actlr },
> + access_cp15_actlr, NULL, c1_ACTLR },
> + { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b011),
> + access_cp15_actlr, NULL, c1_ACTLR2 },
> };
>
> static struct kvm_sys_reg_target_table genericv8_target_table = {
I'd get rid of any form of storage, and go with something like
(untested, again):
diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c
b/arch/arm64/kvm/sys_regs_generic_v8.c
index 9cb6b4c8355a..1b2bf2d37612 100644
--- a/arch/arm64/kvm/sys_regs_generic_v8.c
+++ b/arch/arm64/kvm/sys_regs_generic_v8.c
@@ -26,13 +26,16 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
if (p->is_write)
return ignore_write(vcpu, p);
- p->regval = vcpu_read_sys_reg(vcpu, ACTLR_EL1);
- return true;
-}
+ p->regval = read_sysreg(actlr_el1);
-static void reset_actlr(struct kvm_vcpu *vcpu, const struct
sys_reg_desc *r)
-{
- __vcpu_sys_reg(vcpu, ACTLR_EL1) = read_sysreg(actlr_el1);
+ if (p->aarch32) {
+ if (r->Op2 & 2)
+ p->regval = upper_32_bit(p->regval);
+ else
+ p->regval = lower_32_bit(p->regval);
+ }
+
+ return true;
}
/*
@@ -40,13 +43,13 @@ static void reset_actlr(struct kvm_vcpu *vcpu, const
struct sys_reg_desc *r)
* Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
*/
static const struct sys_reg_desc genericv8_sys_regs[] = {
- { SYS_DESC(SYS_ACTLR_EL1), access_actlr, reset_actlr, ACTLR_EL1 },
+ { SYS_DESC(SYS_ACTLR_EL1), access_actlr, },
};
static const struct sys_reg_desc genericv8_cp15_regs[] = {
/* ACTLR */
- { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001),
- access_actlr },
+ { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001), access_actlr },
+ { Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b011), access_actlr },
};
static struct kvm_sys_reg_target_table genericv8_target_table = {
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-05-28 12:51 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-26 16:18 [PATCH 0/3] KVM: arm64: aarch32 ACTLR accesses James Morse
2020-05-26 16:18 ` James Morse
2020-05-26 16:18 ` [PATCH 1/3] KVM: arm64: Stop writing aarch32's CSSELR into ACTLR James Morse
2020-05-26 16:18 ` James Morse
2020-05-26 16:18 ` James Morse
2020-05-27 16:57 ` Sasha Levin
2020-05-27 16:57 ` Sasha Levin
2020-05-27 16:57 ` Sasha Levin
2020-05-28 8:57 ` Marc Zyngier
2020-05-28 8:57 ` Marc Zyngier
2020-05-28 8:57 ` Marc Zyngier
2020-05-28 11:59 ` James Morse
2020-05-28 11:59 ` James Morse
2020-05-28 11:59 ` James Morse
2020-05-28 12:10 ` Marc Zyngier
2020-05-28 12:10 ` Marc Zyngier
2020-05-28 12:10 ` Marc Zyngier
2020-05-26 16:18 ` [PATCH 2/3] KVM: arm64: Stop save/restoring ACTLR_EL1 James Morse
2020-05-26 16:18 ` James Morse
2020-05-28 12:36 ` Marc Zyngier
2020-05-28 12:36 ` Marc Zyngier
2020-05-28 12:38 ` Marc Zyngier
2020-05-28 12:38 ` Marc Zyngier
2020-05-28 12:55 ` James Morse
2020-05-28 12:55 ` James Morse
2020-05-26 16:18 ` [PATCH 3/3] KVM: arm64: Add emulation for 32bit guests accessing ACTLR2 James Morse
2020-05-26 16:18 ` James Morse
2020-05-28 12:51 ` Marc Zyngier [this message]
2020-05-28 12:51 ` Marc Zyngier
2020-05-31 13:37 ` [PATCH 0/3] KVM: arm64: aarch32 ACTLR accesses Marc Zyngier
2020-05-31 13:37 ` Marc Zyngier
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=1da83682a9ba3704601cb2071e8b638d@kernel.org \
--to=maz@kernel.org \
--cc=james.morse@arm.com \
--cc=kvmarm@lists.cs.columbia.edu \
--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.