From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932206AbcHSBSP (ORCPT ); Thu, 18 Aug 2016 21:18:15 -0400 Received: from mail-bl2nam02on0050.outbound.protection.outlook.com ([104.47.38.50]:33760 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750768AbcHSBSL (ORCPT ); Thu, 18 Aug 2016 21:18:11 -0400 X-Greylist: delayed 20070 seconds by postgrey-1.27 at vger.kernel.org; Thu, 18 Aug 2016 21:18:10 EDT Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Suravee.Suthikulpanit@amd.com; From: Suravee Suthikulpanit To: , , , CC: , , , Suravee Suthikulpanit Subject: [PART2 PATCH v6 04/12] iommu/amd: Add support for multiple IRTE formats Date: Thu, 18 Aug 2016 14:42:36 -0500 Message-ID: <1471549364-6672-5-git-send-email-Suravee.Suthikulpanit@amd.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1471549364-6672-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1471549364-6672-1-git-send-email-Suravee.Suthikulpanit@amd.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [114.109.128.54] X-ClientProxiedBy: KL1PR0201CA0016.apcprd02.prod.outlook.com (10.167.53.154) To MWHPR12MB1453.namprd12.prod.outlook.com (10.172.55.22) X-MS-Office365-Filtering-Correlation-Id: 7de77ec3-7074-491b-907c-08d3c79ff3f3 X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1453;2:H9h4ugtFLG0icQ0Qg0/LXaHy8lrybxaBs+pHsv/RId7ZPhMDsWAORCFj3pEzUcA11A7hwKb0UnqeruQGdTcdpKlzWJsZkOCpX3fCPu/I3N1TRcEjyIhwtW4NKQrYVpQKKvHkND9+9sYhuusFn5VAQ3GAwUnem8S81nyu7sRf1l0nfmfew1VVVYBRG60FhaZW;3:vJnd6BvYkR7I6gnEwJQYYULx/kbNoPE5Io6Fl67qRs0WlGMNEheElgcgVFZEeJoHt18ugMKWlJvFMb+sseyGSpGZkQ7ffpde9EmhakhtueDhaS7wFiVfUH78JWscA7MW X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:MWHPR12MB1453; X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1453;25:qjwvvk1DKvIzdB2aA4MoN3J0mYuCqMgT98NdHRmfG+TkpcEDt3zK72DWJafH1MpThsE1vZ6H3BaUbkCA2krmeztytMWi17FRsyrkPCl50MveACt6kFwJMsm80XyFM3SePW9XL+TUAuhTbhGfI2AqMll6jiR3Gc1VxX5XhX5Bu3AVucLar4ORvtikeoeM47hWEIkB0mOF2Gi7ye/0hAPHVYNTXIvqJhdFzH1F7VEwjLpruFNFmI6R4OOTjLPhAmbR3STusU4gjjH0o9QGMss2BdWw9HPwwvRokpUwHhrSLvtHpj6IkRXK15JPNcgkKpJKyTPS9hcThkYQXBWekMt4zU0fhR/99RyPL3vHRtzFpYDkP8jdB02Clb3E4z0ExO72rDAf/pgbXBp1Th/iHLc4M2M+r/fLaB7qqix1dxcqmVuEVAJ/WkmZj1UGEkU2JPcCme+72u1C+3KZo58xapxs41jhDUzSisf6SahDtmyo9iWRxUFv5kSV/sTDaSAuH3QtKqC6uMdJKWyZ4qyE34ZiAFPRR+EThcluIi7a/WwqQAA63lMgJZnmuLwS/zQgdj8yhwuZeW8LRhbs0Bt3nfvb2BpWBGitARs9aHNQX/K3FPzIGdfVqY/lnyibDYPGjrmoKgirrEyooFpIWhGxIGySp05GFR3qQ2S1aXxIh8FlQ27Nsst2hjh1ZFNtG0jE7yQ1YSJqPxhD7MK9jxutP4TYigqQ4XN6FR1pqIR0xRYxVgQ= X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1453;31:IXp0QtEa2L18Z+zuq29XFWghFxfTxx8houwotL7WYnYeUdsAYBUBpkS3/Byg+HFDjocJP6D7qa6ZWV+dZYKSNjQKu29XsAJVmL/HUssF5ZDknY10Z1kJmu84+olNu70F02+hoFQAZEqOYAb76fNEzEC2l7Nhm2VPvxh/mmQZFFpYcbGMPWPEmsD9OxiETuY0NfqbGSp2eWM0Untx8akZ0/OHFzMNAb7w6Maw9dOCpC8=;20:n7CgrVlEFYzTqc29ftLNwT+vsC/eaahiQLY0zDoNIoHSKUzeQMqTnj2WqbrMaTku9fPLRI3ReVvoLqTQ2edW+Ma2mh7dIe7Yd60/QZUkzXtKyPQXCfsfoGJ5Ft7gmEEalnYO778UUZVlY6KPl/7QjYqXJXr+ANpMquZrPKu7yNR8YrwgOlQbW07JcesUogPf7Krn7pfQKGL4k8ZRIzuz2KWGf14SZLlDpdkLt314Yj8fM9Hkr4e9aKw3DIL0W4rVmwHdevqTOZ4uW/VTYharpPgeXcWQlZrOXAv3ZCXSQyoj1R3z/MF4FJgQK1z+kywrWWueibFa/ASUzA5WS4yZpqZTMLBG5P3HFwvdRIN1fyr8ym7A/G3W+rziknn6eD128464jnq/4c5BsWuBmBY6H7uZAiRw1EOIQBHuloJsw9tKZp2DwhI3RCQF+aLRv0dnxIG/U7OxMXTW5zQD5An/rt2cKj6i09fMHXREyrPIjvO+1PVSgLJjACXzQhZMwQqC X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6055026);SRVR:MWHPR12MB1453;BCL:0;PCL:0;RULEID:;SRVR:MWHPR12MB1453; X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1453;4:cTPM0vB4wMoVrOM5yFpXaK9UnxktpqXy5LHo0yvrB1BqXcyq6j31/0dg1GyrYN9OttOZ3pyDQiVv/nqEA1vWsTo9fRcdgVc2rKUtRT0IY4c+WDx4aOQZa+WjbDFKMPPKAEi/ftxzJEqJT4y3UwIteFqKldunJk6f2tqMT2HRolCAhPqQhUGg+wjiskbQNS5m2y5Cvow8Osgo+ZSHoc2tKerYZJW1E8iwCaMNcoXqOAGcN5qu8BM4WbpxtsEujsiyvuvSQ0KXh3ajC6opsJnRKKIxTk3t1dYnVywibukGS6+2pyFtZQCkWX3UKMgGM3WHVb9shQz4VF8a7qIYJTRYjY1X9aNTcqP0gTETh1hawDcDkC9bcM00f6wQnQcW+xtMMCJzuG1IODTCgeUwHvuOs+9rYEItjVk6xDCDldJix70ZCoJLP4p8mxHCfNRQfFIx X-Forefront-PRVS: 0038DE95A2 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6069001)(6009001)(7916002)(189002)(199003)(86362001)(42186005)(50226002)(19580395003)(586003)(68736007)(92566002)(3846002)(6116002)(189998001)(105586002)(8676002)(81156014)(81166006)(5003940100001)(47776003)(5001770100001)(2950100001)(97736004)(48376002)(77096005)(50986999)(50466002)(106356001)(36756003)(2201001)(305945005)(19580405001)(76176999)(7846002)(7736002)(4326007)(2906002)(66066001)(229853001)(101416001);DIR:OUT;SFP:1101;SCL:1;SRVR:MWHPR12MB1453;H:localhost.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;MWHPR12MB1453;23:OAtB2tnaLMo4KLl7pb0O7tccVdba4kARKbxOTeSAq?= =?us-ascii?Q?UILmMctQdiCf4FQvCKq0rCarMG3+yxxjAUSu5ZTjsKswH8+0TDOm6xE1oemM?= =?us-ascii?Q?QeOm+n+JCssMuALDenIDHbmWE2J4AAyRxAo79o5EdvYpJp2yqiicc9lzwr9T?= =?us-ascii?Q?HVSy2JEF77wnoT9byX4KhcRmzZVY8LDKCuyW7vHN59LhjqK90tKTkyDmeErf?= =?us-ascii?Q?17gwEDhbkbaYHym0MbgCXFf11yDzsn1IxIucE2OJ/VU11F2AWe+oW5G/rBIA?= =?us-ascii?Q?0NuTK+LSG7dOLLCGTekU6tZp7ZG/VF09jA81vkBBHcOcKXrayqYR1H5ldCNk?= =?us-ascii?Q?4Omiik/9tsXTga9lPRtTE5vt6RWaaTdHLPSlDCCnQEWf0a4LURJP3UUJ5gWq?= =?us-ascii?Q?Y8mehH6wZ3v4Su7+XMoBatC+GjOVb80mL3+6yuf8hgctCYFua3e4486DpOW4?= =?us-ascii?Q?+hwRdgpXE94/iMtAH8rswnKI4XpDalPdfMaGqkh6+tNSoKPElmVFBh3SXCl4?= =?us-ascii?Q?Tsw2Jf3F1lXCZMFQoNlRpmg+f6OuPbnKxQdn4iHjGGxH4g4pMk9bANs6w5wU?= =?us-ascii?Q?IItyLr9Tv6yqF9UtcIrzrcn4qJAbMjiHmU+JulTQRxFVQU298btfCj5JP9cl?= =?us-ascii?Q?zeCRhh+Q4Sj0xXUuiKxTuHF/DB8CsspWAkmU2NBZT5UBW1eDDF//2Tw+S/BL?= =?us-ascii?Q?NDnmCMjiEkSMTmgq7o0GpBs+PN253A3hu9K4AnXx3SHQ784f4y54jvQ6kQJQ?= =?us-ascii?Q?3szZHoCytR5fzN1KOJSIsXjIkWtHTrUM92trE6+zfxBV8M7te5jYeoPUN8BF?= =?us-ascii?Q?hbr4HuL5OW4hhyFs5e98ZlKSPECeeTOwBSTXQJf1VCz9T+rCHbib+4D+6TiZ?= =?us-ascii?Q?TVopI0eFm+zF5+wUPiOgrxh028v56mdt1dQ+footz2FaiDvV4jRYIL8t69k3?= =?us-ascii?Q?T2QBTc6N6J6fimESPxErE+3b3UBMIl8AmMP4QCacWMYCaElWN2QnTafDVin0?= =?us-ascii?Q?TnMURWwM7kSDuHJgg0co/y9kUxDQI/ManXd1OtuqvrZaoRB4H1lYQf9cVUfQ?= =?us-ascii?Q?ICDX7/QMiaz0QlLMB1EH0elHPbf?= X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1453;6:MxP6B5RT48Gd7Ol73chL7AFxcJp7i74u621korNsl6Cl1lXCUvO0JLXvFUJEYQp4bW41T1SymBmkMwSFo/BpCeuG+DaERdzwVEl2Kqfqm5FFtshg5SX5I51i3OaoIsJy8xB5rrzHKPmzJmjMeRnkIUB4RSa4ugeJqqcrBOeFGn/Dr8Nj2ytK8Yk9cE4WO//Plgfd2xjyzMNYYSz2Q30Oh81N3iIUa2/2vFrgEULtrk/w5poF+n1yYsAns3UNfpDfzitlirM3niAd2zvlU0zp4GnUs601QDQf+V4nqFuJRMaWV0D1tjnP7dpQhvXPB7e/4HXHYczM0rUAWD0a4eZ9ug==;5:4GTjg/moSXC3mj3HoImRtNNDmGJlKUmpVtIWT5xk2j0MBcrpp0+sx60hwPis/t7c886GZO51dttpfOrPsgBe1sNDjvS2O33s9tikaW8BtpBfsO4EFnjRj5bp/PzdUwbbNbVElxOnYldJPl7WReAysA==;24:kdPuc/WuWnuyLYszPWU913JxYXjePpFs4VDd3uP7em5q111k6HQBfmUfNgb4RmUbwPNH23atUkDKPxjS91wGR5S/vSXSiVK9zfsc4KSj6+o=;7:o5aP1XXOg+WS4AQin0GsYMDtmvVT2yM8J0yiw22xk/C+76DKSv0NtpCrwKOELH8CoZ7zgo5JGgKN4jKiT/ziLAU7l10XRO1OaYBfOX9pcLR+VoMuPLOI4xMxy58eKXttgNAOrxs4UkE71Ds32nsNQpIOWGl1iI3Yc8J+EUEutBPFJy/y3BaP/S14AQKJmmhtAH46eDyPztpwWf3sb+A2hgFiW+Bpe6edPu/24TbxVWz7lI+OB7Sxr5kvbTRU0T4J SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1453;20:ou8xvUv9mgOtzqM+rgwwWfrFKdIA4GQjG43wJYl+9WxOKlTzgNRm/4e0WIzEW4peMrnQoCOnqaHrsLGSNVnrdwTK4T91WfQq9WBpsqp/ggmm7Hkcg+eQhbIaBSa71Yw2wMLQADAuEJRhCa40JdK8vit4VN2vxseWq7qDVtR0r7F7uVVbAsNBLIMB/PQeN7tS3fC6VVurZ7sRaiCTmSVDbTLHFzdYwH9jVyKlrbbXzCBwxFJB4FfYtUTU8XBQlYq6 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Aug 2016 19:43:37.1274 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1453 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch enables support for the new 128-bit IOMMU IRTE format, which can be used for both legacy and vapic interrupt remapping modes. It replaces the existing operations on IRTE, which can only support the older 32-bit IRTE format, with calls to the new struct amd_irt_ops. It also provides helper functions for setting up, accessing, and updating interrupt remapping table entries in different mode. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd_iommu.c | 72 +++++++++++++++++++++++++++-------------- drivers/iommu/amd_iommu_init.c | 2 ++ drivers/iommu/amd_iommu_types.h | 1 - 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 139ea8b..abfb2b7 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -3714,8 +3714,6 @@ static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) amd_iommu_dev_table[devid].data[2] = dte; } -#define IRTE_ALLOCATED (~1U) - static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic) { struct irq_remap_table *table = NULL; @@ -3761,13 +3759,18 @@ static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic) goto out; } - memset(table->table, 0, MAX_IRQS_PER_TABLE * sizeof(u32)); + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) + memset(table->table, 0, + MAX_IRQS_PER_TABLE * sizeof(u32)); + else + memset(table->table, 0, + (MAX_IRQS_PER_TABLE * (sizeof(u64) * 2))); if (ioapic) { int i; for (i = 0; i < 32; ++i) - table->table[i] = IRTE_ALLOCATED; + iommu->irte_ops->set_allocated(table, i); } irq_lookup_table[devid] = table; @@ -3793,6 +3796,10 @@ static int alloc_irq_index(u16 devid, int count) struct irq_remap_table *table; unsigned long flags; int index, c; + struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; + + if (!iommu) + return -ENODEV; table = get_irq_table(devid, false); if (!table) @@ -3804,14 +3811,14 @@ static int alloc_irq_index(u16 devid, int count) for (c = 0, index = table->min_index; index < MAX_IRQS_PER_TABLE; ++index) { - if (table->table[index] == 0) + if (!iommu->irte_ops->is_allocated(table, index)) c += 1; else c = 0; if (c == count) { for (; c != 0; --c) - table->table[index - c + 1] = IRTE_ALLOCATED; + iommu->irte_ops->set_allocated(table, index - c + 1); index -= count - 1; goto out; @@ -3900,7 +3907,7 @@ static void free_irte(u16 devid, int index) return; spin_lock_irqsave(&table->lock, flags); - table->table[index] = 0; + iommu->irte_ops->clear_allocated(table, index); spin_unlock_irqrestore(&table->lock, flags); iommu_flush_irt(iommu, devid); @@ -3990,6 +3997,7 @@ static void irte_ga_set_affinity(void *entry, u16 devid, u16 index, modify_irte_ga(devid, index, irte); } +#define IRTE_ALLOCATED (~1U) static void irte_set_allocated(struct irq_remap_table *table, int index) { table->table[index] = IRTE_ALLOCATED; @@ -4119,19 +4127,17 @@ static void irq_remapping_prepare_irte(struct amd_ir_data *data, { struct irq_2_irte *irte_info = &data->irq_2_irte; struct msi_msg *msg = &data->msi_entry; - union irte *irte = &data->irte_entry; struct IO_APIC_route_entry *entry; + struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; + + if (!iommu) + return; data->irq_2_irte.devid = devid; data->irq_2_irte.index = index + sub_handle; - - /* Setup IRTE for IOMMU */ - irte->val = 0; - irte->fields.vector = irq_cfg->vector; - irte->fields.int_type = apic->irq_delivery_mode; - irte->fields.destination = irq_cfg->dest_apicid; - irte->fields.dm = apic->irq_dest_mode; - irte->fields.valid = 1; + iommu->irte_ops->prepare(data->entry, apic->irq_delivery_mode, + apic->irq_dest_mode, irq_cfg->vector, + irq_cfg->dest_apicid); switch (info->type) { case X86_IRQ_ALLOC_TYPE_IOAPIC: @@ -4187,7 +4193,7 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, { struct irq_alloc_info *info = arg; struct irq_data *irq_data; - struct amd_ir_data *data; + struct amd_ir_data *data = NULL; struct irq_cfg *cfg; int i, ret, devid; int index = -1; @@ -4239,6 +4245,16 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, if (!data) goto out_free_data; + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) + data->entry = kzalloc(sizeof(union irte), GFP_KERNEL); + else + data->entry = kzalloc(sizeof(struct irte_ga), + GFP_KERNEL); + if (!data->entry) { + kfree(data); + goto out_free_data; + } + irq_data->hwirq = (devid << 16) + i; irq_data->chip_data = data; irq_data->chip = &amd_ir_chip; @@ -4275,6 +4291,7 @@ static void irq_remapping_free(struct irq_domain *domain, unsigned int virq, data = irq_data->chip_data; irte_info = &data->irq_2_irte; free_irte(irte_info->devid, irte_info->index); + kfree(data->entry); kfree(data); } } @@ -4286,8 +4303,11 @@ static void irq_remapping_activate(struct irq_domain *domain, { struct amd_ir_data *data = irq_data->chip_data; struct irq_2_irte *irte_info = &data->irq_2_irte; + struct amd_iommu *iommu = amd_iommu_rlookup_table[irte_info->devid]; - modify_irte(irte_info->devid, irte_info->index, &data->irte_entry); + if (iommu) + iommu->irte_ops->activate(data->entry, irte_info->devid, + irte_info->index); } static void irq_remapping_deactivate(struct irq_domain *domain, @@ -4295,10 +4315,11 @@ static void irq_remapping_deactivate(struct irq_domain *domain, { struct amd_ir_data *data = irq_data->chip_data; struct irq_2_irte *irte_info = &data->irq_2_irte; - union irte entry; + struct amd_iommu *iommu = amd_iommu_rlookup_table[irte_info->devid]; - entry.val = 0; - modify_irte(irte_info->devid, irte_info->index, &data->irte_entry); + if (iommu) + iommu->irte_ops->deactivate(data->entry, irte_info->devid, + irte_info->index); } static struct irq_domain_ops amd_ir_domain_ops = { @@ -4315,8 +4336,12 @@ static int amd_ir_set_affinity(struct irq_data *data, struct irq_2_irte *irte_info = &ir_data->irq_2_irte; struct irq_cfg *cfg = irqd_cfg(data); struct irq_data *parent = data->parent_data; + struct amd_iommu *iommu = amd_iommu_rlookup_table[irte_info->devid]; int ret; + if (!iommu) + return -ENODEV; + ret = parent->chip->irq_set_affinity(parent, mask, force); if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE) return ret; @@ -4325,9 +4350,8 @@ static int amd_ir_set_affinity(struct irq_data *data, * Atomically updates the IRTE with the new destination, vector * and flushes the interrupt entry cache. */ - ir_data->irte_entry.fields.vector = cfg->vector; - ir_data->irte_entry.fields.destination = cfg->dest_apicid; - modify_irte(irte_info->devid, irte_info->index, &ir_data->irte_entry); + iommu->irte_ops->set_affinity(ir_data->entry, irte_info->devid, + irte_info->index, cfg->vector, cfg->dest_apicid); /* * After this point, all the interrupts will start arriving diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index c3afd86..c17febb 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -1893,8 +1893,10 @@ static void iommu_enable_ga(struct amd_iommu *iommu) /* Fall through */ case AMD_IOMMU_GUEST_IR_LEGACY_GA: iommu_feature_enable(iommu, CONTROL_GA_EN); + iommu->irte_ops = &irte_128_ops; break; default: + iommu->irte_ops = &irte_32_ops; break; } #endif diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index d57c56d..a591747 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -781,7 +781,6 @@ struct irq_2_irte { struct amd_ir_data { struct irq_2_irte irq_2_irte; - union irte irte_entry; struct msi_msg msi_entry; void *entry; /* Pointer to union irte or struct irte_ga */ }; -- 1.9.1