Message ID | 20230918144111.641369-10-paul@xen.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp2780650vqi; Mon, 18 Sep 2023 09:19:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHI1ShYFNRH5xjMc5jWCGDVEexNOMujnskY2bML86H6uKettvkKjUUmYq/4W7rqTQ73j4cz X-Received: by 2002:a05:6a00:2d20:b0:68f:cc0e:355d with SMTP id fa32-20020a056a002d2000b0068fcc0e355dmr9269228pfb.25.1695053976827; Mon, 18 Sep 2023 09:19:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695053976; cv=none; d=google.com; s=arc-20160816; b=iQen8OoDc0HhQgjeZpmqjtgYh1X14mBthXeRCfUrnB642EyNALVpmT5YmN/Blj7qsS hWcvn0rHYGIKVgjALXDdwNeQLI0m3Z7MgJ3e4dYI/iw7+Gtcspls1S1YLfxEMS22cO8Y S8MZ7S0kRWEvPhnxcxQ7BHqV2L9QKxytfwiwhMJeEO49t69LHVFhOp/yrHhhRLi1gNyR TNCsQgXVm2F4z1DC2dj6ZE+bub670m2DvzM2j7qswiUKCqgDxd3SJ6S/rM4COEhoZnsm KVrVX8GX12fZyP3lz9Ou5snh6q5k6nubcX59OKij8QoWizXNzJfXoqW290z4Jy6+h4ri LfSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Oc53yzU2VCdUyIo3BjcPhE5hr1+ghEoPGq4cggTejWY=; fh=Pw8ME2ioat+0rO24kCOjPSzdtMZ7IXXfoe/kHVOMV8g=; b=zN0UmG3PZ0DOY+YSZrn2dHTHmQuhuy4DdA+C6N7MJSpEggUSZ4F/QG+unubiVQRrhX F4Wh6cokAVd1Q6WE94DpzxbWOvtAy3gIo691yB2IYNm/UF4AVxO/EnBuR4P+viGoHVxW gwwX+cals7w6Rmlbpe6mhTKMcIsVc5AJ3DWnReaczrNneohZhhi0BuY7Ip+jn3+ZeLzR VDU81MXfR9OXZmMg07NNKJ5/DUq8XIGwTe68k/KRCBN4tP2tnH2pQSZFz4fh2bOV6Woi x7qbNRlmvsISeRVp+QKbxuYWK4CtJHqvQSDBaya0bWXkSAFVS856WDDH6pkyVW+JzZZF mt6Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xen.org header.s=20200302mail header.b="R/WcIPwh"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from agentk.vger.email (agentk.vger.email. [2620:137:e000::3:2]) by mx.google.com with ESMTPS id ea13-20020a056a004c0d00b00686baf235easi8264931pfb.258.2023.09.18.09.19.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Sep 2023 09:19:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) client-ip=2620:137:e000::3:2; Authentication-Results: mx.google.com; dkim=pass header.i=@xen.org header.s=20200302mail header.b="R/WcIPwh"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id D284080D754A; Mon, 18 Sep 2023 09:10:31 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229959AbjIRQJ6 (ORCPT <rfc822;kernel.ruili@gmail.com> + 25 others); Mon, 18 Sep 2023 12:09:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229957AbjIRQJW (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 18 Sep 2023 12:09:22 -0400 Received: from mail.xenproject.org (mail.xenproject.org [104.130.215.37]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F58D49C8; Mon, 18 Sep 2023 09:08:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=Oc53yzU2VCdUyIo3BjcPhE5hr1+ghEoPGq4cggTejWY=; b=R/WcIPwhyvbzwQowjQg0taQRF7 mgRpElbPoVEYQLzQux7XmW2HdWINeMgZ8KT/ooK55CxcHrecXjIxuoJl2TpjufIdb1ftAu/zVYLkP ySz/H1HlWPq0jGQVNlxWKP/WPDyhv6rtzScpwYdzLAf9YiwVFCbKyfz0sPWPrbYJd1bE=; Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.92) (envelope-from <paul@xen.org>) id 1qiFRI-0003Rs-6X; Mon, 18 Sep 2023 14:41:28 +0000 Received: from ec2-63-33-11-17.eu-west-1.compute.amazonaws.com ([63.33.11.17] helo=REM-PW02S00X.ant.amazon.com) by xenbits.xenproject.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from <paul@xen.org>) id 1qiFRH-0006IJ-VD; Mon, 18 Sep 2023 14:41:28 +0000 From: Paul Durrant <paul@xen.org> To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Paul Durrant <pdurrant@amazon.com>, Sean Christopherson <seanjc@google.com>, Paolo Bonzini <pbonzini@redhat.com>, Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>, Dave Hansen <dave.hansen@linux.intel.com>, "H. Peter Anvin" <hpa@zytor.com>, David Woodhouse <dwmw2@infradead.org>, x86@kernel.org Subject: [PATCH v3 09/13] KVM: xen: automatically use the vcpu_info embedded in shared_info Date: Mon, 18 Sep 2023 14:41:07 +0000 Message-Id: <20230918144111.641369-10-paul@xen.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230918144111.641369-1-paul@xen.org> References: <20230918144111.641369-1-paul@xen.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Mon, 18 Sep 2023 09:10:31 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777392918725376354 X-GMAIL-MSGID: 1777392918725376354 |
Series |
KVM: xen: update shared_info and vcpu_info handling
|
|
Commit Message
Paul Durrant
Sept. 18, 2023, 2:41 p.m. UTC
From: Paul Durrant <pdurrant@amazon.com> The VMM should only need to set the KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO attribute in response to a VCPUOP_register_vcpu_info hypercall. We can handle the default case internally since we already know where the shared_info page is. Modify get_vcpu_info_cache() to pass back a pointer to the shared info pfn cache (and appropriate offset) for any of the first 32 vCPUs if the attribute has not been set. A VMM will be able to determine whether it needs to set up default vcpu_info using the previously defined KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA Xen capability flag, which will be advertized in a subsequent patch. Also update the KVM API documentation to describe the new behaviour. Signed-off-by: Paul Durrant <pdurrant@amazon.com> --- Cc: Sean Christopherson <seanjc@google.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: David Woodhouse <dwmw2@infradead.org> Cc: x86@kernel.org v3: - Add a note to the API documentation discussing vcpu_info copying. v2: - Dispense with the KVM_XEN_HVM_CONFIG_DEFAULT_VCPU_INFO capability. - Add API documentation. --- Documentation/virt/kvm/api.rst | 22 +++++++++++++++------- arch/x86/kvm/xen.c | 15 +++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-)
Comments
On Mon, 2023-09-18 at 14:41 +0000, Paul Durrant wrote: > From: Paul Durrant <pdurrant@amazon.com> > > The VMM should only need to set the KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO > attribute in response to a VCPUOP_register_vcpu_info hypercall. We can > handle the default case internally since we already know where the > shared_info page is. Modify get_vcpu_info_cache() to pass back a pointer > to the shared info pfn cache (and appropriate offset) for any of the > first 32 vCPUs if the attribute has not been set. > > A VMM will be able to determine whether it needs to set up default > vcpu_info using the previously defined KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA > Xen capability flag, which will be advertized in a subsequent patch. > > Also update the KVM API documentation to describe the new behaviour. > > Signed-off-by: Paul Durrant <pdurrant@amazon.com> > --- > Cc: Sean Christopherson <seanjc@google.com> > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Ingo Molnar <mingo@redhat.com> > Cc: Borislav Petkov <bp@alien8.de> > Cc: Dave Hansen <dave.hansen@linux.intel.com> > Cc: "H. Peter Anvin" <hpa@zytor.com> > Cc: David Woodhouse <dwmw2@infradead.org> > Cc: x86@kernel.org > > v3: > - Add a note to the API documentation discussing vcpu_info copying. > > v2: > - Dispense with the KVM_XEN_HVM_CONFIG_DEFAULT_VCPU_INFO capability. > - Add API documentation. > --- > Documentation/virt/kvm/api.rst | 22 +++++++++++++++------- > arch/x86/kvm/xen.c | 15 +++++++++++++++ > 2 files changed, 30 insertions(+), 7 deletions(-) > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > index e9df4df6fe48..47bf3db74674 100644 > --- a/Documentation/virt/kvm/api.rst > +++ b/Documentation/virt/kvm/api.rst > @@ -5442,13 +5442,7 @@ KVM_XEN_ATTR_TYPE_LONG_MODE > > KVM_XEN_ATTR_TYPE_SHARED_INFO > Sets the guest physical frame number at which the Xen shared_info > - page resides. Note that although Xen places vcpu_info for the first > - 32 vCPUs in the shared_info page, KVM does not automatically do so > - and instead requires that KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO be used > - explicitly even when the vcpu_info for a given vCPU resides at the > - "default" location in the shared_info page. This is because KVM may > - not be aware of the Xen CPU id which is used as the index into the > - vcpu_info[] array, so may know the correct default location. > + page resides. > > Note that the shared_info page may be constantly written to by KVM; > it contains the event channel bitmap used to deliver interrupts to > @@ -5564,12 +5558,26 @@ type values: > > KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO > Sets the guest physical address of the vcpu_info for a given vCPU. > + The vcpu_info for the first 32 vCPUs defaults to the structures > + embedded in the shared_info page. The above is true only if KVM has KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA. You kind of touch on that next, but perhaps the 'if the KVM_...' condition should be moved up? > + If the KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA flag is also set in the > + Xen capabilities then the VMM is not required to set this default > + location; KVM will handle that internally. Otherwise this attribute > + must be set for all vCPUs. > + > As with the shared_info page for the VM, the corresponding page may be > dirtied at any time if event channel interrupt delivery is enabled, so > userspace should always assume that the page is dirty without relying > on dirty logging. Setting the gpa to KVM_XEN_INVALID_GPA will disable > the vcpu_info. > > + Note that, if the guest sets an explicit vcpu_info location in guest > + memory then the VMM is expected to copy the content of the structure > + embedded in the shared_info page to the new location. It is therefore > + important that no event delivery is in progress at this time, otherwise > + events may be missed. > That's difficult. It means tearing down all interrupts from passthrough devices which are mapped via PIRQs, and also all IPIs. The IPI code *should* be able to fall back to just letting the VMM handle the hypercall in userspace. But PIRQs are harder. I'd be happier if our plan — handwavy though it may be — led to being able to use the existing slow path for delivering interrupts by just *invalidating* the cache. Maybe we *should* move the memcpy into the kernel, and let it lock *both* the shinfo and new vcpu_info caches while it's doing the copy? Given that that's the only valid transition, that shouldn't be so hard, should it? > KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO > Sets the guest physical address of an additional pvclock structure > for a given vCPU. This is typically used for guest vsyscall support. > diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c > index 459f3ca4710e..660a808c0b50 100644 > --- a/arch/x86/kvm/xen.c > +++ b/arch/x86/kvm/xen.c > @@ -491,6 +491,21 @@ static void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v) > > static struct gfn_to_pfn_cache *get_vcpu_info_cache(struct kvm_vcpu *v, unsigned long *offset) > { > + if (!v->arch.xen.vcpu_info_cache.active && v->arch.xen.vcpu_id < MAX_VIRT_CPUS) { > + struct kvm *kvm = v->kvm; > + > + if (offset) { > + if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) > + *offset = offsetof(struct shared_info, > + vcpu_info[v->arch.xen.vcpu_id]); > + else > + *offset = offsetof(struct compat_shared_info, > + vcpu_info[v->arch.xen.vcpu_id]); > + } > + > + return &kvm->arch.xen.shinfo_cache; > + } > + > if (offset) > *offset = 0; >
On 18/09/2023 17:07, David Woodhouse wrote: > On Mon, 2023-09-18 at 14:41 +0000, Paul Durrant wrote: >> From: Paul Durrant <pdurrant@amazon.com> >> >> The VMM should only need to set the KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO >> attribute in response to a VCPUOP_register_vcpu_info hypercall. We can >> handle the default case internally since we already know where the >> shared_info page is. Modify get_vcpu_info_cache() to pass back a pointer >> to the shared info pfn cache (and appropriate offset) for any of the >> first 32 vCPUs if the attribute has not been set. >> >> A VMM will be able to determine whether it needs to set up default >> vcpu_info using the previously defined KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA >> Xen capability flag, which will be advertized in a subsequent patch. >> >> Also update the KVM API documentation to describe the new behaviour. >> >> Signed-off-by: Paul Durrant <pdurrant@amazon.com> >> --- >> Cc: Sean Christopherson <seanjc@google.com> >> Cc: Paolo Bonzini <pbonzini@redhat.com> >> Cc: Thomas Gleixner <tglx@linutronix.de> >> Cc: Ingo Molnar <mingo@redhat.com> >> Cc: Borislav Petkov <bp@alien8.de> >> Cc: Dave Hansen <dave.hansen@linux.intel.com> >> Cc: "H. Peter Anvin" <hpa@zytor.com> >> Cc: David Woodhouse <dwmw2@infradead.org> >> Cc: x86@kernel.org >> >> v3: >> - Add a note to the API documentation discussing vcpu_info copying. >> >> v2: >> - Dispense with the KVM_XEN_HVM_CONFIG_DEFAULT_VCPU_INFO capability. >> - Add API documentation. >> --- >> Documentation/virt/kvm/api.rst | 22 +++++++++++++++------- >> arch/x86/kvm/xen.c | 15 +++++++++++++++ >> 2 files changed, 30 insertions(+), 7 deletions(-) >> >> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst >> index e9df4df6fe48..47bf3db74674 100644 >> --- a/Documentation/virt/kvm/api.rst >> +++ b/Documentation/virt/kvm/api.rst >> @@ -5442,13 +5442,7 @@ KVM_XEN_ATTR_TYPE_LONG_MODE >> >> KVM_XEN_ATTR_TYPE_SHARED_INFO >> Sets the guest physical frame number at which the Xen shared_info >> - page resides. Note that although Xen places vcpu_info for the first >> - 32 vCPUs in the shared_info page, KVM does not automatically do so >> - and instead requires that KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO be used >> - explicitly even when the vcpu_info for a given vCPU resides at the >> - "default" location in the shared_info page. This is because KVM may >> - not be aware of the Xen CPU id which is used as the index into the >> - vcpu_info[] array, so may know the correct default location. >> + page resides. >> >> Note that the shared_info page may be constantly written to by KVM; >> it contains the event channel bitmap used to deliver interrupts to >> @@ -5564,12 +5558,26 @@ type values: >> >> KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO >> Sets the guest physical address of the vcpu_info for a given vCPU. >> + The vcpu_info for the first 32 vCPUs defaults to the structures >> + embedded in the shared_info page. > > The above is true only if KVM has KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA. > You kind of touch on that next, but perhaps the 'if the KVM_...' > condition should be moved up? > >> + If the KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA flag is also set in the >> + Xen capabilities then the VMM is not required to set this default >> + location; KVM will handle that internally. Otherwise this attribute >> + must be set for all vCPUs. >> + >> As with the shared_info page for the VM, the corresponding page may be >> dirtied at any time if event channel interrupt delivery is enabled, so >> userspace should always assume that the page is dirty without relying >> on dirty logging. Setting the gpa to KVM_XEN_INVALID_GPA will disable >> the vcpu_info. >> >> + Note that, if the guest sets an explicit vcpu_info location in guest >> + memory then the VMM is expected to copy the content of the structure >> + embedded in the shared_info page to the new location. It is therefore >> + important that no event delivery is in progress at this time, otherwise >> + events may be missed. >> > > That's difficult. It means tearing down all interrupts from passthrough > devices which are mapped via PIRQs, and also all IPIs. So those don't honour event channel masking? That seems like a problem. > > The IPI code *should* be able to fall back to just letting the VMM > handle the hypercall in userspace. But PIRQs are harder. I'd be happier > if our plan — handwavy though it may be — led to being able to use the > existing slow path for delivering interrupts by just *invalidating* the > cache. Maybe we *should* move the memcpy into the kernel, and let it > lock *both* the shinfo and new vcpu_info caches while it's doing the > copy? Given that that's the only valid transition, that shouldn't be so > hard, should it? > No, it just kind of oversteps the remit of the attribute... but I'll try adding it and see how messy it gets. Paul >> KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO >> Sets the guest physical address of an additional pvclock structure >> for a given vCPU. This is typically used for guest vsyscall support. >> diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c >> index 459f3ca4710e..660a808c0b50 100644 >> --- a/arch/x86/kvm/xen.c >> +++ b/arch/x86/kvm/xen.c >> @@ -491,6 +491,21 @@ static void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v) >> >> static struct gfn_to_pfn_cache *get_vcpu_info_cache(struct kvm_vcpu *v, unsigned long *offset) >> { >> + if (!v->arch.xen.vcpu_info_cache.active && v->arch.xen.vcpu_id < MAX_VIRT_CPUS) { >> + struct kvm *kvm = v->kvm; >> + >> + if (offset) { >> + if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) >> + *offset = offsetof(struct shared_info, >> + vcpu_info[v->arch.xen.vcpu_id]); >> + else >> + *offset = offsetof(struct compat_shared_info, >> + vcpu_info[v->arch.xen.vcpu_id]); >> + } >> + >> + return &kvm->arch.xen.shinfo_cache; >> + } >> + >> if (offset) >> *offset = 0; >> >
On Mon, 2023-09-18 at 17:15 +0100, Paul Durrant wrote: > > > + Note that, if the guest sets an explicit vcpu_info location in guest > > > + memory then the VMM is expected to copy the content of the structure > > > + embedded in the shared_info page to the new location. It is therefore > > > + important that no event delivery is in progress at this time, otherwise > > > + events may be missed. > > > > > > > That's difficult. It means tearing down all interrupts from passthrough > > devices which are mapped via PIRQs, and also all IPIs. > > So those don't honour event channel masking? That seems like a problem. Oh, *mask*. Sure, it does honour masking. But... that would mean the VMM has to keep track of which ports were *really* masked by the guest, and which ones were just masked for the switchover. Including if the guest does some mask/unmask activity *while* the switchover is happening (or locking to prevent such). I still don't think that's a kind thing to be telling the VMMs they need to do. > > > > The IPI code *should* be able to fall back to just letting the VMM > > handle the hypercall in userspace. But PIRQs are harder. I'd be happier > > if our plan — handwavy though it may be — led to being able to use the > > existing slow path for delivering interrupts by just *invalidating* the > > cache. Maybe we *should* move the memcpy into the kernel, and let it > > lock *both* the shinfo and new vcpu_info caches while it's doing the > > copy? Given that that's the only valid transition, that shouldn't be so > > hard, should it? > > > > No, it just kind of oversteps the remit of the attribute... but I'll try > adding it and see how messy it gets. Well, there's a reason I left all the vcpu_info address magic in userspace in the first place. It was there in João's original patches and I ripped it all out. But I see your logic for wanting to put it back; I suspect moving the memcpy too is part of the cost of that? Should work out OK, I think.
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index e9df4df6fe48..47bf3db74674 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -5442,13 +5442,7 @@ KVM_XEN_ATTR_TYPE_LONG_MODE KVM_XEN_ATTR_TYPE_SHARED_INFO Sets the guest physical frame number at which the Xen shared_info - page resides. Note that although Xen places vcpu_info for the first - 32 vCPUs in the shared_info page, KVM does not automatically do so - and instead requires that KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO be used - explicitly even when the vcpu_info for a given vCPU resides at the - "default" location in the shared_info page. This is because KVM may - not be aware of the Xen CPU id which is used as the index into the - vcpu_info[] array, so may know the correct default location. + page resides. Note that the shared_info page may be constantly written to by KVM; it contains the event channel bitmap used to deliver interrupts to @@ -5564,12 +5558,26 @@ type values: KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO Sets the guest physical address of the vcpu_info for a given vCPU. + The vcpu_info for the first 32 vCPUs defaults to the structures + embedded in the shared_info page. + + If the KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA flag is also set in the + Xen capabilities then the VMM is not required to set this default + location; KVM will handle that internally. Otherwise this attribute + must be set for all vCPUs. + As with the shared_info page for the VM, the corresponding page may be dirtied at any time if event channel interrupt delivery is enabled, so userspace should always assume that the page is dirty without relying on dirty logging. Setting the gpa to KVM_XEN_INVALID_GPA will disable the vcpu_info. + Note that, if the guest sets an explicit vcpu_info location in guest + memory then the VMM is expected to copy the content of the structure + embedded in the shared_info page to the new location. It is therefore + important that no event delivery is in progress at this time, otherwise + events may be missed. + KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO Sets the guest physical address of an additional pvclock structure for a given vCPU. This is typically used for guest vsyscall support. diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index 459f3ca4710e..660a808c0b50 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -491,6 +491,21 @@ static void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v) static struct gfn_to_pfn_cache *get_vcpu_info_cache(struct kvm_vcpu *v, unsigned long *offset) { + if (!v->arch.xen.vcpu_info_cache.active && v->arch.xen.vcpu_id < MAX_VIRT_CPUS) { + struct kvm *kvm = v->kvm; + + if (offset) { + if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) + *offset = offsetof(struct shared_info, + vcpu_info[v->arch.xen.vcpu_id]); + else + *offset = offsetof(struct compat_shared_info, + vcpu_info[v->arch.xen.vcpu_id]); + } + + return &kvm->arch.xen.shinfo_cache; + } + if (offset) *offset = 0;