From nobody Fri Nov 29 16:38:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1632544664; cv=none; d=zohomail.com; s=zohoarc; b=KkVTYNCHewVYQoIpjJxeqJwi9F+TsVnw3wg8beLw9GyD3rsxl5A6mR/O2QIdGWpcH4VPsMJ5wz1T59OfAvjI6rjVUQ8WaR99xft/Ug1iw9x88j0FLczfx6jlL5/X2l5ARhOgMhwRiti6Ayt2dVy0Vz0G3lxwC9qyKaD2dMDfc08= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1632544664; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9SjNRKk5NXPDvp5QWjMJFRC3W8sz2kqMr2/m/QyAXos=; b=R/MquxSIDALiD4MHsqEOtdGGYJiG32zKC8WXWwBlduHRymOhqfmtW9loFKVA76rRMlwyjYVgvwEVgemkI+sbVMwbFchhzRw8CTHuBUvXXKzSd83gfBunOutw3TpNKmBiUQ/BJah1k6oYyHmpjkgne0C0nLf+lnD1fFgf3qoHTbs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1632544664752606.1652207689992; Fri, 24 Sep 2021 21:37:44 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.195624.348666 (Exim 4.92) (envelope-from ) id 1mTzR1-0004Dq-3U; Sat, 25 Sep 2021 04:37:11 +0000 Received: by outflank-mailman (output) from mailman id 195624.348666; Sat, 25 Sep 2021 04:37:11 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1mTzR0-0004CW-Tc; Sat, 25 Sep 2021 04:37:10 +0000 Received: by outflank-mailman (input) for mailman id 195624; Fri, 24 Sep 2021 19:40:40 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1mTr3n-0003J8-TX for xen-devel@lists.xenproject.org; Fri, 24 Sep 2021 19:40:39 +0000 Received: from mail-qt1-x833.google.com (unknown [2607:f8b0:4864:20::833]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 18a82e6f-e431-48f1-80ac-8f7083d24bae; Fri, 24 Sep 2021 19:40:36 +0000 (UTC) Received: by mail-qt1-x833.google.com with SMTP id r1so10488410qta.12 for ; Fri, 24 Sep 2021 12:40:36 -0700 (PDT) Received: from localhost.localdomain ([24.214.236.228]) by smtp.gmail.com with ESMTPSA id s10sm6957971qko.134.2021.09.24.12.40.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 12:40:35 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 18a82e6f-e431-48f1-80ac-8f7083d24bae DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9SjNRKk5NXPDvp5QWjMJFRC3W8sz2kqMr2/m/QyAXos=; b=YLnmy4MhxIOeh27w+2iaWtlqaOtNA/wco23lILFwUvPrqfxEVZy0SNBQbX/VHfRymH s4tTtNwIH8Yxq57mEcNQPanObde3berAZwimM28vsyBXtozOeKOlb+jKsBlO2n4541Fg 0gO1qdBTraBk1fkjF8tBuLvUalMAJlD2yAXEg6UF0H96E0rV2dKz/OWI4HWIHIGh+1CL kwbzxUWI/ItfJxvij1nJMoTNb+juSXueFTRsjcEA89zbbIxbIzKlbKY7o4/hdU246Fb+ keMjIEm+3tR+Vgp4+Y2C/xV8WfEhOMa5DhBkWajEu9vH71zayBeDSV0gF9Tq7L1bHkH8 bJmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9SjNRKk5NXPDvp5QWjMJFRC3W8sz2kqMr2/m/QyAXos=; b=Eo4pvajqSzrjJjVvByxT7hvFTI9cVpWK014DlfIcHqAGTKg+xs6tNJeSH4uCOXys0Y kCQbeJnsCq11oDehMNDGroPsGQie4Zg7d6ejSZpSz1f+QsQiD65Ml3sHak7oTEbeg7v0 RUOmvQuvi30rNmMBY4LgACIxyvOUJoFdwWxxeENJDwHj4CPtOV608oyd5LNd8V3M6k88 p6G8EFlUOuNSduCsQ1t8i3q0NP6bDQ1/b9Fm60v0T4aAxmZWDuIr6aOW4NvDZw91NrUN ZFU8fY+zatYqyLWMRU2IoGBhBdmP3CXx1Ci6vXsEgFaaxAK2ZsaWANlUV/UwkK59IOXZ YP7A== X-Gm-Message-State: AOAM532GuLoFF9GMUfUApX5UWUo9MDDorimsvJHwzbuPfsxeNushz4kF B3sYmdzPYU4RbyH7HKxzRSaQC6HY4nqIaA== X-Google-Smtp-Source: ABdhPJwaUDVJHuEB0YctSzsdaH5+ImJpcYhgb38pEzB5Qxbt6mMGgA1kElXucw2fyZqsS7ykji2mVg== X-Received: by 2002:ac8:7143:: with SMTP id h3mr6216840qtp.242.1632512435684; Fri, 24 Sep 2021 12:40:35 -0700 (PDT) From: Alex Olson To: xen-devel@lists.xenproject.org Cc: Alex Olson , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Wei Liu , Ian Jackson , George Dunlap , Julien Grall , Stefano Stabellini , Juergen Gross , Anthony PERARD , Alex Olson Subject: [PATCH 1/1] x86: centralize default APIC id definition Date: Fri, 24 Sep 2021 14:39:55 -0500 Message-Id: <85b59046315b8a84afa8538aacdea92b19200faa.1632512149.git.this.is.a0lson@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1632544666615100001 Content-Type: text/plain; charset="utf-8" Inspired by an earlier attempt by Chao Gao , this revision aims to put the hypervisor in control of x86 APIC identifier definition instead of hard-coding a formula in multiple places (libxl, hvmloader, hypervisor). This is intended as a first step toward exposing/altering CPU topology seen by guests. Changes: - Add field to vlapic for holding default ID (on reset) - add HVMOP_get_vcpu_topology_id hypercall so libxl (for PVH domains) can access APIC ids needed for ACPI table definition prior to domain star= t. - For HVM guests, hvmloader now also uses the same hypercall. - Make CPUID code use vlapic ID instead of hard-coded formula for runtime reporting to guests Signed-off-by: Alex Olson --- tools/firmware/hvmloader/Makefile | 2 +- tools/firmware/hvmloader/config.h | 1 - tools/firmware/hvmloader/hvmloader.c | 3 +- tools/firmware/hvmloader/mp_tables.c | 3 +- tools/firmware/hvmloader/smp.c | 3 +- tools/firmware/hvmloader/topology.c | 54 ++++++++++++++++++++++++++ tools/firmware/hvmloader/topology.h | 33 ++++++++++++++++ tools/firmware/hvmloader/util.c | 6 ++- tools/include/xenctrl.h | 6 +++ tools/libacpi/build.c | 4 +- tools/libacpi/libacpi.h | 3 +- tools/libs/ctrl/xc_domain.c | 27 +++++++++++++ tools/libs/light/libxl_x86_acpi.c | 9 ++++- xen/arch/x86/cpuid.c | 14 +++++-- xen/arch/x86/hvm/hvm.c | 36 ++++++++++++++++- xen/arch/x86/hvm/vlapic.c | 18 ++++++--- xen/include/asm-x86/hvm/vlapic.h | 4 +- xen/include/public/arch-x86/hvm/save.h | 1 + xen/include/public/hvm/hvm_op.h | 17 ++++++++ 19 files changed, 222 insertions(+), 22 deletions(-) create mode 100644 tools/firmware/hvmloader/topology.c create mode 100644 tools/firmware/hvmloader/topology.h diff --git a/tools/firmware/hvmloader/Makefile b/tools/firmware/hvmloader/M= akefile index e980ce7c5f..158f62b4e6 100644 --- a/tools/firmware/hvmloader/Makefile +++ b/tools/firmware/hvmloader/Makefile @@ -29,7 +29,7 @@ CFLAGS +=3D $(CFLAGS_xeninclude) CFLAGS +=3D -D__XEN_INTERFACE_VERSION__=3D__XEN_LATEST_INTERFACE_VERSION__ =20 OBJS =3D hvmloader.o mp_tables.o util.o smbios.o=20 -OBJS +=3D smp.o cacheattr.o xenbus.o vnuma.o +OBJS +=3D smp.o cacheattr.o xenbus.o vnuma.o topology.o OBJS +=3D e820.o pci.o pir.o ctype.o OBJS +=3D hvm_param.o OBJS +=3D ovmf.o seabios.o diff --git a/tools/firmware/hvmloader/config.h b/tools/firmware/hvmloader/c= onfig.h index 844120bc87..91d73c9086 100644 --- a/tools/firmware/hvmloader/config.h +++ b/tools/firmware/hvmloader/config.h @@ -50,7 +50,6 @@ extern uint8_t ioapic_version; #define IOAPIC_ID 0x01 =20 #define LAPIC_BASE_ADDRESS 0xfee00000 -#define LAPIC_ID(vcpu_id) ((vcpu_id) * 2) =20 #define PCI_ISA_DEVFN 0x08 /* dev 1, fn 0 */ #define PCI_ISA_IRQ_MASK 0x0c20U /* ISA IRQs 5,10,11 are PCI connected = */ diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloade= r/hvmloader.c index c58841e5b5..250e6779b1 100644 --- a/tools/firmware/hvmloader/hvmloader.c +++ b/tools/firmware/hvmloader/hvmloader.c @@ -25,6 +25,7 @@ #include "pci_regs.h" #include "apic_regs.h" #include "vnuma.h" +#include "topology.h" #include #include #include @@ -225,7 +226,7 @@ static void apic_setup(void) =20 /* 8259A ExtInts are delivered through IOAPIC pin 0 (Virtual Wire Mode= ). */ ioapic_write(0x10, APIC_DM_EXTINT); - ioapic_write(0x11, SET_APIC_ID(LAPIC_ID(0))); + ioapic_write(0x11, SET_APIC_ID(get_topology_id(0))); } =20 struct bios_info { diff --git a/tools/firmware/hvmloader/mp_tables.c b/tools/firmware/hvmloade= r/mp_tables.c index d207ecbf00..562961ca0b 100644 --- a/tools/firmware/hvmloader/mp_tables.c +++ b/tools/firmware/hvmloader/mp_tables.c @@ -29,6 +29,7 @@ =20 #include #include "config.h" +#include "topology.h" =20 /* number of non-processor MP table entries */ #define NR_NONPROC_ENTRIES 18 @@ -199,7 +200,7 @@ static void fill_mp_config_table(struct mp_config_table= *mpct, int length) static void fill_mp_proc_entry(struct mp_proc_entry *mppe, int vcpu_id) { mppe->type =3D ENTRY_TYPE_PROCESSOR; - mppe->lapic_id =3D LAPIC_ID(vcpu_id); + mppe->lapic_id =3D get_topology_id(vcpu_id); mppe->lapic_version =3D 0x11; mppe->cpu_flags =3D CPU_FLAG_ENABLED; if ( vcpu_id =3D=3D 0 ) diff --git a/tools/firmware/hvmloader/smp.c b/tools/firmware/hvmloader/smp.c index 082b17f138..5091ff1f1f 100644 --- a/tools/firmware/hvmloader/smp.c +++ b/tools/firmware/hvmloader/smp.c @@ -22,6 +22,7 @@ #include "util.h" #include "config.h" #include "apic_regs.h" +#include "topology.h" =20 #define AP_BOOT_EIP 0x1000 extern char ap_boot_start[], ap_boot_end[]; @@ -86,7 +87,7 @@ static void lapic_wait_ready(void) =20 static void boot_cpu(unsigned int cpu) { - unsigned int icr2 =3D SET_APIC_DEST_FIELD(LAPIC_ID(cpu)); + unsigned int icr2 =3D SET_APIC_DEST_FIELD(get_topology_id(cpu)); =20 /* Initialise shared variables. */ ap_cpuid =3D cpu; diff --git a/tools/firmware/hvmloader/topology.c b/tools/firmware/hvmloader= /topology.c new file mode 100644 index 0000000000..f92bbb8b7a --- /dev/null +++ b/tools/firmware/hvmloader/topology.c @@ -0,0 +1,54 @@ +/* + * topology.c: obtain vCPU topology from hypervisor + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP= OSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT= IAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STR= ICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W= AY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "util.h" +#include "hypercall.h" +#include "topology.h" +#include + +uint32_t get_topology_id(unsigned vcpu_id) +{ + int rc; + struct xen_vcpu_topology_id tid =3D + { .domid =3D DOMID_SELF, .vcpu_id =3D vcpu_id }; + + rc =3D hypercall_hvm_op(HVMOP_get_vcpu_topology_id, &tid); + if ( rc < 0 ) + { + printf("Failed to retrieve cpu topology for vcpu=3D%u, rc =3D %d\n= ", vcpu_id, rc); + return 0xdeadbeef; + } + return tid.topology_id; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/firmware/hvmloader/topology.h b/tools/firmware/hvmloader= /topology.h new file mode 100644 index 0000000000..6e37051556 --- /dev/null +++ b/tools/firmware/hvmloader/topology.h @@ -0,0 +1,33 @@ +/*************************************************************************= ***** + * topology.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modi= fy, + * merge, publish, distribute, sublicense, and/or sell copies of the Softw= are, + * and to permit persons to whom the Software is furnished to do so, subje= ct 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 DEA= LINGS + * IN THE SOFTWARE. + */ +#ifndef __HVMLOADER_TOPOLOGY_H_ +#define __HVMLOADER_TOPOLOGY_H_ + +uint32_t get_topology_id(unsigned vcpu_id); + +#endif /* __HVMLOADER_TOPOLOGY_H__ */ diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/uti= l.c index 581b35e5cf..a5fe15d198 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -22,6 +22,7 @@ #include "hypercall.h" #include "ctype.h" #include "vnuma.h" +#include "topology.h" #include #include #include @@ -910,9 +911,9 @@ static void acpi_mem_free(struct acpi_ctxt *ctxt, /* ACPI builder currently doesn't free memory so this is just a stub */ } =20 -static uint32_t acpi_lapic_id(unsigned cpu) +static uint32_t acpi_lapic_id(unsigned cpu, void *arg) { - return LAPIC_ID(cpu); + return get_topology_id(cpu); } =20 void hvmloader_acpi_build_tables(struct acpi_config *config, @@ -943,6 +944,7 @@ void hvmloader_acpi_build_tables(struct acpi_config *co= nfig, =20 config->lapic_base_address =3D LAPIC_BASE_ADDRESS; config->lapic_id =3D acpi_lapic_id; + config->lapic_id_arg =3D NULL; config->ioapic_base_address =3D ioapic_base_address; config->ioapic_id =3D IOAPIC_ID; config->pci_isa_irq_mask =3D PCI_ISA_IRQ_MASK;=20 diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h index a3063998e0..c15a2bb0c8 100644 --- a/tools/include/xenctrl.h +++ b/tools/include/xenctrl.h @@ -1262,6 +1262,12 @@ int xc_domain_set_memory_map(xc_interface *xch, int xc_get_machine_memory_map(xc_interface *xch, struct e820entry entries[], uint32_t max_entries); + +int xc_get_vcpu_topology_id(xc_interface *xch, + uint32_t domid, + unsigned int vcpu_id, + uint32_t *topology_id); + #endif =20 int xc_reserved_device_memory_map(xc_interface *xch, diff --git a/tools/libacpi/build.c b/tools/libacpi/build.c index fe2db66a62..aa5e851172 100644 --- a/tools/libacpi/build.c +++ b/tools/libacpi/build.c @@ -156,7 +156,7 @@ static struct acpi_20_madt *construct_madt(struct acpi_= ctxt *ctxt, lapic->length =3D sizeof(*lapic); /* Processor ID must match processor-object IDs in the DSDT. */ lapic->acpi_processor_id =3D i; - lapic->apic_id =3D config->lapic_id(i); + lapic->apic_id =3D config->lapic_id(i, config->lapic_id_arg); lapic->flags =3D (test_bit(i, hvminfo->vcpu_online) ? ACPI_LOCAL_APIC_ENABLED : 0); lapic++; @@ -244,7 +244,7 @@ static struct acpi_20_srat *construct_srat(struct acpi_= ctxt *ctxt, processor->type =3D ACPI_PROCESSOR_AFFINITY; processor->length =3D sizeof(*processor); processor->domain =3D config->numa.vcpu_to_vnode[i]; - processor->apic_id =3D config->lapic_id(i); + processor->apic_id =3D config->lapic_id(i, config->lapic_id_arg); processor->flags =3D ACPI_LOCAL_APIC_AFFIN_ENABLED; processor++; } diff --git a/tools/libacpi/libacpi.h b/tools/libacpi/libacpi.h index a2efd23b0b..c66d1f0ea1 100644 --- a/tools/libacpi/libacpi.h +++ b/tools/libacpi/libacpi.h @@ -91,7 +91,8 @@ struct acpi_config { unsigned long rsdp; =20 /* x86-specific parameters */ - uint32_t (*lapic_id)(unsigned cpu); + uint32_t (*lapic_id)(unsigned cpu, void *arg); + void *lapic_id_arg; uint32_t lapic_base_address; uint32_t ioapic_base_address; uint16_t pci_isa_irq_mask; diff --git a/tools/libs/ctrl/xc_domain.c b/tools/libs/ctrl/xc_domain.c index 23322b70b5..087196130c 100644 --- a/tools/libs/ctrl/xc_domain.c +++ b/tools/libs/ctrl/xc_domain.c @@ -1506,6 +1506,33 @@ int xc_get_hvm_param(xc_interface *handle, uint32_t = dom, int param, unsigned lon return 0; } =20 + +#if defined (__i386__) || defined (__x86_64__) +int xc_get_vcpu_topology_id(xc_interface *xch, + uint32_t dom, + unsigned int vcpu_id, + uint32_t *topology_id) +{ + DECLARE_HYPERCALL_BUFFER(xen_vcpu_topology_id_t, arg); + int rc; + + arg =3D xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); + if ( arg =3D=3D NULL ) + return -1; + + arg->domid =3D dom; + arg->vcpu_id =3D vcpu_id; + arg->topology_id =3D 0xdeadbeef; + + rc =3D xencall2(xch->xcall, __HYPERVISOR_hvm_op, + HVMOP_get_vcpu_topology_id, + HYPERCALL_BUFFER_AS_ARG(arg)); + *topology_id =3D arg->topology_id; + xc_hypercall_buffer_free(xch, arg); + return rc; +} +#endif + int xc_domain_setdebugging(xc_interface *xch, uint32_t domid, unsigned int enable) diff --git a/tools/libs/light/libxl_x86_acpi.c b/tools/libs/light/libxl_x86= _acpi.c index 3eca1c7a9f..8e471f222f 100644 --- a/tools/libs/light/libxl_x86_acpi.c +++ b/tools/libs/light/libxl_x86_acpi.c @@ -79,9 +79,13 @@ static void acpi_mem_free(struct acpi_ctxt *ctxt, { } =20 -static uint32_t acpi_lapic_id(unsigned cpu) +static uint32_t acpi_lapic_id(unsigned cpu, void *arg) { - return cpu * 2; + struct xc_dom_image *dom =3D (struct xc_dom_image *)arg; + uint32_t ret =3D 0xdeadbeef; + int rc; + rc =3D xc_get_vcpu_topology_id(dom->xch, dom->guest_domid, cpu, &ret); + return ret; } =20 static int init_acpi_config(libxl__gc *gc,=20 @@ -149,6 +153,7 @@ static int init_acpi_config(libxl__gc *gc, =20 config->lapic_base_address =3D LAPIC_BASE_ADDRESS; config->lapic_id =3D acpi_lapic_id; + config->lapic_id_arg =3D dom; config->acpi_revision =3D 5; =20 rc =3D 0; diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c index 2079a30ae4..cbed233726 100644 --- a/xen/arch/x86/cpuid.c +++ b/xen/arch/x86/cpuid.c @@ -867,8 +867,10 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, case 0x1: /* TODO: Rework topology logic. */ res->b &=3D 0x00ffffffu; - if ( is_hvm_domain(d) ) - res->b |=3D (v->vcpu_id * 2) << 24; + +#ifdef CONFIG_HVM + res->b |=3D vlapic_get_default_id(v) << 24; +#endif =20 /* TODO: Rework vPMU control in terms of toolstack choices. */ if ( vpmu_available(v) && @@ -1049,7 +1051,13 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, *(uint8_t *)&res->c =3D subleaf; =20 /* Fix the x2APIC identifier. */ - res->d =3D v->vcpu_id * 2; +#ifdef CONFIG_HVM + res->d =3D vlapic_get_default_id(v); +#endif + } + else + { + *res =3D EMPTY_LEAF; } break; =20 diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 7b48a1b925..e93ca8187d 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -1555,7 +1555,7 @@ int hvm_vcpu_initialise(struct vcpu *v) goto fail1; =20 /* NB: vlapic_init must be called before hvm_funcs.vcpu_initialise */ - rc =3D vlapic_init(v); + rc =3D vlapic_init(v, v->vcpu_id * 2); if ( rc !=3D 0 ) /* teardown: vlapic_destroy */ goto fail2; =20 @@ -5084,6 +5084,40 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PA= RAM(void) arg) rc =3D current->hcall_compat ? compat_altp2m_op(arg) : do_altp2m_o= p(arg); break; =20 + case HVMOP_get_vcpu_topology_id: + { + struct domain *d; + struct xen_vcpu_topology_id tid; + + if ( copy_from_guest(&tid, arg, 1) ) + return -EFAULT; + + if (tid.domid !=3D DOMID_SELF && !is_hardware_domain(current->doma= in)) + return -EPERM; + + if ( (d =3D rcu_lock_domain_by_any_id(tid.domid)) =3D=3D NULL ) + return -ESRCH; + + if ( !is_hvm_domain(d)) + { + rc =3D -EOPNOTSUPP; + goto get_cpu_topology_failed; + } + + if ( tid.vcpu_id >=3D d->max_vcpus ) + { + rc =3D -EINVAL; + goto get_cpu_topology_failed; + } + tid.topology_id =3D vlapic_get_default_id(d->vcpu[tid.vcpu_id]); + + rc =3D copy_to_guest(arg, &tid, 1) ? -EFAULT : 0; + + get_cpu_topology_failed: + rcu_unlock_domain(d); + break; + } + default: { gdprintk(XENLOG_DEBUG, "Bad HVM op %ld.\n", op); diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index 5e21fb4937..e65b1e8e94 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -1068,12 +1068,18 @@ static const struct hvm_mmio_ops vlapic_mmio_ops = =3D { .write =3D vlapic_mmio_write, }; =20 +uint32_t vlapic_get_default_id(const struct vcpu *v) +{ + const struct vlapic *vlapic =3D vcpu_vlapic(v); + return vlapic->hw.default_id; +} + static void set_x2apic_id(struct vlapic *vlapic) { - u32 id =3D vlapic_vcpu(vlapic)->vcpu_id; + u32 id =3D vlapic->hw.default_id; u32 ldr =3D ((id & ~0xf) << 12) | (1 << (id & 0xf)); =20 - vlapic_set_reg(vlapic, APIC_ID, id * 2); + vlapic_set_reg(vlapic, APIC_ID, id); vlapic_set_reg(vlapic, APIC_LDR, ldr); } =20 @@ -1440,7 +1446,7 @@ void vlapic_reset(struct vlapic *vlapic) if ( v->vcpu_id =3D=3D 0 ) vlapic->hw.apic_base_msr |=3D APIC_BASE_BSP; =20 - vlapic_set_reg(vlapic, APIC_ID, (v->vcpu_id * 2) << 24); + vlapic_set_reg(vlapic, APIC_ID, vlapic->hw.default_id << 24); vlapic_do_init(vlapic); } =20 @@ -1508,7 +1514,7 @@ static void lapic_load_fixup(struct vlapic *vlapic) * here, but can be dropped as soon as it is found to conflict with * other (future) changes. */ - if ( GET_xAPIC_ID(id) !=3D vlapic_vcpu(vlapic)->vcpu_id * 2 || + if ( GET_xAPIC_ID(id) !=3D vlapic->hw.default_id || id !=3D SET_xAPIC_ID(GET_xAPIC_ID(id)) ) printk(XENLOG_G_WARNING "%pv: bogus APIC ID %#x loaded\n", vlapic_vcpu(vlapic), id); @@ -1596,12 +1602,14 @@ HVM_REGISTER_SAVE_RESTORE(LAPIC, lapic_save_hidden, HVM_REGISTER_SAVE_RESTORE(LAPIC_REGS, lapic_save_regs, lapic_load_regs, 1, HVMSR_PER_VCPU); =20 -int vlapic_init(struct vcpu *v) +int vlapic_init(struct vcpu *v, uint32_t apic_id) { struct vlapic *vlapic =3D vcpu_vlapic(v); =20 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id); =20 + vlapic->hw.default_id =3D apic_id; + if ( !has_vlapic(v->domain) ) { vlapic->hw.disabled =3D VLAPIC_HW_DISABLED; diff --git a/xen/include/asm-x86/hvm/vlapic.h b/xen/include/asm-x86/hvm/vla= pic.h index 8f908928c3..06c9c5cd7d 100644 --- a/xen/include/asm-x86/hvm/vlapic.h +++ b/xen/include/asm-x86/hvm/vlapic.h @@ -116,7 +116,7 @@ void vlapic_set_irq(struct vlapic *vlapic, uint8_t vec,= uint8_t trig); int vlapic_has_pending_irq(struct vcpu *v); int vlapic_ack_pending_irq(struct vcpu *v, int vector, bool_t force_ack); =20 -int vlapic_init(struct vcpu *v); +int vlapic_init(struct vcpu *v, uint32_t apic_id); void vlapic_destroy(struct vcpu *v); =20 void vlapic_reset(struct vlapic *vlapic); @@ -154,4 +154,6 @@ static inline void vlapic_sync_pir_to_irr(struct vcpu *= v) alternative_vcall(hvm_funcs.sync_pir_to_irr, v); } =20 +uint32_t vlapic_get_default_id(const struct vcpu *v); + #endif /* __ASM_X86_HVM_VLAPIC_H__ */ diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/ar= ch-x86/hvm/save.h index 773a380bc2..f960257dbf 100644 --- a/xen/include/public/arch-x86/hvm/save.h +++ b/xen/include/public/arch-x86/hvm/save.h @@ -411,6 +411,7 @@ struct hvm_hw_lapic { uint32_t disabled; /* VLAPIC_xx_DISABLED */ uint32_t timer_divisor; uint64_t tdt_msr; + uint32_t default_id; }; =20 DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic); diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_o= p.h index 870ec52060..bf7872a4d1 100644 --- a/xen/include/public/hvm/hvm_op.h +++ b/xen/include/public/hvm/hvm_op.h @@ -183,6 +183,23 @@ struct xen_hvm_get_mem_type { typedef struct xen_hvm_get_mem_type xen_hvm_get_mem_type_t; DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_type_t); =20 +/* + * HVMOP_get_cpu_topology is used by guest to acquire vcpu topology from + * hypervisor. + */ +#define HVMOP_get_vcpu_topology_id 16 + +struct xen_vcpu_topology_id { + /* IN */ + domid_t domid; + uint32_t vcpu_id; + + /* OUT */ + uint32_t topology_id; +}; +typedef struct xen_vcpu_topology_id xen_vcpu_topology_id_t; +DEFINE_XEN_GUEST_HANDLE(xen_vcpu_topology_id_t); + /* Following tools-only interfaces may change in future. */ #if defined(__XEN__) || defined(__XEN_TOOLS__) =20 --=20 2.25.1