From owner-svn-src-all@freebsd.org Wed Jan 30 11:34:53 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 656B214BCCF5; Wed, 30 Jan 2019 11:34:53 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 0DC5A8DB7A; Wed, 30 Jan 2019 11:34:53 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id EFC611EA78; Wed, 30 Jan 2019 11:34:52 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x0UBYqAx073987; Wed, 30 Jan 2019 11:34:52 GMT (envelope-from royger@FreeBSD.org) Received: (from royger@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x0UBYqu4073984; Wed, 30 Jan 2019 11:34:52 GMT (envelope-from royger@FreeBSD.org) Message-Id: <201901301134.x0UBYqu4073984@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: royger set sender to royger@FreeBSD.org using -f From: =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= Date: Wed, 30 Jan 2019 11:34:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r343573 - in head/sys: x86/xen xen X-SVN-Group: head X-SVN-Commit-Author: royger X-SVN-Commit-Paths: in head/sys: x86/xen xen X-SVN-Commit-Revision: 343573 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 0DC5A8DB7A X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.94 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.998,0]; NEURAL_HAM_LONG(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.94)[-0.944,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Jan 2019 11:34:53 -0000 Author: royger Date: Wed Jan 30 11:34:52 2019 New Revision: 343573 URL: https://svnweb.freebsd.org/changeset/base/343573 Log: xen: introduce a new way to setup event channel upcall The main differences with the currently implemented method are: - Requires a local APIC EOI, since it doesn't bypass the local APIC as the previous method used to do. - Can be set to use different IDT vectors on each vCPU. Note that FreeBSD doesn't make use of this feature since the event channel IDT vector is reserved system wide. Note that the old method of setting the event channel upcall is not removed, and will be used as a fallback if this newly introduced method is not available. MFC after: 1 month Sponsored by: Citrix Systems R&D Modified: head/sys/x86/xen/hvm.c head/sys/x86/xen/xen_intr.c head/sys/xen/hvm.h Modified: head/sys/x86/xen/hvm.c ============================================================================== --- head/sys/x86/xen/hvm.c Wed Jan 30 09:44:54 2019 (r343572) +++ head/sys/x86/xen/hvm.c Wed Jan 30 11:34:52 2019 (r343573) @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -88,6 +89,12 @@ int xen_vector_callback_enabled; */ uint32_t hvm_start_flags; +/** + * Signal whether the vector injected for the event channel upcall requires to + * be EOI'ed on the local APIC. + */ +bool xen_evtchn_needs_ack; + /*------------------------------- Per-CPU Data -------------------------------*/ DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); DPCPU_DEFINE(struct vcpu_info *, vcpu_info); @@ -223,6 +230,19 @@ xen_hvm_init_shared_info_page(void) panic("HYPERVISOR_memory_op failed"); } +static int +set_percpu_callback(unsigned int vcpu) +{ + struct xen_hvm_evtchn_upcall_vector vec; + int error; + + vec.vcpu = vcpu; + vec.vector = IDT_EVTCHN; + error = HYPERVISOR_hvm_op(HVMOP_set_evtchn_upcall_vector, &vec); + + return (error != 0 ? xen_translate_error(error) : 0); +} + /* * Tell the hypervisor how to contact us for event channel callbacks. */ @@ -240,12 +260,20 @@ xen_hvm_set_callback(device_t dev) if (xen_feature(XENFEAT_hvm_callback_vector) != 0) { int error; - xhp.value = HVM_CALLBACK_VECTOR(IDT_EVTCHN); + error = set_percpu_callback(0); + if (error == 0) { + xen_evtchn_needs_ack = true; + /* Trick toolstack to think we are enlightened */ + xhp.value = 1; + } else + xhp.value = HVM_CALLBACK_VECTOR(IDT_EVTCHN); error = HYPERVISOR_hvm_op(HVMOP_set_param, &xhp); if (error == 0) { xen_vector_callback_enabled = 1; return; - } + } else if (xen_evtchn_needs_ack) + panic("Unable to setup fake HVM param: %d", error); + printf("Xen HVM callback vector registration failed (%d). " "Falling back to emulated device interrupt\n", error); } @@ -360,6 +388,7 @@ xen_hvm_init(enum xen_hvm_init_type init_type) } xen_vector_callback_enabled = 0; + xen_evtchn_needs_ack = false; xen_hvm_set_callback(NULL); /* @@ -426,6 +455,20 @@ xen_hvm_cpu_init(void) ("Xen PV domain without vcpu_id in cpuid")); PCPU_SET(vcpu_id, (regs[0] & XEN_HVM_CPUID_VCPU_ID_PRESENT) ? regs[1] : PCPU_GET(acpi_id)); + + if (xen_evtchn_needs_ack && !IS_BSP()) { + /* + * Setup the per-vpcu event channel upcall vector. This is only + * required when using the new HVMOP_set_evtchn_upcall_vector + * hypercall, which allows using a different vector for each + * vCPU. Note that FreeBSD uses the same vector for all vCPUs + * because it's not dynamically allocated. + */ + rc = set_percpu_callback(PCPU_GET(vcpu_id)); + if (rc != 0) + panic("Event channel upcall vector setup failed: %d", + rc); + } /* * Set the vCPU info. Modified: head/sys/x86/xen/xen_intr.c ============================================================================== --- head/sys/x86/xen/xen_intr.c Wed Jan 30 09:44:54 2019 (r343572) +++ head/sys/x86/xen/xen_intr.c Wed Jan 30 11:34:52 2019 (r343573) @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -620,6 +621,10 @@ xen_intr_handle_upcall(struct trapframe *trap_frame) l1 &= ~(1UL << l1i); } } + + if (xen_evtchn_needs_ack) + lapic_eoi(); + critical_exit(); } Modified: head/sys/xen/hvm.h ============================================================================== --- head/sys/xen/hvm.h Wed Jan 30 09:44:54 2019 (r343572) +++ head/sys/xen/hvm.h Wed Jan 30 11:34:52 2019 (r343573) @@ -104,5 +104,6 @@ void xen_hvm_suspend(void); void xen_hvm_resume(bool suspend_cancelled); extern uint32_t hvm_start_flags; +extern bool xen_evtchn_needs_ack; #endif /* __XEN_HVM_H__ */