Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755606AbcDGIW2 (ORCPT ); Thu, 7 Apr 2016 04:22:28 -0400 Received: from mail-by2on0073.outbound.protection.outlook.com ([207.46.100.73]:36454 "EHLO na01-by2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751387AbcDGIWY (ORCPT ); Thu, 7 Apr 2016 04:22:24 -0400 Authentication-Results: redhat.com; dkim=none (message not signed) header.d=none;redhat.com; dmarc=none action=none header.from=amd.com; From: Suravee Suthikulpanit To: , , , , , CC: , , , , Suravee Suthikulpanit Subject: [PART1 RFC v4 11/11] svm: Manage vcpu load/unload when enable AVIC Date: Thu, 7 Apr 2016 03:20:32 -0500 Message-ID: <1460017232-17429-12-git-send-email-Suravee.Suthikulpanit@amd.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1460017232-17429-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1460017232-17429-1-git-send-email-Suravee.Suthikulpanit@amd.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [124.121.8.20] X-ClientProxiedBy: KL1PR02CA0009.apcprd02.prod.outlook.com (10.165.15.19) To SN1PR12MB0445.namprd12.prod.outlook.com (10.162.105.139) X-MS-Office365-Filtering-Correlation-Id: a26becda-53fe-4d64-c824-08d35ebdbd2c X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0445;2:5O1io4dmxO0mVfpZIwXLtoVqRiutuD0CCGsFZFmA7238BX6d2EAxNnXWhPXCGJ9JP8wPP3r/81pB2w5NSLDGE1n8GWx0ZZWRthVJSkhAjbRX7qjS8qLGKO9a0zEDzGM4bK2JsYQai2BKrRvkF0owkk0MNaRedJiOstjR1fALHrEp72al2NSdMeRRqiaPvK8f;3:Cb1uiGthTDnW0dlj4/8s5eBvw7XCCTfi/TuuHmzP1wwCSZsWQ8iFSEta+HOoFhrSXG5QA+pyePMyH147xVDgmq1yEfbp3Rbw/e3U3KUmWcsFHbVynx2eS2x4WThoa4lS;25:1Ur8ncfLi5Nw/mUV16jJwvhu18snwr1P3YmXJmZNWR424GQV8hwFbFPgnxrC/LbLy5vZZpN3+jugXxYICwOzuRl5Qdq+2xLZrZiOw/LS2wgvnlRi+H79riDhe37wTtMAOn8aXmJqMZDwG7Q60rPfulxytJ9fb9YQWg4xrrOtys4aMOW+z7Kz4JISGdVR/ubCQwmj2Z00iTWL+Jl52NXD71Yn0BCT0OuasCCUQ+v8TyyiRXqhkPmgnL4MiQ0cZ4obZVe0O9YSCRgskj9lsFsNXMacymzV1CRdo6M/aRVc1hWwG7yEVswjNj1NBAzYC88/qqDZ81/PaF+XNUAbQVcmf0b8kg1BNue8qaEsfKJ0NI8OgC3EHAEGpfgTX/bRc0UQ+XkLcwiZazCWoFn4DWT4mE09aOFVmSwYyZie0ehfxycka0rUN3Vj0gZhcJH4phk2QVIU3LoxTFdErSnmq3cCdN+v+mDGRAIQFHyHpoNJU2xdx4YtF0zczmTylV+wbqeHnuF1xKxZnvnW34x8Lvm7nQZcWd47EwN/7USiI7oYkCbi8/jKeT8RMIs2PkPqnhbImrXZJL36Imj1eBT1zsrfgIK7EZmYDa99k/rd8uP7lWA= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0445; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0445;20:I50fUDDTCDCeGyXiESAvcB7lwKtfM+iSXPOg3n6YdrcBovbgwJNcaNKFcu2LOOml0L8hD/43uRjDD85+eOP+G1Ap22ZF0tKPj7kSIygeZ/oO8Peh8L1RmFrl3kBHvfku+EHiXuME+dk8xr+HnMN3cAeAj5sGZFjhF4hBMEYeRe9connjViRhilgiciik+eh78EapV/pt103skBHHtTEM8pNloUxq3VlVffZVz1TDro1t0rdUykOyiMOBRuYjmBipdNFcIKYvwjv7Zs5MweBhGIP3TJQ7alhVeTyQfydbNYtwowDTCvX09uPLQZoLuuYvexzZahka+4yj/PdjQugLwNk/tY7Q2uzy2yfjAOMuKuomG/NjJC4tnLmvM5GqdKhOQhDI43pRZhAGKsBfw58aHZ8OiEWAIT6aqW48rm3iCQ6LnNnA9XhaFnXnu4nLhmdDxzsrX38Vjk/aPz+nHz3wLM9FDeVp6lLFGoOw99yofTmsvyscLhRFl4Q5sDZP11cx;4:iMvG7YyZQP8rB1V1QAXOI6BICwhfHW+h5zUfBj6DS9mXpRzA+uV4yZVzcKSOBN5Tkupbf/FhGyOZ9zRhe+HlfmwoxWM6dwop0zVr6hVkep0mON06FyajUYFLlQxlIgXOxQW0KoDf2Uyrs3H6XntNlYdPtRQTtvJshcUzNv4jOabXnluISPLCe4glZJclWXKowprckh5wKTGUymaNuFCBsUQbXlxaTC95Q54lTX6lzEavC6hMNmGydpVm9Bo98IIKQB0JMkGKpDl3vS+0sQitqebJF77Nm79lwd5CrM96RKAFi19w7T3uhymiAubkX8O7gsIYW9fL9XgZXqedB5lfiMrh3xQkAO2z+wPKu9lEyoKhP/Z6K/OadVbSnLuAwDUq 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)(10201501046)(3002001);SRVR:SN1PR12MB0445;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0445; X-Forefront-PRVS: 0905A6B2C7 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6069001)(6009001)(5001770100001)(50466002)(2906002)(48376002)(50986999)(189998001)(77096005)(4326007)(2950100001)(36756003)(5003940100001)(92566002)(76176999)(47776003)(19580395003)(19580405001)(81166005)(2201001)(229853001)(50226001)(86362001)(42186005)(586003)(3846002)(5008740100001)(66066001)(1096002)(6116002);DIR:OUT;SFP:1101;SCL:1;SRVR:SN1PR12MB0445;H:localhost.localdomain;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0445;23:3iJW83XTLdySAFTlyeXlAW0iV7veZW/ggXpl3b7iR3TFKuTCCPyPm58DciONF6PuRk2Uf7LbbscNdUvrEybdoLeTfUPkGdW1/7UHHI+7WxJ4Q5gyE1+bJjp7ttq5z3UD5f2PyQw3mwcVqfo7buFhonY9AXS4pmlKOr6/mKOFH+VbW+RzoDOgeBr6f+ftmv3OQ7Z0iq5P0SVbWRdt8TPS0zUdIvqtgHpT2SlDkYsFrheTvy62qDJzLQ5kqVXH/lrGPq09NieSv2Pj0zTCmjAeSn18usoUY2p4xDP/DQFmp0nA8VWZMVP75kyKienYK234al1C4/5iiPWPlsrJrD9RIMUqV3q/bsPwYmUs7ECTBiGqY8KJFxjQlZv5mHsa74mmfSr+TyD93P7Xps895UiiD94X7zSCpleIJdDOL/DQfGLFzYYzfKs3iREQV42Oevp/O6dEsaGxOAlUlt8chN7hTzER9IbvW5gfrFFfrmZzMOsjmRryEgUCXyY3wOA2mpfS+XM46YFc1PHBAu3XyACW5jI2k1NSqucTAoCv/4yzXDTTQGkRlEiTDWGtfy7yldMHozbC6Ngve2KSRhC6z1NytQH0RZveMvf8dMlBm6tQCTZq6KhJlUJ5phd72iwegYd64ok1NaOJenEfUEUx1/0JN032IRGrrbwfBRuGj1qRCNUptkha0Tb+qo2PmTo066GDz11H97VxYLW3snpv7tPrJifjzdN9WjqKGv/9+x/hgdF1Opb8ioECmLqyvLqJhb+2fZkk6TV6eqy8gP4lAwGG8X9ZqRQJNg+T74HpNIXWDnUWMjZhizknsEotwtFz1q6UDHRlF91m8PuDujWqYBt/UUDCnSsF/3Fz5ROod41rizE= X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0445;5:E8Ck0ohDDlwN3JxhQUtKXLUHWheddOkdYhh60XIetoOytD3aM5mEsVDp6IvfWt0v5C1+a67U1Mj51xPIis6hneksOXgr8p0u5hwiEwKiwmlbUl36097gOecqOFwKfsOXOq0DfU/wv+yb2+ug5y21AA==;24:0LHenJPRzjADlbQRb4i0nCjInOO7mZU+3AVHOk5rvGoPM4Bu6Pm3e0d5VfG7xRsZz1I68FzxDVgc6CeoW7Vo+wsm//S/4Fr9rqgdMIQ3/Rg=;20:fLWmbemJiJ6rBaeL9ofUaiPMJi8f7/xvNZe6qzU5amxj22TgDnpOtCEZB85xmjWGdWQi5IoG0YGaa97/+DvyRv0ctDHNb25oYpYbjCvitewvHIkiMrIlj41smqa/KUYBYVbFPkpTInNrSaNzcwO1dAZAJYBm1swdbwbvOvsz3fuy8ob0GWM2fSoE8/XHPq2HpSDwnCtUDSwYO4k8x7zQXwoH6I4j8Eix7p9KQ6UX+hBIL6TA8mT4wbZBLRKpVfw8 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Apr 2016 08:22:17.0810 (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 Content-Length: 4673 Lines: 160 From: Suravee Suthikulpanit When a vcpu is loaded/unloaded to a physical core, we need to update host physical APIC ID information in the Physical APIC-ID table accordingly. Also, when vCPU is blocking/un-blocking (due to halt instruction), we need to make sure that the is-running bit in set accordingly in the physical APIC-ID table. Signed-off-by: Suravee Suthikulpanit --- arch/x86/kvm/svm.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index bccf6cb..f527afe 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_backing_page; u64 *avic_physical_id_cache; + bool avic_is_blocking; }; #define AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK (0xFF) @@ -1330,6 +1332,64 @@ free_avic: return err; } +/** + * This function is called during VCPU halt/unhalt. + */ +static int avic_set_running(struct kvm_vcpu *vcpu, bool is_run) +{ + u64 entry; + int h_physical_id = __default_cpu_present_to_apicid(vcpu->cpu); + struct vcpu_svm *svm = to_svm(vcpu); + + if (!svm_vcpu_avic_enabled(svm)) + return 0; + + /* ID = 0xff (broadcast), ID > 0xff (reserved) */ + if (h_physical_id >= AVIC_PHYSICAL_ID_MAX) + return -EINVAL; + + entry = READ_ONCE(*(svm->avic_physical_id_cache)); + if (is_run) + WARN_ON((entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK) != 0); + else + WARN_ON((entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK) == 0); + + entry &= ~AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK; + if (is_run) + entry |= AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK; + WRITE_ONCE(*(svm->avic_physical_id_cache), entry); + + return 0; +} + +static int avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu, bool is_load) +{ + u64 entry; + int h_physical_id = __default_cpu_present_to_apicid(cpu); + struct vcpu_svm *svm = to_svm(vcpu); + + if (!svm_vcpu_avic_enabled(svm)) + return 0; + + /* ID = 0xff (broadcast), ID > 0xff (reserved) */ + if (h_physical_id >= AVIC_PHYSICAL_ID_MAX) + return -EINVAL; + + entry = READ_ONCE(*(svm->avic_physical_id_cache)); + WARN_ON(is_load && (entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK)); + + entry &= ~AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK; + if (is_load) { + entry &= ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK; + entry |= (h_physical_id & AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK); + if (!svm->avic_is_blocking) + entry |= AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK; + } + WRITE_ONCE(*(svm->avic_physical_id_cache), entry); + + return 0; +} + static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { struct vcpu_svm *svm = to_svm(vcpu); @@ -1395,6 +1455,11 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) } } + /* We initialize this flag to one to make sure that the is_running + * bit would be set the first time the vcpu is loaded. + */ + svm->avic_is_blocking = false; + svm->nested.hsave = page_address(hsave_page); svm->msrpm = page_address(msrpm_pages); @@ -1472,6 +1537,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) @@ -1479,6 +1546,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 @@ -1494,6 +1563,18 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); } +static void svm_vcpu_blocking(struct kvm_vcpu *vcpu) +{ + to_svm(vcpu)->avic_is_blocking = true; + avic_set_running(vcpu, false); +} + +static void svm_vcpu_unblocking(struct kvm_vcpu *vcpu) +{ + to_svm(vcpu)->avic_is_blocking = false; + avic_set_running(vcpu, true); +} + static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) { return to_svm(vcpu)->vmcb->save.rflags; @@ -4858,6 +4939,8 @@ static struct kvm_x86_ops svm_x86_ops = { .prepare_guest_switch = svm_prepare_guest_switch, .vcpu_load = svm_vcpu_load, .vcpu_put = svm_vcpu_put, + .vcpu_blocking = svm_vcpu_blocking, + .vcpu_unblocking = svm_vcpu_unblocking, .update_bp_intercept = update_bp_intercept, .get_msr = svm_get_msr, -- 1.9.1