From patchwork Sun May 20 07:28:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zihan Yang X-Patchwork-Id: 917074 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="m62BBdBo"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40pYTQ0XjDz9s3x for ; Sun, 20 May 2018 17:30:02 +1000 (AEST) Received: from localhost ([::1]:45522 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fKIn1-00010Y-Ii for incoming@patchwork.ozlabs.org; Sun, 20 May 2018 03:29:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52328) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fKImN-0000nQ-VI for qemu-devel@nongnu.org; Sun, 20 May 2018 03:29:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fKImM-0006vh-Gk for qemu-devel@nongnu.org; Sun, 20 May 2018 03:29:19 -0400 Received: from mail-pf0-x22a.google.com ([2607:f8b0:400e:c00::22a]:39142) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fKImM-0006vR-8z for qemu-devel@nongnu.org; Sun, 20 May 2018 03:29:18 -0400 Received: by mail-pf0-x22a.google.com with SMTP id a22-v6so5605041pfn.6 for ; Sun, 20 May 2018 00:29:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=N36BuP71NBMRr6iBuz5bSASyjIFYKdsi+77E9kfMQWE=; b=m62BBdBonyD1JFamqm17oTH2foEd4A7JoeXBhgQLEKqXlMk3MMoNS4ICweORy0TMqX 5NOoi6aoWZ14kIfnNfFluHWSnH3EqNVnOuUMsh8Y92wYq1HXV95Z1+7Q4XdfP4eQhOB1 MKXbEVK5fs6OMSBI4CGgkGJCbsisJCDvcCsJwtbCAsrXB0r7/QHSFmOO9+4m6uZFzdTt GUJUhPel6HKJV6xzVgYzFRLP0OPphQvFMWmnOY6eiw/BeKdFu2uHOiDUgrxyetY0AY/j deOdeD0WcfN2zcE1gm+3xiZ1JMR6DWkYnb/u2Q4GEMtGOYG80pbXZkFGgx1EOzHeBrmF thag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=N36BuP71NBMRr6iBuz5bSASyjIFYKdsi+77E9kfMQWE=; b=ix7iNjbPLP0hT6HwEFCyZ9tZ6L5Gg9csiK7iuXaYypbabMJbap18cLX0HAqK1MUhRC M2insYVPTf3lQ/Cdjm1PXGk9gKQI0bUR4GDIXc8Q5bLyafEqeUBhlin4c0c9ULQhcQWE IMIIbSpUKlU/732no4qozxBivPC4fOe0b2AV3DYGk3P8JduLmMgz5WLLhmEFvMT98Mhg UNenBaj5fA6GAA2LPzAPKoeNkKbt0aRYFd5Ga37bTWHNlUdrbdYGj6ayjDc5qiUBPGKx Qq3olvGXPmcBXVDy1vI1tLtgcYub6NnTZOaECMJznqILRf3k+g8loqtgraFojfu+HWf1 rwdQ== X-Gm-Message-State: ALKqPwffi6Fck3j9PorerO2htCT5sFgwf2Mn+E+t5r8/7K1FYQIk8OIY Fg9iTn33K/va16u6pafOda655+Da X-Google-Smtp-Source: AB8JxZp/llrysxAHIShoHFJTetPHA6ApadnsLPa1ctyM3ceXMQATMbG2W2EEPeDNotN1trZeuV790Q== X-Received: by 2002:a63:18a:: with SMTP id 132-v6mr12516098pgb.344.1526801356898; Sun, 20 May 2018 00:29:16 -0700 (PDT) Received: from biggerfish-TM1701.lan ([203.69.105.4]) by smtp.gmail.com with ESMTPSA id j3-v6sm17338975pgs.76.2018.05.20.00.29.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 20 May 2018 00:29:15 -0700 (PDT) From: Zihan Yang To: qemu-devel@nongnu.org Date: Sun, 20 May 2018 15:28:51 +0800 Message-Id: <1526801333-30613-2-git-send-email-whois.zihan.yang@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1526801333-30613-1-git-send-email-whois.zihan.yang@gmail.com> References: <1526801333-30613-1-git-send-email-whois.zihan.yang@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::22a Subject: [Qemu-devel] [RFC 1/3] pci_expander_bridge: reserve enough mcfg space for pxb host X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , Zihan Yang , "Michael S. Tsirkin" , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" To put each pxb into separate pci domain, we need to reserve enough MCFG space for each pxb host in the main memory. First try to put them under 4G, before pci_hole_start, if there are too many hosts, try to put them into main memory above 4G, before pci_hole64_start. We should check if there is enough memory to reserve for them Signed-off-by: Zihan Yang --- hw/i386/pc.c | 5 ++ hw/pci-bridge/pci_expander_bridge.c | 96 ++++++++++++++++++++++++++++- include/hw/pci-bridge/pci_expander_bridge.h | 7 +++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 include/hw/pci-bridge/pci_expander_bridge.h diff --git a/hw/i386/pc.c b/hw/i386/pc.c index d768930..98097fd 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -34,6 +34,7 @@ #include "hw/ide.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" +#include "hw/pci-bridge/pci_expander_bridge.h" #include "hw/nvram/fw_cfg.h" #include "hw/timer/hpet.h" #include "hw/smbios/smbios.h" @@ -1466,6 +1467,7 @@ uint64_t pc_pci_hole64_start(void) PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); MachineState *ms = MACHINE(pcms); uint64_t hole64_start = 0; + int pxb_hosts; if (pcmc->has_reserved_memory && ms->device_memory->base) { hole64_start = ms->device_memory->base; @@ -1473,6 +1475,9 @@ uint64_t pc_pci_hole64_start(void) hole64_start += memory_region_size(&ms->device_memory->mr); } } else { + /* make sure enough space is left for pxb host, otherwise fail */ + pxb_hosts = pxb_get_expander_hosts(); + g_assert (pxb_hosts <= 0 || pcms->above_4g_mem_size >= (pxb_hosts << 28ULL)); hole64_start = 0x100000000ULL + pcms->above_4g_mem_size; } diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index e62de42..8409c87 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -12,10 +12,13 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "qapi/visitor.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" #include "hw/pci/pci_host.h" #include "hw/pci/pci_bridge.h" +#include "hw/pci-host/q35.h" +#include "hw/pci-bridge/pci_expander_bridge.h" #include "qemu/range.h" #include "qemu/error-report.h" #include "sysemu/numa.h" @@ -57,7 +60,13 @@ static PXBDev *convert_to_pxb(PCIDevice *dev) static GList *pxb_dev_list; +typedef struct PXBPCIHost { + PCIExpressHost parent_obj; +} PXBPCIHost; + #define TYPE_PXB_HOST "pxb-host" +#define PXB_HOST_DEVICE(obj) \ + OBJECT_CHECK(PXBPCIHost, (obj), TYPE_PXB_HOST) static int pxb_bus_num(PCIBus *bus) { @@ -111,6 +120,14 @@ static const char *pxb_host_root_bus_path(PCIHostState *host_bridge, return bus->bus_path; } +static void pxb_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + PCIExpressHost *e = PCIE_HOST_BRIDGE(obj); + + visit_type_uint64(v, name, &e->size, errp); +} + static char *pxb_host_ofw_unit_address(const SysBusDevice *dev) { const PCIHostState *pxb_host; @@ -142,6 +159,80 @@ static char *pxb_host_ofw_unit_address(const SysBusDevice *dev) return NULL; } +static Object *pxb_get_i386_pci_host(void) +{ + PCIHostState *host; + + host = OBJECT_CHECK(PCIHostState, + object_resolve_path("/machine/i440fx", NULL), + TYPE_PCI_HOST_BRIDGE); + if (!host) { + host = OBJECT_CHECK(PCIHostState, + object_resolve_path("/machine/q35", NULL), + TYPE_PCI_HOST_BRIDGE); + } + + return OBJECT(host); +} + +int pxhb_cnt = 0; + +/* -1 means to exclude q35 host */ +#define MCFG_IN_PCI_HOLE (((IO_APIC_DEFAULT_ADDRESS - MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT) >> 28) - 1) + +int pxb_get_expander_hosts(void) +{ + return pxhb_cnt - MCFG_IN_PCI_HOLE; +} + +/* Dirty workaround */ +static void modify_q35_pci_hole(void) +{ + Object *pci_host; + Q35PCIHost *s; + + pci_host = pxb_get_i386_pci_host(); + g_assert(pci_host); + s = Q35_HOST_DEVICE(pci_host); + + ++pxhb_cnt; + if (pxhb_cnt <= MCFG_IN_PCI_HOLE) { + range_set_bounds(&s->mch.pci_hole, + MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT + ((1 + pxhb_cnt) << 28), + IO_APIC_DEFAULT_ADDRESS - 1); + } + + // leave pci hole64 to acpi build part +} + +static void pxb_host_initfn(Object *obj) +{ + PCIHostState *phb = PCI_HOST_BRIDGE(obj); + + memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb, + "pci-conf-idx", 4); + memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb, + "pci-conf-data", 4); + + object_property_add(obj, PCIE_HOST_MCFG_SIZE, "uint64", + pxb_host_get_mmcfg_size, + NULL, NULL, NULL, NULL); + + /* Leave enough space for the biggest MCFG BAR */ + /* TODO. Since pxb host is just an expander bridge without an mch, + * we modify the range in q35 host. It should be workable as it is + * before acpi build, although it is dirty + */ + modify_q35_pci_hole(); +} + +/* default value does not matter as guest firmware will overwrite it */ +static Property pxb_host_props[] = { + DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, PXBPCIHost, parent_obj.base_addr, + MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT), + DEFINE_PROP_END_OF_LIST(), +}; + static void pxb_host_class_init(ObjectClass *class, void *data) { DeviceClass *dc = DEVICE_CLASS(class); @@ -149,6 +240,7 @@ static void pxb_host_class_init(ObjectClass *class, void *data) PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class); dc->fw_name = "pci"; + dc->props = pxb_host_props; /* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself */ dc->user_creatable = false; sbc->explicit_ofw_unit_address = pxb_host_ofw_unit_address; @@ -157,7 +249,9 @@ static void pxb_host_class_init(ObjectClass *class, void *data) static const TypeInfo pxb_host_info = { .name = TYPE_PXB_HOST, - .parent = TYPE_PCI_HOST_BRIDGE, + .parent = TYPE_PCIE_HOST_BRIDGE, + .instance_size = sizeof(PXBPCIHost), + .instance_init = pxb_host_initfn, .class_init = pxb_host_class_init, }; diff --git a/include/hw/pci-bridge/pci_expander_bridge.h b/include/hw/pci-bridge/pci_expander_bridge.h new file mode 100644 index 0000000..d48ddb1 --- /dev/null +++ b/include/hw/pci-bridge/pci_expander_bridge.h @@ -0,0 +1,7 @@ +#ifndef HW_PCI_EXPANDER_H +#define HW_PCI_EXPANDER_H + +/* return the number of pxb hosts that resides in the main memory above 4G */ +int pxb_get_expander_hosts(void); + +#endif From patchwork Sun May 20 07:28:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zihan Yang X-Patchwork-Id: 917075 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="cCLTFaX5"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40pYTW2y19z9s3x for ; Sun, 20 May 2018 17:30:07 +1000 (AEST) Received: from localhost ([::1]:45523 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fKIn7-0001Cb-4C for incoming@patchwork.ozlabs.org; Sun, 20 May 2018 03:30:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52345) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fKImU-00014m-Gc for qemu-devel@nongnu.org; Sun, 20 May 2018 03:29:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fKImR-0006xO-DR for qemu-devel@nongnu.org; Sun, 20 May 2018 03:29:26 -0400 Received: from mail-pl0-x242.google.com ([2607:f8b0:400e:c01::242]:36599) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fKImR-0006xD-6Z for qemu-devel@nongnu.org; Sun, 20 May 2018 03:29:23 -0400 Received: by mail-pl0-x242.google.com with SMTP id v24-v6so6961097plo.3 for ; Sun, 20 May 2018 00:29:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=33eFeNMAjdIJscKRlmAq6QzWSZxXOkqULDb+Hwkqm/4=; b=cCLTFaX53Bq1NEZo3NN9BRIsEfVoQ6ZtGRPBcHmF0pOotMyjKi6obWaphnt/rTFYGN hDrF97cSFaN4HumPHZYiFappwSVlZb+mt/7L5jKBdtpxnUoy1Ift4WyuD+zwIPDrQZ4w GxkGyjfLQxLHwXKmFdZXM7BZCgy52FhjqYfo5xfwNbifK/pI6qjIlD6AM26k1HK67fEw Wi9gSm0B1Prkd1Xv/HK+GZMIp+TyaS1UQgcpEvMd48dUS2/bXd+KvM3H7BzzJxH35QOv Rmlf6HmmQq50uqAe5slB/qW0dASNJnzLEKBjErXBTyskyT5gW01gEp05RWTL/h1DTO2P 9MwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=33eFeNMAjdIJscKRlmAq6QzWSZxXOkqULDb+Hwkqm/4=; b=ddO4Lqn2rdb2SW1LhOGWDTeBZhubWUIbuvinBGiXiFf4hCoiR94Y1ZX+Wy+08NrQKV fH4ty9qLlIL2JkCztjNyWTKSoKQt6AzzEGrVfdgNRZs+ZvVO33XpsHokp6JAJp1tz1zX jobZyVtdb53wsq0C9zdZGupyt/BebGjIx9rrohpS5i3Cp+DuenyiTalWyiigR8+Inrev lnmuxmfviLMvFw4iDLU53okqF9VNAZyz1PX781ioiw3IRG3n3PKFAcN5D6fCzO2BWflk tD5XSQF95oszplV+Xk12LlgI6bUw8/0QpoDGYB1soT4zRE0bllI3WCuwx8DhJ9kcIxz8 zg3Q== X-Gm-Message-State: ALKqPwdHKFFdRF7SJXa5oMo/Ec1j7sWDZefp5mD48hphDpeHb71EQuxJ mreoRFB/kKDmBcn54MY8w4BHOw== X-Google-Smtp-Source: AB8JxZpHz3ZPwxK4AUToiFq6LX5Qz2ju4lRh5MowxVpTis3+FvMe8H5BvjedriL/Er4AHZQsB/v/RA== X-Received: by 2002:a17:902:7406:: with SMTP id g6-v6mr15473882pll.237.1526801362062; Sun, 20 May 2018 00:29:22 -0700 (PDT) Received: from biggerfish-TM1701.lan ([203.69.105.4]) by smtp.gmail.com with ESMTPSA id j3-v6sm17338975pgs.76.2018.05.20.00.29.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 20 May 2018 00:29:20 -0700 (PDT) From: Zihan Yang To: qemu-devel@nongnu.org Date: Sun, 20 May 2018 15:28:52 +0800 Message-Id: <1526801333-30613-3-git-send-email-whois.zihan.yang@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1526801333-30613-1-git-send-email-whois.zihan.yang@gmail.com> References: <1526801333-30613-1-git-send-email-whois.zihan.yang@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c01::242 Subject: [Qemu-devel] [RFC 2/3] pci: Link pci_host_bridges with QTAILQ X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Zihan Yang , "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" QLIST will place the original q35 host bridge at the end of list because it is added first. Replace it with QTAILQ to make q35 at the first of queue, which makes it convinient and compatible when there are pxb hosts other than q35 hosts Signed-off-by: Zihan Yang --- hw/pci/pci.c | 9 +++++---- include/hw/pci/pci_host.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 80bc459..ddc27ba 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -196,7 +196,8 @@ static void pci_del_option_rom(PCIDevice *pdev); static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET; static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU; -static QLIST_HEAD(, PCIHostState) pci_host_bridges; +static QTAILQ_HEAD(, PCIHostState) pci_host_bridges = + QTAILQ_HEAD_INITIALIZER(pci_host_bridges); int pci_bar(PCIDevice *d, int reg) { @@ -330,7 +331,7 @@ static void pci_host_bus_register(DeviceState *host) { PCIHostState *host_bridge = PCI_HOST_BRIDGE(host); - QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next); + QTAILQ_INSERT_TAIL(&pci_host_bridges, host_bridge, next); } PCIBus *pci_device_root_bus(const PCIDevice *d) @@ -1798,7 +1799,7 @@ PciInfoList *qmp_query_pci(Error **errp) PciInfoList *info, *head = NULL, *cur_item = NULL; PCIHostState *host_bridge; - QLIST_FOREACH(host_bridge, &pci_host_bridges, next) { + QTAILQ_FOREACH(host_bridge, &pci_host_bridges, next) { info = g_malloc0(sizeof(*info)); info->value = qmp_query_pci_bus(host_bridge->bus, pci_bus_num(host_bridge->bus)); @@ -2493,7 +2494,7 @@ int pci_qdev_find_device(const char *id, PCIDevice **pdev) PCIHostState *host_bridge; int rc = -ENODEV; - QLIST_FOREACH(host_bridge, &pci_host_bridges, next) { + QTAILQ_FOREACH(host_bridge, &pci_host_bridges, next) { int tmp = pci_qdev_find_recursive(host_bridge->bus, id, pdev); if (!tmp) { rc = 0; diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h index ba31595..a5617cf 100644 --- a/include/hw/pci/pci_host.h +++ b/include/hw/pci/pci_host.h @@ -47,7 +47,7 @@ struct PCIHostState { uint32_t config_reg; PCIBus *bus; - QLIST_ENTRY(PCIHostState) next; + QTAILQ_ENTRY(PCIHostState) next; }; typedef struct PCIHostBridgeClass { From patchwork Sun May 20 07:28:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zihan Yang X-Patchwork-Id: 917076 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Xbgrd0fU"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40pYXy6XsHz9s4b for ; Sun, 20 May 2018 17:33:06 +1000 (AEST) Received: from localhost ([::1]:45535 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fKIq0-0003sU-HY for incoming@patchwork.ozlabs.org; Sun, 20 May 2018 03:33:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52363) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fKImZ-0001K0-65 for qemu-devel@nongnu.org; Sun, 20 May 2018 03:29:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fKImY-0006yf-3c for qemu-devel@nongnu.org; Sun, 20 May 2018 03:29:31 -0400 Received: from mail-pl0-x244.google.com ([2607:f8b0:400e:c01::244]:46372) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fKImX-0006yO-Rl for qemu-devel@nongnu.org; Sun, 20 May 2018 03:29:30 -0400 Received: by mail-pl0-x244.google.com with SMTP id 30-v6so6937671pld.13 for ; Sun, 20 May 2018 00:29:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=sCIyPtABjdYZVS2dyc8BF8r272aSyTOAxlqSBWzMvHA=; b=Xbgrd0fUum2SkFQgyNCJSn4zrD1z9A36/sEEHKG+eha5BffUbTE8pmmRMBPpgZf6qD SL+CVNNUCUkYrCsFhyJNmZhDRPig8xOI6DKdDcwZRSACFen+QLozQSOMyTy4EpDKf+ls YxMP+ttO2+C7UhV18M63j60ypVMIy9ivxSLPfpqFVyxAAZu+tr+aVM/mgg7coPKOTSnd P9Z+GYwdb5+ohjVJsr6Or+o+zMpriZEZKsYrBMbUNUHPtEPGjZEa47GQBwUqN6S9Rolf 80Q8DOj37/JBwQUj2Zt7Q/MMrlvoPTNQb8qiJ7cpIddwteoqp88LfXj463fite2HgFL3 ba3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=sCIyPtABjdYZVS2dyc8BF8r272aSyTOAxlqSBWzMvHA=; b=ExLk+SDIzCROfxChsA0MZFV+D9jzyWtyIWMv7JnsC8LreUc2ChG406JzV7VTJ1WgKf ND+mv6bakmXspCNm2AgUKwllOBtDaLEhWZuCMjh5JYD7oDoYOJu0q6dfI+6Bvcnt8oQE 4Ag0BY7SZuwvZI8eam+JAxCGwyYcpS+UGWwVprRL0SL5VOJrYghnFQGbOaq4T5izZ9I8 moyjApdA4tQfLK1e0tO4cMCtmkmJHyx8YKLnkFntPb89nDhEV13+/QcXMY/3krQ6LIF9 /T+9i0tcRKpX1z7TskmTMKPix3wT0SvVDSizhP+o8g7nX2dolSyGWjj66P/TvR5MlZg9 uPqw== X-Gm-Message-State: ALKqPwch3kurHH6E9Bm8bV0bbfixDZiA46pLRMcXOiiu2VRGTRtQk51g OLAZ5T6lMw2Xkf0OMRtxRe3zpBpp X-Google-Smtp-Source: AB8JxZoxIg/RSmI35BJaAuGNcQk4SEC1be5Hm9vln9vJgpchpAHY3Eyj2yxmhCRCBlmM1YIXffS92g== X-Received: by 2002:a17:902:125:: with SMTP id 34-v6mr16384501plb.42.1526801368702; Sun, 20 May 2018 00:29:28 -0700 (PDT) Received: from biggerfish-TM1701.lan ([203.69.105.4]) by smtp.gmail.com with ESMTPSA id j3-v6sm17338975pgs.76.2018.05.20.00.29.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 20 May 2018 00:29:27 -0700 (PDT) From: Zihan Yang To: qemu-devel@nongnu.org Date: Sun, 20 May 2018 15:28:53 +0800 Message-Id: <1526801333-30613-4-git-send-email-whois.zihan.yang@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1526801333-30613-1-git-send-email-whois.zihan.yang@gmail.com> References: <1526801333-30613-1-git-send-email-whois.zihan.yang@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c01::244 Subject: [Qemu-devel] [RFC 3/3] acpi-build: allocate mcfg for multiple host bridges X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , Zihan Yang , "Michael S. Tsirkin" , Paolo Bonzini , Igor Mammedov , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Currently only q35 host bridge us allocated space in MCFG table. To put pxb host into sepratate pci domain, each of them should have its own configuration space int MCFG table Signed-off-by: Zihan Yang --- hw/i386/acpi-build.c | 83 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 21 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 9bc6d97..808d815 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -89,6 +89,7 @@ typedef struct AcpiMcfgInfo { uint64_t mcfg_base; uint32_t mcfg_size; + struct AcpiMcfgInfo *next; } AcpiMcfgInfo; typedef struct AcpiPmInfo { @@ -2427,14 +2428,15 @@ build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info) { AcpiTableMcfg *mcfg; const char *sig; - int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]); + int len, count = 0; + AcpiMcfgInfo *cfg = info; + while (cfg) { + ++count; + cfg = cfg->next; + } + len = sizeof(*mcfg) + count * sizeof(mcfg->allocation[0]); mcfg = acpi_data_push(table_data, len); - mcfg->allocation[0].address = cpu_to_le64(info->mcfg_base); - /* Only a single allocation so no need to play with segments */ - mcfg->allocation[0].pci_segment = cpu_to_le16(0); - mcfg->allocation[0].start_bus_number = 0; - mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->mcfg_size - 1); /* MCFG is used for ECAM which can be enabled or disabled by guest. * To avoid table size changes (which create migration issues), @@ -2448,6 +2450,17 @@ build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info) } else { sig = "MCFG"; } + + count = 0; + while (info) { + mcfg[count].allocation[0].address = cpu_to_le64(info->mcfg_base); + /* Only a single allocation so no need to play with segments */ + mcfg[count].allocation[0].pci_segment = cpu_to_le16(count); + mcfg[count].allocation[0].start_bus_number = 0; + mcfg[count++].allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->mcfg_size - 1); + info = info->next; + } + build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL, NULL); } @@ -2602,26 +2615,52 @@ struct AcpiBuildState { MemoryRegion *linker_mr; } AcpiBuildState; -static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) +static inline void cleanup_mcfg(AcpiMcfgInfo *mcfg) +{ + AcpiMcfgInfo *tmp; + while (mcfg) { + tmp = mcfg->next; + g_free(mcfg); + mcfg = tmp; + } +} + +static AcpiMcfgInfo *acpi_get_mcfg(void) { Object *pci_host; QObject *o; + AcpiMcfgInfo *head = NULL, *tail, *mcfg; pci_host = acpi_get_i386_pci_host(); g_assert(pci_host); - o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_BASE, NULL); - if (!o) { - return false; + while (pci_host) { + mcfg = g_new0(AcpiMcfgInfo, 1); + mcfg->next = NULL; + if (!head) { + tail = head = mcfg; + } else { + tail->next = mcfg; + tail = mcfg; + } + + o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_BASE, NULL); + if (!o) { + cleanup_mcfg(head); + g_free(mcfg); + return NULL; + } + mcfg->mcfg_base = qnum_get_uint(qobject_to(QNum, o)); + qobject_unref(o); + + o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL); + assert(o); + mcfg->mcfg_size = qnum_get_uint(qobject_to(QNum, o)); + qobject_unref(o); + + pci_host = OBJECT(QTAILQ_NEXT(PCI_HOST_BRIDGE(pci_host), next)); } - mcfg->mcfg_base = qnum_get_uint(qobject_to(QNum, o)); - qobject_unref(o); - - o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL); - assert(o); - mcfg->mcfg_size = qnum_get_uint(qobject_to(QNum, o)); - qobject_unref(o); - return true; + return head; } static @@ -2633,7 +2672,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) unsigned facs, dsdt, rsdt, fadt; AcpiPmInfo pm; AcpiMiscInfo misc; - AcpiMcfgInfo mcfg; + AcpiMcfgInfo *mcfg; Range pci_hole, pci_hole64; uint8_t *u; size_t aml_len = 0; @@ -2714,10 +2753,12 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) build_slit(tables_blob, tables->linker); } } - if (acpi_get_mcfg(&mcfg)) { + if ((mcfg = acpi_get_mcfg()) != NULL) { acpi_add_table(table_offsets, tables_blob); - build_mcfg_q35(tables_blob, tables->linker, &mcfg); + build_mcfg_q35(tables_blob, tables->linker, mcfg); } + cleanup_mcfg(mcfg); + if (x86_iommu_get_default()) { IommuType IOMMUType = x86_iommu_get_type(); if (IOMMUType == TYPE_AMD) {