All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Roger Pau Monné" <roger.pau@citrix.com>
To: Chao Gao <chao.gao@intel.com>
Cc: Lan Tianyu <tianyu.lan@intel.com>,
	Kevin Tian <kevin.tian@intel.com>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Wei Liu <wei.liu2@citrix.com>,
	George Dunlap <george.dunlap@eu.citrix.com>,
	Ian Jackson <ian.jackson@eu.citrix.com>, Tim Deegan <tim@xen.org>,
	xen-devel@lists.xen.org, Jan Beulich <jbeulich@suse.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>
Subject: Re: [PATCH v4 07/28] x86/hvm: Introduce a emulated VTD for HVM
Date: Fri, 9 Feb 2018 16:27:54 +0000	[thread overview]
Message-ID: <20180209162754.udtnnij4cmcrntft@MacBook-Pro-de-Roger.local> (raw)
In-Reply-To: <1510899755-40237-8-git-send-email-chao.gao@intel.com>

On Fri, Nov 17, 2017 at 02:22:14PM +0800, Chao Gao wrote:
> This patch adds create/destroy function for the emulated VTD
> and adapts it to the common VIOMMU abstraction.
> 
> As the Makefile is changed here, put all files in alphabetic order
> by this chance.
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
> 
> ---
> v4:
> - use REGISTER_VIOMMU
> - shrink the size of hvm_hw_vvtd_regs
> - make hvm_hw_vvtd_regs a field inside struct vvtd
> ---
>  xen/drivers/passthrough/vtd/Makefile |   7 +-
>  xen/drivers/passthrough/vtd/iommu.h  |   9 +++
>  xen/drivers/passthrough/vtd/vvtd.c   | 150 +++++++++++++++++++++++++++++++++++
>  3 files changed, 163 insertions(+), 3 deletions(-)
>  create mode 100644 xen/drivers/passthrough/vtd/vvtd.c
> 
> diff --git a/xen/drivers/passthrough/vtd/Makefile b/xen/drivers/passthrough/vtd/Makefile
> index f302653..163c7fe 100644
> --- a/xen/drivers/passthrough/vtd/Makefile
> +++ b/xen/drivers/passthrough/vtd/Makefile
> @@ -1,8 +1,9 @@
>  subdir-$(CONFIG_X86) += x86
>  
> -obj-y += iommu.o
>  obj-y += dmar.o
> -obj-y += utils.o
> -obj-y += qinval.o
>  obj-y += intremap.o
> +obj-y += iommu.o
> +obj-y += qinval.o
>  obj-y += quirks.o
> +obj-y += utils.o
> +obj-$(CONFIG_VIOMMU) += vvtd.o
> diff --git a/xen/drivers/passthrough/vtd/iommu.h b/xen/drivers/passthrough/vtd/iommu.h
> index db80b31..f2ef3dd 100644
> --- a/xen/drivers/passthrough/vtd/iommu.h
> +++ b/xen/drivers/passthrough/vtd/iommu.h
> @@ -47,6 +47,7 @@
>  #define DMAR_IQH_REG            0x80 /* invalidation queue head */
>  #define DMAR_IQT_REG            0x88 /* invalidation queue tail */
>  #define DMAR_IQA_REG            0x90 /* invalidation queue addr */
> +#define DMAR_IECTL_REG          0xa0 /* invalidation event control register */
>  #define DMAR_IRTA_REG           0xb8 /* intr remap */
>  
>  #define OFFSET_STRIDE        (9)
> @@ -89,6 +90,12 @@
>  #define cap_afl(c)        (((c) >> 3) & 1)
>  #define cap_ndoms(c)        (1 << (4 + 2 * ((c) & 0x7)))
>  
> +#define cap_set_num_fault_regs(c)   ((((c) - 1) & 0xff) << 40)
> +#define cap_set_fault_reg_offset(c) ((((c) / 16) & 0x3ff) << 24)
> +#define cap_set_mgaw(c)             ((((c) - 1) & 0x3f) << 16)
> +#define cap_set_sagaw(c)            (((c) & 0x1f) << 8)
> +#define cap_set_ndoms(c)            ((c) & 0x7)
> +
>  /*
>   * Extended Capability Register
>   */
> @@ -114,6 +121,8 @@
>  #define ecap_niotlb_iunits(e)    ((((e) >> 24) & 0xff) + 1)
>  #define ecap_iotlb_offset(e)     ((((e) >> 8) & 0x3ff) * 16)
>  
> +#define ecap_set_mhmv(e)         (((e) & 0xf) << 20)
> +
>  /* IOTLB_REG */
>  #define DMA_TLB_FLUSH_GRANU_OFFSET  60
>  #define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60)
> diff --git a/xen/drivers/passthrough/vtd/vvtd.c b/xen/drivers/passthrough/vtd/vvtd.c
> new file mode 100644
> index 0000000..9f76ccf
> --- /dev/null
> +++ b/xen/drivers/passthrough/vtd/vvtd.c
> @@ -0,0 +1,150 @@
> +/*
> + * vvtd.c
> + *
> + * virtualize VTD for HVM.
> + *
> + * Copyright (C) 2017 Chao Gao, Intel Corporation.
> + *
> + * 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 that 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/types.h>
> +#include <xen/viommu.h>
> +#include <xen/xmalloc.h>
> +#include <asm/current.h>
> +#include <asm/hvm/domain.h>
> +
> +#include "iommu.h"
> +
> +/* Supported capabilities by vvtd */
> +#define VVTD_MAX_CAPS VIOMMU_CAP_IRQ_REMAPPING
> +
> +#define VVTD_FRCD_NUM   1ULL
> +#define VVTD_FRCD_START (DMAR_IRTA_REG + 8)
> +#define VVTD_FRCD_END   (VVTD_FRCD_START + VVTD_FRCD_NUM * 16)
> +#define VVTD_MAX_OFFSET VVTD_FRCD_END
> +
> +struct hvm_hw_vvtd {
> +    uint32_t regs[VVTD_MAX_OFFSET/sizeof(uint32_t)];

Unless I'm mistaken this is 208bytes in size, yet you only seem to use
28bytes (from the registers used in vvtd_reset). I guess this is going
to change over the series so all this space is really needed.

Also I think this would be better as:

union hw_vvtd {
    uint32_t regs32[VVTD_MAX_OFFSET/sizeof(uint32_t)];
    uint64_t regs64[VVTD_MAX_OFFSET/sizeof(uint64_t)];
};

> +};
> +
> +struct vvtd {
> +    /* Base address of remapping hardware register-set */
> +    uint64_t base_addr;
> +    /* Point back to the owner domain */
> +    struct domain *domain;
> +
> +    struct hvm_hw_vvtd hw;
> +};
> +
> +/* Setting viommu_verbose enables debugging messages of vIOMMU */
> +bool __read_mostly viommu_verbose;

static?

> +boolean_runtime_param("viommu_verbose", viommu_verbose);
> +
> +#ifndef NDEBUG
> +#define vvtd_info(fmt...) do {                    \
> +    if ( viommu_verbose )                         \
> +        gprintk(XENLOG_INFO, ## fmt);             \
> +} while(0)
> +/*
> + * Use printk and '_G_' prefix because vvtd_debug() may be called
> + * in the context of another domain's vCPU. Don't output 'current'
> + * information to avoid confusion.
> + */
> +#define vvtd_debug(fmt...) do {                   \
> +    if ( viommu_verbose && printk_ratelimit())    \
> +        printk(XENLOG_G_DEBUG fmt);               \

I think printk is already rate-limited if you use _G_, so no need for
the ratelimit call.

> +} while(0)
> +#else
> +#define vvtd_info(...) do {} while(0)
> +#define vvtd_debug(...) do {} while(0)
> +#endif
> +
> +#define VVTD_REG_POS(vvtd, offset) &(vvtd->hw.regs[offset/sizeof(uint32_t)])
> +
> +static inline void vvtd_set_reg(struct vvtd *vvtd, uint32_t reg, uint32_t value)

I don't think you need the vvtd prefix here, and I would leave adding
inline to the compiler discretion:

static void set_reg32(struct vvtd *vvtd, unsigned long offset, uint32_t val)
{
    vvtd->hw.regs32[offset / 4] = val
}

But I think you can even get rid of the helper functions and just use
macros directly, ie:

#define GET_REG(vvtd, offset, size) \
    ((vvtd)->hw.regs ## size [(offset) / size / 8 ])
#define SET_REG(vvtd, offset, val, size) \
    (GET_REG(vvtd, offset, val) = val)

This is better IMHO, and I'm not really sure the SET_REG macro is
really needed, you can just open code GET_REG(...) = val;

> +{
> +    *VVTD_REG_POS(vvtd, reg) = value;
> +}
> +
> +static inline uint32_t vvtd_get_reg(const struct vvtd *vvtd, uint32_t reg)
> +{
> +    return *VVTD_REG_POS(vvtd, reg);
> +}
> +
> +static inline void vvtd_set_reg_quad(struct vvtd *vvtd, uint32_t reg,
> +                                     uint64_t value)
> +{
> +    *(uint64_t*)VVTD_REG_POS(vvtd, reg) = value;
> +}
> +
> +static inline uint64_t vvtd_get_reg_quad(const struct vvtd *vvtd, uint32_t reg)
> +{
> +    return *(uint64_t*)VVTD_REG_POS(vvtd, reg);
> +}
> +
> +static void vvtd_reset(struct vvtd *vvtd)
> +{
> +    uint64_t cap = cap_set_num_fault_regs(VVTD_FRCD_NUM)
> +                   | cap_set_fault_reg_offset(VVTD_FRCD_START)
> +                   | cap_set_mgaw(39) /* maximum guest address width */
> +                   | cap_set_sagaw(2) /* support 3-level page_table */
> +                   | cap_set_ndoms(6); /* support 64K domains */
> +    uint64_t ecap = DMA_ECAP_QUEUED_INVAL | DMA_ECAP_INTR_REMAP | DMA_ECAP_EIM |
> +                    ecap_set_mhmv(0xf);
> +
> +    vvtd_set_reg(vvtd, DMAR_VER_REG, 0x10UL);
> +    vvtd_set_reg_quad(vvtd, DMAR_CAP_REG, cap);
> +    vvtd_set_reg_quad(vvtd, DMAR_ECAP_REG, ecap);
> +    vvtd_set_reg(vvtd, DMAR_FECTL_REG, 0x80000000UL);
> +    vvtd_set_reg(vvtd, DMAR_IECTL_REG, 0x80000000UL);
> +}
> +
> +static int vvtd_create(struct domain *d, struct viommu *viommu)
> +{
> +    struct vvtd *vvtd;
> +
> +    if ( !is_hvm_domain(d) || (viommu->base_address & (PAGE_SIZE - 1)) ||
> +         (~VVTD_MAX_CAPS & viommu->caps) )
> +        return -EINVAL;
> +
> +    vvtd = xzalloc_bytes(sizeof(struct vvtd));

vvtd = xzalloc(struct vvtd);

> +    if ( !vvtd )
> +        return ENOMEM;
> +
> +    vvtd_reset(vvtd);
> +    vvtd->base_addr = viommu->base_address;

I think it would be good to have some check here, so that the vIOMMU
is not for example positioned on top of a RAM region. Ideally you
should check that the gfns [base_address, base_address + size) are
unpopulated.

> +    vvtd->domain = d;
> +
> +    viommu->priv = vvtd;
> +
> +    return 0;
> +}
> +
> +static int vvtd_destroy(struct viommu *viommu)
> +{
> +    struct vvtd *vvtd = viommu->priv;
> +
> +    if ( vvtd )
> +        xfree(vvtd);
> +
> +    return 0;
> +}
> +
> +static const struct viommu_ops vvtd_hvm_vmx_ops = {

Is the vmx needed? vvtd is already Intel specific AFAICT. You could
probably omit the hvm also, so vvtd_ops.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  reply	other threads:[~2018-02-09 16:27 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-17  6:22 [PATCH v4 00/28] add vIOMMU support with irq remapping function of virtual VT-d Chao Gao
2017-11-17  6:22 ` [PATCH v4 01/28] Xen/doc: Add Xen virtual IOMMU doc Chao Gao
2018-02-09 12:54   ` Roger Pau Monné
2018-02-09 15:53     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 02/28] VIOMMU: Add vIOMMU framework and vIOMMU domctl Chao Gao
2018-02-09 14:33   ` Roger Pau Monné
2018-02-09 16:13     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 03/28] VIOMMU: Add irq request callback to deal with irq remapping Chao Gao
2018-02-09 15:02   ` Roger Pau Monné
2018-02-09 16:21     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 04/28] VIOMMU: Add get irq info callback to convert irq remapping request Chao Gao
2018-02-09 15:06   ` Roger Pau Monné
2018-02-09 16:34     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 05/28] VIOMMU: Introduce callback of checking irq remapping mode Chao Gao
2018-02-09 15:11   ` Roger Pau Monné
2018-02-09 16:47     ` Chao Gao
2018-02-12 10:21       ` Roger Pau Monné
2017-11-17  6:22 ` [PATCH v4 06/28] vtd: clean-up and preparation for vvtd Chao Gao
2018-02-09 15:17   ` Roger Pau Monné
2018-02-09 16:51     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 07/28] x86/hvm: Introduce a emulated VTD for HVM Chao Gao
2018-02-09 16:27   ` Roger Pau Monné [this message]
2018-02-09 17:12     ` Chao Gao
2018-02-12 10:35       ` Roger Pau Monné
2017-11-17  6:22 ` [PATCH v4 08/28] x86/vvtd: Add MMIO handler for VVTD Chao Gao
2018-02-09 16:39   ` Roger Pau Monné
2018-02-09 17:21     ` Chao Gao
2018-02-09 17:51       ` Roger Pau Monné
2018-02-22  6:20         ` Chao Gao
2018-02-23 17:07           ` Roger Pau Monné
2018-02-23 17:37             ` Wei Liu
2017-11-17  6:22 ` [PATCH v4 09/28] x86/vvtd: Set Interrupt Remapping Table Pointer through GCMD Chao Gao
2018-02-09 16:59   ` Roger Pau Monné
2018-02-11  4:34     ` Chao Gao
2018-02-11  5:09       ` Chao Gao
2018-02-12 11:25       ` Roger Pau Monné
2017-11-17  6:22 ` [PATCH v4 10/28] x86/vvtd: Enable Interrupt Remapping " Chao Gao
2018-02-09 17:15   ` Roger Pau Monné
2018-02-11  5:05     ` Chao Gao
2018-02-12 11:30       ` Roger Pau Monné
2018-02-22  6:25         ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 11/28] x86/vvtd: Process interrupt remapping request Chao Gao
2018-02-09 17:44   ` Roger Pau Monné
2018-02-11  5:31     ` Chao Gao
2018-02-23 17:04       ` Roger Pau Monné
2017-11-17  6:22 ` [PATCH v4 12/28] x86/vvtd: decode interrupt attribute from IRTE Chao Gao
2018-02-12 11:55   ` Roger Pau Monné
2018-02-22  6:33     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 13/28] x86/vvtd: add a helper function to decide the interrupt format Chao Gao
2018-02-12 12:14   ` Roger Pau Monné
2017-11-17  6:22 ` [PATCH v4 14/28] x86/vvtd: Handle interrupt translation faults Chao Gao
2018-02-12 12:55   ` Roger Pau Monné
2018-02-22  8:23     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 15/28] x86/vvtd: Enable Queued Invalidation through GCMD Chao Gao
2018-02-12 14:04   ` Roger Pau Monné
2018-02-22 10:33     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 16/28] x86/vvtd: Add queued invalidation (QI) support Chao Gao
2018-02-12 14:36   ` Roger Pau Monné
2018-02-23  4:38     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 17/28] x86/vvtd: save and restore emulated VT-d Chao Gao
2018-02-12 14:49   ` Roger Pau Monné
2018-02-23  5:22     ` Chao Gao
2018-02-23 17:19       ` Roger Pau Monné
2017-11-17  6:22 ` [PATCH v4 18/28] x86/vioapic: Hook interrupt delivery of vIOAPIC Chao Gao
2018-02-12 14:54   ` Roger Pau Monné
2018-02-24  1:51     ` Chao Gao
2018-02-24  3:17       ` Tian, Kevin
2017-11-17  6:22 ` [PATCH v4 19/28] x86/vioapic: extend vioapic_get_vector() to support remapping format RTE Chao Gao
2018-02-12 15:01   ` Roger Pau Monné
2017-11-17  6:22 ` [PATCH v4 20/28] xen/pt: when binding guest msi, accept the whole msi message Chao Gao
2018-02-12 15:16   ` Roger Pau Monné
2018-02-24  2:20     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 21/28] vvtd: update hvm_gmsi_info when binding guest msi with pirq or Chao Gao
2018-02-12 15:38   ` Roger Pau Monné
2018-02-24  5:05     ` Chao Gao
2017-11-17  6:22 ` [PATCH v4 22/28] x86/vmsi: Hook delivering remapping format msi to guest and handling eoi Chao Gao
2017-11-17  6:22 ` [PATCH v4 23/28] tools/libacpi: Add DMA remapping reporting (DMAR) ACPI table structures Chao Gao
2017-11-17  6:22 ` [PATCH v4 24/28] tools/libacpi: Add new fields in acpi_config for DMAR table Chao Gao
2017-11-17  6:22 ` [PATCH v4 25/28] tools/libxl: Add an user configurable parameter to control vIOMMU attributes Chao Gao
2017-11-17  6:22 ` [PATCH v4 26/28] tools/libxl: build DMAR table for a guest with one virtual VTD Chao Gao
2017-11-17  6:22 ` [PATCH v4 27/28] tools/libxl: create vIOMMU during domain construction Chao Gao
2017-11-17  6:22 ` [PATCH v4 28/28] tools/libxc: Add viommu operations in libxc Chao Gao
2018-10-04 15:51 ` [PATCH v4 00/28] add vIOMMU support with irq remapping function of virtual VT-d Jan Beulich

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=20180209162754.udtnnij4cmcrntft@MacBook-Pro-de-Roger.local \
    --to=roger.pau@citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=chao.gao@intel.com \
    --cc=george.dunlap@eu.citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=kevin.tian@intel.com \
    --cc=sstabellini@kernel.org \
    --cc=tianyu.lan@intel.com \
    --cc=tim@xen.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.