From patchwork Fri Jul 29 16:29:05 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: 9252695 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 CACD560757 for ; Fri, 29 Jul 2016 16:32:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BBB38283E1 for ; Fri, 29 Jul 2016 16:32:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B064C283E3; Fri, 29 Jul 2016 16:32:14 +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 0C4B0283E1 for ; Fri, 29 Jul 2016 16:32:14 +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 1bTAfT-0003le-NE; Fri, 29 Jul 2016 16:29:47 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bTAfS-0003jV-T8 for xen-devel@lists.xenproject.org; Fri, 29 Jul 2016 16:29:47 +0000 Received: from [85.158.139.211] by server-10.bemta-5.messagelabs.com id 24/FA-19922-A748B975; Fri, 29 Jul 2016 16:29:46 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrKIsWRWlGSWpSXmKPExsXitHRDpG5ly+x wg00zjC2+b5nM5MDocfjDFZYAxijWzLyk/IoE1ozph3ewFiyyqFi9eD1zA+MVzS5GTg4JAX+J q4tms4DYbAI6Ehfn7mTrYuTgEBFQkbi91wAkzCywgFHi7R43EFtYIFzi7tJzbCA2i4CqxLuTM xlBbF4BV4krPd/ZIEbqSjw895sVZAwnUPz/qmoQU0jARaKhKRSiWlDi5MwnLBDTNSVat/9mh7 DlJZq3zmYGsYUEFCX65z0AO0ZCgFvib7f9BEb+WUi6ZyHpnoWkewEj8ypGjeLUorLUIl1DY72 kosz0jJLcxMwcXUMDU73c1OLixPTUnMSkYr3k/NxNjMDgYwCCHYz/tnkeYpTkYFIS5V2wYla4 EF9SfkplRmJxRnxRaU5q8SFGGQ4OJQne202zw4UEi1LTUyvSMnOAcQCTluDgURLh3dIIlOYtL kjMLc5Mh0idYlSUEufVbwZKCIAkMkrz4NpgsXeJUVZKmJcR6BAhnoLUotzMElT5V4ziHIxKwr zMIFN4MvNK4Ka/AlrMBLS4OHYGyOKSRISUVAPjcr5la8Q3t6b4ZM1zzPz2s9vZ6LIAr4eQXOL jsyEPvv9RM/klVrJUyKV8W3+U38uWO7u77A6LX5iiqjmVe/KPLmnGGYduy86La7/Z8oEl2uyo gtqyZ/f3h5558Ov00kkWiZxbfgdwLTZumbqiPIpdZKbDWeH5Kfkr4+sblgl5BzA+Cv25y7FGi aU4I9FQi7moOBEA32zj8rgCAAA= X-Env-Sender: prvs=011b0443a=roger.pau@citrix.com X-Msg-Ref: server-12.tower-206.messagelabs.com!1469809781!15677055!4 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 8.77; banners=-,-,- X-VirusChecked: Checked Received: (qmail 4154 invoked from network); 29 Jul 2016 16:29:45 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-12.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 29 Jul 2016 16:29:45 -0000 X-IronPort-AV: E=Sophos;i="5.28,440,1464652800"; d="scan'208";a="369281753" From: Roger Pau Monne To: Date: Fri, 29 Jul 2016 18:29:05 +0200 Message-ID: <1469809747-11176-11-git-send-email-roger.pau@citrix.com> X-Mailer: git-send-email 2.7.4 (Apple Git-66) In-Reply-To: <1469809747-11176-1-git-send-email-roger.pau@citrix.com> References: <1469809747-11176-1-git-send-email-roger.pau@citrix.com> MIME-Version: 1.0 X-DLP: MIA1 Cc: Andrew Cooper , Paul Durrant , Jan Beulich , Roger Pau Monne Subject: [Xen-devel] [PATCH RFC 10/12] 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 767d0b0..4333bc1 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -2031,45 +2031,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 8bce213..e3595a9 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 *);