[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/vMSI-X: also snoop REP MOVS
commit 854c6aab46dec23573ca7dc1a4a03674d2ec63d5 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Fri Apr 29 18:28:41 2016 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Fri Apr 29 18:28:41 2016 +0200 x86/vMSI-X: also snoop REP MOVS ... as at least certain versions of Windows use such to update the MSI-X table. However, to not overly complicate the logic for now - only EFLAGS.DF=0 is being handled, - only updates not crossing MSI-X table entry boundaries are handled. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Paul Durrant <paul.durrant@xxxxxxxxxx> Release-acked-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- xen/arch/x86/hvm/vmsi.c | 46 +++++++++++++++++++++++++++++++++++++++++- xen/include/asm-x86/hvm/vcpu.h | 1 + 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c index d72c568..0066be5 100644 --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -351,9 +351,10 @@ static int msixtbl_range(struct vcpu *v, unsigned long addr) ASSERT(r->type == IOREQ_TYPE_COPY); if ( r->dir == IOREQ_WRITE ) { + unsigned int size = r->size; + if ( !r->data_is_ptr ) { - unsigned int size = r->size; uint64_t data = r->data; if ( size == 8 ) @@ -366,7 +367,29 @@ static int msixtbl_range(struct vcpu *v, unsigned long addr) ((addr & (PCI_MSIX_ENTRY_SIZE - 1)) == PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET) && !(data & PCI_MSIX_VECTOR_BITMASK) ) + { v->arch.hvm_vcpu.hvm_io.msix_snoop_address = addr; + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa = 0; + } + } + else if ( (size == 4 || size == 8) && + /* Only support forward REP MOVS for now. */ + !r->df && + /* + * Only fully support accesses to a single table entry for + * now (if multiple ones get written to in one go, only the + * final one gets dealt with). + */ + r->count && r->count <= PCI_MSIX_ENTRY_SIZE / size && + !((addr + (size * r->count)) & (PCI_MSIX_ENTRY_SIZE - 1)) ) + { + BUILD_BUG_ON((PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET + 4) & + (PCI_MSIX_ENTRY_SIZE - 1)); + + v->arch.hvm_vcpu.hvm_io.msix_snoop_address = + addr + size * r->count - 4; + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa = + r->data + size * r->count - 4; } } @@ -471,6 +494,7 @@ out: for_each_vcpu ( d, v ) { if ( (v->pause_flags & VPF_blocked_in_xen) && + !v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa && v->arch.hvm_vcpu.hvm_io.msix_snoop_address == (gtable + msi_desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + @@ -561,9 +585,29 @@ void msixtbl_pt_cleanup(struct domain *d) void msix_write_completion(struct vcpu *v) { unsigned long ctrl_address = v->arch.hvm_vcpu.hvm_io.msix_unmask_address; + unsigned long snoop_addr = v->arch.hvm_vcpu.hvm_io.msix_snoop_address; v->arch.hvm_vcpu.hvm_io.msix_snoop_address = 0; + if ( !ctrl_address && snoop_addr && + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa ) + { + const struct msi_desc *desc; + uint32_t data; + + rcu_read_lock(&msixtbl_rcu_lock); + desc = msixtbl_addr_to_desc(msixtbl_find_entry(v, snoop_addr), + snoop_addr); + rcu_read_unlock(&msixtbl_rcu_lock); + + if ( desc && + hvm_copy_from_guest_phys(&data, + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa, + sizeof(data)) == HVMCOPY_okay && + !(data & PCI_MSIX_VECTOR_BITMASK) ) + ctrl_address = snoop_addr; + } + if ( !ctrl_address ) return; diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h index 06778eb..8a4a92f 100644 --- a/xen/include/asm-x86/hvm/vcpu.h +++ b/xen/include/asm-x86/hvm/vcpu.h @@ -86,6 +86,7 @@ struct hvm_vcpu_io { unsigned long msix_unmask_address; unsigned long msix_snoop_address; + unsigned long msix_snoop_gpa; const struct g2m_ioport *g2m_ioport; }; -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |