Re: [PATCH v2 06/43] arm64: RME: Add wrappers for RMI calls

From: Suzuki K Poulose
Date: Tue Apr 16 2024 - 09:15:07 EST


Hi Steven

On 12/04/2024 09:42, Steven Price wrote:
The wrappers make the call sites easier to read and deal with the
boiler plate of handling the error codes from the RMM.


I have compared the parameters and output values to that of the RMM spec
and they match. There are some minor nits below.

Signed-off-by: Steven Price <steven.price@xxxxxxx>
---
arch/arm64/include/asm/rmi_cmds.h | 509 ++++++++++++++++++++++++++++++
1 file changed, 509 insertions(+)
create mode 100644 arch/arm64/include/asm/rmi_cmds.h

diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi_cmds.h
new file mode 100644
index 000000000000..c21414127e8e
--- /dev/null
+++ b/arch/arm64/include/asm/rmi_cmds.h
@@ -0,0 +1,509 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#ifndef __ASM_RMI_CMDS_H
+#define __ASM_RMI_CMDS_H
+
+#include <linux/arm-smccc.h>
+
+#include <asm/rmi_smc.h>
+
+struct rtt_entry {
+ unsigned long walk_level;
+ unsigned long desc;
+ int state;
+ int ripas;
+};
+

..

+/**
+ * rmi_data_destroy() - Destroy a Data Granule
+ * @rd: PA of the RD
+ * @ipa: IPA at which the granule is mapped in the guest
+ * @data_out: PA of the granule which was destroyed
+ * @top_out: Top IPA of non-live RTT entries
+ *
+ * Transitions the granule to DESTROYED state, the address cannot be used by
+ * the guest for the lifetime of the Realm.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_data_destroy(unsigned long rd, unsigned long ipa,
+ unsigned long *data_out,
+ unsigned long *top_out)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_invoke(SMC_RMI_DATA_DESTROY, rd, ipa, &res);
+
+ *data_out = res.a1;
+ *top_out = res.a2;

minor nit: Do we need to be safer by checking the parameters before filling them in ? i.e.,

if (ptr)
*ptr = result_out;

This applies for others calls below.

+
+ return res.a0;
+}

+
+/**
+ * rmi_realm_destroy() - Destroy a Realm
+ * @rd: PA of the RD
+ *
+ * Destroys a Realm, all objects belonging to the Realm must be destroyed first.
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_realm_destroy(unsigned long rd)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_invoke(SMC_RMI_REALM_DESTROY, rd, &res);
+
+ return res.a0;
+}
+
+/**
+ * rmi_rec_aux_count() - Get number of auxiliary Granules required
+ * @rd: PA of the RD
+ * @aux_count: Number of pages written to this pointer
+ *
+ * A REC may require extra auxiliary pages to be delegateed for the RMM to

minor nit: "s/delegateed/delegated/"

..

+/**
+ * rmi_rtt_read_entry() - Read an RTTE
+ * @rd: PA of the RD
+ * @ipa: IPA for which to read the RTTE
+ * @level: RTT level at which to read the RTTE
+ * @rtt: Output structure describing the RTTE
+ *
+ * Reads a RTTE (Realm Translation Table Entry).
+ *
+ * Return: RMI return code
+ */
+static inline int rmi_rtt_read_entry(unsigned long rd, unsigned long ipa,
+ long level, struct rtt_entry *rtt)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_READ_ENTRY,
+ rd, ipa, level
+ };
+
+ arm_smccc_1_2_smc(&regs, &regs);
+
+ rtt->walk_level = regs.a1;
+ rtt->state = regs.a2 & 0xFF;

minor nit: We mask the state, but not the "ripas". Both of them are u8. For consistency, we should mask both or neither.

+ rtt->desc = regs.a3;
+ rtt->ripas = regs.a4;
+
+ return regs.a0;
+}
+

..

+/**
+ * rmi_rtt_get_phys() - Get the PA from a RTTE
+ * @rtt: The RTTE
+ *
+ * Return: the physical address from a RTT entry.
+ */
+static inline phys_addr_t rmi_rtt_get_phys(struct rtt_entry *rtt)
+{
+ return rtt->desc & GENMASK(47, 12);
+}

I guess this may need to change with the LPA2 support in RMM and must be
used in conjunction with the "realm" object to make the correct
conversion.


Suzuki


+
+#endif