From: Marc Zyngier <maz@kernel.org>
To: Peng Liang <liangpeng10@huawei.com>
Cc: will@kernel.org, kvmarm@lists.cs.columbia.edu,
kvm@vger.kernel.org, zhang.zhanghailiang@huawei.com
Subject: Re: [RFC 2/4] kvm: arm64: emulate the ID registers
Date: Fri, 14 Aug 2020 13:20:13 +0100 [thread overview]
Message-ID: <08de5a7ea8d371a5328044cb2039ea83@kernel.org> (raw)
In-Reply-To: <20200813060517.2360048-3-liangpeng10@huawei.com>
On 2020-08-13 07:05, Peng Liang wrote:
> To emulate the ID registers, we need a place to storage the values of
> the ID regsiters. Maybe putting in kvm_arch_vcpu is a good idea.
>
> This commit has no functional changes but only code refactor. When
> initializing a vcpu, get the values of the ID registers from
> arm64_ftr_regs and storage them in kvm_arch_vcpu. And we just read
> the value from kvm_arch_vcpu when getting/setting the value of the ID
> regs.
>
> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
> Signed-off-by: Peng Liang <liangpeng10@huawei.com>
> ---
> arch/arm64/include/asm/kvm_host.h | 2 ++
> arch/arm64/kvm/arm.c | 20 ++++++++++++++++++++
> arch/arm64/kvm/sys_regs.c | 27 +++++++++++++++++++++++----
> include/uapi/linux/kvm.h | 11 +++++++++++
> 4 files changed, 56 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h
> b/arch/arm64/include/asm/kvm_host.h
> index f81151ad3d3c..7f7bd36702f7 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -336,6 +336,8 @@ struct kvm_vcpu_arch {
> u64 last_steal;
> gpa_t base;
> } steal;
> +
> + struct id_registers idregs;
System registers are to be stored in the sysreg file. I've already
spent enough time moving them out of the various subsystems.
> };
>
> /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 73e12869afe3..18ebbe1c64ee 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -262,6 +262,24 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm,
> unsigned int id)
> return 0;
> }
>
> +static int get_cpu_ftr(u32 id, u64 val, void *argp)
> +{
> + struct id_registers *idregs = argp;
> +
> + /*
> + * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
> + * where 1<=crm<8, 0<=op2<8.
> + */
> + if (sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&
> + sys_reg_CRn(id) == 0 && sys_reg_CRm(id) > 0) {
> + idregs->regs[idregs->num].sys_id = id;
> + idregs->regs[idregs->num].sys_val = val;
> + idregs->num++;
> + }
> +
> + return 0;
> +}
> +
> int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
> {
> int err;
> @@ -285,6 +303,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
> if (err)
> return err;
>
> + arm64_cpu_ftr_regs_traverse(get_cpu_ftr, &vcpu->arch.idregs);
> +
> return create_hyp_mappings(vcpu, vcpu + 1, PAGE_HYP);
> }
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 138961d7ebe3..776c2757a01e 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1092,13 +1092,32 @@ static bool access_arch_timer(struct kvm_vcpu
> *vcpu,
> return true;
> }
>
> +static struct id_reg_info *kvm_id_reg(struct kvm_vcpu *vcpu, u64 id)
> +{
> + int i;
> +
> + for (i = 0; i < vcpu->arch.idregs.num; ++i) {
> + if (vcpu->arch.idregs.regs[i].sys_id == id)
> + return &vcpu->arch.idregs.regs[i];
> + }
> + return NULL;
> +}
> +
> +static u64 kvm_get_id_reg(struct kvm_vcpu *vcpu, u64 id)
> +{
> + struct id_reg_info *ri = kvm_id_reg(vcpu, id);
> +
> + BUG_ON(!ri);
> + return ri->sys_val;
> +}
> +
> /* Read a sanitised cpufeature ID register by sys_reg_desc */
> -static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> +static u64 read_id_reg(struct kvm_vcpu *vcpu,
> struct sys_reg_desc const *r, bool raz)
> {
> u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
> (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
> - u64 val = raz ? 0 : read_sanitised_ftr_reg(id);
> + u64 val = raz ? 0 : kvm_get_id_reg(vcpu, id);
>
> if (id == SYS_ID_AA64PFR0_EL1) {
> if (!vcpu_has_sve(vcpu))
> @@ -1238,7 +1257,7 @@ static int set_id_aa64zfr0_el1(struct kvm_vcpu
> *vcpu,
> * are stored, and for set_id_reg() we don't allow the effective value
> * to be changed.
> */
> -static int __get_id_reg(const struct kvm_vcpu *vcpu,
> +static int __get_id_reg(struct kvm_vcpu *vcpu,
> const struct sys_reg_desc *rd, void __user *uaddr,
> bool raz)
> {
> @@ -1248,7 +1267,7 @@ static int __get_id_reg(const struct kvm_vcpu
> *vcpu,
> return reg_to_user(uaddr, &val, id);
> }
>
> -static int __set_id_reg(const struct kvm_vcpu *vcpu,
> +static int __set_id_reg(struct kvm_vcpu *vcpu,
> const struct sys_reg_desc *rd, void __user *uaddr,
> bool raz)
> {
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index f6d86033c4fa..1029444d04aa 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -1272,6 +1272,17 @@ struct kvm_vfio_spapr_tce {
> __s32 tablefd;
> };
>
> +#define ID_REG_MAX_NUMS 64
> +struct id_reg_info {
> + uint64_t sys_id;
> + uint64_t sys_val;
> +};
> +
> +struct id_registers {
> + struct id_reg_info regs[ID_REG_MAX_NUMS];
> + uint64_t num;
> +};
> +
> /*
> * ioctls for VM fds
> */
No way this is an acceptable interface. We have the one-reg interface,
which takes a system register encoding.
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: Peng Liang <liangpeng10@huawei.com>
Cc: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
will@kernel.org, zhang.zhanghailiang@huawei.com,
xiexiangyou@huawei.com
Subject: Re: [RFC 2/4] kvm: arm64: emulate the ID registers
Date: Fri, 14 Aug 2020 13:20:13 +0100 [thread overview]
Message-ID: <08de5a7ea8d371a5328044cb2039ea83@kernel.org> (raw)
In-Reply-To: <20200813060517.2360048-3-liangpeng10@huawei.com>
On 2020-08-13 07:05, Peng Liang wrote:
> To emulate the ID registers, we need a place to storage the values of
> the ID regsiters. Maybe putting in kvm_arch_vcpu is a good idea.
>
> This commit has no functional changes but only code refactor. When
> initializing a vcpu, get the values of the ID registers from
> arm64_ftr_regs and storage them in kvm_arch_vcpu. And we just read
> the value from kvm_arch_vcpu when getting/setting the value of the ID
> regs.
>
> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
> Signed-off-by: Peng Liang <liangpeng10@huawei.com>
> ---
> arch/arm64/include/asm/kvm_host.h | 2 ++
> arch/arm64/kvm/arm.c | 20 ++++++++++++++++++++
> arch/arm64/kvm/sys_regs.c | 27 +++++++++++++++++++++++----
> include/uapi/linux/kvm.h | 11 +++++++++++
> 4 files changed, 56 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h
> b/arch/arm64/include/asm/kvm_host.h
> index f81151ad3d3c..7f7bd36702f7 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -336,6 +336,8 @@ struct kvm_vcpu_arch {
> u64 last_steal;
> gpa_t base;
> } steal;
> +
> + struct id_registers idregs;
System registers are to be stored in the sysreg file. I've already
spent enough time moving them out of the various subsystems.
> };
>
> /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 73e12869afe3..18ebbe1c64ee 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -262,6 +262,24 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm,
> unsigned int id)
> return 0;
> }
>
> +static int get_cpu_ftr(u32 id, u64 val, void *argp)
> +{
> + struct id_registers *idregs = argp;
> +
> + /*
> + * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
> + * where 1<=crm<8, 0<=op2<8.
> + */
> + if (sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&
> + sys_reg_CRn(id) == 0 && sys_reg_CRm(id) > 0) {
> + idregs->regs[idregs->num].sys_id = id;
> + idregs->regs[idregs->num].sys_val = val;
> + idregs->num++;
> + }
> +
> + return 0;
> +}
> +
> int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
> {
> int err;
> @@ -285,6 +303,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
> if (err)
> return err;
>
> + arm64_cpu_ftr_regs_traverse(get_cpu_ftr, &vcpu->arch.idregs);
> +
> return create_hyp_mappings(vcpu, vcpu + 1, PAGE_HYP);
> }
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 138961d7ebe3..776c2757a01e 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1092,13 +1092,32 @@ static bool access_arch_timer(struct kvm_vcpu
> *vcpu,
> return true;
> }
>
> +static struct id_reg_info *kvm_id_reg(struct kvm_vcpu *vcpu, u64 id)
> +{
> + int i;
> +
> + for (i = 0; i < vcpu->arch.idregs.num; ++i) {
> + if (vcpu->arch.idregs.regs[i].sys_id == id)
> + return &vcpu->arch.idregs.regs[i];
> + }
> + return NULL;
> +}
> +
> +static u64 kvm_get_id_reg(struct kvm_vcpu *vcpu, u64 id)
> +{
> + struct id_reg_info *ri = kvm_id_reg(vcpu, id);
> +
> + BUG_ON(!ri);
> + return ri->sys_val;
> +}
> +
> /* Read a sanitised cpufeature ID register by sys_reg_desc */
> -static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> +static u64 read_id_reg(struct kvm_vcpu *vcpu,
> struct sys_reg_desc const *r, bool raz)
> {
> u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
> (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
> - u64 val = raz ? 0 : read_sanitised_ftr_reg(id);
> + u64 val = raz ? 0 : kvm_get_id_reg(vcpu, id);
>
> if (id == SYS_ID_AA64PFR0_EL1) {
> if (!vcpu_has_sve(vcpu))
> @@ -1238,7 +1257,7 @@ static int set_id_aa64zfr0_el1(struct kvm_vcpu
> *vcpu,
> * are stored, and for set_id_reg() we don't allow the effective value
> * to be changed.
> */
> -static int __get_id_reg(const struct kvm_vcpu *vcpu,
> +static int __get_id_reg(struct kvm_vcpu *vcpu,
> const struct sys_reg_desc *rd, void __user *uaddr,
> bool raz)
> {
> @@ -1248,7 +1267,7 @@ static int __get_id_reg(const struct kvm_vcpu
> *vcpu,
> return reg_to_user(uaddr, &val, id);
> }
>
> -static int __set_id_reg(const struct kvm_vcpu *vcpu,
> +static int __set_id_reg(struct kvm_vcpu *vcpu,
> const struct sys_reg_desc *rd, void __user *uaddr,
> bool raz)
> {
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index f6d86033c4fa..1029444d04aa 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -1272,6 +1272,17 @@ struct kvm_vfio_spapr_tce {
> __s32 tablefd;
> };
>
> +#define ID_REG_MAX_NUMS 64
> +struct id_reg_info {
> + uint64_t sys_id;
> + uint64_t sys_val;
> +};
> +
> +struct id_registers {
> + struct id_reg_info regs[ID_REG_MAX_NUMS];
> + uint64_t num;
> +};
> +
> /*
> * ioctls for VM fds
> */
No way this is an acceptable interface. We have the one-reg interface,
which takes a system register encoding.
M.
--
Jazz is not dead. It just smells funny...
next prev parent reply other threads:[~2020-08-14 12:20 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-13 6:05 [RFC 0/4] kvm: arm64: emulate ID registers Peng Liang
2020-08-13 6:05 ` Peng Liang
2020-08-13 6:05 ` [RFC 1/4] arm64: add a helper function to traverse arm64_ftr_regs Peng Liang
2020-08-13 6:05 ` Peng Liang
2020-08-13 6:05 ` [RFC 2/4] kvm: arm64: emulate the ID registers Peng Liang
2020-08-13 6:05 ` Peng Liang
2020-08-13 9:05 ` Andrew Jones
2020-08-13 9:05 ` Andrew Jones
2020-08-13 10:02 ` Andrew Jones
2020-08-13 10:02 ` Andrew Jones
2020-08-14 11:49 ` Peng Liang
2020-08-14 11:49 ` Peng Liang
2020-08-14 12:51 ` Andrew Jones
2020-08-14 12:51 ` Andrew Jones
2020-08-14 11:49 ` Peng Liang
2020-08-14 11:49 ` Peng Liang
2020-08-13 23:10 ` kernel test robot
2020-08-14 12:20 ` Marc Zyngier [this message]
2020-08-14 12:20 ` Marc Zyngier
2020-08-13 6:05 ` [RFC 3/4] kvm: arm64: make ID registers configurable Peng Liang
2020-08-13 6:05 ` Peng Liang
2020-08-13 9:09 ` Andrew Jones
2020-08-13 9:09 ` Andrew Jones
2020-08-14 11:49 ` Peng Liang
2020-08-14 11:49 ` Peng Liang
2020-08-13 9:52 ` Marc Zyngier
2020-08-13 9:52 ` Marc Zyngier
2020-08-13 6:05 ` [RFC 4/4] kvm: arm64: add KVM_CAP_ARM_CPU_FEATURE extension Peng Liang
2020-08-13 6:05 ` Peng Liang
2020-08-13 9:10 ` Andrew Jones
2020-08-13 9:10 ` Andrew Jones
2020-08-14 11:49 ` Peng Liang
2020-08-14 11:49 ` Peng Liang
2020-08-13 9:14 ` [RFC 0/4] kvm: arm64: emulate ID registers Andrew Jones
2020-08-13 9:14 ` Andrew Jones
2020-08-13 14:19 ` Andrew Jones
2020-08-13 14:19 ` Andrew Jones
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=08de5a7ea8d371a5328044cb2039ea83@kernel.org \
--to=maz@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=liangpeng10@huawei.com \
--cc=will@kernel.org \
--cc=zhang.zhanghailiang@huawei.com \
/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.