From patchwork Tue Sep 27 15:57:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 9352169 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 296ED60757 for ; Tue, 27 Sep 2016 16:00:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1990C2913C for ; Tue, 27 Sep 2016 16:00:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0E2AF2928A; Tue, 27 Sep 2016 16:00:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 664952913C for ; Tue, 27 Sep 2016 16:00:27 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1boum9-00080B-82; Tue, 27 Sep 2016 15:58:33 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1boum8-0007vr-6n for xen-devel@lists.xenproject.org; Tue, 27 Sep 2016 15:58:32 +0000 Received: from [85.158.137.68] by server-9.bemta-3.messagelabs.com id 99/4A-27233-7279AE75; Tue, 27 Sep 2016 15:58:31 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrKIsWRWlGSWpSXmKPExsXitHSDva769Ff hBqIW37dMZnJg9Dj84QpLAGMUa2ZeUn5FAmvGxpcvGAsWWVS8PhnUwHhFs4uRk0NCwF/iWv8q RhCbTUBH4uLcnWxdjBwcIgIqErf3GnQxcnEwC9xglPi09i5YjbBAmMShYy/AbBYBVYntn8+zg Ni8Aq4Sh7ZOY4GYqSvx8NxvVhCbEyje27aACcQWEnCRuDvzIytEvaDEyZlPwOqZBTQlWrf/Zo ew5SWat85mhqhXlOif94ANYia3xO3TU5knMPLPQtI+C0n7LCTtCxiZVzGqF6cWlaUW6RrqJRV lpmeU5CZm5ugaGhjr5aYWFyemp+YkJhXrJefnbmIEBh8DEOxgXP7R6RCjJAeTkiivRvurcCG+ pPyUyozE4oz4otKc1OJDjDIcHEoSvB5TgXKCRanpqRVpmTnAOIBJS3DwKInw8kwDSvMWFyTmF memQ6ROMSpKifM2gPQJgCQySvPg2mCxd4lRVkqYlxHoECGegtSi3MwSVPlXjOIcjErCvAog43 ky80rgpr8CWswEtHjpiRcgi0sSEVJSDYzrq+e/WvKZbUrkvaqph5kT5/DrTPJU0SlZ4aKWt1A xNv97fU+OlsrL2wnmc+WUn6+cy/0865ep5lc2jo02pkua+VjWdp37e2K3QXQkX+08If0TbzQr Os8ru2ZGWEzdklVyq/k1k5DyVQPDSd+P2VkK5rTNiWnmljda1P4hpFC/7FNQ5ZMlCUosxRmJh lrMRcWJAILitpi4AgAA X-Env-Sender: prvs=071b8e69e=roger.pau@citrix.com X-Msg-Ref: server-12.tower-31.messagelabs.com!1474991908!46201907!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 8.84; banners=-,-,- X-VirusChecked: Checked Received: (qmail 17680 invoked from network); 27 Sep 2016 15:58:30 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-12.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 27 Sep 2016 15:58:30 -0000 X-IronPort-AV: E=Sophos;i="5.30,405,1470700800"; d="scan'208";a="389169703" From: Roger Pau Monne To: Date: Tue, 27 Sep 2016 17:57:14 +0200 Message-ID: <1474991845-27962-20-git-send-email-roger.pau@citrix.com> X-Mailer: git-send-email 2.7.4 (Apple Git-66) In-Reply-To: <1474991845-27962-1-git-send-email-roger.pau@citrix.com> References: <1474991845-27962-1-git-send-email-roger.pau@citrix.com> MIME-Version: 1.0 X-DLP: MIA2 Cc: Andrew Cooper , Paul Durrant , Jan Beulich , boris.ostrovsky@oracle.com, Roger Pau Monne Subject: [Xen-devel] [PATCH v2 19/30] xen/dcpi: add a dpci passthrough handler for hardware domain X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP This is very similar to the PCI trap used for the traditional PV(H) Dom0. Signed-off-by: Roger Pau Monné --- Cc: Paul Durrant Cc: Jan Beulich Cc: Andrew Cooper --- xen/arch/x86/hvm/io.c | 72 ++++++++++++++++++++++++++++++++++++++++++- xen/arch/x86/traps.c | 39 ----------------------- xen/drivers/passthrough/pci.c | 39 +++++++++++++++++++++++ xen/include/xen/pci.h | 2 ++ 4 files changed, 112 insertions(+), 40 deletions(-) diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c index 1e7a5f9..31d54dc 100644 --- a/xen/arch/x86/hvm/io.c +++ b/xen/arch/x86/hvm/io.c @@ -247,12 +247,79 @@ static int dpci_portio_write(const struct hvm_io_handler *handler, return X86EMUL_OKAY; } +static bool_t hw_dpci_portio_accept(const struct hvm_io_handler *handler, + const ioreq_t *p) +{ + if ( (p->addr == 0xcf8 && p->size == 4) || (p->addr & 0xfffc) == 0xcfc) + { + return 1; + } + + return 0; +} + +static int hw_dpci_portio_read(const struct hvm_io_handler *handler, + uint64_t addr, + uint32_t size, + uint64_t *data) +{ + struct domain *currd = current->domain; + + if ( addr == 0xcf8 ) + { + ASSERT(size == 4); + *data = currd->arch.pci_cf8; + return X86EMUL_OKAY; + } + + ASSERT((addr & 0xfffc) == 0xcfc); + size = min(size, 4 - ((uint32_t)addr & 3)); + if ( size == 3 ) + size = 2; + if ( pci_cfg_ok(currd, addr & 3, size, NULL) ) + *data = pci_conf_read(currd->arch.pci_cf8, addr & 3, size); + + return X86EMUL_OKAY; +} + +static int hw_dpci_portio_write(const struct hvm_io_handler *handler, + uint64_t addr, + uint32_t size, + uint64_t data) +{ + struct domain *currd = current->domain; + uint32_t data32; + + if ( addr == 0xcf8 ) + { + ASSERT(size == 4); + currd->arch.pci_cf8 = data; + return X86EMUL_OKAY; + } + + ASSERT((addr & 0xfffc) == 0xcfc); + size = min(size, 4 - ((uint32_t)addr & 3)); + if ( size == 3 ) + size = 2; + data32 = data; + if ( pci_cfg_ok(currd, addr & 3, size, &data32) ) + pci_conf_write(currd->arch.pci_cf8, addr & 3, size, data); + + return X86EMUL_OKAY; +} + static const struct hvm_io_ops dpci_portio_ops = { .accept = dpci_portio_accept, .read = dpci_portio_read, .write = dpci_portio_write }; +static const struct hvm_io_ops hw_dpci_portio_ops = { + .accept = hw_dpci_portio_accept, + .read = hw_dpci_portio_read, + .write = hw_dpci_portio_write +}; + void register_dpci_portio_handler(struct domain *d) { struct hvm_io_handler *handler = hvm_next_io_handler(d); @@ -261,7 +328,10 @@ void register_dpci_portio_handler(struct domain *d) return; handler->type = IOREQ_TYPE_PIO; - handler->ops = &dpci_portio_ops; + if ( is_hardware_domain(d) ) + handler->ops = &hw_dpci_portio_ops; + else + handler->ops = &dpci_portio_ops; } /* diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 24d173f..f3c5c9e 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -2076,45 +2076,6 @@ static bool_t admin_io_okay(unsigned int port, unsigned int bytes, return ioports_access_permitted(d, port, port + bytes - 1); } -static bool_t pci_cfg_ok(struct domain *currd, unsigned int start, - unsigned int size, uint32_t *write) -{ - uint32_t machine_bdf; - - if ( !is_hardware_domain(currd) ) - return 0; - - if ( !CF8_ENABLED(currd->arch.pci_cf8) ) - return 1; - - machine_bdf = CF8_BDF(currd->arch.pci_cf8); - if ( write ) - { - const unsigned long *ro_map = pci_get_ro_map(0); - - if ( ro_map && test_bit(machine_bdf, ro_map) ) - return 0; - } - start |= CF8_ADDR_LO(currd->arch.pci_cf8); - /* AMD extended configuration space access? */ - if ( CF8_ADDR_HI(currd->arch.pci_cf8) && - boot_cpu_data.x86_vendor == X86_VENDOR_AMD && - boot_cpu_data.x86 >= 0x10 && boot_cpu_data.x86 <= 0x17 ) - { - uint64_t msr_val; - - if ( rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) ) - return 0; - if ( msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT) ) - start |= CF8_ADDR_HI(currd->arch.pci_cf8); - } - - return !write ? - xsm_pci_config_permission(XSM_HOOK, currd, machine_bdf, - start, start + size - 1, 0) == 0 : - pci_conf_write_intercept(0, machine_bdf, start, size, write) >= 0; -} - uint32_t guest_io_read(unsigned int port, unsigned int bytes, struct domain *currd) { diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index dd291a2..a53b4c8 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -966,6 +966,45 @@ void pci_check_disable_device(u16 seg, u8 bus, u8 devfn) PCI_COMMAND, cword & ~PCI_COMMAND_MASTER); } +bool_t pci_cfg_ok(struct domain *currd, unsigned int start, + unsigned int size, uint32_t *write) +{ + uint32_t machine_bdf; + + if ( !is_hardware_domain(currd) ) + return 0; + + if ( !CF8_ENABLED(currd->arch.pci_cf8) ) + return 1; + + machine_bdf = CF8_BDF(currd->arch.pci_cf8); + if ( write ) + { + const unsigned long *ro_map = pci_get_ro_map(0); + + if ( ro_map && test_bit(machine_bdf, ro_map) ) + return 0; + } + start |= CF8_ADDR_LO(currd->arch.pci_cf8); + /* AMD extended configuration space access? */ + if ( CF8_ADDR_HI(currd->arch.pci_cf8) && + boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 >= 0x10 && boot_cpu_data.x86 <= 0x17 ) + { + uint64_t msr_val; + + if ( rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) ) + return 0; + if ( msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT) ) + start |= CF8_ADDR_HI(currd->arch.pci_cf8); + } + + return !write ? + xsm_pci_config_permission(XSM_HOOK, currd, machine_bdf, + start, start + size - 1, 0) == 0 : + pci_conf_write_intercept(0, machine_bdf, start, size, write) >= 0; +} + /* * scan pci devices to add all existed PCI devices to alldevs_list, * and setup pci hierarchy in array bus2bridge. diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index 0872401..f191773 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -162,6 +162,8 @@ const char *parse_pci(const char *, unsigned int *seg, unsigned int *bus, bool_t pcie_aer_get_firmware_first(const struct pci_dev *); +bool_t pci_cfg_ok(struct domain *, unsigned int, unsigned int, uint32_t *); + struct pirq; int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable); void msixtbl_pt_unregister(struct domain *, struct pirq *);