From patchwork Fri Mar 4 20:46:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Suthikulpanit, Suravee" X-Patchwork-Id: 8507651 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 458D8C0553 for ; Fri, 4 Mar 2016 20:49:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 545E420225 for ; Fri, 4 Mar 2016 20:49:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 387B5201F2 for ; Fri, 4 Mar 2016 20:49:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760276AbcCDUte (ORCPT ); Fri, 4 Mar 2016 15:49:34 -0500 Received: from mail-bn1bon0072.outbound.protection.outlook.com ([157.56.111.72]:7168 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1760228AbcCDUta (ORCPT ); Fri, 4 Mar 2016 15:49:30 -0500 Authentication-Results: redhat.com; dkim=none (message not signed) header.d=none; redhat.com; dmarc=none action=none header.from=amd.com; Received: from localhost.localdomain (124.121.8.20) by SN1PR12MB0445.namprd12.prod.outlook.com (10.162.105.139) with Microsoft SMTP Server (TLS) id 15.1.415.20; Fri, 4 Mar 2016 20:49:23 +0000 From: Suravee Suthikulpanit To: , , , , , CC: , , , , Suravee Suthikulpanit Subject: [PART1 RFC v2 10/10] svm: Manage vcpu load/unload when enable AVIC Date: Fri, 4 Mar 2016 14:46:08 -0600 Message-ID: <1457124368-2025-11-git-send-email-Suravee.Suthikulpanit@amd.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1457124368-2025-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1457124368-2025-1-git-send-email-Suravee.Suthikulpanit@amd.com> MIME-Version: 1.0 X-Originating-IP: [124.121.8.20] X-ClientProxiedBy: SINPR01CA0045.apcprd01.prod.exchangelabs.com (10.141.109.45) To SN1PR12MB0445.namprd12.prod.outlook.com (25.162.105.139) X-MS-Office365-Filtering-Correlation-Id: 70d81ea7-4c23-4e7b-776b-08d3446e79ae X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0445; 2:woJld24LZdSeppy1sNkye+s4fnd74LIfyXR8ekPNT6LGG1UX+jCIwlJVyGCuwCLr8Nduvrnv9hSW/O9AecLK/DEg4kD8MuzTk+vEiwsWQYvRJ2YVB15XTQTU4LvOfz5rOZ0Sox/KU5/bsOXjBqHexmRp4HA4PyNu8KgWRZbeFQ3DpyJl11Up9b83G0EtVsM5; 3:gPbxNuabZQID3zGnU+H9h5WbnXCBgWEac22pwv24of1cD001Sm7GfK1I25hKqP2P1tinwIf/JJ7jU7PNmL2QLbePBYHsgQfGVhGCvpmo1vTQpR3ovEswC7m8etYsIW8x; 25:Ybk5uEPfZ+PJbm3vwPzUSYYfr1ZYcc0dJL4tU+QOLCy8v3c4bqWZUN/dNfg8QYo+S/OcatDd18IkB4Qlrm/7F1Q12wvrIX3yzccj+JT43D8IzLPANmEjDhxgZkrLNIGWjTw++OwU65N0eUyvLJVN/x4+IN5MeggKo6CAimRCF/I/H2+Z4ge8r5hTykx6aTLhm6JQl7rsRgT+IJpM9f+WWDEfWtztoG02FAEg7QIwWdZ7O0Pr0qfdVdLVbOc6EfCl+UFccP8PW9yhGEelShutiW+EyybdkTv/918ofGPL08Nck4T7F7F0CJsNk4N0abUs+/C9zSSgY/bnh+x9bd/jt7Stru3ERMThou7QV9K2KoM= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0445; X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0445; 20:BNrq/ZchzHUNXQ/3zRrAjhRKu6WuMIDy2DeYhY1Yze/zuzEC5suOs1f1ojN/yYOuTqhCCpdREbw+stJY6HB7ZBEv9GXzHPDQf0j+w4WX/ePDF7WHgpIEeUYDTSrBiyLOWWJUcyPB0PTpjS4jt71BHgs2A3bsM6Jlfn28tBMeHPVic1CaNjlK1vvQDKKwSHiQJwcPhmpIOu+SAtNZEyF3R7W9s5rFt6AeOq8Qv3t8LZ0q564Zge+3A6y43X/TZPUodieEwi56NYfndx5bl+EY5ak3dNzlrbuAAFNToOHhmVqCZHJ3XryZPQFSkY6U5Vi90YCnfK7Z5pTAvl1KW0mLuOeC2RofBdsBesrIm2DySEt4pzplwjZguJADQEvp/qMMuitbCasYfiQksmyHdYrAfMNOKkjbCt6LacFflFFMxOvnhmUFYxzoaRxJ/gER0QqZKFHFsP0+O5eBp3MXdWWVDo0S9u7sWFfq4afNaqEPfCD2VrJVLFmvC66gBKlgHKey; 4:MiqPmbqlbti1fYRWzCU3eUGeTbKpCXmCzCI77NclDjQFeS1RgcNoHGwJ6y4qOms+k7TTsozTTzaqTqcp/Mgj24gQt129k7BfUD18XJ/19CNVor+7bpv16OPCubcodZfBaBn2Kyq5fmI6CZU3fDGFI8Gs2Y5Vk0f5JIaIVi6CXYZ4H98uM7TLvdG9MJqLl1Trdjeit2mBjkTASOYaK7p+w2ryC9Uo16Qvq9scS4rGMZVK8p4vZGdQfRqFRTc9EHo6yKIrVG68pF2ZBdAxYLIgd5/YWpeJi7Mg0ak6W6bgXPI17WBCm4Fm+fltd3LbqnSnsYOPi13Dj7sUvNtnJC70JqpOh8Yx3qKBg+EII0gDpD2L7LHvjWKmhus2yrflnjYr X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046); SRVR:SN1PR12MB0445; BCL:0; PCL:0; RULEID:; SRVR:SN1PR12MB0445; X-Forefront-PRVS: 0871917CDA X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6069001)(6009001)(77096005)(5001770100001)(87976001)(48376002)(47776003)(229853001)(36756003)(2201001)(66066001)(81166005)(50466002)(2950100001)(5004730100002)(189998001)(40100003)(50226001)(5003940100001)(122386002)(5008740100001)(19580405001)(2906002)(19580395003)(86362001)(4326007)(42186005)(50986999)(6116002)(3846002)(1096002)(92566002)(586003)(76176999); DIR:OUT; SFP:1101; SCL:1; SRVR:SN1PR12MB0445; H:localhost.localdomain; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN1PR12MB0445; 23:atHQDjdQw8fI95umm2cAlpJCvS5tuvvnpWAyueAuD?= =?us-ascii?Q?7lnAEjGPKkzsTJwePvq0YnzNk5QpbClGLxVBEp35cSnkzm0QQoBavFk8l8Y9?= =?us-ascii?Q?JzAcjezzi1bJ/UAAR9Fpx54w1cAmf+Kmq0pvrEmPCrP1/S2MXUW9fuGGr7ay?= =?us-ascii?Q?X0ek7jg+Z7bKCeNzZeBD6FZNK/znvTzE8L7lmecDQxa+kInhO40iaOokuY0n?= =?us-ascii?Q?WbA3lOx+mdKt30xBdW/yrb6SMGaXNHWMuxolxFbQTo2e8tSoDEZELNkLz6bm?= =?us-ascii?Q?j8PizdkO2AstqdUlzdSBWpR+aMfMvIrIN64KaztQoXDK9bcmuRQNWesKZknS?= =?us-ascii?Q?oHx4/OKnclx9VVFPO/b4M4KiBMnTG2yJWU+MuxRl3jW1z9GaPddYEX0bac9x?= =?us-ascii?Q?ApY/U8E8LdrEPj3cfJKoWWZm5Vgcs7+wTAru36wU0Mr3cXo5VkksCx6MzqJw?= =?us-ascii?Q?LS21WsUs2zUT3VvAEDas9lTMa71o/9gIJmr8MTu6d2H0efnRk182GEUot1o8?= =?us-ascii?Q?FiKTVugBA6hMYNhFJSIQpQA4kPSBAo4qI9u4bvK9fI+GAHUgUEMi20LBCwNS?= =?us-ascii?Q?sbGYOqGRLvXrm09h1r/A8t2XazQDi+kOGDX1OBhIzDkR324yTJVTX19TI2QZ?= =?us-ascii?Q?HfYPAlMzEzIeUfViThzJ0yaom50gF1IDN5A1aDJhhA0vF+m0h6Rsnz1I3E+m?= =?us-ascii?Q?n1c6O7tdDoIs3kpXdpFLStOl9KmSlS7PPDV4xJz4depA90rpSA6zqI1Z1f5S?= =?us-ascii?Q?INCWahO3p3M4txHhfavtDqQfaklS4C2tkyWKwQW2RfrNcTtU2JJI2HuulKer?= =?us-ascii?Q?PD2LV0YpxBYvXBgOIzbQHyqjtNVVhSnJRd7xzHNDOX5Rh80/mdbD80+rObIj?= =?us-ascii?Q?wSd6dtjn1bXO7KDdX/SVZczZucCNGzLUXw9FUxVyFnVk93kCA3xHBrodKL7r?= =?us-ascii?Q?SqgKLKkPkIm4OSMMUwHl4qVDDjH9ykSHAo3VKaOLg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0445; 5:vvT9mUyYA3utxXq2cLo3ZJh1LYzw0MWz0lCxSqW861spRKjmaWPHSzdhCTfoZn4PdzszRbhyqt1d0uNQO3ccuO5vudgthibBiSJf5H9Pn3VuYRnge0dIvg+N9td7831lc1JcFYWwDTZK64k80Ne2uQ==; 24:kpbTUr+SFs678ve2Z2DrTLjV5LAUnT2KiKXGGYZgSCKcQnmvl8YZNQOHuPO/+X2LECIWtY9QtFZLdY2G6jc7ClrOsne4z3flMhGpL1HXOqk=; 20:mjpuzm/dzqwX8ojtOkDBJD1tKiMq8fksx0fbOjlZ0vjy6mm8L9Fh29SMCr9M0FOA/pT2nm63+CtK4OWJqis8jg2YcCRgI4LFMJnSi5xznq+n4AXwJrUJ5nmC91qRy+4xq2TY/oIsT+ziNMgiv7ZKVgZPKexpgCE09QOcEfpbMfDPJ+keZX2U/pSKpVHShM/FI7GB+5Nbguc6TUxMoSb/vnW8Cicp1p1ByR+2yG8g1H3HxEZAr1nuEAUCy3Mh+6wQ X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Mar 2016 20:49:23.5907 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0445 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Suravee Suthikulpanit When a vcpu is loaded/unloaded to a physical core, we need to update information in the Physical APIC-ID table accordingly. Signed-off-by: Suravee Suthikulpanit --- arch/x86/kvm/svm.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 5142861..ebcade0 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -175,6 +176,7 @@ struct vcpu_svm { struct page *avic_bk_page; void *in_kernel_lapic_regs; + bool avic_was_running; }; struct __attribute__ ((__packed__)) @@ -1508,6 +1510,146 @@ static int avic_vcpu_init(struct kvm *kvm, struct vcpu_svm *svm, int id) return 0; } +static inline int +avic_update_iommu(struct kvm_vcpu *vcpu, int cpu, phys_addr_t pa, bool r) +{ + if (!kvm_arch_has_assigned_device(vcpu->kvm)) + return 0; + + /* TODO: We will hook up with IOMMU API at later time */ + return 0; +} + +static int avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu, bool is_load) +{ + int g_phy_apic_id, h_phy_apic_id; + struct svm_avic_phy_ait_entry *entry, new_entry; + struct vcpu_svm *svm = to_svm(vcpu); + int ret = 0; + + if (!avic) + return 0; + + if (!svm) + return -EINVAL; + + /* Note: APIC ID = 0xff is used for broadcast. + * APIC ID > 0xff is reserved. + */ + g_phy_apic_id = vcpu->vcpu_id; + h_phy_apic_id = __default_cpu_present_to_apicid(cpu); + + if ((g_phy_apic_id >= AVIC_PHY_APIC_ID_MAX) || + (h_phy_apic_id >= AVIC_PHY_APIC_ID_MAX)) + return -EINVAL; + + entry = avic_get_phy_ait_entry(vcpu, g_phy_apic_id); + if (!entry) + return -EINVAL; + + if (is_load) { + /* Handle vcpu load */ + phys_addr_t pa = PFN_PHYS(page_to_pfn(svm->avic_bk_page)); + + new_entry = READ_ONCE(*entry); + + BUG_ON(new_entry.is_running); + + new_entry.bk_pg_ptr = (pa >> 12) & 0xffffffffff; + new_entry.valid = 1; + new_entry.host_phy_apic_id = h_phy_apic_id; + + if (svm->avic_was_running) { + /** + * Restore AVIC running flag if it was set during + * vcpu unload. + */ + new_entry.is_running = 1; + } + ret = avic_update_iommu(vcpu, h_phy_apic_id, pa, + svm->avic_was_running); + WRITE_ONCE(*entry, new_entry); + + } else { + /* Handle vcpu unload */ + new_entry = READ_ONCE(*entry); + if (new_entry.is_running) { + phys_addr_t pa = PFN_PHYS(page_to_pfn(svm->avic_bk_page)); + + /** + * This handles the case when vcpu is scheduled out + * and has not yet not called blocking. We save the + * AVIC running flag so that we can restore later. + */ + svm->avic_was_running = true; + + /** + * We need to also clear the AVIC running flag + * and communicate the changes to IOMMU. + */ + ret = avic_update_iommu(vcpu, h_phy_apic_id, pa, 0); + + new_entry.is_running = 0; + WRITE_ONCE(*entry, new_entry); + } else { + svm->avic_was_running = false; + } + } + + return ret; +} + +/** + * This function is called during VCPU halt/unhalt. + */ +static int avic_set_running(struct kvm_vcpu *vcpu, bool is_run) +{ + int ret = 0; + int g_phy_apic_id, h_phy_apic_id; + struct svm_avic_phy_ait_entry *entry, new_entry; + struct vcpu_svm *svm = to_svm(vcpu); + phys_addr_t pa = PFN_PHYS(page_to_pfn(svm->avic_bk_page)); + + if (!avic) + return 0; + + /* Note: APIC ID = 0xff is used for broadcast. + * APIC ID > 0xff is reserved. + */ + g_phy_apic_id = vcpu->vcpu_id; + h_phy_apic_id = __default_cpu_present_to_apicid(vcpu->cpu); + + if ((g_phy_apic_id >= AVIC_PHY_APIC_ID_MAX) || + (h_phy_apic_id >= AVIC_PHY_APIC_ID_MAX)) + return -EINVAL; + + entry = avic_get_phy_ait_entry(vcpu, g_phy_apic_id); + if (!entry) + return -EINVAL; + + if (is_run) { + /** + * Handle vcpu unblocking after HLT + */ + new_entry = READ_ONCE(*entry); + new_entry.is_running = is_run; + WRITE_ONCE(*entry, new_entry); + + ret = avic_update_iommu(vcpu, h_phy_apic_id, pa, is_run); + } else { + /** + * Handle vcpu blocking due to HLT + */ + ret = avic_update_iommu(vcpu, h_phy_apic_id, pa, is_run); + + new_entry = READ_ONCE(*entry); + new_entry.is_running = is_run; + WRITE_ONCE(*entry, new_entry); + } + + return ret; +} + static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { struct vcpu_svm *svm = to_svm(vcpu); @@ -1648,6 +1790,8 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) /* This assumes that the kernel never uses MSR_TSC_AUX */ if (static_cpu_has(X86_FEATURE_RDTSCP)) wrmsrl(MSR_TSC_AUX, svm->tsc_aux); + + avic_vcpu_load(vcpu, cpu, true); } static void svm_vcpu_put(struct kvm_vcpu *vcpu) @@ -1655,6 +1799,8 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) struct vcpu_svm *svm = to_svm(vcpu); int i; + avic_vcpu_load(vcpu, 0, false); + ++vcpu->stat.host_state_reload; kvm_load_ldt(svm->host.ldt); #ifdef CONFIG_X86_64