From: Wei Wang <wei.wang2@amd.com>
To: "Zhang, Xiantao" <xiantao.zhang@intel.com>
Cc: "keir@xen.org" <keir@xen.org>,
"xen-devel@lists.xensource.com" <xen-devel@lists.xensource.com>,
"Ian.Jackson@eu.citrix.com" <Ian.Jackson@eu.citrix.com>,
"Ian.Campbell@citrix.com" <Ian.Campbell@citrix.com>,
"JBeulich@suse.com" <JBeulich@suse.com>
Subject: Re: [PATCH 3 of 6 V6] hvmloader: Build IVRS table
Date: Thu, 8 Mar 2012 15:49:48 +0100 [thread overview]
Message-ID: <4F58C70C.8070800@amd.com> (raw)
In-Reply-To: <B6C2EB9186482D47BD0C5A9A483456440954F6@SHSMSX101.ccr.corp.intel.com>
On 03/08/2012 03:22 PM, Zhang, Xiantao wrote:
> I think this IVRS table should be vendor-specific, and we should have the mechanism make it only work for AMD IOMMU. This is because Intel also has the similar support in next generation VT-d, DMAR table should be built also when enable virtual VT-d for the guest. I suggest this table should be only built when guest running on AMD's platforms.
> Thanks!
> Xiantao
Hi Xianto
Thanks for reviewing it. Actually construct_ivrs() will invoke a
hypercall guest_iommu_set_base() and it will fail on non-iommuv2 systems
including vtd. So IVRS can be avoided on Intel systems. But I am also
thinking that maybe we should let user chose different iommu hw at the
beginning. For example, use guest_iommu={vtd, amd, 0} to distinguish
different iommu hardware?
Thanks,
Wei
>> -----Original Message-----
>> From: xen-devel-bounces@lists.xen.org [mailto:xen-devel-
>> bounces@lists.xen.org] On Behalf Of Wei Wang
>> Sent: Thursday, March 08, 2012 9:22 PM
>> To: Ian.Jackson@eu.citrix.com; Ian.Campbell@citrix.com; JBeulich@suse.com;
>> keir@xen.org
>> Cc: xen-devel@lists.xensource.com
>> Subject: [Xen-devel] [PATCH 3 of 6 V6] hvmloader: Build IVRS table
>>
>> # HG changeset patch
>> # User Wei Wang<wei.wang2@amd.com>
>> # Date 1331210217 -3600
>> # Node ID d0611a8ee06d3f34de1c7c51da8571d9e1a668e1
>> # Parent e9d74ec1077472f9127c43903811ce3107fc038d
>> hvmloader: Build IVRS table.
>>
>> There are 32 ivrs padding entries allocated at the beginning. If a passthru
>> device has been found from qemu bus, a padding entry will be replaced by a
>> real device entry. This patch has been tested with both rombios and seabios
>>
>> Signed-off-by: Wei Wang<wei.wang2@amd.com>
>>
>> diff -r e9d74ec10774 -r d0611a8ee06d
>> tools/firmware/hvmloader/acpi/acpi2_0.h
>> --- a/tools/firmware/hvmloader/acpi/acpi2_0.h Thu Mar 08 13:36:54
>> 2012 +0100
>> +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h Thu Mar 08 13:36:57
>> 2012 +0100
>> @@ -389,6 +389,60 @@ struct acpi_20_madt_intsrcovr { #define
>> ACPI_2_0_WAET_REVISION 0x01 #define ACPI_1_0_FADT_REVISION 0x01
>>
>> +#define IVRS_SIGNATURE ASCII32('I','V','R','S')
>> +#define IVRS_REVISION 1
>> +#define IVRS_VASIZE 64
>> +#define IVRS_PASIZE 52
>> +#define IVRS_GVASIZE 64
>> +
>> +#define IVHD_BLOCK_TYPE 0x10
>> +#define IVHD_FLAG_HTTUNEN (1<< 0)
>> +#define IVHD_FLAG_PASSPW (1<< 1)
>> +#define IVHD_FLAG_RESPASSPW (1<< 2)
>> +#define IVHD_FLAG_ISOC (1<< 3)
>> +#define IVHD_FLAG_IOTLBSUP (1<< 4)
>> +#define IVHD_FLAG_COHERENT (1<< 5)
>> +#define IVHD_FLAG_PREFSUP (1<< 6)
>> +#define IVHD_FLAG_PPRSUP (1<< 7)
>> +
>> +#define IVHD_EFR_GTSUP (1<< 2)
>> +#define IVHD_EFR_IASUP (1<< 5)
>> +
>> +#define IVHD_SELECT_4_BYTE 0x2
>> +
>> +struct ivrs_ivhd_block
>> +{
>> + uint8_t type;
>> + uint8_t flags;
>> + uint16_t length;
>> + uint16_t devid;
>> + uint16_t cap_offset;
>> + uint64_t iommu_base_addr;
>> + uint16_t pci_segment;
>> + uint16_t iommu_info;
>> + uint32_t reserved;
>> +};
>> +
>> +/* IVHD 4-byte device entries */
>> +struct ivrs_ivhd_device
>> +{
>> + uint8_t type;
>> + uint16_t dev_id;
>> + uint8_t flags;
>> +};
>> +
>> +#define PT_DEV_MAX_NR 32
>> +#define IOMMU_CAP_OFFSET 0x40
>> +struct acpi_40_ivrs
>> +{
>> + struct acpi_header header;
>> + uint32_t iv_info;
>> + uint32_t reserved[2];
>> + struct ivrs_ivhd_block ivhd_block;
>> + struct ivrs_ivhd_device ivhd_device[PT_DEV_MAX_NR];
>> +};
>> +
>> +
>> #pragma pack ()
>>
>> struct acpi_config {
>> diff -r e9d74ec10774 -r d0611a8ee06d tools/firmware/hvmloader/acpi/build.c
>> --- a/tools/firmware/hvmloader/acpi/build.c Thu Mar 08 13:36:54 2012
>> +0100
>> +++ b/tools/firmware/hvmloader/acpi/build.c Thu Mar 08 13:36:57 2012
>> +0100
>> @@ -23,6 +23,8 @@
>> #include "ssdt_pm.h"
>> #include "../config.h"
>> #include "../util.h"
>> +#include "../hypercall.h"
>> +#include<xen/hvm/params.h>
>>
>> #define align16(sz) (((sz) + 15)& ~15)
>> #define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d)) @@ -198,6 +200,87 @@
>> static struct acpi_20_waet *construct_wa
>> return waet;
>> }
>>
>> +extern uint32_t ptdev_bdf[PT_DEV_MAX_NR]; extern uint32_t ptdev_nr;
>> +extern uint32_t iommu_bdf; static struct acpi_40_ivrs*
>> +construct_ivrs(void) {
>> + struct acpi_40_ivrs *ivrs;
>> + uint64_t mmio;
>> + struct ivrs_ivhd_block *ivhd;
>> + struct ivrs_ivhd_device *dev_entry;
>> + struct xen_hvm_param p;
>> +
>> + if (ptdev_nr == 0 || iommu_bdf == 0) return NULL;
>> +
>> + ivrs = mem_alloc(sizeof(*ivrs), 16);
>> + if (!ivrs)
>> + {
>> + printf("unable to build IVRS tables: out of memory\n");
>> + return NULL;
>> + }
>> + memset(ivrs, 0, sizeof(*ivrs));
>> +
>> + /* initialize acpi header */
>> + ivrs->header.signature = IVRS_SIGNATURE;
>> + ivrs->header.revision = IVRS_REVISION;
>> + fixed_strcpy(ivrs->header.oem_id, ACPI_OEM_ID);
>> + fixed_strcpy(ivrs->header.oem_table_id, ACPI_OEM_TABLE_ID);
>> +
>> + ivrs->header.oem_revision = ACPI_OEM_REVISION;
>> + ivrs->header.creator_id = ACPI_CREATOR_ID;
>> + ivrs->header.creator_revision = ACPI_CREATOR_REVISION;
>> +
>> + ivrs->header.length = sizeof(*ivrs);
>> +
>> + /* initialize IVHD Block */
>> + ivhd =&ivrs->ivhd_block;
>> + ivrs->iv_info = (IVRS_VASIZE<< 15) | (IVRS_PASIZE<< 8) |
>> + (IVRS_GVASIZE<< 5);
>> +
>> + ivhd->type = IVHD_BLOCK_TYPE;
>> + ivhd->flags = IVHD_FLAG_PPRSUP | IVHD_FLAG_IOTLBSUP;
>> + ivhd->devid = iommu_bdf;
>> + ivhd->cap_offset = IOMMU_CAP_OFFSET;
>> +
>> + /*reserve 32K IOMMU MMIO space */
>> + mmio = virt_to_phys(mem_alloc(0x8000, 0x1000));
>> + if (!mmio)
>> + {
>> + printf("unable to reserve iommu mmio pages: out of memory\n");
>> + return NULL;
>> + }
>> +
>> + p.domid = DOMID_SELF;
>> + p.index = HVM_PARAM_IOMMU_BASE;
>> + p.value = mmio;
>> +
>> + /* Return non-zero if IOMMUv2 hardware is not avaliable */
>> + if ( hypercall_hvm_op(HVMOP_set_param,&p) )
>> + {
>> + printf("unable to set iommu mmio base address\n");
>> + return NULL;
>> + }
>> +
>> + ivhd->iommu_base_addr = mmio;
>> + ivhd->reserved = IVHD_EFR_IASUP | IVHD_EFR_GTSUP;
>> +
>> + /* Build IVHD device entries */
>> + dev_entry = ivrs->ivhd_device;
>> + for ( int i = 0; i< ptdev_nr; i++ )
>> + {
>> + dev_entry[i].type = IVHD_SELECT_4_BYTE;
>> + dev_entry[i].dev_id = ptdev_bdf[i];
>> + dev_entry[i].flags = 0;
>> + }
>> +
>> + ivhd->length = sizeof(*ivhd) + sizeof(*dev_entry) * PT_DEV_MAX_NR;
>> + set_checksum(ivrs, offsetof(struct acpi_header, checksum),
>> + ivrs->header.length);
>> +
>> + return ivrs;
>> +}
>> +
>> static int construct_secondary_tables(unsigned long *table_ptrs,
>> struct acpi_info *info) { @@ -206,6 +289,7 @@ static int
>> construct_secondary_tables(un
>> struct acpi_20_hpet *hpet;
>> struct acpi_20_waet *waet;
>> struct acpi_20_tcpa *tcpa;
>> + struct acpi_40_ivrs *ivrs;
>> unsigned char *ssdt;
>> static const uint16_t tis_signature[] = {0x0001, 0x0001, 0x0001};
>> uint16_t *tis_hdr;
>> @@ -293,6 +377,13 @@ static int construct_secondary_tables(un
>> }
>> }
>>
>> + if ( !strncmp(xenstore_read("guest_iommu", "1"), "1", 1) )
>> + {
>> + ivrs = construct_ivrs();
>> + if ( ivrs != NULL )
>> + table_ptrs[nr_tables++] = (unsigned long)ivrs;
>> + }
>> +
>> table_ptrs[nr_tables] = 0;
>> return nr_tables;
>> }
>> diff -r e9d74ec10774 -r d0611a8ee06d tools/firmware/hvmloader/pci.c
>> --- a/tools/firmware/hvmloader/pci.c Thu Mar 08 13:36:54 2012 +0100
>> +++ b/tools/firmware/hvmloader/pci.c Thu Mar 08 13:36:57 2012 +0100
>> @@ -34,11 +34,17 @@ unsigned long pci_mem_end = PCI_MEM_END;
>> enum virtual_vga virtual_vga = VGA_none; unsigned long
>> igd_opregion_pgbase = 0;
>>
>> +/* support up to 32 passthrough devices */
>> +#define PT_DEV_MAX_NR 32
>> +uint32_t ptdev_bdf[PT_DEV_MAX_NR];
>> +uint32_t ptdev_nr;
>> +uint32_t iommu_bdf = 0;
>> +
>> void pci_setup(void)
>> {
>> uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0;
>> uint32_t vga_devfn = 256;
>> - uint16_t class, vendor_id, device_id;
>> + uint16_t class, vendor_id, device_id, sub_vendor_id;
>> unsigned int bar, pin, link, isa_irq;
>>
>> /* Resources assignable to PCI devices via BARs. */ @@ -72,12 +78,34 @@
>> void pci_setup(void)
>> class = pci_readw(devfn, PCI_CLASS_DEVICE);
>> vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
>> device_id = pci_readw(devfn, PCI_DEVICE_ID);
>> + sub_vendor_id = pci_readw(devfn, PCI_SUBSYSTEM_VENDOR_ID);
>> +
>> if ( (vendor_id == 0xffff)&& (device_id == 0xffff) )
>> continue;
>>
>> ASSERT((devfn != PCI_ISA_DEVFN) ||
>> ((vendor_id == 0x8086)&& (device_id == 0x7000)));
>>
>> + /* Found amd iommu device. */
>> + if ( class == 0x0806&& vendor_id == 0x1022 )
>> + {
>> + iommu_bdf = devfn;
>> + continue;
>> + }
>> + /* IVRS: Detecting passthrough devices.
>> + * sub_vendor_id != citrix&& sub_vendor_id != qemu */
>> + if ( sub_vendor_id != 0x5853&& sub_vendor_id != 0x1af4 )
>> + {
>> + /* found a passthru device */
>> + if ( ptdev_nr< PT_DEV_MAX_NR )
>> + {
>> + ptdev_bdf[ptdev_nr] = devfn;
>> + ptdev_nr++;
>> + }
>> + else
>> + printf("Number of passthru devices> PT_DEV_MAX_NR \n");
>> + }
>> +
>> switch ( class )
>> {
>> case 0x0300:
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xen.org
>> http://lists.xen.org/xen-devel
>
next prev parent reply other threads:[~2012-03-08 14:49 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-08 13:21 [PATCH 0 of 6 V6] amd iommu: support ats/gpgpu passthru on iommuv2 systems Wei Wang
2012-03-08 13:21 ` [PATCH 1 of 6 V6] amd iommu: Add 2 hypercalls for libxc Wei Wang
2012-03-08 13:35 ` Jan Beulich
2012-03-08 14:18 ` Wei Wang
2012-03-08 14:41 ` Jan Beulich
2012-03-12 11:25 ` Ian Jackson
2012-03-12 15:43 ` Wei Wang
2012-03-14 11:55 ` [Qemu-devel] [Xen-devel] " Ian Jackson
2012-03-14 11:55 ` Ian Jackson
2012-03-08 13:21 ` [PATCH 2 of 6 V6] amd iommu: call guest_iommu_set_base from hvmloader Wei Wang
2012-03-08 13:21 ` [PATCH 3 of 6 V6] hvmloader: Build IVRS table Wei Wang
2012-03-08 14:22 ` Zhang, Xiantao
2012-03-08 14:49 ` Wei Wang [this message]
2012-03-09 0:55 ` Zhang, Xiantao
2012-03-08 13:21 ` [PATCH 4 of 6 V6] libxc: add wrappers for new hypercalls Wei Wang
2012-03-08 13:21 ` [PATCH 5 of 6 V6] libxl: bind virtual bdf to physical bdf after device assignment Wei Wang
2012-03-08 13:21 ` [PATCH 6 of 6 V6] libxl: Introduce a new guest config file parameter Wei Wang
2012-03-14 14:02 ` [PATCH 0 of 6 V6] amd iommu: support ats/gpgpu passthru on iommuv2 systems Ian Jackson
2012-03-14 14:32 ` Wei Wang
2012-03-14 14:09 ` Ian Campbell
2012-03-14 14:48 ` Wei Wang
-- strict thread matches above, loose matches on Subject: below --
2012-09-26 14:47 [PATCH 3 of 6 V6] hvmloader: Build IVRS table Wei Wang
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=4F58C70C.8070800@amd.com \
--to=wei.wang2@amd.com \
--cc=Ian.Campbell@citrix.com \
--cc=Ian.Jackson@eu.citrix.com \
--cc=JBeulich@suse.com \
--cc=keir@xen.org \
--cc=xen-devel@lists.xensource.com \
--cc=xiantao.zhang@intel.com \
/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.