From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151776260637.7925939322884; Thu, 15 Dec 2022 16:49:36 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yp5-0007O1-IB; Thu, 15 Dec 2022 19:43:36 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynx-0005Yy-WD for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:26 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yns-0006ow-Hm for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:25 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymy-00Azys-1r; Fri, 16 Dec 2022 00:42:12 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cO8-F6; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=9eRBMBq07fZ3ikPJJeMQdDDxFNpQylTZMd1Ai8Ky8Nw=; b=flrWQC5m8bWqiVKBFNhH0ihT2G 8wbsgN+TPLUPt5y+ud0xUf3gRwg5Sr01Ru/uVNIJcPOy9vBo4omDihI4+ODhjT9wMRWvRo9Dn98dQ 03yq7I1X6QfuxipvNYZwQ5PZGdIZga5bYuI2/XPBgDZLBHQjFJMq5chwFIERbarmniXiE7H1KWw51 KIsPXQJcMDHao4iw5EZZOSXl+8fiORBMw6oeLNVuNC4L3xPwuxLau1MVrCTr6grWP083uNSFvonUg 7zEFrR8vNo2HgmPQio1pSIj/3Uffy3ligyn0MzmT35NzSg80uNIVluPv/Xl+PaCvqqXsY1pZLYo6U gJoAG2vQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 01/38] include: import xen public headers Date: Fri, 16 Dec 2022 00:40:40 +0000 Message-Id: <20221216004117.862106-2-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151778569100003 Content-Type: text/plain; charset="utf-8" From: Joao Martins Signed-off-by: Joao Martins [dwmw2: Update to Xen public headers from 4.16.2 release] Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- include/standard-headers/xen/arch-x86/cpuid.h | 118 ++ .../xen/arch-x86/xen-x86_32.h | 194 +++ .../xen/arch-x86/xen-x86_64.h | 241 ++++ include/standard-headers/xen/arch-x86/xen.h | 398 +++++++ include/standard-headers/xen/event_channel.h | 388 ++++++ include/standard-headers/xen/features.h | 143 +++ include/standard-headers/xen/grant_table.h | 686 +++++++++++ include/standard-headers/xen/hvm/hvm_op.h | 395 +++++++ include/standard-headers/xen/hvm/params.h | 318 +++++ include/standard-headers/xen/memory.h | 754 ++++++++++++ include/standard-headers/xen/physdev.h | 383 ++++++ include/standard-headers/xen/sched.h | 202 ++++ include/standard-headers/xen/trace.h | 341 ++++++ include/standard-headers/xen/vcpu.h | 248 ++++ include/standard-headers/xen/version.h | 113 ++ include/standard-headers/xen/xen-compat.h | 46 + include/standard-headers/xen/xen.h | 1049 +++++++++++++++++ 17 files changed, 6017 insertions(+) create mode 100644 include/standard-headers/xen/arch-x86/cpuid.h create mode 100644 include/standard-headers/xen/arch-x86/xen-x86_32.h create mode 100644 include/standard-headers/xen/arch-x86/xen-x86_64.h create mode 100644 include/standard-headers/xen/arch-x86/xen.h create mode 100644 include/standard-headers/xen/event_channel.h create mode 100644 include/standard-headers/xen/features.h create mode 100644 include/standard-headers/xen/grant_table.h create mode 100644 include/standard-headers/xen/hvm/hvm_op.h create mode 100644 include/standard-headers/xen/hvm/params.h create mode 100644 include/standard-headers/xen/memory.h create mode 100644 include/standard-headers/xen/physdev.h create mode 100644 include/standard-headers/xen/sched.h create mode 100644 include/standard-headers/xen/trace.h create mode 100644 include/standard-headers/xen/vcpu.h create mode 100644 include/standard-headers/xen/version.h create mode 100644 include/standard-headers/xen/xen-compat.h create mode 100644 include/standard-headers/xen/xen.h diff --git a/include/standard-headers/xen/arch-x86/cpuid.h b/include/standa= rd-headers/xen/arch-x86/cpuid.h new file mode 100644 index 0000000000..ce46305bee --- /dev/null +++ b/include/standard-headers/xen/arch-x86/cpuid.h @@ -0,0 +1,118 @@ +/*************************************************************************= ***** + * arch-x86/cpuid.h + * + * CPUID interface to Xen. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2007 Citrix Systems, Inc. + * + * Authors: + * Keir Fraser + */ + +#ifndef __XEN_PUBLIC_ARCH_X86_CPUID_H__ +#define __XEN_PUBLIC_ARCH_X86_CPUID_H__ + +/* + * For compatibility with other hypervisor interfaces, the Xen cpuid leaves + * can be found at the first otherwise unused 0x100 aligned boundary start= ing + * from 0x40000000. + * + * e.g If viridian extensions are enabled for an HVM domain, the Xen cpuid + * leaves will start at 0x40000100 + */ + +#define XEN_CPUID_FIRST_LEAF 0x40000000 +#define XEN_CPUID_LEAF(i) (XEN_CPUID_FIRST_LEAF + (i)) + +/* + * Leaf 1 (0x40000x00) + * EAX: Largest Xen-information leaf. All leaves up to an including @EAX + * are supported by the Xen host. + * EBX-EDX: "XenVMMXenVMM" signature, allowing positive identification + * of a Xen host. + */ +#define XEN_CPUID_SIGNATURE_EBX 0x566e6558 /* "XenV" */ +#define XEN_CPUID_SIGNATURE_ECX 0x65584d4d /* "MMXe" */ +#define XEN_CPUID_SIGNATURE_EDX 0x4d4d566e /* "nVMM" */ + +/* + * Leaf 2 (0x40000x01) + * EAX[31:16]: Xen major version. + * EAX[15: 0]: Xen minor version. + * EBX-EDX: Reserved (currently all zeroes). + */ + +/* + * Leaf 3 (0x40000x02) + * EAX: Number of hypercall transfer pages. This register is always guaran= teed + * to specify one hypercall page. + * EBX: Base address of Xen-specific MSRs. + * ECX: Features 1. Unused bits are set to zero. + * EDX: Features 2. Unused bits are set to zero. + */ + +/* Does the host support MMU_PT_UPDATE_PRESERVE_AD for this guest? */ +#define _XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD 0 +#define XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD (1u<<0) + +/* + * Leaf 4 (0x40000x03) + * Sub-leaf 0: EAX: bit 0: emulated tsc + * bit 1: host tsc is known to be reliable + * bit 2: RDTSCP instruction available + * EBX: tsc_mode: 0=3Ddefault (emulate if necessary), 1=3Demul= ate, + * 2=3Dno emulation, 3=3Dno emulation + TSC_AUX= support + * ECX: guest tsc frequency in kHz + * EDX: guest tsc incarnation (migration count) + * Sub-leaf 1: EAX: tsc offset low part + * EBX: tsc offset high part + * ECX: multiplicator for tsc->ns conversion + * EDX: shift amount for tsc->ns conversion + * Sub-leaf 2: EAX: host tsc frequency in kHz + */ + +/* + * Leaf 5 (0x40000x04) + * HVM-specific features + * Sub-leaf 0: EAX: Features + * Sub-leaf 0: EBX: vcpu id (iff EAX has XEN_HVM_CPUID_VCPU_ID_PRESENT fla= g) + * Sub-leaf 0: ECX: domain id (iff EAX has XEN_HVM_CPUID_DOMID_PRESENT fla= g) + */ +#define XEN_HVM_CPUID_APIC_ACCESS_VIRT (1u << 0) /* Virtualized APIC regis= ters */ +#define XEN_HVM_CPUID_X2APIC_VIRT (1u << 1) /* Virtualized x2APIC acc= esses */ +/* Memory mapped from other domains has valid IOMMU entries */ +#define XEN_HVM_CPUID_IOMMU_MAPPINGS (1u << 2) +#define XEN_HVM_CPUID_VCPU_ID_PRESENT (1u << 3) /* vcpu id is present in = EBX */ +#define XEN_HVM_CPUID_DOMID_PRESENT (1u << 4) /* domid is present in EC= X */ + +/* + * Leaf 6 (0x40000x05) + * PV-specific parameters + * Sub-leaf 0: EAX: max available sub-leaf + * Sub-leaf 0: EBX: bits 0-7: max machine address width + */ + +/* Max. address width in bits taking memory hotplug into account. */ +#define XEN_CPUID_MACHINE_ADDRESS_WIDTH_MASK (0xffu << 0) + +#define XEN_CPUID_MAX_NUM_LEAVES 5 + +#endif /* __XEN_PUBLIC_ARCH_X86_CPUID_H__ */ diff --git a/include/standard-headers/xen/arch-x86/xen-x86_32.h b/include/s= tandard-headers/xen/arch-x86/xen-x86_32.h new file mode 100644 index 0000000000..19d7388633 --- /dev/null +++ b/include/standard-headers/xen/arch-x86/xen-x86_32.h @@ -0,0 +1,194 @@ +/*************************************************************************= ***** + * xen-x86_32.h + * + * Guest OS interface to x86 32-bit Xen. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2004-2007, K A Fraser + */ + +#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ +#define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ + +/* + * Hypercall interface: + * Input: %ebx, %ecx, %edx, %esi, %edi, %ebp (arguments 1-6) + * Output: %eax + * Access is via hypercall page (set up by guest loader or via a Xen MSR): + * call hypercall_page + hypercall-number * 32 + * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx) + */ + +/* + * These flat segments are in the Xen-private section of every GDT. Since = these + * are also present in the initial GDT, many OSes will be able to avoid + * installing their own GDT. + */ +#define FLAT_RING1_CS 0xe019 /* GDT index 259 */ +#define FLAT_RING1_DS 0xe021 /* GDT index 260 */ +#define FLAT_RING1_SS 0xe021 /* GDT index 260 */ +#define FLAT_RING3_CS 0xe02b /* GDT index 261 */ +#define FLAT_RING3_DS 0xe033 /* GDT index 262 */ +#define FLAT_RING3_SS 0xe033 /* GDT index 262 */ + +#define FLAT_KERNEL_CS FLAT_RING1_CS +#define FLAT_KERNEL_DS FLAT_RING1_DS +#define FLAT_KERNEL_SS FLAT_RING1_SS +#define FLAT_USER_CS FLAT_RING3_CS +#define FLAT_USER_DS FLAT_RING3_DS +#define FLAT_USER_SS FLAT_RING3_SS + +#define __HYPERVISOR_VIRT_START_PAE 0xF5800000 +#define __MACH2PHYS_VIRT_START_PAE 0xF5800000 +#define __MACH2PHYS_VIRT_END_PAE 0xF6800000 +#define HYPERVISOR_VIRT_START_PAE xen_mk_ulong(__HYPERVISOR_VIRT_STAR= T_PAE) +#define MACH2PHYS_VIRT_START_PAE xen_mk_ulong(__MACH2PHYS_VIRT_START= _PAE) +#define MACH2PHYS_VIRT_END_PAE xen_mk_ulong(__MACH2PHYS_VIRT_END_P= AE) + +/* Non-PAE bounds are obsolete. */ +#define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000 +#define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000 +#define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000 +#define HYPERVISOR_VIRT_START_NONPAE \ + xen_mk_ulong(__HYPERVISOR_VIRT_START_NONPAE) +#define MACH2PHYS_VIRT_START_NONPAE \ + xen_mk_ulong(__MACH2PHYS_VIRT_START_NONPAE) +#define MACH2PHYS_VIRT_END_NONPAE \ + xen_mk_ulong(__MACH2PHYS_VIRT_END_NONPAE) + +#define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE +#define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE +#define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE + +#ifndef HYPERVISOR_VIRT_START +#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START) +#endif + +#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START) +#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END) +#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>= 2) +#ifndef machine_to_phys_mapping +#define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START) +#endif + +/* 32-/64-bit invariability for control interfaces (domctl/sysctl). */ +#if defined(__XEN__) || defined(__XEN_TOOLS__) +#undef ___DEFINE_XEN_GUEST_HANDLE +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ + typedef struct { type *p; } \ + __guest_handle_ ## name; \ + typedef struct { union { type *p; uint64_aligned_t q; }; } \ + __guest_handle_64_ ## name +#undef set_xen_guest_handle_raw +#define set_xen_guest_handle_raw(hnd, val) \ + do { if ( sizeof(hnd) =3D=3D 8 ) *(uint64_t *)&(hnd) =3D 0; \ + (hnd).p =3D val; \ + } while ( 0 ) +#define int64_aligned_t int64_t __attribute__((aligned(8))) +#define uint64_aligned_t uint64_t __attribute__((aligned(8))) +#define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name +#define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name) +#endif + +#ifndef __ASSEMBLY__ + +#if defined(XEN_GENERATING_COMPAT_HEADERS) +/* nothing */ +#elif defined(__XEN__) || defined(__XEN_TOOLS__) +/* Anonymous unions include all permissible names (e.g., al/ah/ax/eax). */ +#define __DECL_REG_LO8(which) union { \ + uint32_t e ## which ## x; \ + uint16_t which ## x; \ + struct { \ + uint8_t which ## l; \ + uint8_t which ## h; \ + }; \ +} +#define __DECL_REG_LO16(name) union { \ + uint32_t e ## name, _e ## name; \ + uint16_t name; \ +} +#else +/* Other sources must always use the proper 32-bit name (e.g., eax). */ +#define __DECL_REG_LO8(which) uint32_t e ## which ## x +#define __DECL_REG_LO16(name) uint32_t e ## name +#endif + +struct cpu_user_regs { + __DECL_REG_LO8(b); + __DECL_REG_LO8(c); + __DECL_REG_LO8(d); + __DECL_REG_LO16(si); + __DECL_REG_LO16(di); + __DECL_REG_LO16(bp); + __DECL_REG_LO8(a); + uint16_t error_code; /* private */ + uint16_t entry_vector; /* private */ + __DECL_REG_LO16(ip); + uint16_t cs; + uint8_t saved_upcall_mask; + uint8_t _pad0; + __DECL_REG_LO16(flags); /* eflags.IF =3D=3D !saved_upcall_mask */ + __DECL_REG_LO16(sp); + uint16_t ss, _pad1; + uint16_t es, _pad2; + uint16_t ds, _pad3; + uint16_t fs, _pad4; + uint16_t gs, _pad5; +}; +typedef struct cpu_user_regs cpu_user_regs_t; +DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); + +#undef __DECL_REG_LO8 +#undef __DECL_REG_LO16 + +/* + * Page-directory addresses above 4GB do not fit into architectural %cr3. + * When accessing %cr3, or equivalent field in vcpu_guest_context, guests + * must use the following accessor macros to pack/unpack valid MFNs. + */ +#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >>= 20)) +#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) <<= 20)) + +struct arch_vcpu_info { + unsigned long cr2; + unsigned long pad[5]; /* sizeof(vcpu_info_t) =3D=3D 64 */ +}; +typedef struct arch_vcpu_info arch_vcpu_info_t; + +struct xen_callback { + unsigned long cs; + unsigned long eip; +}; +typedef struct xen_callback xen_callback_t; + +#endif /* !__ASSEMBLY__ */ + +#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/arch-x86/xen-x86_64.h b/include/s= tandard-headers/xen/arch-x86/xen-x86_64.h new file mode 100644 index 0000000000..40aed14366 --- /dev/null +++ b/include/standard-headers/xen/arch-x86/xen-x86_64.h @@ -0,0 +1,241 @@ +/*************************************************************************= ***** + * xen-x86_64.h + * + * Guest OS interface to x86 64-bit Xen. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2004-2006, K A Fraser + */ + +#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ +#define __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ + +/* + * Hypercall interface: + * Input: %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6) + * Output: %rax + * Access is via hypercall page (set up by guest loader or via a Xen MSR): + * call hypercall_page + hypercall-number * 32 + * Clobbered: argument registers (e.g., 2-arg hypercall clobbers %rdi,%rsi) + */ + +/* + * 64-bit segment selectors + * These flat segments are in the Xen-private section of every GDT. Since = these + * are also present in the initial GDT, many OSes will be able to avoid + * installing their own GDT. + */ + +#define FLAT_RING3_CS32 0xe023 /* GDT index 260 */ +#define FLAT_RING3_CS64 0xe033 /* GDT index 262 */ +#define FLAT_RING3_DS32 0xe02b /* GDT index 261 */ +#define FLAT_RING3_DS64 0x0000 /* NULL selector */ +#define FLAT_RING3_SS32 0xe02b /* GDT index 261 */ +#define FLAT_RING3_SS64 0xe02b /* GDT index 261 */ + +#define FLAT_KERNEL_DS64 FLAT_RING3_DS64 +#define FLAT_KERNEL_DS32 FLAT_RING3_DS32 +#define FLAT_KERNEL_DS FLAT_KERNEL_DS64 +#define FLAT_KERNEL_CS64 FLAT_RING3_CS64 +#define FLAT_KERNEL_CS32 FLAT_RING3_CS32 +#define FLAT_KERNEL_CS FLAT_KERNEL_CS64 +#define FLAT_KERNEL_SS64 FLAT_RING3_SS64 +#define FLAT_KERNEL_SS32 FLAT_RING3_SS32 +#define FLAT_KERNEL_SS FLAT_KERNEL_SS64 + +#define FLAT_USER_DS64 FLAT_RING3_DS64 +#define FLAT_USER_DS32 FLAT_RING3_DS32 +#define FLAT_USER_DS FLAT_USER_DS64 +#define FLAT_USER_CS64 FLAT_RING3_CS64 +#define FLAT_USER_CS32 FLAT_RING3_CS32 +#define FLAT_USER_CS FLAT_USER_CS64 +#define FLAT_USER_SS64 FLAT_RING3_SS64 +#define FLAT_USER_SS32 FLAT_RING3_SS32 +#define FLAT_USER_SS FLAT_USER_SS64 + +#define __HYPERVISOR_VIRT_START 0xFFFF800000000000 +#define __HYPERVISOR_VIRT_END 0xFFFF880000000000 +#define __MACH2PHYS_VIRT_START 0xFFFF800000000000 +#define __MACH2PHYS_VIRT_END 0xFFFF804000000000 + +#ifndef HYPERVISOR_VIRT_START +#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START) +#define HYPERVISOR_VIRT_END xen_mk_ulong(__HYPERVISOR_VIRT_END) +#endif + +#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START) +#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END) +#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>= 3) +#ifndef machine_to_phys_mapping +#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) +#endif + +/* + * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) + * @which =3D=3D SEGBASE_* ; @base =3D=3D 64-bit base address + * Returns 0 on success. + */ +#define SEGBASE_FS 0 +#define SEGBASE_GS_USER 1 +#define SEGBASE_GS_KERNEL 2 +#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */ + +/* + * int HYPERVISOR_iret(void) + * All arguments are on the kernel stack, in the following format. + * Never returns if successful. Current kernel context is lost. + * The saved CS is mapped as follows: + * RING0 -> RING3 kernel mode. + * RING1 -> RING3 kernel mode. + * RING2 -> RING3 kernel mode. + * RING3 -> RING3 user mode. + * However RING0 indicates that the guest kernel should return to iteself + * directly with + * orb $3,1*8(%rsp) + * iretq + * If flags contains VGCF_in_syscall: + * Restore RAX, RIP, RFLAGS, RSP. + * Discard R11, RCX, CS, SS. + * Otherwise: + * Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP. + * All other registers are saved on hypercall entry and restored to user. + */ +/* Guest exited in SYSCALL context? Return to guest with SYSRET? */ +#define _VGCF_in_syscall 8 +#define VGCF_in_syscall (1<<_VGCF_in_syscall) +#define VGCF_IN_SYSCALL VGCF_in_syscall + +#ifndef __ASSEMBLY__ + +struct iret_context { + /* Top of stack (%rsp at point of hypercall). */ + uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; + /* Bottom of iret stack frame. */ +}; + +#if defined(__XEN__) || defined(__XEN_TOOLS__) +/* Anonymous unions include all permissible names (e.g., al/ah/ax/eax/rax)= . */ +#define __DECL_REG_LOHI(which) union { \ + uint64_t r ## which ## x; \ + uint32_t e ## which ## x; \ + uint16_t which ## x; \ + struct { \ + uint8_t which ## l; \ + uint8_t which ## h; \ + }; \ +} +#define __DECL_REG_LO8(name) union { \ + uint64_t r ## name; \ + uint32_t e ## name; \ + uint16_t name; \ + uint8_t name ## l; \ +} +#define __DECL_REG_LO16(name) union { \ + uint64_t r ## name; \ + uint32_t e ## name; \ + uint16_t name; \ +} +#define __DECL_REG_HI(num) union { \ + uint64_t r ## num; \ + uint32_t r ## num ## d; \ + uint16_t r ## num ## w; \ + uint8_t r ## num ## b; \ +} +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) +/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ +#define __DECL_REG(name) union { \ + uint64_t r ## name, e ## name; \ + uint32_t _e ## name; \ +} +#else +/* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ +#define __DECL_REG(name) uint64_t r ## name +#endif + +#ifndef __DECL_REG_LOHI +#define __DECL_REG_LOHI(name) __DECL_REG(name ## x) +#define __DECL_REG_LO8 __DECL_REG +#define __DECL_REG_LO16 __DECL_REG +#define __DECL_REG_HI(num) uint64_t r ## num +#endif + +struct cpu_user_regs { + __DECL_REG_HI(15); + __DECL_REG_HI(14); + __DECL_REG_HI(13); + __DECL_REG_HI(12); + __DECL_REG_LO8(bp); + __DECL_REG_LOHI(b); + __DECL_REG_HI(11); + __DECL_REG_HI(10); + __DECL_REG_HI(9); + __DECL_REG_HI(8); + __DECL_REG_LOHI(a); + __DECL_REG_LOHI(c); + __DECL_REG_LOHI(d); + __DECL_REG_LO8(si); + __DECL_REG_LO8(di); + uint32_t error_code; /* private */ + uint32_t entry_vector; /* private */ + __DECL_REG_LO16(ip); + uint16_t cs, _pad0[1]; + uint8_t saved_upcall_mask; + uint8_t _pad1[3]; + __DECL_REG_LO16(flags); /* rflags.IF =3D=3D !saved_upcall_mask */ + __DECL_REG_LO8(sp); + uint16_t ss, _pad2[3]; + uint16_t es, _pad3[3]; + uint16_t ds, _pad4[3]; + uint16_t fs, _pad5[3]; + uint16_t gs, _pad6[3]; +}; +typedef struct cpu_user_regs cpu_user_regs_t; +DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); + +#undef __DECL_REG +#undef __DECL_REG_LOHI +#undef __DECL_REG_LO8 +#undef __DECL_REG_LO16 +#undef __DECL_REG_HI + +#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12) +#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12) + +struct arch_vcpu_info { + unsigned long cr2; + unsigned long pad; /* sizeof(vcpu_info_t) =3D=3D 64 */ +}; +typedef struct arch_vcpu_info arch_vcpu_info_t; + +typedef unsigned long xen_callback_t; + +#endif /* !__ASSEMBLY__ */ + +#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/arch-x86/xen.h b/include/standard= -headers/xen/arch-x86/xen.h new file mode 100644 index 0000000000..7acd94c8eb --- /dev/null +++ b/include/standard-headers/xen/arch-x86/xen.h @@ -0,0 +1,398 @@ +/*************************************************************************= ***** + * arch-x86/xen.h + * + * Guest OS interface to x86 Xen. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2004-2006, K A Fraser + */ + +#include "../xen.h" + +#ifndef __XEN_PUBLIC_ARCH_X86_XEN_H__ +#define __XEN_PUBLIC_ARCH_X86_XEN_H__ + +/* Structural guest handles introduced in 0x00030201. */ +#if __XEN_INTERFACE_VERSION__ >=3D 0x00030201 +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ + typedef struct { type *p; } __guest_handle_ ## name +#else +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ + typedef type * __guest_handle_ ## name +#endif + +/* + * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field + * in a struct in memory. + * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an + * hypercall argument. + * XEN_GUEST_HANDLE_PARAM and XEN_GUEST_HANDLE are the same on X86 but + * they might not be on other architectures. + */ +#define __DEFINE_XEN_GUEST_HANDLE(name, type) \ + ___DEFINE_XEN_GUEST_HANDLE(name, type); \ + ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type) +#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, na= me) +#define __XEN_GUEST_HANDLE(name) __guest_handle_ ## name +#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name) +#define XEN_GUEST_HANDLE_PARAM(name) XEN_GUEST_HANDLE(name) +#define set_xen_guest_handle_raw(hnd, val) do { (hnd).p =3D val; } while = (0) +#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val) + +#if defined(__i386__) +# ifdef __XEN__ +__DeFiNe__ __DECL_REG_LO8(which) uint32_t e ## which ## x +__DeFiNe__ __DECL_REG_LO16(name) union { uint32_t e ## name; } +# endif +#include "xen-x86_32.h" +# ifdef __XEN__ +__UnDeF__ __DECL_REG_LO8 +__UnDeF__ __DECL_REG_LO16 +__DeFiNe__ __DECL_REG_LO8(which) e ## which ## x +__DeFiNe__ __DECL_REG_LO16(name) e ## name +# endif +#elif defined(__x86_64__) +#include "xen-x86_64.h" +#endif + +#ifndef __ASSEMBLY__ +typedef unsigned long xen_pfn_t; +#define PRI_xen_pfn "lx" +#define PRIu_xen_pfn "lu" +#endif + +#define XEN_HAVE_PV_GUEST_ENTRY 1 + +#define XEN_HAVE_PV_UPCALL_MASK 1 + +/* + * `incontents 200 segdesc Segment Descriptor Tables + */ +/* + * ` enum neg_errnoval + * ` HYPERVISOR_set_gdt(const xen_pfn_t frames[], unsigned int entries); + * ` + */ +/* + * A number of GDT entries are reserved by Xen. These are not situated at = the + * start of the GDT because some stupid OSes export hard-coded selector va= lues + * in their ABI. These hard-coded values are always near the start of the = GDT, + * so Xen places itself out of the way, at the far end of the GDT. + * + * NB The LDT is set using the MMUEXT_SET_LDT op of HYPERVISOR_mmuext_op + */ +#define FIRST_RESERVED_GDT_PAGE 14 +#define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096) +#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8) + + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_update_descriptor(u64 pa, u64 desc); + * ` + * ` @pa The machine physical address of the descriptor to + * ` update. Must be either a descriptor page or writable. + * ` @desc The descriptor value to update, in the same format as a + * ` native descriptor table entry. + */ + +/* Maximum number of virtual CPUs in legacy multi-processor guests. */ +#define XEN_LEGACY_MAX_VCPUS 32 + +#ifndef __ASSEMBLY__ + +typedef unsigned long xen_ulong_t; +#define PRI_xen_ulong "lx" + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp); + * ` + * Sets the stack segment and pointer for the current vcpu. + */ + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_set_trap_table(const struct trap_info traps[]); + * ` + */ +/* + * Send an array of these to HYPERVISOR_set_trap_table(). + * Terminate the array with a sentinel entry, with traps[].address=3D=3D0. + * The privilege level specifies which modes may enter a trap via a softwa= re + * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate + * privilege levels as follows: + * Level =3D=3D 0: Noone may enter + * Level =3D=3D 1: Kernel may enter + * Level =3D=3D 2: Kernel may enter + * Level =3D=3D 3: Everyone may enter + * + * Note: For compatibility with kernels not setting up exception handlers + * early enough, Xen will avoid trying to inject #GP (and hence crash + * the domain) when an RDMSR would require this, but no handler was + * set yet. The precise conditions are implementation specific, and + * new code may not rely on such behavior anyway. + */ +#define TI_GET_DPL(_ti) ((_ti)->flags & 3) +#define TI_GET_IF(_ti) ((_ti)->flags & 4) +#define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |=3D (_dpl)) +#define TI_SET_IF(_ti,_if) ((_ti)->flags |=3D ((!!(_if))<<2)) +struct trap_info { + uint8_t vector; /* exception vector = */ + uint8_t flags; /* 0-3: privilege level; 4: clear event enable?= */ + uint16_t cs; /* code selector = */ + unsigned long address; /* code offset = */ +}; +typedef struct trap_info trap_info_t; +DEFINE_XEN_GUEST_HANDLE(trap_info_t); + +typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ + +/* + * The following is all CPU context. Note that the fpu_ctxt block is filled + * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. + * + * Also note that when calling DOMCTL_setvcpucontext for HVM guests, not a= ll + * information in this structure is updated, the fields read include: fpu_= ctxt + * (if VGCT_I387_VALID is set), flags, user_regs and debugreg[*]. + * + * Note: VCPUOP_initialise for HVM guests is non-symetric with + * DOMCTL_setvcpucontext, and uses struct vcpu_hvm_context from hvm/hvm_vc= pu.h + */ +struct vcpu_guest_context { + /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR.= */ + struct { char x[512]; } fpu_ctxt; /* User-level FPU registers = */ +#define VGCF_I387_VALID (1<<0) +#define VGCF_IN_KERNEL (1<<2) +#define _VGCF_i387_valid 0 +#define VGCF_i387_valid (1<<_VGCF_i387_valid) +#define _VGCF_in_kernel 2 +#define VGCF_in_kernel (1<<_VGCF_in_kernel) +#define _VGCF_failsafe_disables_events 3 +#define VGCF_failsafe_disables_events (1<<_VGCF_failsafe_disables_events) +#define _VGCF_syscall_disables_events 4 +#define VGCF_syscall_disables_events (1<<_VGCF_syscall_disables_events) +#define _VGCF_online 5 +#define VGCF_online (1<<_VGCF_online) + unsigned long flags; /* VGCF_* flags = */ + struct cpu_user_regs user_regs; /* User-level CPU registers = */ + struct trap_info trap_ctxt[256]; /* Virtual IDT = */ + unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents= ) */ + unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents= ) */ + unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) = */ + /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */ + unsigned long ctrlreg[8]; /* CR0-CR7 (control registers)= */ + unsigned long debugreg[8]; /* DB0-DB7 (debug registers) = */ +#ifdef __i386__ + unsigned long event_callback_cs; /* CS:EIP of event callback = */ + unsigned long event_callback_eip; + unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback= */ + unsigned long failsafe_callback_eip; +#else + unsigned long event_callback_eip; + unsigned long failsafe_callback_eip; +#ifdef __XEN__ + union { + unsigned long syscall_callback_eip; + struct { + unsigned int event_callback_cs; /* compat CS of event cb = */ + unsigned int failsafe_callback_cs; /* compat CS of failsafe cb= */ + }; + }; +#else + unsigned long syscall_callback_eip; +#endif +#endif + unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ +#ifdef __x86_64__ + /* Segment base addresses. */ + uint64_t fs_base; + uint64_t gs_base_kernel; + uint64_t gs_base_user; +#endif +}; +typedef struct vcpu_guest_context vcpu_guest_context_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); + +struct arch_shared_info { + /* + * Number of valid entries in the p2m table(s) anchored at + * pfn_to_mfn_frame_list_list and/or p2m_vaddr. + */ + unsigned long max_pfn; + /* + * Frame containing list of mfns containing list of mfns containing p2= m. + * A value of 0 indicates it has not yet been set up, ~0 indicates it = has + * been set to invalid e.g. due to the p2m being too large for the 3-l= evel + * p2m tree. In this case the linear mapper p2m list anchored at p2m_v= addr + * is to be used. + */ + xen_pfn_t pfn_to_mfn_frame_list_list; + unsigned long nmi_reason; + /* + * Following three fields are valid if p2m_cr3 contains a value differ= ent + * from 0. + * p2m_cr3 is the root of the address space where p2m_vaddr is valid. + * p2m_cr3 is in the same format as a cr3 value in the vcpu register s= tate + * and holds the folded machine frame number (via xen_pfn_to_cr3) of a + * L3 or L4 page table. + * p2m_vaddr holds the virtual address of the linear p2m list. All ent= ries + * in the range [0...max_pfn[ are accessible via this pointer. + * p2m_generation will be incremented by the guest before and after ea= ch + * change of the mappings of the p2m list. p2m_generation starts at 0 = and + * a value with the least significant bit set indicates that a mapping + * update is in progress. This allows guest external software (e.g. in= Dom0) + * to verify that read mappings are consistent and whether they have c= hanged + * since the last check. + * Modifying a p2m element in the linear p2m list is allowed via an at= omic + * write only. + */ + unsigned long p2m_cr3; /* cr3 value of the p2m address space */ + unsigned long p2m_vaddr; /* virtual address of the p2m list */ + unsigned long p2m_generation; /* generation count of p2m mapping */ +#ifdef __i386__ + /* There's no room for this field in the generic structure. */ + uint32_t wc_sec_hi; +#endif +}; +typedef struct arch_shared_info arch_shared_info_t; + +#if defined(__XEN__) || defined(__XEN_TOOLS__) +/* + * struct xen_arch_domainconfig's ABI is covered by + * XEN_DOMCTL_INTERFACE_VERSION. + */ +struct xen_arch_domainconfig { +#define _XEN_X86_EMU_LAPIC 0 +#define XEN_X86_EMU_LAPIC (1U<<_XEN_X86_EMU_LAPIC) +#define _XEN_X86_EMU_HPET 1 +#define XEN_X86_EMU_HPET (1U<<_XEN_X86_EMU_HPET) +#define _XEN_X86_EMU_PM 2 +#define XEN_X86_EMU_PM (1U<<_XEN_X86_EMU_PM) +#define _XEN_X86_EMU_RTC 3 +#define XEN_X86_EMU_RTC (1U<<_XEN_X86_EMU_RTC) +#define _XEN_X86_EMU_IOAPIC 4 +#define XEN_X86_EMU_IOAPIC (1U<<_XEN_X86_EMU_IOAPIC) +#define _XEN_X86_EMU_PIC 5 +#define XEN_X86_EMU_PIC (1U<<_XEN_X86_EMU_PIC) +#define _XEN_X86_EMU_VGA 6 +#define XEN_X86_EMU_VGA (1U<<_XEN_X86_EMU_VGA) +#define _XEN_X86_EMU_IOMMU 7 +#define XEN_X86_EMU_IOMMU (1U<<_XEN_X86_EMU_IOMMU) +#define _XEN_X86_EMU_PIT 8 +#define XEN_X86_EMU_PIT (1U<<_XEN_X86_EMU_PIT) +#define _XEN_X86_EMU_USE_PIRQ 9 +#define XEN_X86_EMU_USE_PIRQ (1U<<_XEN_X86_EMU_USE_PIRQ) +#define _XEN_X86_EMU_VPCI 10 +#define XEN_X86_EMU_VPCI (1U<<_XEN_X86_EMU_VPCI) + +#define XEN_X86_EMU_ALL (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET = | \ + XEN_X86_EMU_PM | XEN_X86_EMU_RTC | = \ + XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC = | \ + XEN_X86_EMU_VGA | XEN_X86_EMU_IOMMU |= \ + XEN_X86_EMU_PIT | XEN_X86_EMU_USE_PIR= Q |\ + XEN_X86_EMU_VPCI) + uint32_t emulation_flags; + +/* + * Select whether to use a relaxed behavior for accesses to MSRs not expli= citly + * handled by Xen instead of injecting a #GP to the guest. Note this option + * doesn't allow the guest to read or write to the underlying MSR. + */ +#define XEN_X86_MSR_RELAXED (1u << 0) + uint32_t misc_flags; +}; + +/* Location of online VCPU bitmap. */ +#define XEN_ACPI_CPU_MAP 0xaf00 +#define XEN_ACPI_CPU_MAP_LEN ((HVM_MAX_VCPUS + 7) / 8) + +/* GPE0 bit set during CPU hotplug */ +#define XEN_ACPI_GPE0_CPUHP_BIT 2 +#endif + +/* + * Representations of architectural CPUID and MSR information. Used as the + * serialised version of Xen's internal representation. + */ +typedef struct xen_cpuid_leaf { +#define XEN_CPUID_NO_SUBLEAF 0xffffffffu + uint32_t leaf, subleaf; + uint32_t a, b, c, d; +} xen_cpuid_leaf_t; +DEFINE_XEN_GUEST_HANDLE(xen_cpuid_leaf_t); + +typedef struct xen_msr_entry { + uint32_t idx; + uint32_t flags; /* Reserved MBZ. */ + uint64_t val; +} xen_msr_entry_t; +DEFINE_XEN_GUEST_HANDLE(xen_msr_entry_t); + +#endif /* !__ASSEMBLY__ */ + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_fpu_taskswitch(int set); + * ` + * Sets (if set!=3D0) or clears (if set=3D=3D0) CR0.TS. + */ + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_set_debugreg(int regno, unsigned long value); + * + * ` unsigned long + * ` HYPERVISOR_get_debugreg(int regno); + * For 0<=3Dreg<=3D7, returns the debug register value. + * For other values of reg, returns ((unsigned long)-EINVAL). + * (Unfortunately, this interface is defective.) + */ + +/* + * Prefix forces emulation of some non-trapping instructions. + * Currently only CPUID. + */ +#ifdef __ASSEMBLY__ +#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ; +#define XEN_CPUID XEN_EMULATE_PREFIX cpuid +#else +#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; " +#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" +#endif + +/* + * Debug console IO port, also called "port E9 hack". Each character writt= en + * to this IO port will be printed on the hypervisor console, subject to l= og + * level restrictions. + */ +#define XEN_HVM_DEBUGCONS_IOPORT 0xe9 + +#endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/event_channel.h b/include/standar= d-headers/xen/event_channel.h new file mode 100644 index 0000000000..73c9f38ce1 --- /dev/null +++ b/include/standard-headers/xen/event_channel.h @@ -0,0 +1,388 @@ +/*************************************************************************= ***** + * event_channel.h + * + * Event channels between domains. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2003-2004, K A Fraser. + */ + +#ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__ +#define __XEN_PUBLIC_EVENT_CHANNEL_H__ + +#include "xen.h" + +/* + * `incontents 150 evtchn Event Channels + * + * Event channels are the basic primitive provided by Xen for event + * notifications. An event is the Xen equivalent of a hardware + * interrupt. They essentially store one bit of information, the event + * of interest is signalled by transitioning this bit from 0 to 1. + * + * Notifications are received by a guest via an upcall from Xen, + * indicating when an event arrives (setting the bit). Further + * notifications are masked until the bit is cleared again (therefore, + * guests must check the value of the bit after re-enabling event + * delivery to ensure no missed notifications). + * + * Event notifications can be masked by setting a flag; this is + * equivalent to disabling interrupts and can be used to ensure + * atomicity of certain operations in the guest kernel. + * + * Event channels are represented by the evtchn_* fields in + * struct shared_info and struct vcpu_info. + */ + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_event_channel_op(enum event_channel_op cmd, void *args) + * ` + * @cmd =3D=3D EVTCHNOP_* (event-channel operation). + * @args =3D=3D struct evtchn_* Operation-specific extra arguments (NULL i= f none). + */ + +/* ` enum event_channel_op { // EVTCHNOP_* =3D> struct evtchn_* */ +#define EVTCHNOP_bind_interdomain 0 +#define EVTCHNOP_bind_virq 1 +#define EVTCHNOP_bind_pirq 2 +#define EVTCHNOP_close 3 +#define EVTCHNOP_send 4 +#define EVTCHNOP_status 5 +#define EVTCHNOP_alloc_unbound 6 +#define EVTCHNOP_bind_ipi 7 +#define EVTCHNOP_bind_vcpu 8 +#define EVTCHNOP_unmask 9 +#define EVTCHNOP_reset 10 +#define EVTCHNOP_init_control 11 +#define EVTCHNOP_expand_array 12 +#define EVTCHNOP_set_priority 13 +#ifdef __XEN__ +#define EVTCHNOP_reset_cont 14 +#endif +/* ` } */ + +typedef uint32_t evtchn_port_t; +DEFINE_XEN_GUEST_HANDLE(evtchn_port_t); + +/* + * EVTCHNOP_alloc_unbound: Allocate a port in domain and mark as + * accepting interdomain bindings from domain . A fresh port + * is allocated in and returned as . + * NOTES: + * 1. If the caller is unprivileged then must be DOMID_SELF. + * 2. may be DOMID_SELF, allowing loopback connections. + */ +struct evtchn_alloc_unbound { + /* IN parameters */ + domid_t dom, remote_dom; + /* OUT parameters */ + evtchn_port_t port; +}; +typedef struct evtchn_alloc_unbound evtchn_alloc_unbound_t; + +/* + * EVTCHNOP_bind_interdomain: Construct an interdomain event channel betwe= en + * the calling domain and . must iden= tify + * a port that is unbound and marked as accepting bindings from the calling + * domain. A fresh port is allocated in the calling domain and returned as + * . + * + * In case the peer domain has already tried to set our event channel + * pending, before it was bound, EVTCHNOP_bind_interdomain always sets + * the local event channel pending. + * + * The usual pattern of use, in the guest's upcall (or subsequent + * handler) is as follows: (Re-enable the event channel for subsequent + * signalling and then) check for the existence of whatever condition + * is being waited for by other means, and take whatever action is + * needed (if any). + * + * NOTES: + * 1. may be DOMID_SELF, allowing loopback connections. + */ +struct evtchn_bind_interdomain { + /* IN parameters. */ + domid_t remote_dom; + evtchn_port_t remote_port; + /* OUT parameters. */ + evtchn_port_t local_port; +}; +typedef struct evtchn_bind_interdomain evtchn_bind_interdomain_t; + +/* + * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ on specifi= ed + * vcpu. + * NOTES: + * 1. Virtual IRQs are classified as per-vcpu or global. See the VIRQ list + * in xen.h for the classification of each VIRQ. + * 2. Global VIRQs must be allocated on VCPU0 but can subsequently be + * re-bound via EVTCHNOP_bind_vcpu. + * 3. Per-vcpu VIRQs may be bound to at most one event channel per vcpu. + * The allocated event channel is bound to the specified vcpu and the + * binding cannot be changed. + */ +struct evtchn_bind_virq { + /* IN parameters. */ + uint32_t virq; /* enum virq */ + uint32_t vcpu; + /* OUT parameters. */ + evtchn_port_t port; +}; +typedef struct evtchn_bind_virq evtchn_bind_virq_t; + +/* + * EVTCHNOP_bind_pirq: Bind a local event channel to a real IRQ (PIRQ ). + * NOTES: + * 1. A physical IRQ may be bound to at most one event channel per domain. + * 2. Only a sufficiently-privileged domain may bind to a physical IRQ. + */ +struct evtchn_bind_pirq { + /* IN parameters. */ + uint32_t pirq; +#define BIND_PIRQ__WILL_SHARE 1 + uint32_t flags; /* BIND_PIRQ__* */ + /* OUT parameters. */ + evtchn_port_t port; +}; +typedef struct evtchn_bind_pirq evtchn_bind_pirq_t; + +/* + * EVTCHNOP_bind_ipi: Bind a local event channel to receive events. + * NOTES: + * 1. The allocated event channel is bound to the specified vcpu. The bin= ding + * may not be changed. + */ +struct evtchn_bind_ipi { + uint32_t vcpu; + /* OUT parameters. */ + evtchn_port_t port; +}; +typedef struct evtchn_bind_ipi evtchn_bind_ipi_t; + +/* + * EVTCHNOP_close: Close a local event channel . If the channel is + * interdomain then the remote end is placed in the unbound state + * (EVTCHNSTAT_unbound), awaiting a new connection. + */ +struct evtchn_close { + /* IN parameters. */ + evtchn_port_t port; +}; +typedef struct evtchn_close evtchn_close_t; + +/* + * EVTCHNOP_send: Send an event to the remote end of the channel whose loc= al + * endpoint is . + */ +struct evtchn_send { + /* IN parameters. */ + evtchn_port_t port; +}; +typedef struct evtchn_send evtchn_send_t; + +/* + * EVTCHNOP_status: Get the current status of the communication channel wh= ich + * has an endpoint at . + * NOTES: + * 1. may be specified as DOMID_SELF. + * 2. Only a sufficiently-privileged domain may obtain the status of an e= vent + * channel for which is not DOMID_SELF. + */ +struct evtchn_status { + /* IN parameters */ + domid_t dom; + evtchn_port_t port; + /* OUT parameters */ +#define EVTCHNSTAT_closed 0 /* Channel is not in use. = */ +#define EVTCHNSTAT_unbound 1 /* Channel is waiting interdom connecti= on.*/ +#define EVTCHNSTAT_interdomain 2 /* Channel is connected to remote domai= n. */ +#define EVTCHNSTAT_pirq 3 /* Channel is bound to a phys IRQ line.= */ +#define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ li= ne */ +#define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI li= ne */ + uint32_t status; + uint32_t vcpu; /* VCPU to which this channel is bound.= */ + union { + struct { + domid_t dom; + } unbound; /* EVTCHNSTAT_unbound */ + struct { + domid_t dom; + evtchn_port_t port; + } interdomain; /* EVTCHNSTAT_interdomain */ + uint32_t pirq; /* EVTCHNSTAT_pirq */ + uint32_t virq; /* EVTCHNSTAT_virq */ + } u; +}; +typedef struct evtchn_status evtchn_status_t; + +/* + * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an + * event is pending. + * NOTES: + * 1. IPI-bound channels always notify the vcpu specified at bind time. + * This binding cannot be changed. + * 2. Per-VCPU VIRQ channels always notify the vcpu specified at bind tim= e. + * This binding cannot be changed. + * 3. All other channels notify vcpu0 by default. This default is set when + * the channel is allocated (a port that is freed and subsequently reu= sed + * has its binding reset to vcpu0). + */ +struct evtchn_bind_vcpu { + /* IN parameters. */ + evtchn_port_t port; + uint32_t vcpu; +}; +typedef struct evtchn_bind_vcpu evtchn_bind_vcpu_t; + +/* + * EVTCHNOP_unmask: Unmask the specified local event-channel port and deli= ver + * a notification to the appropriate VCPU if an event is pending. + */ +struct evtchn_unmask { + /* IN parameters. */ + evtchn_port_t port; +}; +typedef struct evtchn_unmask evtchn_unmask_t; + +/* + * EVTCHNOP_reset: Close all event channels associated with specified doma= in. + * NOTES: + * 1. may be specified as DOMID_SELF. + * 2. Only a sufficiently-privileged domain may specify other than DOMID_= SELF. + * 3. Destroys all control blocks and event array, resets event channel + * operations to 2-level ABI if called with =3D=3D DOMID_SELF an= d FIFO + * ABI was used. Guests should not bind events during EVTCHNOP_reset c= all + * as these events are likely to be lost. + */ +struct evtchn_reset { + /* IN parameters. */ + domid_t dom; +}; +typedef struct evtchn_reset evtchn_reset_t; + +/* + * EVTCHNOP_init_control: initialize the control block for the FIFO ABI. + * + * Note: any events that are currently pending will not be resent and + * will be lost. Guests should call this before binding any event to + * avoid losing any events. + */ +struct evtchn_init_control { + /* IN parameters. */ + uint64_t control_gfn; + uint32_t offset; + uint32_t vcpu; + /* OUT parameters. */ + uint8_t link_bits; + uint8_t _pad[7]; +}; +typedef struct evtchn_init_control evtchn_init_control_t; + +/* + * EVTCHNOP_expand_array: add an additional page to the event array. + */ +struct evtchn_expand_array { + /* IN parameters. */ + uint64_t array_gfn; +}; +typedef struct evtchn_expand_array evtchn_expand_array_t; + +/* + * EVTCHNOP_set_priority: set the priority for an event channel. + */ +struct evtchn_set_priority { + /* IN parameters. */ + evtchn_port_t port; + uint32_t priority; +}; +typedef struct evtchn_set_priority evtchn_set_priority_t; + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_event_channel_op_compat(struct evtchn_op *op) + * ` + * Superceded by new event_channel_op() hypercall since 0x00030202. + */ +struct evtchn_op { + uint32_t cmd; /* enum event_channel_op */ + union { + evtchn_alloc_unbound_t alloc_unbound; + evtchn_bind_interdomain_t bind_interdomain; + evtchn_bind_virq_t bind_virq; + evtchn_bind_pirq_t bind_pirq; + evtchn_bind_ipi_t bind_ipi; + evtchn_close_t close; + evtchn_send_t send; + evtchn_status_t status; + evtchn_bind_vcpu_t bind_vcpu; + evtchn_unmask_t unmask; + } u; +}; +typedef struct evtchn_op evtchn_op_t; +DEFINE_XEN_GUEST_HANDLE(evtchn_op_t); + +/* + * 2-level ABI + */ + +#define EVTCHN_2L_NR_CHANNELS (sizeof(xen_ulong_t) * sizeof(xen_ulong_t) *= 64) + +/* + * FIFO ABI + */ + +/* Events may have priorities from 0 (highest) to 15 (lowest). */ +#define EVTCHN_FIFO_PRIORITY_MAX 0 +#define EVTCHN_FIFO_PRIORITY_DEFAULT 7 +#define EVTCHN_FIFO_PRIORITY_MIN 15 + +#define EVTCHN_FIFO_MAX_QUEUES (EVTCHN_FIFO_PRIORITY_MIN + 1) + +typedef uint32_t event_word_t; + +#define EVTCHN_FIFO_PENDING 31 +#define EVTCHN_FIFO_MASKED 30 +#define EVTCHN_FIFO_LINKED 29 +#define EVTCHN_FIFO_BUSY 28 + +#define EVTCHN_FIFO_LINK_BITS 17 +#define EVTCHN_FIFO_LINK_MASK ((1 << EVTCHN_FIFO_LINK_BITS) - 1) + +#define EVTCHN_FIFO_NR_CHANNELS (1 << EVTCHN_FIFO_LINK_BITS) + +struct evtchn_fifo_control_block { + uint32_t ready; + uint32_t _rsvd; + uint32_t head[EVTCHN_FIFO_MAX_QUEUES]; +}; +typedef struct evtchn_fifo_control_block evtchn_fifo_control_block_t; + +#endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/features.h b/include/standard-hea= ders/xen/features.h new file mode 100644 index 0000000000..9ee2f760ef --- /dev/null +++ b/include/standard-headers/xen/features.h @@ -0,0 +1,143 @@ +/*************************************************************************= ***** + * features.h + * + * Feature flags, reported by XENVER_get_features. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2006, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_FEATURES_H__ +#define __XEN_PUBLIC_FEATURES_H__ + +/* + * `incontents 200 elfnotes_features XEN_ELFNOTE_FEATURES + * + * The list of all the features the guest supports. They are set by + * parsing the XEN_ELFNOTE_FEATURES and XEN_ELFNOTE_SUPPORTED_FEATURES + * string. The format is the feature names (as given here without the + * "XENFEAT_" prefix) separated by '|' characters. + * If a feature is required for the kernel to function then the feature na= me + * must be preceded by a '!' character. + * + * Note that if XEN_ELFNOTE_SUPPORTED_FEATURES is used, then in the + * XENFEAT_dom0 MUST be set if the guest is to be booted as dom0, + */ + +/* + * If set, the guest does not need to write-protect its pagetables, and can + * update them via direct writes. + */ +#define XENFEAT_writable_page_tables 0 + +/* + * If set, the guest does not need to write-protect its segment descriptor + * tables, and can update them via direct writes. + */ +#define XENFEAT_writable_descriptor_tables 1 + +/* + * If set, translation between the guest's 'pseudo-physical' address space + * and the host's machine address space are handled by the hypervisor. In = this + * mode the guest does not need to perform phys-to/from-machine translatio= ns + * when performing page table operations. + */ +#define XENFEAT_auto_translated_physmap 2 + +/* If set, the guest is running in supervisor mode (e.g., x86 ring 0). */ +#define XENFEAT_supervisor_mode_kernel 3 + +/* + * If set, the guest does not need to allocate x86 PAE page directories + * below 4GB. This flag is usually implied by auto_translated_physmap. + */ +#define XENFEAT_pae_pgdir_above_4gb 4 + +/* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall= ? */ +#define XENFEAT_mmu_pt_update_preserve_ad 5 + +/* x86: Does this Xen host support the MMU_{CLEAR,COPY}_PAGE hypercall? */ +#define XENFEAT_highmem_assist 6 + +/* + * If set, GNTTABOP_map_grant_ref honors flags to be placed into guest ker= nel + * available pte bits. + */ +#define XENFEAT_gnttab_map_avail_bits 7 + +/* x86: Does this Xen host support the HVM callback vector type? */ +#define XENFEAT_hvm_callback_vector 8 + +/* x86: pvclock algorithm is safe to use on HVM */ +#define XENFEAT_hvm_safe_pvclock 9 + +/* x86: pirq can be used by HVM guests */ +#define XENFEAT_hvm_pirqs 10 + +/* operation as Dom0 is supported */ +#define XENFEAT_dom0 11 + +/* Xen also maps grant references at pfn =3D mfn. + * This feature flag is deprecated and should not be used. +#define XENFEAT_grant_map_identity 12 + */ + +/* Guest can use XENMEMF_vnode to specify virtual node for memory op. */ +#define XENFEAT_memory_op_vnode_supported 13 + +/* arm: Hypervisor supports ARM SMC calling convention. */ +#define XENFEAT_ARM_SMCCC_supported 14 + +/* + * x86/PVH: If set, ACPI RSDP can be placed at any address. Otherwise RSDP + * must be located in lower 1MB, as required by ACPI Specification for IA-= PC + * systems. + * This feature flag is only consulted if XEN_ELFNOTE_GUEST_OS contains + * the "linux" string. + */ +#define XENFEAT_linux_rsdp_unrestricted 15 + +/* + * A direct-mapped (or 1:1 mapped) domain is a domain for which its + * local pages have gfn =3D=3D mfn. If a domain is direct-mapped, + * XENFEAT_direct_mapped is set; otherwise XENFEAT_not_direct_mapped + * is set. + * + * If neither flag is set (e.g. older Xen releases) the assumptions are: + * - not auto_translated domains (x86 only) are always direct-mapped + * - on x86, auto_translated domains are not direct-mapped + * - on ARM, Dom0 is direct-mapped, DomUs are not + */ +#define XENFEAT_not_direct_mapped 16 +#define XENFEAT_direct_mapped 17 + +#define XENFEAT_NR_SUBMAPS 1 + +#endif /* __XEN_PUBLIC_FEATURES_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/grant_table.h b/include/standard-= headers/xen/grant_table.h new file mode 100644 index 0000000000..7934d7b718 --- /dev/null +++ b/include/standard-headers/xen/grant_table.h @@ -0,0 +1,686 @@ +/*************************************************************************= ***** + * grant_table.h + * + * Interface for granting foreign access to page frames, and receiving + * page-ownership transfers. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2004, K A Fraser + */ + +#ifndef __XEN_PUBLIC_GRANT_TABLE_H__ +#define __XEN_PUBLIC_GRANT_TABLE_H__ + +#include "xen.h" + +/* + * `incontents 150 gnttab Grant Tables + * + * Xen's grant tables provide a generic mechanism to memory sharing + * between domains. This shared memory interface underpins the split + * device drivers for block and network IO. + * + * Each domain has its own grant table. This is a data structure that + * is shared with Xen; it allows the domain to tell Xen what kind of + * permissions other domains have on its pages. Entries in the grant + * table are identified by grant references. A grant reference is an + * integer, which indexes into the grant table. It acts as a + * capability which the grantee can use to perform operations on the + * granter's memory. + * + * This capability-based system allows shared-memory communications + * between unprivileged domains. A grant reference also encapsulates + * the details of a shared page, removing the need for a domain to + * know the real machine address of a page it is sharing. This makes + * it possible to share memory correctly with domains running in + * fully virtualised memory. + */ + +/*********************************** + * GRANT TABLE REPRESENTATION + */ + +/* Some rough guidelines on accessing and updating grant-table entries + * in a concurrency-safe manner. For more information, Linux contains a + * reference implementation for guest OSes (drivers/xen/grant_table.c, see + * http://git.kernel.org/?p=3Dlinux/kernel/git/torvalds/linux.git;a=3Dblob= ;f=3Ddrivers/xen/grant-table.c;hb=3DHEAD + * + * NB. WMB is a no-op on current-generation x86 processors. However, a + * compiler barrier will still be required. + * + * Introducing a valid entry into the grant table: + * 1. Write ent->domid. + * 2. Write ent->frame: + * GTF_permit_access: Frame to which access is permitted. + * GTF_accept_transfer: Pseudo-phys frame slot being filled by new + * frame, or zero if none. + * 3. Write memory barrier (WMB). + * 4. Write ent->flags, inc. valid type. + * + * Invalidating an unused GTF_permit_access entry: + * 1. flags =3D ent->flags. + * 2. Observe that !(flags & (GTF_reading|GTF_writing)). + * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). + * NB. No need for WMB as reuse of entry is control-dependent on success = of + * step 3, and all architectures guarantee ordering of ctrl-dep write= s. + * + * Invalidating an in-use GTF_permit_access entry: + * This cannot be done directly. Request assistance from the domain contr= oller + * which can set a timeout on the use of a grant entry and take necessary + * action. (NB. This is not yet implemented!). + * + * Invalidating an unused GTF_accept_transfer entry: + * 1. flags =3D ent->flags. + * 2. Observe that !(flags & GTF_transfer_committed). [*] + * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). + * NB. No need for WMB as reuse of entry is control-dependent on success = of + * step 3, and all architectures guarantee ordering of ctrl-dep write= s. + * [*] If GTF_transfer_committed is set then the grant entry is 'committe= d'. + * The guest must /not/ modify the grant entry until the address of t= he + * transferred frame is written. It is safe for the guest to spin wai= ting + * for this to occur (detect by observing GTF_transfer_completed in + * ent->flags). + * + * Invalidating a committed GTF_accept_transfer entry: + * 1. Wait for (ent->flags & GTF_transfer_completed). + * + * Changing a GTF_permit_access from writable to read-only: + * Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing. + * + * Changing a GTF_permit_access from read-only to writable: + * Use SMP-safe bit-setting instruction. + */ + +/* + * Reference to a grant entry in a specified domain's grant table. + */ +typedef uint32_t grant_ref_t; + +/* + * A grant table comprises a packed array of grant entries in one or more + * page frames shared between Xen and a guest. + * [XEN]: This field is written by Xen and read by the sharing guest. + * [GST]: This field is written by the guest and read by Xen. + */ + +/* + * Version 1 of the grant table entry structure is maintained largely for + * backwards compatibility. New guests are recommended to support using + * version 2 to overcome version 1 limitations, but to default to version = 1. + */ +#if __XEN_INTERFACE_VERSION__ < 0x0003020a +#define grant_entry_v1 grant_entry +#define grant_entry_v1_t grant_entry_t +#endif +struct grant_entry_v1 { + /* GTF_xxx: various type and flag information. [XEN,GST] */ + uint16_t flags; + /* The domain being granted foreign privileges. [GST] */ + domid_t domid; + /* + * GTF_permit_access: GFN that @domid is allowed to map and access. [G= ST] + * GTF_accept_transfer: GFN that @domid is allowed to transfer into. [= GST] + * GTF_transfer_completed: MFN whose ownership transferred by @domid + * (non-translated guests only). [XEN] + */ + uint32_t frame; +}; +typedef struct grant_entry_v1 grant_entry_v1_t; + +/* The first few grant table entries will be preserved across grant table + * version changes and may be pre-populated at domain creation by tools. + */ +#define GNTTAB_NR_RESERVED_ENTRIES 8 +#define GNTTAB_RESERVED_CONSOLE 0 +#define GNTTAB_RESERVED_XENSTORE 1 + +/* + * Type of grant entry. + * GTF_invalid: This grant entry grants no privileges. + * GTF_permit_access: Allow @domid to map/access @frame. + * GTF_accept_transfer: Allow @domid to transfer ownership of one page fr= ame + * to this guest. Xen writes the page number to @fra= me. + * GTF_transitive: Allow @domid to transitively access a subrange of + * @trans_grant in @trans_domid. No mappings are allowed. + */ +#define GTF_invalid (0U<<0) +#define GTF_permit_access (1U<<0) +#define GTF_accept_transfer (2U<<0) +#define GTF_transitive (3U<<0) +#define GTF_type_mask (3U<<0) + +/* + * Subflags for GTF_permit_access and GTF_transitive. + * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] + * GTF_reading: Grant entry is currently mapped for reading by @domid. [X= EN] + * GTF_writing: Grant entry is currently mapped for writing by @domid. [X= EN] + * Further subflags for GTF_permit_access only. + * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags to be used for + * mappings of the grant [GST] + * GTF_sub_page: Grant access to only a subrange of the page. @domid + * will only be allowed to copy from the grant, and not + * map it. [GST] + */ +#define _GTF_readonly (2) +#define GTF_readonly (1U<<_GTF_readonly) +#define _GTF_reading (3) +#define GTF_reading (1U<<_GTF_reading) +#define _GTF_writing (4) +#define GTF_writing (1U<<_GTF_writing) +#define _GTF_PWT (5) +#define GTF_PWT (1U<<_GTF_PWT) +#define _GTF_PCD (6) +#define GTF_PCD (1U<<_GTF_PCD) +#define _GTF_PAT (7) +#define GTF_PAT (1U<<_GTF_PAT) +#define _GTF_sub_page (8) +#define GTF_sub_page (1U<<_GTF_sub_page) + +/* + * Subflags for GTF_accept_transfer: + * GTF_transfer_committed: Xen sets this flag to indicate that it is comm= itted + * to transferring ownership of a page frame. When a guest sees this = flag + * it must /not/ modify the grant entry until GTF_transfer_completed = is + * set by Xen. + * GTF_transfer_completed: It is safe for the guest to spin-wait on this = flag + * after reading GTF_transfer_committed. Xen will always write the fr= ame + * address, followed by ORing this flag, in a timely manner. + */ +#define _GTF_transfer_committed (2) +#define GTF_transfer_committed (1U<<_GTF_transfer_committed) +#define _GTF_transfer_completed (3) +#define GTF_transfer_completed (1U<<_GTF_transfer_completed) + +/* + * Version 2 grant table entries. These fulfil the same role as + * version 1 entries, but can represent more complicated operations. + * Any given domain will have either a version 1 or a version 2 table, + * and every entry in the table will be the same version. + * + * The interface by which domains use grant references does not depend + * on the grant table version in use by the other domain. + */ +#if __XEN_INTERFACE_VERSION__ >=3D 0x0003020a +/* + * Version 1 and version 2 grant entries share a common prefix. The + * fields of the prefix are documented as part of struct + * grant_entry_v1. + */ +struct grant_entry_header { + uint16_t flags; + domid_t domid; +}; +typedef struct grant_entry_header grant_entry_header_t; + +/* + * Version 2 of the grant entry structure. + */ +union grant_entry_v2 { + grant_entry_header_t hdr; + + /* + * This member is used for V1-style full page grants, where either: + * + * -- hdr.type is GTF_accept_transfer, or + * -- hdr.type is GTF_permit_access and GTF_sub_page is not set. + * + * In that case, the frame field has the same semantics as the + * field of the same name in the V1 entry structure. + */ + struct { + grant_entry_header_t hdr; + uint32_t pad0; + uint64_t frame; + } full_page; + + /* + * If the grant type is GTF_grant_access and GTF_sub_page is set, + * @domid is allowed to access bytes [@page_off,@page_off+@length) + * in frame @frame. + */ + struct { + grant_entry_header_t hdr; + uint16_t page_off; + uint16_t length; + uint64_t frame; + } sub_page; + + /* + * If the grant is GTF_transitive, @domid is allowed to use the + * grant @gref in domain @trans_domid, as if it was the local + * domain. Obviously, the transitive access must be compatible + * with the original grant. + * + * The current version of Xen does not allow transitive grants + * to be mapped. + */ + struct { + grant_entry_header_t hdr; + domid_t trans_domid; + uint16_t pad0; + grant_ref_t gref; + } transitive; + + uint32_t __spacer[4]; /* Pad to a power of two */ +}; +typedef union grant_entry_v2 grant_entry_v2_t; + +typedef uint16_t grant_status_t; + +#endif /* __XEN_INTERFACE_VERSION__ */ + +/*********************************** + * GRANT TABLE QUERIES AND USES + */ + +/* ` enum neg_errnoval + * ` HYPERVISOR_grant_table_op(enum grant_table_op cmd, + * ` void *args, + * ` unsigned int count) + * ` + * + * @args points to an array of a per-command data structure. The array + * has @count members + */ + +/* ` enum grant_table_op { // GNTTABOP_* =3D> struct gnttab_* */ +#define GNTTABOP_map_grant_ref 0 +#define GNTTABOP_unmap_grant_ref 1 +#define GNTTABOP_setup_table 2 +#define GNTTABOP_dump_table 3 +#define GNTTABOP_transfer 4 +#define GNTTABOP_copy 5 +#define GNTTABOP_query_size 6 +#define GNTTABOP_unmap_and_replace 7 +#if __XEN_INTERFACE_VERSION__ >=3D 0x0003020a +#define GNTTABOP_set_version 8 +#define GNTTABOP_get_status_frames 9 +#define GNTTABOP_get_version 10 +#define GNTTABOP_swap_grant_ref 11 +#define GNTTABOP_cache_flush 12 +#endif /* __XEN_INTERFACE_VERSION__ */ +/* ` } */ + +/* + * Handle to track a mapping created via a grant reference. + */ +typedef uint32_t grant_handle_t; + +/* + * GNTTABOP_map_grant_ref: Map the grant entry (,) for access + * by devices and/or host CPUs. If successful, is a tracking numb= er + * that must be presented later to destroy the mapping(s). On error, + * is a negative status code. + * NOTES: + * 1. If GNTMAP_device_map is specified then is the address + * via which I/O devices may access the granted frame. + * 2. If GNTMAP_host_map is specified then a mapping will be added at + * either a host virtual address in the current address space, or at + * a PTE at the specified machine address. The type of mapping to + * perform is selected through the GNTMAP_contains_pte flag, and the + * address is specified in . + * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a + * host mapping is destroyed by other means then it is *NOT* guaranteed + * to be accounted to the correct grant reference! + */ +struct gnttab_map_grant_ref { + /* IN parameters. */ + uint64_t host_addr; + uint32_t flags; /* GNTMAP_* */ + grant_ref_t ref; + domid_t dom; + /* OUT parameters. */ + int16_t status; /* =3D> enum grant_status */ + grant_handle_t handle; + uint64_t dev_bus_addr; +}; +typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t); + +/* + * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings + * tracked by . If or is zero, that + * field is ignored. If non-zero, they must refer to a device/host mapping + * that is tracked by + * NOTES: + * 1. The call may fail in an undefined manner if either mapping is not + * tracked by . + * 3. After executing a batch of unmaps, it is guaranteed that no stale + * mappings will remain in the device or host TLBs. + */ +struct gnttab_unmap_grant_ref { + /* IN parameters. */ + uint64_t host_addr; + uint64_t dev_bus_addr; + grant_handle_t handle; + /* OUT parameters. */ + int16_t status; /* =3D> enum grant_status */ +}; +typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t); + +/* + * GNTTABOP_setup_table: Set up a grant table for comprising at least + * pages. The frame addresses are written to the . + * Only addresses are written, even if the table is larger. + * NOTES: + * 1. may be specified as DOMID_SELF. + * 2. Only a sufficiently-privileged domain may specify !=3D DOMID_= SELF. + * 3. Xen may not support more than a single grant-table page per domain. + */ +struct gnttab_setup_table { + /* IN parameters. */ + domid_t dom; + uint32_t nr_frames; + /* OUT parameters. */ + int16_t status; /* =3D> enum grant_status */ +#if __XEN_INTERFACE_VERSION__ < 0x00040300 + XEN_GUEST_HANDLE(ulong) frame_list; +#else + XEN_GUEST_HANDLE(xen_pfn_t) frame_list; +#endif +}; +typedef struct gnttab_setup_table gnttab_setup_table_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t); + +/* + * GNTTABOP_dump_table: Dump the contents of the grant table to the + * xen console. Debugging use only. + */ +struct gnttab_dump_table { + /* IN parameters. */ + domid_t dom; + /* OUT parameters. */ + int16_t status; /* =3D> enum grant_status */ +}; +typedef struct gnttab_dump_table gnttab_dump_table_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t); + +/* + * GNTTABOP_transfer: Transfer to a foreign domain. The foreign do= main + * has previously registered its interest in the transfer via . + * + * Note that, even if the transfer fails, the specified page no longer bel= ongs + * to the calling domain *unless* the error is GNTST_bad_page. + * + * Note further that only PV guests can use this operation. + */ +struct gnttab_transfer { + /* IN parameters. */ + xen_pfn_t mfn; + domid_t domid; + grant_ref_t ref; + /* OUT parameters. */ + int16_t status; +}; +typedef struct gnttab_transfer gnttab_transfer_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t); + + +/* + * GNTTABOP_copy: Hypervisor based copy + * source and destinations can be eithers MFNs or, for foreign domains, + * grant references. the foreign domain has to grant read/write access + * in its grant table. + * + * The flags specify what type source and destinations are (either MFN + * or grant reference). + * + * Note that this can also be used to copy data between two domains + * via a third party if the source and destination domains had previously + * grant appropriate access to their pages to the third party. + * + * source_offset specifies an offset in the source frame, dest_offset + * the offset in the target frame and len specifies the number of + * bytes to be copied. + */ + +#define _GNTCOPY_source_gref (0) +#define GNTCOPY_source_gref (1<<_GNTCOPY_source_gref) +#define _GNTCOPY_dest_gref (1) +#define GNTCOPY_dest_gref (1<<_GNTCOPY_dest_gref) + +struct gnttab_copy { + /* IN parameters. */ + struct gnttab_copy_ptr { + union { + grant_ref_t ref; + xen_pfn_t gmfn; + } u; + domid_t domid; + uint16_t offset; + } source, dest; + uint16_t len; + uint16_t flags; /* GNTCOPY_* */ + /* OUT parameters. */ + int16_t status; +}; +typedef struct gnttab_copy gnttab_copy_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_copy_t); + +/* + * GNTTABOP_query_size: Query the current and maximum sizes of the shared + * grant table. + * NOTES: + * 1. may be specified as DOMID_SELF. + * 2. Only a sufficiently-privileged domain may specify !=3D DOMID_= SELF. + */ +struct gnttab_query_size { + /* IN parameters. */ + domid_t dom; + /* OUT parameters. */ + uint32_t nr_frames; + uint32_t max_nr_frames; + int16_t status; /* =3D> enum grant_status */ +}; +typedef struct gnttab_query_size gnttab_query_size_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_query_size_t); + +/* + * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings + * tracked by but atomically replace the page table entry with one + * pointing to the machine address under . will be + * redirected to the null entry. + * NOTES: + * 1. The call may fail in an undefined manner if either mapping is not + * tracked by . + * 2. After executing a batch of unmaps, it is guaranteed that no stale + * mappings will remain in the device or host TLBs. + */ +struct gnttab_unmap_and_replace { + /* IN parameters. */ + uint64_t host_addr; + uint64_t new_addr; + grant_handle_t handle; + /* OUT parameters. */ + int16_t status; /* =3D> enum grant_status */ +}; +typedef struct gnttab_unmap_and_replace gnttab_unmap_and_replace_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_and_replace_t); + +#if __XEN_INTERFACE_VERSION__ >=3D 0x0003020a +/* + * GNTTABOP_set_version: Request a particular version of the grant + * table shared table structure. This operation may be used to toggle + * between different versions, but must be performed while no grants + * are active. The only defined versions are 1 and 2. + */ +struct gnttab_set_version { + /* IN/OUT parameters */ + uint32_t version; +}; +typedef struct gnttab_set_version gnttab_set_version_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_set_version_t); + + +/* + * GNTTABOP_get_status_frames: Get the list of frames used to store grant + * status for . In grant format version 2, the status is separated + * from the other shared grant fields to allow more efficient synchronizat= ion + * using barriers instead of atomic cmpexch operations. + * specify the size of vector . + * The frame addresses are returned in the . + * Only addresses are returned, even if the table is larger. + * NOTES: + * 1. may be specified as DOMID_SELF. + * 2. Only a sufficiently-privileged domain may specify !=3D DOMID_= SELF. + */ +struct gnttab_get_status_frames { + /* IN parameters. */ + uint32_t nr_frames; + domid_t dom; + /* OUT parameters. */ + int16_t status; /* =3D> enum grant_status */ + XEN_GUEST_HANDLE(uint64_t) frame_list; +}; +typedef struct gnttab_get_status_frames gnttab_get_status_frames_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_get_status_frames_t); + +/* + * GNTTABOP_get_version: Get the grant table version which is in + * effect for domain . + */ +struct gnttab_get_version { + /* IN parameters */ + domid_t dom; + uint16_t pad; + /* OUT parameters */ + uint32_t version; +}; +typedef struct gnttab_get_version gnttab_get_version_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_get_version_t); + +/* + * GNTTABOP_swap_grant_ref: Swap the contents of two grant entries. + */ +struct gnttab_swap_grant_ref { + /* IN parameters */ + grant_ref_t ref_a; + grant_ref_t ref_b; + /* OUT parameters */ + int16_t status; /* =3D> enum grant_status */ +}; +typedef struct gnttab_swap_grant_ref gnttab_swap_grant_ref_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t); + +/* + * Issue one or more cache maintenance operations on a portion of a + * page granted to the calling domain by a foreign domain. + */ +struct gnttab_cache_flush { + union { + uint64_t dev_bus_addr; + grant_ref_t ref; + } a; + uint16_t offset; /* offset from start of grant */ + uint16_t length; /* size within the grant */ +#define GNTTAB_CACHE_CLEAN (1u<<0) +#define GNTTAB_CACHE_INVAL (1u<<1) +#define GNTTAB_CACHE_SOURCE_GREF (1u<<31) + uint32_t op; +}; +typedef struct gnttab_cache_flush gnttab_cache_flush_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_cache_flush_t); + +#endif /* __XEN_INTERFACE_VERSION__ */ + +/* + * Bitfield values for gnttab_map_grant_ref.flags. + */ + /* Map the grant entry for access by I/O devices. */ +#define _GNTMAP_device_map (0) +#define GNTMAP_device_map (1<<_GNTMAP_device_map) + /* Map the grant entry for access by host CPUs. */ +#define _GNTMAP_host_map (1) +#define GNTMAP_host_map (1<<_GNTMAP_host_map) + /* Accesses to the granted frame will be restricted to read-only access. = */ +#define _GNTMAP_readonly (2) +#define GNTMAP_readonly (1<<_GNTMAP_readonly) + /* + * GNTMAP_host_map subflag: + * 0 =3D> The host mapping is usable only by the guest OS. + * 1 =3D> The host mapping is usable by guest OS + current application. + */ +#define _GNTMAP_application_map (3) +#define GNTMAP_application_map (1<<_GNTMAP_application_map) + + /* + * GNTMAP_contains_pte subflag: + * 0 =3D> This map request contains a host virtual address. + * 1 =3D> This map request contains the machine addess of the PTE to upd= ate. + */ +#define _GNTMAP_contains_pte (4) +#define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte) + +/* + * Bits to be placed in guest kernel available PTE bits (architecture + * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set). + */ +#define _GNTMAP_guest_avail0 (16) +#define GNTMAP_guest_avail_mask ((uint32_t)~0 << _GNTMAP_guest_avail0) + +/* + * Values for error status returns. All errors are -ve. + */ +/* ` enum grant_status { */ +#define GNTST_okay (0) /* Normal return. = */ +#define GNTST_general_error (-1) /* General undefined error. = */ +#define GNTST_bad_domain (-2) /* Unrecognsed domain id. = */ +#define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntre= f. */ +#define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handl= e. */ +#define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to ma= p. */ +#define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unm= ap.*/ +#define GNTST_no_device_space (-7) /* Out of space in I/O MMU. = */ +#define GNTST_permission_denied (-8) /* Not enough privilege for operation= . */ +#define GNTST_bad_page (-9) /* Specified page was invalid for op. = */ +#define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary.= */ +#define GNTST_address_too_big (-11) /* transfer page address too large. = */ +#define GNTST_eagain (-12) /* Operation not done; try again. = */ +#define GNTST_no_space (-13) /* Out of space (handles etc). = */ +/* ` } */ + +#define GNTTABOP_error_msgs { \ + "okay", \ + "undefined error", \ + "unrecognised domain id", \ + "invalid grant reference", \ + "invalid mapping handle", \ + "invalid virtual address", \ + "invalid device address", \ + "no spare translation slot in the I/O MMU", \ + "permission denied", \ + "bad page", \ + "copy arguments cross page boundary", \ + "page address size too large", \ + "operation not done; try again", \ + "out of space", \ +} + +#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/hvm/hvm_op.h b/include/standard-h= eaders/xen/hvm/hvm_op.h new file mode 100644 index 0000000000..870ec52060 --- /dev/null +++ b/include/standard-headers/xen/hvm/hvm_op.h @@ -0,0 +1,395 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2007, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__ +#define __XEN_PUBLIC_HVM_HVM_OP_H__ + +#include "../xen.h" +#include "../trace.h" +#include "../event_channel.h" + +/* Get/set subcommands: extra argument =3D=3D pointer to xen_hvm_param str= uct. */ +#define HVMOP_set_param 0 +#define HVMOP_get_param 1 +struct xen_hvm_param { + domid_t domid; /* IN */ + uint16_t pad; + uint32_t index; /* IN */ + uint64_t value; /* IN/OUT */ +}; +typedef struct xen_hvm_param xen_hvm_param_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t); + +struct xen_hvm_altp2m_suppress_ve { + uint16_t view; + uint8_t suppress_ve; /* Boolean type. */ + uint8_t pad1; + uint32_t pad2; + uint64_t gfn; +}; + +struct xen_hvm_altp2m_suppress_ve_multi { + uint16_t view; + uint8_t suppress_ve; /* Boolean type. */ + uint8_t pad1; + int32_t first_error; /* Should be set to 0. */ + uint64_t first_gfn; /* Value may be updated. */ + uint64_t last_gfn; + uint64_t first_error_gfn; /* Gfn of the first error. */ +}; + +#if __XEN_INTERFACE_VERSION__ < 0x00040900 + +/* Set the logical level of one of a domain's PCI INTx wires. */ +#define HVMOP_set_pci_intx_level 2 +struct xen_hvm_set_pci_intx_level { + /* Domain to be updated. */ + domid_t domid; + /* PCI INTx identification in PCI topology (domain:bus:device:intx). */ + uint8_t domain, bus, device, intx; + /* Assertion level (0 =3D unasserted, 1 =3D asserted). */ + uint8_t level; +}; +typedef struct xen_hvm_set_pci_intx_level xen_hvm_set_pci_intx_level_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t); + +/* Set the logical level of one of a domain's ISA IRQ wires. */ +#define HVMOP_set_isa_irq_level 3 +struct xen_hvm_set_isa_irq_level { + /* Domain to be updated. */ + domid_t domid; + /* ISA device identification, by ISA IRQ (0-15). */ + uint8_t isa_irq; + /* Assertion level (0 =3D unasserted, 1 =3D asserted). */ + uint8_t level; +}; +typedef struct xen_hvm_set_isa_irq_level xen_hvm_set_isa_irq_level_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t); + +#define HVMOP_set_pci_link_route 4 +struct xen_hvm_set_pci_link_route { + /* Domain to be updated. */ + domid_t domid; + /* PCI link identifier (0-3). */ + uint8_t link; + /* ISA IRQ (1-15), or 0 (disable link). */ + uint8_t isa_irq; +}; +typedef struct xen_hvm_set_pci_link_route xen_hvm_set_pci_link_route_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_link_route_t); + +#endif /* __XEN_INTERFACE_VERSION__ < 0x00040900 */ + +/* Flushes all VCPU TLBs: @arg must be NULL. */ +#define HVMOP_flush_tlbs 5 + +/* + * hvmmem_type_t should not be defined when generating the corresponding + * compat header. This will ensure that the improperly named HVMMEM_(*) + * values are defined only once. + */ +#ifndef XEN_GENERATING_COMPAT_HEADERS + +typedef enum { + HVMMEM_ram_rw, /* Normal read/write guest RAM */ + HVMMEM_ram_ro, /* Read-only; writes are discarded */ + HVMMEM_mmio_dm, /* Reads and write go to the device model */ +#if __XEN_INTERFACE_VERSION__ < 0x00040700 + HVMMEM_mmio_write_dm, /* Read-only; writes go to the device model= */ +#else + HVMMEM_unused, /* Placeholder; setting memory to this type + will fail for code after 4.7.0 */ +#endif + HVMMEM_ioreq_server /* Memory type claimed by an ioreq server; = type + changes to this value are only allowed a= fter + an ioreq server has claimed its ownershi= p. + Only pages with HVMMEM_ram_rw are allowe= d to + change to this type; conversely, pages w= ith + this type are only allowed to be changed= back + to HVMMEM_ram_rw. */ +} hvmmem_type_t; + +#endif /* XEN_GENERATING_COMPAT_HEADERS */ + +/* Hint from PV drivers for pagetable destruction. */ +#define HVMOP_pagetable_dying 9 +struct xen_hvm_pagetable_dying { + /* Domain with a pagetable about to be destroyed. */ + domid_t domid; + uint16_t pad[3]; /* align next field on 8-byte boundary */ + /* guest physical address of the toplevel pagetable dying */ + uint64_t gpa; +}; +typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_pagetable_dying_t); + +/* Get the current Xen time, in nanoseconds since system boot. */ +#define HVMOP_get_time 10 +struct xen_hvm_get_time { + uint64_t now; /* OUT */ +}; +typedef struct xen_hvm_get_time xen_hvm_get_time_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_time_t); + +#define HVMOP_xentrace 11 +struct xen_hvm_xentrace { + uint16_t event, extra_bytes; + uint8_t extra[TRACE_EXTRA_MAX * sizeof(uint32_t)]; +}; +typedef struct xen_hvm_xentrace xen_hvm_xentrace_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_xentrace_t); + +/* Following tools-only interfaces may change in future. */ +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +/* Deprecated by XENMEM_access_op_set_access */ +#define HVMOP_set_mem_access 12 + +/* Deprecated by XENMEM_access_op_get_access */ +#define HVMOP_get_mem_access 13 + +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ + +#define HVMOP_get_mem_type 15 +/* Return hvmmem_type_t for the specified pfn. */ +struct xen_hvm_get_mem_type { + /* Domain to be queried. */ + domid_t domid; + /* OUT variable. */ + uint16_t mem_type; + uint16_t pad[2]; /* align next field on 8-byte boundary */ + /* IN variable. */ + uint64_t pfn; +}; +typedef struct xen_hvm_get_mem_type xen_hvm_get_mem_type_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_type_t); + +/* Following tools-only interfaces may change in future. */ +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +/* + * Definitions relating to DMOP_create_ioreq_server. (Defined here for + * backwards compatibility). + */ + +#define HVM_IOREQSRV_BUFIOREQ_OFF 0 +#define HVM_IOREQSRV_BUFIOREQ_LEGACY 1 +/* + * Use this when read_pointer gets updated atomically and + * the pointer pair gets read atomically: + */ +#define HVM_IOREQSRV_BUFIOREQ_ATOMIC 2 + +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ + +#if defined(__i386__) || defined(__x86_64__) + +/* + * HVMOP_set_evtchn_upcall_vector: Set a that should be used for = event + * channel upcalls on the specified = . If set, + * this vector will be used in preference = to the + * domain global callback via (see + * HVM_PARAM_CALLBACK_IRQ). + */ +#define HVMOP_set_evtchn_upcall_vector 23 +struct xen_hvm_evtchn_upcall_vector { + uint32_t vcpu; + uint8_t vector; +}; +typedef struct xen_hvm_evtchn_upcall_vector xen_hvm_evtchn_upcall_vector_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_evtchn_upcall_vector_t); + +#endif /* defined(__i386__) || defined(__x86_64__) */ + +#define HVMOP_guest_request_vm_event 24 + +/* HVMOP_altp2m: perform altp2m state operations */ +#define HVMOP_altp2m 25 + +#define HVMOP_ALTP2M_INTERFACE_VERSION 0x00000001 + +struct xen_hvm_altp2m_domain_state { + /* IN or OUT variable on/off */ + uint8_t state; +}; +typedef struct xen_hvm_altp2m_domain_state xen_hvm_altp2m_domain_state_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_domain_state_t); + +struct xen_hvm_altp2m_vcpu_enable_notify { + uint32_t vcpu_id; + uint32_t pad; + /* #VE info area gfn */ + uint64_t gfn; +}; +typedef struct xen_hvm_altp2m_vcpu_enable_notify xen_hvm_altp2m_vcpu_enabl= e_notify_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t); + +struct xen_hvm_altp2m_vcpu_disable_notify { + uint32_t vcpu_id; +}; +typedef struct xen_hvm_altp2m_vcpu_disable_notify xen_hvm_altp2m_vcpu_disa= ble_notify_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_disable_notify_t); + +struct xen_hvm_altp2m_view { + /* IN/OUT variable */ + uint16_t view; + uint16_t hvmmem_default_access; /* xenmem_access_t */ +}; +typedef struct xen_hvm_altp2m_view xen_hvm_altp2m_view_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_view_t); + +#if __XEN_INTERFACE_VERSION__ < 0x00040a00 +struct xen_hvm_altp2m_set_mem_access { + /* view */ + uint16_t view; + /* Memory type */ + uint16_t access; /* xenmem_access_t */ + uint32_t pad; + /* gfn */ + uint64_t gfn; +}; +typedef struct xen_hvm_altp2m_set_mem_access xen_hvm_altp2m_set_mem_access= _t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_mem_access_t); +#endif /* __XEN_INTERFACE_VERSION__ < 0x00040a00 */ + +struct xen_hvm_altp2m_mem_access { + /* view */ + uint16_t view; + /* Memory type */ + uint16_t access; /* xenmem_access_t */ + uint32_t pad; + /* gfn */ + uint64_t gfn; +}; +typedef struct xen_hvm_altp2m_mem_access xen_hvm_altp2m_mem_access_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_mem_access_t); + +struct xen_hvm_altp2m_set_mem_access_multi { + /* view */ + uint16_t view; + uint16_t pad; + /* Number of pages */ + uint32_t nr; + /* + * Used for continuation purposes. + * Must be set to zero upon initial invocation. + */ + uint64_t opaque; + /* List of pfns to set access for */ + XEN_GUEST_HANDLE(const_uint64) pfn_list; + /* Corresponding list of access settings for pfn_list */ + XEN_GUEST_HANDLE(const_uint8) access_list; +}; + +struct xen_hvm_altp2m_change_gfn { + /* view */ + uint16_t view; + uint16_t pad1; + uint32_t pad2; + /* old gfn */ + uint64_t old_gfn; + /* new gfn, INVALID_GFN (~0UL) means revert */ + uint64_t new_gfn; +}; +typedef struct xen_hvm_altp2m_change_gfn xen_hvm_altp2m_change_gfn_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_change_gfn_t); + +struct xen_hvm_altp2m_get_vcpu_p2m_idx { + uint32_t vcpu_id; + uint16_t altp2m_idx; +}; + +struct xen_hvm_altp2m_set_visibility { + uint16_t altp2m_idx; + uint8_t visible; + uint8_t pad; +}; + +struct xen_hvm_altp2m_op { + uint32_t version; /* HVMOP_ALTP2M_INTERFACE_VERSION */ + uint32_t cmd; +/* Get/set the altp2m state for a domain */ +#define HVMOP_altp2m_get_domain_state 1 +#define HVMOP_altp2m_set_domain_state 2 +/* Set a given VCPU to receive altp2m event notifications */ +#define HVMOP_altp2m_vcpu_enable_notify 3 +/* Create a new view */ +#define HVMOP_altp2m_create_p2m 4 +/* Destroy a view */ +#define HVMOP_altp2m_destroy_p2m 5 +/* Switch view for an entire domain */ +#define HVMOP_altp2m_switch_p2m 6 +/* Notify that a page of memory is to have specific access types */ +#define HVMOP_altp2m_set_mem_access 7 +/* Change a p2m entry to have a different gfn->mfn mapping */ +#define HVMOP_altp2m_change_gfn 8 +/* Set access for an array of pages */ +#define HVMOP_altp2m_set_mem_access_multi 9 +/* Set the "Suppress #VE" bit on a page */ +#define HVMOP_altp2m_set_suppress_ve 10 +/* Get the "Suppress #VE" bit of a page */ +#define HVMOP_altp2m_get_suppress_ve 11 +/* Get the access of a page of memory from a certain view */ +#define HVMOP_altp2m_get_mem_access 12 +/* Disable altp2m event notifications for a given VCPU */ +#define HVMOP_altp2m_vcpu_disable_notify 13 +/* Get the active vcpu p2m index */ +#define HVMOP_altp2m_get_p2m_idx 14 +/* Set the "Supress #VE" bit for a range of pages */ +#define HVMOP_altp2m_set_suppress_ve_multi 15 +/* Set visibility for a given altp2m view */ +#define HVMOP_altp2m_set_visibility 16 + domid_t domain; + uint16_t pad1; + uint32_t pad2; + union { + struct xen_hvm_altp2m_domain_state domain_state; + struct xen_hvm_altp2m_vcpu_enable_notify enable_notify; + struct xen_hvm_altp2m_view view; +#if __XEN_INTERFACE_VERSION__ < 0x00040a00 + struct xen_hvm_altp2m_set_mem_access set_mem_access; +#endif /* __XEN_INTERFACE_VERSION__ < 0x00040a00 */ + struct xen_hvm_altp2m_mem_access mem_access; + struct xen_hvm_altp2m_change_gfn change_gfn; + struct xen_hvm_altp2m_set_mem_access_multi set_mem_access_multi; + struct xen_hvm_altp2m_suppress_ve suppress_ve; + struct xen_hvm_altp2m_suppress_ve_multi suppress_ve_multi; + struct xen_hvm_altp2m_vcpu_disable_notify disable_notify; + struct xen_hvm_altp2m_get_vcpu_p2m_idx get_vcpu_p2m_idx; + struct xen_hvm_altp2m_set_visibility set_visibility; + uint8_t pad[64]; + } u; +}; +typedef struct xen_hvm_altp2m_op xen_hvm_altp2m_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_op_t); + +#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/hvm/params.h b/include/standard-h= eaders/xen/hvm/params.h new file mode 100644 index 0000000000..c9d6e70d7b --- /dev/null +++ b/include/standard-headers/xen/hvm/params.h @@ -0,0 +1,318 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2007, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_HVM_PARAMS_H__ +#define __XEN_PUBLIC_HVM_PARAMS_H__ + +#include "hvm_op.h" + +/* These parameters are deprecated and their meaning is undefined. */ +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +#define HVM_PARAM_PAE_ENABLED 4 +#define HVM_PARAM_DM_DOMAIN 13 +#define HVM_PARAM_MEMORY_EVENT_CR0 20 +#define HVM_PARAM_MEMORY_EVENT_CR3 21 +#define HVM_PARAM_MEMORY_EVENT_CR4 22 +#define HVM_PARAM_MEMORY_EVENT_INT3 23 +#define HVM_PARAM_NESTEDHVM 24 +#define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP 25 +#define HVM_PARAM_BUFIOREQ_EVTCHN 26 +#define HVM_PARAM_MEMORY_EVENT_MSR 30 + +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ + +/* + * Parameter space for HVMOP_{set,get}_param. + */ + +#define HVM_PARAM_CALLBACK_IRQ 0 +#define HVM_PARAM_CALLBACK_IRQ_TYPE_MASK xen_mk_ullong(0xFF00000000000000) +/* + * How should CPU0 event-channel notifications be delivered? + * + * If val =3D=3D 0 then CPU0 event-channel notifications are not delivered. + * If val !=3D 0, val[63:56] encodes the type, as follows: + */ + +#define HVM_PARAM_CALLBACK_TYPE_GSI 0 +/* + * val[55:0] is a delivery GSI. GSI 0 cannot be used, as it aliases val = =3D=3D 0, + * and disables all notifications. + */ + +#define HVM_PARAM_CALLBACK_TYPE_PCI_INTX 1 +/* + * val[55:0] is a delivery PCI INTx line: + * Domain =3D val[47:32], Bus =3D val[31:16] DevFn =3D val[15:8], IntX =3D= val[1:0] + */ + +#if defined(__i386__) || defined(__x86_64__) +#define HVM_PARAM_CALLBACK_TYPE_VECTOR 2 +/* + * val[7:0] is a vector number. Check for XENFEAT_hvm_callback_vector to = know + * if this delivery method is available. + */ +#elif defined(__arm__) || defined(__aarch64__) +#define HVM_PARAM_CALLBACK_TYPE_PPI 2 +/* + * val[55:16] needs to be zero. + * val[15:8] is interrupt flag of the PPI used by event-channel: + * bit 8: the PPI is edge(1) or level(0) triggered + * bit 9: the PPI is active low(1) or high(0) + * val[7:0] is a PPI number used by event-channel. + * This is only used by ARM/ARM64 and masking/eoi the interrupt associated= to + * the notification is handled by the interrupt controller. + */ +#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_MASK 0xFF00 +#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_LOW_LEVEL 2 +#endif + +/* + * These are not used by Xen. They are here for convenience of HVM-guest + * xenbus implementations. + */ +#define HVM_PARAM_STORE_PFN 1 +#define HVM_PARAM_STORE_EVTCHN 2 + +#define HVM_PARAM_IOREQ_PFN 5 + +#define HVM_PARAM_BUFIOREQ_PFN 6 + +#if defined(__i386__) || defined(__x86_64__) + +/* + * Viridian enlightenments + * + * (See http://download.microsoft.com/download/A/B/4/AB43A34E-BDD0-4FA6-BD= EF-79EEF16E880B/Hypervisor%20Top%20Level%20Functional%20Specification%20v4.= 0.docx) + * + * To expose viridian enlightenments to the guest set this parameter + * to the desired feature mask. The base feature set must be present + * in any valid feature mask. + */ +#define HVM_PARAM_VIRIDIAN 9 + +/* Base+Freq viridian feature sets: + * + * - Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) + * - APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR) + * - Virtual Processor index MSR (HV_X64_MSR_VP_INDEX) + * - Timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and + * HV_X64_MSR_APIC_FREQUENCY) + */ +#define _HVMPV_base_freq 0 +#define HVMPV_base_freq (1 << _HVMPV_base_freq) + +/* Feature set modifications */ + +/* Disable timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and + * HV_X64_MSR_APIC_FREQUENCY). + * This modification restores the viridian feature set to the + * original 'base' set exposed in releases prior to Xen 4.4. + */ +#define _HVMPV_no_freq 1 +#define HVMPV_no_freq (1 << _HVMPV_no_freq) + +/* Enable Partition Time Reference Counter (HV_X64_MSR_TIME_REF_COUNT) */ +#define _HVMPV_time_ref_count 2 +#define HVMPV_time_ref_count (1 << _HVMPV_time_ref_count) + +/* Enable Reference TSC Page (HV_X64_MSR_REFERENCE_TSC) */ +#define _HVMPV_reference_tsc 3 +#define HVMPV_reference_tsc (1 << _HVMPV_reference_tsc) + +/* Use Hypercall for remote TLB flush */ +#define _HVMPV_hcall_remote_tlb_flush 4 +#define HVMPV_hcall_remote_tlb_flush (1 << _HVMPV_hcall_remote_tlb_flush) + +/* Use APIC assist */ +#define _HVMPV_apic_assist 5 +#define HVMPV_apic_assist (1 << _HVMPV_apic_assist) + +/* Enable crash MSRs */ +#define _HVMPV_crash_ctl 6 +#define HVMPV_crash_ctl (1 << _HVMPV_crash_ctl) + +/* Enable SYNIC MSRs */ +#define _HVMPV_synic 7 +#define HVMPV_synic (1 << _HVMPV_synic) + +/* Enable STIMER MSRs */ +#define _HVMPV_stimer 8 +#define HVMPV_stimer (1 << _HVMPV_stimer) + +/* Use Synthetic Cluster IPI Hypercall */ +#define _HVMPV_hcall_ipi 9 +#define HVMPV_hcall_ipi (1 << _HVMPV_hcall_ipi) + +/* Enable ExProcessorMasks */ +#define _HVMPV_ex_processor_masks 10 +#define HVMPV_ex_processor_masks (1 << _HVMPV_ex_processor_masks) + +/* Allow more than 64 VPs */ +#define _HVMPV_no_vp_limit 11 +#define HVMPV_no_vp_limit (1 << _HVMPV_no_vp_limit) + +/* Enable vCPU hotplug */ +#define _HVMPV_cpu_hotplug 12 +#define HVMPV_cpu_hotplug (1 << _HVMPV_cpu_hotplug) + +#define HVMPV_feature_mask \ + (HVMPV_base_freq | \ + HVMPV_no_freq | \ + HVMPV_time_ref_count | \ + HVMPV_reference_tsc | \ + HVMPV_hcall_remote_tlb_flush | \ + HVMPV_apic_assist | \ + HVMPV_crash_ctl | \ + HVMPV_synic | \ + HVMPV_stimer | \ + HVMPV_hcall_ipi | \ + HVMPV_ex_processor_masks | \ + HVMPV_no_vp_limit | \ + HVMPV_cpu_hotplug) + +#endif + +/* + * Set mode for virtual timers (currently x86 only): + * delay_for_missed_ticks (default): + * Do not advance a vcpu's time beyond the correct delivery time for + * interrupts that have been missed due to preemption. Deliver missed + * interrupts when the vcpu is rescheduled and advance the vcpu's virtual + * time stepwise for each one. + * no_delay_for_missed_ticks: + * As above, missed interrupts are delivered, but guest time always trac= ks + * wallclock (i.e., real) time while doing so. + * no_missed_ticks_pending: + * No missed interrupts are held pending. Instead, to ensure ticks are + * delivered at some non-zero rate, if we detect missed ticks then the + * internal tick alarm is not disabled if the VCPU is preempted during t= he + * next tick period. + * one_missed_tick_pending: + * Missed interrupts are collapsed together and delivered as one 'late t= ick'. + * Guest time always tracks wallclock (i.e., real) time. + */ +#define HVM_PARAM_TIMER_MODE 10 +#define HVMPTM_delay_for_missed_ticks 0 +#define HVMPTM_no_delay_for_missed_ticks 1 +#define HVMPTM_no_missed_ticks_pending 2 +#define HVMPTM_one_missed_tick_pending 3 + +/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */ +#define HVM_PARAM_HPET_ENABLED 11 + +/* Identity-map page directory used by Intel EPT when CR0.PG=3D0. */ +#define HVM_PARAM_IDENT_PT 12 + +/* ACPI S state: currently support S0 and S3 on x86. */ +#define HVM_PARAM_ACPI_S_STATE 14 + +/* TSS used on Intel when CR0.PE=3D0. */ +#define HVM_PARAM_VM86_TSS 15 + +/* Boolean: Enable aligning all periodic vpts to reduce interrupts */ +#define HVM_PARAM_VPT_ALIGN 16 + +/* Console debug shared memory ring and event channel */ +#define HVM_PARAM_CONSOLE_PFN 17 +#define HVM_PARAM_CONSOLE_EVTCHN 18 + +/* + * Select location of ACPI PM1a and TMR control blocks. Currently two loca= tions + * are supported, specified by version 0 or 1 in this parameter: + * - 0: default, use the old addresses + * PM1A_EVT =3D=3D 0x1f40; PM1A_CNT =3D=3D 0x1f44; PM_TMR =3D=3D 0x= 1f48 + * - 1: use the new default qemu addresses + * PM1A_EVT =3D=3D 0xb000; PM1A_CNT =3D=3D 0xb004; PM_TMR =3D=3D 0x= b008 + * You can find these address definitions in + */ +#define HVM_PARAM_ACPI_IOPORTS_LOCATION 19 + +/* Params for the mem event rings */ +#define HVM_PARAM_PAGING_RING_PFN 27 +#define HVM_PARAM_MONITOR_RING_PFN 28 +#define HVM_PARAM_SHARING_RING_PFN 29 + +/* SHUTDOWN_* action in case of a triple fault */ +#define HVM_PARAM_TRIPLE_FAULT_REASON 31 + +#define HVM_PARAM_IOREQ_SERVER_PFN 32 +#define HVM_PARAM_NR_IOREQ_SERVER_PAGES 33 + +/* Location of the VM Generation ID in guest physical address space. */ +#define HVM_PARAM_VM_GENERATION_ID_ADDR 34 + +/* + * Set mode for altp2m: + * disabled: don't activate altp2m (default) + * mixed: allow access to all altp2m ops for both in-guest and external t= ools + * external: allow access to external privileged tools only + * limited: guest only has limited access (ie. control VMFUNC and #VE) + * + * Note that 'mixed' mode has not been evaluated for safety from a + * security perspective. Before using this mode in a + * security-critical environment, each subop should be evaluated for + * safety, with unsafe subops blacklisted in XSM. + */ +#define HVM_PARAM_ALTP2M 35 +#define XEN_ALTP2M_disabled 0 +#define XEN_ALTP2M_mixed 1 +#define XEN_ALTP2M_external 2 +#define XEN_ALTP2M_limited 3 + +/* + * Size of the x87 FPU FIP/FDP registers that the hypervisor needs to + * save/restore. This is a workaround for a hardware limitation that + * does not allow the full FIP/FDP and FCS/FDS to be restored. + * + * Valid values are: + * + * 8: save/restore 64-bit FIP/FDP and clear FCS/FDS (default if CPU + * has FPCSDS feature). + * + * 4: save/restore 32-bit FIP/FDP, FCS/FDS, and clear upper 32-bits of + * FIP/FDP. + * + * 0: allow hypervisor to choose based on the value of FIP/FDP + * (default if CPU does not have FPCSDS). + * + * If FPCSDS (bit 13 in CPUID leaf 0x7, subleaf 0x0) is set, the CPU + * never saves FCS/FDS and this parameter should be left at the + * default of 8. + */ +#define HVM_PARAM_X87_FIP_WIDTH 36 + +/* + * TSS (and its size) used on Intel when CR0.PE=3D0. The address occupies + * the low 32 bits, while the size is in the high 32 ones. + */ +#define HVM_PARAM_VM86_TSS_SIZED 37 + +/* Enable MCA capabilities. */ +#define HVM_PARAM_MCA_CAP 38 +#define XEN_HVM_MCA_CAP_LMCE (xen_mk_ullong(1) << 0) +#define XEN_HVM_MCA_CAP_MASK XEN_HVM_MCA_CAP_LMCE + +#define HVM_NR_PARAMS 39 + +#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff --git a/include/standard-headers/xen/memory.h b/include/standard-heade= rs/xen/memory.h new file mode 100644 index 0000000000..383a9468c3 --- /dev/null +++ b/include/standard-headers/xen/memory.h @@ -0,0 +1,754 @@ +/*************************************************************************= ***** + * memory.h + * + * Memory reservation and information. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2005, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_MEMORY_H__ +#define __XEN_PUBLIC_MEMORY_H__ + +#include "xen.h" +#include "physdev.h" + +/* + * Increase or decrease the specified domain's memory reservation. Returns= the + * number of extents successfully allocated or freed. + * arg =3D=3D addr of struct xen_memory_reservation. + */ +#define XENMEM_increase_reservation 0 +#define XENMEM_decrease_reservation 1 +#define XENMEM_populate_physmap 6 + +#if __XEN_INTERFACE_VERSION__ >=3D 0x00030209 +/* + * Maximum # bits addressable by the user of the allocated region (e.g., I= /O + * devices often have a 32-bit limitation even in 64-bit systems). If zero + * then the user has no addressing restriction. This field is not used by + * XENMEM_decrease_reservation. + */ +#define XENMEMF_address_bits(x) (x) +#define XENMEMF_get_address_bits(x) ((x) & 0xffu) +/* NUMA node to allocate from. */ +#define XENMEMF_node(x) (((x) + 1) << 8) +#define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu) +/* Flag to populate physmap with populate-on-demand entries */ +#define XENMEMF_populate_on_demand (1<<16) +/* Flag to request allocation only from the node specified */ +#define XENMEMF_exact_node_request (1<<17) +#define XENMEMF_exact_node(n) (XENMEMF_node(n) | XENMEMF_exact_node_reques= t) +/* Flag to indicate the node specified is virtual node */ +#define XENMEMF_vnode (1<<18) +#endif + +struct xen_memory_reservation { + + /* + * XENMEM_increase_reservation: + * OUT: MFN (*not* GMFN) bases of extents that were allocated + * XENMEM_decrease_reservation: + * IN: GMFN bases of extents to free + * XENMEM_populate_physmap: + * IN: GPFN bases of extents to populate with memory + * OUT: GMFN bases of extents that were allocated + * (NB. This command also updates the mach_to_phys translation table) + * XENMEM_claim_pages: + * IN: must be zero + */ + XEN_GUEST_HANDLE(xen_pfn_t) extent_start; + + /* Number of extents, and size/alignment of each (2^extent_order pages= ). */ + xen_ulong_t nr_extents; + unsigned int extent_order; + +#if __XEN_INTERFACE_VERSION__ >=3D 0x00030209 + /* XENMEMF flags. */ + unsigned int mem_flags; +#else + unsigned int address_bits; +#endif + + /* + * Domain whose reservation is being changed. + * Unprivileged domains can specify only DOMID_SELF. + */ + domid_t domid; +}; +typedef struct xen_memory_reservation xen_memory_reservation_t; +DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t); + +/* + * An atomic exchange of memory pages. If return code is zero then + * @out.extent_list provides GMFNs of the newly-allocated memory. + * Returns zero on complete success, otherwise a negative error code. + * On complete success then always @nr_exchanged =3D=3D @in.nr_extents. + * On partial success @nr_exchanged indicates how much work was done. + * + * Note that only PV guests can use this operation. + */ +#define XENMEM_exchange 11 +struct xen_memory_exchange { + /* + * [IN] Details of memory extents to be exchanged (GMFN bases). + * Note that @in.address_bits is ignored and unused. + */ + struct xen_memory_reservation in; + + /* + * [IN/OUT] Details of new memory extents. + * We require that: + * 1. @in.domid =3D=3D @out.domid + * 2. @in.nr_extents << @in.extent_order =3D=3D + * @out.nr_extents << @out.extent_order + * 3. @in.extent_start and @out.extent_start lists must not overlap + * 4. @out.extent_start lists GPFN bases to be populated + * 5. @out.extent_start is overwritten with allocated GMFN bases + */ + struct xen_memory_reservation out; + + /* + * [OUT] Number of input extents that were successfully exchanged: + * 1. The first @nr_exchanged input extents were successfully + * deallocated. + * 2. The corresponding first entries in the output extent list corre= ctly + * indicate the GMFNs that were successfully exchanged. + * 3. All other input and output extents are untouched. + * 4. If not all input exents are exchanged then the return code of t= his + * command will be non-zero. + * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER! + */ + xen_ulong_t nr_exchanged; +}; +typedef struct xen_memory_exchange xen_memory_exchange_t; +DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t); + +/* + * Returns the maximum machine frame number of mapped RAM in this system. + * This command always succeeds (it never returns an error code). + * arg =3D=3D NULL. + */ +#define XENMEM_maximum_ram_page 2 + +struct xen_memory_domain { + /* [IN] Domain information is being queried for. */ + domid_t domid; +}; + +/* + * Returns the current or maximum memory reservation, in pages, of the + * specified domain (may be DOMID_SELF). Returns -ve errcode on failure. + * arg =3D=3D addr of struct xen_memory_domain. + */ +#define XENMEM_current_reservation 3 +#define XENMEM_maximum_reservation 4 + +/* + * Returns the maximum GFN in use by the specified domain (may be DOMID_SE= LF). + * Returns -ve errcode on failure. + * arg =3D=3D addr of struct xen_memory_domain. + */ +#define XENMEM_maximum_gpfn 14 + +/* + * Returns a list of MFN bases of 2MB extents comprising the machine_to_ph= ys + * mapping table. Architectures which do not have a m2p table do not imple= ment + * this command. + * arg =3D=3D addr of xen_machphys_mfn_list_t. + */ +#define XENMEM_machphys_mfn_list 5 +struct xen_machphys_mfn_list { + /* + * Size of the 'extent_start' array. Fewer entries will be filled if t= he + * machphys table is smaller than max_extents * 2MB. + */ + unsigned int max_extents; + + /* + * Pointer to buffer to fill with list of extent starts. If there are + * any large discontiguities in the machine address space, 2MB gaps in + * the machphys table will be represented by an MFN base of zero. + */ + XEN_GUEST_HANDLE(xen_pfn_t) extent_start; + + /* + * Number of extents written to the above array. This will be smaller + * than 'max_extents' if the machphys table is smaller than max_e * 2M= B. + */ + unsigned int nr_extents; +}; +typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t; +DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t); + +/* + * For a compat caller, this is identical to XENMEM_machphys_mfn_list. + * + * For a non compat caller, this functions similarly to + * XENMEM_machphys_mfn_list, but returns the mfns making up the compatibil= ity + * m2p table. + */ +#define XENMEM_machphys_compat_mfn_list 25 + +/* + * Returns the location in virtual address space of the machine_to_phys + * mapping table. Architectures which do not have a m2p table, or which do= not + * map it by default into guest address space, do not implement this comma= nd. + * arg =3D=3D addr of xen_machphys_mapping_t. + */ +#define XENMEM_machphys_mapping 12 +struct xen_machphys_mapping { + xen_ulong_t v_start, v_end; /* Start and end virtual addresses. */ + xen_ulong_t max_mfn; /* Maximum MFN that can be looked up. */ +}; +typedef struct xen_machphys_mapping xen_machphys_mapping_t; +DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t); + +/* Source mapping space. */ +/* ` enum phys_map_space { */ +#define XENMAPSPACE_shared_info 0 /* shared info page */ +#define XENMAPSPACE_grant_table 1 /* grant table page */ +#define XENMAPSPACE_gmfn 2 /* GMFN */ +#define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap on= ly. */ +#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom, + * XENMEM_add_to_physmap_batch only. */ +#define XENMAPSPACE_dev_mmio 5 /* device mmio region + ARM only; the region is mapped in + Stage-2 using the Normal Memory + Inner/Outer Write-Back Cacheable + memory attribute. */ +/* ` } */ + +/* + * Sets the GPFN at which a particular page appears in the specified guest= 's + * physical address space (translated guests only). + * arg =3D=3D addr of xen_add_to_physmap_t. + */ +#define XENMEM_add_to_physmap 7 +struct xen_add_to_physmap { + /* Which domain to change the mapping for. */ + domid_t domid; + + /* Number of pages to go through for gmfn_range */ + uint16_t size; + + unsigned int space; /* =3D> enum phys_map_space */ + +#define XENMAPIDX_grant_table_status 0x80000000 + + /* Index into space being mapped. */ + xen_ulong_t idx; + + /* GPFN in domid where the source mapping page should appear. */ + xen_pfn_t gpfn; +}; +typedef struct xen_add_to_physmap xen_add_to_physmap_t; +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t); + +/* A batched version of add_to_physmap. */ +#define XENMEM_add_to_physmap_batch 23 +struct xen_add_to_physmap_batch { + /* IN */ + /* Which domain to change the mapping for. */ + domid_t domid; + uint16_t space; /* =3D> enum phys_map_space */ + + /* Number of pages to go through */ + uint16_t size; + +#if __XEN_INTERFACE_VERSION__ < 0x00040700 + domid_t foreign_domid; /* IFF gmfn_foreign. Should be 0 for other spac= es. */ +#else + union xen_add_to_physmap_batch_extra { + domid_t foreign_domid; /* gmfn_foreign */ + uint16_t res0; /* All the other spaces. Should be 0 */ + } u; +#endif + + /* Indexes into space being mapped. */ + XEN_GUEST_HANDLE(xen_ulong_t) idxs; + + /* GPFN in domid where the source mapping page should appear. */ + XEN_GUEST_HANDLE(xen_pfn_t) gpfns; + + /* OUT */ + + /* Per index error code. */ + XEN_GUEST_HANDLE(int) errs; +}; +typedef struct xen_add_to_physmap_batch xen_add_to_physmap_batch_t; +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_batch_t); + +#if __XEN_INTERFACE_VERSION__ < 0x00040400 +#define XENMEM_add_to_physmap_range XENMEM_add_to_physmap_batch +#define xen_add_to_physmap_range xen_add_to_physmap_batch +typedef struct xen_add_to_physmap_batch xen_add_to_physmap_range_t; +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_range_t); +#endif + +/* + * Unmaps the page appearing at a particular GPFN from the specified guest= 's + * physical address space (translated guests only). + * arg =3D=3D addr of xen_remove_from_physmap_t. + */ +#define XENMEM_remove_from_physmap 15 +struct xen_remove_from_physmap { + /* Which domain to change the mapping for. */ + domid_t domid; + + /* GPFN of the current mapping of the page. */ + xen_pfn_t gpfn; +}; +typedef struct xen_remove_from_physmap xen_remove_from_physmap_t; +DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t); + +/*** REMOVED ***/ +/*#define XENMEM_translate_gpfn_list 8*/ + +/* + * Returns the pseudo-physical memory map as it was when the domain + * was started (specified by XENMEM_set_memory_map). + * arg =3D=3D addr of xen_memory_map_t. + */ +#define XENMEM_memory_map 9 +struct xen_memory_map { + /* + * On call the number of entries which can be stored in buffer. On + * return the number of entries which have been stored in + * buffer. + */ + unsigned int nr_entries; + + /* + * Entries in the buffer are in the same format as returned by the + * BIOS INT 0x15 EAX=3D0xE820 call. + */ + XEN_GUEST_HANDLE(void) buffer; +}; +typedef struct xen_memory_map xen_memory_map_t; +DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t); + +/* + * Returns the real physical memory map. Passes the same structure as + * XENMEM_memory_map. + * Specifying buffer as NULL will return the number of entries required + * to store the complete memory map. + * arg =3D=3D addr of xen_memory_map_t. + */ +#define XENMEM_machine_memory_map 10 + +/* + * Set the pseudo-physical memory map of a domain, as returned by + * XENMEM_memory_map. + * arg =3D=3D addr of xen_foreign_memory_map_t. + */ +#define XENMEM_set_memory_map 13 +struct xen_foreign_memory_map { + domid_t domid; + struct xen_memory_map map; +}; +typedef struct xen_foreign_memory_map xen_foreign_memory_map_t; +DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t); + +#define XENMEM_set_pod_target 16 +#define XENMEM_get_pod_target 17 +struct xen_pod_target { + /* IN */ + uint64_t target_pages; + /* OUT */ + uint64_t tot_pages; + uint64_t pod_cache_pages; + uint64_t pod_entries; + /* IN */ + domid_t domid; +}; +typedef struct xen_pod_target xen_pod_target_t; + +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +#ifndef uint64_aligned_t +#define uint64_aligned_t uint64_t +#endif + +/* + * Get the number of MFNs saved through memory sharing. + * The call never fails. + */ +#define XENMEM_get_sharing_freed_pages 18 +#define XENMEM_get_sharing_shared_pages 19 + +#define XENMEM_paging_op 20 +#define XENMEM_paging_op_nominate 0 +#define XENMEM_paging_op_evict 1 +#define XENMEM_paging_op_prep 2 + +struct xen_mem_paging_op { + uint8_t op; /* XENMEM_paging_op_* */ + domid_t domain; + + /* IN: (XENMEM_paging_op_prep) buffer to immediately fill page from */ + XEN_GUEST_HANDLE_64(const_uint8) buffer; + /* IN: gfn of page being operated on */ + uint64_aligned_t gfn; +}; +typedef struct xen_mem_paging_op xen_mem_paging_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_mem_paging_op_t); + +#define XENMEM_access_op 21 +#define XENMEM_access_op_set_access 0 +#define XENMEM_access_op_get_access 1 +/* + * XENMEM_access_op_enable_emulate and XENMEM_access_op_disable_emulate are + * currently unused, but since they have been in use please do not reuse t= hem. + * + * #define XENMEM_access_op_enable_emulate 2 + * #define XENMEM_access_op_disable_emulate 3 + */ +#define XENMEM_access_op_set_access_multi 4 + +typedef enum { + XENMEM_access_n, + XENMEM_access_r, + XENMEM_access_w, + XENMEM_access_rw, + XENMEM_access_x, + XENMEM_access_rx, + XENMEM_access_wx, + XENMEM_access_rwx, + /* + * Page starts off as r-x, but automatically + * change to r-w on a write + */ + XENMEM_access_rx2rw, + /* + * Log access: starts off as n, automatically + * goes to rwx, generating an event without + * pausing the vcpu + */ + XENMEM_access_n2rwx, + /* Take the domain default */ + XENMEM_access_default +} xenmem_access_t; + +struct xen_mem_access_op { + /* XENMEM_access_op_* */ + uint8_t op; + /* xenmem_access_t */ + uint8_t access; + domid_t domid; + /* + * Number of pages for set op (or size of pfn_list for + * XENMEM_access_op_set_access_multi) + * Ignored on setting default access and other ops + */ + uint32_t nr; + /* + * First pfn for set op + * pfn for get op + * ~0ull is used to set and get the default access for pages + */ + uint64_aligned_t pfn; + /* + * List of pfns to set access for + * Used only with XENMEM_access_op_set_access_multi + */ + XEN_GUEST_HANDLE(const_uint64) pfn_list; + /* + * Corresponding list of access settings for pfn_list + * Used only with XENMEM_access_op_set_access_multi + */ + XEN_GUEST_HANDLE(const_uint8) access_list; +}; +typedef struct xen_mem_access_op xen_mem_access_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t); + +#define XENMEM_sharing_op 22 +#define XENMEM_sharing_op_nominate_gfn 0 +#define XENMEM_sharing_op_nominate_gref 1 +#define XENMEM_sharing_op_share 2 +#define XENMEM_sharing_op_debug_gfn 3 +#define XENMEM_sharing_op_debug_mfn 4 +#define XENMEM_sharing_op_debug_gref 5 +#define XENMEM_sharing_op_add_physmap 6 +#define XENMEM_sharing_op_audit 7 +#define XENMEM_sharing_op_range_share 8 +#define XENMEM_sharing_op_fork 9 +#define XENMEM_sharing_op_fork_reset 10 + +#define XENMEM_SHARING_OP_S_HANDLE_INVALID (-10) +#define XENMEM_SHARING_OP_C_HANDLE_INVALID (-9) + +/* The following allows sharing of grant refs. This is useful + * for sharing utilities sitting as "filters" in IO backends + * (e.g. memshr + blktap(2)). The IO backend is only exposed + * to grant references, and this allows sharing of the grefs */ +#define XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG (xen_mk_ullong(1) << 62) + +#define XENMEM_SHARING_OP_FIELD_MAKE_GREF(field, val) \ + (field) =3D (XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG | val) +#define XENMEM_SHARING_OP_FIELD_IS_GREF(field) \ + ((field) & XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG) +#define XENMEM_SHARING_OP_FIELD_GET_GREF(field) \ + ((field) & (~XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG)) + +struct xen_mem_sharing_op { + uint8_t op; /* XENMEM_sharing_op_* */ + domid_t domain; + + union { + struct mem_sharing_op_nominate { /* OP_NOMINATE_xxx */ + union { + uint64_aligned_t gfn; /* IN: gfn to nominate */ + uint32_t grant_ref; /* IN: grant ref to nominate */ + } u; + uint64_aligned_t handle; /* OUT: the handle */ + } nominate; + struct mem_sharing_op_share { /* OP_SHARE/ADD_PHYSMAP */ + uint64_aligned_t source_gfn; /* IN: the gfn of the source p= age */ + uint64_aligned_t source_handle; /* IN: handle to the source pa= ge */ + uint64_aligned_t client_gfn; /* IN: the client gfn */ + uint64_aligned_t client_handle; /* IN: handle to the client pa= ge */ + domid_t client_domain; /* IN: the client domain id */ + } share; + struct mem_sharing_op_range { /* OP_RANGE_SHARE */ + uint64_aligned_t first_gfn; /* IN: the first gfn */ + uint64_aligned_t last_gfn; /* IN: the last gfn */ + uint64_aligned_t opaque; /* Must be set to 0 */ + domid_t client_domain; /* IN: the client domain id */ + uint16_t _pad[3]; /* Must be set to 0 */ + } range; + struct mem_sharing_op_debug { /* OP_DEBUG_xxx */ + union { + uint64_aligned_t gfn; /* IN: gfn to debug */ + uint64_aligned_t mfn; /* IN: mfn to debug */ + uint32_t gref; /* IN: gref to debug */ + } u; + } debug; + struct mem_sharing_op_fork { /* OP_FORK */ + domid_t parent_domain; /* IN: parent's domain id */ +/* Only makes sense for short-lived forks */ +#define XENMEM_FORK_WITH_IOMMU_ALLOWED (1u << 0) +/* Only makes sense for short-lived forks */ +#define XENMEM_FORK_BLOCK_INTERRUPTS (1u << 1) + uint16_t flags; /* IN: optional settings */ + uint32_t pad; /* Must be set to 0 */ + } fork; + } u; +}; +typedef struct xen_mem_sharing_op xen_mem_sharing_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_mem_sharing_op_t); + +/* + * Attempt to stake a claim for a domain on a quantity of pages + * of system RAM, but _not_ assign specific pageframes. Only + * arithmetic is performed so the hypercall is very fast and need + * not be preemptible, thus sidestepping time-of-check-time-of-use + * races for memory allocation. Returns 0 if the hypervisor page + * allocator has atomically and successfully claimed the requested + * number of pages, else non-zero. + * + * Any domain may have only one active claim. When sufficient memory + * has been allocated to resolve the claim, the claim silently expires. + * Claiming zero pages effectively resets any outstanding claim and + * is always successful. + * + * Note that a valid claim may be staked even after memory has been + * allocated for a domain. In this case, the claim is not incremental, + * i.e. if the domain's total page count is 3, and a claim is staked + * for 10, only 7 additional pages are claimed. + * + * Caller must be privileged or the hypercall fails. + */ +#define XENMEM_claim_pages 24 + +/* + * XENMEM_claim_pages flags - the are no flags at this time. + * The zero value is appropriate. + */ + +/* + * With some legacy devices, certain guest-physical addresses cannot safely + * be used for other purposes, e.g. to map guest RAM. This hypercall + * enumerates those regions so the toolstack can avoid using them. + */ +#define XENMEM_reserved_device_memory_map 27 +struct xen_reserved_device_memory { + xen_pfn_t start_pfn; + xen_ulong_t nr_pages; +}; +typedef struct xen_reserved_device_memory xen_reserved_device_memory_t; +DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_t); + +struct xen_reserved_device_memory_map { +#define XENMEM_RDM_ALL 1 /* Request all regions (ignore dev union). */ + /* IN */ + uint32_t flags; + /* + * IN/OUT + * + * Gets set to the required number of entries when too low, + * signaled by error code -ERANGE. + */ + unsigned int nr_entries; + /* OUT */ + XEN_GUEST_HANDLE(xen_reserved_device_memory_t) buffer; + /* IN */ + union { + physdev_pci_device_t pci; + } dev; +}; +typedef struct xen_reserved_device_memory_map xen_reserved_device_memory_m= ap_t; +DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_map_t); + +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ + +/* + * Get the pages for a particular guest resource, so that they can be + * mapped directly by a tools domain. + */ +#define XENMEM_acquire_resource 28 +struct xen_mem_acquire_resource { + /* IN - The domain whose resource is to be mapped */ + domid_t domid; + /* IN - the type of resource */ + uint16_t type; + +#define XENMEM_resource_ioreq_server 0 +#define XENMEM_resource_grant_table 1 +#define XENMEM_resource_vmtrace_buf 2 + + /* + * IN - a type-specific resource identifier, which must be zero + * unless stated otherwise. + * + * type =3D=3D XENMEM_resource_ioreq_server -> id =3D=3D ioreq server = id + * type =3D=3D XENMEM_resource_grant_table -> id defined below + */ + uint32_t id; + +#define XENMEM_resource_grant_table_id_shared 0 +#define XENMEM_resource_grant_table_id_status 1 + + /* + * IN/OUT + * + * As an IN parameter number of frames of the resource to be mapped. + * This value may be updated over the course of the operation. + * + * When frame_list is NULL and nr_frames is 0, this is interpreted as a + * request for the size of the resource, which shall be returned in the + * nr_frames field. + * + * The size of a resource will never be zero, but a nonzero result doe= sn't + * guarantee that a subsequent mapping request will be successful. Th= ere + * are further type/id specific constraints which may change between t= he + * two calls. + */ + uint32_t nr_frames; + uint32_t pad; + /* + * IN - the index of the initial frame to be mapped. This parameter + * is ignored if nr_frames is 0. This value may be updated + * over the course of the operation. + */ + uint64_t frame; + +#define XENMEM_resource_ioreq_server_frame_bufioreq 0 +#define XENMEM_resource_ioreq_server_frame_ioreq(n) (1 + (n)) + + /* + * IN/OUT - If the tools domain is PV then, upon return, frame_list + * will be populated with the MFNs of the resource. + * If the tools domain is HVM then it is expected that, on + * entry, frame_list will be populated with a list of GFNs + * that will be mapped to the MFNs of the resource. + * If -EIO is returned then the frame_list has only been + * partially mapped and it is up to the caller to unmap all + * the GFNs. + * This parameter may be NULL if nr_frames is 0. This + * value may be updated over the course of the operation. + */ + XEN_GUEST_HANDLE(xen_pfn_t) frame_list; +}; +typedef struct xen_mem_acquire_resource xen_mem_acquire_resource_t; +DEFINE_XEN_GUEST_HANDLE(xen_mem_acquire_resource_t); + +/* + * XENMEM_get_vnumainfo used by guest to get + * vNUMA topology from hypervisor. + */ +#define XENMEM_get_vnumainfo 26 + +/* vNUMA node memory ranges */ +struct xen_vmemrange { + uint64_t start, end; + unsigned int flags; + unsigned int nid; +}; +typedef struct xen_vmemrange xen_vmemrange_t; +DEFINE_XEN_GUEST_HANDLE(xen_vmemrange_t); + +/* + * vNUMA topology specifies vNUMA node number, distance table, + * memory ranges and vcpu mapping provided for guests. + * XENMEM_get_vnumainfo hypercall expects to see from guest + * nr_vnodes, nr_vmemranges and nr_vcpus to indicate available memory. + * After filling guests structures, nr_vnodes, nr_vmemranges and nr_vcpus + * copied back to guest. Domain returns expected values of nr_vnodes, + * nr_vmemranges and nr_vcpus to guest if the values where incorrect. + */ +struct xen_vnuma_topology_info { + /* IN */ + domid_t domid; + uint16_t pad; + /* IN/OUT */ + unsigned int nr_vnodes; + unsigned int nr_vcpus; + unsigned int nr_vmemranges; + /* OUT */ + union { + XEN_GUEST_HANDLE(uint) h; + uint64_t pad; + } vdistance; + union { + XEN_GUEST_HANDLE(uint) h; + uint64_t pad; + } vcpu_to_vnode; + union { + XEN_GUEST_HANDLE(xen_vmemrange_t) h; + uint64_t pad; + } vmemrange; +}; +typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t; +DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t); + +/* Next available subop number is 29 */ + +#endif /* __XEN_PUBLIC_MEMORY_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/physdev.h b/include/standard-head= ers/xen/physdev.h new file mode 100644 index 0000000000..d271766ad0 --- /dev/null +++ b/include/standard-headers/xen/physdev.h @@ -0,0 +1,383 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2006, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_PHYSDEV_H__ +#define __XEN_PUBLIC_PHYSDEV_H__ + +#include "xen.h" + +/* + * Prototype for this hypercall is: + * int physdev_op(int cmd, void *args) + * @cmd =3D=3D PHYSDEVOP_??? (physdev operation). + * @args =3D=3D Operation-specific extra arguments (NULL if none). + */ + +/* + * Notify end-of-interrupt (EOI) for the specified IRQ. + * @arg =3D=3D pointer to physdev_eoi structure. + */ +#define PHYSDEVOP_eoi 12 +struct physdev_eoi { + /* IN */ + uint32_t irq; +}; +typedef struct physdev_eoi physdev_eoi_t; +DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t); + +/* + * Register a shared page for the hypervisor to indicate whether the guest + * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly + * once the guest used this function in that the associated event channel + * will automatically get unmasked. The page registered is used as a bit + * array indexed by Xen's PIRQ value. + */ +#define PHYSDEVOP_pirq_eoi_gmfn_v1 17 +/* + * Register a shared page for the hypervisor to indicate whether the + * guest must issue PHYSDEVOP_eoi. This hypercall is very similar to + * PHYSDEVOP_pirq_eoi_gmfn_v1 but it doesn't change the semantics of + * PHYSDEVOP_eoi. The page registered is used as a bit array indexed by + * Xen's PIRQ value. + */ +#define PHYSDEVOP_pirq_eoi_gmfn_v2 28 +struct physdev_pirq_eoi_gmfn { + /* IN */ + xen_pfn_t gmfn; +}; +typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t; +DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t); + +/* + * Query the status of an IRQ line. + * @arg =3D=3D pointer to physdev_irq_status_query structure. + */ +#define PHYSDEVOP_irq_status_query 5 +struct physdev_irq_status_query { + /* IN */ + uint32_t irq; + /* OUT */ + uint32_t flags; /* XENIRQSTAT_* */ +}; +typedef struct physdev_irq_status_query physdev_irq_status_query_t; +DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t); + +/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */ +#define _XENIRQSTAT_needs_eoi (0) +#define XENIRQSTAT_needs_eoi (1U<<_XENIRQSTAT_needs_eoi) + +/* IRQ shared by multiple guests? */ +#define _XENIRQSTAT_shared (1) +#define XENIRQSTAT_shared (1U<<_XENIRQSTAT_shared) + +/* + * Set the current VCPU's I/O privilege level. + * @arg =3D=3D pointer to physdev_set_iopl structure. + */ +#define PHYSDEVOP_set_iopl 6 +struct physdev_set_iopl { + /* IN */ + uint32_t iopl; +}; +typedef struct physdev_set_iopl physdev_set_iopl_t; +DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t); + +/* + * Set the current VCPU's I/O-port permissions bitmap. + * @arg =3D=3D pointer to physdev_set_iobitmap structure. + */ +#define PHYSDEVOP_set_iobitmap 7 +struct physdev_set_iobitmap { + /* IN */ +#if __XEN_INTERFACE_VERSION__ >=3D 0x00030205 + XEN_GUEST_HANDLE(uint8) bitmap; +#else + uint8_t *bitmap; +#endif + uint32_t nr_ports; +}; +typedef struct physdev_set_iobitmap physdev_set_iobitmap_t; +DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t); + +/* + * Read or write an IO-APIC register. + * @arg =3D=3D pointer to physdev_apic structure. + */ +#define PHYSDEVOP_apic_read 8 +#define PHYSDEVOP_apic_write 9 +struct physdev_apic { + /* IN */ + unsigned long apic_physbase; + uint32_t reg; + /* IN or OUT */ + uint32_t value; +}; +typedef struct physdev_apic physdev_apic_t; +DEFINE_XEN_GUEST_HANDLE(physdev_apic_t); + +/* + * Allocate or free a physical upcall vector for the specified IRQ line. + * @arg =3D=3D pointer to physdev_irq structure. + */ +#define PHYSDEVOP_alloc_irq_vector 10 +#define PHYSDEVOP_free_irq_vector 11 +struct physdev_irq { + /* IN */ + uint32_t irq; + /* IN or OUT */ + uint32_t vector; +}; +typedef struct physdev_irq physdev_irq_t; +DEFINE_XEN_GUEST_HANDLE(physdev_irq_t); + +#define MAP_PIRQ_TYPE_MSI 0x0 +#define MAP_PIRQ_TYPE_GSI 0x1 +#define MAP_PIRQ_TYPE_UNKNOWN 0x2 +#define MAP_PIRQ_TYPE_MSI_SEG 0x3 +#define MAP_PIRQ_TYPE_MULTI_MSI 0x4 + +#define PHYSDEVOP_map_pirq 13 +struct physdev_map_pirq { + domid_t domid; + /* IN */ + int type; + /* IN (ignored for ..._MULTI_MSI) */ + int index; + /* IN or OUT */ + int pirq; + /* IN - high 16 bits hold segment for ..._MSI_SEG and ..._MULTI_MSI */ + int bus; + /* IN */ + int devfn; + /* IN (also OUT for ..._MULTI_MSI) */ + int entry_nr; + /* IN */ + uint64_t table_base; +}; +typedef struct physdev_map_pirq physdev_map_pirq_t; +DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t); + +#define PHYSDEVOP_unmap_pirq 14 +struct physdev_unmap_pirq { + domid_t domid; + /* IN */ + int pirq; +}; + +typedef struct physdev_unmap_pirq physdev_unmap_pirq_t; +DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t); + +#define PHYSDEVOP_manage_pci_add 15 +#define PHYSDEVOP_manage_pci_remove 16 +struct physdev_manage_pci { + /* IN */ + uint8_t bus; + uint8_t devfn; +}; + +typedef struct physdev_manage_pci physdev_manage_pci_t; +DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t); + +#define PHYSDEVOP_restore_msi 19 +struct physdev_restore_msi { + /* IN */ + uint8_t bus; + uint8_t devfn; +}; +typedef struct physdev_restore_msi physdev_restore_msi_t; +DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t); + +#define PHYSDEVOP_manage_pci_add_ext 20 +struct physdev_manage_pci_ext { + /* IN */ + uint8_t bus; + uint8_t devfn; + unsigned is_extfn; + unsigned is_virtfn; + struct { + uint8_t bus; + uint8_t devfn; + } physfn; +}; + +typedef struct physdev_manage_pci_ext physdev_manage_pci_ext_t; +DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_ext_t); + +/* + * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op= () + * hypercall since 0x00030202. + */ +struct physdev_op { + uint32_t cmd; + union { + physdev_irq_status_query_t irq_status_query; + physdev_set_iopl_t set_iopl; + physdev_set_iobitmap_t set_iobitmap; + physdev_apic_t apic_op; + physdev_irq_t irq_op; + } u; +}; +typedef struct physdev_op physdev_op_t; +DEFINE_XEN_GUEST_HANDLE(physdev_op_t); + +#define PHYSDEVOP_setup_gsi 21 +struct physdev_setup_gsi { + int gsi; + /* IN */ + uint8_t triggering; + /* IN */ + uint8_t polarity; + /* IN */ +}; + +typedef struct physdev_setup_gsi physdev_setup_gsi_t; +DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t); + +/* leave PHYSDEVOP 22 free */ + +/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI + * the hypercall returns a free pirq */ +#define PHYSDEVOP_get_free_pirq 23 +struct physdev_get_free_pirq { + /* IN */ + int type; + /* OUT */ + uint32_t pirq; +}; + +typedef struct physdev_get_free_pirq physdev_get_free_pirq_t; +DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t); + +#define XEN_PCI_MMCFG_RESERVED 0x1 + +#define PHYSDEVOP_pci_mmcfg_reserved 24 +struct physdev_pci_mmcfg_reserved { + uint64_t address; + uint16_t segment; + uint8_t start_bus; + uint8_t end_bus; + uint32_t flags; +}; +typedef struct physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved_t; +DEFINE_XEN_GUEST_HANDLE(physdev_pci_mmcfg_reserved_t); + +#define XEN_PCI_DEV_EXTFN 0x1 +#define XEN_PCI_DEV_VIRTFN 0x2 +#define XEN_PCI_DEV_PXM 0x4 + +#define PHYSDEVOP_pci_device_add 25 +struct physdev_pci_device_add { + /* IN */ + uint16_t seg; + uint8_t bus; + uint8_t devfn; + uint32_t flags; + struct { + uint8_t bus; + uint8_t devfn; + } physfn; + /* + * Optional parameters array. + * First element ([0]) is PXM domain associated with the device (if + * XEN_PCI_DEV_PXM is set) + */ + uint32_t optarr[XEN_FLEX_ARRAY_DIM]; +}; +typedef struct physdev_pci_device_add physdev_pci_device_add_t; +DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_add_t); + +#define PHYSDEVOP_pci_device_remove 26 +#define PHYSDEVOP_restore_msi_ext 27 +/* + * Dom0 should use these two to announce MMIO resources assigned to + * MSI-X capable devices won't (prepare) or may (release) change. + */ +#define PHYSDEVOP_prepare_msix 30 +#define PHYSDEVOP_release_msix 31 +struct physdev_pci_device { + /* IN */ + uint16_t seg; + uint8_t bus; + uint8_t devfn; +}; +typedef struct physdev_pci_device physdev_pci_device_t; +DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_t); + +#define PHYSDEVOP_DBGP_RESET_PREPARE 1 +#define PHYSDEVOP_DBGP_RESET_DONE 2 + +#define PHYSDEVOP_DBGP_BUS_UNKNOWN 0 +#define PHYSDEVOP_DBGP_BUS_PCI 1 + +#define PHYSDEVOP_dbgp_op 29 +struct physdev_dbgp_op { + /* IN */ + uint8_t op; + uint8_t bus; + union { + physdev_pci_device_t pci; + } u; +}; +typedef struct physdev_dbgp_op physdev_dbgp_op_t; +DEFINE_XEN_GUEST_HANDLE(physdev_dbgp_op_t); + +/* + * Notify that some PIRQ-bound event channels have been unmasked. + * ** This command is obsolete since interface version 0x00030202 and is ** + * ** unsupported by newer versions of Xen. ** + */ +#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4 + +#if __XEN_INTERFACE_VERSION__ < 0x00040600 +/* + * These all-capitals physdev operation names are superceded by the new na= mes + * (defined above) since interface version 0x00030202. The guard above was + * added post-4.5 only though and hence shouldn't check for 0x00030202. + */ +#define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query +#define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl +#define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap +#define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read +#define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write +#define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector +#define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector +#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi +#define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared +#endif + +#if __XEN_INTERFACE_VERSION__ < 0x00040200 +#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v1 +#else +#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v2 +#endif + +#endif /* __XEN_PUBLIC_PHYSDEV_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/sched.h b/include/standard-header= s/xen/sched.h new file mode 100644 index 0000000000..811bd87c82 --- /dev/null +++ b/include/standard-headers/xen/sched.h @@ -0,0 +1,202 @@ +/*************************************************************************= ***** + * sched.h + * + * Scheduler state interactions + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2005, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_SCHED_H__ +#define __XEN_PUBLIC_SCHED_H__ + +#include "event_channel.h" + +/* + * `incontents 150 sched Guest Scheduler Operations + * + * The SCHEDOP interface provides mechanisms for a guest to interact + * with the scheduler, including yield, blocking and shutting itself + * down. + */ + +/* + * The prototype for this hypercall is: + * ` long HYPERVISOR_sched_op(enum sched_op cmd, void *arg, ...) + * + * @cmd =3D=3D SCHEDOP_??? (scheduler operation). + * @arg =3D=3D Operation-specific extra argument(s), as described below. + * ... =3D=3D Additional Operation-specific extra arguments, described be= low. + * + * Versions of Xen prior to 3.0.2 provided only the following legacy versi= on + * of this hypercall, supporting only the commands yield, block and shutdo= wn: + * long sched_op(int cmd, unsigned long arg) + * @cmd =3D=3D SCHEDOP_??? (scheduler operation). + * @arg =3D=3D 0 (SCHEDOP_yield and SCHEDOP_block) + * =3D=3D SHUTDOWN_* code (SCHEDOP_shutdown) + * + * This legacy version is available to new guests as: + * ` long HYPERVISOR_sched_op_compat(enum sched_op cmd, unsigned long arg) + */ + +/* ` enum sched_op { // SCHEDOP_* =3D> struct sched_* */ +/* + * Voluntarily yield the CPU. + * @arg =3D=3D NULL. + */ +#define SCHEDOP_yield 0 + +/* + * Block execution of this VCPU until an event is received for processing. + * If called with event upcalls masked, this operation will atomically + * reenable event delivery and check for pending events before blocking the + * VCPU. This avoids a "wakeup waiting" race. + * @arg =3D=3D NULL. + */ +#define SCHEDOP_block 1 + +/* + * Halt execution of this domain (all VCPUs) and notify the system control= ler. + * @arg =3D=3D pointer to sched_shutdown_t structure. + * + * If the sched_shutdown_t reason is SHUTDOWN_suspend then + * x86 PV guests must also set RDX (EDX for 32-bit guests) to the MFN + * of the guest's start info page. RDX/EDX is the third hypercall + * argument. + * + * In addition, which reason is SHUTDOWN_suspend this hypercall + * returns 1 if suspend was cancelled or the domain was merely + * checkpointed, and 0 if it is resuming in a new domain. + */ +#define SCHEDOP_shutdown 2 + +/* + * Poll a set of event-channel ports. Return when one or more are pending.= An + * optional timeout may be specified. + * @arg =3D=3D pointer to sched_poll_t structure. + */ +#define SCHEDOP_poll 3 + +/* + * Declare a shutdown for another domain. The main use of this function is + * in interpreting shutdown requests and reasons for fully-virtualized + * domains. A para-virtualized domain may use SCHEDOP_shutdown directly. + * @arg =3D=3D pointer to sched_remote_shutdown_t structure. + */ +#define SCHEDOP_remote_shutdown 4 + +/* + * Latch a shutdown code, so that when the domain later shuts down it + * reports this code to the control tools. + * @arg =3D=3D sched_shutdown_t, as for SCHEDOP_shutdown. + */ +#define SCHEDOP_shutdown_code 5 + +/* + * Setup, poke and destroy a domain watchdog timer. + * @arg =3D=3D pointer to sched_watchdog_t structure. + * With id =3D=3D 0, setup a domain watchdog timer to cause domain shutdown + * after timeout, returns watchdog id. + * With id !=3D 0 and timeout =3D=3D 0, destroy domain watchdog timer. + * With id !=3D 0 and timeout !=3D 0, poke watchdog timer and set new time= out. + */ +#define SCHEDOP_watchdog 6 + +/* + * Override the current vcpu affinity by pinning it to one physical cpu or + * undo this override restoring the previous affinity. + * @arg =3D=3D pointer to sched_pin_override_t structure. + * + * A negative pcpu value will undo a previous pin override and restore the + * previous cpu affinity. + * This call is allowed for the hardware domain only and requires the cpu + * to be part of the domain's cpupool. + */ +#define SCHEDOP_pin_override 7 +/* ` } */ + +struct sched_shutdown { + unsigned int reason; /* SHUTDOWN_* =3D> enum sched_shutdown_reason */ +}; +typedef struct sched_shutdown sched_shutdown_t; +DEFINE_XEN_GUEST_HANDLE(sched_shutdown_t); + +struct sched_poll { + XEN_GUEST_HANDLE(evtchn_port_t) ports; + unsigned int nr_ports; + uint64_t timeout; +}; +typedef struct sched_poll sched_poll_t; +DEFINE_XEN_GUEST_HANDLE(sched_poll_t); + +struct sched_remote_shutdown { + domid_t domain_id; /* Remote domain ID */ + unsigned int reason; /* SHUTDOWN_* =3D> enum sched_shutdown_reas= on */ +}; +typedef struct sched_remote_shutdown sched_remote_shutdown_t; +DEFINE_XEN_GUEST_HANDLE(sched_remote_shutdown_t); + +struct sched_watchdog { + uint32_t id; /* watchdog ID */ + uint32_t timeout; /* timeout */ +}; +typedef struct sched_watchdog sched_watchdog_t; +DEFINE_XEN_GUEST_HANDLE(sched_watchdog_t); + +struct sched_pin_override { + int32_t pcpu; +}; +typedef struct sched_pin_override sched_pin_override_t; +DEFINE_XEN_GUEST_HANDLE(sched_pin_override_t); + +/* + * Reason codes for SCHEDOP_shutdown. These may be interpreted by control + * software to determine the appropriate action. For the most part, Xen do= es + * not care about the shutdown code. + */ +/* ` enum sched_shutdown_reason { */ +#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kil= l. */ +#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. = */ +#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. = */ +#define SHUTDOWN_crash 3 /* Tell controller we've crashed. = */ +#define SHUTDOWN_watchdog 4 /* Restart because watchdog time expired. = */ + +/* + * Domain asked to perform 'soft reset' for it. The expected behavior is to + * reset internal Xen state for the domain returning it to the point where= it + * was created but leaving the domain's memory contents and vCPU contexts + * intact. This will allow the domain to start over and set up all Xen spe= cific + * interfaces again. + */ +#define SHUTDOWN_soft_reset 5 +#define SHUTDOWN_MAX 5 /* Maximum valid shutdown reason. = */ +/* ` } */ + +#endif /* __XEN_PUBLIC_SCHED_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/trace.h b/include/standard-header= s/xen/trace.h new file mode 100644 index 0000000000..d5fa4aea8d --- /dev/null +++ b/include/standard-headers/xen/trace.h @@ -0,0 +1,341 @@ +/*************************************************************************= ***** + * include/public/trace.h + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Mark Williamson, (C) 2004 Intel Research Cambridge + * Copyright (C) 2005 Bin Ren + */ + +#ifndef __XEN_PUBLIC_TRACE_H__ +#define __XEN_PUBLIC_TRACE_H__ + +#define TRACE_EXTRA_MAX 7 +#define TRACE_EXTRA_SHIFT 28 + +/* Trace classes */ +#define TRC_CLS_SHIFT 16 +#define TRC_GEN 0x0001f000 /* General trace */ +#define TRC_SCHED 0x0002f000 /* Xen Scheduler trace */ +#define TRC_DOM0OP 0x0004f000 /* Xen DOM0 operation trace */ +#define TRC_HVM 0x0008f000 /* Xen HVM trace */ +#define TRC_MEM 0x0010f000 /* Xen memory trace */ +#define TRC_PV 0x0020f000 /* Xen PV traces */ +#define TRC_SHADOW 0x0040f000 /* Xen shadow tracing */ +#define TRC_HW 0x0080f000 /* Xen hardware-related traces */ +#define TRC_GUEST 0x0800f000 /* Guest-generated traces */ +#define TRC_ALL 0x0ffff000 +#define TRC_HD_TO_EVENT(x) ((x)&0x0fffffff) +#define TRC_HD_CYCLE_FLAG (1UL<<31) +#define TRC_HD_INCLUDES_CYCLE_COUNT(x) ( !!( (x) & TRC_HD_CYCLE_FLAG ) ) +#define TRC_HD_EXTRA(x) (((x)>>TRACE_EXTRA_SHIFT)&TRACE_EXTRA_MAX) + +/* Trace subclasses */ +#define TRC_SUBCLS_SHIFT 12 + +/* trace subclasses for SVM */ +#define TRC_HVM_ENTRYEXIT 0x00081000 /* VMENTRY and #VMEXIT */ +#define TRC_HVM_HANDLER 0x00082000 /* various HVM handlers */ +#define TRC_HVM_EMUL 0x00084000 /* emulated devices */ + +#define TRC_SCHED_MIN 0x00021000 /* Just runstate changes */ +#define TRC_SCHED_CLASS 0x00022000 /* Scheduler-specific */ +#define TRC_SCHED_VERBOSE 0x00028000 /* More inclusive scheduling */ + +/* + * The highest 3 bits of the last 12 bits of TRC_SCHED_CLASS above are + * reserved for encoding what scheduler produced the information. The + * actual event is encoded in the last 9 bits. + * + * This means we have 8 scheduling IDs available (which means at most 8 + * schedulers generating events) and, in each scheduler, up to 512 + * different events. + */ +#define TRC_SCHED_ID_BITS 3 +#define TRC_SCHED_ID_SHIFT (TRC_SUBCLS_SHIFT - TRC_SCHED_ID_BITS) +#define TRC_SCHED_ID_MASK (((1UL<cpu_offset[cpu]). + */ +struct t_info { + uint16_t tbuf_size; /* Size in pages of each trace buffer */ + uint16_t mfn_offset[]; /* Offset within t_info structure of the page = list per cpu */ + /* MFN lists immediately after the header */ +}; + +#endif /* __XEN_PUBLIC_TRACE_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/vcpu.h b/include/standard-headers= /xen/vcpu.h new file mode 100644 index 0000000000..3623af932f --- /dev/null +++ b/include/standard-headers/xen/vcpu.h @@ -0,0 +1,248 @@ +/*************************************************************************= ***** + * vcpu.h + * + * VCPU initialisation, query, and hotplug. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2005, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_VCPU_H__ +#define __XEN_PUBLIC_VCPU_H__ + +#include "xen.h" + +/* + * Prototype for this hypercall is: + * long vcpu_op(int cmd, unsigned int vcpuid, void *extra_args) + * @cmd =3D=3D VCPUOP_??? (VCPU operation). + * @vcpuid =3D=3D VCPU to operate on. + * @extra_args =3D=3D Operation-specific extra arguments (NULL if none). + */ + +/* + * Initialise a VCPU. Each VCPU can be initialised only once. A + * newly-initialised VCPU will not run until it is brought up by VCPUOP_up. + * + * @extra_arg =3D=3D For PV or ARM guests this is a pointer to a vcpu_gues= t_context + * structure containing the initial state for the VCPU. For = x86 + * HVM based guests this is a pointer to a vcpu_hvm_context + * structure. + */ +#define VCPUOP_initialise 0 + +/* + * Bring up a VCPU. This makes the VCPU runnable. This operation will fail + * if the VCPU has not been initialised (VCPUOP_initialise). + */ +#define VCPUOP_up 1 + +/* + * Bring down a VCPU (i.e., make it non-runnable). + * There are a few caveats that callers should observe: + * 1. This operation may return, and VCPU_is_up may return false, before = the + * VCPU stops running (i.e., the command is asynchronous). It is a good + * idea to ensure that the VCPU has entered a non-critical loop before + * bringing it down. Alternatively, this operation is guaranteed + * synchronous if invoked by the VCPU itself. + * 2. After a VCPU is initialised, there is currently no way to drop all = its + * references to domain memory. Even a VCPU that is down still holds + * memory references via its pagetable base pointer and GDT. It is good + * practise to move a VCPU onto an 'idle' or default page table, LDT a= nd + * GDT before bringing it down. + */ +#define VCPUOP_down 2 + +/* Returns 1 if the given VCPU is up. */ +#define VCPUOP_is_up 3 + +/* + * Return information about the state and running time of a VCPU. + * @extra_arg =3D=3D pointer to vcpu_runstate_info structure. + */ +#define VCPUOP_get_runstate_info 4 +struct vcpu_runstate_info { + /* VCPU's current state (RUNSTATE_*). */ + int state; + /* When was current state entered (system time, ns)? */ + uint64_t state_entry_time; + /* + * Update indicator set in state_entry_time: + * When activated via VMASST_TYPE_runstate_update_flag, set during + * updates in guest memory mapped copy of vcpu_runstate_info. + */ +#define XEN_RUNSTATE_UPDATE (xen_mk_ullong(1) << 63) + /* + * Time spent in each RUNSTATE_* (ns). The sum of these times is + * guaranteed not to drift from system time. + */ + uint64_t time[4]; +}; +typedef struct vcpu_runstate_info vcpu_runstate_info_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_t); + +/* VCPU is currently running on a physical CPU. */ +#define RUNSTATE_running 0 + +/* VCPU is runnable, but not currently scheduled on any physical CPU. */ +#define RUNSTATE_runnable 1 + +/* VCPU is blocked (a.k.a. idle). It is therefore not runnable. */ +#define RUNSTATE_blocked 2 + +/* + * VCPU is not runnable, but it is not blocked. + * This is a 'catch all' state for things like hotplug and pauses by the + * system administrator (or for critical sections in the hypervisor). + * RUNSTATE_blocked dominates this state (it is the preferred state). + */ +#define RUNSTATE_offline 3 + +/* + * Register a shared memory area from which the guest may obtain its own + * runstate information without needing to execute a hypercall. + * Notes: + * 1. The registered address may be virtual or physical or guest handle, + * depending on the platform. Virtual address or guest handle should be + * registered on x86 systems. + * 2. Only one shared area may be registered per VCPU. The shared area is + * updated by the hypervisor each time the VCPU is scheduled. Thus + * runstate.state will always be RUNSTATE_running and + * runstate.state_entry_time will indicate the system time at which the + * VCPU was last scheduled to run. + * @extra_arg =3D=3D pointer to vcpu_register_runstate_memory_area structu= re. + */ +#define VCPUOP_register_runstate_memory_area 5 +struct vcpu_register_runstate_memory_area { + union { + XEN_GUEST_HANDLE(vcpu_runstate_info_t) h; + struct vcpu_runstate_info *v; + uint64_t p; + } addr; +}; +typedef struct vcpu_register_runstate_memory_area vcpu_register_runstate_m= emory_area_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_register_runstate_memory_area_t); + +/* + * Set or stop a VCPU's periodic timer. Every VCPU has one periodic timer + * which can be set via these commands. Periods smaller than one milliseco= nd + * may not be supported. + */ +#define VCPUOP_set_periodic_timer 6 /* arg =3D=3D vcpu_set_periodic_tim= er_t */ +#define VCPUOP_stop_periodic_timer 7 /* arg =3D=3D NULL */ +struct vcpu_set_periodic_timer { + uint64_t period_ns; +}; +typedef struct vcpu_set_periodic_timer vcpu_set_periodic_timer_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_set_periodic_timer_t); + +/* + * Set or stop a VCPU's single-shot timer. Every VCPU has one single-shot + * timer which can be set via these commands. + */ +#define VCPUOP_set_singleshot_timer 8 /* arg =3D=3D vcpu_set_singleshot_t= imer_t */ +#define VCPUOP_stop_singleshot_timer 9 /* arg =3D=3D NULL */ +struct vcpu_set_singleshot_timer { + uint64_t timeout_abs_ns; /* Absolute system time value in nanosecond= s. */ + uint32_t flags; /* VCPU_SSHOTTMR_??? */ +}; +typedef struct vcpu_set_singleshot_timer vcpu_set_singleshot_timer_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_set_singleshot_timer_t); + +/* Flags to VCPUOP_set_singleshot_timer. */ + /* Require the timeout to be in the future (return -ETIME if it's passed)= . */ +#define _VCPU_SSHOTTMR_future (0) +#define VCPU_SSHOTTMR_future (1U << _VCPU_SSHOTTMR_future) + +/* + * Register a memory location in the guest address space for the + * vcpu_info structure. This allows the guest to place the vcpu_info + * structure in a convenient place, such as in a per-cpu data area. + * The pointer need not be page aligned, but the structure must not + * cross a page boundary. + * + * This may be called only once per vcpu. + */ +#define VCPUOP_register_vcpu_info 10 /* arg =3D=3D vcpu_register_vcpu_i= nfo_t */ +struct vcpu_register_vcpu_info { + uint64_t mfn; /* mfn of page to place vcpu_info */ + uint32_t offset; /* offset within page */ + uint32_t rsvd; /* unused */ +}; +typedef struct vcpu_register_vcpu_info vcpu_register_vcpu_info_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_register_vcpu_info_t); + +/* Send an NMI to the specified VCPU. @extra_arg =3D=3D NULL. */ +#define VCPUOP_send_nmi 11 + +/* + * Get the physical ID information for a pinned vcpu's underlying physical + * processor. The physical ID informmation is architecture-specific. + * On x86: id[31:0]=3Dapic_id, id[63:32]=3Dacpi_id. + * This command returns -EINVAL if it is not a valid operation for this VC= PU. + */ +#define VCPUOP_get_physid 12 /* arg =3D=3D vcpu_get_physid_t */ +struct vcpu_get_physid { + uint64_t phys_id; +}; +typedef struct vcpu_get_physid vcpu_get_physid_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_get_physid_t); +#define xen_vcpu_physid_to_x86_apicid(physid) ((uint32_t)(physid)) +#define xen_vcpu_physid_to_x86_acpiid(physid) ((uint32_t)((physid) >> 32)) + +/* + * Register a memory location to get a secondary copy of the vcpu time + * parameters. The master copy still exists as part of the vcpu shared + * memory area, and this secondary copy is updated whenever the master copy + * is updated (and using the same versioning scheme for synchronisation). + * + * The intent is that this copy may be mapped (RO) into userspace so + * that usermode can compute system time using the time info and the + * tsc. Usermode will see an array of vcpu_time_info structures, one + * for each vcpu, and choose the right one by an existing mechanism + * which allows it to get the current vcpu number (such as via a + * segment limit). It can then apply the normal algorithm to compute + * system time from the tsc. + * + * @extra_arg =3D=3D pointer to vcpu_register_time_info_memory_area struct= ure. + */ +#define VCPUOP_register_vcpu_time_memory_area 13 +DEFINE_XEN_GUEST_HANDLE(vcpu_time_info_t); +struct vcpu_register_time_memory_area { + union { + XEN_GUEST_HANDLE(vcpu_time_info_t) h; + struct vcpu_time_info *v; + uint64_t p; + } addr; +}; +typedef struct vcpu_register_time_memory_area vcpu_register_time_memory_ar= ea_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_register_time_memory_area_t); + +#endif /* __XEN_PUBLIC_VCPU_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/version.h b/include/standard-head= ers/xen/version.h new file mode 100644 index 0000000000..17a81e23cd --- /dev/null +++ b/include/standard-headers/xen/version.h @@ -0,0 +1,113 @@ +/*************************************************************************= ***** + * version.h + * + * Xen version, type, and compile information. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2005, Nguyen Anh Quynh + * Copyright (c) 2005, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_VERSION_H__ +#define __XEN_PUBLIC_VERSION_H__ + +#include "xen.h" + +/* NB. All ops return zero on success, except XENVER_{version,pagesize} + * XENVER_{version,pagesize,build_id} */ + +/* arg =3D=3D NULL; returns major:minor (16:16). */ +#define XENVER_version 0 + +/* arg =3D=3D xen_extraversion_t. */ +#define XENVER_extraversion 1 +typedef char xen_extraversion_t[16]; +#define XEN_EXTRAVERSION_LEN (sizeof(xen_extraversion_t)) + +/* arg =3D=3D xen_compile_info_t. */ +#define XENVER_compile_info 2 +struct xen_compile_info { + char compiler[64]; + char compile_by[16]; + char compile_domain[32]; + char compile_date[32]; +}; +typedef struct xen_compile_info xen_compile_info_t; + +#define XENVER_capabilities 3 +typedef char xen_capabilities_info_t[1024]; +#define XEN_CAPABILITIES_INFO_LEN (sizeof(xen_capabilities_info_t)) + +#define XENVER_changeset 4 +typedef char xen_changeset_info_t[64]; +#define XEN_CHANGESET_INFO_LEN (sizeof(xen_changeset_info_t)) + +#define XENVER_platform_parameters 5 +struct xen_platform_parameters { + xen_ulong_t virt_start; +}; +typedef struct xen_platform_parameters xen_platform_parameters_t; + +#define XENVER_get_features 6 +struct xen_feature_info { + unsigned int submap_idx; /* IN: which 32-bit submap to return */ + uint32_t submap; /* OUT: 32-bit submap */ +}; +typedef struct xen_feature_info xen_feature_info_t; + +/* Declares the features reported by XENVER_get_features. */ +#include "features.h" + +/* arg =3D=3D NULL; returns host memory page size. */ +#define XENVER_pagesize 7 + +/* arg =3D=3D xen_domain_handle_t. + * + * The toolstack fills it out for guest consumption. It is intended to hold + * the UUID of the guest. + */ +#define XENVER_guest_handle 8 + +#define XENVER_commandline 9 +typedef char xen_commandline_t[1024]; + +/* + * Return value is the number of bytes written, or XEN_Exx on error. + * Calling with empty parameter returns the size of build_id. + */ +#define XENVER_build_id 10 +struct xen_build_id { + uint32_t len; /* IN: size of buf[]. */ + unsigned char buf[XEN_FLEX_ARRAY_DIM]; + /* OUT: Variable length buffer with build_id.= */ +}; +typedef struct xen_build_id xen_build_id_t; + +#endif /* __XEN_PUBLIC_VERSION_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/standard-headers/xen/xen-compat.h b/include/standard-h= eaders/xen/xen-compat.h new file mode 100644 index 0000000000..e1c027a95c --- /dev/null +++ b/include/standard-headers/xen/xen-compat.h @@ -0,0 +1,46 @@ +/*************************************************************************= ***** + * xen-compat.h + * + * Guest OS interface to Xen. Compatibility layer. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2006, Christian Limpach + */ + +#ifndef __XEN_PUBLIC_XEN_COMPAT_H__ +#define __XEN_PUBLIC_XEN_COMPAT_H__ + +#define __XEN_LATEST_INTERFACE_VERSION__ 0x00040e00 + +#if defined(__XEN__) || defined(__XEN_TOOLS__) +/* Xen is built with matching headers and implements the latest interface.= */ +#define __XEN_INTERFACE_VERSION__ __XEN_LATEST_INTERFACE_VERSION__ +#elif !defined(__XEN_INTERFACE_VERSION__) +/* Guests which do not specify a version get the legacy interface. */ +#define __XEN_INTERFACE_VERSION__ 0x00000000 +#endif + +#if __XEN_INTERFACE_VERSION__ > __XEN_LATEST_INTERFACE_VERSION__ +#error "These header files do not support the requested interface version." +#endif + +#define COMPAT_FLEX_ARRAY_DIM XEN_FLEX_ARRAY_DIM + +#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */ diff --git a/include/standard-headers/xen/xen.h b/include/standard-headers/= xen/xen.h new file mode 100644 index 0000000000..e373592c33 --- /dev/null +++ b/include/standard-headers/xen/xen.h @@ -0,0 +1,1049 @@ +/*************************************************************************= ***** + * xen.h + * + * Guest OS interface to Xen. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation = the + * rights to use, copy, modify, merge, publish, distribute, sublicense, an= d/or + * sell copies of the Software, and to permit persons to whom the Software= is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2004, K A Fraser + */ + +#ifndef __XEN_PUBLIC_XEN_H__ +#define __XEN_PUBLIC_XEN_H__ + +#include "xen-compat.h" + +#if defined(__i386__) || defined(__x86_64__) +#include "arch-x86/xen.h" +#elif defined(__arm__) || defined (__aarch64__) +#include "arch-arm.h" +#else +#error "Unsupported architecture" +#endif + +#ifndef __ASSEMBLY__ +/* Guest handles for primitive C types. */ +DEFINE_XEN_GUEST_HANDLE(char); +__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); +DEFINE_XEN_GUEST_HANDLE(int); +__DEFINE_XEN_GUEST_HANDLE(uint, unsigned int); +#if __XEN_INTERFACE_VERSION__ < 0x00040300 +DEFINE_XEN_GUEST_HANDLE(long); +__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long); +#endif +DEFINE_XEN_GUEST_HANDLE(void); + +DEFINE_XEN_GUEST_HANDLE(uint64_t); +DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); +DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); + +/* Define a variable length array (depends on compiler). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >=3D 199901L +#define XEN_FLEX_ARRAY_DIM +#elif defined(__GNUC__) +#define XEN_FLEX_ARRAY_DIM 0 +#else +#define XEN_FLEX_ARRAY_DIM 1 /* variable size */ +#endif + +/* Turn a plain number into a C unsigned (long (long)) constant. */ +#define __xen_mk_uint(x) x ## U +#define __xen_mk_ulong(x) x ## UL +#ifndef __xen_mk_ullong +# define __xen_mk_ullong(x) x ## ULL +#endif +#define xen_mk_uint(x) __xen_mk_uint(x) +#define xen_mk_ulong(x) __xen_mk_ulong(x) +#define xen_mk_ullong(x) __xen_mk_ullong(x) + +#else + +/* In assembly code we cannot use C numeric constant suffixes. */ +#define xen_mk_uint(x) x +#define xen_mk_ulong(x) x +#define xen_mk_ullong(x) x + +#endif + +/* + * HYPERCALLS + */ + +/* `incontents 100 hcalls List of hypercalls + * ` enum hypercall_num { // __HYPERVISOR_* =3D> HYPERVISOR_*() + */ + +#define __HYPERVISOR_set_trap_table 0 +#define __HYPERVISOR_mmu_update 1 +#define __HYPERVISOR_set_gdt 2 +#define __HYPERVISOR_stack_switch 3 +#define __HYPERVISOR_set_callbacks 4 +#define __HYPERVISOR_fpu_taskswitch 5 +#define __HYPERVISOR_sched_op_compat 6 /* compat since 0x00030101 */ +#define __HYPERVISOR_platform_op 7 +#define __HYPERVISOR_set_debugreg 8 +#define __HYPERVISOR_get_debugreg 9 +#define __HYPERVISOR_update_descriptor 10 +#define __HYPERVISOR_memory_op 12 +#define __HYPERVISOR_multicall 13 +#define __HYPERVISOR_update_va_mapping 14 +#define __HYPERVISOR_set_timer_op 15 +#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202= */ +#define __HYPERVISOR_xen_version 17 +#define __HYPERVISOR_console_io 18 +#define __HYPERVISOR_physdev_op_compat 19 /* compat since 0x00030202 */ +#define __HYPERVISOR_grant_table_op 20 +#define __HYPERVISOR_vm_assist 21 +#define __HYPERVISOR_update_va_mapping_otherdomain 22 +#define __HYPERVISOR_iret 23 /* x86 only */ +#define __HYPERVISOR_vcpu_op 24 +#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */ +#define __HYPERVISOR_mmuext_op 26 +#define __HYPERVISOR_xsm_op 27 +#define __HYPERVISOR_nmi_op 28 +#define __HYPERVISOR_sched_op 29 +#define __HYPERVISOR_callback_op 30 +#define __HYPERVISOR_xenoprof_op 31 +#define __HYPERVISOR_event_channel_op 32 +#define __HYPERVISOR_physdev_op 33 +#define __HYPERVISOR_hvm_op 34 +#define __HYPERVISOR_sysctl 35 +#define __HYPERVISOR_domctl 36 +#define __HYPERVISOR_kexec_op 37 +#define __HYPERVISOR_tmem_op 38 +#define __HYPERVISOR_argo_op 39 +#define __HYPERVISOR_xenpmu_op 40 +#define __HYPERVISOR_dm_op 41 +#define __HYPERVISOR_hypfs_op 42 + +/* Architecture-specific hypercall definitions. */ +#define __HYPERVISOR_arch_0 48 +#define __HYPERVISOR_arch_1 49 +#define __HYPERVISOR_arch_2 50 +#define __HYPERVISOR_arch_3 51 +#define __HYPERVISOR_arch_4 52 +#define __HYPERVISOR_arch_5 53 +#define __HYPERVISOR_arch_6 54 +#define __HYPERVISOR_arch_7 55 + +/* ` } */ + +/* + * HYPERCALL COMPATIBILITY. + */ + +/* New sched_op hypercall introduced in 0x00030101. */ +#if __XEN_INTERFACE_VERSION__ < 0x00030101 +#undef __HYPERVISOR_sched_op +#define __HYPERVISOR_sched_op __HYPERVISOR_sched_op_compat +#endif + +/* New event-channel and physdev hypercalls introduced in 0x00030202. */ +#if __XEN_INTERFACE_VERSION__ < 0x00030202 +#undef __HYPERVISOR_event_channel_op +#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat +#undef __HYPERVISOR_physdev_op +#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat +#endif + +/* New platform_op hypercall introduced in 0x00030204. */ +#if __XEN_INTERFACE_VERSION__ < 0x00030204 +#define __HYPERVISOR_dom0_op __HYPERVISOR_platform_op +#endif + +/* + * VIRTUAL INTERRUPTS + * + * Virtual interrupts that a guest OS may receive from Xen. + * + * In the side comments, 'V.' denotes a per-VCPU VIRQ while 'G.' denotes a + * global VIRQ. The former can be bound once per VCPU and cannot be re-bou= nd. + * The latter can be allocated only once per guest: they must initially be + * allocated to VCPU0 but can subsequently be re-bound. + */ +/* ` enum virq { */ +#define VIRQ_TIMER 0 /* V. Timebase update, and/or requested timeout= . */ +#define VIRQ_DEBUG 1 /* V. Request guest to dump debug info. = */ +#define VIRQ_CONSOLE 2 /* G. (DOM0) Bytes received on emergency consol= e. */ +#define VIRQ_DOM_EXC 3 /* G. (DOM0) Exceptional event for some domain.= */ +#define VIRQ_TBUF 4 /* G. (DOM0) Trace buffer has records available= . */ +#define VIRQ_DEBUGGER 6 /* G. (DOM0) A domain has paused for debugging.= */ +#define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample availab= le */ +#define VIRQ_CON_RING 8 /* G. (DOM0) Bytes received on console = */ +#define VIRQ_PCPU_STATE 9 /* G. (DOM0) PCPU state changed = */ +#define VIRQ_MEM_EVENT 10 /* G. (DOM0) A memory event has occurred = */ +#define VIRQ_ARGO 11 /* G. Argo interdomain message notification = */ +#define VIRQ_ENOMEM 12 /* G. (DOM0) Low on heap memory */ +#define VIRQ_XENPMU 13 /* V. PMC interrupt = */ + +/* Architecture-specific VIRQ definitions. */ +#define VIRQ_ARCH_0 16 +#define VIRQ_ARCH_1 17 +#define VIRQ_ARCH_2 18 +#define VIRQ_ARCH_3 19 +#define VIRQ_ARCH_4 20 +#define VIRQ_ARCH_5 21 +#define VIRQ_ARCH_6 22 +#define VIRQ_ARCH_7 23 +/* ` } */ + +#define NR_VIRQS 24 + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_mmu_update(const struct mmu_update reqs[], + * ` unsigned count, unsigned *done_out, + * ` unsigned foreigndom) + * ` + * @reqs is an array of mmu_update_t structures ((ptr, val) pairs). + * @count is the length of the above array. + * @pdone is an output parameter indicating number of completed operations + * @foreigndom[15:0]: FD, the expected owner of data pages referenced in t= his + * hypercall invocation. Can be DOMID_SELF. + * @foreigndom[31:16]: PFD, the expected owner of pagetable pages referenc= ed + * in this hypercall invocation. The value of this fie= ld + * (x) encodes the PFD as follows: + * x =3D=3D 0 =3D> PFD =3D=3D DOMID_SELF + * x !=3D 0 =3D> PFD =3D=3D x - 1 + * + * Sub-commands: ptr[1:0] specifies the appropriate MMU_* command. + * ------------- + * ptr[1:0] =3D=3D MMU_NORMAL_PT_UPDATE: + * Updates an entry in a page table belonging to PFD. If updating an L1 ta= ble, + * and the new table entry is valid/present, the mapped frame must belong = to + * FD. If attempting to map an I/O page then the caller assumes the privil= ege + * of the FD. + * FD =3D=3D DOMID_IO: Permit /only/ I/O mappings, at the priv level of th= e caller. + * FD =3D=3D DOMID_XEN: Map restricted areas of Xen's heap space. + * ptr[:2] -- Machine address of the page-table entry to modify. + * val -- Value to write. + * + * There also certain implicit requirements when using this hypercall. The + * pages that make up a pagetable must be mapped read-only in the guest. + * This prevents uncontrolled guest updates to the pagetable. Xen strictly + * enforces this, and will disallow any pagetable update which will end up + * mapping pagetable page RW, and will disallow using any writable page as= a + * pagetable. In practice it means that when constructing a page table for= a + * process, thread, etc, we MUST be very dilligient in following these rul= es: + * 1). Start with top-level page (PGD or in Xen language: L4). Fill out + * the entries. + * 2). Keep on going, filling out the upper (PUD or L3), and middle (PMD + * or L2). + * 3). Start filling out the PTE table (L1) with the PTE entries. Once + * done, make sure to set each of those entries to RO (so writeable bit + * is unset). Once that has been completed, set the PMD (L2) for this + * PTE table as RO. + * 4). When completed with all of the PMD (L2) entries, and all of them h= ave + * been set to RO, make sure to set RO the PUD (L3). Do the same + * operation on PGD (L4) pagetable entries that have a PUD (L3) entry. + * 5). Now before you can use those pages (so setting the cr3), you MUST = also + * pin them so that the hypervisor can verify the entries. This is do= ne + * via the HYPERVISOR_mmuext_op(MMUEXT_PIN_L4_TABLE, guest physical f= rame + * number of the PGD (L4)). And this point the HYPERVISOR_mmuext_op( + * MMUEXT_NEW_BASEPTR, guest physical frame number of the PGD (L4)) c= an be + * issued. + * For 32-bit guests, the L4 is not used (as there is less pagetables), so + * instead use L3. + * At this point the pagetables can be modified using the MMU_NORMAL_PT_UP= DATE + * hypercall. Also if so desired the OS can also try to write to the PTE + * and be trapped by the hypervisor (as the PTE entry is RO). + * + * To deallocate the pages, the operations are the reverse of the steps + * mentioned above. The argument is MMUEXT_UNPIN_TABLE for all levels and = the + * pagetable MUST not be in use (meaning that the cr3 is not set to it). + * + * ptr[1:0] =3D=3D MMU_MACHPHYS_UPDATE: + * Updates an entry in the machine->pseudo-physical mapping table. + * ptr[:2] -- Machine address within the frame whose mapping to modify. + * The frame must belong to the FD, if one is specified. + * val -- Value to write into the mapping entry. + * + * ptr[1:0] =3D=3D MMU_PT_UPDATE_PRESERVE_AD: + * As MMU_NORMAL_PT_UPDATE above, but A/D bits currently in the PTE are OR= ed + * with those in @val. + * + * ptr[1:0] =3D=3D MMU_PT_UPDATE_NO_TRANSLATE: + * As MMU_NORMAL_PT_UPDATE above, but @val is not translated though FD + * page tables. + * + * @val is usually the machine frame number along with some attributes. + * The attributes by default follow the architecture defined bits. Meaning= that + * if this is a X86_64 machine and four page table layout is used, the lay= out + * of val is: + * - 63 if set means No execute (NX) + * - 46-13 the machine frame number + * - 12 available for guest + * - 11 available for guest + * - 10 available for guest + * - 9 available for guest + * - 8 global + * - 7 PAT (PSE is disabled, must use hypercall to make 4MB or 2MB pages) + * - 6 dirty + * - 5 accessed + * - 4 page cached disabled + * - 3 page write through + * - 2 userspace accessible + * - 1 writeable + * - 0 present + * + * The one bits that does not fit with the default layout is the PAGE_PSE + * also called PAGE_PAT). The MMUEXT_[UN]MARK_SUPER arguments to the + * HYPERVISOR_mmuext_op serve as mechanism to set a pagetable to be 4MB + * (or 2MB) instead of using the PAGE_PSE bit. + * + * The reason that the PAGE_PSE (bit 7) is not being utilized is due to X= en + * using it as the Page Attribute Table (PAT) bit - for details on it ple= ase + * refer to Intel SDM 10.12. The PAT allows to set the caching attributes= of + * pages instead of using MTRRs. + * + * The PAT MSR is as follows (it is a 64-bit value, each entry is 8 bits): + * PAT4 PAT0 + * +-----+-----+----+----+----+-----+----+----+ + * | UC | UC- | WC | WB | UC | UC- | WC | WB | <=3D Linux + * +-----+-----+----+----+----+-----+----+----+ + * | UC | UC- | WT | WB | UC | UC- | WT | WB | <=3D BIOS (default when = machine boots) + * +-----+-----+----+----+----+-----+----+----+ + * | rsv | rsv | WP | WC | UC | UC- | WT | WB | <=3D Xen + * +-----+-----+----+----+----+-----+----+----+ + * + * The lookup of this index table translates to looking up + * Bit 7, Bit 4, and Bit 3 of val entry: + * + * PAT/PSE (bit 7) ... PCD (bit 4) .. PWT (bit 3). + * + * If all bits are off, then we are using PAT0. If bit 3 turned on, + * then we are using PAT1, if bit 3 and bit 4, then PAT2.. + * + * As you can see, the Linux PAT1 translates to PAT4 under Xen. Which mea= ns + * that if a guest that follows Linux's PAT setup and would like to set W= rite + * Combined on pages it MUST use PAT4 entry. Meaning that Bit 7 (PAGE_PAT= ) is + * set. For example, under Linux it only uses PAT0, PAT1, and PAT2 for the + * caching as: + * + * WB =3D none (so PAT0) + * WC =3D PWT (bit 3 on) + * UC =3D PWT | PCD (bit 3 and 4 are on). + * + * To make it work with Xen, it needs to translate the WC bit as so: + * + * PWT (so bit 3 on) --> PAT (so bit 7 is on) and clear bit 3 + * + * And to translate back it would: + * + * PAT (bit 7 on) --> PWT (bit 3 on) and clear bit 7. + */ +#define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr =3D val'. ptr is MA.= */ +#define MMU_MACHPHYS_UPDATE 1 /* ptr =3D MA of frame to modify entr= y for */ +#define MMU_PT_UPDATE_PRESERVE_AD 2 /* atomically: *ptr =3D val | (*ptr&(= A|D)) */ +#define MMU_PT_UPDATE_NO_TRANSLATE 3 /* checked '*ptr =3D val'. ptr is MA.= */ + /* val never translated. = */ + +/* + * MMU EXTENDED OPERATIONS + * + * ` enum neg_errnoval + * ` HYPERVISOR_mmuext_op(mmuext_op_t uops[], + * ` unsigned int count, + * ` unsigned int *pdone, + * ` unsigned int foreigndom) + */ +/* HYPERVISOR_mmuext_op() accepts a list of mmuext_op structures. + * A foreigndom (FD) can be specified (or DOMID_SELF for none). + * Where the FD has some effect, it is described below. + * + * cmd: MMUEXT_(UN)PIN_*_TABLE + * mfn: Machine frame number to be (un)pinned as a p.t. page. + * The frame must belong to the FD, if one is specified. + * + * cmd: MMUEXT_NEW_BASEPTR + * mfn: Machine frame number of new page-table base to install in MMU. + * + * cmd: MMUEXT_NEW_USER_BASEPTR [x86/64 only] + * mfn: Machine frame number of new page-table base to install in MMU + * when in user space. + * + * cmd: MMUEXT_TLB_FLUSH_LOCAL + * No additional arguments. Flushes local TLB. + * + * cmd: MMUEXT_INVLPG_LOCAL + * linear_addr: Linear address to be flushed from the local TLB. + * + * cmd: MMUEXT_TLB_FLUSH_MULTI + * vcpumask: Pointer to bitmap of VCPUs to be flushed. + * + * cmd: MMUEXT_INVLPG_MULTI + * linear_addr: Linear address to be flushed. + * vcpumask: Pointer to bitmap of VCPUs to be flushed. + * + * cmd: MMUEXT_TLB_FLUSH_ALL + * No additional arguments. Flushes all VCPUs' TLBs. + * + * cmd: MMUEXT_INVLPG_ALL + * linear_addr: Linear address to be flushed from all VCPUs' TLBs. + * + * cmd: MMUEXT_FLUSH_CACHE + * No additional arguments. Writes back and flushes cache contents. + * + * cmd: MMUEXT_FLUSH_CACHE_GLOBAL + * No additional arguments. Writes back and flushes cache contents + * on all CPUs in the system. + * + * cmd: MMUEXT_SET_LDT + * linear_addr: Linear address of LDT base (NB. must be page-aligned). + * nr_ents: Number of entries in LDT. + * + * cmd: MMUEXT_CLEAR_PAGE + * mfn: Machine frame number to be cleared. + * + * cmd: MMUEXT_COPY_PAGE + * mfn: Machine frame number of the destination page. + * src_mfn: Machine frame number of the source page. + * + * cmd: MMUEXT_[UN]MARK_SUPER + * mfn: Machine frame number of head of superpage to be [un]marked. + */ +/* ` enum mmuext_cmd { */ +#define MMUEXT_PIN_L1_TABLE 0 +#define MMUEXT_PIN_L2_TABLE 1 +#define MMUEXT_PIN_L3_TABLE 2 +#define MMUEXT_PIN_L4_TABLE 3 +#define MMUEXT_UNPIN_TABLE 4 +#define MMUEXT_NEW_BASEPTR 5 +#define MMUEXT_TLB_FLUSH_LOCAL 6 +#define MMUEXT_INVLPG_LOCAL 7 +#define MMUEXT_TLB_FLUSH_MULTI 8 +#define MMUEXT_INVLPG_MULTI 9 +#define MMUEXT_TLB_FLUSH_ALL 10 +#define MMUEXT_INVLPG_ALL 11 +#define MMUEXT_FLUSH_CACHE 12 +#define MMUEXT_SET_LDT 13 +#define MMUEXT_NEW_USER_BASEPTR 15 +#define MMUEXT_CLEAR_PAGE 16 +#define MMUEXT_COPY_PAGE 17 +#define MMUEXT_FLUSH_CACHE_GLOBAL 18 +#define MMUEXT_MARK_SUPER 19 +#define MMUEXT_UNMARK_SUPER 20 +/* ` } */ + +#ifndef __ASSEMBLY__ +struct mmuext_op { + unsigned int cmd; /* =3D> enum mmuext_cmd */ + union { + /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR + * CLEAR_PAGE, COPY_PAGE, [UN]MARK_SUPER */ + xen_pfn_t mfn; + /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */ + unsigned long linear_addr; + } arg1; + union { + /* SET_LDT */ + unsigned int nr_ents; + /* TLB_FLUSH_MULTI, INVLPG_MULTI */ +#if __XEN_INTERFACE_VERSION__ >=3D 0x00030205 + XEN_GUEST_HANDLE(const_void) vcpumask; +#else + const void *vcpumask; +#endif + /* COPY_PAGE */ + xen_pfn_t src_mfn; + } arg2; +}; +typedef struct mmuext_op mmuext_op_t; +DEFINE_XEN_GUEST_HANDLE(mmuext_op_t); +#endif + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_update_va_mapping(unsigned long va, u64 val, + * ` enum uvm_flags flags) + * ` + * ` enum neg_errnoval + * ` HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, u64 val, + * ` enum uvm_flags flags, + * ` domid_t domid) + * ` + * ` @va: The virtual address whose mapping we want to change + * ` @val: The new page table entry, must contain a machine address + * ` @flags: Control TLB flushes + */ +/* These are passed as 'flags' to update_va_mapping. They can be ORed. */ +/* When specifying UVMF_MULTI, also OR in a pointer to a CPU bitmap. */ +/* UVMF_LOCAL is merely UVMF_MULTI with a NULL bitmap pointer. */ +/* ` enum uvm_flags { */ +#define UVMF_NONE (xen_mk_ulong(0)<<0) /* No flushing at all. = */ +#define UVMF_TLB_FLUSH (xen_mk_ulong(1)<<0) /* Flush entire TLB(s). = */ +#define UVMF_INVLPG (xen_mk_ulong(2)<<0) /* Flush only one entry. = */ +#define UVMF_FLUSHTYPE_MASK (xen_mk_ulong(3)<<0) +#define UVMF_MULTI (xen_mk_ulong(0)<<2) /* Flush subset of TLBs. = */ +#define UVMF_LOCAL (xen_mk_ulong(0)<<2) /* Flush local TLB. = */ +#define UVMF_ALL (xen_mk_ulong(1)<<2) /* Flush all TLBs. = */ +/* ` } */ + +/* + * ` int + * ` HYPERVISOR_console_io(unsigned int cmd, + * ` unsigned int count, + * ` char buffer[]); + * + * @cmd: Command (see below) + * @count: Size of the buffer to read/write + * @buffer: Pointer in the guest memory + * + * List of commands: + * + * * CONSOLEIO_write: Write the buffer to Xen console. + * For the hardware domain, all the characters in the buffer will + * be written. Characters will be printed directly to the console. + * For all the other domains, only the printable characters will be + * written. Characters may be buffered until a newline (i.e '\n') is + * found. + * @return 0 on success, otherwise return an error code. + * * CONSOLEIO_read: Attempts to read up to @count characters from Xen + * console. The maximum buffer size (i.e. @count) supported is 2GB. + * @return the number of characters read on success, otherwise return + * an error code. + */ +#define CONSOLEIO_write 0 +#define CONSOLEIO_read 1 + +/* + * Commands to HYPERVISOR_vm_assist(). + */ +#define VMASST_CMD_enable 0 +#define VMASST_CMD_disable 1 + +/* x86/32 guests: simulate full 4GB segment limits. */ +#define VMASST_TYPE_4gb_segments 0 + +/* x86/32 guests: trap (vector 15) whenever above vmassist is used. */ +#define VMASST_TYPE_4gb_segments_notify 1 + +/* + * x86 guests: support writes to bottom-level PTEs. + * NB1. Page-directory entries cannot be written. + * NB2. Guest must continue to remove all writable mappings of PTEs. + */ +#define VMASST_TYPE_writable_pagetables 2 + +/* x86/PAE guests: support PDPTs above 4GB. */ +#define VMASST_TYPE_pae_extended_cr3 3 + +/* + * x86 guests: Sane behaviour for virtual iopl + * - virtual iopl updated from do_iret() hypercalls. + * - virtual iopl reported in bounce frames. + * - guest kernels assumed to be level 0 for the purpose of iopl checks. + */ +#define VMASST_TYPE_architectural_iopl 4 + +/* + * All guests: activate update indicator in vcpu_runstate_info + * Enable setting the XEN_RUNSTATE_UPDATE flag in guest memory mapped + * vcpu_runstate_info during updates of the runstate information. + */ +#define VMASST_TYPE_runstate_update_flag 5 + +/* + * x86/64 guests: strictly hide M2P from user mode. + * This allows the guest to control respective hypervisor behavior: + * - when not set, L4 tables get created with the respective slot blank, + * and whenever the L4 table gets used as a kernel one the missing + * mapping gets inserted, + * - when set, L4 tables get created with the respective slot initialized + * as before, and whenever the L4 table gets used as a user one the + * mapping gets zapped. + */ +#define VMASST_TYPE_m2p_strict 32 + +#if __XEN_INTERFACE_VERSION__ < 0x00040600 +#define MAX_VMASST_TYPE 3 +#endif + +/* Domain ids >=3D DOMID_FIRST_RESERVED cannot be used for ordinary domain= s. */ +#define DOMID_FIRST_RESERVED xen_mk_uint(0x7FF0) + +/* DOMID_SELF is used in certain contexts to refer to oneself. */ +#define DOMID_SELF xen_mk_uint(0x7FF0) + +/* + * DOMID_IO is used to restrict page-table updates to mapping I/O memory. + * Although no Foreign Domain need be specified to map I/O pages, DOMID_IO + * is useful to ensure that no mappings to the OS's own heap are accidenta= lly + * installed. (e.g., in Linux this could cause havoc as reference counts + * aren't adjusted on the I/O-mapping code path). + * This only makes sense as HYPERVISOR_mmu_update()'s and + * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument. For + * HYPERVISOR_mmu_update() context it can be specified by any calling doma= in, + * otherwise it's only permitted if the caller is privileged. + */ +#define DOMID_IO xen_mk_uint(0x7FF1) + +/* + * DOMID_XEN is used to allow privileged domains to map restricted parts of + * Xen's heap space (e.g., the machine_to_phys table). + * This only makes sense as + * - HYPERVISOR_mmu_update()'s, HYPERVISOR_mmuext_op()'s, or + * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument, + * - with XENMAPSPACE_gmfn_foreign, + * and is only permitted if the caller is privileged. + */ +#define DOMID_XEN xen_mk_uint(0x7FF2) + +/* + * DOMID_COW is used as the owner of sharable pages */ +#define DOMID_COW xen_mk_uint(0x7FF3) + +/* DOMID_INVALID is used to identify pages with unknown owner. */ +#define DOMID_INVALID xen_mk_uint(0x7FF4) + +/* Idle domain. */ +#define DOMID_IDLE xen_mk_uint(0x7FFF) + +/* Mask for valid domain id values */ +#define DOMID_MASK xen_mk_uint(0x7FFF) + +#ifndef __ASSEMBLY__ + +typedef uint16_t domid_t; + +/* + * Send an array of these to HYPERVISOR_mmu_update(). + * NB. The fields are natural pointer/address size for this architecture. + */ +struct mmu_update { + uint64_t ptr; /* Machine address of PTE. */ + uint64_t val; /* New contents of PTE. */ +}; +typedef struct mmu_update mmu_update_t; +DEFINE_XEN_GUEST_HANDLE(mmu_update_t); + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_multicall(multicall_entry_t call_list[], + * ` uint32_t nr_calls); + * + * NB. The fields are logically the natural register size for this + * architecture. In cases where xen_ulong_t is larger than this then + * any unused bits in the upper portion must be zero. + */ +struct multicall_entry { + xen_ulong_t op, result; + xen_ulong_t args[6]; +}; +typedef struct multicall_entry multicall_entry_t; +DEFINE_XEN_GUEST_HANDLE(multicall_entry_t); + +#if __XEN_INTERFACE_VERSION__ < 0x00040400 +/* + * Event channel endpoints per domain (when using the 2-level ABI): + * 1024 if a long is 32 bits; 4096 if a long is 64 bits. + */ +#define NR_EVENT_CHANNELS EVTCHN_2L_NR_CHANNELS +#endif + +struct vcpu_time_info { + /* + * Updates to the following values are preceded and followed by an + * increment of 'version'. The guest can therefore detect updates by + * looking for changes to 'version'. If the least-significant bit of + * the version number is set then an update is in progress and the gue= st + * must wait to read a consistent set of values. + * The correct way to interact with the version number is similar to + * Linux's seqlock: see the implementations of read_seqbegin/read_seqr= etry. + */ + uint32_t version; + uint32_t pad0; + uint64_t tsc_timestamp; /* TSC at last update of time vals. */ + uint64_t system_time; /* Time, in nanosecs, since boot. */ + /* + * Current system time: + * system_time + + * ((((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul) >> 32) + * CPU frequency (Hz): + * ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift + */ + uint32_t tsc_to_system_mul; + int8_t tsc_shift; +#if __XEN_INTERFACE_VERSION__ > 0x040600 + uint8_t flags; + uint8_t pad1[2]; +#else + int8_t pad1[3]; +#endif +}; /* 32 bytes */ +typedef struct vcpu_time_info vcpu_time_info_t; + +#define XEN_PVCLOCK_TSC_STABLE_BIT (1 << 0) +#define XEN_PVCLOCK_GUEST_STOPPED (1 << 1) + +struct vcpu_info { + /* + * 'evtchn_upcall_pending' is written non-zero by Xen to indicate + * a pending notification for a particular VCPU. It is then cleared + * by the guest OS /before/ checking for pending work, thus avoiding + * a set-and-check race. Note that the mask is only accessed by Xen + * on the CPU that is currently hosting the VCPU. This means that the + * pending and mask flags can be updated by the guest without special + * synchronisation (i.e., no need for the x86 LOCK prefix). + * This may seem suboptimal because if the pending flag is set by + * a different CPU then an IPI may be scheduled even when the mask + * is set. However, note: + * 1. The task of 'interrupt holdoff' is covered by the per-event- + * channel mask bits. A 'noisy' event that is continually being + * triggered can be masked at source at this very precise + * granularity. + * 2. The main purpose of the per-VCPU mask is therefore to restrict + * reentrant execution: whether for concurrency control, or to + * prevent unbounded stack usage. Whatever the purpose, we expect + * that the mask will be asserted only for short periods at a time, + * and so the likelihood of a 'spurious' IPI is suitably small. + * The mask is read before making an event upcall to the guest: a + * non-zero mask therefore guarantees that the VCPU will not receive + * an upcall activation. The mask is cleared when the VCPU requests + * to block: this avoids wakeup-waiting races. + */ + uint8_t evtchn_upcall_pending; +#ifdef XEN_HAVE_PV_UPCALL_MASK + uint8_t evtchn_upcall_mask; +#else /* XEN_HAVE_PV_UPCALL_MASK */ + uint8_t pad0; +#endif /* XEN_HAVE_PV_UPCALL_MASK */ + xen_ulong_t evtchn_pending_sel; + struct arch_vcpu_info arch; + vcpu_time_info_t time; +}; /* 64 bytes (x86) */ +#ifndef __XEN__ +typedef struct vcpu_info vcpu_info_t; +#endif + +/* + * `incontents 200 startofday_shared Start-of-day shared data structure + * Xen/kernel shared data -- pointer provided in start_info. + * + * This structure is defined to be both smaller than a page, and the + * only data on the shared page, but may vary in actual size even within + * compatible Xen versions; guests should not rely on the size + * of this structure remaining constant. + */ +struct shared_info { + struct vcpu_info vcpu_info[XEN_LEGACY_MAX_VCPUS]; + + /* + * A domain can create "event channels" on which it can send and recei= ve + * asynchronous event notifications. There are three classes of event = that + * are delivered by this mechanism: + * 1. Bi-directional inter- and intra-domain connections. Domains must + * arrange out-of-band to set up a connection (usually by allocati= ng + * an unbound 'listener' port and avertising that via a storage se= rvice + * such as xenstore). + * 2. Physical interrupts. A domain with suitable hardware-access + * privileges can bind an event-channel port to a physical interru= pt + * source. + * 3. Virtual interrupts ('events'). A domain can bind an event-chann= el + * port to a virtual interrupt source, such as the virtual-timer + * device or the emergency console. + * + * Event channels are addressed by a "port index". Each channel is + * associated with two bits of information: + * 1. PENDING -- notifies the domain that there is a pending notifica= tion + * to be processed. This bit is cleared by the guest. + * 2. MASK -- if this bit is clear then a 0->1 transition of PENDING + * will cause an asynchronous upcall to be scheduled. This bit is = only + * updated by the guest. It is read-only within Xen. If a channel + * becomes pending while the channel is masked then the 'edge' is = lost + * (i.e., when the channel is unmasked, the guest must manually ha= ndle + * pending notifications as no upcall will be scheduled by Xen). + * + * To expedite scanning of pending notifications, any 0->1 pending + * transition on an unmasked channel causes a corresponding bit in a + * per-vcpu selector word to be set. Each bit in the selector covers a + * 'C long' in the PENDING bitfield array. + */ + xen_ulong_t evtchn_pending[sizeof(xen_ulong_t) * 8]; + xen_ulong_t evtchn_mask[sizeof(xen_ulong_t) * 8]; + + /* + * Wallclock time: updated by control software or RTC emulation. + * Guests should base their gettimeofday() syscall on this + * wallclock-base value. + * The values of wc_sec and wc_nsec are offsets from the Unix epoch + * adjusted by the domain's 'time offset' (in seconds) as set either + * by XEN_DOMCTL_settimeoffset, or adjusted via a guest write to the + * emulated RTC. + */ + uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */ + uint32_t wc_sec; + uint32_t wc_nsec; +#if !defined(__i386__) + uint32_t wc_sec_hi; +# define xen_wc_sec_hi wc_sec_hi +#elif !defined(__XEN__) && !defined(__XEN_TOOLS__) +# define xen_wc_sec_hi arch.wc_sec_hi +#endif + + struct arch_shared_info arch; + +}; +#ifndef __XEN__ +typedef struct shared_info shared_info_t; +#endif + +/* + * `incontents 200 startofday Start-of-day memory layout + * + * 1. The domain is started within contiguous virtual-memory region. + * 2. The contiguous region ends on an aligned 4MB boundary. + * 3. This the order of bootstrap elements in the initial virtual region: + * a. relocated kernel image + * b. initial ram disk [mod_start, mod_len] + * (may be omitted) + * c. list of allocated page frames [mfn_list, nr_pages] + * (unless relocated due to XEN_ELFNOTE_INIT_P2M) + * d. start_info_t structure [register rSI (x86)] + * in case of dom0 this page contains the console info, too + * e. unless dom0: xenstore ring page + * f. unless dom0: console ring page + * g. bootstrap page tables [pt_base and CR3 (x86)] + * h. bootstrap stack [register ESP (x86)] + * 4. Bootstrap elements are packed together, but each is 4kB-aligned. + * 5. The list of page frames forms a contiguous 'pseudo-physical' memory + * layout for the domain. In particular, the bootstrap virtual-memory + * region is a 1:1 mapping to the first section of the pseudo-physical= map. + * 6. All bootstrap elements are mapped read-writable for the guest OS. T= he + * only exception is the bootstrap page table, which is mapped read-on= ly. + * 7. There is guaranteed to be at least 512kB padding after the final + * bootstrap element. If necessary, the bootstrap virtual region is + * extended by an extra 4MB to ensure this. + * + * Note: Prior to 25833:bb85bbccb1c9. ("x86/32-on-64 adjust Dom0 initial p= age + * table layout") a bug caused the pt_base (3.g above) and cr3 to not point + * to the start of the guest page tables (it was offset by two pages). + * This only manifested itself on 32-on-64 dom0 kernels and not 32-on-64 d= omU + * or 64-bit kernels of any colour. The page tables for a 32-on-64 dom0 got + * allocated in the order: 'first L1','first L2', 'first L3', so the offset + * to the page table base is by two pages back. The initial domain if it is + * 32-bit and runs under a 64-bit hypervisor should _NOT_ use two of the + * pages preceding pt_base and mark them as reserved/unused. + */ +#ifdef XEN_HAVE_PV_GUEST_ENTRY +struct start_info { + /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. = */ + char magic[32]; /* "xen--". = */ + unsigned long nr_pages; /* Total pages allocated to this domain. = */ + unsigned long shared_info; /* MACHINE address of shared info struct. = */ + uint32_t flags; /* SIF_xxx flags. = */ + xen_pfn_t store_mfn; /* MACHINE page number of shared page. = */ + uint32_t store_evtchn; /* Event channel for store communication. = */ + union { + struct { + xen_pfn_t mfn; /* MACHINE page number of console page. = */ + uint32_t evtchn; /* Event channel for console page. = */ + } domU; + struct { + uint32_t info_off; /* Offset of console_info struct. = */ + uint32_t info_size; /* Size of console_info struct from start.= */ + } dom0; + } console; + /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). = */ + unsigned long pt_base; /* VIRTUAL address of page directory. = */ + unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames. = */ + unsigned long mfn_list; /* VIRTUAL address of page-frame list. = */ + unsigned long mod_start; /* VIRTUAL address of pre-loaded module = */ + /* (PFN of pre-loaded module if = */ + /* SIF_MOD_START_PFN set in flags). = */ + unsigned long mod_len; /* Size (bytes) of pre-loaded module. = */ +#define MAX_GUEST_CMDLINE 1024 + int8_t cmd_line[MAX_GUEST_CMDLINE]; + /* The pfn range here covers both page table and p->m table frames. = */ + unsigned long first_p2m_pfn;/* 1st pfn forming initial P->M table. = */ + unsigned long nr_p2m_frames;/* # of pfns forming initial P->M table. = */ +}; +typedef struct start_info start_info_t; + +/* New console union for dom0 introduced in 0x00030203. */ +#if __XEN_INTERFACE_VERSION__ < 0x00030203 +#define console_mfn console.domU.mfn +#define console_evtchn console.domU.evtchn +#endif +#endif /* XEN_HAVE_PV_GUEST_ENTRY */ + +/* These flags are passed in the 'flags' field of start_info_t. */ +#define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */ +#define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */ +#define SIF_MULTIBOOT_MOD (1<<2) /* Is mod_start a multiboot module? */ +#define SIF_MOD_START_PFN (1<<3) /* Is mod_start a PFN? */ +#define SIF_VIRT_P2M_4TOOLS (1<<4) /* Do Xen tools understand a virt. mapp= ed */ + /* P->M making the 3 level tree obsolet= e? */ +#define SIF_PM_MASK (0xFF<<8) /* reserve 1 byte for xen-pm options */ + +/* + * A multiboot module is a package containing modules very similar to a + * multiboot module array. The only differences are: + * - the array of module descriptors is by convention simply at the beginn= ing + * of the multiboot module, + * - addresses in the module descriptors are based on the beginning of the + * multiboot module, + * - the number of modules is determined by a termination descriptor that = has + * mod_start =3D=3D 0. + * + * This permits to both build it statically and reference it in a configur= ation + * file, and let the PV guest easily rebase the addresses to virtual addre= sses + * and at the same time count the number of modules. + */ +struct xen_multiboot_mod_list +{ + /* Address of first byte of the module */ + uint32_t mod_start; + /* Address of last byte of the module (inclusive) */ + uint32_t mod_end; + /* Address of zero-terminated command line */ + uint32_t cmdline; + /* Unused, must be zero */ + uint32_t pad; +}; +/* + * `incontents 200 startofday_dom0_console Dom0_console + * + * The console structure in start_info.console.dom0 + * + * This structure includes a variety of information required to + * have a working VGA/VESA console. + */ +typedef struct dom0_vga_console_info { + uint8_t video_type; /* DOM0_VGA_CONSOLE_??? */ +#define XEN_VGATYPE_TEXT_MODE_3 0x03 +#define XEN_VGATYPE_VESA_LFB 0x23 +#define XEN_VGATYPE_EFI_LFB 0x70 + + union { + struct { + /* Font height, in pixels. */ + uint16_t font_height; + /* Cursor location (column, row). */ + uint16_t cursor_x, cursor_y; + /* Number of rows and columns (dimensions in characters). */ + uint16_t rows, columns; + } text_mode_3; + + struct { + /* Width and height, in pixels. */ + uint16_t width, height; + /* Bytes per scan line. */ + uint16_t bytes_per_line; + /* Bits per pixel. */ + uint16_t bits_per_pixel; + /* LFB physical address, and size (in units of 64kB). */ + uint32_t lfb_base; + uint32_t lfb_size; + /* RGB mask offsets and sizes, as defined by VBE 1.2+ */ + uint8_t red_pos, red_size; + uint8_t green_pos, green_size; + uint8_t blue_pos, blue_size; + uint8_t rsvd_pos, rsvd_size; +#if __XEN_INTERFACE_VERSION__ >=3D 0x00030206 + /* VESA capabilities (offset 0xa, VESA command 0x4f00). */ + uint32_t gbl_caps; + /* Mode attributes (offset 0x0, VESA command 0x4f01). */ + uint16_t mode_attrs; + uint16_t pad; +#endif +#if __XEN_INTERFACE_VERSION__ >=3D 0x00040d00 + /* high 32 bits of lfb_base */ + uint32_t ext_lfb_base; +#endif + } vesa_lfb; + } u; +} dom0_vga_console_info_t; +#define xen_vga_console_info dom0_vga_console_info +#define xen_vga_console_info_t dom0_vga_console_info_t + +typedef uint8_t xen_domain_handle_t[16]; + +__DEFINE_XEN_GUEST_HANDLE(uint8, uint8_t); +__DEFINE_XEN_GUEST_HANDLE(uint16, uint16_t); +__DEFINE_XEN_GUEST_HANDLE(uint32, uint32_t); +__DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t); + +typedef struct { + uint8_t a[16]; +} xen_uuid_t; + +/* + * XEN_DEFINE_UUID(0x00112233, 0x4455, 0x6677, 0x8899, + * 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff) + * will construct UUID 00112233-4455-6677-8899-aabbccddeeff presented as + * {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, + * 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + * + * NB: This is compatible with Linux kernel and with libuuid, but it is not + * compatible with Microsoft, as they use mixed-endian encoding (some + * components are little-endian, some are big-endian). + */ +#define XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6) \ + {{((a) >> 24) & 0xFF, ((a) >> 16) & 0xFF, \ + ((a) >> 8) & 0xFF, ((a) >> 0) & 0xFF, \ + ((b) >> 8) & 0xFF, ((b) >> 0) & 0xFF, \ + ((c) >> 8) & 0xFF, ((c) >> 0) & 0xFF, \ + ((d) >> 8) & 0xFF, ((d) >> 0) & 0xFF, \ + e1, e2, e3, e4, e5, e6}} + +#if defined(__STDC_VERSION__) ? __STDC_VERSION__ >=3D 199901L : defined(__= GNUC__) +#define XEN_DEFINE_UUID(a, b, c, d, e1, e2, e3, e4, e5, e6) \ + ((xen_uuid_t)XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6)) +#else +#define XEN_DEFINE_UUID(a, b, c, d, e1, e2, e3, e4, e5, e6) \ + XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6) +#endif /* __STDC_VERSION__ / __GNUC__ */ + +#endif /* !__ASSEMBLY__ */ + +/* Default definitions for macros used by domctl/sysctl. */ +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +#ifndef int64_aligned_t +#define int64_aligned_t int64_t +#endif +#ifndef uint64_aligned_t +#define uint64_aligned_t uint64_t +#endif +#ifndef XEN_GUEST_HANDLE_64 +#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name) +#endif + +#ifndef __ASSEMBLY__ +struct xenctl_bitmap { + XEN_GUEST_HANDLE_64(uint8) bitmap; + uint32_t nr_bits; +}; +typedef struct xenctl_bitmap xenctl_bitmap_t; +#endif + +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ + +#endif /* __XEN_PUBLIC_XEN_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151582129442.8690837036455; Thu, 15 Dec 2022 16:46:22 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynp-0005Sm-Ep; Thu, 15 Dec 2022 19:42:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynH-0005Fi-QM for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:45 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0006bO-Mf for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:43 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV5-7U; Fri, 16 Dec 2022 00:41:36 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOB-Lz; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=XV6ezbcy4KDF/NBVfOcOo5swXlZMSxd05Z6YrPxEygw=; b=eOgz8ZP6sKnoPjpX0QtfOZTQ8O plSvEYmBuBaYN+irIMXMMomPaEpGyOXj4dozRML51Ry0x8DvCUdjDIwsWgJqTcjpivVveuz9eYjjD xRmTqUyxR07TQ5UAekhJifqUmaa5ApqdneRHG8t3rDf16nBdG8LA4d09F80bZJZsCAkEXimQig8n+ vPsCNMS19eXoBPreLLlyWQkfFi2RURdgnxBbvZ6+ebRcQ0lFtiyzocquzQqIti9lO+CPh1l8QyvTA JoiW/u6XQ3x8lh/c4FfEFshm4W/AOZ1UnnSRBJ3TEWCwd7dP2M4HzWeNsapp+k3YDknEK8a0le+89 hD2GgF+g==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 02/38] xen: add CONFIG_XENFV_MACHINE and CONFIG_XEN_EMU options for Xen emulation Date: Fri, 16 Dec 2022 00:40:41 +0000 Message-Id: <20221216004117.862106-3-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151582588100001 Content-Type: text/plain; charset="utf-8" From: David Woodhouse The XEN_EMU option will cover core Xen support in target/, which exists only for x86 with KVM today but could theoretically also be implemented on Arm/Aarch64 and with TCG or other accelerators. It will also cover the support for architecture-independent grant table and event channel support which will be added in hw/i386/kvm/ (on the basis that the non-KVM support is very theoretical and making it not use KVM directly seems like gratuitous overengineering at this point). The XENFV_MACHINE option is for the xenfv platform support, which will now be used both by XEN_EMU and by real Xen. The XEN option remains dependent on the Xen runtime libraries, and covers support for real Xen. Some code which currently resides under CONFIG_XEN will be moving to CONFIG_XENFV_MACHINE over time. Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- hw/Kconfig | 1 + hw/i386/Kconfig | 5 +++++ hw/xen/Kconfig | 3 +++ meson.build | 1 + 4 files changed, 10 insertions(+) create mode 100644 hw/xen/Kconfig diff --git a/hw/Kconfig b/hw/Kconfig index 38233bbb0f..ba62ff6417 100644 --- a/hw/Kconfig +++ b/hw/Kconfig @@ -41,6 +41,7 @@ source tpm/Kconfig source usb/Kconfig source virtio/Kconfig source vfio/Kconfig +source xen/Kconfig source watchdog/Kconfig =20 # arch Kconfig diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index d22ac4a4b9..c9fd577997 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -137,3 +137,8 @@ config VMPORT config VMMOUSE bool depends on VMPORT + +config XEN_EMU + bool + default y + depends on KVM && (I386 || X86_64) diff --git a/hw/xen/Kconfig b/hw/xen/Kconfig new file mode 100644 index 0000000000..755c8b1faf --- /dev/null +++ b/hw/xen/Kconfig @@ -0,0 +1,3 @@ +config XENFV_MACHINE + bool + default y if (XEN || XEN_EMU) diff --git a/meson.build b/meson.build index 5c6b5a1c75..9348cf572c 100644 --- a/meson.build +++ b/meson.build @@ -3828,6 +3828,7 @@ if have_system if xen.found() summary_info +=3D {'xen ctrl version': xen.version()} endif + summary_info +=3D {'Xen emulation': config_all.has_key('CONFIG_XEN_E= MU')} endif summary_info +=3D {'TCG support': config_all.has_key('CONFIG_TCG')} if config_all.has_key('CONFIG_TCG') --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151619492714.9400885822105; Thu, 15 Dec 2022 16:46:59 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynj-0005SM-8F; Thu, 15 Dec 2022 19:42:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0005Dl-CQ for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006aN-5n for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:38 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV4-7U; Fri, 16 Dec 2022 00:41:34 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOE-Mh; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=xrCGpMsmPqcCvSEu1E/dWqCyDDejxgMyqrmnLObBC88=; b=vQlj9cD2a92QpyxmmSaPHMBR1M WnQjdaYz85ev52gM9/A164xnx9QqnBnMoW9n7kGwh3UqFo5B+8czyzfPX4fxMpPyDyi1Aw/W+YjGB 8sMEThJy2gpoAJaznJqSuSrmqdmmfEOHTdSHMMBJIYKC3/ub5Nf5uKT03ioLJ+ebcgMXmof3AU9EX Bo7Zth5BlkxQyy9zuNEKWRtzq1AicIBcUVUvD+TgkaqE9MZXWxGwlxTMP5g6U2scn896e9C0XCf0N +LlBuG2OXkASWlCBKDapDHdoANaR+L4oZV+a7kU9pS4NqYkZt7ZRCANORN5ahrdPdsy+N5KTtZ2gK bM75kqug==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 03/38] xen: Add XEN_DISABLED mode and make it default Date: Fri, 16 Dec 2022 00:40:42 +0000 Message-Id: <20221216004117.862106-4-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151621413100001 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Also check for XEN_ATTACH mode in xen_init() Suggested-by: Paolo Bonzini Signed-off-by: David Woodhouse --- accel/xen/xen-all.c | 4 ++++ include/hw/xen/xen.h | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/accel/xen/xen-all.c b/accel/xen/xen-all.c index 69aa7d018b..109d2e84bc 100644 --- a/accel/xen/xen-all.c +++ b/accel/xen/xen-all.c @@ -158,6 +158,10 @@ static int xen_init(MachineState *ms) { MachineClass *mc =3D MACHINE_GET_CLASS(ms); =20 + if (xen_mode !=3D XEN_ATTACH) { + xen_pv_printf(NULL, 0, "xen requires --xen-attach mode\n"); + return -1; + } xen_xc =3D xc_interface_open(0, 0, 0); if (xen_xc =3D=3D NULL) { xen_pv_printf(NULL, 0, "can't open xen interface\n"); diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index afdf9c436a..82347e76a4 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -12,8 +12,9 @@ =20 /* xen-machine.c */ enum xen_mode { - XEN_EMULATE =3D 0, // xen emulation, using xenner (default) - XEN_ATTACH // attach to xen domain created by libxl + XEN_DISABLED =3D 0, // xen support disabled (default) + XEN_ATTACH, // attach to xen domain created by libxl + XEN_EMULATE, }; =20 extern uint32_t xen_domid; --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152149245952.2205700625755; Thu, 15 Dec 2022 16:55:49 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynx-0005Xa-7W; Thu, 15 Dec 2022 19:42:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynG-0005FX-5I for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:44 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006c4-5G for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymx-00Azyr-9j; Fri, 16 Dec 2022 00:41:25 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOH-NH; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=3uj0sHhewUulHImG4eR8T4o0qONJhSfW74GT3Efs6EI=; b=EnQQAhLtNYY6bn2GDGOUb4aK8U 04GrM9pQIPVVH5MWHabDrNFNz5vUwTiTuMy6Xw/+ZaS404AMOdBwQAFbLFf8653c1ltrn7AgmIscR 9tagy0caEGlRJvsLZkeQ3zNyu3UQnIuPM6dgWVM6n9tg8sOkjJZcW4Qz9CHRmMwGjlr93DNjFpuha ILA9/BKx5O9AU9m69gAU0UmZJzOIujCGZuXKZ7gHMmjT74s6P/cQTwhq0TLPDfQtdVtIroYlMEpnc rWi3XubRT8NuOEYj6Y5DLx1YOSMXNdaHpexe1W93CrQscXKtN1eeoyp8LlsCnU8n6xr9BWO7J4Y71 9xxjPAuQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 04/38] i386/kvm: Add xen-version machine property and init KVM Xen support Date: Fri, 16 Dec 2022 00:40:43 +0000 Message-Id: <20221216004117.862106-5-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152150561100003 From: David Woodhouse This just initializes the basic Xen support in KVM for now. Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- accel/kvm/kvm-all.c | 1 + include/sysemu/kvm_int.h | 1 + target/i386/kvm/kvm.c | 53 +++++++++++++++++++++++++++++++++++++ target/i386/kvm/meson.build | 2 ++ target/i386/kvm/xen-emu.c | 50 ++++++++++++++++++++++++++++++++++ target/i386/kvm/xen-emu.h | 19 +++++++++++++ 6 files changed, 126 insertions(+) create mode 100644 target/i386/kvm/xen-emu.c create mode 100644 target/i386/kvm/xen-emu.h diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index f99b0becd8..568bb09c09 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -3620,6 +3620,7 @@ static void kvm_accel_instance_init(Object *obj) s->kvm_dirty_ring_size =3D 0; s->notify_vmexit =3D NOTIFY_VMEXIT_OPTION_RUN; s->notify_window =3D 0; + s->xen_version =3D 0; } =20 /** diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h index 3b4adcdc10..429cecbd04 100644 --- a/include/sysemu/kvm_int.h +++ b/include/sysemu/kvm_int.h @@ -110,6 +110,7 @@ struct KVMState struct KVMDirtyRingReaper reaper; NotifyVmexitOption notify_vmexit; uint32_t notify_window; + uint32_t xen_version; }; =20 void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml, diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index a213209379..a98995d4d7 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -31,6 +31,7 @@ #include "sysemu/runstate.h" #include "kvm_i386.h" #include "sev.h" +#include "xen-emu.h" #include "hyperv.h" #include "hyperv-proto.h" =20 @@ -48,6 +49,8 @@ #include "hw/i386/x86-iommu.h" #include "hw/i386/e820_memory_layout.h" =20 +#include "hw/xen/xen.h" + #include "hw/pci/pci.h" #include "hw/pci/msi.h" #include "hw/pci/msix.h" @@ -2513,6 +2516,18 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } } =20 + if (s->xen_version) { +#ifdef CONFIG_XEN_EMU + ret =3D kvm_xen_init(s); + if (ret < 0) { + return ret; + } +#else + error_report("kvm: Xen support not enabled in qemu"); + return -ENOTSUP; +#endif + } + ret =3D kvm_get_supported_msrs(s); if (ret < 0) { return ret; @@ -5706,6 +5721,35 @@ static void kvm_arch_set_notify_window(Object *obj, = Visitor *v, s->notify_window =3D value; } =20 +static void kvm_arch_get_xen_version(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + KVMState *s =3D KVM_STATE(obj); + uint32_t value =3D s->xen_version; + + visit_type_uint32(v, name, &value, errp); +} + +static void kvm_arch_set_xen_version(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + KVMState *s =3D KVM_STATE(obj); + Error *error =3D NULL; + uint32_t value; + + visit_type_uint32(v, name, &value, &error); + if (error) { + error_propagate(errp, error); + return; + } + + s->xen_version =3D value; + if (value && xen_mode =3D=3D XEN_DISABLED) + xen_mode =3D XEN_EMULATE; +} + void kvm_arch_accel_class_init(ObjectClass *oc) { object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOptio= n", @@ -5722,6 +5766,15 @@ void kvm_arch_accel_class_init(ObjectClass *oc) object_class_property_set_description(oc, "notify-window", "Clock cycles without an event w= indow " "after which a notification VM e= xit occurs"); + + object_class_property_add(oc, "xen-version", "uint32", + kvm_arch_get_xen_version, + kvm_arch_set_xen_version, + NULL, NULL); + object_class_property_set_description(oc, "xen-version", + "Xen version to be emulated " + "(in XENVER_version form " + "e.g. 0x4000a for 4.10)"); } =20 void kvm_set_max_apic_id(uint32_t max_apic_id) diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build index 736df8b72e..322272091b 100644 --- a/target/i386/kvm/meson.build +++ b/target/i386/kvm/meson.build @@ -7,6 +7,8 @@ i386_softmmu_kvm_ss.add(files( 'kvm-cpu.c', )) =20 +i386_softmmu_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen-emu.c'= )) + i386_softmmu_kvm_ss.add(when: 'CONFIG_SEV', if_false: files('sev-stub.c')) =20 i386_softmmu_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_= false: files('hyperv-stub.c')) diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c new file mode 100644 index 0000000000..4bd2eeeb5a --- /dev/null +++ b/target/i386/kvm/xen-emu.c @@ -0,0 +1,50 @@ +/* + * Xen HVM emulation support in KVM + * + * Copyright =C2=A9 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "sysemu/kvm_int.h" +#include "kvm/kvm_i386.h" +#include "xen-emu.h" + +int kvm_xen_init(KVMState *s) +{ + const int required_caps =3D KVM_XEN_HVM_CONFIG_HYPERCALL_MSR | + KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL | KVM_XEN_HVM_CONFIG_SHARED_INF= O; + struct kvm_xen_hvm_config cfg =3D { + .msr =3D XEN_HYPERCALL_MSR, + .flags =3D KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL, + }; + int xen_caps, ret; + + xen_caps =3D kvm_check_extension(s, KVM_CAP_XEN_HVM); + if (required_caps & ~xen_caps) { + error_report("kvm: Xen HVM guest support not present or insufficie= nt"); + return -ENOSYS; + } + + if (xen_caps & KVM_XEN_HVM_CONFIG_EVTCHN_SEND) { + struct kvm_xen_hvm_attr ha =3D { + .type =3D KVM_XEN_ATTR_TYPE_XEN_VERSION, + .u.xen_version =3D s->xen_version, + }; + (void)kvm_vm_ioctl(s, KVM_XEN_HVM_SET_ATTR, &ha); + + cfg.flags |=3D KVM_XEN_HVM_CONFIG_EVTCHN_SEND; + } + + ret =3D kvm_vm_ioctl(s, KVM_XEN_HVM_CONFIG, &cfg); + if (ret < 0) { + error_report("kvm: Failed to enable Xen HVM support: %s", strerror= (-ret)); + return ret; + } + + return 0; +} diff --git a/target/i386/kvm/xen-emu.h b/target/i386/kvm/xen-emu.h new file mode 100644 index 0000000000..4f31bd96cb --- /dev/null +++ b/target/i386/kvm/xen-emu.h @@ -0,0 +1,19 @@ +/* + * Xen HVM emulation support in KVM + * + * Copyright =C2=A9 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_I386_KVM_XEN_EMU_H +#define QEMU_I386_KVM_XEN_EMU_H + +#define XEN_HYPERCALL_MSR 0x40000000 + +int kvm_xen_init(KVMState *s); + +#endif /* QEMU_I386_KVM_XEN_EMU_H */ --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 167115188093597.24553722148778; Thu, 15 Dec 2022 16:51:20 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yop-00071s-4N; Thu, 15 Dec 2022 19:43:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynu-0005XM-Nx for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:22 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yns-0006ot-HT for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:22 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymx-00Azyq-9l; Fri, 16 Dec 2022 00:42:13 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOK-OG; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=qE9WJmHsb5IZzpUJRqNMD1JFO985Hct/DBHwQ/XnyPs=; b=ao+GK2OymDyofJ+ppC5xJted8W jrJjXuQjmCHvYevolf/PhrnoZj08qH1nYPsD8EWGZ5JskZj9T0FQ97q3W4U7xdwPoY4+Mi98RA3Ax rFtrPwHJAz0pq2EvqLm69The8P9vVvEHvW17Nk941vHwxVxZQJn3h8Xltbtx67qlMLW9wSzC3ILh2 F3LMOfM2rJ7KsBJ+pr5tcC3QCFbqEYTT7KNerRt91qCLtH1diu143AIh4cyJjFXjOiZj3RMMNl+ZG L5Xu2p4QO94PH760ZQRAnpShUrqOSKFQ65pa5eneDDU+VY8YZ/JI3P2gT9FdygvobYSBTPWOIck7l ee8c4eZQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 05/38] i386/kvm: handle Xen HVM cpuid leaves Date: Fri, 16 Dec 2022 00:40:44 +0000 Message-Id: <20221216004117.862106-6-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151882801100007 Content-Type: text/plain; charset="utf-8" From: Joao Martins Introduce support for emulating CPUID for Xen HVM guests. It doesn't make sense to advertise the KVM leaves to a Xen guest, so do it unconditionally when the xen-version machine property is set. Signed-off-by: Joao Martins [dwmw2: Obtain xen_version from machine property, make it automatic] Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- target/i386/cpu.c | 1 + target/i386/cpu.h | 2 + target/i386/kvm/kvm.c | 78 +++++++++++++++++++++++++++++++++++++-- target/i386/kvm/xen-emu.c | 4 +- target/i386/kvm/xen-emu.h | 13 ++++++- 5 files changed, 91 insertions(+), 7 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 22b681ca37..50aa95f134 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -7069,6 +7069,7 @@ static Property x86_cpu_properties[] =3D { * own cache information (see x86_cpu_load_def()). */ DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, true), + DEFINE_PROP_BOOL("xen-vapic", X86CPU, xen_vapic, false), =20 /* * From "Requirements for Implementing the Microsoft diff --git a/target/i386/cpu.h b/target/i386/cpu.h index d4bc19577a..c6c57baed5 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1964,6 +1964,8 @@ struct ArchCPU { int32_t thread_id; =20 int32_t hv_max_vps; + + bool xen_vapic; }; =20 =20 diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index a98995d4d7..5977edb1ca 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -22,6 +22,7 @@ =20 #include #include "standard-headers/asm-x86/kvm_para.h" +#include "standard-headers/xen/arch-x86/cpuid.h" =20 #include "cpu.h" #include "host-cpu.h" @@ -1750,7 +1751,6 @@ int kvm_arch_init_vcpu(CPUState *cs) int max_nested_state_len; int r; Error *local_err =3D NULL; - memset(&cpuid_data, 0, sizeof(cpuid_data)); =20 cpuid_i =3D 0; @@ -1802,7 +1802,77 @@ int kvm_arch_init_vcpu(CPUState *cs) has_msr_hv_hypercall =3D true; } =20 - if (cpu->expose_kvm) { + if (cs->kvm_state->xen_version) { +#ifdef CONFIG_XEN_EMU + struct kvm_cpuid_entry2 *xen_max_leaf; + + memcpy(signature, "XenVMMXenVMM", 12); + + xen_max_leaf =3D c =3D &cpuid_data.entries[cpuid_i++]; + c->function =3D kvm_base + XEN_CPUID_SIGNATURE; + c->eax =3D kvm_base + XEN_CPUID_TIME; + c->ebx =3D signature[0]; + c->ecx =3D signature[1]; + c->edx =3D signature[2]; + + c =3D &cpuid_data.entries[cpuid_i++]; + c->function =3D kvm_base + XEN_CPUID_VENDOR; + c->eax =3D cs->kvm_state->xen_version; + c->ebx =3D 0; + c->ecx =3D 0; + c->edx =3D 0; + + c =3D &cpuid_data.entries[cpuid_i++]; + c->function =3D kvm_base + XEN_CPUID_HVM_MSR; + /* Number of hypercall-transfer pages */ + c->eax =3D 1; + /* Hypercall MSR base address */ + if (hyperv_enabled(cpu)) { + c->ebx =3D XEN_HYPERCALL_MSR_HYPERV; + kvm_xen_init(cs->kvm_state, c->ebx); + } else { + c->ebx =3D XEN_HYPERCALL_MSR; + } + c->ecx =3D 0; + c->edx =3D 0; + + c =3D &cpuid_data.entries[cpuid_i++]; + c->function =3D kvm_base + XEN_CPUID_TIME; + c->eax =3D ((!!tsc_is_stable_and_known(env) << 1) | + (!!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_RDTSCP) << = 2)); + /* default=3D0 (emulate if necessary) */ + c->ebx =3D 0; + /* guest tsc frequency */ + c->ecx =3D env->user_tsc_khz; + /* guest tsc incarnation (migration count) */ + c->edx =3D 0; + + c =3D &cpuid_data.entries[cpuid_i++]; + c->function =3D kvm_base + XEN_CPUID_HVM; + xen_max_leaf->eax =3D kvm_base + XEN_CPUID_HVM; + if (cs->kvm_state->xen_version >=3D XEN_VERSION(4,5)) { + c->function =3D kvm_base + XEN_CPUID_HVM; + + if (cpu->xen_vapic) { + c->eax |=3D XEN_HVM_CPUID_APIC_ACCESS_VIRT; + c->eax |=3D XEN_HVM_CPUID_X2APIC_VIRT; + } + + c->eax |=3D XEN_HVM_CPUID_IOMMU_MAPPINGS; + + if (cs->kvm_state->xen_version >=3D XEN_VERSION(4,6)) { + c->eax |=3D XEN_HVM_CPUID_VCPU_ID_PRESENT; + c->ebx =3D cs->cpu_index; + } + } + + kvm_base +=3D 0x100; +#else /* CONFIG_XEN_EMU */ + /* This should never happen as kvm_arch_init() would have died fir= st. */ + fprintf(stderr, "Cannot enable Xen CPUID without Xen support\n"); + abort(); +#endif + } else if (cpu->expose_kvm) { memcpy(signature, "KVMKVMKVM\0\0\0", 12); c =3D &cpuid_data.entries[cpuid_i++]; c->function =3D KVM_CPUID_SIGNATURE | kvm_base; @@ -2518,7 +2588,9 @@ int kvm_arch_init(MachineState *ms, KVMState *s) =20 if (s->xen_version) { #ifdef CONFIG_XEN_EMU - ret =3D kvm_xen_init(s); + /* hyperv_enabled() doesn't work yet. */ + uint32_t msr =3D XEN_HYPERCALL_MSR; + ret =3D kvm_xen_init(s, msr); if (ret < 0) { return ret; } diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 4bd2eeeb5a..8433c4d70f 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -14,12 +14,12 @@ #include "kvm/kvm_i386.h" #include "xen-emu.h" =20 -int kvm_xen_init(KVMState *s) +int kvm_xen_init(KVMState *s, uint32_t hypercall_msr) { const int required_caps =3D KVM_XEN_HVM_CONFIG_HYPERCALL_MSR | KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL | KVM_XEN_HVM_CONFIG_SHARED_INF= O; struct kvm_xen_hvm_config cfg =3D { - .msr =3D XEN_HYPERCALL_MSR, + .msr =3D hypercall_msr, .flags =3D KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL, }; int xen_caps, ret; diff --git a/target/i386/kvm/xen-emu.h b/target/i386/kvm/xen-emu.h index 4f31bd96cb..2101df0182 100644 --- a/target/i386/kvm/xen-emu.h +++ b/target/i386/kvm/xen-emu.h @@ -12,8 +12,17 @@ #ifndef QEMU_I386_KVM_XEN_EMU_H #define QEMU_I386_KVM_XEN_EMU_H =20 -#define XEN_HYPERCALL_MSR 0x40000000 +#define XEN_HYPERCALL_MSR 0x40000000 +#define XEN_HYPERCALL_MSR_HYPERV 0x40000200 =20 -int kvm_xen_init(KVMState *s); +#define XEN_CPUID_SIGNATURE 0 +#define XEN_CPUID_VENDOR 1 +#define XEN_CPUID_HVM_MSR 2 +#define XEN_CPUID_TIME 3 +#define XEN_CPUID_HVM 4 + +#define XEN_VERSION(maj, min) ((maj) << 16 | (min)) + +int kvm_xen_init(KVMState *s, uint32_t hypercall_msr); =20 #endif /* QEMU_I386_KVM_XEN_EMU_H */ --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151343274199.29643106864592; Thu, 15 Dec 2022 16:42:23 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynU-0005L5-EW; Thu, 15 Dec 2022 19:41:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0005Dk-CT for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006c3-5Y for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:37 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymx-00Azyk-9m; Fri, 16 Dec 2022 00:41:26 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cON-PC; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=8AJifdwjiqRQtfUf0q/e6/X60sR9ptVL3WVrG9kgEec=; b=T3jR1bTJLNUJXfHY7jOwEBOdDC HRiRaVWvjIsx0gRqQt+tvk/EhEM5HLfKzjXp7za9h6PA9dL5Jg4YFE5AjnFVO28MKQDehavYG0H9i 9nro9X5xQ4Ag+56lssy0ilenALtU8l84mrepPJdRJJBbK55kYE89eV0PZL3tCRCSqsY7k5nW3VAfi nRrKYrEw+9JCufqb3eJvxCAWfIWixcnsg0bV3Zfin1bg9Rv7zl12hAwUsINs1I7P7xtQw1YsfUQ7X +GIFLHyCwPInStrBeZ7rZlacPWmu4B3/EjPRQmnV1EP4ZcQbx64V6WTMSJU274fCkr69mlGhSj/zV f+bk9+Ew==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 06/38] xen-platform: exclude vfio-pci from the PCI platform unplug Date: Fri, 16 Dec 2022 00:40:45 +0000 Message-Id: <20221216004117.862106-7-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151346045100005 Content-Type: text/plain; charset="utf-8" From: Joao Martins Such that PCI passthrough devices work for Xen emulated guests. Signed-off-by: Joao Martins Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- hw/i386/xen/xen_platform.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index a64265cca0..a6f0fb478a 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -109,12 +109,25 @@ static void log_writeb(PCIXenPlatformState *s, char v= al) #define _UNPLUG_NVME_DISKS 3 #define UNPLUG_NVME_DISKS (1u << _UNPLUG_NVME_DISKS) =20 +static bool pci_device_is_passthrough(PCIDevice *d) +{ + if (!strcmp(d->name, "xen-pci-passthrough")) { + return true; + } + + if (xen_mode =3D=3D XEN_EMULATE && !strcmp(d->name, "vfio-pci")) { + return true; + } + + return false; +} + static void unplug_nic(PCIBus *b, PCIDevice *d, void *o) { /* We have to ignore passthrough devices */ if (pci_get_word(d->config + PCI_CLASS_DEVICE) =3D=3D PCI_CLASS_NETWORK_ETHERNET - && strcmp(d->name, "xen-pci-passthrough") !=3D 0) { + && !pci_device_is_passthrough(d)) { object_unparent(OBJECT(d)); } } @@ -187,9 +200,8 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void = *opaque) !(flags & UNPLUG_IDE_SCSI_DISKS); =20 /* We have to ignore passthrough devices */ - if (!strcmp(d->name, "xen-pci-passthrough")) { + if (pci_device_is_passthrough(d)) return; - } =20 switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) { case PCI_CLASS_STORAGE_IDE: --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151875462864.501626007723; Thu, 15 Dec 2022 16:51:15 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ypO-0007pJ-I9; Thu, 15 Dec 2022 19:43:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yoF-000634-OP for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:48 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yoD-0006qA-8h for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:43 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymy-00Azyl-1g; Fri, 16 Dec 2022 00:42:25 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOQ-Q0; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=NMSyOXCeQvGp6e8gECxXRvoV0igLWYKZUw5/1jmRJIY=; b=EpRYaLP/gnuyGdyN+xx1BnWZ9r Txh0smYpMCaDowwDaQQ4fFhJsmhAjWVKe8Wmm9eVNmRkUWsZqhV3BgoicNqTAszABIXes7yNjsnCP CZy6VPXFuRQDCeqaELBax6z09D/JACL27Bvd0g3xxzIU/SbtFeNLPNErvajwgULBrMaEzxiOhtyQy FvpNtvjrE5pVn/3pBl8rtB6TdyEuE102Qz1ax4uVtHtG9sulPcugKhGugc/7n86sxyw14WeuSDhpd fhU7of5EvDQ01COZO82r/nONTHH79k0I3n98mWpy/C397hOwFfh6dySsMDuLS3MShjiTA0Cx933nc jERk9iaA==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 07/38] xen-platform: allow its creation with XEN_EMULATE mode Date: Fri, 16 Dec 2022 00:40:46 +0000 Message-Id: <20221216004117.862106-8-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151876780100001 Content-Type: text/plain; charset="utf-8" From: Joao Martins The only thing we need to handle on KVM side is to change the pfn from R/W to R/O. Signed-off-by: Joao Martins Signed-off-by: David Woodhouse --- hw/i386/xen/xen_platform.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index a6f0fb478a..15d5ae7c69 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -283,7 +283,10 @@ static void platform_fixed_ioport_writeb(void *opaque,= uint32_t addr, uint32_t v case 0: /* Platform flags */ { hvmmem_type_t mem_type =3D (val & PFFLAG_ROM_LOCK) ? HVMMEM_ram_ro : HVMMEM_ram_rw; - if (xen_set_mem_type(xen_domid, mem_type, 0xc0, 0x40)) { + if (xen_mode =3D=3D XEN_EMULATE) { + /* XXX */ + s->flags =3D val & PFFLAG_ROM_LOCK; + } else if (xen_set_mem_type(xen_domid, mem_type, 0xc0, 0x40)) { DPRINTF("unable to change ro/rw state of ROM memory area!\n"); } else { s->flags =3D val & PFFLAG_ROM_LOCK; @@ -508,12 +511,6 @@ static void xen_platform_realize(PCIDevice *dev, Error= **errp) PCIXenPlatformState *d =3D XEN_PLATFORM(dev); uint8_t *pci_conf; =20 - /* Device will crash on reset if xen is not initialized */ - if (!xen_enabled()) { - error_setg(errp, "xen-platform device requires the Xen accelerator= "); - return; - } - pci_conf =3D dev->config; =20 pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMO= RY); --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151417173816.8607890611619; Thu, 15 Dec 2022 16:43:37 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yo4-0005ns-7K; Thu, 15 Dec 2022 19:42:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynK-0005Fu-1I for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:46 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynI-0006fZ-4r for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:45 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymz-00Azyh-9S; Fri, 16 Dec 2022 00:41:32 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOT-Qp; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=Aupl4kuf/gI1/02kk+I2HSRBuWEl9wsI/NsKPpWNr5M=; b=JS7Fvl9bF673bKzWF/JzNy+xnD ULPJpdYGe1IWfUsH4zB0Posiaw8oO9Kd+gI3Gxl519KxzWSxHOOa2aFxd+H/bBzFMLUup4qmP87Cm +DWHYOLdCbTL3CUFVKpz+o0r1W+i+NiFTtnnXFWmB/rAmUn6h2ywkIHFilFZPDONMluXFsS+Eko+/ j+6cEPjf6Z4CHgcHoCiWt/ajUJmDybQ6vujQJzzL+V2BTTWHgeRmEzc+9YVJYUW3z84K2MH3uAnDi TfpxHCdZGzlIxLjXJitw0979gIPKWXRe2rTpZjWFgYNe7e8xt6/gXRZCnmiSSDyGnC4MS6oLdIV3a zP9cMu0Q==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 08/38] hw/xen_backend: refactor xen_be_init() Date: Fri, 16 Dec 2022 00:40:47 +0000 Message-Id: <20221216004117.862106-9-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151417855100001 Content-Type: text/plain; charset="utf-8" From: Joao Martins Signed-off-by: Joao Martins Signed-off-by: David Woodhouse Reviewed-by: Paul Durrant --- hw/xen/xen-legacy-backend.c | 40 +++++++++++++++++++++-------- include/hw/xen/xen-legacy-backend.h | 3 +++ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c index 085fd31ef7..694e7bbc54 100644 --- a/hw/xen/xen-legacy-backend.c +++ b/hw/xen/xen-legacy-backend.c @@ -676,17 +676,40 @@ void xenstore_update_fe(char *watch, struct XenLegacy= Device *xendev) } /* -------------------------------------------------------------------- */ =20 -int xen_be_init(void) +int xen_be_xenstore_open(void) { - xengnttab_handle *gnttabdev; - xenstore =3D xs_daemon_open(); if (!xenstore) { - xen_pv_printf(NULL, 0, "can't connect to xenstored\n"); return -1; } =20 qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL); + return 0; +} + +void xen_be_xenstore_close(void) +{ + qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL); + xs_daemon_close(xenstore); + xenstore =3D NULL; +} + +void xen_be_sysdev_init(void) +{ + xen_sysdev =3D qdev_new(TYPE_XENSYSDEV); + sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal); + xen_sysbus =3D qbus_new(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus"); + qbus_set_bus_hotplug_handler(xen_sysbus); +} + +int xen_be_init(void) +{ + xengnttab_handle *gnttabdev; + + if (xen_be_xenstore_open()) { + xen_pv_printf(NULL, 0, "can't connect to xenstored\n"); + return -1; + } =20 if (xen_xc =3D=3D NULL || xen_fmem =3D=3D NULL) { /* Check if xen_init() have been called */ @@ -701,17 +724,12 @@ int xen_be_init(void) xengnttab_close(gnttabdev); } =20 - xen_sysdev =3D qdev_new(TYPE_XENSYSDEV); - sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal); - xen_sysbus =3D qbus_new(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus"); - qbus_set_bus_hotplug_handler(xen_sysbus); + xen_be_sysdev_init(); =20 return 0; =20 err: - qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL); - xs_daemon_close(xenstore); - xenstore =3D NULL; + xen_be_xenstore_close(); =20 return -1; } diff --git a/include/hw/xen/xen-legacy-backend.h b/include/hw/xen/xen-legac= y-backend.h index be281e1f38..0aa171f6c2 100644 --- a/include/hw/xen/xen-legacy-backend.h +++ b/include/hw/xen/xen-legacy-backend.h @@ -42,6 +42,9 @@ int xenstore_read_fe_uint64(struct XenLegacyDevice *xende= v, const char *node, void xen_be_check_state(struct XenLegacyDevice *xendev); =20 /* xen backend driver bits */ +int xen_be_xenstore_open(void); +void xen_be_xenstore_close(void); +void xen_be_sysdev_init(void); int xen_be_init(void); void xen_be_register_common(void); int xen_be_register(const char *type, struct XenDevOps *ops); --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151761421191.85662875511127; Thu, 15 Dec 2022 16:49:21 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynu-0005XB-Hk; Thu, 15 Dec 2022 19:42:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynH-0005Fj-Um for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:45 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0006bC-KN for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:43 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV7-85; Fri, 16 Dec 2022 00:41:36 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOW-Rh; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=R+FWIvGoV3DQl1uWefrUJT7YzDAnI7XE7wZE92gzRAw=; b=hnfM0psqauNlHPJ+NFo/qJGJYP CNMltsoX8Tzin/Cy2lS6V7HTF0A4gzsWR1Fo3ovGX7gGifQNO2qXPaXnJ//d8WJSgCg1IizjUn5i2 LsMeyYCJprwDwCWtmn4Sq37DdOBDDdFYM6D6QlTnTHr+e90tqw2/FiN/l9utueY7G1CKgCfX9MXSA f4dfOfPR5Jl4SFD0TPtEUA36yUycdTBF9wOTe+Sx+APohn4gs58sD/RaVxC7kjbHKdNBJ5B6qQRL+ Gk9O5FkQq5FhRCS7NEg/HAchyH0Gs5F74LkPSPAmqXMicL0o0N0/w7WRJ7UURN6bnBOD+znmg/rFe Lt2KYAcw==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 09/38] i386/xen: handle guest hypercalls Date: Fri, 16 Dec 2022 00:40:48 +0000 Message-Id: <20221216004117.862106-10-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151762177100001 Content-Type: text/plain; charset="utf-8" From: Joao Martins This means handling the new exit reason for Xen but still crashing on purpose. As we implement each of the hypercalls we will then return the right return code. Signed-off-by: Joao Martins [dwmw2: Add CPL to hypercall tracing, disallow hypercalls from CPL > 0] Signed-off-by: David Woodhouse --- target/i386/kvm/kvm.c | 5 +++++ target/i386/kvm/trace-events | 3 +++ target/i386/kvm/xen-emu.c | 39 ++++++++++++++++++++++++++++++++++++ target/i386/kvm/xen-emu.h | 1 + 4 files changed, 48 insertions(+) diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 5977edb1ca..c37e44d88f 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -5466,6 +5466,11 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_ru= n *run) assert(run->msr.reason =3D=3D KVM_MSR_EXIT_REASON_FILTER); ret =3D kvm_handle_wrmsr(cpu, run); break; +#ifdef CONFIG_XEN_EMU + case KVM_EXIT_XEN: + ret =3D kvm_xen_handle_exit(cpu, &run->xen); + break; +#endif default: fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); ret =3D -1; diff --git a/target/i386/kvm/trace-events b/target/i386/kvm/trace-events index 7c369db1e1..cd6f842b1f 100644 --- a/target/i386/kvm/trace-events +++ b/target/i386/kvm/trace-events @@ -5,3 +5,6 @@ kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap= interrupt for GSI %" kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d" kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d" kvm_x86_update_msi_routes(int num) "Updated %d MSI routes" + +# xen-emu.c +kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint6= 4_t a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" P= RIu64 " a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64 diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 8433c4d70f..668713d5af 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -10,9 +10,11 @@ */ =20 #include "qemu/osdep.h" +#include "qemu/log.h" #include "sysemu/kvm_int.h" #include "kvm/kvm_i386.h" #include "xen-emu.h" +#include "trace.h" =20 int kvm_xen_init(KVMState *s, uint32_t hypercall_msr) { @@ -48,3 +50,40 @@ int kvm_xen_init(KVMState *s, uint32_t hypercall_msr) =20 return 0; } + +static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) +{ + uint16_t code =3D exit->u.hcall.input; + + if (exit->u.hcall.cpl > 0) { + exit->u.hcall.result =3D -EPERM; + return true; + } + + switch (code) { + default: + return false; + } +} + +int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) +{ + if (exit->type !=3D KVM_EXIT_XEN_HCALL) + return -1; + + if (!do_kvm_xen_handle_exit(cpu, exit)) { + /* Some hypercalls will be deliberately "implemented" by returning + * -ENOSYS. This case is for hypercalls which are unexpected. */ + exit->u.hcall.result =3D -ENOSYS; + qemu_log_mask(LOG_UNIMP, "Unimplemented Xen hypercall %" + PRId64 " (0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 ")= \n", + (uint64_t)exit->u.hcall.input, (uint64_t)exit->u.hca= ll.params[0], + (uint64_t)exit->u.hcall.params[1], (uint64_t)exit->u= .hcall.params[1]); + } + + trace_kvm_xen_hypercall(CPU(cpu)->cpu_index, exit->u.hcall.cpl, + exit->u.hcall.input, exit->u.hcall.params[0], + exit->u.hcall.params[1], exit->u.hcall.params[= 2], + exit->u.hcall.result); + return 0; +} diff --git a/target/i386/kvm/xen-emu.h b/target/i386/kvm/xen-emu.h index 2101df0182..76a3de6c4d 100644 --- a/target/i386/kvm/xen-emu.h +++ b/target/i386/kvm/xen-emu.h @@ -24,5 +24,6 @@ #define XEN_VERSION(maj, min) ((maj) << 16 | (min)) =20 int kvm_xen_init(KVMState *s, uint32_t hypercall_msr); +int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit); =20 #endif /* QEMU_I386_KVM_XEN_EMU_H */ --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151875613579.9980408755576; Thu, 15 Dec 2022 16:51:15 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ypK-0007eN-Ua; Thu, 15 Dec 2022 19:43:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yo8-0005sO-8r for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:36 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yo6-0006pK-Ml for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:36 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymz-00Azyi-9J; Fri, 16 Dec 2022 00:42:12 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOZ-Sc; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=w1DBVXe/l3AlZ7H7l/kSK4vVa6NrSwnY94Z8tKdSTLU=; b=oYZPbgQnwtdtQ+V2YeNJ8uS5rD 9YGLNV8SaGZvLP6mdiX+SYhENU3RCK2JHlYhJxJENy78ZEHJedbDOGrJw2FwXiTF9uvxtXcxL00Zt C8P00iKU4OzGkvptIsDwPWrZeqTf1M0RkngTB4YrNdFwmfXa80ytvFU6d1iZznCe5lv4rBZqoMUbq 8JLb1rQpmZI4LHUrzDFz7z9hO4za7hTuE1P4Rjq9yPREgeB2U9yeN6iKBh2ToZNMLKi3WMfPHAi3T fjkVuzmA3R3F9ZWxqlIg7FLlEirU8UpsbeLeCdZcdXwCs2jjYtoG/OKFPVfKCWyU/gOafUXygpl/k mXuxp/Fw==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 10/38] i386/xen: implement HYPERCALL_xen_version Date: Fri, 16 Dec 2022 00:40:49 +0000 Message-Id: <20221216004117.862106-11-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151876791100002 Content-Type: text/plain; charset="utf-8" From: Joao Martins This is just meant to serve as an example on how we can implement hypercalls. xen_version specifically since Qemu does all kind of feature controllability. So handling that here seems appropriate. Signed-off-by: Joao Martins [dwmw2: Implement kvm_gva_rw() safely] Signed-off-by: David Woodhouse --- target/i386/kvm/xen-emu.c | 86 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 668713d5af..9026fd3eb6 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -13,9 +13,55 @@ #include "qemu/log.h" #include "sysemu/kvm_int.h" #include "kvm/kvm_i386.h" +#include "exec/address-spaces.h" #include "xen-emu.h" +#include "xen.h" #include "trace.h" =20 +#include "standard-headers/xen/version.h" + +static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz, + bool is_write) +{ + uint8_t *buf =3D (uint8_t *)_buf; + int ret; + + while (sz) { + struct kvm_translation tr =3D { + .linear_address =3D gva, + }; + + size_t len =3D TARGET_PAGE_SIZE - (tr.linear_address & ~TARGET_PAG= E_MASK); + if (len > sz) + len =3D sz; + + ret =3D kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &tr); + if (ret || !tr.valid || (is_write && !tr.writeable)) { + return -EFAULT; + } + + cpu_physical_memory_rw(tr.physical_address, buf, len, is_write); + + buf +=3D len; + sz -=3D len; + gva +=3D len; + } + + return 0; +} + +static inline int kvm_copy_from_gva(CPUState *cs, uint64_t gva, void *buf, + size_t sz) +{ + return kvm_gva_rw(cs, gva, buf, sz, false); +} + +static inline int kvm_copy_to_gva(CPUState *cs, uint64_t gva, void *buf, + size_t sz) +{ + return kvm_gva_rw(cs, gva, buf, sz, true); +} + int kvm_xen_init(KVMState *s, uint32_t hypercall_msr) { const int required_caps =3D KVM_XEN_HVM_CONFIG_HYPERCALL_MSR | @@ -51,6 +97,43 @@ int kvm_xen_init(KVMState *s, uint32_t hypercall_msr) return 0; } =20 +static bool kvm_xen_hcall_xen_version(struct kvm_xen_exit *exit, X86CPU *c= pu, + int cmd, uint64_t arg) +{ + int err =3D 0; + + switch (cmd) { + case XENVER_get_features: { + struct xen_feature_info fi; + + /* No need for 32/64 compat handling */ + qemu_build_assert(sizeof(fi) =3D=3D 8); + + err =3D kvm_copy_from_gva(CPU(cpu), arg, &fi, sizeof(fi)); + if (err) { + break; + } + + fi.submap =3D 0; + if (fi.submap_idx =3D=3D 0) { + fi.submap |=3D 1 << XENFEAT_writable_page_tables | + 1 << XENFEAT_writable_descriptor_tables | + 1 << XENFEAT_auto_translated_physmap | + 1 << XENFEAT_supervisor_mode_kernel; + } + + err =3D kvm_copy_to_gva(CPU(cpu), arg, &fi, sizeof(fi)); + break; + } + + default: + return false; + } + + exit->u.hcall.result =3D err; + return true; +} + static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) { uint16_t code =3D exit->u.hcall.input; @@ -61,6 +144,9 @@ static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct k= vm_xen_exit *exit) } =20 switch (code) { + case __HYPERVISOR_xen_version: + return kvm_xen_hcall_xen_version(exit, cpu, exit->u.hcall.params[0= ], + exit->u.hcall.params[1]); default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152011805125.36248156296824; Thu, 15 Dec 2022 16:53:31 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynz-0005Zu-3p; Thu, 15 Dec 2022 19:42:27 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynD-0005Dt-4Q for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006c5-4n for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:38 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-00Azyp-Qi; Fri, 16 Dec 2022 00:41:24 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOc-TY; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=5B1uN+3MgPrsF2fzIQNpUf078erm8LsxSREMzJT+ogc=; b=WRUiNtGDOTSY1TOXTCkwyEA9RM Etmqbf+GVQrq+R8q498uPudcE4czTzk6H/jlL8WnDCwclP1r5+3NDn/Ol496uVFbDrE8EhJpGh6V/ hBNBtElnBJMyRr8VG1TFljjpOHpoplb2stf5e5IYVhkFwikDdkjMsuVXLBF1ogUYt4Rpl7pQaUZc6 UFT9yZI3u0mJk75EVWIYb3OyO46QHHI0LrJF7bH+TirCh+Pkg0+SWKh/npObttPFBLhVvgGtxogoH CWavx1WGW8uKjEGbBKyS7UUGvka4vbHiEb0Q/YwRFFgZ4eFr1YYxy3QGK+3Cn1XwHMWHaZsZrAn1G MDrm/EDA==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 11/38] hw/xen: Add xen_overlay device for emulating shared xenheap pages Date: Fri, 16 Dec 2022 00:40:50 +0000 Message-Id: <20221216004117.862106-12-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152013885100003 From: David Woodhouse For the shared info page and for grant tables, Xen shares its own pages from the "Xen heap" to the guest. The guest requests that a given page from a certain address space (XENMAPSPACE_shared_info, etc.) be mapped to a given GPA using the XENMEM_add_to_physmap hypercall. To support that in qemu when *emulating* Xen, create a memory region (migratable) and allow it to be mapped as an overlay when requested. Xen theoretically allows the same page to be mapped multiple times into the guest, but that's hard to track and reinstate over migration, so we automatically *unmap* any previous mapping when creating a new one. This approach has been used in production with.... a non-trivial number of guests expecting true Xen, without any problems yet being noticed. This adds just the shared info page for now. The grant tables will be a larger region, and will need to be overlaid one page at a time. I think that means I need to create separate aliases for each page of the overall grant_frames region, so that they can be mapped individually. Expecting some heckling at the use of xen_overlay_singleton. What is the best way to do that? Using qemu_find_recursive() every time seemed a bit wrong. But I suppose mapping it into the *guest* isn't a fast path, and if the actual grant table code is allowed to just stash the pointer it gets from xen_overlay_page_ptr() for later use then that isn't a fast path for device I/O either. Signed-off-by: David Woodhouse --- hw/i386/kvm/meson.build | 1 + hw/i386/kvm/xen_overlay.c | 198 ++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_overlay.h | 14 +++ 3 files changed, 213 insertions(+) create mode 100644 hw/i386/kvm/xen_overlay.c create mode 100644 hw/i386/kvm/xen_overlay.h diff --git a/hw/i386/kvm/meson.build b/hw/i386/kvm/meson.build index 95467f1ded..6165cbf019 100644 --- a/hw/i386/kvm/meson.build +++ b/hw/i386/kvm/meson.build @@ -4,5 +4,6 @@ i386_kvm_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c= ')) i386_kvm_ss.add(when: 'CONFIG_I8254', if_true: files('i8254.c')) i386_kvm_ss.add(when: 'CONFIG_I8259', if_true: files('i8259.c')) i386_kvm_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c')) +i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen_overlay.c')) =20 i386_ss.add_all(when: 'CONFIG_KVM', if_true: i386_kvm_ss) diff --git a/hw/i386/kvm/xen_overlay.c b/hw/i386/kvm/xen_overlay.c new file mode 100644 index 0000000000..2ae54e1a88 --- /dev/null +++ b/hw/i386/kvm/xen_overlay.c @@ -0,0 +1,198 @@ +/* + * QEMU Xen emulation: Shared/overlay pages support + * + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: David Woodhouse + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/host-utils.h" +#include "qemu/module.h" +#include "qemu/main-loop.h" +#include "qapi/error.h" +#include "qom/object.h" +#include "exec/target_page.h" +#include "exec/address-spaces.h" +#include "migration/vmstate.h" + +#include "hw/sysbus.h" +#include "hw/xen/xen.h" +#include "xen_overlay.h" + +#include "sysemu/kvm.h" +#include + +#include "standard-headers/xen/memory.h" + +static int xen_overlay_map_page_locked(uint32_t space, uint64_t idx, uint6= 4_t gpa); + +#define INVALID_GPA UINT64_MAX +#define INVALID_GFN UINT64_MAX + +#define TYPE_XEN_OVERLAY "xenoverlay" +OBJECT_DECLARE_SIMPLE_TYPE(XenOverlayState, XEN_OVERLAY) + +#define XEN_PAGE_SHIFT 12 +#define XEN_PAGE_SIZE (1ULL << XEN_PAGE_SHIFT) + +struct XenOverlayState { + /*< private >*/ + SysBusDevice busdev; + /*< public >*/ + + MemoryRegion shinfo_mem; + void *shinfo_ptr; + uint64_t shinfo_gpa; +}; + +struct XenOverlayState *xen_overlay_singleton; + +static void xen_overlay_realize(DeviceState *dev, Error **errp) +{ + XenOverlayState *s =3D XEN_OVERLAY(dev); + + if (xen_mode !=3D XEN_EMULATE) { + error_setg(errp, "Xen overlay page support is for Xen emulation"); + return; + } + + memory_region_init_ram(&s->shinfo_mem, OBJECT(dev), "xen:shared_info",= XEN_PAGE_SIZE, &error_abort); + memory_region_set_enabled(&s->shinfo_mem, true); + s->shinfo_ptr =3D memory_region_get_ram_ptr(&s->shinfo_mem); + s->shinfo_gpa =3D INVALID_GPA; + memset(s->shinfo_ptr, 0, XEN_PAGE_SIZE); +} + +static int xen_overlay_post_load(void *opaque, int version_id) +{ + XenOverlayState *s =3D opaque; + + if (s->shinfo_gpa !=3D INVALID_GPA) { + xen_overlay_map_page_locked(XENMAPSPACE_shared_info, 0, s->shinfo_= gpa); + } + + return 0; +} + +static bool xen_overlay_is_needed(void *opaque) +{ + return xen_mode =3D=3D XEN_EMULATE; +} + +static const VMStateDescription xen_overlay_vmstate =3D { + .name =3D "xen_overlay", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D xen_overlay_is_needed, + .post_load =3D xen_overlay_post_load, + .fields =3D (VMStateField[]) { + VMSTATE_UINT64(shinfo_gpa, XenOverlayState), + VMSTATE_END_OF_LIST() + } +}; + +static void xen_overlay_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D xen_overlay_realize; + dc->vmsd =3D &xen_overlay_vmstate; +} + +static const TypeInfo xen_overlay_info =3D { + .name =3D TYPE_XEN_OVERLAY, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(XenOverlayState), + .class_init =3D xen_overlay_class_init, +}; + +void xen_overlay_create(void) +{ + xen_overlay_singleton =3D XEN_OVERLAY(sysbus_create_simple(TYPE_XEN_OV= ERLAY, -1, NULL)); +} + +static void xen_overlay_register_types(void) +{ + type_register_static(&xen_overlay_info); +} + +type_init(xen_overlay_register_types) + +int xen_overlay_map_page(uint32_t space, uint64_t idx, uint64_t gpa) +{ + int ret; + + qemu_mutex_lock_iothread(); + ret =3D xen_overlay_map_page_locked(space, idx, gpa); + qemu_mutex_unlock_iothread(); + + return ret; +} + +/* KVM is the only existing back end for now. Let's not overengineer it ye= t. */ +static int xen_overlay_set_be_shinfo(uint64_t gfn) +{ + struct kvm_xen_hvm_attr xa =3D { + .type =3D KVM_XEN_ATTR_TYPE_SHARED_INFO, + .u.shared_info.gfn =3D gfn, + }; + + return kvm_vm_ioctl(kvm_state, KVM_XEN_HVM_SET_ATTR, &xa); +} + +static int xen_overlay_map_page_locked(uint32_t space, uint64_t idx, uint6= 4_t gpa) +{ + MemoryRegion *ovl_page; + int err; + + if (space !=3D XENMAPSPACE_shared_info || idx !=3D 0) + return -EINVAL; + + if (!xen_overlay_singleton) + return -ENOENT; + + ovl_page =3D &xen_overlay_singleton->shinfo_mem; + + /* Xen allows guests to map the same page as many times as it likes + * into guest physical frames. We don't, because it would be hard + * to track and restore them all. One mapping of each page is + * perfectly sufficient for all known guests... and we've tested + * that theory on a few now in other implementations. dwmw2. */ + if (memory_region_is_mapped(ovl_page)) { + if (gpa =3D=3D INVALID_GPA) { + /* If removing shinfo page, turn the kernel magic off first */ + if (space =3D=3D XENMAPSPACE_shared_info) { + err =3D xen_overlay_set_be_shinfo(INVALID_GFN); + if (err) + return err; + } + memory_region_del_subregion(get_system_memory(), ovl_page); + goto done; + } else { + /* Just move it */ + memory_region_set_address(ovl_page, gpa); + } + } else if (gpa !=3D INVALID_GPA) { + memory_region_add_subregion_overlap(get_system_memory(), gpa, ovl_= page, 0); + } + + xen_overlay_set_be_shinfo(gpa >> XEN_PAGE_SHIFT); + done: + xen_overlay_singleton->shinfo_gpa =3D gpa; + return 0; +} + +void *xen_overlay_page_ptr(uint32_t space, uint64_t idx) +{ + if (space !=3D XENMAPSPACE_shared_info || idx !=3D 0) + return NULL; + + if (!xen_overlay_singleton) + return NULL; + + return xen_overlay_singleton->shinfo_ptr; +} diff --git a/hw/i386/kvm/xen_overlay.h b/hw/i386/kvm/xen_overlay.h new file mode 100644 index 0000000000..afc63991ea --- /dev/null +++ b/hw/i386/kvm/xen_overlay.h @@ -0,0 +1,14 @@ +/* + * QEMU Xen emulation: Shared/overlay pages support + * + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: David Woodhouse + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +void xen_overlay_create(void); +int xen_overlay_map_page(uint32_t space, uint64_t idx, uint64_t gpa); +void *xen_overlay_page_ptr(uint32_t space, uint64_t idx); --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151661497378.370694036593; Thu, 15 Dec 2022 16:47:41 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynP-0005Hv-JE; Thu, 15 Dec 2022 19:41:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynA-0005DF-JT for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:37 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn5-0006c2-GJ for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:34 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymx-00Azyj-1n; Fri, 16 Dec 2022 00:41:24 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOf-Ub; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=gtgG1W5Ka58PoBWIC0tn+Dtg4khX0TN+Lyd0L1oA6pk=; b=Qvkrp9Ra9ah+ZZI4EO7ipwr3TX kv51/69Z3dfW4sEgPY3BRRXeR0e1v/1LIx7qmGT9UzAPt2WwLqweAnydKM23zgoUgpC1Q8PrZLGE5 VkEFGSkBPwEsrpbigPGUfCrQXTOTXFc9Q1bWuWBBIeqNuQ6jSCDyz1Y3qZHlLkc++kUDfbvLQfbW5 F0TRetS637gJpYMQwrZ6fS5zaIGZRRKzCS4OO89G4moFLBsdYgDAR6YMCddfexQeaZAGqlyqRH28+ kQ8MlKVFmJFYw6lVu0DCfpdEbC7lRF4Ee16lV6ynf/ul/PXbB/2KcK19aK9SYV6ubKmmZExZ9eaML ve7rKe0w==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 12/38] i386/xen: add pc_machine_kvm_type to initialize XEN_EMULATE mode Date: Fri, 16 Dec 2022 00:40:51 +0000 Message-Id: <20221216004117.862106-13-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151663686100003 Content-Type: text/plain; charset="utf-8" From: David Woodhouse The xen_overlay device (and later similar devices for event channels and grant tables) need to be instantiated. Do this from a kvm_type method on the PC machine derivatives, since KVM is only way to support Xen emulation for now. Signed-off-by: David Woodhouse --- hw/i386/pc.c | 11 +++++++++++ include/hw/i386/pc.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 546b703cb4..f1780daa4c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -89,6 +89,7 @@ #include "hw/virtio/virtio-iommu.h" #include "hw/virtio/virtio-pmem-pci.h" #include "hw/virtio/virtio-mem-pci.h" +#include "hw/i386/kvm/xen_overlay.h" #include "hw/mem/memory-device.h" #include "sysemu/replay.h" #include "target/i386/cpu.h" @@ -1842,6 +1843,16 @@ static void pc_machine_initfn(Object *obj) cxl_machine_init(obj, &pcms->cxl_devices_state); } =20 +int pc_machine_kvm_type(MachineState *machine, const char *kvm_type) +{ +#ifdef CONFIG_XEN_EMU + if (xen_mode =3D=3D XEN_EMULATE) { + xen_overlay_create(); + } +#endif + return 0; +} + static void pc_machine_reset(MachineState *machine, ShutdownCause reason) { CPUState *cs; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index c95333514e..e82224857e 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -290,12 +290,15 @@ extern const size_t pc_compat_1_5_len; extern GlobalProperty pc_compat_1_4[]; extern const size_t pc_compat_1_4_len; =20 +extern int pc_machine_kvm_type(MachineState *machine, const char *vm_type); + #define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \ static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *da= ta) \ { \ MachineClass *mc =3D MACHINE_CLASS(oc); \ optsfn(mc); \ mc->init =3D initfn; \ + mc->kvm_type =3D pc_machine_kvm_type; \ } \ static const TypeInfo pc_machine_type_##suffix =3D { \ .name =3D namestr TYPE_MACHINE_SUFFIX, \ --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151914974892.3090788018158; Thu, 15 Dec 2022 16:51:54 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yoy-0007EK-Vu; Thu, 15 Dec 2022 19:43:29 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynu-0005XK-PH for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:22 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yns-0006ov-Hx for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:22 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymx-00Azyn-9s; Fri, 16 Dec 2022 00:42:13 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymv-003cOi-VS; Fri, 16 Dec 2022 00:41:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=HHo/imGSQJ7G3wmm2n8XVa25vfC6B8yh3+uR9QTLQXQ=; b=fsbXM+Xo/ntn3i7CJtLNaAgDSx SKe7Tyh/aEXyX4pP7a7rLyPdx/qljw6PYKHGWx47M22SFKB4dl4XJltAjb+HFzh6N2HqDc7SFp9SC Gfrcb65qpjnwrN7VCuVsg3t64GNt54LHN0IErix/Qm7+SlvOkAP33JHbl0npq+1zrXhfoNS6IwXj6 pDtraNlLILhmG/H12RAjr1HkVMoPwGQaUAR8GSeAQDTbKTTlDUd6uLE45t3R9j/VEpEsv/2iYwH/v L1hFJqwVFhYe5eRgU6INJCQXeNFm9ImFSnYeGlPn2isJWUmD2kaPZovGKWswYguUYEmREfv9cIOrj v6+zaQEA==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 13/38] i386/xen: manage and save/restore Xen guest long_mode setting Date: Fri, 16 Dec 2022 00:40:52 +0000 Message-Id: <20221216004117.862106-14-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151917015100003 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Xen will "latch" the guest's 32-bit or 64-bit ("long mode") setting when the guest writes the MSR to fill in the hypercall page, or when the guest sets the event channel callback in HVM_PARAM_CALLBACK_IRQ. KVM handles the former and sets the kernel's long_mode flag accordingly. The latter will be handled in userspace. Keep them in sync by noticing when a hypercall is made in a mode that doesn't match qemu's idea of the guest mode, and resyncing from the kernel. Do that same sync right before serialization too, in case the guest has set the hypercall page but hasn't yet made a system call. Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_overlay.c | 63 +++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_overlay.h | 4 +++ target/i386/kvm/xen-emu.c | 10 ++++++- 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/hw/i386/kvm/xen_overlay.c b/hw/i386/kvm/xen_overlay.c index 2ae54e1a88..a0ddbda91c 100644 --- a/hw/i386/kvm/xen_overlay.c +++ b/hw/i386/kvm/xen_overlay.c @@ -47,6 +47,7 @@ struct XenOverlayState { MemoryRegion shinfo_mem; void *shinfo_ptr; uint64_t shinfo_gpa; + bool long_mode; }; =20 struct XenOverlayState *xen_overlay_singleton; @@ -64,9 +65,19 @@ static void xen_overlay_realize(DeviceState *dev, Error = **errp) memory_region_set_enabled(&s->shinfo_mem, true); s->shinfo_ptr =3D memory_region_get_ram_ptr(&s->shinfo_mem); s->shinfo_gpa =3D INVALID_GPA; + s->long_mode =3D false; memset(s->shinfo_ptr, 0, XEN_PAGE_SIZE); } =20 +static int xen_overlay_pre_save(void *opaque) +{ + /* Fetch the kernel's idea of long_mode to avoid the race condition wh= ere + * the guest has set the hypercall page up in 64-bit mode but not yet + * made a hypercall by the time migration happens, so qemu hasn't yet + * noticed. */ + return xen_sync_long_mode(); +} + static int xen_overlay_post_load(void *opaque, int version_id) { XenOverlayState *s =3D opaque; @@ -74,6 +85,9 @@ static int xen_overlay_post_load(void *opaque, int versio= n_id) if (s->shinfo_gpa !=3D INVALID_GPA) { xen_overlay_map_page_locked(XENMAPSPACE_shared_info, 0, s->shinfo_= gpa); } + if (s->long_mode) { + xen_set_long_mode(true); + } =20 return 0; } @@ -88,9 +102,11 @@ static const VMStateDescription xen_overlay_vmstate =3D= { .version_id =3D 1, .minimum_version_id =3D 1, .needed =3D xen_overlay_is_needed, + .pre_save =3D xen_overlay_pre_save, .post_load =3D xen_overlay_post_load, .fields =3D (VMStateField[]) { VMSTATE_UINT64(shinfo_gpa, XenOverlayState), + VMSTATE_BOOL(long_mode, XenOverlayState), VMSTATE_END_OF_LIST() } }; @@ -196,3 +212,50 @@ void *xen_overlay_page_ptr(uint32_t space, uint64_t id= x) =20 return xen_overlay_singleton->shinfo_ptr; } + +int xen_sync_long_mode(void) +{ + int ret; + struct kvm_xen_hvm_attr xa =3D { + .type =3D KVM_XEN_ATTR_TYPE_LONG_MODE, + }; + + if (!xen_overlay_singleton) { + return -ENOENT; + } + + ret =3D kvm_vm_ioctl(kvm_state, KVM_XEN_HVM_GET_ATTR, &xa); + if (!ret) { + xen_overlay_singleton->long_mode =3D xa.u.long_mode; + } + + return ret; +} + +int xen_set_long_mode(bool long_mode) +{ + int ret; + struct kvm_xen_hvm_attr xa =3D { + .type =3D KVM_XEN_ATTR_TYPE_LONG_MODE, + .u.long_mode =3D long_mode, + }; + + if (!xen_overlay_singleton) { + return -ENOENT; + } + + ret =3D kvm_vm_ioctl(kvm_state, KVM_XEN_HVM_SET_ATTR, &xa); + if (!ret) { + xen_overlay_singleton->long_mode =3D xa.u.long_mode; + } + + return ret; +} + +bool xen_is_long_mode(void) +{ + if (xen_overlay_singleton) { + return xen_overlay_singleton->long_mode; + } + return false; +} diff --git a/hw/i386/kvm/xen_overlay.h b/hw/i386/kvm/xen_overlay.h index afc63991ea..ed8f0ef0e7 100644 --- a/hw/i386/kvm/xen_overlay.h +++ b/hw/i386/kvm/xen_overlay.h @@ -12,3 +12,7 @@ void xen_overlay_create(void); int xen_overlay_map_page(uint32_t space, uint64_t idx, uint64_t gpa); void *xen_overlay_page_ptr(uint32_t space, uint64_t idx); + +int xen_sync_long_mode(void); +int xen_set_long_mode(bool long_mode); +bool xen_is_long_mode(void); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 9026fd3eb6..11e34ed125 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -17,7 +17,7 @@ #include "xen-emu.h" #include "xen.h" #include "trace.h" - +#include "hw/i386/kvm/xen_overlay.h" #include "standard-headers/xen/version.h" =20 static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz, @@ -157,6 +157,14 @@ int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_ex= it *exit) if (exit->type !=3D KVM_EXIT_XEN_HCALL) return -1; =20 + /* The kernel latches the guest 32/64 mode when the MSR is used to fill + * the hypercall page. So if we see a hypercall in a mode that doesn't + * match our own idea of the guest mode, fetch the kernel's idea of the + * "long mode" to remain in sync. */ + if (exit->u.hcall.longmode !=3D xen_is_long_mode()) { + xen_sync_long_mode(); + } + if (!do_kvm_xen_handle_exit(cpu, exit)) { /* Some hypercalls will be deliberately "implemented" by returning * -ENOSYS. This case is for hypercalls which are unexpected. */ --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151879896120.01995715644216; Thu, 15 Dec 2022 16:51:19 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yny-0005Yi-GY; Thu, 15 Dec 2022 19:42:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynH-0005Ff-GH for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:45 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0006b9-Hp for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:42 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV6-7m; Fri, 16 Dec 2022 00:41:36 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cOl-0A; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=8Ff2qXnnGA+6pGq7J5XUlI5PPSNcUbGDwpwmBmVMqAQ=; b=OHRlulGCD74oLy83r0RFFtHwCF f/TpShl4aW/ecTuEm6uOYCr1sn3yH3pjJ2SLvL42tPt7jHJrL4ZLLv+NjiJ0hg6rG0hn9zBLtQGjj p8vNXtQPbEOFi4TJqYoIEQUswmo3HY+ddFYN4Ux/9N6RaZeGeRm3To09AVlto5I7+/nqRwqoyUuIC TqF7JPOfGs1PCAcDh8/wZvJEphg+EdOKqCYPeXI8IH7OFKFJz42YgzxvRFwGxEpqtOLS3+pNFIJGN z6MjyekW33h9PoHuWogUuLVDaQPTUv3ONOHLg1raBB2o2Vhc3qucZTKf3qOjVN7c7CnaSb934JGqA jcBKWl9w==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 14/38] i386/xen: implement HYPERVISOR_memory_op Date: Fri, 16 Dec 2022 00:40:53 +0000 Message-Id: <20221216004117.862106-15-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151880796100001 From: Joao Martins Specifically XENMEM_add_to_physmap with space XENMAPSPACE_shared_info to allow the guest to set its shared_info page. Signed-off-by: Joao Martins [dwmw2: Use the xen_overlay device, add compat support] Signed-off-by: David Woodhouse --- target/i386/kvm/trace-events | 1 + target/i386/kvm/xen-compat.h | 27 +++++++++ target/i386/kvm/xen-emu.c | 104 ++++++++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 target/i386/kvm/xen-compat.h diff --git a/target/i386/kvm/trace-events b/target/i386/kvm/trace-events index cd6f842b1f..0a47c26e80 100644 --- a/target/i386/kvm/trace-events +++ b/target/i386/kvm/trace-events @@ -8,3 +8,4 @@ kvm_x86_update_msi_routes(int num) "Updated %d MSI routes" =20 # xen-emu.c kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint6= 4_t a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" P= RIu64 " a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64 +kvm_xen_set_shared_info(uint64_t gfn) "shared info at gfn 0x%" PRIx64 diff --git a/target/i386/kvm/xen-compat.h b/target/i386/kvm/xen-compat.h new file mode 100644 index 0000000000..0b7088662a --- /dev/null +++ b/target/i386/kvm/xen-compat.h @@ -0,0 +1,27 @@ +/* + * Xen HVM emulation support in KVM + * + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_I386_KVM_XEN_COMPAT_H +#define QEMU_I386_KVM_XEN_COMPAT_H + +#include "standard-headers/xen/memory.h" + +typedef uint32_t compat_pfn_t; +typedef uint32_t compat_ulong_t; + +struct compat_xen_add_to_physmap { + domid_t domid; + uint16_t size; + unsigned int space; + compat_ulong_t idx; + compat_pfn_t gpfn; +}; + +#endif /* QEMU_I386_XEN_COMPAT_H */ diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 11e34ed125..1fecab6e10 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -9,16 +9,27 @@ * */ =20 +#define __XEN_INTERFACE_VERSION__ 0x00040e00 + #include "qemu/osdep.h" #include "qemu/log.h" +#include "hw/xen/xen.h" #include "sysemu/kvm_int.h" #include "kvm/kvm_i386.h" #include "exec/address-spaces.h" #include "xen-emu.h" -#include "xen.h" #include "trace.h" #include "hw/i386/kvm/xen_overlay.h" #include "standard-headers/xen/version.h" +#include "standard-headers/xen/memory.h" + +#include "xen-compat.h" + +#ifdef TARGET_X86_64 +#define hypercall_compat32(longmode) (!(longmode)) +#else +#define hypercall_compat32(longmode) (false) +#endif =20 static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz, bool is_write) @@ -134,6 +145,94 @@ static bool kvm_xen_hcall_xen_version(struct kvm_xen_e= xit *exit, X86CPU *cpu, return true; } =20 +static int xen_set_shared_info(uint64_t gfn) +{ + uint64_t gpa =3D gfn << TARGET_PAGE_BITS; + int err; + + /* The xen_overlay device tells KVM about it too, since it had to + * do that on migration load anyway (unless we're going to jump + * through lots of hoops to maintain the fiction that this isn't + * KVM-specific */ + err =3D xen_overlay_map_page(XENMAPSPACE_shared_info, 0, gpa); + if (err) + return err; + + trace_kvm_xen_set_shared_info(gfn); + + return err; +} + +static int add_to_physmap_one(uint32_t space, uint64_t idx, uint64_t gfn) +{ + switch (space) { + case XENMAPSPACE_shared_info: + if (idx > 0) { + return -EINVAL; + } + return xen_set_shared_info(gfn); + + case XENMAPSPACE_grant_table: + case XENMAPSPACE_gmfn: + case XENMAPSPACE_gmfn_range: + return -ENOTSUP; + + case XENMAPSPACE_gmfn_foreign: + case XENMAPSPACE_dev_mmio: + return -EPERM; + + default: + return -EINVAL;; + } +} + +static int do_add_to_physmap(struct kvm_xen_exit *exit, X86CPU *cpu, uint6= 4_t arg) +{ + struct xen_add_to_physmap xatp; + CPUState *cs =3D CPU(cpu); + + if (hypercall_compat32(exit->u.hcall.longmode)) { + struct compat_xen_add_to_physmap xatp32; + + qemu_build_assert(sizeof(struct compat_xen_add_to_physmap) =3D=3D = 16); + if (kvm_copy_from_gva(cs, arg, &xatp32, sizeof(xatp32))) { + return -EFAULT; + } + xatp.domid =3D xatp32.domid; + xatp.size =3D xatp32.size; + xatp.space =3D xatp32.space; + xatp.idx =3D xatp32.idx; + xatp.gpfn =3D xatp32.gpfn; + } else { + if (kvm_copy_from_gva(cs, arg, &xatp, sizeof(xatp))) { + return -EFAULT; + } + } + + if (xatp.domid !=3D DOMID_SELF && xatp.domid !=3D xen_domid) { + return -ESRCH; + } + + return add_to_physmap_one(xatp.space, xatp.idx, xatp.gpfn); +} +static bool kvm_xen_hcall_memory_op(struct kvm_xen_exit *exit, X86CPU *cpu, + int cmd, uint64_t arg) +{ + int err; + + switch (cmd) { + case XENMEM_add_to_physmap: + err =3D do_add_to_physmap(exit, cpu, arg); + break; + + default: + return false; + } + + exit->u.hcall.result =3D err; + return true; +} + static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) { uint16_t code =3D exit->u.hcall.input; @@ -144,6 +243,9 @@ static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct = kvm_xen_exit *exit) } =20 switch (code) { + case __HYPERVISOR_memory_op: + return kvm_xen_hcall_memory_op(exit, cpu, exit->u.hcall.params[0], + exit->u.hcall.params[1]); case __HYPERVISOR_xen_version: return kvm_xen_hcall_xen_version(exit, cpu, exit->u.hcall.params[0= ], exit->u.hcall.params[1]); --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151412828808.8586711018512; Thu, 15 Dec 2022 16:43:32 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yne-0005PK-Gm; Thu, 15 Dec 2022 19:42:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynK-0005Fv-1l for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:46 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynI-0006fd-81 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:45 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymz-00Azyt-9R; Fri, 16 Dec 2022 00:41:32 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cOo-17; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=VWjE1fM6kr8j65/rSw8tUwrrimb4U2TfBvsIMEU3MTw=; b=Icp3a++NenhqP0t1IHf0EzBJf5 veEe076qdPpR18RHLGagX+AXCkltHSm1MO1z+myti82pKxr3qoBznAjhyNP1iYJxK4l78/oKRpBqB fDzFzd7Lq5bBtgzQCgt4NEz2wFRxWFdOANbmdjCqcqhiPZJ4XNgQm2eI/SE3ecbkdoVUZKmNOW9s0 yBeQO51HD0dxM9ZqhGxbdgYsb+gGEC6dxV6csAo4ptLOVELPSalQ1uj1aUvgTDZ1R1r4UbKM0erBN Y6a8El6xIIpBVt1fXriVOJSRWxmI+D4eGlvZv/uxXYbGLrEpKbS6DGBRXrfPGE8MtF0kZa4CSTXtG 3kDR0/Ng==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 15/38] i386/xen: implement XENMEM_add_to_physmap_batch Date: Fri, 16 Dec 2022 00:40:54 +0000 Message-Id: <20221216004117.862106-16-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151413871100003 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Signed-off-by: David Woodhouse --- target/i386/kvm/xen-compat.h | 24 +++++++++++++ target/i386/kvm/xen-emu.c | 70 ++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/target/i386/kvm/xen-compat.h b/target/i386/kvm/xen-compat.h index 0b7088662a..2925dcc7f6 100644 --- a/target/i386/kvm/xen-compat.h +++ b/target/i386/kvm/xen-compat.h @@ -15,6 +15,20 @@ =20 typedef uint32_t compat_pfn_t; typedef uint32_t compat_ulong_t; +typedef uint32_t compat_ptr_t; + +#define __DEFINE_COMPAT_HANDLE(name, type) \ + typedef struct { \ + compat_ptr_t c; \ + type *_[0] __attribute__((packed)); \ + } __compat_handle_ ## name; \ + +#define DEFINE_COMPAT_HANDLE(name) __DEFINE_COMPAT_HANDLE(name, name) +#define COMPAT_HANDLE(name) __compat_handle_ ## name + +DEFINE_COMPAT_HANDLE(compat_pfn_t); +DEFINE_COMPAT_HANDLE(compat_ulong_t); +DEFINE_COMPAT_HANDLE(int); =20 struct compat_xen_add_to_physmap { domid_t domid; @@ -24,4 +38,14 @@ struct compat_xen_add_to_physmap { compat_pfn_t gpfn; }; =20 +struct compat_xen_add_to_physmap_batch { + domid_t domid; + uint16_t space; + uint16_t size; + uint16_t extra; + COMPAT_HANDLE(compat_ulong_t) idxs; + COMPAT_HANDLE(compat_pfn_t) gpfns; + COMPAT_HANDLE(int) errs; +}; + #endif /* QEMU_I386_XEN_COMPAT_H */ diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 1fecab6e10..c23026b872 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -215,6 +215,72 @@ static int do_add_to_physmap(struct kvm_xen_exit *exit= , X86CPU *cpu, uint64_t ar =20 return add_to_physmap_one(xatp.space, xatp.idx, xatp.gpfn); } + +static int do_add_to_physmap_batch(struct kvm_xen_exit *exit, X86CPU *cpu, + uint64_t arg) +{ + struct xen_add_to_physmap_batch xatpb; + unsigned long idxs_gva, gpfns_gva, errs_gva; + CPUState *cs =3D CPU(cpu); + size_t op_sz; + + if (hypercall_compat32(exit->u.hcall.longmode)) { + struct compat_xen_add_to_physmap_batch xatpb32; + + qemu_build_assert(sizeof(struct compat_xen_add_to_physmap_batch) = =3D=3D 20); + if (kvm_copy_from_gva(cs, arg, &xatpb32, sizeof(xatpb32))) { + return -EFAULT; + } + xatpb.domid =3D xatpb32.domid; + xatpb.space =3D xatpb32.space; + xatpb.size =3D xatpb32.size; + + idxs_gva =3D xatpb32.idxs.c; + gpfns_gva =3D xatpb32.gpfns.c; + errs_gva =3D xatpb32.errs.c; + op_sz =3D sizeof(uint32_t);; + } else { + if (kvm_copy_from_gva(cs, arg, &xatpb, sizeof(xatpb))) { + return -EFAULT; + } + op_sz =3D sizeof(unsigned long); + idxs_gva =3D (unsigned long)xatpb.idxs.p; + gpfns_gva =3D (unsigned long)xatpb.gpfns.p; + errs_gva =3D (unsigned long)xatpb.errs.p; + } + + if (xatpb.domid !=3D DOMID_SELF && xatpb.domid !=3D xen_domid) { + return -ESRCH; + } + + /* Explicitly invalid for the batch op. Not that we implement it anywa= y. */ + if (xatpb.space =3D=3D XENMAPSPACE_gmfn_range) { + return -EINVAL; + } + + while (xatpb.size--) { + unsigned long idx =3D 0; + unsigned long gpfn =3D 0; + int err; + + /* For 32-bit compat this only copies the low 32 bits of each */ + if (kvm_copy_from_gva(cs, idxs_gva, &idx, op_sz) || + kvm_copy_from_gva(cs, gpfns_gva, &gpfn, op_sz)) { + return -EFAULT; + } + idxs_gva +=3D op_sz; + gpfns_gva +=3D op_sz; + + err =3D add_to_physmap_one(xatpb.space, idx, gpfn); + + if (kvm_copy_to_gva(cs, errs_gva, &err, sizeof(err))) { + return -EFAULT; + } + errs_gva +=3D sizeof(err); + } + return 0; +} + static bool kvm_xen_hcall_memory_op(struct kvm_xen_exit *exit, X86CPU *cpu, int cmd, uint64_t arg) { @@ -225,6 +291,10 @@ static bool kvm_xen_hcall_memory_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, err =3D do_add_to_physmap(exit, cpu, arg); break; =20 + case XENMEM_add_to_physmap_batch: + err =3D do_add_to_physmap_batch(exit, cpu, arg); + break; + default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152104374998.6953482757009; Thu, 15 Dec 2022 16:55:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynr-0005TI-9b; Thu, 15 Dec 2022 19:42:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynG-0005FZ-5d for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:44 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynB-0006aS-Vr for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:41 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV8-79; Fri, 16 Dec 2022 00:41:35 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cOr-1v; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=kDehJ+ZaE96SaSHoFH+UEUYcFNxlGFzdUWksLyQZbQI=; b=HfZDtim3TbYYhGD2XjrJ5L4l77 D0vE8pYzkm33IT2zWlsmzvaOPV7SSEcdjIfzYV0eLj2l38MbtKrbBqu5Hwp5f3myAwVsrXtFKnmZi YePcnkc8OscivQKQn9zJpnJ8WecCy16ngzqw4WdRD6a0TdJjmwRjDnKOd+daj4C/38MKSNlO5AS8C Rush4XKQvpwAJ6C8hjP6hYbKaXqabHlwhczUkGJ7s/srVHD86NmMG/e3joUTEJ/D7Q5g7vT/ZKG/a X3/tinP7DetOoLzOA9sCsZ8ptAUlZ+HjjxU7njuXYTlxOFWlOYfNyYuQARFGS3CJt1bpsXfB2Og1C GlXAdnDQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 16/38] i386/xen: implement HYPERVISOR_hvm_op Date: Fri, 16 Dec 2022 00:40:55 +0000 Message-Id: <20221216004117.862106-17-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152106255100003 Content-Type: text/plain; charset="utf-8" From: Joao Martins This is when guest queries for support for HVMOP_pagetable_dying. Signed-off-by: Joao Martins Signed-off-by: David Woodhouse --- target/i386/kvm/xen-emu.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index c23026b872..da77297ef9 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -22,6 +22,7 @@ #include "hw/i386/kvm/xen_overlay.h" #include "standard-headers/xen/version.h" #include "standard-headers/xen/memory.h" +#include "standard-headers/xen/hvm/hvm_op.h" =20 #include "xen-compat.h" =20 @@ -303,6 +304,19 @@ static bool kvm_xen_hcall_memory_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, return true; } =20 +static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit *exit, X86CPU *cpu, + int cmd, uint64_t arg) +{ + switch (cmd) { + case HVMOP_pagetable_dying: + exit->u.hcall.result =3D -ENOSYS; + return true; + + default: + return false; + } +} + static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) { uint16_t code =3D exit->u.hcall.input; @@ -313,6 +327,9 @@ static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct = kvm_xen_exit *exit) } =20 switch (code) { + case __HYPERVISOR_hvm_op: + return kvm_xen_hcall_hvm_op(exit, cpu, exit->u.hcall.params[0], + exit->u.hcall.params[1]); case __HYPERVISOR_memory_op: return kvm_xen_hcall_memory_op(exit, cpu, exit->u.hcall.params[0], exit->u.hcall.params[1]); --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 167115180692324.477280499223525; Thu, 15 Dec 2022 16:50:06 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynK-0005F9-5V; Thu, 15 Dec 2022 19:41:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynA-0005DO-Lc for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:37 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn6-0006dc-3V for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:36 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymy-00Azyu-1p; Fri, 16 Dec 2022 00:41:29 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cOu-2f; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=DbYXTM9ZCYwc4lgjru+zdjS5TQxUcToh43/n+0mqExE=; b=B6ksSAEFuEQ+zyGFExWcDJDunB IObDliQytnzK8kQF6MzsRnMBeA93CoU2q+CmuijmGFE3RqG9bRLpBZ3yb4DRLCLIl2oCThGRe1E2w rbxWy+sD5pC+hmHzL5bdK3LY31fQHFiRxxy/4dufhLMzxAUiCbmpbtJo+E0zdYc8ihUKYbKZvXAmj JFyz80DLSaIjrZ8ZKmtkxIevQApyBHMdlw3hSBtfi4fuBBqlXa3ptVVtUBr0eU0oS9yMLMJJHaZDE uzUVArauAtdTlZIk96ujtTf9QUjigUHCFRemdzsOIiMl6ljeWHY+yyCQK7gJIVdHpHhUeY7eYOSJQ DdAYVI9Q==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 17/38] i386/xen: implement HYPERVISOR_vcpu_op Date: Fri, 16 Dec 2022 00:40:56 +0000 Message-Id: <20221216004117.862106-18-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151808459100003 Content-Type: text/plain; charset="utf-8" From: Joao Martins This is simply when guest tries to register a vcpu_info and since vcpu_info placement is optional in the minimum ABI therefore we can just fail with -ENOSYS Signed-off-by: Joao Martins Signed-off-by: David Woodhouse --- target/i386/kvm/xen-emu.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index da77297ef9..83d98cbfd9 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -23,6 +23,7 @@ #include "standard-headers/xen/version.h" #include "standard-headers/xen/memory.h" #include "standard-headers/xen/hvm/hvm_op.h" +#include "standard-headers/xen/vcpu.h" =20 #include "xen-compat.h" =20 @@ -317,6 +318,25 @@ static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit *= exit, X86CPU *cpu, } } =20 +static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu, + int cmd, int vcpu_id, uint64_t arg) +{ + int err; + + switch (cmd) { + case VCPUOP_register_vcpu_info: + /* no vcpu info placement for now */ + err =3D -ENOSYS; + break; + + default: + return false; + } + + exit->u.hcall.result =3D err; + return true; +} + static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) { uint16_t code =3D exit->u.hcall.input; @@ -327,6 +347,11 @@ static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct= kvm_xen_exit *exit) } =20 switch (code) { + case __HYPERVISOR_vcpu_op: + return kvm_xen_hcall_vcpu_op(exit, cpu, + exit->u.hcall.params[0], + exit->u.hcall.params[1], + exit->u.hcall.params[2]); case __HYPERVISOR_hvm_op: return kvm_xen_hcall_hvm_op(exit, cpu, exit->u.hcall.params[0], exit->u.hcall.params[1]); --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 167115183320978.5880336878771; Thu, 15 Dec 2022 16:50:33 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ypH-0007Un-L5; Thu, 15 Dec 2022 19:43:48 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yny-0005a8-Qj for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:26 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynw-0006pJ-MD for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:26 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymz-00Azyo-9M; Fri, 16 Dec 2022 00:42:13 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cOx-3Q; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=xNDBz0dz9aaRz4gtLDKk7jjwVAWCuOnXemhrtJukk0w=; b=n/cQvUIzRxWnWtxbvJPxrj7ffR T7+8qWAWJf5+58R2kqL6fEqIG2wiOOqfscijb8AwDlVLZSC2OwoTqdK8h/1RyO0D2nkB9ux/4fgic QYz7RS4GoMENNIIlQShXZljbzwYzML7MhQqzN7XtAunGGjJco2Bq9Yk6Hz9unBkNQ7qy6gEaNZYeZ PDM4XFsPOFXWftKHVSQSFNRMnA+VvZsVsubfTlxFLZVLorOJfayQb5XcAF+UdCkcdPPTRs7XHwdHn MkLgUeHrF3/qmfWJecx5f5J4pcV6+dZXl1MZpi4wlRjm3hue+M44qAoZMYTg0VYTwRZgDJyjnHczn oK9tV5wA==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 18/38] i386/xen: handle VCPUOP_register_vcpu_info Date: Fri, 16 Dec 2022 00:40:57 +0000 Message-Id: <20221216004117.862106-19-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151834599100003 Content-Type: text/plain; charset="utf-8" From: Joao Martins Handle the hypercall to set a per vcpu info, and also wire up the default vcpu_info in the shared_info page for the first 32 vCPUs. To avoid deadlock within KVM a vCPU thread must set its *own* vcpu_info rather than it being set from the context in which the hypercall is invoked. Add the vcpu_info (and default) GPA to the vmstate_x86_cpu for migration, and restore it in kvm_arch_put_registers() appropriately. Signed-off-by: Joao Martins Signed-off-by: David Woodhouse --- target/i386/cpu.h | 2 + target/i386/kvm/kvm.c | 19 +++++++++ target/i386/kvm/trace-events | 1 + target/i386/kvm/xen-emu.c | 78 ++++++++++++++++++++++++++++++++++-- target/i386/kvm/xen-emu.h | 1 + target/i386/machine.c | 21 ++++++++++ 6 files changed, 119 insertions(+), 3 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index c6c57baed5..109b2e5669 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1788,6 +1788,8 @@ typedef struct CPUArchState { #endif #if defined(CONFIG_KVM) struct kvm_nested_state *nested_state; + uint64_t xen_vcpu_info_gpa; + uint64_t xen_vcpu_info_default_gpa; #endif #if defined(CONFIG_HVF) HVFX86LazyFlags hvf_lflags; diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index c37e44d88f..8affe1eeae 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -1802,6 +1802,9 @@ int kvm_arch_init_vcpu(CPUState *cs) has_msr_hv_hypercall =3D true; } =20 + env->xen_vcpu_info_gpa =3D UINT64_MAX; + env->xen_vcpu_info_default_gpa =3D UINT64_MAX; + if (cs->kvm_state->xen_version) { #ifdef CONFIG_XEN_EMU struct kvm_cpuid_entry2 *xen_max_leaf; @@ -4723,6 +4726,22 @@ int kvm_arch_put_registers(CPUState *cpu, int level) kvm_arch_set_tsc_khz(cpu); } =20 +#ifdef CONFIG_XEN_EMU + if (level =3D=3D KVM_PUT_FULL_STATE) { + uint64_t gpa =3D x86_cpu->env.xen_vcpu_info_gpa; + if (gpa =3D=3D UINT64_MAX) { + gpa =3D x86_cpu->env.xen_vcpu_info_default_gpa; + } + + if (gpa !=3D UINT64_MAX) { + ret =3D kvm_xen_set_vcpu_attr(cpu, KVM_XEN_VCPU_ATTR_TYPE_VCPU= _INFO, gpa); + if (ret < 0) { + return ret; + } + } + } +#endif + ret =3D kvm_getput_regs(x86_cpu, 1); if (ret < 0) { return ret; diff --git a/target/i386/kvm/trace-events b/target/i386/kvm/trace-events index 0a47c26e80..14e54dfca5 100644 --- a/target/i386/kvm/trace-events +++ b/target/i386/kvm/trace-events @@ -9,3 +9,4 @@ kvm_x86_update_msi_routes(int num) "Updated %d MSI routes" # xen-emu.c kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint6= 4_t a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" P= RIu64 " a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64 kvm_xen_set_shared_info(uint64_t gfn) "shared info at gfn 0x%" PRIx64 +kvm_xen_set_vcpu_attr(int cpu, int type, uint64_t gpa) "vcpu attr cpu %d t= ype %d gpa 0x%" PRIx64 diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 83d98cbfd9..25c48248ce 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -147,10 +147,47 @@ static bool kvm_xen_hcall_xen_version(struct kvm_xen_= exit *exit, X86CPU *cpu, return true; } =20 +int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type, uint64_t gpa) +{ + struct kvm_xen_vcpu_attr xhsi; + + xhsi.type =3D type; + xhsi.u.gpa =3D gpa; + + trace_kvm_xen_set_vcpu_attr(cs->cpu_index, type, gpa); + + return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xhsi); +} + +static void do_set_vcpu_info_default_gpa(CPUState *cs, run_on_cpu_data dat= a) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + env->xen_vcpu_info_default_gpa =3D data.host_ulong; + + /* Changing the default does nothing if a vcpu_info was explicitly set= . */ + if (env->xen_vcpu_info_gpa =3D=3D UINT64_MAX) { + kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO, + env->xen_vcpu_info_default_gpa); + } +} + +static void do_set_vcpu_info_gpa(CPUState *cs, run_on_cpu_data data) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + env->xen_vcpu_info_gpa =3D data.host_ulong; + + kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO, + env->xen_vcpu_info_gpa); +} + static int xen_set_shared_info(uint64_t gfn) { uint64_t gpa =3D gfn << TARGET_PAGE_BITS; - int err; + int i, err; =20 /* The xen_overlay device tells KVM about it too, since it had to * do that on migration load anyway (unless we're going to jump @@ -162,6 +199,14 @@ static int xen_set_shared_info(uint64_t gfn) =20 trace_kvm_xen_set_shared_info(gfn); =20 + for (i =3D 0; i < XEN_LEGACY_MAX_VCPUS; i++) { + CPUState *cpu =3D qemu_get_cpu(i); + if (cpu) { + async_run_on_cpu(cpu, do_set_vcpu_info_default_gpa, RUN_ON_CPU= _HOST_ULONG(gpa)); + } + gpa +=3D sizeof(vcpu_info_t); + } + return err; } =20 @@ -318,15 +363,42 @@ static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit = *exit, X86CPU *cpu, } } =20 +static int vcpuop_register_vcpu_info(CPUState *cs, CPUState *target, + uint64_t arg) +{ + struct vcpu_register_vcpu_info rvi; + uint64_t gpa; + + /* No need for 32/64 compat handling */ + qemu_build_assert(sizeof(rvi) =3D=3D 16); + qemu_build_assert(sizeof(struct vcpu_info) =3D=3D 64); + + if (!target) + return -ENOENT; + + if (kvm_copy_from_gva(cs, arg, &rvi, sizeof(rvi))) { + return -EFAULT; + } + + if (rvi.offset > TARGET_PAGE_SIZE - sizeof(struct vcpu_info)) { + return -EINVAL; + } + + gpa =3D ((rvi.mfn << TARGET_PAGE_BITS) + rvi.offset); + async_run_on_cpu(target, do_set_vcpu_info_gpa, RUN_ON_CPU_HOST_ULONG(g= pa)); + return 0; +} + static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu, int cmd, int vcpu_id, uint64_t arg) { + CPUState *dest =3D qemu_get_cpu(vcpu_id); + CPUState *cs =3D CPU(cpu); int err; =20 switch (cmd) { case VCPUOP_register_vcpu_info: - /* no vcpu info placement for now */ - err =3D -ENOSYS; + err =3D vcpuop_register_vcpu_info(cs, dest, arg); break; =20 default: diff --git a/target/i386/kvm/xen-emu.h b/target/i386/kvm/xen-emu.h index 76a3de6c4d..20da62d39f 100644 --- a/target/i386/kvm/xen-emu.h +++ b/target/i386/kvm/xen-emu.h @@ -25,5 +25,6 @@ =20 int kvm_xen_init(KVMState *s, uint32_t hypercall_msr); int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit); +int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type, uint64_t gpa); =20 #endif /* QEMU_I386_KVM_XEN_EMU_H */ diff --git a/target/i386/machine.c b/target/i386/machine.c index 310b125235..104cd6047c 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -1257,6 +1257,26 @@ static const VMStateDescription vmstate_nested_state= =3D { } }; =20 +static bool xen_vcpu_needed(void *opaque) +{ + X86CPU *cpu =3D opaque; + CPUX86State *env =3D &cpu->env; + + return (env->xen_vcpu_info_gpa !=3D UINT64_MAX || + env->xen_vcpu_info_default_gpa !=3D UINT64_MAX); +} + +static const VMStateDescription vmstate_xen_vcpu =3D { + .name =3D "cpu/xen_vcpu", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D xen_vcpu_needed, + .fields =3D (VMStateField[]) { + VMSTATE_UINT64(env.xen_vcpu_info_gpa, X86CPU), + VMSTATE_UINT64(env.xen_vcpu_info_default_gpa, X86CPU), + VMSTATE_END_OF_LIST() + } +}; #endif =20 static bool mcg_ext_ctl_needed(void *opaque) @@ -1716,6 +1736,7 @@ const VMStateDescription vmstate_x86_cpu =3D { #endif #ifdef CONFIG_KVM &vmstate_nested_state, + &vmstate_xen_vcpu, #endif &vmstate_msr_tsx_ctrl, &vmstate_msr_intel_sgx, --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151642797636.2160496029385; Thu, 15 Dec 2022 16:47:22 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynQ-0005I1-HS; Thu, 15 Dec 2022 19:41:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynD-0005Dv-D6 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006aL-57 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:39 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV1-6s; Fri, 16 Dec 2022 00:41:32 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cP0-4M; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=HUqjl2ZetqWgA9+4iOiLOPOG2qoUYzw/7UEbE0HfBLU=; b=WuufNIrWu3X9pY5NlQwf83PDOa P3dFoY7N0jQNrc5ppeXFrVOCRhhrzssT7T9HtO2naXA/PZ+mz4Svgj4GECy/akNHAbmBkh8jccZZm gC0xRDgyNvuQT+Ui8U/AY3ymxeUdDxiT9wloLgOkAZNM5xDTBuhbY/xZR495Lh0RukcwMp5iWTMSh iDWw/45AFRH2quqBc4hTadQF3zriKlPbEcEKwZycLtj8HA8t0wF7/kjN/zJjAy/rMpty/o+yuIKAb DBkmVTL8quEHXGJ/1etzJK/qR/W8oWxg2Kup6/GvEe4f04K9W5lpDp6edgFxiRNGUHIxo1uXUNQT4 NDRswGLQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 19/38] i386/xen: handle VCPUOP_register_vcpu_time_info Date: Fri, 16 Dec 2022 00:40:58 +0000 Message-Id: <20221216004117.862106-20-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151643662100001 From: Joao Martins In order to support Linux vdso in Xen. Signed-off-by: Joao Martins Signed-off-by: David Woodhouse --- target/i386/cpu.h | 1 + target/i386/kvm/kvm.c | 9 ++++ target/i386/kvm/xen-emu.c | 86 +++++++++++++++++++++++++++++++++------ target/i386/machine.c | 4 +- 4 files changed, 87 insertions(+), 13 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 109b2e5669..96c2d0d5cb 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1790,6 +1790,7 @@ typedef struct CPUArchState { struct kvm_nested_state *nested_state; uint64_t xen_vcpu_info_gpa; uint64_t xen_vcpu_info_default_gpa; + uint64_t xen_vcpu_time_info_gpa; #endif #if defined(CONFIG_HVF) HVFX86LazyFlags hvf_lflags; diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 8affe1eeae..766e0add13 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -1804,6 +1804,7 @@ int kvm_arch_init_vcpu(CPUState *cs) =20 env->xen_vcpu_info_gpa =3D UINT64_MAX; env->xen_vcpu_info_default_gpa =3D UINT64_MAX; + env->xen_vcpu_time_info_gpa =3D UINT64_MAX; =20 if (cs->kvm_state->xen_version) { #ifdef CONFIG_XEN_EMU @@ -4739,6 +4740,14 @@ int kvm_arch_put_registers(CPUState *cpu, int level) return ret; } } + + gpa =3D x86_cpu->env.xen_vcpu_time_info_gpa; + if (gpa !=3D UINT64_MAX) { + ret =3D kvm_xen_set_vcpu_attr(cpu, KVM_XEN_VCPU_ATTR_TYPE_VCPU= _TIME_INFO, gpa); + if (ret < 0) { + return ret; + } + } } #endif =20 diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 25c48248ce..b45d5af7d7 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -33,27 +33,40 @@ #define hypercall_compat32(longmode) (false) #endif =20 -static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz, - bool is_write) +static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa, + size_t *len, bool is_write) { - uint8_t *buf =3D (uint8_t *)_buf; - int ret; - - while (sz) { struct kvm_translation tr =3D { .linear_address =3D gva, }; =20 - size_t len =3D TARGET_PAGE_SIZE - (tr.linear_address & ~TARGET_PAG= E_MASK); - if (len > sz) - len =3D sz; + if (len) { + *len =3D TARGET_PAGE_SIZE - (gva & ~TARGET_PAGE_MASK); + } + + if (kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &tr) || !tr.valid || + (is_write && !tr.writeable)) { + return false; + } + *gpa =3D tr.physical_address; + return true; +} + +static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz, + bool is_write) +{ + uint8_t *buf =3D (uint8_t *)_buf; + uint64_t gpa; + size_t len; =20 - ret =3D kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &tr); - if (ret || !tr.valid || (is_write && !tr.writeable)) { + while (sz) { + if (!kvm_gva_to_gpa(cs, gva, &gpa, &len, is_write)) { return -EFAULT; } + if (len > sz) + len =3D sz; =20 - cpu_physical_memory_rw(tr.physical_address, buf, len, is_write); + cpu_physical_memory_rw(gpa, buf, len, is_write); =20 buf +=3D len; sz -=3D len; @@ -184,6 +197,17 @@ static void do_set_vcpu_info_gpa(CPUState *cs, run_on_= cpu_data data) env->xen_vcpu_info_gpa); } =20 +static void do_set_vcpu_time_info_gpa(CPUState *cs, run_on_cpu_data data) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + env->xen_vcpu_time_info_gpa =3D data.host_ulong; + + kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO, + env->xen_vcpu_time_info_gpa); +} + static int xen_set_shared_info(uint64_t gfn) { uint64_t gpa =3D gfn << TARGET_PAGE_BITS; @@ -389,6 +413,41 @@ static int vcpuop_register_vcpu_info(CPUState *cs, CPU= State *target, return 0; } =20 +static int vcpuop_register_vcpu_time_info(CPUState *cs, CPUState *target, + uint64_t arg) +{ + struct vcpu_register_time_memory_area tma; + uint64_t gpa; + size_t len; + + /* No need for 32/64 compat handling */ + qemu_build_assert(sizeof(tma) =3D=3D 8); + qemu_build_assert(sizeof(struct vcpu_time_info) =3D=3D 32); + + if (!target) + return -ENOENT; + + if (kvm_copy_from_gva(cs, arg, &tma, sizeof(tma))) { + return -EFAULT; + } + + /* + * Xen actually uses the GVA and does the translation through the guest + * page tables each time. But Linux/KVM uses the GPA, on the assumption + * that guests only ever use *global* addresses (kernel virtual addres= ses) + * for it. If Linux is changed to redo the GVA=E2=86=92GPA translation= each time, + * it will offer a new vCPU attribute for that, and we'll use it inste= ad. + */ + if (!kvm_gva_to_gpa(cs, tma.addr.p, &gpa, &len, false) || + len < sizeof(struct vcpu_time_info)) { + return -EFAULT; + } + + async_run_on_cpu(target, do_set_vcpu_time_info_gpa, + RUN_ON_CPU_HOST_ULONG(gpa)); + return 0; +} + static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu, int cmd, int vcpu_id, uint64_t arg) { @@ -397,6 +456,9 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *= exit, X86CPU *cpu, int err; =20 switch (cmd) { + case VCPUOP_register_vcpu_time_memory_area: + err =3D vcpuop_register_vcpu_time_info(cs, dest, arg); + break; case VCPUOP_register_vcpu_info: err =3D vcpuop_register_vcpu_info(cs, dest, arg); break; diff --git a/target/i386/machine.c b/target/i386/machine.c index 104cd6047c..9acef102a3 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -1263,7 +1263,8 @@ static bool xen_vcpu_needed(void *opaque) CPUX86State *env =3D &cpu->env; =20 return (env->xen_vcpu_info_gpa !=3D UINT64_MAX || - env->xen_vcpu_info_default_gpa !=3D UINT64_MAX); + env->xen_vcpu_info_default_gpa !=3D UINT64_MAX || + env->xen_vcpu_time_info_gpa !=3D UINT64_MAX); } =20 static const VMStateDescription vmstate_xen_vcpu =3D { @@ -1274,6 +1275,7 @@ static const VMStateDescription vmstate_xen_vcpu =3D { .fields =3D (VMStateField[]) { VMSTATE_UINT64(env.xen_vcpu_info_gpa, X86CPU), VMSTATE_UINT64(env.xen_vcpu_info_default_gpa, X86CPU), + VMSTATE_UINT64(env.xen_vcpu_time_info_gpa, X86CPU), VMSTATE_END_OF_LIST() } }; --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151433572559.324444882537; Thu, 15 Dec 2022 16:43:53 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yoF-000611-1a; Thu, 15 Dec 2022 19:42:43 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynI-0005Fl-7k for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:46 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0006bh-Q5 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:43 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV3-7m; Fri, 16 Dec 2022 00:41:36 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cP3-5E; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=f0X2egZG5zzVUMXCMQ1cggmTowl6jkcb5iseWcNGzOc=; b=cijJML4Wpx0W6kPo/B1eoe96C1 gyXwlW6of5gB3LDGN+rwTWlzTooWBPr5bv5JzY4eKP3jHU5BIgXY9NlYKz+InYDsgpZ8G2122tHh2 +YB4TEF8IRckzEf4cM9mnCfySzSCCtP91/S4i1hCkf16o8RCePDqfa0IjIS9QDHL09S5I8fd/63Db oSDWoCUHbsULvhvG+/YilmKJZZZO3r/wBPIY1c6s1rl6rq6R21EpgdjhwuFxfDzESf6v6JZ8RxFBX Ih4OJulidtFhDZ/Jh7RFTxxq75avQfd3jrru+xMAEpmGuuBzwQgiu5rYSFPXkyMuelOZv4IP/0FS/ VVIh55vQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 20/38] i386/xen: handle VCPUOP_register_runstate_memory_area Date: Fri, 16 Dec 2022 00:40:59 +0000 Message-Id: <20221216004117.862106-21-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151433930100001 Content-Type: text/plain; charset="utf-8" From: Joao Martins Allow guest to setup the vcpu runstates which is used as steal clock. Signed-off-by: Joao Martins Signed-off-by: David Woodhouse --- target/i386/cpu.h | 1 + target/i386/kvm/kvm.c | 9 +++++++++ target/i386/kvm/xen-emu.c | 42 +++++++++++++++++++++++++++++++++++++++ target/i386/machine.c | 4 +++- 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 96c2d0d5cb..bf44a87ddb 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1791,6 +1791,7 @@ typedef struct CPUArchState { uint64_t xen_vcpu_info_gpa; uint64_t xen_vcpu_info_default_gpa; uint64_t xen_vcpu_time_info_gpa; + uint64_t xen_vcpu_runstate_gpa; #endif #if defined(CONFIG_HVF) HVFX86LazyFlags hvf_lflags; diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 766e0add13..8aee95d4c1 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -1805,6 +1805,7 @@ int kvm_arch_init_vcpu(CPUState *cs) env->xen_vcpu_info_gpa =3D UINT64_MAX; env->xen_vcpu_info_default_gpa =3D UINT64_MAX; env->xen_vcpu_time_info_gpa =3D UINT64_MAX; + env->xen_vcpu_runstate_gpa =3D UINT64_MAX; =20 if (cs->kvm_state->xen_version) { #ifdef CONFIG_XEN_EMU @@ -4748,6 +4749,14 @@ int kvm_arch_put_registers(CPUState *cpu, int level) return ret; } } + + gpa =3D x86_cpu->env.xen_vcpu_runstate_gpa; + if (gpa !=3D UINT64_MAX) { + ret =3D kvm_xen_set_vcpu_attr(cpu, KVM_XEN_VCPU_ATTR_TYPE_RUNS= TATE_ADDR, gpa); + if (ret < 0) { + return ret; + } + } } #endif =20 diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index b45d5af7d7..1297b37ee8 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -208,6 +208,17 @@ static void do_set_vcpu_time_info_gpa(CPUState *cs, ru= n_on_cpu_data data) env->xen_vcpu_time_info_gpa); } =20 +static void do_set_vcpu_runstate_gpa(CPUState *cs, run_on_cpu_data data) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + env->xen_vcpu_runstate_gpa =3D data.host_ulong; + + kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR, + env->xen_vcpu_runstate_gpa); +} + static int xen_set_shared_info(uint64_t gfn) { uint64_t gpa =3D gfn << TARGET_PAGE_BITS; @@ -448,6 +459,34 @@ static int vcpuop_register_vcpu_time_info(CPUState *cs= , CPUState *target, return 0; } =20 +static int vcpuop_register_runstate_info(CPUState *cs, CPUState *target, + uint64_t arg) +{ + struct vcpu_register_runstate_memory_area rma; + uint64_t gpa; + size_t len; + + /* No need for 32/64 compat handling */ + qemu_build_assert(sizeof(rma) =3D=3D 8); + /* The runstate area actually does change size, but Linux copes. */ + + if (!target) + return -ENOENT; + + if (kvm_copy_from_gva(cs, arg, &rma, sizeof(rma))) { + return -EFAULT; + } + + /* As with vcpu_time_info, Xen actually uses the GVA but KVM doesn't. = */ + if (!kvm_gva_to_gpa(cs, rma.addr.p, &gpa, &len, false)) { + return -EFAULT; + } + + async_run_on_cpu(target, do_set_vcpu_runstate_gpa, + RUN_ON_CPU_HOST_ULONG(gpa)); + return 0; +} + static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu, int cmd, int vcpu_id, uint64_t arg) { @@ -456,6 +495,9 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *= exit, X86CPU *cpu, int err; =20 switch (cmd) { + case VCPUOP_register_runstate_memory_area: + err =3D vcpuop_register_runstate_info(cs, dest, arg); + break; case VCPUOP_register_vcpu_time_memory_area: err =3D vcpuop_register_vcpu_time_info(cs, dest, arg); break; diff --git a/target/i386/machine.c b/target/i386/machine.c index 9acef102a3..6a510e5cbd 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -1264,7 +1264,8 @@ static bool xen_vcpu_needed(void *opaque) =20 return (env->xen_vcpu_info_gpa !=3D UINT64_MAX || env->xen_vcpu_info_default_gpa !=3D UINT64_MAX || - env->xen_vcpu_time_info_gpa !=3D UINT64_MAX); + env->xen_vcpu_time_info_gpa !=3D UINT64_MAX || + env->xen_vcpu_runstate_gpa !=3D UINT64_MAX); } =20 static const VMStateDescription vmstate_xen_vcpu =3D { @@ -1276,6 +1277,7 @@ static const VMStateDescription vmstate_xen_vcpu =3D { VMSTATE_UINT64(env.xen_vcpu_info_gpa, X86CPU), VMSTATE_UINT64(env.xen_vcpu_info_default_gpa, X86CPU), VMSTATE_UINT64(env.xen_vcpu_time_info_gpa, X86CPU), + VMSTATE_UINT64(env.xen_vcpu_runstate_gpa, X86CPU), VMSTATE_END_OF_LIST() } }; --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151469118209.56197589735496; Thu, 15 Dec 2022 16:44:29 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynf-0005QO-Nk; Thu, 15 Dec 2022 19:42:08 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynE-0005F6-EN for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:41 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006aO-5H for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV2-6x; Fri, 16 Dec 2022 00:41:34 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cP6-64; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=EsPQIX2Hnxlr+aH9qp05RJWdYjbfQPNm1bwxx8s6vJ0=; b=uGljoItSsrvfmDcof/3u8rDylY v1fSFzqiMW/pB4zT2v7nxXnE2Z4QNHMpyxi4Vkhr7HzPB2U8jmrFEOQ0EzjKtOGsPnBuIG8qiKOvf IsTjRmlGfWWMi6v4TaTRfNLwS9n5DXwyqcVA4Le72JalCbcyoAsdO1AyNeAEhG0qsbR40CFwpP2Mw JsGdWXiMhPnSHDiGus8kjJZpBsV6xnD8w1kA0Rr77CKs9XbMs+GFO2GIB8oOep+b6rcFuPd3HQIBj LTzZFwk+VW5I/kw50VqGjfv3brzQaWW4S3ektYIoR1LAJZGuWJJh93od2dkepuv0Rfav5Wxh2nLQr YuTUmYWQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 21/38] i386/xen: implement HVMOP_set_evtchn_upcall_vector Date: Fri, 16 Dec 2022 00:41:00 +0000 Message-Id: <20221216004117.862106-22-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151470086100003 Content-Type: text/plain; charset="utf-8" From: Ankur Arora The HVMOP_set_evtchn_upcall_vector hypercall sets the per-vCPU upcall vector, to be delivered to the local APIC just like an MSI (with an EOI). This takes precedence over the system-wide delivery method set by the HVMOP_set_param hypercall with HVM_PARAM_CALLBACK_IRQ. It's used by Windows and Xen (PV shim) guests but normally not by Linux. Signed-off-by: Ankur Arora Signed-off-by: Joao Martins [dwmw2: Rework for upstream kernel changes and split from HVMOP_set_param] Signed-off-by: David Woodhouse --- target/i386/cpu.h | 1 + target/i386/kvm/kvm.c | 7 ++++ target/i386/kvm/trace-events | 1 + target/i386/kvm/xen-emu.c | 67 +++++++++++++++++++++++++++++++++--- target/i386/kvm/xen-emu.h | 1 + target/i386/machine.c | 4 ++- 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index bf44a87ddb..938a1b9c8b 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1792,6 +1792,7 @@ typedef struct CPUArchState { uint64_t xen_vcpu_info_default_gpa; uint64_t xen_vcpu_time_info_gpa; uint64_t xen_vcpu_runstate_gpa; + uint8_t xen_vcpu_callback_vector; #endif #if defined(CONFIG_HVF) HVFX86LazyFlags hvf_lflags; diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 8aee95d4c1..cbf41d6f81 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -4757,6 +4757,13 @@ int kvm_arch_put_registers(CPUState *cpu, int level) return ret; } } + + if (x86_cpu->env.xen_vcpu_callback_vector) { + ret =3D kvm_xen_set_vcpu_callback_vector(cpu); + if (ret < 0) { + return ret; + } + } } #endif =20 diff --git a/target/i386/kvm/trace-events b/target/i386/kvm/trace-events index 14e54dfca5..6133f6dd9e 100644 --- a/target/i386/kvm/trace-events +++ b/target/i386/kvm/trace-events @@ -10,3 +10,4 @@ kvm_x86_update_msi_routes(int num) "Updated %d MSI routes" kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint6= 4_t a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" P= RIu64 " a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64 kvm_xen_set_shared_info(uint64_t gfn) "shared info at gfn 0x%" PRIx64 kvm_xen_set_vcpu_attr(int cpu, int type, uint64_t gpa) "vcpu attr cpu %d t= ype %d gpa 0x%" PRIx64 +kvm_xen_set_vcpu_callback(int cpu, int vector) "callback vcpu %d vector %d" diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 1297b37ee8..d35609563c 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -23,6 +23,7 @@ #include "standard-headers/xen/version.h" #include "standard-headers/xen/memory.h" #include "standard-headers/xen/hvm/hvm_op.h" +#include "standard-headers/xen/hvm/params.h" #include "standard-headers/xen/vcpu.h" =20 #include "xen-compat.h" @@ -145,7 +146,8 @@ static bool kvm_xen_hcall_xen_version(struct kvm_xen_ex= it *exit, X86CPU *cpu, fi.submap |=3D 1 << XENFEAT_writable_page_tables | 1 << XENFEAT_writable_descriptor_tables | 1 << XENFEAT_auto_translated_physmap | - 1 << XENFEAT_supervisor_mode_kernel; + 1 << XENFEAT_supervisor_mode_kernel | + 1 << XENFEAT_hvm_callback_vector; } =20 err =3D kvm_copy_to_gva(CPU(cpu), arg, &fi, sizeof(fi)); @@ -172,6 +174,29 @@ int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type,= uint64_t gpa) return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xhsi); } =20 +int kvm_xen_set_vcpu_callback_vector(CPUState *cs) +{ + uint8_t vector =3D X86_CPU(cs)->env.xen_vcpu_callback_vector; + struct kvm_xen_vcpu_attr xva; + + xva.type =3D KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR; + xva.u.vector =3D vector; + + trace_kvm_xen_set_vcpu_callback(cs->cpu_index, vector); + + return kvm_vcpu_ioctl(cs, KVM_XEN_HVM_SET_ATTR, &xva); +} + +static void do_set_vcpu_callback_vector(CPUState *cs, run_on_cpu_data data) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + env->xen_vcpu_callback_vector =3D data.host_int; + + kvm_xen_set_vcpu_callback_vector(cs); +} + static void do_set_vcpu_info_default_gpa(CPUState *cs, run_on_cpu_data dat= a) { X86CPU *cpu =3D X86_CPU(cs); @@ -385,17 +410,51 @@ static bool kvm_xen_hcall_memory_op(struct kvm_xen_ex= it *exit, X86CPU *cpu, return true; } =20 +static int kvm_xen_hcall_evtchn_upcall_vector(struct kvm_xen_exit *exit, + X86CPU *cpu, uint64_t arg) +{ + struct xen_hvm_evtchn_upcall_vector up; + CPUState *target_cs; + + /* No need for 32/64 compat handling */ + qemu_build_assert(sizeof(up) =3D=3D 8); + + if (kvm_copy_from_gva(CPU(cpu), arg, &up, sizeof(up))) { + return -EFAULT; + } + + if (up.vector < 0x10) { + return -EINVAL; + } + + target_cs =3D qemu_get_cpu(up.vcpu); + if (!target_cs) { + return -EINVAL; + } + + async_run_on_cpu(target_cs, do_set_vcpu_callback_vector, RUN_ON_CPU_HO= ST_INT(up.vector)); + return 0; +} + static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit *exit, X86CPU *cpu, int cmd, uint64_t arg) { + int ret =3D -ENOSYS; switch (cmd) { + case HVMOP_set_evtchn_upcall_vector: + ret =3D kvm_xen_hcall_evtchn_upcall_vector(exit, cpu, + exit->u.hcall.params[0]); + break; case HVMOP_pagetable_dying: - exit->u.hcall.result =3D -ENOSYS; - return true; + ret =3D -ENOSYS; + break; =20 default: - return false; + return false; } + + exit->u.hcall.result =3D ret; + return true; } =20 static int vcpuop_register_vcpu_info(CPUState *cs, CPUState *target, diff --git a/target/i386/kvm/xen-emu.h b/target/i386/kvm/xen-emu.h index 20da62d39f..58e4748d80 100644 --- a/target/i386/kvm/xen-emu.h +++ b/target/i386/kvm/xen-emu.h @@ -26,5 +26,6 @@ int kvm_xen_init(KVMState *s, uint32_t hypercall_msr); int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit); int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type, uint64_t gpa); +int kvm_xen_set_vcpu_callback_vector(CPUState *cs); =20 #endif /* QEMU_I386_KVM_XEN_EMU_H */ diff --git a/target/i386/machine.c b/target/i386/machine.c index 6a510e5cbd..09e13cf716 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -1265,7 +1265,8 @@ static bool xen_vcpu_needed(void *opaque) return (env->xen_vcpu_info_gpa !=3D UINT64_MAX || env->xen_vcpu_info_default_gpa !=3D UINT64_MAX || env->xen_vcpu_time_info_gpa !=3D UINT64_MAX || - env->xen_vcpu_runstate_gpa !=3D UINT64_MAX); + env->xen_vcpu_runstate_gpa !=3D UINT64_MAX || + env->xen_vcpu_callback_vector !=3D 0); } =20 static const VMStateDescription vmstate_xen_vcpu =3D { @@ -1278,6 +1279,7 @@ static const VMStateDescription vmstate_xen_vcpu =3D { VMSTATE_UINT64(env.xen_vcpu_info_default_gpa, X86CPU), VMSTATE_UINT64(env.xen_vcpu_time_info_gpa, X86CPU), VMSTATE_UINT64(env.xen_vcpu_runstate_gpa, X86CPU), + VMSTATE_UINT8(env.xen_vcpu_callback_vector, X86CPU), VMSTATE_END_OF_LIST() } }; --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152175653415.1376044254357; Thu, 15 Dec 2022 16:56:15 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynX-0005Mv-Uh; Thu, 15 Dec 2022 19:42:00 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0005Di-C4 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn6-0006eM-3i for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:36 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymy-00Azym-1v; Fri, 16 Dec 2022 00:41:30 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cP9-6y; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=W2YKH76DPZcxknW7uDaurgzD32goS9CDITUkkQXVnUQ=; b=e6SXJRX3hvR93KHMapaZCktwGv U7Ar2giuwnXidX1gqkOXt+TNT6IgN0chKPe6PlZPh2wlpHTVhcrBLmrY03xbc7uQTsGmmC+UESe/9 9GR660tsL4SVDLywHGGJcropK2hIACLV51oy5QKPxCHYNxk/3zIA2fxL7JmKTsWIJo5MP+OCN5ESU BPB7QpatCXZ4hXOPdjqtdLZcP9UMEtQTXf8iTHoLlLjr0qY2sRy3bvp4UMTS5bXf7T3c+1jBFaMU9 U9x9Znoh4CocW0FKdcnxLEZM4amNDjOcH4AaLE9m0AJqvFWAMtDwcMLdKMcc7CuimXlmGb19AODCJ e9uwlIwQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 22/38] i386/xen: HVMOP_set_param / HVM_PARAM_CALLBACK_IRQ Date: Fri, 16 Dec 2022 00:41:01 +0000 Message-Id: <20221216004117.862106-23-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152176641100006 From: Ankur Arora The HVM_PARAM_CALLBACK_IRQ parameter controls the system-wide event channel upcall method. The vector support is handled by KVM internally, when the evtchn_upcall_pending field in the vcpu_info is set. The GSI and PCI_INTX delivery methods are not supported. yet; those need to simulate a level-triggered event on the I/OAPIC. Add a 'xen_evtchn' device to host the migration state, as we'll shortly be adding a full event channel table there too. Signed-off-by: Ankur Arora Signed-off-by: Joao Martins [dwmw2: Rework for upstream kernel changes, split from per-VCPU vector] Signed-off-by: David Woodhouse --- hw/i386/kvm/meson.build | 5 +- hw/i386/kvm/xen_evtchn.c | 117 ++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 13 +++++ hw/i386/pc.c | 2 + target/i386/kvm/xen-emu.c | 39 +++++++++++++ 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 hw/i386/kvm/xen_evtchn.c create mode 100644 hw/i386/kvm/xen_evtchn.h diff --git a/hw/i386/kvm/meson.build b/hw/i386/kvm/meson.build index 6165cbf019..cab64df339 100644 --- a/hw/i386/kvm/meson.build +++ b/hw/i386/kvm/meson.build @@ -4,6 +4,9 @@ i386_kvm_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c= ')) i386_kvm_ss.add(when: 'CONFIG_I8254', if_true: files('i8254.c')) i386_kvm_ss.add(when: 'CONFIG_I8259', if_true: files('i8259.c')) i386_kvm_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c')) -i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen_overlay.c')) +i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files( + 'xen_overlay.c', + 'xen_evtchn.c', + )) =20 i386_ss.add_all(when: 'CONFIG_KVM', if_true: i386_kvm_ss) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c new file mode 100644 index 0000000000..1ca0c034e7 --- /dev/null +++ b/hw/i386/kvm/xen_evtchn.c @@ -0,0 +1,117 @@ +/* + * QEMU Xen emulation: Shared/overlay pages support + * + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: David Woodhouse + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/host-utils.h" +#include "qemu/module.h" +#include "qemu/main-loop.h" +#include "qapi/error.h" +#include "qom/object.h" +#include "exec/target_page.h" +#include "exec/address-spaces.h" +#include "migration/vmstate.h" + +#include "hw/sysbus.h" +#include "hw/xen/xen.h" +#include "xen_evtchn.h" + +#include "sysemu/kvm.h" +#include + +#include "standard-headers/xen/memory.h" +#include "standard-headers/xen/hvm/params.h" + +#define TYPE_XEN_EVTCHN "xenevtchn" +OBJECT_DECLARE_SIMPLE_TYPE(XenEvtchnState, XEN_EVTCHN) + +struct XenEvtchnState { + /*< private >*/ + SysBusDevice busdev; + /*< public >*/ + + uint64_t callback_param; +}; + +struct XenEvtchnState *xen_evtchn_singleton; + +static int xen_evtchn_post_load(void *opaque, int version_id) +{ + XenEvtchnState *s =3D opaque; + + if (s->callback_param) { + xen_evtchn_set_callback_param(s->callback_param); + } + + return 0; +} + +static bool xen_evtchn_is_needed(void *opaque) +{ + return xen_mode =3D=3D XEN_EMULATE; +} + +static const VMStateDescription xen_evtchn_vmstate =3D { + .name =3D "xen_evtchn", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D xen_evtchn_is_needed, + .post_load =3D xen_evtchn_post_load, + .fields =3D (VMStateField[]) { + VMSTATE_UINT64(callback_param, XenEvtchnState), + VMSTATE_END_OF_LIST() + } +}; + +static void xen_evtchn_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->vmsd =3D &xen_evtchn_vmstate; +} + +static const TypeInfo xen_evtchn_info =3D { + .name =3D TYPE_XEN_EVTCHN, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(XenEvtchnState), + .class_init =3D xen_evtchn_class_init, +}; + +void xen_evtchn_create(void) +{ + xen_evtchn_singleton =3D XEN_EVTCHN(sysbus_create_simple(TYPE_XEN_EVTC= HN, -1, NULL)); +} + +static void xen_evtchn_register_types(void) +{ + type_register_static(&xen_evtchn_info); +} + +type_init(xen_evtchn_register_types) + + +#define CALLBACK_VIA_TYPE_SHIFT 56 + +int xen_evtchn_set_callback_param(uint64_t param) +{ + int ret =3D -ENOSYS; + + if (param >> CALLBACK_VIA_TYPE_SHIFT =3D=3D HVM_PARAM_CALLBACK_TYPE_VE= CTOR) { + struct kvm_xen_hvm_attr xa =3D { + .type =3D KVM_XEN_ATTR_TYPE_UPCALL_VECTOR, + .u.vector =3D (uint8_t)param, + }; + + ret =3D kvm_vm_ioctl(kvm_state, KVM_XEN_HVM_SET_ATTR, &xa); + if (!ret && xen_evtchn_singleton) + xen_evtchn_singleton->callback_param =3D param; + } + return ret; +} diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h new file mode 100644 index 0000000000..11c6ed22a0 --- /dev/null +++ b/hw/i386/kvm/xen_evtchn.h @@ -0,0 +1,13 @@ +/* + * QEMU Xen emulation: Event channel support + * + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: David Woodhouse + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +void xen_evtchn_create(void); +int xen_evtchn_set_callback_param(uint64_t param); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index f1780daa4c..427f79e6a8 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -90,6 +90,7 @@ #include "hw/virtio/virtio-pmem-pci.h" #include "hw/virtio/virtio-mem-pci.h" #include "hw/i386/kvm/xen_overlay.h" +#include "hw/i386/kvm/xen_evtchn.h" #include "hw/mem/memory-device.h" #include "sysemu/replay.h" #include "target/i386/cpu.h" @@ -1848,6 +1849,7 @@ int pc_machine_kvm_type(MachineState *machine, const = char *kvm_type) #ifdef CONFIG_XEN_EMU if (xen_mode =3D=3D XEN_EMULATE) { xen_overlay_create(); + xen_evtchn_create(); } #endif return 0; diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index d35609563c..09978c83ca 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -20,6 +20,8 @@ #include "xen-emu.h" #include "trace.h" #include "hw/i386/kvm/xen_overlay.h" +#include "hw/i386/kvm/xen_evtchn.h" + #include "standard-headers/xen/version.h" #include "standard-headers/xen/memory.h" #include "standard-headers/xen/hvm/hvm_op.h" @@ -410,6 +412,40 @@ static bool kvm_xen_hcall_memory_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, return true; } =20 +static bool handle_set_param(struct kvm_xen_exit *exit, X86CPU *cpu, + uint64_t arg) +{ + CPUState *cs =3D CPU(cpu); + struct xen_hvm_param hp; + int err =3D 0; + + /* No need for 32/64 compat handling */ + qemu_build_assert(sizeof(hp) =3D=3D 16); + + if (kvm_copy_from_gva(cs, arg, &hp, sizeof(hp))) { + err =3D -EFAULT; + goto out; + } + + if (hp.domid !=3D DOMID_SELF) { + err =3D -EINVAL; + goto out; + } + + switch (hp.index) { + case HVM_PARAM_CALLBACK_IRQ: + err =3D xen_evtchn_set_callback_param(hp.value); + xen_set_long_mode(exit->u.hcall.longmode); + break; + default: + return false; + } + +out: + exit->u.hcall.result =3D err; + return true; +} + static int kvm_xen_hcall_evtchn_upcall_vector(struct kvm_xen_exit *exit, X86CPU *cpu, uint64_t arg) { @@ -449,6 +485,9 @@ static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit *e= xit, X86CPU *cpu, ret =3D -ENOSYS; break; =20 + case HVMOP_set_param: + return handle_set_param(exit, cpu, arg); + default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152129718524.7310722476625; Thu, 15 Dec 2022 16:55:29 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yoC-0005oD-83; Thu, 15 Dec 2022 19:42:40 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0005Dm-Cz for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006aK-5H for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:36 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV0-82; Fri, 16 Dec 2022 00:41:33 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cPC-7p; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=W9l0xAzjVivxbJ+Yz8tRFxlKa/UOkP/hXTZkxh0gAx0=; b=qKefyFLfn6ysJuTS4Lwr3gzTT5 fVBS4128YUcM4ExiU/ItUx5V383/rhfyvRnJ4xwh0pUL0I+IlBe9pZjijRIpm8m9a3DjHQQGxQHbd msrWMga6gArBoq+ftV4AZKM3AzYnX4QyT7RkXVDJdrgFGaNUAFu5XdAYM3n8MmyFocw6GgQJLfTXF PkAX8H2PJ1WGIVwDlqUIM06Ap9v2py+KnI5IZr4YdbbG4udpCQppM0pWGZYGjOZnnJbSDC+FUl+t6 O/DemM2rFkesy6K7uyNJt5UAsxGe/mrtFkeh0763nIftIH42vKLnzV5IEpzmFHcUaTIgqkZIbScmr 5shVjw4w==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 23/38] i386/xen: implement HYPERVISOR_event_channel_op Date: Fri, 16 Dec 2022 00:41:02 +0000 Message-Id: <20221216004117.862106-24-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152130512100001 Content-Type: text/plain; charset="utf-8" From: Joao Martins Additionally set XEN_INTERFACE_VERSION to most recent in order to exercise the "new" event_channel_op. Signed-off-by: Joao Martins [dwmw2: Ditch event_channel_op_compat which was never available to HVM gues= ts] Signed-off-by: David Woodhouse --- target/i386/kvm/xen-emu.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 09978c83ca..d6f3102d8e 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -27,6 +27,7 @@ #include "standard-headers/xen/hvm/hvm_op.h" #include "standard-headers/xen/hvm/params.h" #include "standard-headers/xen/vcpu.h" +#include "standard-headers/xen/event_channel.h" =20 #include "xen-compat.h" =20 @@ -611,6 +612,23 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit = *exit, X86CPU *cpu, return true; } =20 +static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exit *exit, + int cmd, uint64_t arg) +{ + int err =3D -ENOSYS; + + switch (cmd) { + case EVTCHNOP_init_control: + err =3D -ENOSYS; + break; + default: + return false; + } + + exit->u.hcall.result =3D err; + return true; +} + static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) { uint16_t code =3D exit->u.hcall.input; @@ -621,6 +639,9 @@ static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct = kvm_xen_exit *exit) } =20 switch (code) { + case __HYPERVISOR_event_channel_op: + return kvm_xen_hcall_evtchn_op(exit, exit->u.hcall.params[0], + exit->u.hcall.params[1]); case __HYPERVISOR_vcpu_op: return kvm_xen_hcall_vcpu_op(exit, cpu, exit->u.hcall.params[0], --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151526669420.4834192137132; Thu, 15 Dec 2022 16:45:26 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yok-0006mE-6y; Thu, 15 Dec 2022 19:43:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynG-0005Fd-P3 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:45 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynB-0006cs-VS for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:42 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymx-00Azyv-9o; Fri, 16 Dec 2022 00:41:27 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cPF-8c; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=7UcMPqOUFVHrvjG6b85D3YQtF72RKPxFv/Mlkkh4KII=; b=qN4QyPmVQ8Fg0DwqGhvpGW2XZW 76P/aTt840bGLqOfAK60oHBpLkgnqtQkEhnmiP8oiVXgWOZE67IylTVwNpIBzZVeDGD8l50sGx6mf rQa2LMgtrNH06w7JQRLx0X97kNCkKWMXjN8Sf9iCCfeM5P1flYUOIna3Ug+JnTc9GM4gabGTgCMSM 789Y9T0kW/Eqx7EHT0wdUOgk+CnO50uK4nlbXXdKxzZjBPjLvl2+ocS7UPW3OYHtv1MMEHjTYlzJ1 48D9JtkwnW3r0oXGEIsCRbnzgMhLuBLaGhtoKN/36/Zu6aJf/iNIs1s6U0lH+cQcO+9ZEooVjpw5p Hitr5HHQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 24/38] i386/xen: implement HYPERVISOR_sched_op Date: Fri, 16 Dec 2022 00:41:03 +0000 Message-Id: <20221216004117.862106-25-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151528345100003 Content-Type: text/plain; charset="utf-8" From: Joao Martins It allows to shutdown itself via hypercall with any of the 3 reasons: 1) self-reboot 2) shutdown 3) crash Implementing SCHEDOP_shutdown sub op let us handle crashes gracefully rather than leading to triple faults if it remains unimplemented. Signed-off-by: Joao Martins [dwmw2: Ditch sched_op_compat which was never available for HVM guests] Signed-off-by: David Woodhouse --- target/i386/kvm/xen-emu.c | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index d6f3102d8e..1ff6d32edd 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -21,12 +21,14 @@ #include "trace.h" #include "hw/i386/kvm/xen_overlay.h" #include "hw/i386/kvm/xen_evtchn.h" +#include "sysemu/runstate.h" =20 #include "standard-headers/xen/version.h" #include "standard-headers/xen/memory.h" #include "standard-headers/xen/hvm/hvm_op.h" #include "standard-headers/xen/hvm/params.h" #include "standard-headers/xen/vcpu.h" +#include "standard-headers/xen/sched.h" #include "standard-headers/xen/event_channel.h" =20 #include "xen-compat.h" @@ -629,6 +631,59 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, return true; } =20 +static int schedop_shutdown(CPUState *cs, uint64_t arg) +{ + struct sched_shutdown shutdown; + int ret =3D 0; + + /* No need for 32/64 compat handling */ + qemu_build_assert(sizeof(shutdown) =3D=3D 4); + + if (kvm_copy_from_gva(cs, arg, &shutdown, sizeof(shutdown))) { + return -EFAULT; + } + + switch(shutdown.reason) { + case SHUTDOWN_crash: + cpu_dump_state(cs, stderr, CPU_DUMP_CODE); + qemu_system_guest_panicked(NULL); + break; + + case SHUTDOWN_reboot: + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + break; + + case SHUTDOWN_poweroff: + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); + break; + + default: + ret =3D -EINVAL; + break; + } + + return ret; +} + +static bool kvm_xen_hcall_sched_op(struct kvm_xen_exit *exit, X86CPU *cpu, + int cmd, uint64_t arg) +{ + CPUState *cs =3D CPU(cpu); + int err =3D -ENOSYS; + + switch (cmd) { + case SCHEDOP_shutdown: + err =3D schedop_shutdown(cs, arg); + break; + + default: + return false; + } + + exit->u.hcall.result =3D err; + return true; +} + static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit) { uint16_t code =3D exit->u.hcall.input; @@ -639,6 +694,9 @@ static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct = kvm_xen_exit *exit) } =20 switch (code) { + case __HYPERVISOR_sched_op: + return kvm_xen_hcall_sched_op(exit, cpu, exit->u.hcall.params[0], + exit->u.hcall.params[1]); case __HYPERVISOR_event_channel_op: return kvm_xen_hcall_evtchn_op(exit, exit->u.hcall.params[0], exit->u.hcall.params[1]); --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151468068550.3891460726485; Thu, 15 Dec 2022 16:44:28 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yo2-0005kS-9N; Thu, 15 Dec 2022 19:42:31 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynI-0005Fm-GK for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:46 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0006bN-MQ for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:44 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvUz-7B; Fri, 16 Dec 2022 00:41:36 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cPI-9L; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=xiB6Zv+Mz0wwjJUtAaHEfH8WlJgQDa7qtA4LR5bBdHw=; b=mJtZn28/rnNUFfTedCt8iI8TDZ tDuL8iecL2XNh7zI3M61euWsD7o9HC4V+9Jq4KxsuaeQTuh9Iiotzrup9/Zqg7kTd9vFSZQ9NUbsg 3gAq9Ji+CnAT8s0Ksvk6SzlD06ySb2hSLCQCaWnPt/N+khmewRjZIgQqSMwBMP13ASddHhsWNoz5s OFuIe8oSJktsdnoH+fWgepwAs6+rHWOPLRdFppR1j/txzay2IgK501S0HcB7gkodcl3XTW5bxQAT+ FLWEOMsNXnjhjdDACxlmmHZhjz73FyBO1Ancs/PpNJw2DmP4z1hJJOFD8Aj+qxvPivJt8XodFVbDi mPJyaN6Q==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 25/38] hw/xen: Implement EVTCHNOP_status Date: Fri, 16 Dec 2022 00:41:04 +0000 Message-Id: <20221216004117.862106-26-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151470089100004 Content-Type: text/plain; charset="utf-8" From: David Woodhouse This adds the basic structure for maintaining the port table and reporting the status of ports therein. Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 108 +++++++++++++++++++++++++++++++++++++- hw/i386/kvm/xen_evtchn.h | 4 ++ target/i386/kvm/xen-emu.c | 21 +++++++- 3 files changed, 130 insertions(+), 3 deletions(-) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 1ca0c034e7..77acf58540 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -22,6 +22,7 @@ #include "hw/sysbus.h" #include "hw/xen/xen.h" #include "xen_evtchn.h" +#include "xen_overlay.h" =20 #include "sysemu/kvm.h" #include @@ -32,12 +33,34 @@ #define TYPE_XEN_EVTCHN "xenevtchn" OBJECT_DECLARE_SIMPLE_TYPE(XenEvtchnState, XEN_EVTCHN) =20 +typedef struct XenEvtchnPort { + uint32_t vcpu; /* Xen/ACPI vcpu_id */ + uint16_t type; /* EVTCHNSTAT_xxxx */ + uint16_t type_val; /* pirq# / virq# / remote port according to type */ +} XenEvtchnPort; + +#define COMPAT_EVTCHN_2L_NR_CHANNELS 1024 + +/* + * For unbound/interdomain ports there are only two possible remote + * domains; self and QEMU. Use a single high bit in type_val for that, + * and the low bits for the remote port number (or 0 for unbound). + */ +#define PORT_INFO_TYPEVAL_REMOTE_QEMU 0x8000 +#define PORT_INFO_TYPEVAL_REMOTE_PORT_MASK 0x7FFF + +#define DOMID_QEMU 0 + struct XenEvtchnState { /*< private >*/ SysBusDevice busdev; /*< public >*/ =20 uint64_t callback_param; + + QemuMutex port_lock; + uint32_t nr_ports; + XenEvtchnPort port_table[EVTCHN_2L_NR_CHANNELS]; }; =20 struct XenEvtchnState *xen_evtchn_singleton; @@ -58,6 +81,18 @@ static bool xen_evtchn_is_needed(void *opaque) return xen_mode =3D=3D XEN_EMULATE; } =20 +static const VMStateDescription xen_evtchn_port_vmstate =3D { + .name =3D "xen_evtchn_port", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(vcpu, XenEvtchnPort), + VMSTATE_UINT16(type, XenEvtchnPort), + VMSTATE_UINT16(type_val, XenEvtchnPort), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription xen_evtchn_vmstate =3D { .name =3D "xen_evtchn", .version_id =3D 1, @@ -66,6 +101,9 @@ static const VMStateDescription xen_evtchn_vmstate =3D { .post_load =3D xen_evtchn_post_load, .fields =3D (VMStateField[]) { VMSTATE_UINT64(callback_param, XenEvtchnState), + VMSTATE_UINT32(nr_ports, XenEvtchnState), + VMSTATE_STRUCT_VARRAY_UINT32(port_table, XenEvtchnState, nr_ports,= 1, + xen_evtchn_port_vmstate, XenEvtchnPor= t), VMSTATE_END_OF_LIST() } }; @@ -86,7 +124,10 @@ static const TypeInfo xen_evtchn_info =3D { =20 void xen_evtchn_create(void) { - xen_evtchn_singleton =3D XEN_EVTCHN(sysbus_create_simple(TYPE_XEN_EVTC= HN, -1, NULL)); + XenEvtchnState *s =3D XEN_EVTCHN(sysbus_create_simple(TYPE_XEN_EVTCHN,= -1, NULL)); + xen_evtchn_singleton =3D s; + + qemu_mutex_init(&s->port_lock); } =20 static void xen_evtchn_register_types(void) @@ -115,3 +156,68 @@ int xen_evtchn_set_callback_param(uint64_t param) } return ret; } + +static bool valid_port(evtchn_port_t port) +{ + if (!port) { + return false; + } + + if (xen_is_long_mode()) { + return port < EVTCHN_2L_NR_CHANNELS; + } else { + return port < COMPAT_EVTCHN_2L_NR_CHANNELS; + } +} + +int xen_evtchn_status_op(struct evtchn_status *status) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + XenEvtchnPort *p; + + if (!s) { + return -ENOTSUP; + } + + if (status->dom !=3D DOMID_SELF && status->dom !=3D xen_domid) + return -EPERM; + + if (!valid_port(status->port)) + return -EINVAL; + + qemu_mutex_lock(&s->port_lock); + + p =3D &s->port_table[status->port]; + + status->status =3D p->type; + status->vcpu =3D p->vcpu; + + switch (p->type) { + case EVTCHNSTAT_unbound: + if (p->type_val & PORT_INFO_TYPEVAL_REMOTE_QEMU) + status->u.unbound.dom =3D DOMID_QEMU; + else + status->u.unbound.dom =3D xen_domid; + break; + + case EVTCHNSTAT_interdomain: + if (p->type_val & PORT_INFO_TYPEVAL_REMOTE_QEMU) + status->u.interdomain.dom =3D DOMID_QEMU; + else + status->u.interdomain.dom =3D xen_domid; + + status->u.interdomain.port =3D p->type_val & PORT_INFO_TYPEVAL_REM= OTE_PORT_MASK; + break; + + case EVTCHNSTAT_pirq: + status->u.pirq =3D p->type_val; + break; + + case EVTCHNSTAT_virq: + status->u.virq =3D p->type_val; + break; + } + + qemu_mutex_unlock(&s->port_lock); + return 0; +} diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index 11c6ed22a0..6f50e5c52d 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -9,5 +9,9 @@ * See the COPYING file in the top-level directory. */ =20 + void xen_evtchn_create(void); int xen_evtchn_set_callback_param(uint64_t param); + +struct evtchn_status; +int xen_evtchn_status_op(struct evtchn_status *status); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 1ff6d32edd..d4a35bef64 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -614,15 +614,32 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_xen_exit= *exit, X86CPU *cpu, return true; } =20 -static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exit *exit, +static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exit *exit, X86CPU *cpu, int cmd, uint64_t arg) { + CPUState *cs =3D CPU(cpu); int err =3D -ENOSYS; =20 switch (cmd) { case EVTCHNOP_init_control: err =3D -ENOSYS; break; + + case EVTCHNOP_status: { + struct evtchn_status status; + + qemu_build_assert(sizeof(status) =3D=3D 24); + if (kvm_copy_from_gva(cs, arg, &status, sizeof(status))) { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_status_op(&status); + if (!err && kvm_copy_to_gva(cs, arg, &status, sizeof(status))) { + err =3D -EFAULT; + } + break; + } default: return false; } @@ -698,7 +715,7 @@ static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct = kvm_xen_exit *exit) return kvm_xen_hcall_sched_op(exit, cpu, exit->u.hcall.params[0], exit->u.hcall.params[1]); case __HYPERVISOR_event_channel_op: - return kvm_xen_hcall_evtchn_op(exit, exit->u.hcall.params[0], + return kvm_xen_hcall_evtchn_op(exit, cpu, exit->u.hcall.params[0], exit->u.hcall.params[1]); case __HYPERVISOR_vcpu_op: return kvm_xen_hcall_vcpu_op(exit, cpu, --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151343789965.5827578848865; Thu, 15 Dec 2022 16:42:23 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynF-0005Ds-Ua; Thu, 15 Dec 2022 19:41:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0005D6-Cb for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:36 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn5-0006aM-AT for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:33 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvV9-8C; Fri, 16 Dec 2022 00:41:33 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cPL-A8; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=cSKxzKfvouPFGYFcxXOq0p0UCfDdKppUVWOt4h+XFHk=; b=YSwfVK87gBmJE+EJ+1xYNDY/q9 caAMNdPg2GdJRrOdI9srirUZspudLB0hOkKwW1MHKCwSCwC2dJTASqfwYIoHU/DcRU45mVpVuKRQY peLfuZLfkkMT78jQgrlbm+bwpE22xwdPKPczg+CBJXynHNszYJataBJwBqv4z028sFTNZyadL9ajh lrvN2AQvDG8RmfMmkUB0zNCHHDNSq5jowf8FH4WwABeWkrKRGW0gUJcn5fwGbSBLRmhw2qm3z6bCt qTZA4HsYdc7uHZ1f3RS+TJJU6Uh7u8BA78/hGuQ64yYLBCAFKELYi87+nCyCUa69BuLVpLm7BrC/e 5E796wng==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 26/38] hw/xen: Implement EVTCHNOP_close Date: Fri, 16 Dec 2022 00:41:05 +0000 Message-Id: <20221216004117.862106-27-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151346186100007 Content-Type: text/plain; charset="utf-8" From: David Woodhouse It calls an internal close_port() helper which will also be used from EVTCHNOP_reset and will actually do the work to disconnect/unbind a port once any of that is actually implemented in the first place. That in turn calls a free_port() internal function which will be in error paths after allocation. Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 51 +++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 2 ++ target/i386/kvm/xen-emu.c | 12 +++++++++ 3 files changed, 65 insertions(+) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 77acf58540..d4008e7ee1 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -221,3 +221,54 @@ int xen_evtchn_status_op(struct evtchn_status *status) qemu_mutex_unlock(&s->port_lock); return 0; } + +static void free_port(XenEvtchnState *s, evtchn_port_t port) +{ + s->port_table[port].type =3D EVTCHNSTAT_closed; + s->port_table[port].type_val =3D 0; + s->port_table[port].vcpu =3D 0; + + if (s->nr_ports =3D=3D port + 1) { + do { + s->nr_ports--; + } while (s->port_table[s->nr_ports - 1].type =3D=3D EVTCHNSTAT_clo= sed); + } +} + +static int close_port(XenEvtchnState *s, evtchn_port_t port) +{ + XenEvtchnPort *p =3D &s->port_table[port]; + + switch (p->type) { + case EVTCHNSTAT_closed: + return -ENOENT; + + default: + break; + } + + free_port(s, port); + return 0; +} + +int xen_evtchn_close_op(struct evtchn_close *close) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + int ret; + + if (!s) { + return -ENOTSUP; + } + + if (!valid_port(close->port)) { + return -EINVAL; + } + + qemu_mutex_lock(&s->port_lock); + + ret =3D close_port(s, close->port); + + qemu_mutex_unlock(&s->port_lock); + + return ret; +} diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index 6f50e5c52d..4c00000315 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -14,4 +14,6 @@ void xen_evtchn_create(void); int xen_evtchn_set_callback_param(uint64_t param); =20 struct evtchn_status; +struct evtchn_close; int xen_evtchn_status_op(struct evtchn_status *status); +int xen_evtchn_close_op(struct evtchn_close *close); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index d4a35bef64..f57d99f9d6 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -640,6 +640,18 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, } break; } + case EVTCHNOP_close: { + struct evtchn_close close; + + qemu_build_assert(sizeof(close) =3D=3D 4); + if (kvm_copy_from_gva(cs, arg, &close, sizeof(close))) { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_close_op(&close); + break; + } default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151726985726.3516035503633; Thu, 15 Dec 2022 16:48:46 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yok-0006n7-6j; Thu, 15 Dec 2022 19:43:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynW-0005MH-S3 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:58 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynU-0006lr-0l for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:58 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymz-00Azyx-9H; Fri, 16 Dec 2022 00:41:44 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cPn-As; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=woARrJmRgiliWU/s2kD+HXuiJgoIfPM64yxExCX209A=; b=GsdkGRX7Q96KTPLIvL58h+qCBY v9jbqWd1j/QZ75NrbcDwgUjLA77AOjXDB2vDoZ4kFr+7Heas4B+fqw0vrBLEqOYPQPS6o8GB/XFrQ p/OXGQa2ZbWdId7DgfFN00BfsBGBFX7jHsejnmmHm+GRxsfOEvCJFYhU9g3nNc9JE/FZ9tMjbyL5w IWcU6ZZHLmz7L+wEWJfVGRY2PWBulkU0GgaO9sAPQgTBzX093OqR9r57R0/JwtNmDrssvnsS9jvwc vBFPf3tNOw3yrTdldO7Epp3fcq/1nVbyrKlC5jcFD797LU4RH9WAurq0fAz+UJwyp2JC5OinSprYO Cvx8+jOQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 27/38] hw/xen: Implement EVTCHNOP_unmask Date: Fri, 16 Dec 2022 00:41:06 +0000 Message-Id: <20221216004117.862106-28-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151728169100001 From: David Woodhouse This finally comes with a mechanism for actually injecting events into the guest vCPU, with all the atomic-test-and-set that's involved in setting the bit in the shinfo, then the index in the vcpu_info, and injecting either the lapic vector as MSI, or letting KVM inject the bare vector. Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 198 ++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 2 + include/sysemu/kvm_xen.h | 18 ++++ target/i386/kvm/xen-emu.c | 72 ++++++++++++++ 4 files changed, 290 insertions(+) create mode 100644 include/sysemu/kvm_xen.h diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index d4008e7ee1..50adef0864 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -21,10 +21,13 @@ =20 #include "hw/sysbus.h" #include "hw/xen/xen.h" + #include "xen_evtchn.h" #include "xen_overlay.h" =20 #include "sysemu/kvm.h" +#include "sysemu/kvm_xen.h" + #include =20 #include "standard-headers/xen/memory.h" @@ -39,6 +42,41 @@ typedef struct XenEvtchnPort { uint16_t type_val; /* pirq# / virq# / remote port according to type */ } XenEvtchnPort; =20 +/* 32-bit compatibility definitions, also used natively in 32-bit build */ +struct compat_arch_vcpu_info { + unsigned int cr2; + unsigned int pad[5]; +}; + +struct compat_vcpu_info { + uint8_t evtchn_upcall_pending; + uint8_t evtchn_upcall_mask; + uint16_t pad; + uint32_t evtchn_pending_sel; + struct compat_arch_vcpu_info arch; + struct vcpu_time_info time; +}; /* 64 bytes (x86) */ + +struct compat_arch_shared_info { + unsigned int max_pfn; + unsigned int pfn_to_mfn_frame_list_list; + unsigned int nmi_reason; + unsigned int p2m_cr3; + unsigned int p2m_vaddr; + unsigned int p2m_generation; + uint32_t wc_sec_hi; +}; + +struct compat_shared_info { + struct compat_vcpu_info vcpu_info[XEN_LEGACY_MAX_VCPUS]; + uint32_t evtchn_pending[32]; + uint32_t evtchn_mask[32]; + uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */ + uint32_t wc_sec; + uint32_t wc_nsec; + struct compat_arch_shared_info arch; +}; + #define COMPAT_EVTCHN_2L_NR_CHANNELS 1024 =20 /* @@ -222,6 +260,144 @@ int xen_evtchn_status_op(struct evtchn_status *status) return 0; } =20 +/* + * Never thought I'd hear myself say this, but C++ templates would be + * kind of nice here. + * + * template static int do_unmask_port(T *shinfo, ...); + */ +static int do_unmask_port_lm(XenEvtchnState *s, evtchn_port_t port, + bool do_unmask, struct shared_info *shinfo, + struct vcpu_info *vcpu_info) +{ + const int bits_per_word =3D BITS_PER_BYTE * sizeof(shinfo->evtchn_pend= ing[0]); + typeof(shinfo->evtchn_pending[0]) mask; + int idx =3D port / bits_per_word; + int offset =3D port % bits_per_word; + + mask =3D 1UL << offset; + + if (idx >=3D bits_per_word) { + return -EINVAL; + } + + if (do_unmask) { + /* If this is a true unmask operation, clear the mask bit. If + * it was already unmasked, we have nothing further to do. */ + if (!((qatomic_fetch_and(&shinfo->evtchn_mask[idx], ~mask) & mask)= )) { + return 0; + } + } else { + /* This is a pseudo-unmask for affinity changes. We don't + * change the mask bit, and if it's *masked* we have nothing + * else to do. */ + if (qatomic_fetch_or(&shinfo->evtchn_mask[idx], 0) & mask) { + return 0; + } + } + + /* If the event was not pending, we're done. */ + if (!(qatomic_fetch_or(&shinfo->evtchn_pending[idx], 0) & mask)) { + return 0; + } + + /* Now on to the vcpu_info evtchn_pending_sel index... */ + mask =3D 1UL << idx; + + /* If a port in this word was already pending for this vCPU, all done.= */ + if (qatomic_fetch_or(&vcpu_info->evtchn_pending_sel, mask) & mask) { + return 0; + } + + /* Set evtchn_upcall_pending for this vCPU */ + if (qatomic_fetch_or(&vcpu_info->evtchn_upcall_pending, 1)) { + return 0; + } + + kvm_xen_inject_vcpu_callback_vector(s->port_table[port].vcpu); + + return 0; +} + +static int do_unmask_port_compat(XenEvtchnState *s, evtchn_port_t port, + bool do_unmask, + struct compat_shared_info *shinfo, + struct compat_vcpu_info *vcpu_info) +{ + const int bits_per_word =3D BITS_PER_BYTE * sizeof(shinfo->evtchn_pend= ing[0]); + typeof(shinfo->evtchn_pending[0]) mask; + int idx =3D port / bits_per_word; + int offset =3D port % bits_per_word; + + mask =3D 1UL << offset; + + if (idx >=3D bits_per_word) { + return -EINVAL; + } + + if (do_unmask) { + /* If this is a true unmask operation, clear the mask bit. If + * it was already unmasked, we have nothing further to do. */ + if (!((qatomic_fetch_and(&shinfo->evtchn_mask[idx], ~mask) & mask)= )) { + return 0; + } + } else { + /* This is a pseudo-unmask for affinity changes. We don't + * change the mask bit, and if it's *masked* we have nothing + * else to do. */ + if (qatomic_fetch_or(&shinfo->evtchn_mask[idx], 0) & mask) { + return 0; + } + } + + /* If the event was not pending, we're done. */ + if (!(qatomic_fetch_or(&shinfo->evtchn_pending[idx], 0) & mask)) { + return 0; + } + + /* Now on to the vcpu_info evtchn_pending_sel index... */ + mask =3D 1UL << idx; + + /* If a port in this word was already pending for this vCPU, all done.= */ + if (qatomic_fetch_or(&vcpu_info->evtchn_pending_sel, mask) & mask) { + return 0; + } + + /* Set evtchn_upcall_pending for this vCPU */ + if (qatomic_fetch_or(&vcpu_info->evtchn_upcall_pending, 1)) { + return 0; + } + + kvm_xen_inject_vcpu_callback_vector(s->port_table[port].vcpu); + + return 0; +} + +static int unmask_port(XenEvtchnState *s, evtchn_port_t port, bool do_unma= sk) +{ + void *vcpu_info, *shinfo; + + if (s->port_table[port].type =3D=3D EVTCHNSTAT_closed) { + return -EINVAL; + } + + shinfo =3D xen_overlay_page_ptr(XENMAPSPACE_shared_info, 0); + if (!shinfo) { + return -ENOTSUP; + } + + vcpu_info =3D kvm_xen_get_vcpu_info_hva(s->port_table[port].vcpu); + if (!vcpu_info) { + return -EINVAL; + } + + if (xen_is_long_mode()) { + return do_unmask_port_lm(s, port, do_unmask, shinfo, vcpu_info); + } else { + return do_unmask_port_compat(s, port, do_unmask, shinfo, vcpu_info= ); + } +} + static void free_port(XenEvtchnState *s, evtchn_port_t port) { s->port_table[port].type =3D EVTCHNSTAT_closed; @@ -272,3 +448,25 @@ int xen_evtchn_close_op(struct evtchn_close *close) =20 return ret; } + +int xen_evtchn_unmask_op(struct evtchn_unmask *unmask) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + int ret; + + if (!s) { + return -ENOTSUP; + } + + if (!valid_port(unmask->port)) { + return -EINVAL; + } + + qemu_mutex_lock(&s->port_lock); + + ret =3D unmask_port(s, unmask->port, true); + + qemu_mutex_unlock(&s->port_lock); + + return ret; +} diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index 4c00000315..2fb7d70043 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -15,5 +15,7 @@ int xen_evtchn_set_callback_param(uint64_t param); =20 struct evtchn_status; struct evtchn_close; +struct evtchn_unmask; int xen_evtchn_status_op(struct evtchn_status *status); int xen_evtchn_close_op(struct evtchn_close *close); +int xen_evtchn_unmask_op(struct evtchn_unmask *unmask); diff --git a/include/sysemu/kvm_xen.h b/include/sysemu/kvm_xen.h new file mode 100644 index 0000000000..ab629feb13 --- /dev/null +++ b/include/sysemu/kvm_xen.h @@ -0,0 +1,18 @@ +/* + * Xen HVM emulation support in KVM + * + * Copyright =C2=A9 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_SYSEMU_KVM_XEN_H +#define QEMU_SYSEMU_KVM_XEN_H + +void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id); +void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id); + +#endif /* QEMU_SYSEMU_KVM_XEN_H */ diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index f57d99f9d6..51cb6bf052 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -15,10 +15,13 @@ #include "qemu/log.h" #include "hw/xen/xen.h" #include "sysemu/kvm_int.h" +#include "sysemu/kvm_xen.h" #include "kvm/kvm_i386.h" #include "exec/address-spaces.h" #include "xen-emu.h" #include "trace.h" +#include "hw/pci/msi.h" +#include "hw/i386/apic-msidef.h" #include "hw/i386/kvm/xen_overlay.h" #include "hw/i386/kvm/xen_evtchn.h" #include "sysemu/runstate.h" @@ -227,6 +230,63 @@ static void do_set_vcpu_info_gpa(CPUState *cs, run_on_= cpu_data data) env->xen_vcpu_info_gpa); } =20 + +static void *gpa_to_hva(uint64_t gpa) +{ + MemoryRegionSection mrs; + + mrs =3D memory_region_find(get_system_memory(), gpa, 1); + return !mrs.mr ? NULL : qemu_map_ram_ptr(mrs.mr->ram_block, + mrs.offset_within_region); +} + +void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id) +{ + CPUState *cs =3D qemu_get_cpu(vcpu_id); + CPUX86State *env; + uint64_t gpa; + + if (!cs) { + return NULL; + } + env =3D &X86_CPU(cs)->env; + + gpa =3D env->xen_vcpu_info_gpa; + if (gpa =3D=3D UINT64_MAX) + gpa =3D env->xen_vcpu_info_default_gpa; + if (gpa =3D=3D UINT64_MAX) + return NULL; + + return gpa_to_hva(gpa); +} + +void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id) +{ + CPUState *cs =3D qemu_get_cpu(vcpu_id); + uint8_t vector; + + if (!cs) { + return; + } + vector =3D X86_CPU(cs)->env.xen_vcpu_callback_vector; + + if (vector) { + /* The per-vCPU callback vector injected via lapic. Just + * deliver it as an MSI. */ + MSIMessage msg =3D { + .address =3D APIC_DEFAULT_ADDRESS | X86_CPU(cs)->apic_id, + .data =3D vector | (1UL << MSI_DATA_LEVEL_SHIFT), + }; + kvm_irqchip_send_msi(kvm_state, msg); + return; + } + + /* If the evtchn_upcall_pending field in the vcpu_info is set, then + * KVM will automatically deliver the vector on entering the vCPU + * so all we have to do is kick it out. */ + qemu_cpu_kick(cs); +} + static void do_set_vcpu_time_info_gpa(CPUState *cs, run_on_cpu_data data) { X86CPU *cpu =3D X86_CPU(cs); @@ -652,6 +712,18 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, err =3D xen_evtchn_close_op(&close); break; } + case EVTCHNOP_unmask: { + struct evtchn_unmask unmask; + + qemu_build_assert(sizeof(unmask) =3D=3D 4); + if (kvm_copy_from_gva(cs, arg, &unmask, sizeof(unmask))) { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_unmask_op(&unmask); + break; + } default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151932337194.45215984300955; Thu, 15 Dec 2022 16:52:12 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynY-0005NH-KG; Thu, 15 Dec 2022 19:42:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynE-0005F5-EV for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:41 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006aJ-57 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvVC-AK; Fri, 16 Dec 2022 00:41:33 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cPs-Bo; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=GBOWYyuWKdYysrZ+j4MeLrWFq/GKTS0ZAHS+vvkBe24=; b=C+AIMhV3ErZdRRVanVTFo6Vz2D gHqAnpjqx5iuJYyuRuTIAb1uSd73Jb9doVob/AnkAlYUKtt+zfkr/Hy+lq5vqbfV0iVM9+3No44++ XO1asMn73Ls7e5Y0dHagCGMa3iGwPjq8gQh/pARsehJ51eWrp5yQUdtLIuuBtVOfoF+gwsmNTPV+a kyW6KkupbqVBefqU2WtfjJEdr32aAmjBGVlyA+XOxv+8UIt01NrHw7MDy9bPdV5tCEkfz3VceTJSW gKJsp0WmL5Qk7oZTeQYZndYSBH5HSm7JjxAE2DqANfMEfRSuuoJPTLKyuPYOzCPKVfolUKsKGHaeb eyvVTp8g==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 28/38] hw/xen: Implement EVTCHNOP_bind_virq Date: Fri, 16 Dec 2022 00:41:07 +0000 Message-Id: <20221216004117.862106-29-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151933094100001 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Add the array of virq ports to each vCPU so that we can deliver timers, debug ports, etc. Global virqs are allocated against vCPU 0 initially, but can be migrated to other vCPUs (when we implement that). The kernel needs to know about VIRQ_TIMER in order to accelerate timers, so tell it via KVM_XEN_VCPU_ATTR_TYPE_TIMER. Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 83 +++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 2 + include/sysemu/kvm_xen.h | 1 + target/i386/cpu.h | 3 ++ target/i386/kvm/xen-emu.c | 61 ++++++++++++++++++++++++++++ target/i386/machine.c | 1 + 6 files changed, 151 insertions(+) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 50adef0864..19b8eb7a6f 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -208,6 +208,11 @@ static bool valid_port(evtchn_port_t port) } } =20 +static bool valid_vcpu(uint32_t vcpu) +{ + return !!qemu_get_cpu(vcpu); +} + int xen_evtchn_status_op(struct evtchn_status *status) { XenEvtchnState *s =3D xen_evtchn_singleton; @@ -398,6 +403,20 @@ static int unmask_port(XenEvtchnState *s, evtchn_port_= t port, bool do_unmask) } } =20 +static bool virq_is_global(uint32_t virq) +{ + switch (virq) { + case VIRQ_TIMER: + case VIRQ_DEBUG: + case VIRQ_XENOPROF: + case VIRQ_XENPMU: + return false; + + default: + return true; + } +} + static void free_port(XenEvtchnState *s, evtchn_port_t port) { s->port_table[port].type =3D EVTCHNSTAT_closed; @@ -411,6 +430,28 @@ static void free_port(XenEvtchnState *s, evtchn_port_t= port) } } =20 +static int allocate_port(XenEvtchnState *s, uint32_t vcpu, uint16_t type, + uint16_t val, evtchn_port_t *port) +{ + evtchn_port_t p =3D 1; + + for (p =3D 1; valid_port(p); p++) { + if (s->port_table[p].type =3D=3D EVTCHNSTAT_closed) { + s->port_table[p].vcpu =3D vcpu; + s->port_table[p].type =3D type; + s->port_table[p].type_val =3D val; + + *port =3D p; + + if (s->nr_ports < p + 1) + s->nr_ports =3D p + 1; + + return 0; + } + } + return -ENOSPC; +} + static int close_port(XenEvtchnState *s, evtchn_port_t port) { XenEvtchnPort *p =3D &s->port_table[port]; @@ -419,6 +460,11 @@ static int close_port(XenEvtchnState *s, evtchn_port_t= port) case EVTCHNSTAT_closed: return -ENOENT; =20 + case EVTCHNSTAT_virq: + kvm_xen_set_vcpu_virq(virq_is_global(p->type_val) ? 0 : p->vcpu, + p->type_val, 0); + break; + default: break; } @@ -470,3 +516,40 @@ int xen_evtchn_unmask_op(struct evtchn_unmask *unmask) =20 return ret; } + +int xen_evtchn_bind_virq_op(struct evtchn_bind_virq *virq) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + int ret; + + if (!s) { + return -ENOTSUP; + } + + if (virq->virq >=3D NR_VIRQS) { + return -EINVAL; + } + + /* Global VIRQ must be allocated on vCPU0 first */ + if (virq_is_global(virq->virq) && virq->vcpu !=3D 0) { + return -EINVAL; + } + + if (!valid_vcpu(virq->vcpu)) { + return -ENOENT; + } + + qemu_mutex_lock(&s->port_lock); + + ret =3D allocate_port(s, virq->vcpu, EVTCHNSTAT_virq, virq->virq, &vir= q->port); + if (!ret) { + ret =3D kvm_xen_set_vcpu_virq(virq->vcpu, virq->virq, virq->port); + if (ret) { + free_port(s, virq->port); + } + } + + qemu_mutex_unlock(&s->port_lock); + + return ret; +} diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index 2fb7d70043..ffddd87bdc 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -16,6 +16,8 @@ int xen_evtchn_set_callback_param(uint64_t param); struct evtchn_status; struct evtchn_close; struct evtchn_unmask; +struct evtchn_bind_virq; int xen_evtchn_status_op(struct evtchn_status *status); int xen_evtchn_close_op(struct evtchn_close *close); int xen_evtchn_unmask_op(struct evtchn_unmask *unmask); +int xen_evtchn_bind_virq_op(struct evtchn_bind_virq *virq); diff --git a/include/sysemu/kvm_xen.h b/include/sysemu/kvm_xen.h index ab629feb13..e5b14ffe8d 100644 --- a/include/sysemu/kvm_xen.h +++ b/include/sysemu/kvm_xen.h @@ -14,5 +14,6 @@ =20 void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id); void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id); +int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port); =20 #endif /* QEMU_SYSEMU_KVM_XEN_H */ diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 938a1b9c8b..846c738fd7 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -27,6 +27,8 @@ #include "qapi/qapi-types-common.h" #include "qemu/cpu-float.h" =20 +#define XEN_NR_VIRQS 24 + /* The x86 has a strong memory model with some store-after-load re-orderin= g */ #define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD) =20 @@ -1793,6 +1795,7 @@ typedef struct CPUArchState { uint64_t xen_vcpu_time_info_gpa; uint64_t xen_vcpu_runstate_gpa; uint8_t xen_vcpu_callback_vector; + uint16_t xen_virq[XEN_NR_VIRQS]; #endif #if defined(CONFIG_HVF) HVFX86LazyFlags hvf_lflags; diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 51cb6bf052..d6b26c59e1 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -287,6 +287,52 @@ void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu= _id) qemu_cpu_kick(cs); } =20 +static int kvm_xen_set_vcpu_timer(CPUState *cs) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + struct kvm_xen_vcpu_attr va =3D { + .type =3D KVM_XEN_VCPU_ATTR_TYPE_TIMER, + .u.timer.port =3D env->xen_virq[VIRQ_TIMER], + .u.timer.priority =3D KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL, + .u.timer.expires_ns =3D 0, + }; + + return kvm_vm_ioctl(kvm_state, KVM_XEN_VCPU_SET_ATTR, &va); +} + +static void do_set_vcpu_timer_virq(CPUState *cs, run_on_cpu_data data) +{ + kvm_xen_set_vcpu_timer(cs); +} + +int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port) +{ + CPUState *cs =3D qemu_get_cpu(vcpu_id); + + if (!cs) { + return -ENOENT; + } + + /* cpu.h doesn't include the actual Xen header. */ + qemu_build_assert(NR_VIRQS =3D=3D XEN_NR_VIRQS); + + if (virq >=3D NR_VIRQS) { + return -EINVAL; + } + + if (port && X86_CPU(cs)->env.xen_virq[virq]) { + return -EEXIST; + } + + X86_CPU(cs)->env.xen_virq[virq] =3D port; + if (virq =3D=3D VIRQ_TIMER) { + async_run_on_cpu(cs, do_set_vcpu_timer_virq, RUN_ON_CPU_HOST_INT(p= ort)); + } + return 0; +} + static void do_set_vcpu_time_info_gpa(CPUState *cs, run_on_cpu_data data) { X86CPU *cpu =3D X86_CPU(cs); @@ -724,6 +770,21 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, err =3D xen_evtchn_unmask_op(&unmask); break; } + case EVTCHNOP_bind_virq: { + struct evtchn_bind_virq virq; + + qemu_build_assert(sizeof(virq) =3D=3D 12); + if (kvm_copy_from_gva(cs, arg, &virq, sizeof(virq))) { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_bind_virq_op(&virq); + if (!err && kvm_copy_to_gva(cs, arg, &virq, sizeof(virq))) { + err =3D -EFAULT; + } + break; + } default: return false; } diff --git a/target/i386/machine.c b/target/i386/machine.c index 09e13cf716..e04d64913c 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -1280,6 +1280,7 @@ static const VMStateDescription vmstate_xen_vcpu =3D { VMSTATE_UINT64(env.xen_vcpu_time_info_gpa, X86CPU), VMSTATE_UINT64(env.xen_vcpu_runstate_gpa, X86CPU), VMSTATE_UINT8(env.xen_vcpu_callback_vector, X86CPU), + VMSTATE_UINT16_ARRAY(env.xen_virq, X86CPU, XEN_NR_VIRQS), VMSTATE_END_OF_LIST() } }; --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152145278101.14277907686619; Thu, 15 Dec 2022 16:55:45 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynt-0005Tb-HC; Thu, 15 Dec 2022 19:42:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynG-0005FY-5T for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:44 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynB-0006aU-VV for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvVD-Bz; Fri, 16 Dec 2022 00:41:35 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cPw-Cc; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=relzIU2tsMjB0FQ/kvzkTnpvoCSaGCmN7Ded0o90LEA=; b=E83W4f7nAFiaqVYUMPaaNfnxAZ nqh1yVSR6fJPYgr6RFp/EHC9vcNV9f/EYqOU0ZlvZEQfNk6AZT5UuZtWj3qGjIZTiZmvqZSX1ZSEN OIzuU9+ks53BRrtnGRmeIrbUfDusDheisOfKOXOKe8yT4YebwU4pBAwcZeW6ZpxXN6qNxoXfaGWis GupNE4L8odrMRyCkJqpdYnhL19Q3hsT5VBgyKcm1jlKvf0iTIEQeq6MCr+oWKalNRvAsK5UOb8QOj jwVL/fUDoDR8ec/7bxcyzQXhyaa1j2j8eJqMXXAWt4Yv3TZgIhQjN//31b1ne5VgJ/4Lz8P3bb2P/ fXfIc0Zw==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 29/38] hw/xen: Implement EVTCHNOP_bind_ipi Date: Fri, 16 Dec 2022 00:41:08 +0000 Message-Id: <20221216004117.862106-30-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152146509100003 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 67 +++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 2 ++ target/i386/kvm/xen-emu.c | 15 +++++++++ 3 files changed, 84 insertions(+) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 19b8eb7a6f..2e35812b32 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -13,6 +13,7 @@ #include "qemu/host-utils.h" #include "qemu/module.h" #include "qemu/main-loop.h" +#include "qemu/log.h" #include "qapi/error.h" #include "qom/object.h" #include "exec/target_page.h" @@ -195,6 +196,43 @@ int xen_evtchn_set_callback_param(uint64_t param) return ret; } =20 +static void deassign_kernel_port(evtchn_port_t port) +{ + struct kvm_xen_hvm_attr ha; + int ret; + + ha.type =3D KVM_XEN_ATTR_TYPE_EVTCHN; + ha.u.evtchn.send_port =3D port; + ha.u.evtchn.flags =3D KVM_XEN_EVTCHN_DEASSIGN; + + ret =3D kvm_vm_ioctl(kvm_state, KVM_XEN_HVM_SET_ATTR, &ha); + if (ret) { + qemu_log_mask(LOG_GUEST_ERROR, "Failed to unbind kernel port %d: %= s\n", + port, strerror(ret)); + } +} + +static int assign_kernel_port(uint16_t type, evtchn_port_t port, + uint32_t vcpu_id) +{ + CPUState *cpu =3D qemu_get_cpu(vcpu_id); + struct kvm_xen_hvm_attr ha; + + if (!cpu) { + return -ENOENT; + } + + ha.type =3D KVM_XEN_ATTR_TYPE_EVTCHN; + ha.u.evtchn.send_port =3D port; + ha.u.evtchn.type =3D type; + ha.u.evtchn.flags =3D 0; + ha.u.evtchn.deliver.port.port =3D port; + ha.u.evtchn.deliver.port.vcpu =3D kvm_arch_vcpu_id(cpu); + ha.u.evtchn.deliver.port.priority =3D KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_= 2LEVEL; + + return kvm_vm_ioctl(kvm_state, KVM_XEN_HVM_SET_ATTR, &ha); +} + static bool valid_port(evtchn_port_t port) { if (!port) { @@ -465,6 +503,10 @@ static int close_port(XenEvtchnState *s, evtchn_port_t= port) p->type_val, 0); break; =20 + case EVTCHNSTAT_ipi: + deassign_kernel_port(port); + break; + default: break; } @@ -553,3 +595,28 @@ int xen_evtchn_bind_virq_op(struct evtchn_bind_virq *v= irq) =20 return ret; } + +int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + int ret; + + if (!s) { + return -ENOTSUP; + } + + if (!valid_vcpu(ipi->vcpu)) { + return -ENOENT; + } + + qemu_mutex_lock(&s->port_lock); + + ret =3D allocate_port(s, ipi->vcpu, EVTCHNSTAT_ipi, 0, &ipi->port); + if (!ret) { + assign_kernel_port(EVTCHNSTAT_ipi, ipi->port, ipi->vcpu); + } + + qemu_mutex_unlock(&s->port_lock); + + return ret; +} diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index ffddd87bdc..52ade5a64e 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -17,7 +17,9 @@ struct evtchn_status; struct evtchn_close; struct evtchn_unmask; struct evtchn_bind_virq; +struct evtchn_bind_ipi; int xen_evtchn_status_op(struct evtchn_status *status); int xen_evtchn_close_op(struct evtchn_close *close); int xen_evtchn_unmask_op(struct evtchn_unmask *unmask); int xen_evtchn_bind_virq_op(struct evtchn_bind_virq *virq); +int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index d6b26c59e1..b5f8f30d62 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -785,6 +785,21 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, } break; } + case EVTCHNOP_bind_ipi: { + struct evtchn_bind_ipi ipi; + + qemu_build_assert(sizeof(ipi) =3D=3D 8); + if (kvm_copy_from_gva(cs, arg, &ipi, sizeof(ipi))) { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_bind_ipi_op(&ipi); + if (!err && kvm_copy_to_gva(cs, arg, &ipi, sizeof(ipi))) { + err =3D -EFAULT; + } + break; + } default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151924642847.0660326458958; Thu, 15 Dec 2022 16:52:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yoM-00062k-Ue; Thu, 15 Dec 2022 19:42:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0005Do-E5 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn5-0006aR-IQ for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:36 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvVF-Bw; Fri, 16 Dec 2022 00:41:34 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cQ0-DI; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=xjCxkaobxLl3nRt5VtDNl1KNusMd8/F4iusKJDVqbAo=; b=CreJ0gjko2M4jBLgwV9gD4LBz3 ok35TS4NEx5voQDqqcjWfLtdz6TVNpD2Qu4TTz2qHOzwKkd0dnI3NHHI7WEgrR+ZYTTHKofUoHLRM 8bvsR2JRMfJZln95jYRzndXjQXQNoLxw3xpSWgtJwZyXM2zYFNuUcVXcJAp0+Va7NYeYu8Li6JWsn a4ZhGoBhXUMusIIIR7qPH3UshXh8oVACiYPr+Bk3aZ2pQhtZoN5khJze264jcXLsVUFzKUAflssnf DNged98C9MSojm0P32g8B4RfPNR+eFIVSZiikBrqYqv/HetBzHpV6bGJW7UM5BvVao20PmBE4ESm6 OmyyMYbw==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 30/38] hw/xen: Implement EVTCHNOP_send Date: Fri, 16 Dec 2022 00:41:09 +0000 Message-Id: <20221216004117.862106-31-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151925046100002 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 162 ++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 2 + target/i386/kvm/xen-emu.c | 12 +++ 3 files changed, 176 insertions(+) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 2e35812b32..d90a92a25a 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -441,6 +441,117 @@ static int unmask_port(XenEvtchnState *s, evtchn_port= _t port, bool do_unmask) } } =20 +static int do_set_port_lm(XenEvtchnState *s, evtchn_port_t port, + struct shared_info *shinfo, + struct vcpu_info *vcpu_info) +{ + const int bits_per_word =3D BITS_PER_BYTE * sizeof(shinfo->evtchn_pend= ing[0]); + typeof(shinfo->evtchn_pending[0]) mask; + int idx =3D port / bits_per_word; + int offset =3D port % bits_per_word; + + mask =3D 1UL << offset; + + if (idx >=3D bits_per_word) { + return -EINVAL; + } + + /* Update the pending bit itself. If it was already set, we're done. */ + if (qatomic_fetch_or(&shinfo->evtchn_pending[idx], mask) & mask) { + return 0; + } + + /* Check if it's masked. */ + if (qatomic_fetch_or(&shinfo->evtchn_mask[idx], 0) & mask) { + return 0; + } + + /* Now on to the vcpu_info evtchn_pending_sel index... */ + mask =3D 1UL << idx; + + /* If a port in this word was already pending for this vCPU, all done.= */ + if (qatomic_fetch_or(&vcpu_info->evtchn_pending_sel, mask) & mask) { + return 0; + } + + /* Set evtchn_upcall_pending for this vCPU */ + if (qatomic_fetch_or(&vcpu_info->evtchn_upcall_pending, 1)) { + return 0; + } + + kvm_xen_inject_vcpu_callback_vector(s->port_table[port].vcpu); + + return 0; +} + +static int do_set_port_compat(XenEvtchnState *s, evtchn_port_t port, + struct compat_shared_info *shinfo, + struct compat_vcpu_info *vcpu_info) +{ + const int bits_per_word =3D BITS_PER_BYTE * sizeof(shinfo->evtchn_pend= ing[0]); + typeof(shinfo->evtchn_pending[0]) mask; + int idx =3D port / bits_per_word; + int offset =3D port % bits_per_word; + + mask =3D 1UL << offset; + + if (idx >=3D bits_per_word) { + return -EINVAL; + } + + /* Update the pending bit itself. If it was already set, we're done. */ + if (qatomic_fetch_or(&shinfo->evtchn_pending[idx], mask) & mask) { + return 0; + } + + /* Check if it's masked. */ + if (qatomic_fetch_or(&shinfo->evtchn_mask[idx], 0) & mask) { + return 0; + } + + /* Now on to the vcpu_info evtchn_pending_sel index... */ + mask =3D 1UL << idx; + + /* If a port in this word was already pending for this vCPU, all done.= */ + if (qatomic_fetch_or(&vcpu_info->evtchn_pending_sel, mask) & mask) { + return 0; + } + + /* Set evtchn_upcall_pending for this vCPU */ + if (qatomic_fetch_or(&vcpu_info->evtchn_upcall_pending, 1)) { + return 0; + } + + kvm_xen_inject_vcpu_callback_vector(s->port_table[port].vcpu); + + return 0; +} + +static int set_port_pending(XenEvtchnState *s, evtchn_port_t port) +{ + void *vcpu_info, *shinfo; + + if (s->port_table[port].type =3D=3D EVTCHNSTAT_closed) { + return -EINVAL; + } + + shinfo =3D xen_overlay_page_ptr(XENMAPSPACE_shared_info, 0); + if (!shinfo) { + return -ENOTSUP; + } + + vcpu_info =3D kvm_xen_get_vcpu_info_hva(s->port_table[port].vcpu); + if (!vcpu_info) { + return -EINVAL; + } + + if (xen_is_long_mode()) { + return do_set_port_lm(s, port, shinfo, vcpu_info); + } else { + return do_set_port_compat(s, port, shinfo, vcpu_info); + } +} + static bool virq_is_global(uint32_t virq) { switch (virq) { @@ -620,3 +731,54 @@ int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi) =20 return ret; } + +int xen_evtchn_send_op(struct evtchn_send *send) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + XenEvtchnPort *p; + int ret =3D 0; + + if (!s) { + return -ENOTSUP; + } + + if (!valid_port(send->port)) { + return -EINVAL; + } + + qemu_mutex_lock(&s->port_lock); + + p =3D &s->port_table[send->port]; + + switch(p->type) { + case EVTCHNSTAT_interdomain: + if (p->type_val & PORT_INFO_TYPEVAL_REMOTE_QEMU) { + /* This is an event from the guest to qemu itself, which is + * serving as the driver domain. Not yet implemented; it will + * be hooked up to the qemu implementation of xenstore, + * console, PV net/block drivers etc. */ + ret =3D -ENOSYS; + } else { + /* Loopback interdomain ports; just a complex IPI */ + set_port_pending(s, p->type_val); + } + break; + + case EVTCHNSTAT_ipi: + set_port_pending(s, send->port); + break; + + case EVTCHNSTAT_unbound: + /* Xen will silently drop these */ + break; + + default: + ret =3D -EINVAL; + break; + } + + qemu_mutex_unlock(&s->port_lock); + + return ret; +} + diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index 52ade5a64e..c27b9e8096 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -18,8 +18,10 @@ struct evtchn_close; struct evtchn_unmask; struct evtchn_bind_virq; struct evtchn_bind_ipi; +struct evtchn_send; int xen_evtchn_status_op(struct evtchn_status *status); int xen_evtchn_close_op(struct evtchn_close *close); int xen_evtchn_unmask_op(struct evtchn_unmask *unmask); int xen_evtchn_bind_virq_op(struct evtchn_bind_virq *virq); int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi); +int xen_evtchn_send_op(struct evtchn_send *send); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index b5f8f30d62..300b0d75bc 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -800,6 +800,18 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, } break; } + case EVTCHNOP_send: { + struct evtchn_send send; + + qemu_build_assert(sizeof(send) =3D=3D 4); + if (kvm_copy_from_gva(cs, arg, &send, sizeof(send))) { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_send_op(&send); + break; + } default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152158335631.3438857760656; Thu, 15 Dec 2022 16:55:58 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynT-0005KA-O2; Thu, 15 Dec 2022 19:41:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0005Dq-EY for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006aP-5a for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:38 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvVG-CG; Fri, 16 Dec 2022 00:41:34 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cQ4-E3; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=XLTcwcMIgdL3tDzfwKR9X0Dj8KSY4nPrZbJ5xkQKwD8=; b=diRnPMY1DQawrQnO/D3MO+beCv M4o4HI9eMf8FtO7MM9S045LAh1w/93f6tKD8/fBfBHV+wehIarcCxc12nJSiI+LXGXpgpbv2T/DEQ 9QDvVkavCIwwSbQu7aaErfx6WJQrV0XDZFzRhscDoEuBzdNhGNUvnbSKwdNdXqvvxyo/5u8q3yXlO Diuv/XLNXs9eq8SJ8bExjEthins+q1vdJV6J9g0Iq7GXc9zK3McxbNnAEYYwh9TE+gBIlLDbP6seu 54yiCG7OviQmX0mefqVID4Bx5MConYuPZYyXivBRqKmZDmGN5KQ2vz7Sg23joUvJD+EQdgGA9as/c 3ZhDiCKw==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 31/38] hw/xen: Implement EVTCHNOP_alloc_unbound Date: Fri, 16 Dec 2022 00:41:10 +0000 Message-Id: <20221216004117.862106-32-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152158537100005 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 32 ++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 2 ++ target/i386/kvm/xen-emu.c | 15 +++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index d90a92a25a..4272b63853 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -732,6 +732,38 @@ int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi) return ret; } =20 +int xen_evtchn_alloc_unbound_op(struct evtchn_alloc_unbound *alloc) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + uint16_t type_val; + int ret; + + if (!s) { + return -ENOTSUP; + } + + if (alloc->dom !=3D DOMID_SELF && alloc->dom !=3D xen_domid) { + return -ESRCH; + } + + if (alloc->remote_dom =3D=3D DOMID_QEMU) { + type_val =3D PORT_INFO_TYPEVAL_REMOTE_QEMU; + } else if (alloc->remote_dom =3D=3D DOMID_SELF || + alloc->remote_dom =3D=3D xen_domid) { + type_val =3D 0; + } else { + return -EPERM; + } + + qemu_mutex_lock(&s->port_lock); + + ret =3D allocate_port(s, 0, EVTCHNSTAT_unbound, type_val, &alloc->port= ); + + qemu_mutex_unlock(&s->port_lock); + + return ret; +} + int xen_evtchn_send_op(struct evtchn_send *send) { XenEvtchnState *s =3D xen_evtchn_singleton; diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index c27b9e8096..5dc68a188d 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -19,9 +19,11 @@ struct evtchn_unmask; struct evtchn_bind_virq; struct evtchn_bind_ipi; struct evtchn_send; +struct evtchn_alloc_unbound; int xen_evtchn_status_op(struct evtchn_status *status); int xen_evtchn_close_op(struct evtchn_close *close); int xen_evtchn_unmask_op(struct evtchn_unmask *unmask); int xen_evtchn_bind_virq_op(struct evtchn_bind_virq *virq); int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi); int xen_evtchn_send_op(struct evtchn_send *send); +int xen_evtchn_alloc_unbound_op(struct evtchn_alloc_unbound *alloc); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 300b0d75bc..6f393c4149 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -812,6 +812,21 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, err =3D xen_evtchn_send_op(&send); break; } + case EVTCHNOP_alloc_unbound: { + struct evtchn_alloc_unbound alloc; + + qemu_build_assert(sizeof(alloc) =3D=3D 8); + if (kvm_copy_from_gva(cs, arg, &alloc, sizeof(alloc))) { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_alloc_unbound_op(&alloc); + if (!err && kvm_copy_to_gva(cs, arg, &alloc, sizeof(alloc))) { + err =3D -EFAULT; + } + break; + } default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152175900114.9731538958439; Thu, 15 Dec 2022 16:56:15 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynX-0005MD-AL; Thu, 15 Dec 2022 19:41:59 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynG-0005Fe-PX for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:45 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynB-0006ab-VN for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:42 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvVH-CV; Fri, 16 Dec 2022 00:41:35 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cQ8-Ei; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=HxpDGgysz3OvbZOSMLjD0D0bLhGzUibeNUTG8eP7VKk=; b=u/5Szgyk8Apl+QImVwN1ZdRX39 sQDRqrAIdD86fczpETB5RoAkUNGWhvtZKKdAwlA4+9s/8+DP2/10FOWMyOeWrRQY+sTLKoMxgxSc4 quUoMPKet3RR/opG2HDOokxI3ar4Ay8ExTdTJWKXS6F/NZdNTQQ994u6KURTFOcNSIBpnXR+p4YBf gSjFhh+JKhBaqOR4ryusRSVA4Yrgr38qO2HWh5pcs+D0fAz8mcjpphInj53X9eo3B4dq0vHZrcSsi U2lFoKicnL/4C0Om/pWL9us7BDv3at/lKkxXt2aFmGLmbUnEq9SuRQGaxWC57lXD3zSP1sMsoelyM ChrsoGfQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 32/38] hw/xen: Implement EVTCHNOP_bind_interdomain Date: Fri, 16 Dec 2022 00:41:11 +0000 Message-Id: <20221216004117.862106-33-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152176625100005 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 77 +++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 2 + target/i386/kvm/xen-emu.c | 15 ++++++++ 3 files changed, 94 insertions(+) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 4272b63853..b286bbd20e 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -618,6 +618,23 @@ static int close_port(XenEvtchnState *s, evtchn_port_t= port) deassign_kernel_port(port); break; =20 + case EVTCHNSTAT_interdomain: + if (p->type_val & PORT_INFO_TYPEVAL_REMOTE_QEMU) { + /* Not yet implemented. This can't happen! */ + } else { + /* Loopback interdomain */ + XenEvtchnPort *rp =3D &s->port_table[p->type_val]; + if (!valid_port(p->type_val) || rp->type_val !=3D port || + rp->type !=3D EVTCHNSTAT_interdomain) { + error_report("Inconsistent state for interdomain unbind"); + } else { + /* Set the other end back to unbound */ + rp->type =3D EVTCHNSTAT_unbound; + rp->type_val =3D 0; + } + } + break; + default: break; } @@ -732,6 +749,66 @@ int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi) return ret; } =20 +int xen_evtchn_bind_interdomain_op(struct evtchn_bind_interdomain *interdo= main) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + uint16_t type_val; + int ret; + + if (!s) { + return -ENOTSUP; + } + + if (interdomain->remote_dom =3D=3D DOMID_QEMU) { + type_val =3D PORT_INFO_TYPEVAL_REMOTE_QEMU; + } else if (interdomain->remote_dom =3D=3D DOMID_SELF || + interdomain->remote_dom =3D=3D xen_domid) { + type_val =3D 0; + } else { + return -ESRCH; + } + + if (!valid_port(interdomain->remote_port)) { + return -EINVAL; + } + + qemu_mutex_lock(&s->port_lock); + + /* The newly allocated port starts out as unbound */ + ret =3D allocate_port(s, 0, EVTCHNSTAT_unbound, type_val, &interdomain= ->local_port); + if (ret) { + goto out; + } + + if (interdomain->remote_dom =3D=3D DOMID_QEMU) { + /* We haven't hooked up QEMU's PV drivers to this yet */ + ret =3D -ENOSYS; + } else { + /* Loopback */ + XenEvtchnPort *rp =3D &s->port_table[interdomain->remote_port]; + XenEvtchnPort *lp =3D &s->port_table[interdomain->local_port]; + + if (rp->type =3D=3D EVTCHNSTAT_unbound && rp->type_val =3D=3D 0) { + /* It's a match! */ + rp->type =3D EVTCHNSTAT_interdomain; + rp->type_val =3D interdomain->local_port; + + lp->type =3D EVTCHNSTAT_interdomain; + lp->type_val =3D interdomain->remote_port; + } else { + ret =3D -EINVAL; + } + } + + if (ret) { + free_port(s, interdomain->local_port); + } + out: + qemu_mutex_unlock(&s->port_lock); + + return ret; + +} int xen_evtchn_alloc_unbound_op(struct evtchn_alloc_unbound *alloc) { XenEvtchnState *s =3D xen_evtchn_singleton; diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index 5dc68a188d..4783a6f127 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -20,6 +20,7 @@ struct evtchn_bind_virq; struct evtchn_bind_ipi; struct evtchn_send; struct evtchn_alloc_unbound; +struct evtchn_bind_interdomain; int xen_evtchn_status_op(struct evtchn_status *status); int xen_evtchn_close_op(struct evtchn_close *close); int xen_evtchn_unmask_op(struct evtchn_unmask *unmask); @@ -27,3 +28,4 @@ int xen_evtchn_bind_virq_op(struct evtchn_bind_virq *virq= ); int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi); int xen_evtchn_send_op(struct evtchn_send *send); int xen_evtchn_alloc_unbound_op(struct evtchn_alloc_unbound *alloc); +int xen_evtchn_bind_interdomain_op(struct evtchn_bind_interdomain *interdo= main); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 6f393c4149..c4c595cb1a 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -827,6 +827,21 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, } break; } + case EVTCHNOP_bind_interdomain: { + struct evtchn_bind_interdomain interdomain; + + qemu_build_assert(sizeof(interdomain) =3D=3D 12); + if (kvm_copy_from_gva(cs, arg, &interdomain, sizeof(interdomain)))= { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_bind_interdomain_op(&interdomain); + if (!err && kvm_copy_to_gva(cs, arg, &interdomain, sizeof(interdom= ain))) { + err =3D -EFAULT; + } + break; + } default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151353659352.23147665370425; Thu, 15 Dec 2022 16:42:33 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yng-0005RU-Gq; Thu, 15 Dec 2022 19:42:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynG-0005Fa-8v for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:44 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynB-0006cq-VN for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:41 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymy-00Azyy-1k; Fri, 16 Dec 2022 00:41:28 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cQC-FP; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=twBCfa5ab9yvAw8qE/yZyB5yxVmEoa7bU6nINefGeSc=; b=WscDVIJqnOu5jBWGKZERe3oX0m XXrxxu2+ulbHRhTFbqR/GiOyUvl6sps2sKxE2p6JtXtZPwaXzxSy0gtyA4GYJK3U7sD6pmqBCvYE+ kNz0giYHhgr46qEKTSVjuOPhM+400+epGKE2JzRWkzahuEqWgMPTT0JeyOG98kB/4YpAOYFUVlPps 0Sek8adc9t8vTVOE+Jup6f3EXrBPGm8cK+uBww2ecoVb/OHhxKLnAX1KsiqTanpOOGFlIVZpu4ZS6 +2L8aDurbVEED/ZxYqbwkITm52TOg1UA1BpvzXjOBToDJov23JkWqG1HHQ2tQyF77s4MjRaJJWD9e rzOnuH1Q==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 33/38] hw/xen: Implement EVTCHNOP_bind_vcpu Date: Fri, 16 Dec 2022 00:41:12 +0000 Message-Id: <20221216004117.862106-34-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151359600100001 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 40 +++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 2 ++ target/i386/kvm/xen-emu.c | 12 ++++++++++++ 3 files changed, 54 insertions(+) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index b286bbd20e..8cdc26afb7 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -687,6 +687,46 @@ int xen_evtchn_unmask_op(struct evtchn_unmask *unmask) return ret; } =20 +int xen_evtchn_bind_vcpu_op(struct evtchn_bind_vcpu *vcpu) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + XenEvtchnPort *p; + int ret =3D -EINVAL; + + if (!s) { + return -ENOTSUP; + } + + if (!valid_port(vcpu->port)) { + return -EINVAL; + } + + if (!valid_vcpu(vcpu->vcpu)) { + return -ENOENT; + } + + qemu_mutex_lock(&s->port_lock); + + p =3D &s->port_table[vcpu->port]; + + if (p->type =3D=3D EVTCHNSTAT_interdomain || + p->type =3D=3D EVTCHNSTAT_unbound || + p->type =3D=3D EVTCHNSTAT_pirq || + (p->type =3D=3D EVTCHNSTAT_virq && virq_is_global(p->type_val))) { + /* + * unmask_port() with do_unmask=3D=3Dfalse will just raise the eve= nt + * on the new vCPU if the port was already pending. + */ + p->vcpu =3D vcpu->vcpu; + unmask_port(s, vcpu->port, false); + ret =3D 0; + } + + qemu_mutex_unlock(&s->port_lock); + + return ret; +} + int xen_evtchn_bind_virq_op(struct evtchn_bind_virq *virq) { XenEvtchnState *s =3D xen_evtchn_singleton; diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index 4783a6f127..99d5292c1e 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -21,6 +21,7 @@ struct evtchn_bind_ipi; struct evtchn_send; struct evtchn_alloc_unbound; struct evtchn_bind_interdomain; +struct evtchn_bind_vcpu; int xen_evtchn_status_op(struct evtchn_status *status); int xen_evtchn_close_op(struct evtchn_close *close); int xen_evtchn_unmask_op(struct evtchn_unmask *unmask); @@ -29,3 +30,4 @@ int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi); int xen_evtchn_send_op(struct evtchn_send *send); int xen_evtchn_alloc_unbound_op(struct evtchn_alloc_unbound *alloc); int xen_evtchn_bind_interdomain_op(struct evtchn_bind_interdomain *interdo= main); +int xen_evtchn_bind_vcpu_op(struct evtchn_bind_vcpu *vcpu); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index c4c595cb1a..58fa82682f 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -842,6 +842,18 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, } break; } + case EVTCHNOP_bind_vcpu: { + struct evtchn_bind_vcpu vcpu; + + qemu_build_assert(sizeof(vcpu) =3D=3D 8); + if (kvm_copy_from_gva(cs, arg, &vcpu, sizeof(vcpu))) { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_bind_vcpu_op(&vcpu); + break; + } default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152156121968.6578232379852; Thu, 15 Dec 2022 16:55:56 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yp1-0007L6-UT; Thu, 15 Dec 2022 19:43:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yoI-0006Hr-RP for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:48 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yoG-0006qX-Ty for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:42:46 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymy-00Azyz-1g; Fri, 16 Dec 2022 00:42:28 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cQG-G3; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=XOS94y+zWLXZf2qYe14xYzCnPgFXWDv3X0NFxPO3IWA=; b=bVbQXgvpfXzIgdNvwwbvIaJM8d MU3WvpJgGBQOcApnsDVEU2qeHatYEvTxH+J0dgyJPGP6qCzBX5HpndVvrn+EpukK1MHDevVP0k5G/ //04XUwb/8iSnGmDQRAdo0E84WwH8RWCOzRqZ3xCa9f/CGXBW1VV9Ex3nYcZ+WUpvFwTl2NA/TKl4 r6HAHKroltUTjRIr8Hmg95raHau5oYWDnYIQGEnf7ErI4LY0+e3QBnYsAu+urgO5/G+E3VavRhd0/ YhTFUVKXrrDmqby1FbumYL7MPHPT24WpTIO+8WwuipIKJ1KbbMhACteHeNEdy7mAUQVqDsvBXLhZi 5uxWTn6w==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 34/38] hw/xen: Implement EVTCHNOP_reset Date: Fri, 16 Dec 2022 00:41:13 +0000 Message-Id: <20221216004117.862106-35-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152156531100001 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 24 ++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 2 ++ target/i386/kvm/xen-emu.c | 12 ++++++++++++ 3 files changed, 38 insertions(+) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 8cdc26afb7..225d984371 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -643,6 +643,30 @@ static int close_port(XenEvtchnState *s, evtchn_port_t= port) return 0; } =20 +int xen_evtchn_reset_op(struct evtchn_reset *reset) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + int i; + + if (!s) { + return -ENOTSUP; + } + + if (reset->dom !=3D DOMID_SELF && reset->dom !=3D xen_domid) { + return -ESRCH; + } + + qemu_mutex_lock(&s->port_lock); + + for (i =3D 0; i < s->nr_ports; i++) { + close_port(s, i); + } + + qemu_mutex_unlock(&s->port_lock); + + return 0; +} + int xen_evtchn_close_op(struct evtchn_close *close) { XenEvtchnState *s =3D xen_evtchn_singleton; diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index 99d5292c1e..b93f534bee 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -22,6 +22,7 @@ struct evtchn_send; struct evtchn_alloc_unbound; struct evtchn_bind_interdomain; struct evtchn_bind_vcpu; +struct evtchn_reset; int xen_evtchn_status_op(struct evtchn_status *status); int xen_evtchn_close_op(struct evtchn_close *close); int xen_evtchn_unmask_op(struct evtchn_unmask *unmask); @@ -31,3 +32,4 @@ int xen_evtchn_send_op(struct evtchn_send *send); int xen_evtchn_alloc_unbound_op(struct evtchn_alloc_unbound *alloc); int xen_evtchn_bind_interdomain_op(struct evtchn_bind_interdomain *interdo= main); int xen_evtchn_bind_vcpu_op(struct evtchn_bind_vcpu *vcpu); +int xen_evtchn_reset_op(struct evtchn_reset *reset); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 58fa82682f..055afba627 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -854,6 +854,18 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exi= t *exit, X86CPU *cpu, err =3D xen_evtchn_bind_vcpu_op(&vcpu); break; } + case EVTCHNOP_reset: { + struct evtchn_reset reset; + + qemu_build_assert(sizeof(reset) =3D=3D 2); + if (kvm_copy_from_gva(cs, arg, &reset, sizeof(reset))) { + err =3D -EFAULT; + break; + } + + err =3D xen_evtchn_reset_op(&reset); + break; + } default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151391497266.47926132593534; Thu, 15 Dec 2022 16:43:11 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynF-0005Dr-VG; Thu, 15 Dec 2022 19:41:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0005D5-CP for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:36 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn5-0006c1-FB for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:33 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymx-00Azz0-9d; Fri, 16 Dec 2022 00:41:26 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cQK-Gh; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=RO1GgqSiEtjgr0AaYpO5Ge7U63e0Y/fq9edf1weTkbc=; b=O9NPinrEAdVqEvG0TUvQRVPTkj AlOabZKqkW0Q/0VdvmPT3Evy3BFdUTv3U/YhyFWIhHu9bg8BKI1O46Yc8P9/isujeNWEFVjq5VC+T t0qAnC/NIXYs/4rMu8+IrsOcCs8Dvk3AdMRHznhPR7Sj57aGTseEoF9fNjL1qcPRDT7//VRN8j6vU dIZ5u3EOIvAaOSUdh+qjDfjOS6ZBel7Wm8aUKokJmuyIHZ3FWOb7jgvbPV+kxdebMGuw9xxBSRmzK bjjAvyPVp3S+LiG7W7t2mQbargkl2g8O2mOb3K6sdBT1XrxGkHXe9uKt/0nXPZ1to3zaGQdxDa5Bt FEPsBR7w==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 35/38] i386/xen: add monitor commands to test event injection Date: Fri, 16 Dec 2022 00:41:14 +0000 Message-Id: <20221216004117.862106-36-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151391792100003 Content-Type: text/plain; charset="utf-8" From: Joao Martins Specifically add listing, injection of event channels. Signed-off-by: Joao Martins Signed-off-by: David Woodhouse --- hmp-commands.hx | 30 +++++++++++++++ hw/i386/kvm/xen_evtchn.c | 83 ++++++++++++++++++++++++++++++++++++++++ hw/i386/kvm/xen_evtchn.h | 3 ++ monitor/misc.c | 4 ++ 4 files changed, 120 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 673e39a697..a36516c287 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1815,3 +1815,33 @@ SRST Dump the FDT in dtb format to *filename*. ERST #endif + +#if defined(CONFIG_XEN_EMU) + + { + .name =3D "xen-event-inject", + .args_type =3D "port:i", + .params =3D "port", + .help =3D "inject event channel", + .cmd =3D hmp_xen_event_inject, + }, + +SRST +``xen-event-inject`` *port* + Notify guest via event channel on port *port*. +ERST + + + { + .name =3D "xen-event-list", + .args_type =3D "", + .params =3D "", + .help =3D "list event channel state", + .cmd =3D hmp_xen_event_list, + }, + +SRST +``xen-event-list`` + List event channels in the guest +ERST +#endif diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 225d984371..9292602c09 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -19,6 +19,8 @@ #include "exec/target_page.h" #include "exec/address-spaces.h" #include "migration/vmstate.h" +#include "monitor/monitor.h" +#include "qapi/qmp/qdict.h" =20 #include "hw/sysbus.h" #include "hw/xen/xen.h" @@ -955,3 +957,84 @@ int xen_evtchn_send_op(struct evtchn_send *send) return ret; } =20 +static const char *type_names[] =3D { + "closed", + "unbound", + "interdomain", + "pirq", + "virq", + "ipi" +}; + +void hmp_xen_event_list(Monitor *mon, const QDict *qdict) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + void *shinfo, *pending, *mask; + int i; + + if (!s) { + monitor_printf(mon, "Xen event channel emulation not enabled\n"); + return; + } + + shinfo =3D xen_overlay_page_ptr(XENMAPSPACE_shared_info, 0); + if (!shinfo) { + monitor_printf(mon, "Xen shared info page not allocated\n"); + return; + } + if (xen_is_long_mode()) { + pending =3D shinfo + offsetof(struct shared_info, evtchn_pending); + mask =3D shinfo + offsetof(struct shared_info, evtchn_mask); + } else { + pending =3D shinfo + offsetof(struct compat_shared_info, evtchn_pe= nding); + mask =3D shinfo + offsetof(struct compat_shared_info, evtchn_mask); + } + + qemu_mutex_lock(&s->port_lock); + + for (i =3D 0; i < s->nr_ports; i++) { + XenEvtchnPort *p =3D &s->port_table[i]; + + if (p->type =3D=3D EVTCHNSTAT_closed) { + continue; + } + + monitor_printf(mon, "port %4u %s/%d vcpu:%d pending:%d mask:%d\n",= i, + type_names[p->type], p->type_val, p->vcpu, + test_bit(i, pending), test_bit(i, mask)); + } + + qemu_mutex_unlock(&s->port_lock); +} + +void hmp_xen_event_inject(Monitor *mon, const QDict *qdict) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + int port =3D qdict_get_int(qdict, "port"); + XenEvtchnPort *p; + + if (!s) { + monitor_printf(mon, "Xen event channel emulation not enabled\n"); + return; + } + + if (!valid_port(port)) { + monitor_printf(mon, "Invalid port %d\n", port); + return; + } + p =3D &s->port_table[port]; + + qemu_mutex_lock(&s->port_lock); + + monitor_printf(mon, "port %4u %s/%d vcpu:%d\n", port, + type_names[p->type], p->type_val, p->vcpu); + + if (set_port_pending(s, port)) { + monitor_printf(mon, "Failed to set port %d\n", port); + } else { + monitor_printf(mon, "Delivered port %d\n", port); + } + + qemu_mutex_unlock(&s->port_lock); +} + diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index b93f534bee..2acbaeabaa 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -13,6 +13,9 @@ void xen_evtchn_create(void); int xen_evtchn_set_callback_param(uint64_t param); =20 +void hmp_xen_event_list(Monitor *mon, const QDict *qdict); +void hmp_xen_event_inject(Monitor *mon, const QDict *qdict); + struct evtchn_status; struct evtchn_close; struct evtchn_unmask; diff --git a/monitor/misc.c b/monitor/misc.c index 205487e2b9..2b11c0f86a 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -88,6 +88,10 @@ /* Make devices configuration available for use in hmp-commands*.hx templa= tes */ #include CONFIG_DEVICES =20 +#ifdef CONFIG_XEN_EMU +#include "hw/i386/kvm/xen_evtchn.h" +#endif + /* file descriptors passed via SCM_RIGHTS */ typedef struct mon_fd_t mon_fd_t; struct mon_fd_t { --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151389650337.8519992792668; Thu, 15 Dec 2022 16:43:09 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynk-0005SZ-AQ; Thu, 15 Dec 2022 19:42:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0005Dp-EQ for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn8-0006aT-5c for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:38 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvVK-EI; Fri, 16 Dec 2022 00:41:35 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cQO-HP; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=F6K+shAPVANmJrez+derq5sF6GIn6C1YKAiT4HPROfU=; b=MJXC98c5oFqTHqnQ3U3Y6f4PZ9 8oaHR8U+5MaNwLbBXlODIoclpShwd7/pAOsfJZCMQJsEebX+JbRcdcCoiPu7iLyFU9e8NmCis1dzs GjJN4VEE/tEQwg47d+hLSrI9BenEUSWH9q2wLxAmRSGHspYSqJ+tz9NQGkA2f8VVXAnGV+WQCt7Wj Dty/iSVD3IVMi5jrwCCGRUvb4oIT7mVJa6VKwvSv9IySy+yfs8wsdO+xzcKRBvjqSHDV494zf8KU+ EV7hHuHBSeKu2dMQhFMDSwhzKpPGrdDWGK4LrFuG/OJ3wz23nVTUeuiTVxj9kPb42chZxwzWMvF+e pZQChUtw==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 36/38] i386/xen: Implement SCHEDOP_poll Date: Fri, 16 Dec 2022 00:41:15 +0000 Message-Id: <20221216004117.862106-37-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151391805100004 Content-Type: text/plain; charset="utf-8" From: David Woodhouse Just a dummy implementation which will sched_yield(), but it's enough to stop the Linux guest panicking when running on a host kernel which doesn't intercept SCHEDOP_poll and lets it reach userspace. Signed-off-by: David Woodhouse --- target/i386/kvm/xen-emu.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 055afba627..a8c953e3ca 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -919,6 +919,17 @@ static bool kvm_xen_hcall_sched_op(struct kvm_xen_exit= *exit, X86CPU *cpu, err =3D schedop_shutdown(cs, arg); break; =20 + case SCHEDOP_poll: + /* + * Linux will panic if this doesn't work. Just yield; it's not + * worth overthinking it because wWith event channel handling + * in KVM, the kernel will intercept this and it will never + * reach QEMU anyway. + */ + sched_yield(); + err =3D 0; + break; + default: return false; } --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671152012476769.1869510189556; Thu, 15 Dec 2022 16:53:32 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5yo7-0005r1-GC; Thu, 15 Dec 2022 19:42:43 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynW-0005MF-R5 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:58 -0500 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynU-0006lq-06 for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:57 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by desiato.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymx-00Azz1-9b; Fri, 16 Dec 2022 00:41:44 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cQS-IA; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=LcaHmF/kMWTSEEQrkziKUiBG3ngCO21Jl2sYwAz7qyA=; b=iDQzcuzUnmYf4XX1hS3BfziiWN 5ZcShCcUyQEhP4t7zOvNrE9tE0Q3hf3VAR5GBIKFhHs8GIQOrF1TRP6FiVnXRjuv0D2DUyfGkMlG6 iVBXmw312Dp/Be/SZ48im2Bgzhiw5X1uZsS8mxWC5ojRJn9xMFgrRtrE6JOtOwCulNvpL4bDSuS9A fAovesr/Q7sNwI76EEEjZaesAml3Yz+pZDAwq9mBOVxGUnJosZRnRAkh3JDfKQ96Quh/pDEB3gATk CmWj2XuFgQ9ndX+XE8Bu8/7xRW88oEkJNyBseXzYn23U7WlLbRiyAdUSyi/Kij41dzWm2eB6+rhYR /m9xPlKA==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 37/38] hw/xen: Support HVM_PARAM_CALLBACK_TYPE_GSI callback Date: Fri, 16 Dec 2022 00:41:16 +0000 Message-Id: <20221216004117.862106-38-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; envelope-from=BATV+54656a84ae694b50c6d0+7054+infradead.org+dwmw2@desiato.srs.infradead.org; helo=desiato.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671152013887100004 From: David Woodhouse The GSI callback (and later PCI_INTX) is a level triggered interrupt. It is asserted when an event channel is delivered to vCPU0, and is supposed to be cleared when the vcpu_info->evtchn_upcall_pending field for vCPU0 is cleared again. Thankfully, Xen does *not* assert the GSI if the guest sets its own evtchn_upcall_pending field; we only need to assert the GSI when we have delivered an event for ourselves. So that's the easy part. However, we *do* need to poll for the evtchn_upcall_pending flag being cleared. In an ideal world we would poll that when the EOI happens on the PIC/IOAPIC. That's how it works in the kernel with the VFIO eventfd pairs =E2=80=94 one is used to trigger the interrupt, and the other works i= n the other direction to 'resample' on EOI, and trigger the first eventfd again if the line is still active. However, QEMU doesn't seem to do that. Even VFIO level interrupts seem to be supported by temporarily unmapping the device's BARs from the guest when an interrupt happens, then trapping *all* MMIO to the device and sending the 'resample' event on *every* MMIO access until the IRQ is cleared! Maybe in future we'll plumb the 'resample' concept through QEMU's irq framework but for now we'll do what Xen itself does: just check the flag on every vmexit if the upcall GSI is known to be asserted. Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 88 +++++++++++++++++++++++++++++++++++---- hw/i386/kvm/xen_evtchn.h | 3 ++ hw/i386/pc.c | 10 ++++- include/sysemu/kvm_xen.h | 2 +- target/i386/cpu.h | 1 + target/i386/kvm/kvm.c | 13 ++++++ target/i386/kvm/xen-emu.c | 64 ++++++++++++++++++++-------- target/i386/kvm/xen-emu.h | 1 + 8 files changed, 154 insertions(+), 28 deletions(-) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 9292602c09..8ea8cf550e 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -24,6 +24,8 @@ =20 #include "hw/sysbus.h" #include "hw/xen/xen.h" +#include "hw/i386/x86.h" +#include "hw/irq.h" =20 #include "xen_evtchn.h" #include "xen_overlay.h" @@ -102,6 +104,7 @@ struct XenEvtchnState { QemuMutex port_lock; uint32_t nr_ports; XenEvtchnPort port_table[EVTCHN_2L_NR_CHANNELS]; + qemu_irq gsis[GSI_NUM_PINS]; }; =20 struct XenEvtchnState *xen_evtchn_singleton; @@ -166,9 +169,29 @@ static const TypeInfo xen_evtchn_info =3D { void xen_evtchn_create(void) { XenEvtchnState *s =3D XEN_EVTCHN(sysbus_create_simple(TYPE_XEN_EVTCHN,= -1, NULL)); + int i; + xen_evtchn_singleton =3D s; =20 qemu_mutex_init(&s->port_lock); + + for (i =3D 0; i < GSI_NUM_PINS; i++) { + sysbus_init_irq(SYS_BUS_DEVICE(s), &s->gsis[i]); + } +} + +void xen_evtchn_connect_gsis(qemu_irq *system_gsis) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + int i; + + if (!s) { + return; + } + + for (i =3D 0; i < GSI_NUM_PINS; i++) { + sysbus_connect_irq(SYS_BUS_DEVICE(s), i, system_gsis[i]); + } } =20 static void xen_evtchn_register_types(void) @@ -178,26 +201,75 @@ static void xen_evtchn_register_types(void) =20 type_init(xen_evtchn_register_types) =20 - #define CALLBACK_VIA_TYPE_SHIFT 56 =20 int xen_evtchn_set_callback_param(uint64_t param) { + XenEvtchnState *s =3D xen_evtchn_singleton; int ret =3D -ENOSYS; =20 - if (param >> CALLBACK_VIA_TYPE_SHIFT =3D=3D HVM_PARAM_CALLBACK_TYPE_VE= CTOR) { + if (!s) { + return -ENOTSUP; + } + + switch (param >> CALLBACK_VIA_TYPE_SHIFT) { + case HVM_PARAM_CALLBACK_TYPE_VECTOR: { struct kvm_xen_hvm_attr xa =3D { .type =3D KVM_XEN_ATTR_TYPE_UPCALL_VECTOR, .u.vector =3D (uint8_t)param, }; =20 ret =3D kvm_vm_ioctl(kvm_state, KVM_XEN_HVM_SET_ATTR, &xa); - if (!ret && xen_evtchn_singleton) - xen_evtchn_singleton->callback_param =3D param; + break; + } + case HVM_PARAM_CALLBACK_TYPE_GSI: + ret =3D 0; + break; } + + if (!ret) { + s->callback_param =3D param; + } + return ret; } =20 +static void xen_evtchn_set_callback_level(XenEvtchnState *s, int level) +{ + uint32_t param =3D (uint32_t)s->callback_param; + + switch (s->callback_param >> CALLBACK_VIA_TYPE_SHIFT) { + case HVM_PARAM_CALLBACK_TYPE_GSI: + if (param < GSI_NUM_PINS) { + qemu_set_irq(s->gsis[param], level); + } + break; + } +} + +static void inject_callback(XenEvtchnState *s, uint32_t vcpu) +{ + if (kvm_xen_inject_vcpu_callback_vector(vcpu, s->callback_param)) { + return; + } + + /* GSI or PCI_INTX delivery is only for events on vCPU 0 */ + if (vcpu) { + return; + } + + xen_evtchn_set_callback_level(s, 1); +} + +void xen_evtchn_deassert_callback(void) +{ + XenEvtchnState *s =3D xen_evtchn_singleton; + + if (s) { + xen_evtchn_set_callback_level(s, 0); + } +} + static void deassign_kernel_port(evtchn_port_t port) { struct kvm_xen_hvm_attr ha; @@ -359,7 +431,7 @@ static int do_unmask_port_lm(XenEvtchnState *s, evtchn_= port_t port, return 0; } =20 - kvm_xen_inject_vcpu_callback_vector(s->port_table[port].vcpu); + inject_callback(s, s->port_table[port].vcpu); =20 return 0; } @@ -413,7 +485,7 @@ static int do_unmask_port_compat(XenEvtchnState *s, evt= chn_port_t port, return 0; } =20 - kvm_xen_inject_vcpu_callback_vector(s->port_table[port].vcpu); + inject_callback(s, s->port_table[port].vcpu); =20 return 0; } @@ -481,7 +553,7 @@ static int do_set_port_lm(XenEvtchnState *s, evtchn_por= t_t port, return 0; } =20 - kvm_xen_inject_vcpu_callback_vector(s->port_table[port].vcpu); + inject_callback(s, s->port_table[port].vcpu); =20 return 0; } @@ -524,7 +596,7 @@ static int do_set_port_compat(XenEvtchnState *s, evtchn= _port_t port, return 0; } =20 - kvm_xen_inject_vcpu_callback_vector(s->port_table[port].vcpu); + inject_callback(s, s->port_table[port].vcpu); =20 return 0; } diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h index 2acbaeabaa..1176b67b91 100644 --- a/hw/i386/kvm/xen_evtchn.h +++ b/hw/i386/kvm/xen_evtchn.h @@ -9,9 +9,12 @@ * See the COPYING file in the top-level directory. */ =20 +#include "hw/sysbus.h" =20 void xen_evtchn_create(void); int xen_evtchn_set_callback_param(uint64_t param); +void xen_evtchn_connect_gsis(qemu_irq *system_gsis); +void xen_evtchn_deassert_callback(void); =20 void hmp_xen_event_list(Monitor *mon, const QDict *qdict); void hmp_xen_event_inject(Monitor *mon, const QDict *qdict); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 427f79e6a8..1c4941de8f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1303,6 +1303,12 @@ void pc_basic_device_init(struct PCMachineState *pcm= s, } *rtc_state =3D mc146818_rtc_init(isa_bus, 2000, rtc_irq); =20 +#ifdef CONFIG_XEN_EMU + if (xen_mode =3D=3D XEN_EMULATE) { + xen_evtchn_connect_gsis(gsi); + } +#endif + qemu_register_boot_set(pc_boot_set, *rtc_state); =20 if (!xen_enabled() && @@ -1848,8 +1854,8 @@ int pc_machine_kvm_type(MachineState *machine, const = char *kvm_type) { #ifdef CONFIG_XEN_EMU if (xen_mode =3D=3D XEN_EMULATE) { - xen_overlay_create(); - xen_evtchn_create(); + xen_overlay_create(); + xen_evtchn_create(); } #endif return 0; diff --git a/include/sysemu/kvm_xen.h b/include/sysemu/kvm_xen.h index e5b14ffe8d..73fe5969b8 100644 --- a/include/sysemu/kvm_xen.h +++ b/include/sysemu/kvm_xen.h @@ -13,7 +13,7 @@ #define QEMU_SYSEMU_KVM_XEN_H =20 void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id); -void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id); +bool kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, uint64_t callba= ck_param); int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port); =20 #endif /* QEMU_SYSEMU_KVM_XEN_H */ diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 846c738fd7..9330eb83fd 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1795,6 +1795,7 @@ typedef struct CPUArchState { uint64_t xen_vcpu_time_info_gpa; uint64_t xen_vcpu_runstate_gpa; uint8_t xen_vcpu_callback_vector; + bool xen_callback_asserted; uint16_t xen_virq[XEN_NR_VIRQS]; #endif #if defined(CONFIG_HVF) diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index cbf41d6f81..32d808da37 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -5431,6 +5431,19 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_ru= n *run) char str[256]; KVMState *state; =20 +#ifdef CONFIG_XEN_EMU + /* + * If the callback is asserted as a GSI (or PCI INTx) then check if + * vcpu_info->evtchn_upcall_pending has been cleared, and deassert + * the callback IRQ if so. Ideally we could hook into the PIC/IOAPIC + * EOI and only resample then, exactly how the VFIO eventfd pairs + * are designed to work for level triggered interrupts. + */ + if (cpu->env.xen_callback_asserted) { + kvm_xen_maybe_deassert_callback(cs); + } +#endif + switch (run->exit_reason) { case KVM_EXIT_HLT: DPRINTF("handle_hlt\n"); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index a8c953e3ca..48ae47809a 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -240,18 +240,11 @@ static void *gpa_to_hva(uint64_t gpa) mrs.offset_within_region); } =20 -void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id) +static void *vcpu_info_hva_from_cs(CPUState *cs) { - CPUState *cs =3D qemu_get_cpu(vcpu_id); - CPUX86State *env; - uint64_t gpa; - - if (!cs) { - return NULL; - } - env =3D &X86_CPU(cs)->env; + CPUX86State *env =3D &X86_CPU(cs)->env; + uint64_t gpa =3D env->xen_vcpu_info_gpa; =20 - gpa =3D env->xen_vcpu_info_gpa; if (gpa =3D=3D UINT64_MAX) gpa =3D env->xen_vcpu_info_default_gpa; if (gpa =3D=3D UINT64_MAX) @@ -260,13 +253,38 @@ void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id) return gpa_to_hva(gpa); } =20 -void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id) +void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id) +{ + CPUState *cs =3D qemu_get_cpu(vcpu_id); + + if (!cs) { + return NULL; + } + + return vcpu_info_hva_from_cs(cs); +} + +void kvm_xen_maybe_deassert_callback(CPUState *cs) +{ + struct vcpu_info *vi =3D vcpu_info_hva_from_cs(cs); + if (!vi) { + return; + } + + /* If the evtchn_upcall_pending flag is cleared, turn the GSI off. */ + if (!vi->evtchn_upcall_pending) { + X86_CPU(cs)->env.xen_callback_asserted =3D false; + xen_evtchn_deassert_callback(); + } +} + +bool kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, uint64_t callba= ck_param) { CPUState *cs =3D qemu_get_cpu(vcpu_id); uint8_t vector; =20 if (!cs) { - return; + return false; } vector =3D X86_CPU(cs)->env.xen_vcpu_callback_vector; =20 @@ -278,13 +296,25 @@ void kvm_xen_inject_vcpu_callback_vector(uint32_t vcp= u_id) .data =3D vector | (1UL << MSI_DATA_LEVEL_SHIFT), }; kvm_irqchip_send_msi(kvm_state, msg); - return; + return true; } =20 - /* If the evtchn_upcall_pending field in the vcpu_info is set, then - * KVM will automatically deliver the vector on entering the vCPU - * so all we have to do is kick it out. */ - qemu_cpu_kick(cs); + switch(callback_param >> 56) { + case HVM_PARAM_CALLBACK_TYPE_VECTOR: + /* If the evtchn_upcall_pending field in the vcpu_info is set,= then + * KVM will automatically deliver the vector on entering the v= CPU + * so all we have to do is kick it out. */ + qemu_cpu_kick(cs); + return true; + + case HVM_PARAM_CALLBACK_TYPE_GSI: + case HVM_PARAM_CALLBACK_TYPE_PCI_INTX: + if (vcpu_id =3D=3D 0) { + X86_CPU(cs)->env.xen_callback_asserted =3D true; + } + return false; + } + return false; } =20 static int kvm_xen_set_vcpu_timer(CPUState *cs) diff --git a/target/i386/kvm/xen-emu.h b/target/i386/kvm/xen-emu.h index 58e4748d80..0ff8bed350 100644 --- a/target/i386/kvm/xen-emu.h +++ b/target/i386/kvm/xen-emu.h @@ -27,5 +27,6 @@ int kvm_xen_init(KVMState *s, uint32_t hypercall_msr); int kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit); int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type, uint64_t gpa); int kvm_xen_set_vcpu_callback_vector(CPUState *cs); +void kvm_xen_maybe_deassert_callback(CPUState *cs); =20 #endif /* QEMU_I386_KVM_XEN_EMU_H */ --=20 2.35.3 From nobody Thu May 16 07:39:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1671151924212536.6452472956548; Thu, 15 Dec 2022 16:52:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5ynP-0005Hu-LN; Thu, 15 Dec 2022 19:41:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5ynC-0005Dn-Dj for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:40 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5yn5-0006aa-IL for qemu-devel@nongnu.org; Thu, 15 Dec 2022 19:41:36 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5yn6-00EvVM-FG; Fri, 16 Dec 2022 00:41:35 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p5ymw-003cQW-JZ; Fri, 16 Dec 2022 00:41:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=RRDYboOhQxbNNkVR+5pAKTs2a3rx182wi51/Plqb2lg=; b=Y1eNd2/DBOsfQEw1cyYc7rZ+Vr 7UF59iLongvkas5Z6+gAH1OpeQNuA0VB3lDWnc236F1kcf4QFtDtZLLDjLiKLIt6FmmSKx7ofCfGz coylGSgANxfpcb1eaVux6Yag2MPP+aRGM8acN48gWwLpLjU63ffbLrNR04MeQaY9JPwe0+Ozq4+Ff eD5Y167E86mET/6u3XrAzWaikRpgxCcrs0atDkSpEFaUfLNAYtBisfFXcBOrw2fDRthN+LHSMaoD1 wpjc686X05pqxMvyI9ZwKcoi4JqjIS6oTSWenJBXLa/SEYQNzfO1uH5Uk3lhCBVsbzcVjhl7eVeN0 O8uhYUdw==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v3 38/38] hw/xen: Support HVM_PARAM_CALLBACK_TYPE_PCI_INTX callback Date: Fri, 16 Dec 2022 00:41:17 +0000 Message-Id: <20221216004117.862106-39-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221216004117.862106-1-dwmw2@infradead.org> References: <20221216004117.862106-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+64e888c4aa1bfc596c85+7054+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1671151925037100001 From: David Woodhouse The guest is permitted to specify an arbitrary domain/bus/device/function and INTX pin from which the callback IRQ shall appear to have come. In QEMU we can only easily do this for devices that actually exist, and even that requires us "knowing" that it's a PCMachine in order to find the PCI root bus =E2=80=94 although that's OK really because it's always tr= ue. We also don't get to get notified of INTX routing changes, because we can't do that as a passive observer; if we try to register a notifier it will overwrite any existing notifier callback on the device. But in practice, guests using PCI_INTX will only ever use pin A on the Xen platform device, and won't swizzle the INTX routing after they set it up. So this is just fine. Signed-off-by: David Woodhouse --- hw/i386/kvm/xen_evtchn.c | 70 +++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 8ea8cf550e..2852b46b45 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -25,6 +25,8 @@ #include "hw/sysbus.h" #include "hw/xen/xen.h" #include "hw/i386/x86.h" +#include "hw/i386/pc.h" +#include "hw/pci/pci.h" #include "hw/irq.h" =20 #include "xen_evtchn.h" @@ -100,6 +102,7 @@ struct XenEvtchnState { /*< public >*/ =20 uint64_t callback_param; + uint32_t callback_gsi; =20 QemuMutex port_lock; uint32_t nr_ports; @@ -201,11 +204,50 @@ static void xen_evtchn_register_types(void) =20 type_init(xen_evtchn_register_types) =20 +static int set_callback_pci_intx(XenEvtchnState *s, uint64_t param) +{ + PCMachineState *pcms =3D PC_MACHINE(qdev_get_machine()); + uint8_t pin =3D param & 3; + uint8_t devfn =3D (param >> 8) & 0xff; + uint16_t bus =3D (param >> 16) & 0xffff; + uint16_t domain =3D (param >> 32) & 0xffff; + PCIDevice *pdev; + PCIINTxRoute r; + + if (domain || !pcms) + return 0; + + pdev =3D pci_find_device(pcms->bus, bus, devfn); + if (!pdev) { + return 0; + } + + r =3D pci_device_route_intx_to_irq(pdev, pin); + if (r.mode !=3D PCI_INTX_ENABLED) { + return 0; + } + + /* + * Hm, can we be notified of INTX routing changes? Not without + * *owning* the device and being allowed to overwrite its own + * ->intx_routing_notifier, AFAICT. So let's not. + */ + return r.irq; +} + +static void xen_evtchn_set_callback_level(XenEvtchnState *s, int level) +{ + if (s->callback_gsi && s->callback_gsi < GSI_NUM_PINS) { + qemu_set_irq(s->gsis[s->callback_gsi], level); + } +} + #define CALLBACK_VIA_TYPE_SHIFT 56 =20 int xen_evtchn_set_callback_param(uint64_t param) { XenEvtchnState *s =3D xen_evtchn_singleton; + uint32_t gsi =3D 0; int ret =3D -ENOSYS; =20 if (!s) { @@ -220,31 +262,35 @@ int xen_evtchn_set_callback_param(uint64_t param) }; =20 ret =3D kvm_vm_ioctl(kvm_state, KVM_XEN_HVM_SET_ATTR, &xa); + gsi =3D 0; break; } case HVM_PARAM_CALLBACK_TYPE_GSI: + gsi =3D (uint32_t)param; ret =3D 0; break; + + case HVM_PARAM_CALLBACK_TYPE_PCI_INTX: + gsi =3D set_callback_pci_intx(s, param); + ret =3D gsi ? 0 : -EINVAL; + break; } =20 if (!ret) { s->callback_param =3D param; - } - - return ret; -} + if (gsi !=3D s->callback_gsi) { + struct vcpu_info *vi =3D kvm_xen_get_vcpu_info_hva(0); =20 -static void xen_evtchn_set_callback_level(XenEvtchnState *s, int level) -{ - uint32_t param =3D (uint32_t)s->callback_param; + xen_evtchn_set_callback_level(s, 0); + s->callback_gsi =3D gsi; =20 - switch (s->callback_param >> CALLBACK_VIA_TYPE_SHIFT) { - case HVM_PARAM_CALLBACK_TYPE_GSI: - if (param < GSI_NUM_PINS) { - qemu_set_irq(s->gsis[param], level); + if (gsi && vi && vi->evtchn_upcall_pending) { + xen_evtchn_set_callback_level(s, 1); + } } - break; } + + return ret; } =20 static void inject_callback(XenEvtchnState *s, uint32_t vcpu) --=20 2.35.3