* [PATCH v2 0/3] xen/vpci: msix: Make VPCI MSI-X code non-x86 specific @ 2022-02-15 15:25 Rahul Singh 2022-02-15 15:25 ` [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file Rahul Singh ` (2 more replies) 0 siblings, 3 replies; 23+ messages in thread From: Rahul Singh @ 2022-02-15 15:25 UTC (permalink / raw) To: xen-devel Cc: bertrand.marquis, rahul.singh, Jan Beulich, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini This patch series is v2 of preparatory work to make VPCI MSI-X code non-x86 specific. Rahul Singh (3): xen/vpci: msix: move x86 specific code to x86 file xen/vpci: msix: change return value of vpci_msix_{read,write} xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file xen/arch/x86/hvm/vmsi.c | 155 +++++++++++++++++++++++++++ xen/arch/x86/include/asm/msi.h | 28 ----- xen/arch/x86/msi.c | 2 +- xen/drivers/passthrough/amd/iommu.h | 1 + xen/drivers/vpci/msi.c | 3 +- xen/drivers/vpci/msix.c | 158 +++------------------------- xen/include/xen/msi.h | 28 +++++ xen/include/xen/vpci.h | 19 ++++ 8 files changed, 222 insertions(+), 172 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-02-15 15:25 [PATCH v2 0/3] xen/vpci: msix: Make VPCI MSI-X code non-x86 specific Rahul Singh @ 2022-02-15 15:25 ` Rahul Singh 2022-02-24 14:57 ` Jan Beulich 2022-02-15 15:25 ` [PATCH v2 2/3] xen/vpci: msix: change return value of vpci_msix_{read,write} Rahul Singh 2022-02-15 15:25 ` [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file Rahul Singh 2 siblings, 1 reply; 23+ messages in thread From: Rahul Singh @ 2022-02-15 15:25 UTC (permalink / raw) To: xen-devel Cc: bertrand.marquis, rahul.singh, Jan Beulich, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini vpci/msix.c file will be used for arm architecture when vpci msix support will be added to ARM, but there is x86 specific code in this file. Move x86 specific code to the x86/hvm/vmsi.c file to make sure common code will be used for other architecture. No functional change intended. Signed-off-by: Rahul Singh <rahul.singh@arm.com> --- Changes since v1: - Split return value of vpci_msix_{read,write} to separate patch. - Fix the {read,write}{l,q} call in common code to move to arch specific file. --- xen/arch/x86/hvm/vmsi.c | 102 ++++++++++++++++++++++++++++ xen/arch/x86/include/asm/msi.h | 28 -------- xen/arch/x86/msi.c | 2 +- xen/drivers/passthrough/amd/iommu.h | 1 + xen/drivers/vpci/msi.c | 3 +- xen/drivers/vpci/msix.c | 101 +++------------------------ xen/include/xen/msi.h | 28 ++++++++ xen/include/xen/vpci.h | 13 ++++ 8 files changed, 154 insertions(+), 124 deletions(-) diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c index 13e2a190b4..17426f238c 100644 --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) return 0; } + +int vpci_make_msix_hole(const struct pci_dev *pdev) +{ + struct domain *d = pdev->domain; + unsigned int i; + + if ( !pdev->vpci->msix ) + return 0; + + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) + { + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + + vmsix_table_size(pdev->vpci, i) - 1); + + for ( ; start <= end; start++ ) + { + p2m_type_t t; + mfn_t mfn = get_gfn_query(d, start, &t); + + switch ( t ) + { + case p2m_mmio_dm: + case p2m_invalid: + break; + case p2m_mmio_direct: + if ( mfn_x(mfn) == start ) + { + clear_identity_p2m_entry(d, start); + break; + } + /* fallthrough. */ + default: + put_gfn(d, start); + gprintk(XENLOG_WARNING, + "%pp: existing mapping (mfn: %" PRI_mfn + "type: %d) at %#lx clobbers MSIX MMIO area\n", + &pdev->sbdf, mfn_x(mfn), t, start); + return -EEXIST; + } + put_gfn(d, start); + } + } + + return 0; +} + +struct vpci_msix *vpci_msix_find(const struct domain *d, unsigned long addr) +{ + struct vpci_msix *msix; + + list_for_each_entry ( msix, &d->arch.hvm.msix_tables, next ) + { + const struct vpci_bar *bars = msix->pdev->vpci->header.bars; + unsigned int i; + + for ( i = 0; i < ARRAY_SIZE(msix->tables); i++ ) + if ( bars[msix->tables[i] & PCI_MSIX_BIRMASK].enabled && + VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, i) ) + return msix; + } + + return NULL; +} + +static int x86_msix_accept(struct vcpu *v, unsigned long addr) +{ + return !!vpci_msix_find(v->domain, addr); +} + +static int x86_msix_write(struct vcpu *v, unsigned long addr, unsigned int len, + unsigned long data) +{ + const struct domain *d = v->domain; + struct vpci_msix *msix = vpci_msix_find(d, addr); + + return vpci_msix_write(msix, addr, len, data); +} + +static int x86_msix_read(struct vcpu *v, unsigned long addr, unsigned int len, + unsigned long *data) +{ + const struct domain *d = v->domain; + struct vpci_msix *msix = vpci_msix_find(d, addr); + + return vpci_msix_read(msix, addr, len, data); +} + +static const struct hvm_mmio_ops vpci_msix_table_ops = { + .check = x86_msix_accept, + .read = x86_msix_read, + .write = x86_msix_write, +}; + +void vpci_msix_arch_register(struct vpci_msix *msix, struct domain *d) +{ + if ( list_empty(&d->arch.hvm.msix_tables) ) + register_mmio_handler(d, &vpci_msix_table_ops); + + list_add(&msix->next, &d->arch.hvm.msix_tables); +} #endif /* CONFIG_HAS_VPCI */ diff --git a/xen/arch/x86/include/asm/msi.h b/xen/arch/x86/include/asm/msi.h index e228b0f3f3..0a7912e9be 100644 --- a/xen/arch/x86/include/asm/msi.h +++ b/xen/arch/x86/include/asm/msi.h @@ -148,34 +148,6 @@ int msi_free_irq(struct msi_desc *entry); */ #define NR_HP_RESERVED_VECTORS 20 -#define msi_control_reg(base) (base + PCI_MSI_FLAGS) -#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) -#define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) -#define msi_data_reg(base, is64bit) \ - ( (is64bit == 1) ? base+PCI_MSI_DATA_64 : base+PCI_MSI_DATA_32 ) -#define msi_mask_bits_reg(base, is64bit) \ - ( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4) -#define msi_pending_bits_reg(base, is64bit) \ - ((base) + PCI_MSI_MASK_BIT + ((is64bit) ? 4 : 0)) -#define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE -#define multi_msi_capable(control) \ - (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1)) -#define multi_msi_enable(control, num) \ - control |= (((fls(num) - 1) << 4) & PCI_MSI_FLAGS_QSIZE); -#define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) -#define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) -#define msi_enable(control, num) multi_msi_enable(control, num); \ - control |= PCI_MSI_FLAGS_ENABLE - -#define msix_control_reg(base) (base + PCI_MSIX_FLAGS) -#define msix_table_offset_reg(base) (base + PCI_MSIX_TABLE) -#define msix_pba_offset_reg(base) (base + PCI_MSIX_PBA) -#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE -#define msix_disable(control) control &= ~PCI_MSIX_FLAGS_ENABLE -#define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) -#define msix_unmask(address) (address & ~PCI_MSIX_VECTOR_BITMASK) -#define msix_mask(address) (address | PCI_MSIX_VECTOR_BITMASK) - /* * MSI Defined Data Structures */ diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c index 5febc0ea4b..62fd7351dd 100644 --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -20,10 +20,10 @@ #include <xen/iocap.h> #include <xen/keyhandler.h> #include <xen/pfn.h> +#include <xen/msi.h> #include <asm/io.h> #include <asm/smp.h> #include <asm/desc.h> -#include <asm/msi.h> #include <asm/fixmap.h> #include <asm/p2m.h> #include <mach_apic.h> diff --git a/xen/drivers/passthrough/amd/iommu.h b/xen/drivers/passthrough/amd/iommu.h index 93243424e8..f007a0c083 100644 --- a/xen/drivers/passthrough/amd/iommu.h +++ b/xen/drivers/passthrough/amd/iommu.h @@ -26,6 +26,7 @@ #include <xen/tasklet.h> #include <xen/sched.h> #include <xen/domain_page.h> +#include <xen/msi.h> #include <asm/msi.h> #include <asm/apicdef.h> diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c index 5757a7aed2..8fc82a9b8d 100644 --- a/xen/drivers/vpci/msi.c +++ b/xen/drivers/vpci/msi.c @@ -16,12 +16,11 @@ * License along with this program; If not, see <http://www.gnu.org/licenses/>. */ +#include <xen/msi.h> #include <xen/sched.h> #include <xen/softirq.h> #include <xen/vpci.h> -#include <asm/msi.h> - static uint32_t control_read(const struct pci_dev *pdev, unsigned int reg, void *data) { diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c index 846f1b8d70..d89396a3b4 100644 --- a/xen/drivers/vpci/msix.c +++ b/xen/drivers/vpci/msix.c @@ -17,16 +17,12 @@ * License along with this program; If not, see <http://www.gnu.org/licenses/>. */ +#include <xen/msi.h> #include <xen/sched.h> #include <xen/vpci.h> -#include <asm/msi.h> #include <asm/p2m.h> -#define VMSIX_ADDR_IN_RANGE(addr, vpci, nr) \ - ((addr) >= vmsix_table_addr(vpci, nr) && \ - (addr) < vmsix_table_addr(vpci, nr) + vmsix_table_size(vpci, nr)) - static uint32_t control_read(const struct pci_dev *pdev, unsigned int reg, void *data) { @@ -138,29 +134,6 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg, pci_conf_write16(pdev->sbdf, reg, val); } -static struct vpci_msix *msix_find(const struct domain *d, unsigned long addr) -{ - struct vpci_msix *msix; - - list_for_each_entry ( msix, &d->arch.hvm.msix_tables, next ) - { - const struct vpci_bar *bars = msix->pdev->vpci->header.bars; - unsigned int i; - - for ( i = 0; i < ARRAY_SIZE(msix->tables); i++ ) - if ( bars[msix->tables[i] & PCI_MSIX_BIRMASK].enabled && - VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, i) ) - return msix; - } - - return NULL; -} - -static int msix_accept(struct vcpu *v, unsigned long addr) -{ - return !!msix_find(v->domain, addr); -} - static bool access_allowed(const struct pci_dev *pdev, unsigned long addr, unsigned int len) { @@ -182,11 +155,9 @@ static struct vpci_msix_entry *get_entry(struct vpci_msix *msix, return &msix->entries[(addr - start) / PCI_MSIX_ENTRY_SIZE]; } -static int msix_read(struct vcpu *v, unsigned long addr, unsigned int len, - unsigned long *data) +int vpci_msix_read(struct vpci_msix *msix, unsigned long addr, + unsigned int len, unsigned long *data) { - const struct domain *d = v->domain; - struct vpci_msix *msix = msix_find(d, addr); const struct vpci_msix_entry *entry; unsigned int offset; @@ -259,11 +230,10 @@ static int msix_read(struct vcpu *v, unsigned long addr, unsigned int len, return X86EMUL_OKAY; } -static int msix_write(struct vcpu *v, unsigned long addr, unsigned int len, - unsigned long data) +int vpci_msix_write(struct vpci_msix *msix, unsigned long addr, + unsigned int len, unsigned long data) { - const struct domain *d = v->domain; - struct vpci_msix *msix = msix_find(d, addr); + const struct domain *d = msix->pdev->domain; struct vpci_msix_entry *entry; unsigned int offset; @@ -375,59 +345,6 @@ static int msix_write(struct vcpu *v, unsigned long addr, unsigned int len, return X86EMUL_OKAY; } -static const struct hvm_mmio_ops vpci_msix_table_ops = { - .check = msix_accept, - .read = msix_read, - .write = msix_write, -}; - -int vpci_make_msix_hole(const struct pci_dev *pdev) -{ - struct domain *d = pdev->domain; - unsigned int i; - - if ( !pdev->vpci->msix ) - return 0; - - /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ - for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) - { - unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); - unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + - vmsix_table_size(pdev->vpci, i) - 1); - - for ( ; start <= end; start++ ) - { - p2m_type_t t; - mfn_t mfn = get_gfn_query(d, start, &t); - - switch ( t ) - { - case p2m_mmio_dm: - case p2m_invalid: - break; - case p2m_mmio_direct: - if ( mfn_x(mfn) == start ) - { - clear_identity_p2m_entry(d, start); - break; - } - /* fallthrough. */ - default: - put_gfn(d, start); - gprintk(XENLOG_WARNING, - "%pp: existing mapping (mfn: %" PRI_mfn - "type: %d) at %#lx clobbers MSIX MMIO area\n", - &pdev->sbdf, mfn_x(mfn), t, start); - return -EEXIST; - } - put_gfn(d, start); - } - } - - return 0; -} - static int init_msix(struct pci_dev *pdev) { struct domain *d = pdev->domain; @@ -472,11 +389,9 @@ static int init_msix(struct pci_dev *pdev) vpci_msix_arch_init_entry(&msix->entries[i]); } - if ( list_empty(&d->arch.hvm.msix_tables) ) - register_mmio_handler(d, &vpci_msix_table_ops); - pdev->vpci->msix = msix; - list_add(&msix->next, &d->arch.hvm.msix_tables); + + vpci_msix_arch_register(msix, d); return 0; } diff --git a/xen/include/xen/msi.h b/xen/include/xen/msi.h index c903d0050c..c5c8e65feb 100644 --- a/xen/include/xen/msi.h +++ b/xen/include/xen/msi.h @@ -3,6 +3,34 @@ #include <xen/pci.h> +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) +#define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) +#define msi_data_reg(base, is64bit) \ + ( (is64bit) ? (base) + PCI_MSI_DATA_64 : (base) + PCI_MSI_DATA_32 ) +#define msi_mask_bits_reg(base, is64bit) \ + ( (is64bit) ? (base) + PCI_MSI_MASK_BIT : (base) + PCI_MSI_MASK_BIT - 4) +#define msi_pending_bits_reg(base, is64bit) \ + ( (is64bit) ? (base) + PCI_MSI_MASK_BIT + 4 : (base) + PCI_MSI_MASK_BIT) +#define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE +#define multi_msi_capable(control) \ + (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1)) +#define multi_msi_enable(control, num) \ + control |= (((fls(num) - 1) << 4) & PCI_MSI_FLAGS_QSIZE); +#define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) +#define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) +#define msi_enable(control, num) multi_msi_enable(control, num); \ + control |= PCI_MSI_FLAGS_ENABLE + +#define msix_control_reg(base) (base + PCI_MSIX_FLAGS) +#define msix_table_offset_reg(base) (base + PCI_MSIX_TABLE) +#define msix_pba_offset_reg(base) (base + PCI_MSIX_PBA) +#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE +#define msix_disable(control) control &= ~PCI_MSIX_FLAGS_ENABLE +#define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) +#define msix_unmask(address) (address & ~PCI_MSIX_VECTOR_BITMASK) +#define msix_mask(address) (address | PCI_MSIX_VECTOR_BITMASK) + #ifdef CONFIG_HAS_PCI_MSI #include <asm/msi.h> diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index e8ac1eb395..0381a2c911 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -148,6 +148,11 @@ struct vpci_vcpu { }; #ifdef __XEN__ + +#define VMSIX_ADDR_IN_RANGE(addr, vpci, nr) \ + ((addr) >= vmsix_table_addr(vpci, nr) && \ + (addr) < vmsix_table_addr(vpci, nr) + vmsix_table_size(vpci, nr)) + void vpci_dump_msi(void); /* Make sure there's a hole in the p2m for the MSIX mmio areas. */ @@ -218,6 +223,14 @@ bool vpci_ecam_write(pci_sbdf_t sbdf, unsigned int reg, unsigned int len, bool vpci_ecam_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int len, unsigned long *data); +void vpci_msix_arch_register(struct vpci_msix *msix, struct domain *d); + +int vpci_msix_write(struct vpci_msix *msix, unsigned long addr, + unsigned int len, unsigned long data); + +int vpci_msix_read(struct vpci_msix *msix, unsigned long addr, + unsigned int len, unsigned long *data); + #endif /* __XEN__ */ #else /* !CONFIG_HAS_VPCI */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-02-15 15:25 ` [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file Rahul Singh @ 2022-02-24 14:57 ` Jan Beulich 2022-03-01 13:34 ` Rahul Singh 0 siblings, 1 reply; 23+ messages in thread From: Jan Beulich @ 2022-02-24 14:57 UTC (permalink / raw) To: Rahul Singh Cc: bertrand.marquis, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel On 15.02.2022 16:25, Rahul Singh wrote: > vpci/msix.c file will be used for arm architecture when vpci msix > support will be added to ARM, but there is x86 specific code in this > file. > > Move x86 specific code to the x86/hvm/vmsi.c file to make sure common > code will be used for other architecture. Could you provide some criteria by which code is considered x86-specific (or not)? For example ... > --- a/xen/arch/x86/hvm/vmsi.c > +++ b/xen/arch/x86/hvm/vmsi.c > @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) > > return 0; > } > + > +int vpci_make_msix_hole(const struct pci_dev *pdev) > +{ > + struct domain *d = pdev->domain; > + unsigned int i; > + > + if ( !pdev->vpci->msix ) > + return 0; > + > + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ > + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) > + { > + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); > + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + > + vmsix_table_size(pdev->vpci, i) - 1); > + > + for ( ; start <= end; start++ ) > + { > + p2m_type_t t; > + mfn_t mfn = get_gfn_query(d, start, &t); > + > + switch ( t ) > + { > + case p2m_mmio_dm: > + case p2m_invalid: > + break; > + case p2m_mmio_direct: > + if ( mfn_x(mfn) == start ) > + { > + clear_identity_p2m_entry(d, start); > + break; > + } > + /* fallthrough. */ > + default: > + put_gfn(d, start); > + gprintk(XENLOG_WARNING, > + "%pp: existing mapping (mfn: %" PRI_mfn > + "type: %d) at %#lx clobbers MSIX MMIO area\n", > + &pdev->sbdf, mfn_x(mfn), t, start); > + return -EEXIST; > + } > + put_gfn(d, start); > + } > + } > + > + return 0; > +} ... nothing in this function looks to be x86-specific, except maybe functions like clear_identity_p2m_entry() may not currently be available on Arm. But this doesn't make the code x86-specific. > +struct vpci_msix *vpci_msix_find(const struct domain *d, unsigned long addr) > +{ > + struct vpci_msix *msix; > + > + list_for_each_entry ( msix, &d->arch.hvm.msix_tables, next ) > + { > + const struct vpci_bar *bars = msix->pdev->vpci->header.bars; > + unsigned int i; > + > + for ( i = 0; i < ARRAY_SIZE(msix->tables); i++ ) > + if ( bars[msix->tables[i] & PCI_MSIX_BIRMASK].enabled && > + VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, i) ) > + return msix; > + } > + > + return NULL; > +} Or take this one - I don't see anything x86-specific in here. The use of d->arch.hvm merely points out that there may be a field which now needs generalizing. > +static int x86_msix_accept(struct vcpu *v, unsigned long addr) > +{ > + return !!vpci_msix_find(v->domain, addr); > +} > + > +static int x86_msix_write(struct vcpu *v, unsigned long addr, unsigned int len, > + unsigned long data) > +{ > + const struct domain *d = v->domain; > + struct vpci_msix *msix = vpci_msix_find(d, addr); > + > + return vpci_msix_write(msix, addr, len, data); > +} > + > +static int x86_msix_read(struct vcpu *v, unsigned long addr, unsigned int len, > + unsigned long *data) > +{ > + const struct domain *d = v->domain; > + struct vpci_msix *msix = vpci_msix_find(d, addr); > + > + return vpci_msix_read(msix, addr, len, data); > +} > + > +static const struct hvm_mmio_ops vpci_msix_table_ops = { > + .check = x86_msix_accept, > + .read = x86_msix_read, > + .write = x86_msix_write, > +}; I don't see the need to add x86_ prefixes to static functions while you're moving them. Provided any of this is really x86-specific in the first place. > +void vpci_msix_arch_register(struct vpci_msix *msix, struct domain *d) > +{ > + if ( list_empty(&d->arch.hvm.msix_tables) ) > + register_mmio_handler(d, &vpci_msix_table_ops); This is perhaps the only thing which I could see would better live in arch-specific code. > --- a/xen/arch/x86/msi.c > +++ b/xen/arch/x86/msi.c > @@ -20,10 +20,10 @@ > #include <xen/iocap.h> > #include <xen/keyhandler.h> > #include <xen/pfn.h> > +#include <xen/msi.h> > #include <asm/io.h> > #include <asm/smp.h> > #include <asm/desc.h> > -#include <asm/msi.h> Just like you do here and elsewhere, ... > --- a/xen/drivers/passthrough/amd/iommu.h > +++ b/xen/drivers/passthrough/amd/iommu.h > @@ -26,6 +26,7 @@ > #include <xen/tasklet.h> > #include <xen/sched.h> > #include <xen/domain_page.h> > +#include <xen/msi.h> > > #include <asm/msi.h> ... I think you want to remove this now redundant #include as well. > --- a/xen/include/xen/msi.h > +++ b/xen/include/xen/msi.h > @@ -3,6 +3,34 @@ > > #include <xen/pci.h> > > +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) > +#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) > +#define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) > +#define msi_data_reg(base, is64bit) \ > + ( (is64bit) ? (base) + PCI_MSI_DATA_64 : (base) + PCI_MSI_DATA_32 ) > +#define msi_mask_bits_reg(base, is64bit) \ > + ( (is64bit) ? (base) + PCI_MSI_MASK_BIT : (base) + PCI_MSI_MASK_BIT - 4) > +#define msi_pending_bits_reg(base, is64bit) \ > + ( (is64bit) ? (base) + PCI_MSI_MASK_BIT + 4 : (base) + PCI_MSI_MASK_BIT) > +#define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE > +#define multi_msi_capable(control) \ > + (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1)) > +#define multi_msi_enable(control, num) \ > + control |= (((fls(num) - 1) << 4) & PCI_MSI_FLAGS_QSIZE); > +#define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) > +#define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) > +#define msi_enable(control, num) multi_msi_enable(control, num); \ > + control |= PCI_MSI_FLAGS_ENABLE > + > +#define msix_control_reg(base) (base + PCI_MSIX_FLAGS) > +#define msix_table_offset_reg(base) (base + PCI_MSIX_TABLE) > +#define msix_pba_offset_reg(base) (base + PCI_MSIX_PBA) > +#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE > +#define msix_disable(control) control &= ~PCI_MSIX_FLAGS_ENABLE > +#define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) > +#define msix_unmask(address) (address & ~PCI_MSIX_VECTOR_BITMASK) > +#define msix_mask(address) (address | PCI_MSIX_VECTOR_BITMASK) Why did you put these not ... > #ifdef CONFIG_HAS_PCI_MSI .. below here? Also the movement of these is quite the opposite of what the title says. IOW this likely wants to be a separate change. Jan ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-02-24 14:57 ` Jan Beulich @ 2022-03-01 13:34 ` Rahul Singh 2022-03-01 13:55 ` Jan Beulich 0 siblings, 1 reply; 23+ messages in thread From: Rahul Singh @ 2022-03-01 13:34 UTC (permalink / raw) To: Jan Beulich Cc: Bertrand Marquis, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel H Jan, > On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: > > On 15.02.2022 16:25, Rahul Singh wrote: >> vpci/msix.c file will be used for arm architecture when vpci msix >> support will be added to ARM, but there is x86 specific code in this >> file. >> >> Move x86 specific code to the x86/hvm/vmsi.c file to make sure common >> code will be used for other architecture. > > Could you provide some criteria by which code is considered x86-specific > (or not)? For example ... Code moved to x86 file is based on criteria that either the code will be unusable or will be different for ARM when MSIX support will be introduce for ARM. > >> --- a/xen/arch/x86/hvm/vmsi.c >> +++ b/xen/arch/x86/hvm/vmsi.c >> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >> >> return 0; >> } >> + >> +int vpci_make_msix_hole(const struct pci_dev *pdev) >> +{ >> + struct domain *d = pdev->domain; >> + unsigned int i; >> + >> + if ( !pdev->vpci->msix ) >> + return 0; >> + >> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >> + { >> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >> + vmsix_table_size(pdev->vpci, i) - 1); >> + >> + for ( ; start <= end; start++ ) >> + { >> + p2m_type_t t; >> + mfn_t mfn = get_gfn_query(d, start, &t); >> + >> + switch ( t ) >> + { >> + case p2m_mmio_dm: >> + case p2m_invalid: >> + break; >> + case p2m_mmio_direct: >> + if ( mfn_x(mfn) == start ) >> + { >> + clear_identity_p2m_entry(d, start); >> + break; >> + } >> + /* fallthrough. */ >> + default: >> + put_gfn(d, start); >> + gprintk(XENLOG_WARNING, >> + "%pp: existing mapping (mfn: %" PRI_mfn >> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >> + &pdev->sbdf, mfn_x(mfn), t, start); >> + return -EEXIST; >> + } >> + put_gfn(d, start); >> + } >> + } >> + >> + return 0; >> +} > > ... nothing in this function looks to be x86-specific, except maybe > functions like clear_identity_p2m_entry() may not currently be available > on Arm. But this doesn't make the code x86-specific. I will maybe be wrong but what I understand from the code is that for x86 if there is no p2m entries setup for the region, accesses to them will be trapped into the hypervisor and can be handled by specific MMIO handler. But for ARM when we are registering the MMIO handler we have to provide the GPA also for the MMIO handler. For ARM arch vpci_make_msix_hole() will be used to register the MMIO handler for the MSIX MMIO region. int vpci_make_msix_hole(const struct pci_dev *pdev) { struct vpci_msix *msix = pdev->vpci->msix; paddr_t addr,size; for ( int i = 0; msix && i < ARRAY_SIZE(msix->tables); i++ ) { addr = vmsix_table_addr(pdev->vpci, i); size = vmsix_table_size(pdev->vpci, i) - 1; register_mmio_handler(pdev->domain, &vpci_msi_mmio_handler, addr, size, NULL); } return 0; } Therefore in this case there is difference how ARM handle this case. > >> +struct vpci_msix *vpci_msix_find(const struct domain *d, unsigned long addr) >> +{ >> + struct vpci_msix *msix; >> + >> + list_for_each_entry ( msix, &d->arch.hvm.msix_tables, next ) >> + { >> + const struct vpci_bar *bars = msix->pdev->vpci->header.bars; >> + unsigned int i; >> + >> + for ( i = 0; i < ARRAY_SIZE(msix->tables); i++ ) >> + if ( bars[msix->tables[i] & PCI_MSIX_BIRMASK].enabled && >> + VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, i) ) >> + return msix; >> + } >> + >> + return NULL; >> +} > > Or take this one - I don't see anything x86-specific in here. The use > of d->arch.hvm merely points out that there may be a field which now > needs generalizing. Yes, you are right here I can avoid this change if I will introduce "struct list_head msix_tables" in "d->arch.hvm" for ARM also. > >> +static int x86_msix_accept(struct vcpu *v, unsigned long addr) >> +{ >> + return !!vpci_msix_find(v->domain, addr); >> +} >> + >> +static int x86_msix_write(struct vcpu *v, unsigned long addr, unsigned int len, >> + unsigned long data) >> +{ >> + const struct domain *d = v->domain; >> + struct vpci_msix *msix = vpci_msix_find(d, addr); >> + >> + return vpci_msix_write(msix, addr, len, data); >> +} >> + >> +static int x86_msix_read(struct vcpu *v, unsigned long addr, unsigned int len, >> + unsigned long *data) >> +{ >> + const struct domain *d = v->domain; >> + struct vpci_msix *msix = vpci_msix_find(d, addr); >> + >> + return vpci_msix_read(msix, addr, len, data); >> +} >> + >> +static const struct hvm_mmio_ops vpci_msix_table_ops = { >> + .check = x86_msix_accept, >> + .read = x86_msix_read, >> + .write = x86_msix_write, >> +}; > > I don't see the need to add x86_ prefixes to static functions while > you're moving them. Provided any of this is really x86-specific in > the first place. > Ok. Let me remove the x86_ prefixes in next version. MMIO handler functions declaration is different for ARM and X86 therefore I need to move this code to arch specific file. >> +void vpci_msix_arch_register(struct vpci_msix *msix, struct domain *d) >> +{ >> + if ( list_empty(&d->arch.hvm.msix_tables) ) >> + register_mmio_handler(d, &vpci_msix_table_ops); > > This is perhaps the only thing which I could see would better live > in arch-specific code. > >> --- a/xen/arch/x86/msi.c >> +++ b/xen/arch/x86/msi.c >> @@ -20,10 +20,10 @@ >> #include <xen/iocap.h> >> #include <xen/keyhandler.h> >> #include <xen/pfn.h> >> +#include <xen/msi.h> >> #include <asm/io.h> >> #include <asm/smp.h> >> #include <asm/desc.h> >> -#include <asm/msi.h> > > Just like you do here and elsewhere, ... > >> --- a/xen/drivers/passthrough/amd/iommu.h >> +++ b/xen/drivers/passthrough/amd/iommu.h >> @@ -26,6 +26,7 @@ >> #include <xen/tasklet.h> >> #include <xen/sched.h> >> #include <xen/domain_page.h> >> +#include <xen/msi.h> >> >> #include <asm/msi.h> > > ... I think you want to remove this now redundant #include as well. Ok. > >> --- a/xen/include/xen/msi.h >> +++ b/xen/include/xen/msi.h >> @@ -3,6 +3,34 @@ >> >> #include <xen/pci.h> >> >> +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) >> +#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) >> +#define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) >> +#define msi_data_reg(base, is64bit) \ >> + ( (is64bit) ? (base) + PCI_MSI_DATA_64 : (base) + PCI_MSI_DATA_32 ) >> +#define msi_mask_bits_reg(base, is64bit) \ >> + ( (is64bit) ? (base) + PCI_MSI_MASK_BIT : (base) + PCI_MSI_MASK_BIT - 4) >> +#define msi_pending_bits_reg(base, is64bit) \ >> + ( (is64bit) ? (base) + PCI_MSI_MASK_BIT + 4 : (base) + PCI_MSI_MASK_BIT) >> +#define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE >> +#define multi_msi_capable(control) \ >> + (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1)) >> +#define multi_msi_enable(control, num) \ >> + control |= (((fls(num) - 1) << 4) & PCI_MSI_FLAGS_QSIZE); >> +#define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) >> +#define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) >> +#define msi_enable(control, num) multi_msi_enable(control, num); \ >> + control |= PCI_MSI_FLAGS_ENABLE >> + >> +#define msix_control_reg(base) (base + PCI_MSIX_FLAGS) >> +#define msix_table_offset_reg(base) (base + PCI_MSIX_TABLE) >> +#define msix_pba_offset_reg(base) (base + PCI_MSIX_PBA) >> +#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE >> +#define msix_disable(control) control &= ~PCI_MSIX_FLAGS_ENABLE >> +#define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) >> +#define msix_unmask(address) (address & ~PCI_MSIX_VECTOR_BITMASK) >> +#define msix_mask(address) (address | PCI_MSIX_VECTOR_BITMASK) > > Why did you put these not ... > >> #ifdef CONFIG_HAS_PCI_MSI > > .. below here? I will fix this in next version. > > Also the movement of these is quite the opposite of what the title > says. IOW this likely wants to be a separate change. Ok. Let me move this change in separate patch in next series. Regards, Rahul > > Jan > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-01 13:34 ` Rahul Singh @ 2022-03-01 13:55 ` Jan Beulich 2022-03-03 16:31 ` Rahul Singh 0 siblings, 1 reply; 23+ messages in thread From: Jan Beulich @ 2022-03-01 13:55 UTC (permalink / raw) To: Rahul Singh Cc: Bertrand Marquis, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel On 01.03.2022 14:34, Rahul Singh wrote: >> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: >> >> On 15.02.2022 16:25, Rahul Singh wrote: >>> vpci/msix.c file will be used for arm architecture when vpci msix >>> support will be added to ARM, but there is x86 specific code in this >>> file. >>> >>> Move x86 specific code to the x86/hvm/vmsi.c file to make sure common >>> code will be used for other architecture. >> >> Could you provide some criteria by which code is considered x86-specific >> (or not)? For example ... > > Code moved to x86 file is based on criteria that either the code will be unusable or will be different > for ARM when MSIX support will be introduce for ARM. That's a very abstract statement, which you can't really derive any judgement from. It'll be necessary to see in how far the code is indeed different. After all PCI, MSI, and MSI-X are largely arch- agnostic. >>> --- a/xen/arch/x86/hvm/vmsi.c >>> +++ b/xen/arch/x86/hvm/vmsi.c >>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >>> >>> return 0; >>> } >>> + >>> +int vpci_make_msix_hole(const struct pci_dev *pdev) >>> +{ >>> + struct domain *d = pdev->domain; >>> + unsigned int i; >>> + >>> + if ( !pdev->vpci->msix ) >>> + return 0; >>> + >>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >>> + { >>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >>> + vmsix_table_size(pdev->vpci, i) - 1); >>> + >>> + for ( ; start <= end; start++ ) >>> + { >>> + p2m_type_t t; >>> + mfn_t mfn = get_gfn_query(d, start, &t); >>> + >>> + switch ( t ) >>> + { >>> + case p2m_mmio_dm: >>> + case p2m_invalid: >>> + break; >>> + case p2m_mmio_direct: >>> + if ( mfn_x(mfn) == start ) >>> + { >>> + clear_identity_p2m_entry(d, start); >>> + break; >>> + } >>> + /* fallthrough. */ >>> + default: >>> + put_gfn(d, start); >>> + gprintk(XENLOG_WARNING, >>> + "%pp: existing mapping (mfn: %" PRI_mfn >>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >>> + &pdev->sbdf, mfn_x(mfn), t, start); >>> + return -EEXIST; >>> + } >>> + put_gfn(d, start); >>> + } >>> + } >>> + >>> + return 0; >>> +} >> >> ... nothing in this function looks to be x86-specific, except maybe >> functions like clear_identity_p2m_entry() may not currently be available >> on Arm. But this doesn't make the code x86-specific. > > I will maybe be wrong but what I understand from the code is that for x86 > if there is no p2m entries setup for the region, accesses to them will be trapped > into the hypervisor and can be handled by specific MMIO handler. > > But for ARM when we are registering the MMIO handler we have to provide > the GPA also for the MMIO handler. Question is: Is this just an effect resulting from different implementation, or an inherent requirement? In the former case, harmonizing things may be an alternative option. > For ARM arch vpci_make_msix_hole() will be used to register the MMIO handler > for the MSIX MMIO region. > > int vpci_make_msix_hole(const struct pci_dev *pdev) > { > struct vpci_msix *msix = pdev->vpci->msix; > paddr_t addr,size; > > for ( int i = 0; msix && i < ARRAY_SIZE(msix->tables); i++ ) > { > addr = vmsix_table_addr(pdev->vpci, i); > size = vmsix_table_size(pdev->vpci, i) - 1; > register_mmio_handler(pdev->domain, &vpci_msi_mmio_handler, > addr, size, NULL); > } > return 0; > } > > Therefore in this case there is difference how ARM handle this case. > >> >>> +struct vpci_msix *vpci_msix_find(const struct domain *d, unsigned long addr) >>> +{ >>> + struct vpci_msix *msix; >>> + >>> + list_for_each_entry ( msix, &d->arch.hvm.msix_tables, next ) >>> + { >>> + const struct vpci_bar *bars = msix->pdev->vpci->header.bars; >>> + unsigned int i; >>> + >>> + for ( i = 0; i < ARRAY_SIZE(msix->tables); i++ ) >>> + if ( bars[msix->tables[i] & PCI_MSIX_BIRMASK].enabled && >>> + VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, i) ) >>> + return msix; >>> + } >>> + >>> + return NULL; >>> +} >> >> Or take this one - I don't see anything x86-specific in here. The use >> of d->arch.hvm merely points out that there may be a field which now >> needs generalizing. > > Yes, you are right here I can avoid this change if I will introduce > "struct list_head msix_tables" in "d->arch.hvm" for ARM also. Wait - if you pass in the guest address at registration time, you shouldn't have a need for a "find" function. Jan ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-01 13:55 ` Jan Beulich @ 2022-03-03 16:31 ` Rahul Singh 2022-03-04 7:23 ` Jan Beulich 0 siblings, 1 reply; 23+ messages in thread From: Rahul Singh @ 2022-03-03 16:31 UTC (permalink / raw) To: Jan Beulich Cc: Bertrand Marquis, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel Hi Jan, > On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: > > On 01.03.2022 14:34, Rahul Singh wrote: >>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: >>> >>> On 15.02.2022 16:25, Rahul Singh wrote: >>>> vpci/msix.c file will be used for arm architecture when vpci msix >>>> support will be added to ARM, but there is x86 specific code in this >>>> file. >>>> >>>> Move x86 specific code to the x86/hvm/vmsi.c file to make sure common >>>> code will be used for other architecture. >>> >>> Could you provide some criteria by which code is considered x86-specific >>> (or not)? For example ... >> >> Code moved to x86 file is based on criteria that either the code will be unusable or will be different >> for ARM when MSIX support will be introduce for ARM. > > That's a very abstract statement, which you can't really derive any > judgement from. It'll be necessary to see in how far the code is > indeed different. After all PCI, MSI, and MSI-X are largely arch- > agnostic. > >>>> --- a/xen/arch/x86/hvm/vmsi.c >>>> +++ b/xen/arch/x86/hvm/vmsi.c >>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >>>> >>>> return 0; >>>> } >>>> + >>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) >>>> +{ >>>> + struct domain *d = pdev->domain; >>>> + unsigned int i; >>>> + >>>> + if ( !pdev->vpci->msix ) >>>> + return 0; >>>> + >>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >>>> + { >>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >>>> + vmsix_table_size(pdev->vpci, i) - 1); >>>> + >>>> + for ( ; start <= end; start++ ) >>>> + { >>>> + p2m_type_t t; >>>> + mfn_t mfn = get_gfn_query(d, start, &t); >>>> + >>>> + switch ( t ) >>>> + { >>>> + case p2m_mmio_dm: >>>> + case p2m_invalid: >>>> + break; >>>> + case p2m_mmio_direct: >>>> + if ( mfn_x(mfn) == start ) >>>> + { >>>> + clear_identity_p2m_entry(d, start); >>>> + break; >>>> + } >>>> + /* fallthrough. */ >>>> + default: >>>> + put_gfn(d, start); >>>> + gprintk(XENLOG_WARNING, >>>> + "%pp: existing mapping (mfn: %" PRI_mfn >>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >>>> + &pdev->sbdf, mfn_x(mfn), t, start); >>>> + return -EEXIST; >>>> + } >>>> + put_gfn(d, start); >>>> + } >>>> + } >>>> + >>>> + return 0; >>>> +} >>> >>> ... nothing in this function looks to be x86-specific, except maybe >>> functions like clear_identity_p2m_entry() may not currently be available >>> on Arm. But this doesn't make the code x86-specific. >> >> I will maybe be wrong but what I understand from the code is that for x86 >> if there is no p2m entries setup for the region, accesses to them will be trapped >> into the hypervisor and can be handled by specific MMIO handler. >> >> But for ARM when we are registering the MMIO handler we have to provide >> the GPA also for the MMIO handler. > > Question is: Is this just an effect resulting from different implementation, > or an inherent requirement? In the former case, harmonizing things may be an > alternative option. This is an inherent requirement to provide a GPA when registering the MMIO handler. For x86 msix mmio handlers is registered in init_msix(..) function as there is no requirement on x86 to provide GPA when registering the handler. Later point of time when BARs are configured and memory decoding bit is enabled vpci_make_msix_hole() will clear the identity mapping for msix base table address so that access to msix tables will be trapped. On ARM we need to provide GPA to register the mmio handler and MSIX table base address is not valid when init_msix() is called as BAR will be configured later point in time. Therefore on ARM mmio handler will be registered in function vpci_make_msix_hole() when memory decoding bit is enabled. > >> For ARM arch vpci_make_msix_hole() will be used to register the MMIO handler >> for the MSIX MMIO region. >> >> int vpci_make_msix_hole(const struct pci_dev *pdev) >> { >> struct vpci_msix *msix = pdev->vpci->msix; >> paddr_t addr,size; >> >> for ( int i = 0; msix && i < ARRAY_SIZE(msix->tables); i++ ) >> { >> addr = vmsix_table_addr(pdev->vpci, i); >> size = vmsix_table_size(pdev->vpci, i) - 1; >> register_mmio_handler(pdev->domain, &vpci_msi_mmio_handler, >> addr, size, NULL); >> } >> return 0; >> } >> >> Therefore in this case there is difference how ARM handle this case. >> >>> >>>> +struct vpci_msix *vpci_msix_find(const struct domain *d, unsigned long addr) >>>> +{ >>>> + struct vpci_msix *msix; >>>> + >>>> + list_for_each_entry ( msix, &d->arch.hvm.msix_tables, next ) >>>> + { >>>> + const struct vpci_bar *bars = msix->pdev->vpci->header.bars; >>>> + unsigned int i; >>>> + >>>> + for ( i = 0; i < ARRAY_SIZE(msix->tables); i++ ) >>>> + if ( bars[msix->tables[i] & PCI_MSIX_BIRMASK].enabled && >>>> + VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, i) ) >>>> + return msix; >>>> + } >>>> + >>>> + return NULL; >>>> +} >>> >>> Or take this one - I don't see anything x86-specific in here. The use >>> of d->arch.hvm merely points out that there may be a field which now >>> needs generalizing. >> >> Yes, you are right here I can avoid this change if I will introduce >> "struct list_head msix_tables" in "d->arch.hvm" for ARM also. > > Wait - if you pass in the guest address at registration time, you > shouldn't have a need for a "find" function. Yes you are right we don’t need to call msix_find() on ARM. In that case there is need to move msix_find() function to x86 file as I did in v1. Regards, Rahul > > Jan > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-03 16:31 ` Rahul Singh @ 2022-03-04 7:23 ` Jan Beulich 2022-03-09 10:08 ` Rahul Singh 0 siblings, 1 reply; 23+ messages in thread From: Jan Beulich @ 2022-03-04 7:23 UTC (permalink / raw) To: Rahul Singh Cc: Bertrand Marquis, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant On 03.03.2022 17:31, Rahul Singh wrote: >> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: >> On 01.03.2022 14:34, Rahul Singh wrote: >>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>> On 15.02.2022 16:25, Rahul Singh wrote: >>>>> --- a/xen/arch/x86/hvm/vmsi.c >>>>> +++ b/xen/arch/x86/hvm/vmsi.c >>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >>>>> >>>>> return 0; >>>>> } >>>>> + >>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) >>>>> +{ >>>>> + struct domain *d = pdev->domain; >>>>> + unsigned int i; >>>>> + >>>>> + if ( !pdev->vpci->msix ) >>>>> + return 0; >>>>> + >>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >>>>> + { >>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >>>>> + vmsix_table_size(pdev->vpci, i) - 1); >>>>> + >>>>> + for ( ; start <= end; start++ ) >>>>> + { >>>>> + p2m_type_t t; >>>>> + mfn_t mfn = get_gfn_query(d, start, &t); >>>>> + >>>>> + switch ( t ) >>>>> + { >>>>> + case p2m_mmio_dm: >>>>> + case p2m_invalid: >>>>> + break; >>>>> + case p2m_mmio_direct: >>>>> + if ( mfn_x(mfn) == start ) >>>>> + { >>>>> + clear_identity_p2m_entry(d, start); >>>>> + break; >>>>> + } >>>>> + /* fallthrough. */ >>>>> + default: >>>>> + put_gfn(d, start); >>>>> + gprintk(XENLOG_WARNING, >>>>> + "%pp: existing mapping (mfn: %" PRI_mfn >>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >>>>> + &pdev->sbdf, mfn_x(mfn), t, start); >>>>> + return -EEXIST; >>>>> + } >>>>> + put_gfn(d, start); >>>>> + } >>>>> + } >>>>> + >>>>> + return 0; >>>>> +} >>>> >>>> ... nothing in this function looks to be x86-specific, except maybe >>>> functions like clear_identity_p2m_entry() may not currently be available >>>> on Arm. But this doesn't make the code x86-specific. >>> >>> I will maybe be wrong but what I understand from the code is that for x86 >>> if there is no p2m entries setup for the region, accesses to them will be trapped >>> into the hypervisor and can be handled by specific MMIO handler. >>> >>> But for ARM when we are registering the MMIO handler we have to provide >>> the GPA also for the MMIO handler. >> >> Question is: Is this just an effect resulting from different implementation, >> or an inherent requirement? In the former case, harmonizing things may be an >> alternative option. > > This is an inherent requirement to provide a GPA when registering the MMIO handler. So you first say yes to my "inherent" question, but then ... > For x86 msix mmio handlers is registered in init_msix(..) function as there is no requirement > on x86 to provide GPA when registering the handler. Later point of time when BARs are configured > and memory decoding bit is enabled vpci_make_msix_hole() will clear the identity mapping for msix > base table address so that access to msix tables will be trapped. > > On ARM we need to provide GPA to register the mmio handler and MSIX table base > address is not valid when init_msix() is called as BAR will be configured later point in time. > Therefore on ARM mmio handler will be registered in function vpci_make_msix_hole() when > memory decoding bit is enabled. ... you explain it's an implementation detail. I'm inclined to suggest that x86 also pass the GPA where possible. Handler lookup really would benefit from not needing to iterate over all registered handlers, until one claims the access. The optimization part of this of course doesn't need to be done right here, but harmonizing register_mmio_handler() between both architectures would seem to be a reasonable prereq step. I'm adding Paul to Cc in case he wants to comment, as this would touch his territory on the x86 side. Jan ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-04 7:23 ` Jan Beulich @ 2022-03-09 10:08 ` Rahul Singh 2022-03-09 10:16 ` Roger Pau Monné 2022-03-09 10:17 ` Jan Beulich 0 siblings, 2 replies; 23+ messages in thread From: Rahul Singh @ 2022-03-09 10:08 UTC (permalink / raw) To: Jan Beulich Cc: Bertrand Marquis, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant Hi Jan, > On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: > > On 03.03.2022 17:31, Rahul Singh wrote: >>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: >>> On 01.03.2022 14:34, Rahul Singh wrote: >>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>> On 15.02.2022 16:25, Rahul Singh wrote: >>>>>> --- a/xen/arch/x86/hvm/vmsi.c >>>>>> +++ b/xen/arch/x86/hvm/vmsi.c >>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >>>>>> >>>>>> return 0; >>>>>> } >>>>>> + >>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) >>>>>> +{ >>>>>> + struct domain *d = pdev->domain; >>>>>> + unsigned int i; >>>>>> + >>>>>> + if ( !pdev->vpci->msix ) >>>>>> + return 0; >>>>>> + >>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >>>>>> + { >>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >>>>>> + vmsix_table_size(pdev->vpci, i) - 1); >>>>>> + >>>>>> + for ( ; start <= end; start++ ) >>>>>> + { >>>>>> + p2m_type_t t; >>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); >>>>>> + >>>>>> + switch ( t ) >>>>>> + { >>>>>> + case p2m_mmio_dm: >>>>>> + case p2m_invalid: >>>>>> + break; >>>>>> + case p2m_mmio_direct: >>>>>> + if ( mfn_x(mfn) == start ) >>>>>> + { >>>>>> + clear_identity_p2m_entry(d, start); >>>>>> + break; >>>>>> + } >>>>>> + /* fallthrough. */ >>>>>> + default: >>>>>> + put_gfn(d, start); >>>>>> + gprintk(XENLOG_WARNING, >>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn >>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); >>>>>> + return -EEXIST; >>>>>> + } >>>>>> + put_gfn(d, start); >>>>>> + } >>>>>> + } >>>>>> + >>>>>> + return 0; >>>>>> +} >>>>> >>>>> ... nothing in this function looks to be x86-specific, except maybe >>>>> functions like clear_identity_p2m_entry() may not currently be available >>>>> on Arm. But this doesn't make the code x86-specific. >>>> >>>> I will maybe be wrong but what I understand from the code is that for x86 >>>> if there is no p2m entries setup for the region, accesses to them will be trapped >>>> into the hypervisor and can be handled by specific MMIO handler. >>>> >>>> But for ARM when we are registering the MMIO handler we have to provide >>>> the GPA also for the MMIO handler. >>> >>> Question is: Is this just an effect resulting from different implementation, >>> or an inherent requirement? In the former case, harmonizing things may be an >>> alternative option. >> >> This is an inherent requirement to provide a GPA when registering the MMIO handler. > > So you first say yes to my "inherent" question, but then ... > >> For x86 msix mmio handlers is registered in init_msix(..) function as there is no requirement >> on x86 to provide GPA when registering the handler. Later point of time when BARs are configured >> and memory decoding bit is enabled vpci_make_msix_hole() will clear the identity mapping for msix >> base table address so that access to msix tables will be trapped. >> >> On ARM we need to provide GPA to register the mmio handler and MSIX table base >> address is not valid when init_msix() is called as BAR will be configured later point in time. >> Therefore on ARM mmio handler will be registered in function vpci_make_msix_hole() when >> memory decoding bit is enabled. > > ... you explain it's an implementation detail. I'm inclined to > suggest that x86 also pass the GPA where possible. Handler lookup > really would benefit from not needing to iterate over all registered > handlers, until one claims the access. The optimization part of this > of course doesn't need to be done right here, but harmonizing > register_mmio_handler() between both architectures would seem to be > a reasonable prereq step. I agree with you that if we modify the register_mmio_handler() for x86 to pass GPA we can have the common code for x86 and ARM and also we can optimize the MMIO trap handling for x86. What I understand from the code is that modifying the register_mmio_handler() for x86 to pass GPA requires a lot of effort and testing. Unfortunately, I have another high priority task that I have to complete I don’t have time to optimise the register_mmio_handler() for x86 at this time. If you are ok if we can make vpci_make_msix_hole() function arch-specific something like vpci_msix_arch_check_mmio() and get this patch merged. Regards, Rahul > > I'm adding Paul to Cc in case he wants to comment, as this would > touch his territory on the x86 side. > > Jan > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-09 10:08 ` Rahul Singh @ 2022-03-09 10:16 ` Roger Pau Monné 2022-03-09 10:47 ` Rahul Singh 2022-03-09 10:17 ` Jan Beulich 1 sibling, 1 reply; 23+ messages in thread From: Roger Pau Monné @ 2022-03-09 10:16 UTC (permalink / raw) To: Rahul Singh Cc: Jan Beulich, Bertrand Marquis, Andrew Cooper, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant On Wed, Mar 09, 2022 at 10:08:12AM +0000, Rahul Singh wrote: > Hi Jan, > > > On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: > > > > On 03.03.2022 17:31, Rahul Singh wrote: > >>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: > >>> On 01.03.2022 14:34, Rahul Singh wrote: > >>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: > >>>>> On 15.02.2022 16:25, Rahul Singh wrote: > >>>>>> --- a/xen/arch/x86/hvm/vmsi.c > >>>>>> +++ b/xen/arch/x86/hvm/vmsi.c > >>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) > >>>>>> > >>>>>> return 0; > >>>>>> } > >>>>>> + > >>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) > >>>>>> +{ > >>>>>> + struct domain *d = pdev->domain; > >>>>>> + unsigned int i; > >>>>>> + > >>>>>> + if ( !pdev->vpci->msix ) > >>>>>> + return 0; > >>>>>> + > >>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ > >>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) > >>>>>> + { > >>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); > >>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + > >>>>>> + vmsix_table_size(pdev->vpci, i) - 1); > >>>>>> + > >>>>>> + for ( ; start <= end; start++ ) > >>>>>> + { > >>>>>> + p2m_type_t t; > >>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); > >>>>>> + > >>>>>> + switch ( t ) > >>>>>> + { > >>>>>> + case p2m_mmio_dm: > >>>>>> + case p2m_invalid: > >>>>>> + break; > >>>>>> + case p2m_mmio_direct: > >>>>>> + if ( mfn_x(mfn) == start ) > >>>>>> + { > >>>>>> + clear_identity_p2m_entry(d, start); > >>>>>> + break; > >>>>>> + } > >>>>>> + /* fallthrough. */ > >>>>>> + default: > >>>>>> + put_gfn(d, start); > >>>>>> + gprintk(XENLOG_WARNING, > >>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn > >>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", > >>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); > >>>>>> + return -EEXIST; > >>>>>> + } > >>>>>> + put_gfn(d, start); > >>>>>> + } > >>>>>> + } > >>>>>> + > >>>>>> + return 0; > >>>>>> +} > >>>>> > >>>>> ... nothing in this function looks to be x86-specific, except maybe > >>>>> functions like clear_identity_p2m_entry() may not currently be available > >>>>> on Arm. But this doesn't make the code x86-specific. > >>>> > >>>> I will maybe be wrong but what I understand from the code is that for x86 > >>>> if there is no p2m entries setup for the region, accesses to them will be trapped > >>>> into the hypervisor and can be handled by specific MMIO handler. > >>>> > >>>> But for ARM when we are registering the MMIO handler we have to provide > >>>> the GPA also for the MMIO handler. Right, but you still need those regions to not be mapped on the second stage translation, or else no trap will be triggered and thus the handlers won't run? Regardless of whether the way to register the handlers is different on Arm and x86, you still need to assure that the MSI-X related tables are not mapped on the guest second stage translation, or else you are just allowing guest access to the native ones. So you do need this function on Arm in order to prevent hardware MSI-X tables being accessed by the guest. Or are you suggesting it's intended for Arm guest to access the native MSI-X tables? Thanks, Roger. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-09 10:16 ` Roger Pau Monné @ 2022-03-09 10:47 ` Rahul Singh 2022-03-09 11:17 ` Roger Pau Monné 0 siblings, 1 reply; 23+ messages in thread From: Rahul Singh @ 2022-03-09 10:47 UTC (permalink / raw) To: Roger Pau Monné Cc: Jan Beulich, Bertrand Marquis, Andrew Cooper, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant Hi Roger, > On 9 Mar 2022, at 10:16 am, Roger Pau Monné <roger.pau@citrix.com> wrote: > > On Wed, Mar 09, 2022 at 10:08:12AM +0000, Rahul Singh wrote: >> Hi Jan, >> >>> On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: >>> >>> On 03.03.2022 17:31, Rahul Singh wrote: >>>>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>> On 01.03.2022 14:34, Rahul Singh wrote: >>>>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>>>> On 15.02.2022 16:25, Rahul Singh wrote: >>>>>>>> --- a/xen/arch/x86/hvm/vmsi.c >>>>>>>> +++ b/xen/arch/x86/hvm/vmsi.c >>>>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >>>>>>>> >>>>>>>> return 0; >>>>>>>> } >>>>>>>> + >>>>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) >>>>>>>> +{ >>>>>>>> + struct domain *d = pdev->domain; >>>>>>>> + unsigned int i; >>>>>>>> + >>>>>>>> + if ( !pdev->vpci->msix ) >>>>>>>> + return 0; >>>>>>>> + >>>>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >>>>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >>>>>>>> + { >>>>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >>>>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >>>>>>>> + vmsix_table_size(pdev->vpci, i) - 1); >>>>>>>> + >>>>>>>> + for ( ; start <= end; start++ ) >>>>>>>> + { >>>>>>>> + p2m_type_t t; >>>>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); >>>>>>>> + >>>>>>>> + switch ( t ) >>>>>>>> + { >>>>>>>> + case p2m_mmio_dm: >>>>>>>> + case p2m_invalid: >>>>>>>> + break; >>>>>>>> + case p2m_mmio_direct: >>>>>>>> + if ( mfn_x(mfn) == start ) >>>>>>>> + { >>>>>>>> + clear_identity_p2m_entry(d, start); >>>>>>>> + break; >>>>>>>> + } >>>>>>>> + /* fallthrough. */ >>>>>>>> + default: >>>>>>>> + put_gfn(d, start); >>>>>>>> + gprintk(XENLOG_WARNING, >>>>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn >>>>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >>>>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); >>>>>>>> + return -EEXIST; >>>>>>>> + } >>>>>>>> + put_gfn(d, start); >>>>>>>> + } >>>>>>>> + } >>>>>>>> + >>>>>>>> + return 0; >>>>>>>> +} >>>>>>> >>>>>>> ... nothing in this function looks to be x86-specific, except maybe >>>>>>> functions like clear_identity_p2m_entry() may not currently be available >>>>>>> on Arm. But this doesn't make the code x86-specific. >>>>>> >>>>>> I will maybe be wrong but what I understand from the code is that for x86 >>>>>> if there is no p2m entries setup for the region, accesses to them will be trapped >>>>>> into the hypervisor and can be handled by specific MMIO handler. >>>>>> >>>>>> But for ARM when we are registering the MMIO handler we have to provide >>>>>> the GPA also for the MMIO handler. > > Right, but you still need those regions to not be mapped on the second > stage translation, or else no trap will be triggered and thus the > handlers won't run? > > Regardless of whether the way to register the handlers is different on > Arm and x86, you still need to assure that the MSI-X related tables > are not mapped on the guest second stage translation, or else you are > just allowing guest access to the native ones. What I understand from the VPCI code we are not mapping the MSI-X related tables/BAR to Stage-2 translation therefore no need to remove the mapping. http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=xen/drivers/vpci/header.c;h=a1c928a0d26f5cefd98727ee37f5dc43ceba80a6;hb=HEAD#l248 > > So you do need this function on Arm in order to prevent hardware MSI-X > tables being accessed by the guest. Or are you suggesting it's > intended for Arm guest to access the native MSI-X tables? On ARM also access to the MSI-X tables will be trapped and physical MSI-X table will be updated accordingly. Regards, Rahul > > Thanks, Roger. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-09 10:47 ` Rahul Singh @ 2022-03-09 11:17 ` Roger Pau Monné 0 siblings, 0 replies; 23+ messages in thread From: Roger Pau Monné @ 2022-03-09 11:17 UTC (permalink / raw) To: Rahul Singh Cc: Jan Beulich, Bertrand Marquis, Andrew Cooper, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant On Wed, Mar 09, 2022 at 10:47:06AM +0000, Rahul Singh wrote: > Hi Roger, > > > On 9 Mar 2022, at 10:16 am, Roger Pau Monné <roger.pau@citrix.com> wrote: > > > > On Wed, Mar 09, 2022 at 10:08:12AM +0000, Rahul Singh wrote: > >> Hi Jan, > >> > >>> On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: > >>> > >>> On 03.03.2022 17:31, Rahul Singh wrote: > >>>>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: > >>>>> On 01.03.2022 14:34, Rahul Singh wrote: > >>>>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: > >>>>>>> On 15.02.2022 16:25, Rahul Singh wrote: > >>>>>>>> --- a/xen/arch/x86/hvm/vmsi.c > >>>>>>>> +++ b/xen/arch/x86/hvm/vmsi.c > >>>>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) > >>>>>>>> > >>>>>>>> return 0; > >>>>>>>> } > >>>>>>>> + > >>>>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) > >>>>>>>> +{ > >>>>>>>> + struct domain *d = pdev->domain; > >>>>>>>> + unsigned int i; > >>>>>>>> + > >>>>>>>> + if ( !pdev->vpci->msix ) > >>>>>>>> + return 0; > >>>>>>>> + > >>>>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ > >>>>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) > >>>>>>>> + { > >>>>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); > >>>>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + > >>>>>>>> + vmsix_table_size(pdev->vpci, i) - 1); > >>>>>>>> + > >>>>>>>> + for ( ; start <= end; start++ ) > >>>>>>>> + { > >>>>>>>> + p2m_type_t t; > >>>>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); > >>>>>>>> + > >>>>>>>> + switch ( t ) > >>>>>>>> + { > >>>>>>>> + case p2m_mmio_dm: > >>>>>>>> + case p2m_invalid: > >>>>>>>> + break; > >>>>>>>> + case p2m_mmio_direct: > >>>>>>>> + if ( mfn_x(mfn) == start ) > >>>>>>>> + { > >>>>>>>> + clear_identity_p2m_entry(d, start); > >>>>>>>> + break; > >>>>>>>> + } > >>>>>>>> + /* fallthrough. */ > >>>>>>>> + default: > >>>>>>>> + put_gfn(d, start); > >>>>>>>> + gprintk(XENLOG_WARNING, > >>>>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn > >>>>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", > >>>>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); > >>>>>>>> + return -EEXIST; > >>>>>>>> + } > >>>>>>>> + put_gfn(d, start); > >>>>>>>> + } > >>>>>>>> + } > >>>>>>>> + > >>>>>>>> + return 0; > >>>>>>>> +} > >>>>>>> > >>>>>>> ... nothing in this function looks to be x86-specific, except maybe > >>>>>>> functions like clear_identity_p2m_entry() may not currently be available > >>>>>>> on Arm. But this doesn't make the code x86-specific. > >>>>>> > >>>>>> I will maybe be wrong but what I understand from the code is that for x86 > >>>>>> if there is no p2m entries setup for the region, accesses to them will be trapped > >>>>>> into the hypervisor and can be handled by specific MMIO handler. > >>>>>> > >>>>>> But for ARM when we are registering the MMIO handler we have to provide > >>>>>> the GPA also for the MMIO handler. > > > > Right, but you still need those regions to not be mapped on the second > > stage translation, or else no trap will be triggered and thus the > > handlers won't run? > > > > Regardless of whether the way to register the handlers is different on > > Arm and x86, you still need to assure that the MSI-X related tables > > are not mapped on the guest second stage translation, or else you are > > just allowing guest access to the native ones. > > What I understand from the VPCI code we are not mapping the MSI-X related tables/BAR > to Stage-2 translation therefore no need to remove the mapping. > > http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=xen/drivers/vpci/header.c;h=a1c928a0d26f5cefd98727ee37f5dc43ceba80a6;hb=HEAD#l248 Right, sorry, was slightly confused. So this is indeed only needed if Arm does some kind of pre-mapping of non-RAM regions. For example an x86 PVH dom0 will add the regions marked as 'reserved' to the second stage translation, and we need vpci_make_msix_hole in order to punch holes there if those pre-mapped regions happen to overlap with any MSI-X table. If there aren't any non-RAM regions mapped on Arm for it's hardware domain by default then I guess it's safe to make this arch-specific. Thanks, Roger. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-09 10:08 ` Rahul Singh 2022-03-09 10:16 ` Roger Pau Monné @ 2022-03-09 10:17 ` Jan Beulich 2022-03-09 15:50 ` Rahul Singh 1 sibling, 1 reply; 23+ messages in thread From: Jan Beulich @ 2022-03-09 10:17 UTC (permalink / raw) To: Rahul Singh Cc: Bertrand Marquis, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant On 09.03.2022 11:08, Rahul Singh wrote: > Hi Jan, > >> On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: >> >> On 03.03.2022 17:31, Rahul Singh wrote: >>>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>> On 01.03.2022 14:34, Rahul Singh wrote: >>>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>>> On 15.02.2022 16:25, Rahul Singh wrote: >>>>>>> --- a/xen/arch/x86/hvm/vmsi.c >>>>>>> +++ b/xen/arch/x86/hvm/vmsi.c >>>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >>>>>>> >>>>>>> return 0; >>>>>>> } >>>>>>> + >>>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) >>>>>>> +{ >>>>>>> + struct domain *d = pdev->domain; >>>>>>> + unsigned int i; >>>>>>> + >>>>>>> + if ( !pdev->vpci->msix ) >>>>>>> + return 0; >>>>>>> + >>>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >>>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >>>>>>> + { >>>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >>>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >>>>>>> + vmsix_table_size(pdev->vpci, i) - 1); >>>>>>> + >>>>>>> + for ( ; start <= end; start++ ) >>>>>>> + { >>>>>>> + p2m_type_t t; >>>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); >>>>>>> + >>>>>>> + switch ( t ) >>>>>>> + { >>>>>>> + case p2m_mmio_dm: >>>>>>> + case p2m_invalid: >>>>>>> + break; >>>>>>> + case p2m_mmio_direct: >>>>>>> + if ( mfn_x(mfn) == start ) >>>>>>> + { >>>>>>> + clear_identity_p2m_entry(d, start); >>>>>>> + break; >>>>>>> + } >>>>>>> + /* fallthrough. */ >>>>>>> + default: >>>>>>> + put_gfn(d, start); >>>>>>> + gprintk(XENLOG_WARNING, >>>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn >>>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >>>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); >>>>>>> + return -EEXIST; >>>>>>> + } >>>>>>> + put_gfn(d, start); >>>>>>> + } >>>>>>> + } >>>>>>> + >>>>>>> + return 0; >>>>>>> +} >>>>>> >>>>>> ... nothing in this function looks to be x86-specific, except maybe >>>>>> functions like clear_identity_p2m_entry() may not currently be available >>>>>> on Arm. But this doesn't make the code x86-specific. >>>>> >>>>> I will maybe be wrong but what I understand from the code is that for x86 >>>>> if there is no p2m entries setup for the region, accesses to them will be trapped >>>>> into the hypervisor and can be handled by specific MMIO handler. >>>>> >>>>> But for ARM when we are registering the MMIO handler we have to provide >>>>> the GPA also for the MMIO handler. >>>> >>>> Question is: Is this just an effect resulting from different implementation, >>>> or an inherent requirement? In the former case, harmonizing things may be an >>>> alternative option. >>> >>> This is an inherent requirement to provide a GPA when registering the MMIO handler. >> >> So you first say yes to my "inherent" question, but then ... >> >>> For x86 msix mmio handlers is registered in init_msix(..) function as there is no requirement >>> on x86 to provide GPA when registering the handler. Later point of time when BARs are configured >>> and memory decoding bit is enabled vpci_make_msix_hole() will clear the identity mapping for msix >>> base table address so that access to msix tables will be trapped. >>> >>> On ARM we need to provide GPA to register the mmio handler and MSIX table base >>> address is not valid when init_msix() is called as BAR will be configured later point in time. >>> Therefore on ARM mmio handler will be registered in function vpci_make_msix_hole() when >>> memory decoding bit is enabled. >> >> ... you explain it's an implementation detail. I'm inclined to >> suggest that x86 also pass the GPA where possible. Handler lookup >> really would benefit from not needing to iterate over all registered >> handlers, until one claims the access. The optimization part of this >> of course doesn't need to be done right here, but harmonizing >> register_mmio_handler() between both architectures would seem to be >> a reasonable prereq step. > > I agree with you that if we modify the register_mmio_handler() for x86 to pass GPA > we can have the common code for x86 and ARM and also we can optimize the MMIO > trap handling for x86. > > What I understand from the code is that modifying the register_mmio_handler() for > x86 to pass GPA requires a lot of effort and testing. > > Unfortunately, I have another high priority task that I have to complete I don’t have time > to optimise the register_mmio_handler() for x86 at this time. Actually making use of the parameter is nothing I would expect you to do. But is just adding the extra parameter similarly out of scope for you? Jan ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-09 10:17 ` Jan Beulich @ 2022-03-09 15:50 ` Rahul Singh 2022-03-09 15:53 ` Jan Beulich 2022-03-09 16:06 ` Roger Pau Monné 0 siblings, 2 replies; 23+ messages in thread From: Rahul Singh @ 2022-03-09 15:50 UTC (permalink / raw) To: Jan Beulich Cc: Bertrand Marquis, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant Hi Jan, > On 9 Mar 2022, at 10:17 am, Jan Beulich <jbeulich@suse.com> wrote: > > On 09.03.2022 11:08, Rahul Singh wrote: >> Hi Jan, >> >>> On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: >>> >>> On 03.03.2022 17:31, Rahul Singh wrote: >>>>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>> On 01.03.2022 14:34, Rahul Singh wrote: >>>>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>>>> On 15.02.2022 16:25, Rahul Singh wrote: >>>>>>>> --- a/xen/arch/x86/hvm/vmsi.c >>>>>>>> +++ b/xen/arch/x86/hvm/vmsi.c >>>>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >>>>>>>> >>>>>>>> return 0; >>>>>>>> } >>>>>>>> + >>>>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) >>>>>>>> +{ >>>>>>>> + struct domain *d = pdev->domain; >>>>>>>> + unsigned int i; >>>>>>>> + >>>>>>>> + if ( !pdev->vpci->msix ) >>>>>>>> + return 0; >>>>>>>> + >>>>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >>>>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >>>>>>>> + { >>>>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >>>>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >>>>>>>> + vmsix_table_size(pdev->vpci, i) - 1); >>>>>>>> + >>>>>>>> + for ( ; start <= end; start++ ) >>>>>>>> + { >>>>>>>> + p2m_type_t t; >>>>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); >>>>>>>> + >>>>>>>> + switch ( t ) >>>>>>>> + { >>>>>>>> + case p2m_mmio_dm: >>>>>>>> + case p2m_invalid: >>>>>>>> + break; >>>>>>>> + case p2m_mmio_direct: >>>>>>>> + if ( mfn_x(mfn) == start ) >>>>>>>> + { >>>>>>>> + clear_identity_p2m_entry(d, start); >>>>>>>> + break; >>>>>>>> + } >>>>>>>> + /* fallthrough. */ >>>>>>>> + default: >>>>>>>> + put_gfn(d, start); >>>>>>>> + gprintk(XENLOG_WARNING, >>>>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn >>>>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >>>>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); >>>>>>>> + return -EEXIST; >>>>>>>> + } >>>>>>>> + put_gfn(d, start); >>>>>>>> + } >>>>>>>> + } >>>>>>>> + >>>>>>>> + return 0; >>>>>>>> +} >>>>>>> >>>>>>> ... nothing in this function looks to be x86-specific, except maybe >>>>>>> functions like clear_identity_p2m_entry() may not currently be available >>>>>>> on Arm. But this doesn't make the code x86-specific. >>>>>> >>>>>> I will maybe be wrong but what I understand from the code is that for x86 >>>>>> if there is no p2m entries setup for the region, accesses to them will be trapped >>>>>> into the hypervisor and can be handled by specific MMIO handler. >>>>>> >>>>>> But for ARM when we are registering the MMIO handler we have to provide >>>>>> the GPA also for the MMIO handler. >>>>> >>>>> Question is: Is this just an effect resulting from different implementation, >>>>> or an inherent requirement? In the former case, harmonizing things may be an >>>>> alternative option. >>>> >>>> This is an inherent requirement to provide a GPA when registering the MMIO handler. >>> >>> So you first say yes to my "inherent" question, but then ... >>> >>>> For x86 msix mmio handlers is registered in init_msix(..) function as there is no requirement >>>> on x86 to provide GPA when registering the handler. Later point of time when BARs are configured >>>> and memory decoding bit is enabled vpci_make_msix_hole() will clear the identity mapping for msix >>>> base table address so that access to msix tables will be trapped. >>>> >>>> On ARM we need to provide GPA to register the mmio handler and MSIX table base >>>> address is not valid when init_msix() is called as BAR will be configured later point in time. >>>> Therefore on ARM mmio handler will be registered in function vpci_make_msix_hole() when >>>> memory decoding bit is enabled. >>> >>> ... you explain it's an implementation detail. I'm inclined to >>> suggest that x86 also pass the GPA where possible. Handler lookup >>> really would benefit from not needing to iterate over all registered >>> handlers, until one claims the access. The optimization part of this >>> of course doesn't need to be done right here, but harmonizing >>> register_mmio_handler() between both architectures would seem to be >>> a reasonable prereq step. >> >> I agree with you that if we modify the register_mmio_handler() for x86 to pass GPA >> we can have the common code for x86 and ARM and also we can optimize the MMIO >> trap handling for x86. >> >> What I understand from the code is that modifying the register_mmio_handler() for >> x86 to pass GPA requires a lot of effort and testing. >> >> Unfortunately, I have another high priority task that I have to complete I don’t have time >> to optimise the register_mmio_handler() for x86 at this time. > > Actually making use of the parameter is nothing I would expect you to > do. But is just adding the extra parameter similarly out of scope for > you? > If I understand correctly you are asking to make register_mmio_handler() declaration same for x86 and ARM. You are not asking to modify the x86 MMIO handler logic to use GPA to find the handler? As Roger also mentioned that vpci_make_msix_hole() is required only for x86 to clear the identity mapping. If we make the vpci_make_msix_hole() arch-specific there is no need to modify the parameter for register_mmio_handler(), as for x86 and ARM register_mmio_handler() will be called in different places. For x86 register_mmio_handler() will be called in init_msix() whereas for ARM register_mmio_handler() will be called in vpci_make_msix_hole(). In this case we have to move the call to register_mmio_handler() also to arch-specific files. If we move the register_mmio_handler() to arch specific file there is no need to make the function common. Regards, Rahul > Jan ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-09 15:50 ` Rahul Singh @ 2022-03-09 15:53 ` Jan Beulich 2022-03-09 16:06 ` Roger Pau Monné 1 sibling, 0 replies; 23+ messages in thread From: Jan Beulich @ 2022-03-09 15:53 UTC (permalink / raw) To: Rahul Singh Cc: Bertrand Marquis, Andrew Cooper, Roger Pau Monné, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant On 09.03.2022 16:50, Rahul Singh wrote: >> On 9 Mar 2022, at 10:17 am, Jan Beulich <jbeulich@suse.com> wrote: >> On 09.03.2022 11:08, Rahul Singh wrote: >>>> On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: >>>> On 03.03.2022 17:31, Rahul Singh wrote: >>>>>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>>> On 01.03.2022 14:34, Rahul Singh wrote: >>>>>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>>>>> On 15.02.2022 16:25, Rahul Singh wrote: >>>>>>>>> --- a/xen/arch/x86/hvm/vmsi.c >>>>>>>>> +++ b/xen/arch/x86/hvm/vmsi.c >>>>>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >>>>>>>>> >>>>>>>>> return 0; >>>>>>>>> } >>>>>>>>> + >>>>>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) >>>>>>>>> +{ >>>>>>>>> + struct domain *d = pdev->domain; >>>>>>>>> + unsigned int i; >>>>>>>>> + >>>>>>>>> + if ( !pdev->vpci->msix ) >>>>>>>>> + return 0; >>>>>>>>> + >>>>>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >>>>>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >>>>>>>>> + { >>>>>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >>>>>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >>>>>>>>> + vmsix_table_size(pdev->vpci, i) - 1); >>>>>>>>> + >>>>>>>>> + for ( ; start <= end; start++ ) >>>>>>>>> + { >>>>>>>>> + p2m_type_t t; >>>>>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); >>>>>>>>> + >>>>>>>>> + switch ( t ) >>>>>>>>> + { >>>>>>>>> + case p2m_mmio_dm: >>>>>>>>> + case p2m_invalid: >>>>>>>>> + break; >>>>>>>>> + case p2m_mmio_direct: >>>>>>>>> + if ( mfn_x(mfn) == start ) >>>>>>>>> + { >>>>>>>>> + clear_identity_p2m_entry(d, start); >>>>>>>>> + break; >>>>>>>>> + } >>>>>>>>> + /* fallthrough. */ >>>>>>>>> + default: >>>>>>>>> + put_gfn(d, start); >>>>>>>>> + gprintk(XENLOG_WARNING, >>>>>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn >>>>>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >>>>>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); >>>>>>>>> + return -EEXIST; >>>>>>>>> + } >>>>>>>>> + put_gfn(d, start); >>>>>>>>> + } >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + return 0; >>>>>>>>> +} >>>>>>>> >>>>>>>> ... nothing in this function looks to be x86-specific, except maybe >>>>>>>> functions like clear_identity_p2m_entry() may not currently be available >>>>>>>> on Arm. But this doesn't make the code x86-specific. >>>>>>> >>>>>>> I will maybe be wrong but what I understand from the code is that for x86 >>>>>>> if there is no p2m entries setup for the region, accesses to them will be trapped >>>>>>> into the hypervisor and can be handled by specific MMIO handler. >>>>>>> >>>>>>> But for ARM when we are registering the MMIO handler we have to provide >>>>>>> the GPA also for the MMIO handler. >>>>>> >>>>>> Question is: Is this just an effect resulting from different implementation, >>>>>> or an inherent requirement? In the former case, harmonizing things may be an >>>>>> alternative option. >>>>> >>>>> This is an inherent requirement to provide a GPA when registering the MMIO handler. >>>> >>>> So you first say yes to my "inherent" question, but then ... >>>> >>>>> For x86 msix mmio handlers is registered in init_msix(..) function as there is no requirement >>>>> on x86 to provide GPA when registering the handler. Later point of time when BARs are configured >>>>> and memory decoding bit is enabled vpci_make_msix_hole() will clear the identity mapping for msix >>>>> base table address so that access to msix tables will be trapped. >>>>> >>>>> On ARM we need to provide GPA to register the mmio handler and MSIX table base >>>>> address is not valid when init_msix() is called as BAR will be configured later point in time. >>>>> Therefore on ARM mmio handler will be registered in function vpci_make_msix_hole() when >>>>> memory decoding bit is enabled. >>>> >>>> ... you explain it's an implementation detail. I'm inclined to >>>> suggest that x86 also pass the GPA where possible. Handler lookup >>>> really would benefit from not needing to iterate over all registered >>>> handlers, until one claims the access. The optimization part of this >>>> of course doesn't need to be done right here, but harmonizing >>>> register_mmio_handler() between both architectures would seem to be >>>> a reasonable prereq step. >>> >>> I agree with you that if we modify the register_mmio_handler() for x86 to pass GPA >>> we can have the common code for x86 and ARM and also we can optimize the MMIO >>> trap handling for x86. >>> >>> What I understand from the code is that modifying the register_mmio_handler() for >>> x86 to pass GPA requires a lot of effort and testing. >>> >>> Unfortunately, I have another high priority task that I have to complete I don’t have time >>> to optimise the register_mmio_handler() for x86 at this time. >> >> Actually making use of the parameter is nothing I would expect you to >> do. But is just adding the extra parameter similarly out of scope for >> you? >> > > If I understand correctly you are asking to make register_mmio_handler() declaration > same for x86 and ARM. You are not asking to modify the x86 MMIO handler logic to > use GPA to find the handler? Yes, but ... > As Roger also mentioned that vpci_make_msix_hole() is required only for x86 to clear > the identity mapping. If we make the vpci_make_msix_hole() arch-specific there is no > need to modify the parameter for register_mmio_handler(), as for x86 and ARM > register_mmio_handler() will be called in different places. ... with Roger agreeing with this plan, that other alternative is likely dead now. Provided other stuff which isn't obviously arch- specific remains in common code. Jan ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-09 15:50 ` Rahul Singh 2022-03-09 15:53 ` Jan Beulich @ 2022-03-09 16:06 ` Roger Pau Monné 2022-03-10 11:48 ` Rahul Singh 1 sibling, 1 reply; 23+ messages in thread From: Roger Pau Monné @ 2022-03-09 16:06 UTC (permalink / raw) To: Rahul Singh Cc: Jan Beulich, Bertrand Marquis, Andrew Cooper, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant On Wed, Mar 09, 2022 at 03:50:12PM +0000, Rahul Singh wrote: > Hi Jan, > > > On 9 Mar 2022, at 10:17 am, Jan Beulich <jbeulich@suse.com> wrote: > > > > On 09.03.2022 11:08, Rahul Singh wrote: > >> Hi Jan, > >> > >>> On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: > >>> > >>> On 03.03.2022 17:31, Rahul Singh wrote: > >>>>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: > >>>>> On 01.03.2022 14:34, Rahul Singh wrote: > >>>>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: > >>>>>>> On 15.02.2022 16:25, Rahul Singh wrote: > >>>>>>>> --- a/xen/arch/x86/hvm/vmsi.c > >>>>>>>> +++ b/xen/arch/x86/hvm/vmsi.c > >>>>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) > >>>>>>>> > >>>>>>>> return 0; > >>>>>>>> } > >>>>>>>> + > >>>>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) > >>>>>>>> +{ > >>>>>>>> + struct domain *d = pdev->domain; > >>>>>>>> + unsigned int i; > >>>>>>>> + > >>>>>>>> + if ( !pdev->vpci->msix ) > >>>>>>>> + return 0; > >>>>>>>> + > >>>>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ > >>>>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) > >>>>>>>> + { > >>>>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); > >>>>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + > >>>>>>>> + vmsix_table_size(pdev->vpci, i) - 1); > >>>>>>>> + > >>>>>>>> + for ( ; start <= end; start++ ) > >>>>>>>> + { > >>>>>>>> + p2m_type_t t; > >>>>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); > >>>>>>>> + > >>>>>>>> + switch ( t ) > >>>>>>>> + { > >>>>>>>> + case p2m_mmio_dm: > >>>>>>>> + case p2m_invalid: > >>>>>>>> + break; > >>>>>>>> + case p2m_mmio_direct: > >>>>>>>> + if ( mfn_x(mfn) == start ) > >>>>>>>> + { > >>>>>>>> + clear_identity_p2m_entry(d, start); > >>>>>>>> + break; > >>>>>>>> + } > >>>>>>>> + /* fallthrough. */ > >>>>>>>> + default: > >>>>>>>> + put_gfn(d, start); > >>>>>>>> + gprintk(XENLOG_WARNING, > >>>>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn > >>>>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", > >>>>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); > >>>>>>>> + return -EEXIST; > >>>>>>>> + } > >>>>>>>> + put_gfn(d, start); > >>>>>>>> + } > >>>>>>>> + } > >>>>>>>> + > >>>>>>>> + return 0; > >>>>>>>> +} > >>>>>>> > >>>>>>> ... nothing in this function looks to be x86-specific, except maybe > >>>>>>> functions like clear_identity_p2m_entry() may not currently be available > >>>>>>> on Arm. But this doesn't make the code x86-specific. > >>>>>> > >>>>>> I will maybe be wrong but what I understand from the code is that for x86 > >>>>>> if there is no p2m entries setup for the region, accesses to them will be trapped > >>>>>> into the hypervisor and can be handled by specific MMIO handler. > >>>>>> > >>>>>> But for ARM when we are registering the MMIO handler we have to provide > >>>>>> the GPA also for the MMIO handler. > >>>>> > >>>>> Question is: Is this just an effect resulting from different implementation, > >>>>> or an inherent requirement? In the former case, harmonizing things may be an > >>>>> alternative option. > >>>> > >>>> This is an inherent requirement to provide a GPA when registering the MMIO handler. > >>> > >>> So you first say yes to my "inherent" question, but then ... > >>> > >>>> For x86 msix mmio handlers is registered in init_msix(..) function as there is no requirement > >>>> on x86 to provide GPA when registering the handler. Later point of time when BARs are configured > >>>> and memory decoding bit is enabled vpci_make_msix_hole() will clear the identity mapping for msix > >>>> base table address so that access to msix tables will be trapped. > >>>> > >>>> On ARM we need to provide GPA to register the mmio handler and MSIX table base > >>>> address is not valid when init_msix() is called as BAR will be configured later point in time. > >>>> Therefore on ARM mmio handler will be registered in function vpci_make_msix_hole() when > >>>> memory decoding bit is enabled. > >>> > >>> ... you explain it's an implementation detail. I'm inclined to > >>> suggest that x86 also pass the GPA where possible. Handler lookup > >>> really would benefit from not needing to iterate over all registered > >>> handlers, until one claims the access. The optimization part of this > >>> of course doesn't need to be done right here, but harmonizing > >>> register_mmio_handler() between both architectures would seem to be > >>> a reasonable prereq step. > >> > >> I agree with you that if we modify the register_mmio_handler() for x86 to pass GPA > >> we can have the common code for x86 and ARM and also we can optimize the MMIO > >> trap handling for x86. > >> > >> What I understand from the code is that modifying the register_mmio_handler() for > >> x86 to pass GPA requires a lot of effort and testing. > >> > >> Unfortunately, I have another high priority task that I have to complete I don’t have time > >> to optimise the register_mmio_handler() for x86 at this time. > > > > Actually making use of the parameter is nothing I would expect you to > > do. But is just adding the extra parameter similarly out of scope for > > you? > > > > If I understand correctly you are asking to make register_mmio_handler() declaration > same for x86 and ARM. You are not asking to modify the x86 MMIO handler logic to > use GPA to find the handler? > > As Roger also mentioned that vpci_make_msix_hole() is required only for x86 to clear > the identity mapping. If we make the vpci_make_msix_hole() arch-specific there is no > need to modify the parameter for register_mmio_handler(), as for x86 and ARM > register_mmio_handler() will be called in different places. > > For x86 register_mmio_handler() will be called in init_msix() whereas for ARM > register_mmio_handler() will be called in vpci_make_msix_hole(). In this case we > have to move the call to register_mmio_handler() also to arch-specific files. If we move > the register_mmio_handler() to arch specific file there is no need to make the > function common. So then for Arm you will need something akin to unregister_mmio_handler so the handler can be removed when memory decoding is disabled? Or else you would keep adding new handlers every time the guest enables memory decoding for the device without having removed the stale ones? Thanks, Roger. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-09 16:06 ` Roger Pau Monné @ 2022-03-10 11:48 ` Rahul Singh 2022-03-10 15:54 ` Roger Pau Monné 0 siblings, 1 reply; 23+ messages in thread From: Rahul Singh @ 2022-03-10 11:48 UTC (permalink / raw) To: Roger Pau Monné Cc: Jan Beulich, Bertrand Marquis, Andrew Cooper, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant Hello Roger, > On 9 Mar 2022, at 4:06 pm, Roger Pau Monné <roger.pau@citrix.com> wrote: > > On Wed, Mar 09, 2022 at 03:50:12PM +0000, Rahul Singh wrote: >> Hi Jan, >> >>> On 9 Mar 2022, at 10:17 am, Jan Beulich <jbeulich@suse.com> wrote: >>> >>> On 09.03.2022 11:08, Rahul Singh wrote: >>>> Hi Jan, >>>> >>>>> On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: >>>>> >>>>> On 03.03.2022 17:31, Rahul Singh wrote: >>>>>>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>>>> On 01.03.2022 14:34, Rahul Singh wrote: >>>>>>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: >>>>>>>>> On 15.02.2022 16:25, Rahul Singh wrote: >>>>>>>>>> --- a/xen/arch/x86/hvm/vmsi.c >>>>>>>>>> +++ b/xen/arch/x86/hvm/vmsi.c >>>>>>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) >>>>>>>>>> >>>>>>>>>> return 0; >>>>>>>>>> } >>>>>>>>>> + >>>>>>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) >>>>>>>>>> +{ >>>>>>>>>> + struct domain *d = pdev->domain; >>>>>>>>>> + unsigned int i; >>>>>>>>>> + >>>>>>>>>> + if ( !pdev->vpci->msix ) >>>>>>>>>> + return 0; >>>>>>>>>> + >>>>>>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ >>>>>>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) >>>>>>>>>> + { >>>>>>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); >>>>>>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + >>>>>>>>>> + vmsix_table_size(pdev->vpci, i) - 1); >>>>>>>>>> + >>>>>>>>>> + for ( ; start <= end; start++ ) >>>>>>>>>> + { >>>>>>>>>> + p2m_type_t t; >>>>>>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); >>>>>>>>>> + >>>>>>>>>> + switch ( t ) >>>>>>>>>> + { >>>>>>>>>> + case p2m_mmio_dm: >>>>>>>>>> + case p2m_invalid: >>>>>>>>>> + break; >>>>>>>>>> + case p2m_mmio_direct: >>>>>>>>>> + if ( mfn_x(mfn) == start ) >>>>>>>>>> + { >>>>>>>>>> + clear_identity_p2m_entry(d, start); >>>>>>>>>> + break; >>>>>>>>>> + } >>>>>>>>>> + /* fallthrough. */ >>>>>>>>>> + default: >>>>>>>>>> + put_gfn(d, start); >>>>>>>>>> + gprintk(XENLOG_WARNING, >>>>>>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn >>>>>>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", >>>>>>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); >>>>>>>>>> + return -EEXIST; >>>>>>>>>> + } >>>>>>>>>> + put_gfn(d, start); >>>>>>>>>> + } >>>>>>>>>> + } >>>>>>>>>> + >>>>>>>>>> + return 0; >>>>>>>>>> +} >>>>>>>>> >>>>>>>>> ... nothing in this function looks to be x86-specific, except maybe >>>>>>>>> functions like clear_identity_p2m_entry() may not currently be available >>>>>>>>> on Arm. But this doesn't make the code x86-specific. >>>>>>>> >>>>>>>> I will maybe be wrong but what I understand from the code is that for x86 >>>>>>>> if there is no p2m entries setup for the region, accesses to them will be trapped >>>>>>>> into the hypervisor and can be handled by specific MMIO handler. >>>>>>>> >>>>>>>> But for ARM when we are registering the MMIO handler we have to provide >>>>>>>> the GPA also for the MMIO handler. >>>>>>> >>>>>>> Question is: Is this just an effect resulting from different implementation, >>>>>>> or an inherent requirement? In the former case, harmonizing things may be an >>>>>>> alternative option. >>>>>> >>>>>> This is an inherent requirement to provide a GPA when registering the MMIO handler. >>>>> >>>>> So you first say yes to my "inherent" question, but then ... >>>>> >>>>>> For x86 msix mmio handlers is registered in init_msix(..) function as there is no requirement >>>>>> on x86 to provide GPA when registering the handler. Later point of time when BARs are configured >>>>>> and memory decoding bit is enabled vpci_make_msix_hole() will clear the identity mapping for msix >>>>>> base table address so that access to msix tables will be trapped. >>>>>> >>>>>> On ARM we need to provide GPA to register the mmio handler and MSIX table base >>>>>> address is not valid when init_msix() is called as BAR will be configured later point in time. >>>>>> Therefore on ARM mmio handler will be registered in function vpci_make_msix_hole() when >>>>>> memory decoding bit is enabled. >>>>> >>>>> ... you explain it's an implementation detail. I'm inclined to >>>>> suggest that x86 also pass the GPA where possible. Handler lookup >>>>> really would benefit from not needing to iterate over all registered >>>>> handlers, until one claims the access. The optimization part of this >>>>> of course doesn't need to be done right here, but harmonizing >>>>> register_mmio_handler() between both architectures would seem to be >>>>> a reasonable prereq step. >>>> >>>> I agree with you that if we modify the register_mmio_handler() for x86 to pass GPA >>>> we can have the common code for x86 and ARM and also we can optimize the MMIO >>>> trap handling for x86. >>>> >>>> What I understand from the code is that modifying the register_mmio_handler() for >>>> x86 to pass GPA requires a lot of effort and testing. >>>> >>>> Unfortunately, I have another high priority task that I have to complete I don’t have time >>>> to optimise the register_mmio_handler() for x86 at this time. >>> >>> Actually making use of the parameter is nothing I would expect you to >>> do. But is just adding the extra parameter similarly out of scope for >>> you? >>> >> >> If I understand correctly you are asking to make register_mmio_handler() declaration >> same for x86 and ARM. You are not asking to modify the x86 MMIO handler logic to >> use GPA to find the handler? >> >> As Roger also mentioned that vpci_make_msix_hole() is required only for x86 to clear >> the identity mapping. If we make the vpci_make_msix_hole() arch-specific there is no >> need to modify the parameter for register_mmio_handler(), as for x86 and ARM >> register_mmio_handler() will be called in different places. >> >> For x86 register_mmio_handler() will be called in init_msix() whereas for ARM >> register_mmio_handler() will be called in vpci_make_msix_hole(). In this case we >> have to move the call to register_mmio_handler() also to arch-specific files. If we move >> the register_mmio_handler() to arch specific file there is no need to make the >> function common. > > So then for Arm you will need something akin to > unregister_mmio_handler so the handler can be removed when memory > decoding is disabled? > > Or else you would keep adding new handlers every time the guest > enables memory decoding for the device without having removed the > stale ones? Yes, when I will send the patches for ARM I will take care of this not to register the handler again if the memory decoding bit is changed. Before registering the handler will check if the handler is already for GPA if it is already registered no need to register. Regards, Rahul > > Thanks, Roger. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file 2022-03-10 11:48 ` Rahul Singh @ 2022-03-10 15:54 ` Roger Pau Monné 0 siblings, 0 replies; 23+ messages in thread From: Roger Pau Monné @ 2022-03-10 15:54 UTC (permalink / raw) To: Rahul Singh Cc: Jan Beulich, Bertrand Marquis, Andrew Cooper, Wei Liu, George Dunlap, Julien Grall, Stefano Stabellini, xen-devel, Paul Durrant On Thu, Mar 10, 2022 at 11:48:15AM +0000, Rahul Singh wrote: > Hello Roger, > > > On 9 Mar 2022, at 4:06 pm, Roger Pau Monné <roger.pau@citrix.com> wrote: > > > > On Wed, Mar 09, 2022 at 03:50:12PM +0000, Rahul Singh wrote: > >> Hi Jan, > >> > >>> On 9 Mar 2022, at 10:17 am, Jan Beulich <jbeulich@suse.com> wrote: > >>> > >>> On 09.03.2022 11:08, Rahul Singh wrote: > >>>> Hi Jan, > >>>> > >>>>> On 4 Mar 2022, at 7:23 am, Jan Beulich <jbeulich@suse.com> wrote: > >>>>> > >>>>> On 03.03.2022 17:31, Rahul Singh wrote: > >>>>>>> On 1 Mar 2022, at 1:55 pm, Jan Beulich <jbeulich@suse.com> wrote: > >>>>>>> On 01.03.2022 14:34, Rahul Singh wrote: > >>>>>>>>> On 24 Feb 2022, at 2:57 pm, Jan Beulich <jbeulich@suse.com> wrote: > >>>>>>>>> On 15.02.2022 16:25, Rahul Singh wrote: > >>>>>>>>>> --- a/xen/arch/x86/hvm/vmsi.c > >>>>>>>>>> +++ b/xen/arch/x86/hvm/vmsi.c > >>>>>>>>>> @@ -925,4 +925,106 @@ int vpci_msix_arch_print(const struct vpci_msix *msix) > >>>>>>>>>> > >>>>>>>>>> return 0; > >>>>>>>>>> } > >>>>>>>>>> + > >>>>>>>>>> +int vpci_make_msix_hole(const struct pci_dev *pdev) > >>>>>>>>>> +{ > >>>>>>>>>> + struct domain *d = pdev->domain; > >>>>>>>>>> + unsigned int i; > >>>>>>>>>> + > >>>>>>>>>> + if ( !pdev->vpci->msix ) > >>>>>>>>>> + return 0; > >>>>>>>>>> + > >>>>>>>>>> + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ > >>>>>>>>>> + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) > >>>>>>>>>> + { > >>>>>>>>>> + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); > >>>>>>>>>> + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + > >>>>>>>>>> + vmsix_table_size(pdev->vpci, i) - 1); > >>>>>>>>>> + > >>>>>>>>>> + for ( ; start <= end; start++ ) > >>>>>>>>>> + { > >>>>>>>>>> + p2m_type_t t; > >>>>>>>>>> + mfn_t mfn = get_gfn_query(d, start, &t); > >>>>>>>>>> + > >>>>>>>>>> + switch ( t ) > >>>>>>>>>> + { > >>>>>>>>>> + case p2m_mmio_dm: > >>>>>>>>>> + case p2m_invalid: > >>>>>>>>>> + break; > >>>>>>>>>> + case p2m_mmio_direct: > >>>>>>>>>> + if ( mfn_x(mfn) == start ) > >>>>>>>>>> + { > >>>>>>>>>> + clear_identity_p2m_entry(d, start); > >>>>>>>>>> + break; > >>>>>>>>>> + } > >>>>>>>>>> + /* fallthrough. */ > >>>>>>>>>> + default: > >>>>>>>>>> + put_gfn(d, start); > >>>>>>>>>> + gprintk(XENLOG_WARNING, > >>>>>>>>>> + "%pp: existing mapping (mfn: %" PRI_mfn > >>>>>>>>>> + "type: %d) at %#lx clobbers MSIX MMIO area\n", > >>>>>>>>>> + &pdev->sbdf, mfn_x(mfn), t, start); > >>>>>>>>>> + return -EEXIST; > >>>>>>>>>> + } > >>>>>>>>>> + put_gfn(d, start); > >>>>>>>>>> + } > >>>>>>>>>> + } > >>>>>>>>>> + > >>>>>>>>>> + return 0; > >>>>>>>>>> +} > >>>>>>>>> > >>>>>>>>> ... nothing in this function looks to be x86-specific, except maybe > >>>>>>>>> functions like clear_identity_p2m_entry() may not currently be available > >>>>>>>>> on Arm. But this doesn't make the code x86-specific. > >>>>>>>> > >>>>>>>> I will maybe be wrong but what I understand from the code is that for x86 > >>>>>>>> if there is no p2m entries setup for the region, accesses to them will be trapped > >>>>>>>> into the hypervisor and can be handled by specific MMIO handler. > >>>>>>>> > >>>>>>>> But for ARM when we are registering the MMIO handler we have to provide > >>>>>>>> the GPA also for the MMIO handler. > >>>>>>> > >>>>>>> Question is: Is this just an effect resulting from different implementation, > >>>>>>> or an inherent requirement? In the former case, harmonizing things may be an > >>>>>>> alternative option. > >>>>>> > >>>>>> This is an inherent requirement to provide a GPA when registering the MMIO handler. > >>>>> > >>>>> So you first say yes to my "inherent" question, but then ... > >>>>> > >>>>>> For x86 msix mmio handlers is registered in init_msix(..) function as there is no requirement > >>>>>> on x86 to provide GPA when registering the handler. Later point of time when BARs are configured > >>>>>> and memory decoding bit is enabled vpci_make_msix_hole() will clear the identity mapping for msix > >>>>>> base table address so that access to msix tables will be trapped. > >>>>>> > >>>>>> On ARM we need to provide GPA to register the mmio handler and MSIX table base > >>>>>> address is not valid when init_msix() is called as BAR will be configured later point in time. > >>>>>> Therefore on ARM mmio handler will be registered in function vpci_make_msix_hole() when > >>>>>> memory decoding bit is enabled. > >>>>> > >>>>> ... you explain it's an implementation detail. I'm inclined to > >>>>> suggest that x86 also pass the GPA where possible. Handler lookup > >>>>> really would benefit from not needing to iterate over all registered > >>>>> handlers, until one claims the access. The optimization part of this > >>>>> of course doesn't need to be done right here, but harmonizing > >>>>> register_mmio_handler() between both architectures would seem to be > >>>>> a reasonable prereq step. > >>>> > >>>> I agree with you that if we modify the register_mmio_handler() for x86 to pass GPA > >>>> we can have the common code for x86 and ARM and also we can optimize the MMIO > >>>> trap handling for x86. > >>>> > >>>> What I understand from the code is that modifying the register_mmio_handler() for > >>>> x86 to pass GPA requires a lot of effort and testing. > >>>> > >>>> Unfortunately, I have another high priority task that I have to complete I don’t have time > >>>> to optimise the register_mmio_handler() for x86 at this time. > >>> > >>> Actually making use of the parameter is nothing I would expect you to > >>> do. But is just adding the extra parameter similarly out of scope for > >>> you? > >>> > >> > >> If I understand correctly you are asking to make register_mmio_handler() declaration > >> same for x86 and ARM. You are not asking to modify the x86 MMIO handler logic to > >> use GPA to find the handler? > >> > >> As Roger also mentioned that vpci_make_msix_hole() is required only for x86 to clear > >> the identity mapping. If we make the vpci_make_msix_hole() arch-specific there is no > >> need to modify the parameter for register_mmio_handler(), as for x86 and ARM > >> register_mmio_handler() will be called in different places. > >> > >> For x86 register_mmio_handler() will be called in init_msix() whereas for ARM > >> register_mmio_handler() will be called in vpci_make_msix_hole(). In this case we > >> have to move the call to register_mmio_handler() also to arch-specific files. If we move > >> the register_mmio_handler() to arch specific file there is no need to make the > >> function common. > > > > So then for Arm you will need something akin to > > unregister_mmio_handler so the handler can be removed when memory > > decoding is disabled? > > > > Or else you would keep adding new handlers every time the guest > > enables memory decoding for the device without having removed the > > stale ones? > > Yes, when I will send the patches for ARM I will take care of this not to register the handler > again if the memory decoding bit is changed. Before registering the handler will check > if the handler is already for GPA if it is already registered no need to register. I think it might be helpful to post the Arm bits together with the moving of the x86 ones. It's way easier to see why you need to make certain things arch-specific if you also provide the Arm implementation at the same time. Or else it's just code movement that might need to be redone when Arm support is introduced if we deem that certain parts could be unified. Thanks, Roger. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 2/3] xen/vpci: msix: change return value of vpci_msix_{read,write} 2022-02-15 15:25 [PATCH v2 0/3] xen/vpci: msix: Make VPCI MSI-X code non-x86 specific Rahul Singh 2022-02-15 15:25 ` [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file Rahul Singh @ 2022-02-15 15:25 ` Rahul Singh 2022-02-15 15:25 ` [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file Rahul Singh 2 siblings, 0 replies; 23+ messages in thread From: Rahul Singh @ 2022-02-15 15:25 UTC (permalink / raw) To: xen-devel Cc: bertrand.marquis, rahul.singh, Jan Beulich, Andrew Cooper, Roger Pau Monné, Wei Liu Return value is different for the MMIO handler on ARM and x86 architecture. To make the code common for both architectures change the return value of vpci_msix_{read, write} to bool. Architecture-specific return value will be handled in arch code. Signed-off-by: Rahul Singh <rahul.singh@arm.com> --- Changes since v1: - Added in this version --- xen/arch/x86/hvm/vmsi.c | 10 ++++++++-- xen/drivers/vpci/msix.c | 24 ++++++++++++------------ xen/include/xen/vpci.h | 8 ++++---- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c index 17426f238c..761ce674d7 100644 --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -1002,7 +1002,10 @@ static int x86_msix_write(struct vcpu *v, unsigned long addr, unsigned int len, const struct domain *d = v->domain; struct vpci_msix *msix = vpci_msix_find(d, addr); - return vpci_msix_write(msix, addr, len, data); + if( !vpci_msix_write(msix, addr, len, data) ) + return X86EMUL_RETRY; + + return X86EMUL_OKAY; } static int x86_msix_read(struct vcpu *v, unsigned long addr, unsigned int len, @@ -1011,7 +1014,10 @@ static int x86_msix_read(struct vcpu *v, unsigned long addr, unsigned int len, const struct domain *d = v->domain; struct vpci_msix *msix = vpci_msix_find(d, addr); - return vpci_msix_read(msix, addr, len, data); + if ( !vpci_msix_read(msix, addr, len, data) ) + return X86EMUL_RETRY; + + return X86EMUL_OKAY; } static const struct hvm_mmio_ops vpci_msix_table_ops = { diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c index d89396a3b4..5b315757ef 100644 --- a/xen/drivers/vpci/msix.c +++ b/xen/drivers/vpci/msix.c @@ -155,8 +155,8 @@ static struct vpci_msix_entry *get_entry(struct vpci_msix *msix, return &msix->entries[(addr - start) / PCI_MSIX_ENTRY_SIZE]; } -int vpci_msix_read(struct vpci_msix *msix, unsigned long addr, - unsigned int len, unsigned long *data) +bool vpci_msix_read(struct vpci_msix *msix, unsigned long addr, + unsigned int len, unsigned long *data) { const struct vpci_msix_entry *entry; unsigned int offset; @@ -164,10 +164,10 @@ int vpci_msix_read(struct vpci_msix *msix, unsigned long addr, *data = ~0ul; if ( !msix ) - return X86EMUL_RETRY; + return false; if ( !access_allowed(msix->pdev, addr, len) ) - return X86EMUL_OKAY; + return true; if ( VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, VPCI_MSIX_PBA) ) { @@ -193,7 +193,7 @@ int vpci_msix_read(struct vpci_msix *msix, unsigned long addr, break; } - return X86EMUL_OKAY; + return true; } spin_lock(&msix->pdev->vpci->lock); @@ -227,21 +227,21 @@ int vpci_msix_read(struct vpci_msix *msix, unsigned long addr, } spin_unlock(&msix->pdev->vpci->lock); - return X86EMUL_OKAY; + return true; } -int vpci_msix_write(struct vpci_msix *msix, unsigned long addr, - unsigned int len, unsigned long data) +bool vpci_msix_write(struct vpci_msix *msix, unsigned long addr, + unsigned int len, unsigned long data) { const struct domain *d = msix->pdev->domain; struct vpci_msix_entry *entry; unsigned int offset; if ( !msix ) - return X86EMUL_RETRY; + return false; if ( !access_allowed(msix->pdev, addr, len) ) - return X86EMUL_OKAY; + return true; if ( VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, VPCI_MSIX_PBA) ) { @@ -264,7 +264,7 @@ int vpci_msix_write(struct vpci_msix *msix, unsigned long addr, } } - return X86EMUL_OKAY; + return true; } spin_lock(&msix->pdev->vpci->lock); @@ -342,7 +342,7 @@ int vpci_msix_write(struct vpci_msix *msix, unsigned long addr, } spin_unlock(&msix->pdev->vpci->lock); - return X86EMUL_OKAY; + return true; } static int init_msix(struct pci_dev *pdev) diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index 0381a2c911..1c36845abf 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -225,11 +225,11 @@ bool vpci_ecam_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int len, void vpci_msix_arch_register(struct vpci_msix *msix, struct domain *d); -int vpci_msix_write(struct vpci_msix *msix, unsigned long addr, - unsigned int len, unsigned long data); +bool vpci_msix_write(struct vpci_msix *msix, unsigned long addr, + unsigned int len, unsigned long data); -int vpci_msix_read(struct vpci_msix *msix, unsigned long addr, - unsigned int len, unsigned long *data); +bool vpci_msix_read(struct vpci_msix *msix, unsigned long addr, + unsigned int len, unsigned long *data); #endif /* __XEN__ */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file 2022-02-15 15:25 [PATCH v2 0/3] xen/vpci: msix: Make VPCI MSI-X code non-x86 specific Rahul Singh 2022-02-15 15:25 ` [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file Rahul Singh 2022-02-15 15:25 ` [PATCH v2 2/3] xen/vpci: msix: change return value of vpci_msix_{read,write} Rahul Singh @ 2022-02-15 15:25 ` Rahul Singh 2022-02-24 15:18 ` Jan Beulich 2022-02-25 8:20 ` Roger Pau Monné 2 siblings, 2 replies; 23+ messages in thread From: Rahul Singh @ 2022-02-15 15:25 UTC (permalink / raw) To: xen-devel Cc: bertrand.marquis, rahul.singh, Jan Beulich, Andrew Cooper, Roger Pau Monné, Wei Liu {read,write}{l,q} function argument is different for ARM and x86. ARM {read,wrie}(l,q} function argument is pointer whereas X86 {read,wrie}(l,q} function argument is address itself. {read,write}{l,q} is only used in common file to access the MSI-X PBA structure. To avoid impacting other x86 code and to make the code common move the read/write call to MSI-X PBA to arch specific file. Signed-off-by: Rahul Singh <rahul.singh@arm.com> --- Changes since v1: - Added in this version --- xen/arch/x86/hvm/vmsi.c | 47 +++++++++++++++++++++++++++++++++++++++++ xen/drivers/vpci/msix.c | 43 ++----------------------------------- xen/include/xen/vpci.h | 6 ++++++ 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c index 761ce674d7..f124a1d07d 100644 --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -1033,4 +1033,51 @@ void vpci_msix_arch_register(struct vpci_msix *msix, struct domain *d) list_add(&msix->next, &d->arch.hvm.msix_tables); } + +bool vpci_msix_arch_pba_read(unsigned long addr, unsigned int len, + unsigned long *data) +{ + /* + * Access to PBA. + * + * TODO: note that this relies on having the PBA identity mapped to the + * guest address space. If this changes the address will need to be + * translated. + */ + switch ( len ) + { + case 4: + *data = readl(addr); + break; + + case 8: + *data = readq(addr); + break; + + default: + ASSERT_UNREACHABLE(); + break; + } + + return true; +} + +void vpci_msix_arch_pba_write(unsigned long addr, unsigned int len, + unsigned long data) +{ + switch ( len ) + { + case 4: + writel(data, addr); + break; + + case 8: + writeq(data, addr); + break; + + default: + ASSERT_UNREACHABLE(); + break; + } +} #endif /* CONFIG_HAS_VPCI */ diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c index 5b315757ef..b6720f1a1a 100644 --- a/xen/drivers/vpci/msix.c +++ b/xen/drivers/vpci/msix.c @@ -170,31 +170,7 @@ bool vpci_msix_read(struct vpci_msix *msix, unsigned long addr, return true; if ( VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, VPCI_MSIX_PBA) ) - { - /* - * Access to PBA. - * - * TODO: note that this relies on having the PBA identity mapped to the - * guest address space. If this changes the address will need to be - * translated. - */ - switch ( len ) - { - case 4: - *data = readl(addr); - break; - - case 8: - *data = readq(addr); - break; - - default: - ASSERT_UNREACHABLE(); - break; - } - - return true; - } + return vpci_msix_arch_pba_read(addr, len, data); spin_lock(&msix->pdev->vpci->lock); entry = get_entry(msix, addr); @@ -247,22 +223,7 @@ bool vpci_msix_write(struct vpci_msix *msix, unsigned long addr, { /* Ignore writes to PBA for DomUs, it's behavior is undefined. */ if ( is_hardware_domain(d) ) - { - switch ( len ) - { - case 4: - writel(data, addr); - break; - - case 8: - writeq(data, addr); - break; - - default: - ASSERT_UNREACHABLE(); - break; - } - } + vpci_msix_arch_pba_write(addr, len, data); return true; } diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index 1c36845abf..a61daf9d53 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -231,6 +231,12 @@ bool vpci_msix_write(struct vpci_msix *msix, unsigned long addr, bool vpci_msix_read(struct vpci_msix *msix, unsigned long addr, unsigned int len, unsigned long *data); +bool vpci_msix_arch_pba_read(unsigned long addr, unsigned int len, + unsigned long *data); + +void vpci_msix_arch_pba_write(unsigned long addr, unsigned int len, + unsigned long data); + #endif /* __XEN__ */ #else /* !CONFIG_HAS_VPCI */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file 2022-02-15 15:25 ` [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file Rahul Singh @ 2022-02-24 15:18 ` Jan Beulich 2022-02-25 8:21 ` Roger Pau Monné 2022-02-25 8:20 ` Roger Pau Monné 1 sibling, 1 reply; 23+ messages in thread From: Jan Beulich @ 2022-02-24 15:18 UTC (permalink / raw) To: Rahul Singh, Roger Pau Monné Cc: bertrand.marquis, Andrew Cooper, Wei Liu, xen-devel On 15.02.2022 16:25, Rahul Singh wrote: > {read,write}{l,q} function argument is different for ARM and x86. > ARM {read,wrie}(l,q} function argument is pointer whereas X86 > {read,wrie}(l,q} function argument is address itself. I'm afraid I don't follow: x86 has #define readl(x) (*(volatile uint32_t *)(x)) #define readq(x) (*(volatile uint64_t *)(x)) That's no different from Arm64: #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) #define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32)__raw_readl(c)); __v; }) static inline u32 __raw_readl(const volatile void __iomem *addr) The difference is whether the address is expressed as a pointer, or _may_ also be expressed as unsigned long. IOW the x86 variant is perfectly fine to be passed e.g. a void * (preferably qualified appropriately). The conversion from unsigned long to a pointer type is actually expressed ... > @@ -170,31 +170,7 @@ bool vpci_msix_read(struct vpci_msix *msix, unsigned long addr, > return true; > > if ( VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, VPCI_MSIX_PBA) ) > - { > - /* > - * Access to PBA. > - * > - * TODO: note that this relies on having the PBA identity mapped to the > - * guest address space. If this changes the address will need to be > - * translated. > - */ > - switch ( len ) > - { > - case 4: > - *data = readl(addr); > - break; > - > - case 8: > - *data = readq(addr); > - break; > - > - default: > - ASSERT_UNREACHABLE(); > - break; > - } ... in the comment ahead of this switch() (and the assumption is likely wrong for DomU). But then, Roger: What "identity mapped" is meant here? Surely not GVA -> GPA, but rather GPA -> HPA? The address here is a guest physical one, but read{l,q}() act on (host) virtual addresses. This would have been easier to notice as wrong if read{l,q}() weren't allowing unsigned long arguments to be passed to them. Jan ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file 2022-02-24 15:18 ` Jan Beulich @ 2022-02-25 8:21 ` Roger Pau Monné 0 siblings, 0 replies; 23+ messages in thread From: Roger Pau Monné @ 2022-02-25 8:21 UTC (permalink / raw) To: Jan Beulich Cc: Rahul Singh, bertrand.marquis, Andrew Cooper, Wei Liu, xen-devel On Thu, Feb 24, 2022 at 04:18:31PM +0100, Jan Beulich wrote: > On 15.02.2022 16:25, Rahul Singh wrote: > > @@ -170,31 +170,7 @@ bool vpci_msix_read(struct vpci_msix *msix, unsigned long addr, > > return true; > > > > if ( VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, VPCI_MSIX_PBA) ) > > - { > > - /* > > - * Access to PBA. > > - * > > - * TODO: note that this relies on having the PBA identity mapped to the > > - * guest address space. If this changes the address will need to be > > - * translated. > > - */ > > - switch ( len ) > > - { > > - case 4: > > - *data = readl(addr); > > - break; > > - > > - case 8: > > - *data = readq(addr); > > - break; > > - > > - default: > > - ASSERT_UNREACHABLE(); > > - break; > > - } > > ... in the comment ahead of this switch() (and the assumption is likely > wrong for DomU). > > But then, Roger: What "identity mapped" is meant here? Surely not GVA -> > GPA, but rather GPA -> HPA? The address here is a guest physical one, > but read{l,q}() act on (host) virtual addresses. This would have been > easier to notice as wrong if read{l,q}() weren't allowing unsigned long > arguments to be passed to them. Urg, indeed, thanks for noticing. I will send a patch to fix this right now. Roger. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file 2022-02-15 15:25 ` [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file Rahul Singh 2022-02-24 15:18 ` Jan Beulich @ 2022-02-25 8:20 ` Roger Pau Monné 2022-02-28 12:23 ` Rahul Singh 1 sibling, 1 reply; 23+ messages in thread From: Roger Pau Monné @ 2022-02-25 8:20 UTC (permalink / raw) To: Rahul Singh Cc: xen-devel, bertrand.marquis, Jan Beulich, Andrew Cooper, Wei Liu On Tue, Feb 15, 2022 at 03:25:18PM +0000, Rahul Singh wrote: > {read,write}{l,q} function argument is different for ARM and x86. > ARM {read,wrie}(l,q} function argument is pointer whereas X86 > {read,wrie}(l,q} function argument is address itself. > > {read,write}{l,q} is only used in common file to access the MSI-X PBA > structure. To avoid impacting other x86 code and to make the code common > move the read/write call to MSI-X PBA to arch specific file. I think we agreed where going to unify {read,write}{l,q} so they could be used in arch-agnostic code? Thanks, Roger. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file 2022-02-25 8:20 ` Roger Pau Monné @ 2022-02-28 12:23 ` Rahul Singh 0 siblings, 0 replies; 23+ messages in thread From: Rahul Singh @ 2022-02-28 12:23 UTC (permalink / raw) To: Roger Pau Monné Cc: xen-devel, Bertrand Marquis, Jan Beulich, Andrew Cooper, Wei Liu Hi Roger, > On 25 Feb 2022, at 8:20 am, Roger Pau Monné <roger.pau@citrix.com> wrote: > > On Tue, Feb 15, 2022 at 03:25:18PM +0000, Rahul Singh wrote: >> {read,write}{l,q} function argument is different for ARM and x86. >> ARM {read,wrie}(l,q} function argument is pointer whereas X86 >> {read,wrie}(l,q} function argument is address itself. >> >> {read,write}{l,q} is only used in common file to access the MSI-X PBA >> structure. To avoid impacting other x86 code and to make the code common >> move the read/write call to MSI-X PBA to arch specific file. > > I think we agreed where going to unify {read,write}{l,q} so they could > be used in arch-agnostic code? We agreed to modify the vPCI MSIx code to use a pointer, but that not helped me to make code arch-agnostic. I decided to move the PBA handling code to an arch-specific file to make the code usable. Thanks for the series "vpci/msix: fix PBA acceses” series that will help to use the code for ARM arch also without any modification to {read,write}{l,q} . Regards, Rahul > > Thanks, Roger. > ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2022-03-10 15:54 UTC | newest] Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-02-15 15:25 [PATCH v2 0/3] xen/vpci: msix: Make VPCI MSI-X code non-x86 specific Rahul Singh 2022-02-15 15:25 ` [PATCH v2 1/3] xen/vpci: msix: move x86 specific code to x86 file Rahul Singh 2022-02-24 14:57 ` Jan Beulich 2022-03-01 13:34 ` Rahul Singh 2022-03-01 13:55 ` Jan Beulich 2022-03-03 16:31 ` Rahul Singh 2022-03-04 7:23 ` Jan Beulich 2022-03-09 10:08 ` Rahul Singh 2022-03-09 10:16 ` Roger Pau Monné 2022-03-09 10:47 ` Rahul Singh 2022-03-09 11:17 ` Roger Pau Monné 2022-03-09 10:17 ` Jan Beulich 2022-03-09 15:50 ` Rahul Singh 2022-03-09 15:53 ` Jan Beulich 2022-03-09 16:06 ` Roger Pau Monné 2022-03-10 11:48 ` Rahul Singh 2022-03-10 15:54 ` Roger Pau Monné 2022-02-15 15:25 ` [PATCH v2 2/3] xen/vpci: msix: change return value of vpci_msix_{read,write} Rahul Singh 2022-02-15 15:25 ` [PATCH v2 3/3] xen/vpci: msix: move read/write call to MSI-X PBA entry to arch file Rahul Singh 2022-02-24 15:18 ` Jan Beulich 2022-02-25 8:21 ` Roger Pau Monné 2022-02-25 8:20 ` Roger Pau Monné 2022-02-28 12:23 ` Rahul Singh
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.