|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 02/28] VIOMMU: Add vIOMMU framework and vIOMMU domctl
On Fri, Feb 09, 2018 at 02:33:57PM +0000, Roger Pau Monné wrote:
>On Fri, Nov 17, 2017 at 02:22:09PM +0800, Chao Gao wrote:
>> From: Lan Tianyu <tianyu.lan@xxxxxxxxx>
>>
>> This patch is to introduce an abstract layer for arch vIOMMU implementation
>> and vIOMMU domctl to deal with requests from tool stack. Arch vIOMMU code
>> needs to
>> provide callback. vIOMMU domctl supports to create vIOMMU instance in
>> hypervisor
>> and it will be destroyed during destroying domain.
>>
>> Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx>
>> Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx>
>> ---
>> v4:
>> - introduce REGISTER_VIOMMU() to register viommu types and ops.
>> - remove unneeded domctl interface to destroy viommu.
>> ---
>> docs/misc/xen-command-line.markdown | 7 ++
>> xen/arch/x86/Kconfig | 1 +
>> xen/arch/x86/hvm/hvm.c | 3 +
>> xen/arch/x86/xen.lds.S | 3 +
>> xen/common/Kconfig | 3 +
>> xen/common/Makefile | 1 +
>> xen/common/domctl.c | 7 ++
>> xen/common/viommu.c | 125
>> ++++++++++++++++++++++++++++++++++++
>> xen/include/asm-x86/hvm/domain.h | 3 +
>> xen/include/public/domctl.h | 31 +++++++++
>> xen/include/xen/viommu.h | 69 ++++++++++++++++++++
>> 11 files changed, 253 insertions(+)
>> create mode 100644 xen/common/viommu.c
>> create mode 100644 xen/include/xen/viommu.h
>>
>> diff --git a/docs/misc/xen-command-line.markdown
>> b/docs/misc/xen-command-line.markdown
>> index eb4995e..d097382 100644
>> --- a/docs/misc/xen-command-line.markdown
>> +++ b/docs/misc/xen-command-line.markdown
>> @@ -1836,3 +1836,10 @@ mode.
>> > Default: `true`
>>
>> Permit use of the `xsave/xrstor` instructions.
>> +
>> +### viommu
>> +> `= <boolean>`
>> +
>> +> Default: `false`
>> +
>> +Permit use of viommu interface to create and destroy viommu device model.
>
>I'm not sure about the point of having this command line option, this
>is a guest feature and just setting it from the config file should be
>enough IMHO.
Sorry for this. You gave the same remark on our v3. And we promised to
remove it. But we forgot this one. I will remove it.
>
>> diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
>> index 64955dc..df254e4 100644
>> --- a/xen/arch/x86/Kconfig
>> +++ b/xen/arch/x86/Kconfig
>> @@ -25,6 +25,7 @@ config X86
>> select HAS_UBSAN
>> select NUMA
>> select VGA
>> + select VIOMMU
>>
>> config ARCH_DEFCONFIG
>> string
>> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
>> index 205b4cb..964418a 100644
>> --- a/xen/arch/x86/hvm/hvm.c
>> +++ b/xen/arch/x86/hvm/hvm.c
>> @@ -36,6 +36,7 @@
>> #include <xen/rangeset.h>
>> #include <xen/monitor.h>
>> #include <xen/warning.h>
>> +#include <xen/viommu.h>
>> #include <asm/shadow.h>
>> #include <asm/hap.h>
>> #include <asm/current.h>
>> @@ -693,6 +694,8 @@ void hvm_domain_relinquish_resources(struct domain *d)
>> pmtimer_deinit(d);
>> hpet_deinit(d);
>> }
>> +
>> + viommu_destroy_domain(d);
>
>This returns a value, but you ignore it (read below for how I think
>this should be solved).
>
>> }
>>
>> void hvm_domain_destroy(struct domain *d)
>> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
>> index d5e8821..7f8d2b8 100644
>> --- a/xen/arch/x86/xen.lds.S
>> +++ b/xen/arch/x86/xen.lds.S
>> @@ -231,6 +231,9 @@ SECTIONS
>> __start_schedulers_array = .;
>> *(.data.schedulers)
>> __end_schedulers_array = .;
>> + __start_viommus_array = .;
>> + *(.data.viommus)
>> + __end_viommus_array = .;
>
>This should be protected with #ifdef CONFIG_VIOMMU. And please place
>it at the end of the rodata section (AFAICT there's no need for it to
>be in the data.read_mostly section).
>
Will do.
>> } :text
>>
>> .data : { /* Data */
>> diff --git a/xen/common/Kconfig b/xen/common/Kconfig
>> index 103ef44..62aaa76 100644
>> --- a/xen/common/Kconfig
>> +++ b/xen/common/Kconfig
>> @@ -52,6 +52,9 @@ config HAS_CHECKPOLICY
>> string
>> option env="XEN_HAS_CHECKPOLICY"
>>
>> +config VIOMMU
>> + bool
>> +
>> config KEXEC
>> bool "kexec support"
>> default y
>> diff --git a/xen/common/Makefile b/xen/common/Makefile
>> index 66cc2c8..182b3ac 100644
>> --- a/xen/common/Makefile
>> +++ b/xen/common/Makefile
>> @@ -56,6 +56,7 @@ obj-y += time.o
>> obj-y += timer.o
>> obj-y += trace.o
>> obj-y += version.o
>> +obj-$(CONFIG_VIOMMU) += viommu.o
>> obj-y += virtual_region.o
>> obj-y += vm_event.o
>> obj-y += vmap.o
>> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
>> index 3c6fa4e..9c5651d 100644
>> --- a/xen/common/domctl.c
>> +++ b/xen/common/domctl.c
>> @@ -25,6 +25,7 @@
>> #include <xen/paging.h>
>> #include <xen/hypercall.h>
>> #include <xen/vm_event.h>
>> +#include <xen/viommu.h>
>> #include <xen/monitor.h>
>> #include <asm/current.h>
>> #include <asm/irq.h>
>> @@ -1155,6 +1156,12 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t)
>> u_domctl)
>>
>> op->u.set_gnttab_limits.maptrack_frames);
>> break;
>>
>> + case XEN_DOMCTL_viommu_op:
>> + ret = viommu_domctl(d, &op->u.viommu_op);
>> + if ( !ret )
>> + copyback = 1;
>> + break;
>> +
>> default:
>> ret = arch_do_domctl(op, d, u_domctl);
>> break;
>> diff --git a/xen/common/viommu.c b/xen/common/viommu.c
>> new file mode 100644
>> index 0000000..fd8b7fd
>> --- /dev/null
>> +++ b/xen/common/viommu.c
>> @@ -0,0 +1,125 @@
>> +/*
>> + * common/viommu.c
>> + *
>> + * Copyright (c) 2017 Intel Corporation
>> + * Author: Lan Tianyu <tianyu.lan@xxxxxxxxx>
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>> + * more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> with
>> + * this program; If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <xen/sched.h>
>> +#include <xen/spinlock.h>
>> +#include <xen/types.h>
>> +#include <xen/viommu.h>
>> +
>> +extern const struct viommu_ops *__start_viommus_array[],
>> *__end_viommus_array[];
>> +#define NUM_VIOMMU_TYPE (__end_viommus_array - __start_viommus_array)
>> +#define viommu_type_array __start_viommus_array
>> +
>> +int viommu_destroy_domain(struct domain *d)
>
>IMHO I would rather prefer the destroy operation to not be allowed to
>fail, that would allow switching it return value to void.
>
>The more that you simply ignore the return value in
>hvm_domain_relinquish_resources.
>
Got it.
>> +{
>> + struct viommu *viommu = d->arch.hvm_domain.viommu;
>> + int ret;
>> +
>> + if ( !viommu )
>> + return -ENODEV;
>> +
>> + ret = viommu->ops->destroy(viommu);
>> + if ( ret < 0 )
>> + return ret;
>> +
>> + xfree(viommu);
>> + d->arch.hvm_domain.viommu = NULL;
>> +
>> + return 0;
>> +}
>> +
>> +static const struct viommu_ops *viommu_get_ops(uint8_t type)
>> +{
>> + int i;
>
>unsigned int.
>
>> +
>> + for ( i = 0; i < NUM_VIOMMU_TYPE; i++)
>> + {
>> + if ( viommu_type_array[i]->type == type )
>> + return viommu_type_array[i];
>> + }
>> +
>> + return NULL;
>> +}
>> +
>> +static int viommu_create(struct domain *d, uint8_t type,
>> + uint64_t base_address, uint64_t caps,
>> + uint32_t *viommu_id)
>> +{
>> + struct viommu *viommu;
>> + const struct viommu_ops *viommu_ops = NULL;
>
>You can initialize viommu_ops here directly:
>
>const struct viommu_ops *viommu_ops = viommu_get_ops(type);
>
>> + int rc;
>> +
>> + /* Only support one vIOMMU per domain. */
>> + if ( d->arch.hvm_domain.viommu )
>> + return -E2BIG;
>
>EEXIST is maybe better?
>
>> +
>> + viommu_ops = viommu_get_ops(type);
>> + if ( !viommu_ops )
>> + return -EINVAL;
>> +
>> + ASSERT(viommu_ops->create);
>> +
>> + viommu = xzalloc(struct viommu);
>> + if ( !viommu )
>> + return -ENOMEM;
>> +
>> + viommu->base_address = base_address;
>> + viommu->caps = caps;
>> + viommu->ops = viommu_ops;
>> +
>> + rc = viommu_ops->create(d, viommu);
>> + if ( rc < 0 )
>> + {
>> + xfree(viommu);
>> + return rc;
>> + }
>> +
>> + d->arch.hvm_domain.viommu = viommu;
>> +
>> + /* Only support one vIOMMU per domain. */
>> + *viommu_id = 0;
>> + return 0;
>> +}
>> +
>> +int viommu_domctl(struct domain *d, struct xen_domctl_viommu_op *op)
>> +{
>> + int rc;
>> +
>> + switch ( op->cmd )
>> + {
>> + case XEN_DOMCTL_viommu_create:
>> + rc = viommu_create(d, op->u.create.type, op->u.create.base_address,
>> + op->u.create.capabilities, &op->u.create.id);
>> + break;
>
>Newline.
>
>> + default:
>> + return -ENOSYS;
>
>-EOPNOTSUPP
>
>> + }
>> +
>> + return rc;
>> +}
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * tab-width: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/xen/include/asm-x86/hvm/domain.h
>> b/xen/include/asm-x86/hvm/domain.h
>> index 7f128c0..fcd3482 100644
>> --- a/xen/include/asm-x86/hvm/domain.h
>> +++ b/xen/include/asm-x86/hvm/domain.h
>> @@ -21,6 +21,7 @@
>> #define __ASM_X86_HVM_DOMAIN_H__
>>
>> #include <xen/iommu.h>
>> +#include <xen/viommu.h>
>> #include <asm/hvm/irq.h>
>> #include <asm/hvm/vpt.h>
>> #include <asm/hvm/vlapic.h>
>> @@ -196,6 +197,8 @@ struct hvm_domain {
>> struct vmx_domain vmx;
>> struct svm_domain svm;
>> };
>> +
>> + struct viommu *viommu;
>
>Are you sure this will compile if you don't select CONFIG_VIOMMU?
>
>AFAICT struct viommu is only defined if VIOMMU is selected, so you
>should add something like...
>
>> diff --git a/xen/include/xen/viommu.h b/xen/include/xen/viommu.h
>> new file mode 100644
>> index 0000000..a859d80
>> --- /dev/null
>> +++ b/xen/include/xen/viommu.h
>> @@ -0,0 +1,69 @@
>> +/*
>> + * include/xen/viommu.h
>> + *
>> + * Copyright (c) 2017, Intel Corporation
>> + * Author: Lan Tianyu <tianyu.lan@xxxxxxxxx>
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>> + * more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> with
>> + * this program; If not, see <http://www.gnu.org/licenses/>.
>> + *
>> + */
>> +#ifndef __XEN_VIOMMU_H__
>> +#define __XEN_VIOMMU_H__
>> +
>> +#ifdef CONFIG_VIOMMU
>> +
>> +struct viommu;
>> +
>> +struct viommu_ops {
>> + uint8_t type;
>> + int (*create)(struct domain *d, struct viommu *viommu);
>> + int (*destroy)(struct viommu *viommu);
>> +};
>> +
>> +struct viommu {
>> + uint64_t base_address;
>> + uint64_t caps;
>> + const struct viommu_ops *ops;
>> + void *priv;
>> +};
>> +
>> +#define REGISTER_VIOMMU(x) static const struct viommu_ops *x##_entry \
>> + __used_section(".data.viommus") = &x;
>> +
>> +
>> +int viommu_register_type(uint8_t type, struct viommu_ops *ops);
>> +int viommu_destroy_domain(struct domain *d);
>> +int viommu_domctl(struct domain *d, struct xen_domctl_viommu_op *op);
>> +#else
>
>...
>
>struct viommu {
>};
>
>here.
>
Got it.
>> +static inline int viommu_destroy_domain(struct domain *d)
>> +{
>> + return -EINVAL;
>
>ENODEV if you really have to return an error here, note that I think
>destroy should not return anything.
>
>> +}
>> +static inline
>> +int viommu_domctl(struct domain *d, struct xen_domctl_viommu_op *op)
>
>The style should be:
>
>static inline int viommu_domctl(struct domain *d,
> struct xen_domctl_viommu_op *op)
>{
> ...
>
>> +{
>> + return false;
>
>Urg, no please. This should be -EOPNOTSUP.
yes.
Thanks
Chao
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |