All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Durrant <paul.durrant@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
	Paul Durrant <paul.durrant@citrix.com>,
	Keir Fraser <keir@xen.org>, Jan Beulich <jbeulich@suse.com>
Subject: [PATCH v3 08/18] x86/hvm: add length to mmio check op
Date: Tue, 23 Jun 2015 11:39:47 +0100	[thread overview]
Message-ID: <1435055997-30017-9-git-send-email-paul.durrant@citrix.com> (raw)
In-Reply-To: <1435055997-30017-1-git-send-email-paul.durrant@citrix.com>

When memory mapped I/O is range checked by internal handlers, the length
of the access should be taken into account.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/hpet.c                   |    7 ++++---
 xen/arch/x86/hvm/intercept.c              |    2 +-
 xen/arch/x86/hvm/vioapic.c                |   17 ++++++++++++++---
 xen/arch/x86/hvm/vlapic.c                 |    8 +++++---
 xen/arch/x86/hvm/vmsi.c                   |   27 ++++++++++++++++++++-------
 xen/drivers/passthrough/amd/iommu_guest.c |   18 +++++++++++++++---
 xen/include/asm-x86/hvm/io.h              |    4 +++-
 7 files changed, 62 insertions(+), 21 deletions(-)

diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c
index 8958873..1a1f239 100644
--- a/xen/arch/x86/hvm/hpet.c
+++ b/xen/arch/x86/hvm/hpet.c
@@ -498,10 +498,11 @@ static int hpet_write(
     return X86EMUL_OKAY;
 }
 
-static int hpet_range(struct vcpu *v, unsigned long addr)
+static int hpet_range(struct vcpu *v, unsigned long addr,
+                      unsigned long length)
 {
-    return ( (addr >= HPET_BASE_ADDRESS) &&
-             (addr < (HPET_BASE_ADDRESS + HPET_MMAP_SIZE)) );
+    return (addr >= HPET_BASE_ADDRESS) &&
+           ((addr + length) < (HPET_BASE_ADDRESS + HPET_MMAP_SIZE));
 }
 
 static const struct hvm_mmio_ops hpet_mmio_ops = {
diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c
index 4db024e..5e8d8b2 100644
--- a/xen/arch/x86/hvm/intercept.c
+++ b/xen/arch/x86/hvm/intercept.c
@@ -38,7 +38,7 @@ static bool_t hvm_mmio_accept(struct hvm_io_handler *handler,
 {
     BUG_ON(handler->type != IOREQ_TYPE_COPY);
 
-    return handler->u.mmio.ops->check(current, addr);
+    return handler->u.mmio.ops->check(current, addr, size);
 }
 
 static int hvm_mmio_read(struct hvm_io_handler *handler,
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 9ad909b..4a9b33e 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -242,12 +242,13 @@ static int vioapic_write(
     return X86EMUL_OKAY;
 }
 
-static int vioapic_range(struct vcpu *v, unsigned long addr)
+static int vioapic_range(struct vcpu *v, unsigned long addr,
+			 unsigned long length)
 {
     struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
 
-    return ((addr >= vioapic->base_address &&
-             (addr < vioapic->base_address + VIOAPIC_MEM_LENGTH)));
+    return (addr >= vioapic->base_address) &&
+           ((addr + length) <= (vioapic->base_address + VIOAPIC_MEM_LENGTH));
 }
 
 static const struct hvm_mmio_ops vioapic_mmio_ops = {
@@ -466,3 +467,13 @@ void vioapic_deinit(struct domain *d)
     xfree(d->arch.hvm_domain.vioapic);
     d->arch.hvm_domain.vioapic = NULL;
 }
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index f2052cf..7421fc5 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -986,14 +986,16 @@ int hvm_x2apic_msr_write(struct vcpu *v, unsigned int msr, uint64_t msr_content)
     return vlapic_reg_write(v, offset, (uint32_t)msr_content);
 }
 
-static int vlapic_range(struct vcpu *v, unsigned long addr)
+static int vlapic_range(struct vcpu *v, unsigned long address,
+                        unsigned long len)
 {
     struct vlapic *vlapic = vcpu_vlapic(v);
-    unsigned long offset  = addr - vlapic_base_address(vlapic);
+    unsigned long offset  = address - vlapic_base_address(vlapic);
 
     return !vlapic_hw_disabled(vlapic) &&
            !vlapic_x2apic_mode(vlapic) &&
-           (offset < PAGE_SIZE);
+           (address >= vlapic_base_address(vlapic)) &&
+           ((offset + len) <= PAGE_SIZE);
 }
 
 static const struct hvm_mmio_ops vlapic_mmio_ops = {
diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index 09ea301..61fe391 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -168,14 +168,14 @@ struct msixtbl_entry
 static DEFINE_RCU_READ_LOCK(msixtbl_rcu_lock);
 
 static struct msixtbl_entry *msixtbl_find_entry(
-    struct vcpu *v, unsigned long addr)
+    struct vcpu *v, unsigned long address, unsigned long len)
 {
     struct msixtbl_entry *entry;
     struct domain *d = v->domain;
 
     list_for_each_entry( entry, &d->arch.hvm_domain.msixtbl_list, list )
-        if ( addr >= entry->gtable &&
-             addr < entry->gtable + entry->table_len )
+        if ( (address >= entry->gtable) &&
+             ((address + len) <= (entry->gtable + entry->table_len)) )
             return entry;
 
     return NULL;
@@ -214,7 +214,7 @@ static int msixtbl_read(
 
     rcu_read_lock(&msixtbl_rcu_lock);
 
-    entry = msixtbl_find_entry(v, address);
+    entry = msixtbl_find_entry(v, address, len);
     if ( !entry )
         goto out;
     offset = address & (PCI_MSIX_ENTRY_SIZE - 1);
@@ -273,7 +273,7 @@ static int msixtbl_write(struct vcpu *v, unsigned long address,
 
     rcu_read_lock(&msixtbl_rcu_lock);
 
-    entry = msixtbl_find_entry(v, address);
+    entry = msixtbl_find_entry(v, address, len);
     if ( !entry )
         goto out;
     nr_entry = (address - entry->gtable) / PCI_MSIX_ENTRY_SIZE;
@@ -333,12 +333,15 @@ out:
     return r;
 }
 
-static int msixtbl_range(struct vcpu *v, unsigned long addr)
+static int msixtbl_range(struct vcpu *v, unsigned long address,
+                         unsigned long len)
 {
+    struct msixtbl_entry *entry;
     const struct msi_desc *desc;
 
     rcu_read_lock(&msixtbl_rcu_lock);
-    desc = msixtbl_addr_to_desc(msixtbl_find_entry(v, addr), addr);
+    entry = msixtbl_find_entry(v, address, len);
+    desc = msixtbl_addr_to_desc(entry, address);
     rcu_read_unlock(&msixtbl_rcu_lock);
 
     return !!desc;
@@ -514,3 +517,13 @@ void msix_write_completion(struct vcpu *v)
     if ( msixtbl_write(v, ctrl_address, 4, 0) != X86EMUL_OKAY )
         gdprintk(XENLOG_WARNING, "MSI-X write completion failure\n");
 }
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/drivers/passthrough/amd/iommu_guest.c b/xen/drivers/passthrough/amd/iommu_guest.c
index 9c3c488..dd84281 100644
--- a/xen/drivers/passthrough/amd/iommu_guest.c
+++ b/xen/drivers/passthrough/amd/iommu_guest.c
@@ -868,12 +868,14 @@ static void guest_iommu_reg_init(struct guest_iommu *iommu)
     iommu->reg_ext_feature.hi = upper;
 }
 
-static int guest_iommu_mmio_range(struct vcpu *v, unsigned long addr)
+static int guest_iommu_mmio_range(struct vcpu *v, unsigned long addr,
+                                  unsigned long length)
 {
     struct guest_iommu *iommu = vcpu_iommu(v);
 
-    return iommu && addr >= iommu->mmio_base &&
-           addr < iommu->mmio_base + IOMMU_MMIO_SIZE;
+    return iommu &&
+           (addr >= iommu->mmio_base) &&
+           ((addr + length) <= (iommu->mmio_base + IOMMU_MMIO_SIZE));
 }
 
 static const struct hvm_mmio_ops iommu_mmio_ops = {
@@ -926,3 +928,13 @@ void guest_iommu_destroy(struct domain *d)
 
     domain_hvm_iommu(d)->arch.g_iommu = NULL;
 }
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h
index fecd02d..b4596fc 100644
--- a/xen/include/asm-x86/hvm/io.h
+++ b/xen/include/asm-x86/hvm/io.h
@@ -35,7 +35,9 @@ typedef int (*hvm_mmio_write_t)(struct vcpu *v,
                                 unsigned long addr,
                                 unsigned long length,
                                 unsigned long val);
-typedef int (*hvm_mmio_check_t)(struct vcpu *v, unsigned long addr);
+typedef int (*hvm_mmio_check_t)(struct vcpu *v,
+                                unsigned long addr,
+                                unsigned long length);
 
 struct hvm_mmio_ops {
     hvm_mmio_check_t check;
-- 
1.7.10.4

  parent reply	other threads:[~2015-06-23 10:40 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-23 10:39 [PATCH v3 00/18] x86/hvm: I/O emulation cleanup and fix Paul Durrant
2015-06-23 10:39 ` [PATCH v3 01/18] x86/hvm: simplify hvmemul_do_io() Paul Durrant
2015-06-23 10:39 ` [PATCH v3 02/18] x86/hvm: remove hvm_io_pending() check in hvmemul_do_io() Paul Durrant
2015-06-23 10:39 ` [PATCH v3 03/18] x86/hvm: remove extraneous parameter from hvmtrace_io_assist() Paul Durrant
2015-06-23 10:39 ` [PATCH v3 04/18] x86/hvm: make sure translated MMIO reads or writes fall within a page Paul Durrant
2015-06-23 15:52   ` Jan Beulich
2015-06-23 16:13     ` Paul Durrant
2015-06-23 16:21       ` Jan Beulich
2015-06-23 16:32         ` Paul Durrant
2015-06-24  7:38           ` Jan Beulich
2015-06-23 10:39 ` [PATCH v3 05/18] x86/hvm: remove multiple open coded 'chunking' loops Paul Durrant
2015-06-24  9:38   ` Jan Beulich
2015-06-24 10:10     ` Paul Durrant
2015-06-24 10:27       ` Jan Beulich
2015-06-23 10:39 ` [PATCH v3 06/18] x86/hvm: re-name struct hvm_mmio_handler to hvm_mmio_ops Paul Durrant
2015-06-23 10:39 ` [PATCH v3 07/18] x86/hvm: unify internal portio and mmio intercepts Paul Durrant
2015-06-24 12:07   ` Jan Beulich
2015-06-23 10:39 ` Paul Durrant [this message]
2015-06-23 10:39 ` [PATCH v3 09/18] x86/hvm: unify dpci portio intercept with standard portio intercept Paul Durrant
2015-06-23 10:39 ` [PATCH v3 10/18] x86/hvm: unify stdvga mmio intercept with standard mmio intercept Paul Durrant
2015-06-23 10:39 ` [PATCH v3 11/18] x86/hvm: revert 82ed8716b "fix direct PCI port I/O emulation retry Paul Durrant
2015-06-23 10:39 ` [PATCH v3 12/18] x86/hvm: only call hvm_io_assist() from hvm_wait_for_io() Paul Durrant
2015-06-23 10:39 ` [PATCH v3 13/18] x86/hvm: split I/O completion handling from state model Paul Durrant
2015-06-23 10:39 ` [PATCH v3 14/18] x86/hvm: remove HVMIO_dispatched I/O state Paul Durrant
2015-06-23 10:39 ` [PATCH v3 15/18] x86/hvm: remove hvm_io_state enumeration Paul Durrant
2015-06-23 10:39 ` [PATCH v3 16/18] x86/hvm: use ioreq_t to track in-flight state Paul Durrant
2015-06-23 10:39 ` [PATCH v3 17/18] x86/hvm: always re-emulate I/O from a buffer Paul Durrant
2015-06-23 10:39 ` [PATCH v3 18/18] x86/hvm: track large memory mapped accesses by buffer offset Paul Durrant
2015-06-23 14:47 ` [PATCH v3 00/18] x86/hvm: I/O emulation cleanup and fix Fabio Fantoni

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1435055997-30017-9-git-send-email-paul.durrant@citrix.com \
    --to=paul.durrant@citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=keir@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.