From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751737AbcGMQ5s (ORCPT ); Wed, 13 Jul 2016 12:57:48 -0400 Received: from mail-sn1nam02on0044.outbound.protection.outlook.com ([104.47.36.44]:6752 "EHLO NAM02-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750963AbcGMQ5l (ORCPT ); Wed, 13 Jul 2016 12:57:41 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Suravee.Suthikulpanit@amd.com; From: Suravee Suthikulpanit To: , , , CC: , , , Suravee Suthikulpanit Subject: [PART2 PATCH v4 04/11] iommu/amd: Add support for multiple IRTE formats Date: Wed, 13 Jul 2016 08:20:25 -0500 Message-ID: <1468416032-7692-5-git-send-email-suravee.suthikulpanit@amd.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1468416032-7692-1-git-send-email-suravee.suthikulpanit@amd.com> References: <1468416032-7692-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: SIXPR04CA0024.apcprd04.prod.outlook.com (10.162.171.14) To SN1PR12MB0445.namprd12.prod.outlook.com (10.162.105.139) X-MS-Office365-Filtering-Correlation-Id: f3452a8f-cc32-47c9-05fe-08d3ab209632 X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0445;2:xsHHHjJ35l3Fid1YrxyCi4AI1wJxzITeMd5hC7ZU2sRiaXioIKbDBRwEZbgQA9CNnF+/GYS5xyRJSuAixPcCAYfJKwV1lE94Q16GHCD9B9slYxyae30ZxiJSI2xeajR9Vay70E35XLliQud3525ROixZjakWJtHb0PVdmGimnqw3Uq/BL2RmTQTY1+RTv2Mz;3:l01pcCQ8m5/4gKGKUF1Sn6yt5SqpRu9JZUpZ0gJQG1bu7yVrvTi4evkzFSRzvZkxJkRQVW5j8TMX5KCwk8N8YJAe/NYIyqkQuuo5gpT8woTtVHLUBns+EFWCVupyXiFI;25:xSmNlIsWSF6tiuDxgYV1C8FIhYQKNYSaIMdqe+a1lX++YmxUiY3qRWEoIPn22eDi89mcRAjVsAbLn5vNJU9ZunDmUbBH83lH5GpythVbB01QwRVPbavKpAJBdIT46mR/lAJIkDnhqgpRvZbHNSFUnThEHHWXQBV3XLx3aqXCUxUm5iATkc914hJFWeBRf5MQqoxXTY13kx0qOqL6BBwSFle5DX/rjajJT5yOnwc5wwjPKdOUnNGaYYIOG2tYESbR032gv7EUIjiqFRWJeTwq/xuOidCiDOUCkGmUECxUCfqOpqZeRwufwyLLS/Le7zSJZCpbd8wcOVI8bp44xAZS7ZeNnIM6ZZxyrQPng7vgb+S1G40ZFznOW10ztJF7KW34cyUIR9dUycZ30Kp66SaodjmRRfXrJMuw2cQiZwcOJOs=;31:zdNqEs3lweTiXmIs60EVPZ4HNwgDH4onsfYcZ6yjuGx2azdgsvIW75lTSuB89jXgDzBXNFW/cF4CAzE19HizanPyDln1rD7oCDz+kE9jVJXBpcDkDRuQU6zhd8BdupY4vOnYNHghGXzb72KdAMNV+eAKKNzjg04nRhN+J63OVx+RZ5liRCfeAufeYClmzabeWO3T3v+XUcFNGC9MoW0J4g== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0445; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0445;20:bSGJGfQ0ayLBWW8+3UdX3GN82tdho3sNK13wFZKdMCdsY8o3x4RLSToxmf8OM4d/l/rnxTWmsFkkY8xZq+qmK4BTgA84/FYFpAq77CVLmsU3WvUQxmUfXmFQCgAN8S1qOG2sRxdzpGmQNNdKQLgoaR8GwgPeWu+LxRK7umo3oy1Ab+znSgqnkT0YKCdkUQlFczEpZzRe+sfTRpv5QVOn2VWHD6AAaiPl0NQYKBf4XZ56hyIWqLpdZfyz7oHGeZIjat66A7TwAm9AskP58I2rmAbQVUyDL9wDWDIamkcU2HkypBS0FMY1evg+PeS9GP0Mhe3Mr6xm7Jh+/b8KEIXW4zsTcislY5nf95l0RbuQqO+H7hFk5nfa/2nouCC0gq/Ay+HRtsEYOGZmnqTNtxYpcrE6+GD6mSXrQVZBp+MQwvIVJcPlzLUv2+hYUpBO5nlfmqorm9SqyN0xyEuapQasMxecHsJmMxP9Ivs6Sd2wuAbxMLoMlKGHzhLtIkKu83zs;4:+7qlCOY1v8LeLZBfSG6tqcqeRMV4IUHm4jwbSWL/SIQE/k/k0zCHMOPPqH5xNACkyPvSn7IFwtzm9h8hJ9Jwq6OVAfr9SpmLCaEPqFhFD75mHNQJ8JGsAFoGi3ezOMvmaobdhlmB3Z1x1X+J+oI8Cunabt1bKKL1YLsZf1e68fRRaGClgcZqWmQ+/J6FjExOlnA2qXEmwlE5DWxfOkylRiak2+T6BjtECFoc5k0DI9lHinEaKXWBaCGIV/P4iNGLEkL4yOY9iNxuS4kjMP3X+QTJg+o3atJkVtVKZ3mub4tqDowoSRGmqtEB10UK5FAMxl23spV+8qUCWcvbZno3PWQOvsoTiSyxtIIOG+lqr2iXhGz3Q7pQ0hw6Pt7HDQjKfn8hhQqlVLe3v97/a1q/VbrfVrJmyje48Tka9YR3iss= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6055026);SRVR:SN1PR12MB0445;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0445; X-Forefront-PRVS: 000227DA0C X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6069001)(6009001)(7916002)(189002)(199003)(229853001)(101416001)(77096005)(8676002)(6116002)(2950100001)(42186005)(586003)(81156014)(81166006)(2201001)(3846002)(50986999)(4326007)(76176999)(50466002)(36756003)(5003940100001)(68736007)(105586002)(305945005)(47776003)(66066001)(86362001)(7846002)(50226002)(2906002)(48376002)(92566002)(106356001)(19580405001)(7736002)(33646002)(97736004)(189998001)(5001770100001)(19580395003);DIR:OUT;SFP:1101;SCL:1;SRVR:SN1PR12MB0445;H:localhost.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;SN1PR12MB0445;23:+tXHauSgbDMJBNexGkx+Xfh70bpLKV6p4YYzYq4F/?= =?us-ascii?Q?OI5PgOHe/XgbI0HHneuNe6PC9BvY2tlmXobmXyk69yqLapDUHseGbJ/Pejpu?= =?us-ascii?Q?vuxWtynNZsK/PLKJL54BM+n+CsRPHesece3bHLN09BSTjGtukXyHXc/DITX6?= =?us-ascii?Q?MtuLyQCu5Niyx1ekVIo6SWspOJu7C5FkqHbaTa5Cs2qyCJhkLAGtHzuRW3GY?= =?us-ascii?Q?EXn+B7cpPArMQ6Tn0cxUyx3zBIYlKrZlPIeeTChH6m/+DKCi2lEWRsFPtgem?= =?us-ascii?Q?i1Xw7bjMeF3R98pZdNS5CDcjuqlvLwCguFufFPDtXmkbkMc251kpRptOJYvc?= =?us-ascii?Q?bWOqmt9GkP8Et0D1i9pnfX05MFGuRhTqjx92o+1XNbM/eO8+3f0mN47bLas1?= =?us-ascii?Q?eQ7JIT2qvBYiKD+TA7QyFRUcuWgIuptC9Z5MKcCTIR2B4yfzPYQkiKd/kNVA?= =?us-ascii?Q?zCLh3mfbVTpL5lJhQGYNdJ7+hNCXZGgk7qCSen8xtiaDGfuEyUJVy7hdqBT5?= =?us-ascii?Q?+5N7mPVZIX/xM9lsVU6yMz7gEwkwqON0kSHqEXUHGc5qV/6yM/PGCy5CqM3h?= =?us-ascii?Q?8xgojILs4JKrjcc+xTI6H8OWaMxPXYvZ5ckjwuzxKPRFS3D1OkETCvUj18nd?= =?us-ascii?Q?23WshVS3N+vltlzBVq1xHCjhL0no4mVImn1CWTltVL9IgbfBHNi/cWTwD1eT?= =?us-ascii?Q?+5VpNOKMDq/eEi5iexYP2X2l7j6z0aISmCywL5FiG9oczt/zHHn+Ly/CYuxn?= =?us-ascii?Q?HhiA27btn27jVCsmkwB9Lq6H8nhz4uZHQ8QRb1lhXBMaJzkDikus159hLKDa?= =?us-ascii?Q?pxu7LLyrGoxAYCdNYRVx1KPQJumG+xb+2VRMrnjUDZTrKeFumnrpjMLnI62s?= =?us-ascii?Q?7hI3zrhToeQZBXu3eow+YzaWa24Uasx5RoUChRF5OVDn2xe8xJ3SMt5Mobxu?= =?us-ascii?Q?XgxBSDxbDGbeyABSZMYYTj0fXc+/1M1rvO/ppR7FeJAsCqJgos42nEpzdQKK?= =?us-ascii?Q?Q8Sv3cGImMknD8Go1j3zwOvLooBrJncbai7BvzE3A1QV1eQU9YsUg2JxAPNv?= =?us-ascii?Q?Ib69SaH1kE6Q23y6XmzLuNfU4kw02jYajCY8phuL2gOr636tg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0445;6:90d6/XKONODYvxbAXt0mgfeisfrEkcmSXMG4MJiXStCkIijl2Wf+lehkyOtxMfb37YcceaP3R5S9fSHmrOwmORn24geeLzrRKg+aQ3zR+8h5BwieOGrwoJv53eWra4XscPuX5x96Ttxa9i2tMFL3JBs5+8RfI13ntW9ZMapqS4ldsScKanpjDZ0ROf258xde6VwuvsZ6M8YaDyb7kU2DEcCoAgXMfEMZjkZ47dZUmT873/6psnpw2/AML+84F2+++zwIQ7v3pkqGrODhNBvbW6VTjeMkUwJDJE81CW8JzVvJU4Cc9v1A6fD7ke4gCZPP0Mr2j/Zus8gjdOc6zR7v2g==;5:ysJEkKwkSmptiJb6L+L+00XkUKYEJsefnBPR6VWiDiIjmGS8FhfY5hgpVFOGgbbdsHsRJi/XQdZxQd8LshwJBLB7WAuXMyPaKehEY9Kez3G+6jGb2TPpA164p0PDchu3YO2qD0yj4wyq4l52DsaxtQ==;24:viUEKDT/0H5ocGbY9MWKpgonP57xcyhAKLRj0jDCy4ZvGxmsOSnplHRtCVJt+0lyvz/1qX0aghMFtB4VfGDJZflUWL8yLKS6BQdkFtvWuSQ=;7:teeaxjVb3buhDGtaFjmN3Ee2Yt14PkYrVEquiVSIxQdgPMusR+tAIFqF8gfALhXZ7v6xQD/3f5pkIP0KEm6RfdKceg8jw7pRUIO2SWmg6nN5B79Bt8RuBAIYgh0i5pulPriBN/W2z221GF6Hk9mkbICDvVAf+r0j5fab0EjEPh5e5BuQqAoD0Zhq268/IQFZjy+VPCm0yV8mpaMJI4I5oNQfuScoDiie/oBTBiBIBuQ62AtAMEhpd1A5aKBTpT8A SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0445;20:+/cu3AEpgzQd/Xxr6oyc+Xc7sNX1gpzf2vELvQIxeIiXbAZELpY3T1UmTBLdUfGsLqz+Rs4Qmw4bt/zVY9XEnDznEY435QH4Pz7g0mu1r2+JThBAZnulJI/CyEf2iQgsLziFfWXmY5WdEGHc8OhVKBsRig62xPY/FwkXMWlssaQN1IO8VKMCvTPupkqtXQU2MNolIpvdmam5xVeopC+FQn0RmQKPQobLSBDImdZm7HmYbmomKe0AtR2Y4Hh3nEHx X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Jul 2016 13:21:21.1353 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0445 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Suravee Suthikulpanit 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 d0930b1..6635cdf 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -1883,8 +1883,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 cc59fc5..84d3918 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -792,7 +792,6 @@ struct amd_irte_ops { struct amd_ir_data { struct irq_2_irte irq_2_irte; - union irte irte_entry; void *entry; union { struct msi_msg msi_entry; -- 1.9.1