From: Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>
To: qemu-arm@nongnu.org, qemu-devel@nongnu.org,
peter.maydell@linaro.org, richard.henderson@linaro.org
Cc: darren@os.amperecomputing.com, Cornelia Huck <cohuck@redhat.com>
Subject: Re: [PATCH] arm/kvm: add support for MTE
Date: Mon, 15 Jul 2024 16:57:11 +0530 [thread overview]
Message-ID: <2b4bef01-5bcc-458c-9110-d2debe3f3620@os.amperecomputing.com> (raw)
In-Reply-To: <20240709060448.251881-1-gankulkarni@os.amperecomputing.com>
Hi Peter/Richard,
On 09-07-2024 11:34 am, Ganapatrao Kulkarni wrote:
> Extend the 'mte' property for the virt machine to cover KVM as
> well. For KVM, we don't allocate tag memory, but instead enable
> the capability.
>
> If MTE has been enabled, we need to disable migration, as we do not
> yet have a way to migrate the tags as well. Therefore, MTE will stay
> off with KVM unless requested explicitly.
>
> This patch is rework of commit b320e21c48ce64853904bea6631c0158cc2ef227
> which broke TCG since it made the TCG -cpu max
> report the presence of MTE to the guest even if the board hadn't
> enabled MTE by wiring up the tag RAM. This meant that if the guest
> then tried to use MTE QEMU would segfault accessing the
> non-existent tag RAM.
>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> Signed-off-by: Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>
> ---
>
> This patch is boot tested on ARM64 with KVM and on X86 with TCG for mte=on
> and default case(no mte).
Any comments on this patch?
Can this patch be merged in this merge cycle/window?
>
> hw/arm/virt.c | 72 ++++++++++++++++++++++++++------------------
> target/arm/cpu.h | 1 +
> target/arm/kvm.c | 40 ++++++++++++++++++++++++
> target/arm/kvm_arm.h | 19 ++++++++++++
> 4 files changed, 102 insertions(+), 30 deletions(-)
>
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index b0c68d66a3..cc9db79ec3 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2206,7 +2206,7 @@ static void machvirt_init(MachineState *machine)
> exit(1);
> }
>
> - if (vms->mte && (kvm_enabled() || hvf_enabled())) {
> + if (vms->mte && hvf_enabled()) {
> error_report("mach-virt: %s does not support providing "
> "MTE to the guest CPU",
> current_accel_name());
> @@ -2276,39 +2276,51 @@ static void machvirt_init(MachineState *machine)
> }
>
> if (vms->mte) {
> - /* Create the memory region only once, but link to all cpus. */
> - if (!tag_sysmem) {
> - /*
> - * The property exists only if MemTag is supported.
> - * If it is, we must allocate the ram to back that up.
> - */
> - if (!object_property_find(cpuobj, "tag-memory")) {
> - error_report("MTE requested, but not supported "
> - "by the guest CPU");
> - exit(1);
> + if (tcg_enabled()) {
> + /* Create the memory region only once, but link to all cpus. */
> + if (!tag_sysmem) {
> + /*
> + * The property exists only if MemTag is supported.
> + * If it is, we must allocate the ram to back that up.
> + */
> + if (!object_property_find(cpuobj, "tag-memory")) {
> + error_report("MTE requested, but not supported "
> + "by the guest CPU");
> + exit(1);
> + }
> +
> + tag_sysmem = g_new(MemoryRegion, 1);
> + memory_region_init(tag_sysmem, OBJECT(machine),
> + "tag-memory", UINT64_MAX / 32);
> +
> + if (vms->secure) {
> + secure_tag_sysmem = g_new(MemoryRegion, 1);
> + memory_region_init(secure_tag_sysmem, OBJECT(machine),
> + "secure-tag-memory",
> + UINT64_MAX / 32);
> +
> + /* As with ram, secure-tag takes precedence over tag. */
> + memory_region_add_subregion_overlap(secure_tag_sysmem,
> + 0, tag_sysmem, -1);
> + }
> }
>
> - tag_sysmem = g_new(MemoryRegion, 1);
> - memory_region_init(tag_sysmem, OBJECT(machine),
> - "tag-memory", UINT64_MAX / 32);
> -
> + object_property_set_link(cpuobj, "tag-memory",
> + OBJECT(tag_sysmem), &error_abort);
> if (vms->secure) {
> - secure_tag_sysmem = g_new(MemoryRegion, 1);
> - memory_region_init(secure_tag_sysmem, OBJECT(machine),
> - "secure-tag-memory", UINT64_MAX / 32);
> -
> - /* As with ram, secure-tag takes precedence over tag. */
> - memory_region_add_subregion_overlap(secure_tag_sysmem, 0,
> - tag_sysmem, -1);
> + object_property_set_link(cpuobj, "secure-tag-memory",
> + OBJECT(secure_tag_sysmem),
> + &error_abort);
> }
> - }
> -
> - object_property_set_link(cpuobj, "tag-memory", OBJECT(tag_sysmem),
> - &error_abort);
> - if (vms->secure) {
> - object_property_set_link(cpuobj, "secure-tag-memory",
> - OBJECT(secure_tag_sysmem),
> - &error_abort);
> + } else if (kvm_enabled()) {
> + if (!kvm_arm_mte_supported()) {
> + error_report("MTE requested, but not supported by KVM");
> + exit(1);
> + }
> + kvm_arm_enable_mte(cpuobj, &error_abort);
> + } else {
> + error_report("MTE requested, but not supported ");
> + exit(1);
> }
> }
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index d8eb986a04..661d35d8d8 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1054,6 +1054,7 @@ struct ArchCPU {
> bool prop_pauth_impdef;
> bool prop_pauth_qarma3;
> bool prop_lpa2;
> + OnOffAuto prop_mte;
>
> /* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
> uint8_t dcz_blocksize;
> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
> index 70f79eda33..0267a013e4 100644
> --- a/target/arm/kvm.c
> +++ b/target/arm/kvm.c
> @@ -39,6 +39,7 @@
> #include "hw/acpi/acpi.h"
> #include "hw/acpi/ghes.h"
> #include "target/arm/gtimer.h"
> +#include "migration/blocker.h"
>
> const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
> KVM_CAP_LAST_INFO
> @@ -1793,6 +1794,11 @@ bool kvm_arm_sve_supported(void)
> return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
> }
>
> +bool kvm_arm_mte_supported(void)
> +{
> + return kvm_check_extension(kvm_state, KVM_CAP_ARM_MTE);
> +}
> +
> QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
>
> uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
> @@ -2422,3 +2428,37 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
> }
> return 0;
> }
> +
> +void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
> +{
> + static bool tried_to_enable;
> + static bool succeeded_to_enable;
> + Error *mte_migration_blocker = NULL;
> + int ret;
> +
> + if (!tried_to_enable) {
> + /*
> + * MTE on KVM is enabled on a per-VM basis (and retrying doesn't make
> + * sense), and we only want a single migration blocker as well.
> + */
> + tried_to_enable = true;
> +
> + ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_MTE, 0);
> + if (ret) {
> + error_setg_errno(errp, -ret, "Failed to enable KVM_CAP_ARM_MTE");
> + return;
> + }
> +
> + /* TODO: Migration is not supported with MTE enabled */
> + error_setg(&mte_migration_blocker,
> + "Live migration disabled due to MTE enabled");
> + if (migrate_add_blocker(&mte_migration_blocker, errp)) {
> + error_free(mte_migration_blocker);
> + return;
> + }
> + succeeded_to_enable = true;
> + }
> + if (succeeded_to_enable) {
> + object_property_set_bool(cpuobj, "has_mte", true, NULL);
> + }
> +}
> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
> index cfaa0d9bc7..4d293618a7 100644
> --- a/target/arm/kvm_arm.h
> +++ b/target/arm/kvm_arm.h
> @@ -188,6 +188,13 @@ bool kvm_arm_pmu_supported(void);
> */
> bool kvm_arm_sve_supported(void);
>
> +/**
> + * kvm_arm_mte_supported:
> + *
> + * Returns: true if KVM can enable MTE, and false otherwise.
> + */
> +bool kvm_arm_mte_supported(void);
> +
> /**
> * kvm_arm_get_max_vm_ipa_size:
> * @ms: Machine state handle
> @@ -214,6 +221,8 @@ void kvm_arm_pvtime_init(ARMCPU *cpu, uint64_t ipa);
>
> int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
>
> +void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
> +
> #else
>
> /*
> @@ -235,6 +244,11 @@ static inline bool kvm_arm_sve_supported(void)
> return false;
> }
>
> +static inline bool kvm_arm_mte_supported(void)
> +{
> + return false;
> +}
> +
> /*
> * These functions should never actually be called without KVM support.
> */
> @@ -283,6 +297,11 @@ static inline uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
> g_assert_not_reached();
> }
>
> +static inline void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
> +{
> + g_assert_not_reached();
> +}
> +
> #endif
>
> #endif
Thanks,
Ganapat
next prev parent reply other threads:[~2024-07-15 11:28 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-09 6:04 [PATCH] arm/kvm: add support for MTE Ganapatrao Kulkarni
2024-07-10 15:42 ` Cornelia Huck
2024-07-11 8:53 ` Ganapatrao Kulkarni
2024-07-15 11:27 ` Ganapatrao Kulkarni [this message]
2024-07-16 15:45 ` Peter Maydell
2024-07-29 9:37 ` Ganapatrao Kulkarni
2024-07-29 10:14 ` Alex Bennée
2024-07-29 10:40 ` Ganapatrao Kulkarni
2024-07-31 12:36 ` Ganapatrao Kulkarni
2024-08-02 12:34 ` Ganapatrao Kulkarni
2024-08-02 13:16 ` Cornelia Huck
2024-09-10 11:57 ` Ganapatrao Kulkarni
2024-09-10 12:23 ` Peter Maydell
2024-09-11 6:50 ` Ganapatrao Kulkarni
2024-09-11 10:30 ` Peter Maydell
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=2b4bef01-5bcc-458c-9110-d2debe3f3620@os.amperecomputing.com \
--to=gankulkarni@os.amperecomputing.com \
--cc=cohuck@redhat.com \
--cc=darren@os.amperecomputing.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).