diff mbox series

[03/11] KVM: arm64: Add vm fd device attribute accessors

Message ID 20230320221002.4191007-4-oliver.upton@linux.dev (mailing list archive)
State New, archived
Headers show
Series KVM: arm64: Userspace SMCCC call filtering | expand

Commit Message

Oliver Upton March 20, 2023, 10:09 p.m. UTC
A subsequent change will allow userspace to convey a filter for
hypercalls through a vm device attribute. Add the requisite boilerplate
for vm attribute accessors.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
 arch/arm64/kvm/arm.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

Comments

Suzuki K Poulose March 21, 2023, 9:53 a.m. UTC | #1
On 20/03/2023 22:09, Oliver Upton wrote:
> A subsequent change will allow userspace to convey a filter for
> hypercalls through a vm device attribute. Add the requisite boilerplate
> for vm attribute accessors.
> 
> Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
> ---
>   arch/arm64/kvm/arm.c | 29 +++++++++++++++++++++++++++++
>   1 file changed, 29 insertions(+)
> 
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 3bd732eaf087..b6e26c0e65e5 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -1439,11 +1439,28 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
>   	}
>   }
>   
> +static int kvm_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
> +{
> +	switch (attr->group) {
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
> +static int kvm_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
> +{
> +	switch (attr->group) {
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
>   long kvm_arch_vm_ioctl(struct file *filp,
>   		       unsigned int ioctl, unsigned long arg)
>   {
>   	struct kvm *kvm = filp->private_data;
>   	void __user *argp = (void __user *)arg;
> +	struct kvm_device_attr attr;
>   
>   	switch (ioctl) {
>   	case KVM_CREATE_IRQCHIP: {
> @@ -1479,6 +1496,18 @@ long kvm_arch_vm_ioctl(struct file *filp,
>   			return -EFAULT;
>   		return kvm_vm_ioctl_mte_copy_tags(kvm, &copy_tags);
>   	}
> +	case KVM_HAS_DEVICE_ATTR: {
> +		if (copy_from_user(&attr, argp, sizeof(attr)))
> +			return -EFAULT;
> +
> +		return kvm_vm_has_attr(kvm, &attr);
> +	}
> +	case KVM_SET_DEVICE_ATTR: {
> +		if (copy_from_user(&attr, argp, sizeof(attr)))
> +			return -EFAULT;
> +
> +		return kvm_vm_set_attr(kvm, &attr);
> +	}

Is there a reason to exclude KVM_GET_DEVICE_ATTR handling ?

Suzuki
Oliver Upton March 21, 2023, 4:49 p.m. UTC | #2
Hi Suzuki,

On Tue, Mar 21, 2023 at 09:53:06AM +0000, Suzuki K Poulose wrote:
> On 20/03/2023 22:09, Oliver Upton wrote:
> > A subsequent change will allow userspace to convey a filter for
> > hypercalls through a vm device attribute. Add the requisite boilerplate
> > for vm attribute accessors.
> > 
> > Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
> > ---
> >   arch/arm64/kvm/arm.c | 29 +++++++++++++++++++++++++++++
> >   1 file changed, 29 insertions(+)
> > 
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 3bd732eaf087..b6e26c0e65e5 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -1439,11 +1439,28 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
> >   	}
> >   }
> > +static int kvm_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
> > +{
> > +	switch (attr->group) {
> > +	default:
> > +		return -ENXIO;
> > +	}
> > +}
> > +
> > +static int kvm_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
> > +{
> > +	switch (attr->group) {
> > +	default:
> > +		return -ENXIO;
> > +	}
> > +}
> > +
> >   long kvm_arch_vm_ioctl(struct file *filp,
> >   		       unsigned int ioctl, unsigned long arg)
> >   {
> >   	struct kvm *kvm = filp->private_data;
> >   	void __user *argp = (void __user *)arg;
> > +	struct kvm_device_attr attr;
> >   	switch (ioctl) {
> >   	case KVM_CREATE_IRQCHIP: {
> > @@ -1479,6 +1496,18 @@ long kvm_arch_vm_ioctl(struct file *filp,
> >   			return -EFAULT;
> >   		return kvm_vm_ioctl_mte_copy_tags(kvm, &copy_tags);
> >   	}
> > +	case KVM_HAS_DEVICE_ATTR: {
> > +		if (copy_from_user(&attr, argp, sizeof(attr)))
> > +			return -EFAULT;
> > +
> > +		return kvm_vm_has_attr(kvm, &attr);
> > +	}
> > +	case KVM_SET_DEVICE_ATTR: {
> > +		if (copy_from_user(&attr, argp, sizeof(attr)))
> > +			return -EFAULT;
> > +
> > +		return kvm_vm_set_attr(kvm, &attr);
> > +	}
> 
> Is there a reason to exclude KVM_GET_DEVICE_ATTR handling ?

The GET_DEVICE_ATTR would effectively be dead code, as the hypercall filter is
a write-only attribute. The filter is constructed through iterative calls to
the attribute, so conveying the end result to userspace w/ the same UAPI
is non-trivial.

Hopefully userspace remembers what it wrote to the field ;-)
Suzuki K Poulose March 28, 2023, 8:39 a.m. UTC | #3
On 21/03/2023 16:49, Oliver Upton wrote:
> Hi Suzuki,
> 
> On Tue, Mar 21, 2023 at 09:53:06AM +0000, Suzuki K Poulose wrote:
>> On 20/03/2023 22:09, Oliver Upton wrote:
>>> A subsequent change will allow userspace to convey a filter for
>>> hypercalls through a vm device attribute. Add the requisite boilerplate
>>> for vm attribute accessors.
>>>
>>> Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
>>> ---
>>>    arch/arm64/kvm/arm.c | 29 +++++++++++++++++++++++++++++
>>>    1 file changed, 29 insertions(+)
>>>
>>> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
>>> index 3bd732eaf087..b6e26c0e65e5 100644
>>> --- a/arch/arm64/kvm/arm.c
>>> +++ b/arch/arm64/kvm/arm.c
>>> @@ -1439,11 +1439,28 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
>>>    	}
>>>    }
>>> +static int kvm_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
>>> +{
>>> +	switch (attr->group) {
>>> +	default:
>>> +		return -ENXIO;
>>> +	}
>>> +}
>>> +
>>> +static int kvm_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
>>> +{
>>> +	switch (attr->group) {
>>> +	default:
>>> +		return -ENXIO;
>>> +	}
>>> +}
>>> +
>>>    long kvm_arch_vm_ioctl(struct file *filp,
>>>    		       unsigned int ioctl, unsigned long arg)
>>>    {
>>>    	struct kvm *kvm = filp->private_data;
>>>    	void __user *argp = (void __user *)arg;
>>> +	struct kvm_device_attr attr;
>>>    	switch (ioctl) {
>>>    	case KVM_CREATE_IRQCHIP: {
>>> @@ -1479,6 +1496,18 @@ long kvm_arch_vm_ioctl(struct file *filp,
>>>    			return -EFAULT;
>>>    		return kvm_vm_ioctl_mte_copy_tags(kvm, &copy_tags);
>>>    	}
>>> +	case KVM_HAS_DEVICE_ATTR: {
>>> +		if (copy_from_user(&attr, argp, sizeof(attr)))
>>> +			return -EFAULT;
>>> +
>>> +		return kvm_vm_has_attr(kvm, &attr);
>>> +	}
>>> +	case KVM_SET_DEVICE_ATTR: {
>>> +		if (copy_from_user(&attr, argp, sizeof(attr)))
>>> +			return -EFAULT;
>>> +
>>> +		return kvm_vm_set_attr(kvm, &attr);
>>> +	}
>>
>> Is there a reason to exclude KVM_GET_DEVICE_ATTR handling ?
> 
> The GET_DEVICE_ATTR would effectively be dead code, as the hypercall filter is
> a write-only attribute. The filter is constructed through iterative calls to
> the attribute, so conveying the end result to userspace w/ the same UAPI
> is non-trivial.
> 
> Hopefully userspace remembers what it wrote to the field ;-)

Fair enough. I am thinking of using VM DEVICE_ATTR for some of the Arm
CCA Realm Configuration, which are now overloaded with ENABLE_CAP.

We could add GET_DEVICE_ATTR if and when we need it.

Thanks
Suzuki


>
Suzuki K Poulose March 28, 2023, 8:40 a.m. UTC | #4
On 20/03/2023 22:09, Oliver Upton wrote:
> A subsequent change will allow userspace to convey a filter for
> hypercalls through a vm device attribute. Add the requisite boilerplate
> for vm attribute accessors.
> 
> Signed-off-by: Oliver Upton <oliver.upton@linux.dev>

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
diff mbox series

Patch

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 3bd732eaf087..b6e26c0e65e5 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1439,11 +1439,28 @@  static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
 	}
 }
 
+static int kvm_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	switch (attr->group) {
+	default:
+		return -ENXIO;
+	}
+}
+
+static int kvm_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	switch (attr->group) {
+	default:
+		return -ENXIO;
+	}
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
 	struct kvm *kvm = filp->private_data;
 	void __user *argp = (void __user *)arg;
+	struct kvm_device_attr attr;
 
 	switch (ioctl) {
 	case KVM_CREATE_IRQCHIP: {
@@ -1479,6 +1496,18 @@  long kvm_arch_vm_ioctl(struct file *filp,
 			return -EFAULT;
 		return kvm_vm_ioctl_mte_copy_tags(kvm, &copy_tags);
 	}
+	case KVM_HAS_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return -EFAULT;
+
+		return kvm_vm_has_attr(kvm, &attr);
+	}
+	case KVM_SET_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return -EFAULT;
+
+		return kvm_vm_set_attr(kvm, &attr);
+	}
 	default:
 		return -EINVAL;
 	}