Re: [PATCH v1 4/5] arm/kvm: add skeleton implementation for userspace SMCCC call handling

2023-07-04 Thread Cornelia Huck
On Mon, Jun 26 2023, Shaoqin Huang  wrote:

> The SMCCC call filtering provide the ability to forward the SMCCC call
> to userspace, so we provide a new option `user-smccc` to enable handling
> SMCCC call in userspace, the default value is off.
>
> And add the skeleton implementation for userspace SMCCC call
> initialization and handling.
>
> Signed-off-by: Shaoqin Huang 
> ---
>  docs/system/arm/virt.rst |  4 +++
>  hw/arm/virt.c| 21 
>  include/hw/arm/virt.h|  1 +
>  target/arm/kvm.c | 54 
>  4 files changed, 80 insertions(+)
>
> diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
> index 1cab33f02e..ff43d52f04 100644
> --- a/docs/system/arm/virt.rst
> +++ b/docs/system/arm/virt.rst
> @@ -155,6 +155,10 @@ dtb-randomness
>DTB to be non-deterministic. It would be the responsibility of
>the firmware to come up with a seed and pass it on if it wants to.
>  
> +user-smccc
> +  Set ``on``/``off`` to enable/disable handling smccc call in userspace
> +  instead of kernel.
> +
>  dtb-kaslr-seed
>A deprecated synonym for dtb-randomness.
>  
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 9b9f7d9c68..767720321c 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -42,6 +42,7 @@
>  #include "hw/vfio/vfio-amd-xgbe.h"
>  #include "hw/display/ramfb.h"
>  #include "net/net.h"
> +#include "qom/object.h"
>  #include "sysemu/device_tree.h"
>  #include "sysemu/numa.h"
>  #include "sysemu/runstate.h"
> @@ -2511,6 +2512,19 @@ static void virt_set_oem_table_id(Object *obj, const 
> char *value,
>  strncpy(vms->oem_table_id, value, 8);
>  }
>  
> +static bool virt_get_user_smccc(Object *obj, Error **errp)
> +{
> +VirtMachineState *vms = VIRT_MACHINE(obj);
> +
> +return vms->user_smccc;
> +}
> +
> +static void virt_set_user_smccc(Object *obj, bool value, Error **errp)
> +{
> +VirtMachineState *vms = VIRT_MACHINE(obj);
> +
> +vms->user_smccc = value;
> +}
>  
>  bool virt_is_acpi_enabled(VirtMachineState *vms)
>  {
> @@ -3155,6 +3169,13 @@ static void virt_machine_class_init(ObjectClass *oc, 
> void *data)
>"in ACPI table header."
>"The string may be up to 8 bytes 
> in size");
>  
> +object_class_property_add_bool(oc, "user-smccc",
> +   virt_get_user_smccc,
> +   virt_set_user_smccc);
> +object_class_property_set_description(oc, "user-smccc",
> +  "Set on/off to enable/disable "
> +  "handling smccc call in 
> userspace");
> +
>  }
>  
>  static void virt_instance_init(Object *obj)

This knob pretty much only makes sense for KVM guests, and we'll ignore
it with tcg -- would it make sense to check that we are actually using
KVM before we proceed (like we do for the tcg-only props?)




[PATCH v1 4/5] arm/kvm: add skeleton implementation for userspace SMCCC call handling

2023-06-26 Thread Shaoqin Huang
The SMCCC call filtering provide the ability to forward the SMCCC call
to userspace, so we provide a new option `user-smccc` to enable handling
SMCCC call in userspace, the default value is off.

And add the skeleton implementation for userspace SMCCC call
initialization and handling.

Signed-off-by: Shaoqin Huang 
---
 docs/system/arm/virt.rst |  4 +++
 hw/arm/virt.c| 21 
 include/hw/arm/virt.h|  1 +
 target/arm/kvm.c | 54 
 4 files changed, 80 insertions(+)

diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
index 1cab33f02e..ff43d52f04 100644
--- a/docs/system/arm/virt.rst
+++ b/docs/system/arm/virt.rst
@@ -155,6 +155,10 @@ dtb-randomness
   DTB to be non-deterministic. It would be the responsibility of
   the firmware to come up with a seed and pass it on if it wants to.
 
+user-smccc
+  Set ``on``/``off`` to enable/disable handling smccc call in userspace
+  instead of kernel.
+
 dtb-kaslr-seed
   A deprecated synonym for dtb-randomness.
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 9b9f7d9c68..767720321c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -42,6 +42,7 @@
 #include "hw/vfio/vfio-amd-xgbe.h"
 #include "hw/display/ramfb.h"
 #include "net/net.h"
+#include "qom/object.h"
 #include "sysemu/device_tree.h"
 #include "sysemu/numa.h"
 #include "sysemu/runstate.h"
@@ -2511,6 +2512,19 @@ static void virt_set_oem_table_id(Object *obj, const 
char *value,
 strncpy(vms->oem_table_id, value, 8);
 }
 
+static bool virt_get_user_smccc(Object *obj, Error **errp)
+{
+VirtMachineState *vms = VIRT_MACHINE(obj);
+
+return vms->user_smccc;
+}
+
+static void virt_set_user_smccc(Object *obj, bool value, Error **errp)
+{
+VirtMachineState *vms = VIRT_MACHINE(obj);
+
+vms->user_smccc = value;
+}
 
 bool virt_is_acpi_enabled(VirtMachineState *vms)
 {
@@ -3155,6 +3169,13 @@ static void virt_machine_class_init(ObjectClass *oc, 
void *data)
   "in ACPI table header."
   "The string may be up to 8 bytes in 
size");
 
+object_class_property_add_bool(oc, "user-smccc",
+   virt_get_user_smccc,
+   virt_set_user_smccc);
+object_class_property_set_description(oc, "user-smccc",
+  "Set on/off to enable/disable "
+  "handling smccc call in userspace");
+
 }
 
 static void virt_instance_init(Object *obj)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index e1ddbea96b..4f1bc12680 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -160,6 +160,7 @@ struct VirtMachineState {
 bool ras;
 bool mte;
 bool dtb_randomness;
+bool user_smccc;
 OnOffAuto acpi;
 VirtGICType gic_version;
 VirtIOMMUType iommu;
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 84da49332c..579c6edd49 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -9,6 +9,8 @@
  */
 
 #include "qemu/osdep.h"
+#include 
+#include 
 #include 
 
 #include 
@@ -247,6 +249,20 @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool 
*fixed_ipa)
 return ret > 0 ? ret : 40;
 }
 
+static int kvm_arm_init_smccc_filter(KVMState *s)
+{
+int ret = 0;
+
+if (kvm_vm_check_attr(s, KVM_ARM_VM_SMCCC_CTRL, KVM_ARM_VM_SMCCC_FILTER)) {
+error_report("ARM SMCCC filter not supported");
+ret = -EINVAL;
+goto out;
+}
+
+out:
+return ret;
+}
+
 int kvm_arch_init(MachineState *ms, KVMState *s)
 {
 int ret = 0;
@@ -282,6 +298,10 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 
 kvm_arm_init_debug(s);
 
+if (ret == 0 && object_property_get_bool(OBJECT(ms), "user-smccc", NULL)) {
+ret = kvm_arm_init_smccc_filter(s);
+}
+
 return ret;
 }
 
@@ -912,6 +932,37 @@ static int kvm_arm_handle_dabt_nisv(CPUState *cs, uint64_t 
esr_iss,
 return -1;
 }
 
+static void kvm_arm_smccc_return_result(CPUState *cs, struct arm_smccc_res 
*res)
+{
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = >env;
+
+env->xregs[0] = res->a0;
+env->xregs[1] = res->a1;
+env->xregs[2] = res->a2;
+env->xregs[3] = res->a3;
+}
+
+static int kvm_arm_handle_hypercall(CPUState *cs, struct kvm_run *run)
+{
+uint32_t fn = run->hypercall.nr;
+struct arm_smccc_res res = {
+.a0 = SMCCC_RET_NOT_SUPPORTED,
+};
+int ret = 0;
+
+kvm_cpu_synchronize_state(cs);
+
+switch (ARM_SMCCC_OWNER_NUM(fn)) {
+default:
+break;
+}
+
+kvm_arm_smccc_return_result(cs, );
+
+return ret;
+}
+
 int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
 {
 int ret = 0;
@@ -927,6 +978,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
 ret = kvm_arm_handle_dabt_nisv(cs, run->arm_nisv.esr_iss,
run->arm_nisv.fault_ipa);
 break;
+