From patchwork Mon Dec 5 19:36:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suravee Suthikulpanit X-Patchwork-Id: 9461403 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8871060459 for ; Mon, 5 Dec 2016 19:39:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7461527F8D for ; Mon, 5 Dec 2016 19:39:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6599827F90; Mon, 5 Dec 2016 19:39:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DAFAD27F8D for ; Mon, 5 Dec 2016 19:39:28 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cDz4D-0007h7-Gb; Mon, 05 Dec 2016 19:36:49 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cDz4B-0007h1-Tt for xen-devel@lists.xen.org; Mon, 05 Dec 2016 19:36:48 +0000 Received: from [85.158.137.68] by server-16.bemta-3.messagelabs.com id 83/4D-12362-FC1C5485; Mon, 05 Dec 2016 19:36:47 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA1VSe0gTcRz3d6/dzItfW+G3Za9VIpLmKnoQQWV vKgqhLAi75ekG27TdDIUCbfayqKTsaWQpBq7HMEvJlGbloyArJQ0MU8TpKkUqp40ed15a3V+f 331eX758WVIToHWskO4Q7DbeomeCKdO88Iiol5418TEDrXhJ0UAhtQKtf1YZILaiXbTZZkxJ3 0Obqhs7Vak+a7q/t0qVic5uyUHBLIWzSeg77SNzkJpFOAH62gtomdBgJwHO40cpmWDwMvDlt6 lkPBFPBVdOvkoWkfgYgtvvciUHy2rxSmitNciQwrPB35shQw5vgvNttOwEPA0aas+OYA5PgIZ LXSPpJAbw9PSQimYGlPv9jJwO+AiCJ/52QiY0OBKannoYRbQZmq9U0qM4r7dEpRhyGfjemEkr j4cMeD9UMfIUgC2QXX5QgRug8cFqRXKVgMDzDkp5fKOh7sIdQkkNg5KT9X/GeE3B0+xWUnZrp BV9z49V/ncHQ1bHxz9ttxi473SPuLVYB/0VDUjBYeC+mE+NzVd4rUmlVABce5FFnkGzLv+zkM v/LKQAESUoQhTs+wV7lMEQbbSbk00OK2+2RBliFkRbBVHkkwULbxSj96ZYS5F0CEHSV4FcgVU 1aDJL6CdxQdVr4jXjjSmJGSZeNCXY0yyCWIMiWBafLHW9QjrKlmIT9MB5Hku6CXYhWUhPMluk yxqVAhuin8gdkmlOTOWtojlZoZ6jmbpQblgmsEyY0mxjttGbfIOm6rQckobShKQKdqvZ8T/vQ 6Es0mu5XDklxGxzjKX7pGJCKq6vi5WLHfxfSpeJlu/2+LZ89f7qzopZatwY1s4eXBsXsiK3fz ip/9EU/6eF3nWsfjaxqnjfCffb5tLy8YVxLV+Kd3gSk1rOEasXmW68tt780at2Xz9wUz1UdJe Jdbi2nSr71rWzIu9SpTd8cdmgem1nk/Ze2efMwemhzrji6jlDhwVP4sVxP+e+3+6zzNdTook3 RJJ2kf8N9kFAYo4DAAA= X-Env-Sender: Suravee.Suthikulpanit@amd.com X-Msg-Ref: server-4.tower-31.messagelabs.com!1480966605!16479102!1 X-Originating-IP: [104.47.38.40] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.0.16; banners=-,-,- X-VirusChecked: Checked Received: (qmail 20535 invoked from network); 5 Dec 2016 19:36:46 -0000 Received: from mail-bl2nam02on0040.outbound.protection.outlook.com (HELO NAM02-BL2-obe.outbound.protection.outlook.com) (104.47.38.40) by server-4.tower-31.messagelabs.com with AES256-SHA256 encrypted SMTP; 5 Dec 2016 19:36:46 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=Q/OJbb6dTnjspqcA8dfMTfH0ZlT0y9EKP/CYENg1Xn0=; b=t0IiUN3r2zPdWcHhO5eNiSnjuMlZ2BmnP3G1n3B6WU0Vi6a4qZQc2Vd5nG3byAezVXiklnKkveAOOk4D3600dpk4/IJ98ggLZNwV4jO+baPWIOpxNcq2dABS34uWO+MNQurXRxrkNWJ+zmAo4Fg4XW0UExpdnm0gcPOxVyvrUZg= Received: from ssuthiku-ubuntu-zp.amd.com (165.204.77.1) by MWHPR12MB1456.namprd12.prod.outlook.com (10.172.55.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.761.9; Mon, 5 Dec 2016 19:36:40 +0000 From: Suravee Suthikulpanit To: Date: Mon, 5 Dec 2016 13:36:23 -0600 Message-ID: <1480966583-1644-1-git-send-email-suravee.suthikulpanit@amd.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: DM5PR12CA0060.namprd12.prod.outlook.com (10.175.83.150) To MWHPR12MB1456.namprd12.prod.outlook.com (10.172.55.137) X-MS-Office365-Filtering-Correlation-Id: e5758673-8b1a-42a0-d93d-08d41d460965 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:MWHPR12MB1456; X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1456; 3:WwABNwkuIYT8WPi13YpOF2/WSnvIKl7kgESZAS73/+8PNtwiUz4HSZwje3r2LfkCXPcCy/PO4B/3IY7xyOsuceQ7NEJUquFRHF7PiX5AkfhoqxQnaWLeb+6uV3w69mGXejGXSC5XU1vgre+WVN5WpHpGlTpPdl4H1z96su3310zoKPuFGszENXMx5ERtZORrfQA174/SXI/IEHOY/9nouwBEEHpfpQmPSkMAOZqMoFu0uRyOOBEiSX7vydboZ3h0nHAJRDaJHuo9I9rLaDpUeQ==; 25:UQuQQhCbFrXBb1/x1yrlsjK6qtXV/Cfo8jfdjlGRI9zsZf1BIk8cr2wy2jmU2N2FlqNr9NvGPmPVslznwYqiK8fsZgZUUrmEltdmGqa8eK/Ax2W+Lou3UuX7GPmkZWFtJrmt/UNrS+OhYE94LPOuXOPvkobhzRYYuAA36VsC7qfVJrfOdEkx1T5MBLhlH9ER0asKNQHpAIUhQXm5ndZslgPlb7oPV04QwGDM+j5VXlqdyl60dXQ3VfgPxD41fLCA5m7VT0rRqc/Seu5rWrqAtcznGtMJ0OGDdiiUboa1JnaLC3yDiIhMVM2R4/kjwQ192zh/B94ZWIpBDqnsKsAkgy3oHGQXB8apn8vg0mc+B21j8qV89xqUeTQc/raPN1dxEz+AP4oSWg/tniVKsq5VvbV7XPQPtXqQMV6wR/5QQ42OZB3m80KsOEVbQT8JUnk3 X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1456; 31:WFbM2qD0HVETT+uSb+VyhjGi0d1x+9aWz814eHW3kVwU7ptS+KwWYvdcQV+bS67g5BJyPbx2SNxdvJTJZbFH7GoDGwhE0+tmywRJwep1uc6Uc8ADxEZK6e7lGRPP5TFns6mrHTi38vQNTG3FL5gr6I/6BZLZ4tSoPxvJifSouuJQrxrTmvu5FaQZn4+wZao0DW6yaUY+PKujro83J50Iu/kXHkc2Jds6V2khzop5vbh+synhwPBPmc6daGfKpiBV; 20:kxZDPg9UU7iyTVOP9DCuijTeQNuGgCdqgqApqiR9L1jY//W+NXK8lydsP6SR4cb+MfZL84KeW3ZwcBK6IQcjlIZKat0PsozS5CuPBkv4vTcZqGVeH/vl1V720fM9tHQWjguPndpmYcuBKdWGDCxDC+ZkdWjCfT8kdwCvUmqwxXNiKGGCX9QufkL59H0zjIMDlkSVyD9KnO2Y8vJiDZU7I/uNBB6+2Y5YJ8zacIFr6okyl5PQ2GX++kbLx9csmzdF7U1z+s/9UxlLc3QjnyZy8KCaczTaG5Rf2s64UN1PTwjRMsco0/9wWIDyEzkKuUICnv5jHJ3gAoD7MWg467YhGa2OTeiUvXoFXJT5yf66iWcjuuN3hYuj1KDiLRlct26jqwdoRMUKUVE3ettRU9pIsSj2UMwTLYzaYvK5wTwKXIdemTAR378KXujqfNizjYcMLJEbZKtEA5nZ2EtBOeMsTAru0c7zTh5zkwMbOofL2UD0tvTZx6XNRbM7jHxjFr6v X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110)(146099531331640); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026)(6041248)(20161123560025)(20161123562025)(20161123564025)(20161123555025)(6042181)(6072148); SRVR:MWHPR12MB1456; BCL:0; PCL:0; RULEID:; SRVR:MWHPR12MB1456; X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1456; 4:YeANMvAlXWmfmNZslfe6zjRgbbHEuOMthLf28f0rlSZN709hZIb+RS8qUS5Ek2cTbxtvYhvT2uMbO14cHd9EY0ffbi4pOjedjuQ7L8Nne1Lt6ISmRHnWoqa9zMv/58ejAXPbJEP2xA0X16Mqn5OsI9i0l0Q9PMYewMMw9URkDI2QKPFKQ8OHVdasLJ0pfty3FMHLbaRp0rRohmq5tOj3dZIV9/vKP8oXRbLx7LTVRtGKrL4Xby+DOIA/mtl1NJQUvkLSgmhL1awRQSyWMjNWwVgF2XiNLV/Inu3lPSpBl9BZIrwR9qroXslWWk/2cLcvfOXi3KI602SPy+LpT7Oz5pu1kcEz6pqU+8yu3LIixVVq+0cX1781Gkq6Syo5gcbHxneSWgLmSa4+a0ZTCFSedzqxHK7Rjihldjq/g+FdXiycMLVSqC/TztuhdBQGECvpR1+HSYvatm13ukwYYG4OBr7jLlBkgM+vSamAh+Z/XmyH6V4bVQTPC4BKKBc5Hsp7z3jAtB7P324oUN4xcyQFKceRJtzmWDDlcjI3K/O962vGgqgQ3pP4yviOSCVYl/y9H6r8sf/F8mLov85gMUFAQVyaLftmXSWdC7QY0IeuJg59IANBqGxtM9/ZH9P8PNIXLV6BfrjURh2KYggGvWcI3xWKtgb/kL8yvHXcxvEBVeAaXWgAsSO2xbYAah4AggCj X-Forefront-PRVS: 0147E151B5 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(199003)(189002)(6666003)(6916009)(7846002)(38730400001)(2906002)(86362001)(42186005)(97736004)(47776003)(6486002)(4326007)(105586002)(50466002)(733004)(53416004)(2351001)(3846002)(6116002)(66066001)(48376002)(189998001)(106356001)(50986999)(50226002)(81166006)(8676002)(81156014)(92566002)(33646002)(110136003)(5003940100001)(305945005)(36756003)(68736007)(7736002)(5660300001)(101416001); DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR12MB1456; H:ssuthiku-ubuntu-zp.amd.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; MWHPR12MB1456; 23:0wZvWkuV8oWsF6GstGXWuHAJ9PGkVE+Qys8ykoSC3?= =?us-ascii?Q?Z8gofVOj0TALig4Z8SArZyFgZ+WSJEGTFk62j6Lz3gDd6u4f0DddDQ9I5fsi?= =?us-ascii?Q?HWF09uzCItJwAtIY8TG/N/qPiAhWLaqZ2pO4ZXzpxof9y6dkHAeb33ok3gB/?= =?us-ascii?Q?0ixZciXlPQ/U+9IzVnA4dYeC++QUNPY4dVPsfROhj7rH7HnvysBDALPHI4FL?= =?us-ascii?Q?8nXmsB+YA8Bx/Sk+GB5dVfmqHsa+dbm+SJqrhJZ8Bl4/+7+q9V48f1gVxiJQ?= =?us-ascii?Q?W9mvGSLblUTTvVcPg2+2ECFaLZjb6Z0k59YnqiKDVJSDFuXs6tvs7LPZwCB9?= =?us-ascii?Q?wqB/aybw+Hi+phdXOK4aCUGkVUmtKIekE8ARIgVNROIcC/h6cVG6mBv1zoSh?= =?us-ascii?Q?J+V+XjO+jqa5jMiId98LwQq9VVif2/GCwTrV8VirYWY7tRnsZ1Qh+sGnk7Ua?= =?us-ascii?Q?8JIBTvO89nEQLIURImty2mqty7ns54vznnyUIQbJQaks7sF9wB/A3SyltoPX?= =?us-ascii?Q?RWxjMclM27CPTz4F4XxSb0G4yK10FLe0cER4RfGyDBnqKNomOTyCJYTmmYqR?= =?us-ascii?Q?da6O3vpn3zId9qVUWxBDeANYpQYo1+1i4B+5gvzBX53k7/n/wkHrDeHsgTw6?= =?us-ascii?Q?EBY8DoaP2d0XLXjQ6y6a4DfInRzgBOf2ordZKnuk2Y3s8+K4KAS3rbqYic4+?= =?us-ascii?Q?n67mY81HFa8p/RCkg+cphQbqrm1F4sg/mrsvq+PqAU+D9+jhL3sQSYkfEBxz?= =?us-ascii?Q?sgVPCfyUisdBBnN4Kp1io8K2kzMVoXcvj1f8WBP9FhROfT5qKtyLpfkDYhXE?= =?us-ascii?Q?67+6XjZyoqZe2fhURvHVuaAAgSAbrgHrXditQiJyF8q3eUktXU85Jng4Onis?= =?us-ascii?Q?y5Yhi+NvMb0ym3i7cw+XxxmcwFq37/HzwZCGJEYEX9j6on4tn1/A8z5GnjBO?= =?us-ascii?Q?MOcw0j5z8Mc5dC6PMRM4qYE9wxZpqfUbcyBgETxUfyG21oN852q+OT3P6J4j?= =?us-ascii?Q?NLfKWiGw4H78/Sv488jtoOl?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1456; 6:L1fwnSGu1JUF/78ri/TOPXmujOKUnhx0nny0uscaNTwrraQo7W9w/a8w5PSr6v38fEytdBiDhkzbzByzysacIVSEz2RscwqBdwV4bLUk7U9kI/v549TfwgVmPr+YZo8A1MDYz+G3uoQtCGFYbAdoUgTzmtGun/r289RAH3DiYZilF6XT5lnleobbITAFeE2SJ8K9yW+sXmIxSikLCsCbmWzN/hfObePo3nVxSKKXpvZe06F/zDuhLC5k78sWApsRqs2gjOS4ablcE2PltLeecfvYT3tFakWPbgM43CHQj76VwF9eocmr3M6eZ8UMIohEyUP/g+uJelwhznpHsIWHQjR/M2UeIBWYkBMXtXSglwoHAVu1Oi8Vjhjj+R9YSt552lsxvheU3rbhUK03i0tBbGhTn33xNb+VL3Yg3hfISDxJNbytlTrML1DPv0bUp/TFX1p8Y1RE3k2AKg2/jqK8aQ==; 5:XvANrUsjdER3Vp+6oKMGRbcEpoqhx3onQE0M2MAP5EDCG4Ye+l8yOKVzInsR6ftvQbbzTwU7Xo37TZnOWb9CkVVwk4TW2Tg7KSXyizb/O2UZ2w3z23tMx048P4VssCECLolp/9vm4BCEx4LPQwvITcVznibnb9ZFdEBaYXBSaMs=; 24:6XbF0gNrpCuUqCApvor11Ul4rywig4NDoaOWJrXk0aMepAqXvUOXUbhe8HvDM7AbMb1HO+0cL6cJ5DVPBSW7id1xLO+DzSpzQN7ZoD2Mc3E= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1456; 7:Q8zm4p+K39OoApapSJNL5r9TE5MQ/PzQkstf0sJiip+peTmgvNkAs8IQ+mCKX1hCoUix5ReJ8Ukn5u941QdKzp4/P5T+I0nQr7201hRbzFQZ1zWwn4vc2Q6nJ+aqcHbC6EOr5v1Kk+uyO4HpBDHslRUJo1sYqqIu/5tFKDdL4D5IQO0zy6V2HTx01OJmLR/9x/nLBQStqYMGibfrBFJ3olqT1Z84bUb2niGFlFiY+1EWeq9/kHwmdLrNbPAGkdnnzeyj+3J1JVhRA2h60tOO9cFrG/lrglSN8JzTng0R3AVjC0bKVPAiqr1SK5+7BecWiY4b6VcZbH4YIv7PHJQ1WIdFW/GV6p3EO890NA2rMhITG5Rl96589aP/v57w8KbSebOieS2prWbvU0zHa7phWHZ4OrzGndb+p7BzJUEYcrur6p/kyW6kT2KXwHsENSWKWStECE3VVdkczEyfX9a/7g==; 20:rGmxaYSvbMvN0OduR8gtsAXch3p+eHXYQeRdaZnnJwzNfmUtu/UBtoaZhAqE6q8urhgtOe+hU/15mi5gxI+LnQiwv6fciCwVvSz4BUC2VUSQSuUgfFpOLW/Dk//MYmAqGlOvuphmdOpWikoFt17Mo17EigIMhqJdyE89Tg/V7gpVmWQR+80uaHSORFexFPahqNyVLrk1vowMj6efus7t250p7XFUA8oiWptrWQlbGnVQeU92pHB4N4lADvpZ1Q/T X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Dec 2016 19:36:40.3233 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1456 Cc: boris.ostrovsky@oracle.com, Suravee Suthikulpanit , jbeulich@suse.com, sherry.hurwitz@amd.com Subject: [Xen-devel] [PATCH v2] AMD IOMMU: Support IOAPIC IDs larger than 128 X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Currently, the driver uses the APIC ID to index into the ioapic_sbdf array. The current MAX_IO_APICS is 128, which causes the driver initialization to fail on the system with IOAPIC ID >= 128. Instead, this patch adds APIC ID in the struct ioapic_sbdf, which is used to match the entry when searching through the array. Also, this patch removes the use of ioapic_cmdline bit-map, which is used to track the ivrs_ioapic options via command line. Instead, it introduces the cmdline flag in the struct ioapic_sbdf, to identify if the entry is created during ivrs_ioapic command-line parsing. Signed-off-by: Suravee Suthikulpanit Cc: Jan Beulich Cc: Boris Ostrovsky Reviewed-by: Jan Beulich --- Changes in V2: * Fix logic error pointed out by Jan in parse_ivrs_ioapic(), parse_ivhd_device_special(), parse_ivrs_table(), parse_ivrs_table(). * Use unsigned int for array index variable. * Minor clean ups. xen/drivers/passthrough/amd/iommu_acpi.c | 102 +++++++++++++++----------- xen/drivers/passthrough/amd/iommu_intr.c | 64 +++++++++++++--- xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 6 ++ 3 files changed, 118 insertions(+), 54 deletions(-) diff --git a/xen/drivers/passthrough/amd/iommu_acpi.c b/xen/drivers/passthrough/amd/iommu_acpi.c index b92c8ad..ac902ac 100644 --- a/xen/drivers/passthrough/amd/iommu_acpi.c +++ b/xen/drivers/passthrough/amd/iommu_acpi.c @@ -633,26 +633,37 @@ static u16 __init parse_ivhd_device_extended_range( return dev_length; } -static DECLARE_BITMAP(ioapic_cmdline, ARRAY_SIZE(ioapic_sbdf)) __initdata; - static void __init parse_ivrs_ioapic(char *str) { const char *s = str; unsigned long id; unsigned int seg, bus, dev, func; + unsigned int idx; ASSERT(*s == '['); id = simple_strtoul(s + 1, &s, 0); - if ( id >= ARRAY_SIZE(ioapic_sbdf) || *s != ']' || *++s != '=' ) + if ( *s != ']' || *++s != '=' ) return; s = parse_pci(s + 1, &seg, &bus, &dev, &func); if ( !s || *s ) return; - ioapic_sbdf[id].bdf = PCI_BDF(bus, dev, func); - ioapic_sbdf[id].seg = seg; - __set_bit(id, ioapic_cmdline); + idx = ioapic_id_to_index(id); + if ( idx == MAX_IO_APICS ) + { + idx = get_next_ioapic_sbdf_index(); + if ( idx == MAX_IO_APICS ) + { + printk(XENLOG_ERR "Error: %s: Too many IO APICs.\n", __func__); + return; + } + } + + ioapic_sbdf[idx].bdf = PCI_BDF(bus, dev, func); + ioapic_sbdf[idx].seg = seg; + ioapic_sbdf[idx].id = id; + ioapic_sbdf[idx].cmdline = true; } custom_param("ivrs_ioapic[", parse_ivrs_ioapic); @@ -683,7 +694,7 @@ static u16 __init parse_ivhd_device_special( u16 header_length, u16 block_length, struct amd_iommu *iommu) { u16 dev_length, bdf; - int apic; + unsigned int apic, idx; dev_length = sizeof(*special); if ( header_length < (block_length + dev_length) ) @@ -714,21 +725,19 @@ static u16 __init parse_ivhd_device_special( * consistency here --- whether entry's IOAPIC ID is valid and * whether there are conflicting/duplicated entries. */ - apic = find_first_bit(ioapic_cmdline, ARRAY_SIZE(ioapic_sbdf)); - while ( apic < ARRAY_SIZE(ioapic_sbdf) ) + for ( idx = 0; idx < nr_ioapic_sbdf; idx++ ) { - if ( ioapic_sbdf[apic].bdf == bdf && - ioapic_sbdf[apic].seg == seg ) + if ( ioapic_sbdf[idx].bdf == bdf && + ioapic_sbdf[idx].seg == seg && + ioapic_sbdf[idx].cmdline ) break; - apic = find_next_bit(ioapic_cmdline, ARRAY_SIZE(ioapic_sbdf), - apic + 1); } - if ( apic < ARRAY_SIZE(ioapic_sbdf) ) + if ( idx < nr_ioapic_sbdf ) { AMD_IOMMU_DEBUG("IVHD: Command line override present for IO-APIC %#x" "(IVRS: %#x devID %04x:%02x:%02x.%u)\n", - apic, special->handle, seg, PCI_BUS(bdf), - PCI_SLOT(bdf), PCI_FUNC(bdf)); + ioapic_sbdf[idx].id, special->handle, seg, + PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf)); break; } @@ -737,20 +746,14 @@ static u16 __init parse_ivhd_device_special( if ( IO_APIC_ID(apic) != special->handle ) continue; - if ( special->handle >= ARRAY_SIZE(ioapic_sbdf) ) - { - printk(XENLOG_ERR "IVHD Error: IO-APIC %#x entry beyond bounds\n", - special->handle); - return 0; - } - - if ( test_bit(special->handle, ioapic_cmdline) ) + idx = ioapic_id_to_index(special->handle); + if ( idx != MAX_IO_APICS && ioapic_sbdf[idx].cmdline ) AMD_IOMMU_DEBUG("IVHD: Command line override present for IO-APIC %#x\n", special->handle); - else if ( ioapic_sbdf[special->handle].pin_2_idx ) + else if ( idx != MAX_IO_APICS && ioapic_sbdf[idx].pin_2_idx ) { - if ( ioapic_sbdf[special->handle].bdf == bdf && - ioapic_sbdf[special->handle].seg == seg ) + if ( ioapic_sbdf[idx].bdf == bdf && + ioapic_sbdf[idx].seg == seg ) AMD_IOMMU_DEBUG("IVHD Warning: Duplicate IO-APIC %#x entries\n", special->handle); else @@ -763,19 +766,27 @@ static u16 __init parse_ivhd_device_special( } else { + idx = get_next_ioapic_sbdf_index(); + if ( idx == MAX_IO_APICS ) + { + printk(XENLOG_ERR "IVHD Error: Too many IO APICs.\n"); + return 0; + } + /* set device id of ioapic */ - ioapic_sbdf[special->handle].bdf = bdf; - ioapic_sbdf[special->handle].seg = seg; + ioapic_sbdf[idx].bdf = bdf; + ioapic_sbdf[idx].seg = seg; + ioapic_sbdf[idx].id = special->handle; - ioapic_sbdf[special->handle].pin_2_idx = xmalloc_array( + ioapic_sbdf[idx].pin_2_idx = xmalloc_array( u16, nr_ioapic_entries[apic]); if ( nr_ioapic_entries[apic] && - !ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx ) + !ioapic_sbdf[idx].pin_2_idx ) { printk(XENLOG_ERR "IVHD Error: Out of memory\n"); return 0; } - memset(ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx, -1, + memset(ioapic_sbdf[idx].pin_2_idx, -1, nr_ioapic_entries[apic] * sizeof(*ioapic_sbdf->pin_2_idx)); } @@ -1025,18 +1036,13 @@ static int __init parse_ivrs_table(struct acpi_table_header *table) /* Each IO-APIC must have been mentioned in the table. */ for ( apic = 0; !error && iommu_intremap && apic < nr_ioapics; ++apic ) { - if ( !nr_ioapic_entries[apic] ) - continue; - - if ( !ioapic_sbdf[IO_APIC_ID(apic)].seg && - /* SB IO-APIC is always on this device in AMD systems. */ - ioapic_sbdf[IO_APIC_ID(apic)].bdf == PCI_BDF(0, 0x14, 0) ) - sb_ioapic = 1; + unsigned int idx; - if ( ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx ) + if ( !nr_ioapic_entries[apic] ) continue; - if ( !test_bit(IO_APIC_ID(apic), ioapic_cmdline) ) + idx = ioapic_id_to_index(IO_APIC_ID(apic)); + if ( idx == MAX_IO_APICS ) { printk(XENLOG_ERR "IVHD Error: no information for IO-APIC %#x\n", IO_APIC_ID(apic)); @@ -1044,10 +1050,18 @@ static int __init parse_ivrs_table(struct acpi_table_header *table) return -ENXIO; } - ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx = xmalloc_array( + if ( !ioapic_sbdf[idx].seg && + /* SB IO-APIC is always on this device in AMD systems. */ + ioapic_sbdf[idx].bdf == PCI_BDF(0, 0x14, 0) ) + sb_ioapic = 1; + + if ( ioapic_sbdf[idx].pin_2_idx ) + continue; + + ioapic_sbdf[idx].pin_2_idx = xmalloc_array( u16, nr_ioapic_entries[apic]); - if ( ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx ) - memset(ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx, -1, + if ( ioapic_sbdf[idx].pin_2_idx ) + memset(ioapic_sbdf[idx].pin_2_idx, -1, nr_ioapic_entries[apic] * sizeof(*ioapic_sbdf->pin_2_idx)); else { diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c index 0a9f22f..c70998d 100644 --- a/xen/drivers/passthrough/amd/iommu_intr.c +++ b/xen/drivers/passthrough/amd/iommu_intr.c @@ -32,9 +32,35 @@ struct hpet_sbdf hpet_sbdf; void *shared_intremap_table; unsigned long *shared_intremap_inuse; static DEFINE_SPINLOCK(shared_intremap_lock); +unsigned int nr_ioapic_sbdf; static void dump_intremap_tables(unsigned char key); +unsigned int ioapic_id_to_index(unsigned int apic_id) +{ + unsigned int idx; + + if ( !nr_ioapic_sbdf ) + return MAX_IO_APICS; + + for ( idx = 0 ; idx < nr_ioapic_sbdf; idx++ ) + if ( ioapic_sbdf[idx].id == apic_id ) + break; + + if ( idx == nr_ioapic_sbdf ) + return MAX_IO_APICS; + + return idx; +} + +unsigned int __init get_next_ioapic_sbdf_index(void) +{ + if ( nr_ioapic_sbdf < MAX_IO_APICS ) + return nr_ioapic_sbdf++; + + return MAX_IO_APICS; +} + static spinlock_t* get_intremap_lock(int seg, int req_id) { return (amd_iommu_perdev_intremap ? @@ -218,13 +244,19 @@ int __init amd_iommu_setup_ioapic_remapping(void) { for ( pin = 0; pin < nr_ioapic_entries[apic]; pin++ ) { + unsigned int idx; + rte = __ioapic_read_entry(apic, pin, 1); if ( rte.mask == 1 ) continue; /* get device id of ioapic devices */ - bdf = ioapic_sbdf[IO_APIC_ID(apic)].bdf; - seg = ioapic_sbdf[IO_APIC_ID(apic)].seg; + idx = ioapic_id_to_index(IO_APIC_ID(apic)); + if ( idx == MAX_IO_APICS ) + return -EINVAL; + + bdf = ioapic_sbdf[idx].bdf; + seg = ioapic_sbdf[idx].seg; iommu = find_iommu_for_device(seg, bdf); if ( !iommu ) { @@ -250,7 +282,7 @@ int __init amd_iommu_setup_ioapic_remapping(void) spin_unlock_irqrestore(lock, flags); set_rte_index(&rte, offset); - ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx[pin] = offset; + ioapic_sbdf[idx].pin_2_idx[pin] = offset; __ioapic_write_entry(apic, pin, 1, rte); if ( iommu->enabled ) @@ -277,6 +309,7 @@ void amd_iommu_ioapic_update_ire( unsigned int pin = (reg - 0x10) / 2; int saved_mask, seg, bdf, rc; struct amd_iommu *iommu; + unsigned int idx; if ( !iommu_intremap ) { @@ -284,9 +317,13 @@ void amd_iommu_ioapic_update_ire( return; } + idx = ioapic_id_to_index(IO_APIC_ID(apic)); + if ( idx == MAX_IO_APICS ) + return; + /* get device id of ioapic devices */ - bdf = ioapic_sbdf[IO_APIC_ID(apic)].bdf; - seg = ioapic_sbdf[IO_APIC_ID(apic)].seg; + bdf = ioapic_sbdf[idx].bdf; + seg = ioapic_sbdf[idx].seg; iommu = find_iommu_for_device(seg, bdf); if ( !iommu ) { @@ -313,7 +350,7 @@ void amd_iommu_ioapic_update_ire( } if ( new_rte.mask && - ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx[pin] >= INTREMAP_ENTRIES ) + ioapic_sbdf[idx].pin_2_idx[pin] >= INTREMAP_ENTRIES ) { ASSERT(saved_mask); __io_apic_write(apic, reg, value); @@ -330,7 +367,7 @@ void amd_iommu_ioapic_update_ire( /* Update interrupt remapping entry */ rc = update_intremap_entry_from_ioapic( bdf, iommu, &new_rte, reg == rte_lo, - &ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx[pin]); + &ioapic_sbdf[idx].pin_2_idx[pin]); __io_apic_write(apic, reg, ((u32 *)&new_rte)[reg != rte_lo]); @@ -357,14 +394,21 @@ void amd_iommu_ioapic_update_ire( unsigned int amd_iommu_read_ioapic_from_ire( unsigned int apic, unsigned int reg) { + unsigned int idx; + unsigned int offset; unsigned int val = __io_apic_read(apic, reg); unsigned int pin = (reg - 0x10) / 2; - unsigned int offset = ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx[pin]; + + idx = ioapic_id_to_index(IO_APIC_ID(apic)); + if ( idx == MAX_IO_APICS ) + return -EINVAL; + + offset = ioapic_sbdf[idx].pin_2_idx[pin]; if ( !(reg & 1) && offset < INTREMAP_ENTRIES ) { - u16 bdf = ioapic_sbdf[IO_APIC_ID(apic)].bdf; - u16 seg = ioapic_sbdf[IO_APIC_ID(apic)].seg; + u16 bdf = ioapic_sbdf[idx].bdf; + u16 seg = ioapic_sbdf[idx].seg; u16 req_id = get_intremap_requestor_id(seg, bdf); const u32 *entry = get_intremap_entry(seg, req_id, offset); diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h index 6c702e8..1cf9c3d 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h @@ -103,9 +103,15 @@ int amd_setup_hpet_msi(struct msi_desc *msi_desc); extern struct ioapic_sbdf { u16 bdf, seg; + u8 id; + bool cmdline; u16 *pin_2_idx; } ioapic_sbdf[MAX_IO_APICS]; +extern unsigned int nr_ioapic_sbdf; +unsigned int ioapic_id_to_index(unsigned int apic_id); +unsigned int get_next_ioapic_sbdf_index(void); + extern struct hpet_sbdf { u16 bdf, seg, id; enum {