[Qemu-devel] [PATCH v2 2/2] Xen: Use the ioreq-server API when available

2014-10-13 Thread Paul Durrant
The ioreq-server API added to Xen 4.5 offers better security than
the existing Xen/QEMU interface because the shared pages that are
used to pass emulation request/results back and forth are removed
from the guest's memory space before any requests are serviced.
This prevents the guest from mapping these pages (they are in a
well known location) and attempting to attack QEMU by synthesizing
its own request structures. Hence, this patch modifies configure
to detect whether the API is available, and adds the necessary
code to use the API if it is.

Signed-off-by: Paul Durrant paul.durr...@citrix.com
Cc: Stefano Stabellini stefano.stabell...@eu.citrix.com
Cc: Peter Maydell peter.mayd...@linaro.org
Cc: Paolo Bonzini pbonz...@redhat.com
Cc: Michael Tokarev m...@tls.msk.ru
Cc: Stefan Hajnoczi stefa...@redhat.com
Cc: Stefan Weil s...@weilnetz.de
Cc: Olaf Hering o...@aepfle.de
Cc: Gerd Hoffmann kra...@redhat.com
Cc: Alexey Kardashevskiy a...@ozlabs.ru
Cc: Alexander Graf ag...@suse.de
---
 configure   |   29 ++
 include/hw/xen/xen_common.h |  222 +++
 trace-events|8 ++
 xen-hvm.c   |  163 +++
 4 files changed, 403 insertions(+), 19 deletions(-)

diff --git a/configure b/configure
index 9ac2600..c2db574 100755
--- a/configure
+++ b/configure
@@ -1876,6 +1876,32 @@ int main(void) {
   xc_gnttab_open(NULL, 0);
   xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
   xc_hvm_inject_msi(xc, 0, 0xf000, 0x);
+  xc_hvm_create_ioreq_server(xc, 0, 0, NULL);
+  return 0;
+}
+EOF
+  compile_prog  $xen_libs
+then
+xen_ctrl_version=450
+xen=yes
+
+  elif
+  cat  $TMPC EOF 
+#include xenctrl.h
+#include xenstore.h
+#include stdint.h
+#include xen/hvm/hvm_info_table.h
+#if !defined(HVM_MAX_VCPUS)
+# error HVM_MAX_VCPUS not defined
+#endif
+int main(void) {
+  xc_interface *xc;
+  xs_daemon_open();
+  xc = xc_interface_open(0, 0, 0);
+  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  xc_gnttab_open(NULL, 0);
+  xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
+  xc_hvm_inject_msi(xc, 0, 0xf000, 0x);
   return 0;
 }
 EOF
@@ -4282,6 +4308,9 @@ if test -n $sparc_cpu; then
 echo Target Sparc Arch $sparc_cpu
 fi
 echo xen support   $xen
+if test $xen = yes ; then
+  echo xen ctrl version  $xen_ctrl_version
+fi
 echo brlapi support$brlapi
 echo bluez  support$bluez
 echo Documentation $docs
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index 07731b9..7040506 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -16,7 +16,9 @@
 
 #include hw/hw.h
 #include hw/xen/xen.h
+#include hw/pci/pci.h
 #include qemu/queue.h
+#include trace.h
 
 /*
  * We don't support Xen prior to 3.3.0.
@@ -164,4 +166,224 @@ void destroy_hvm_domain(bool reboot);
 /* shutdown/destroy current domain because of an error */
 void xen_shutdown_fatal_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 
+/* Xen before 4.5 */
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION  450
+
+#ifndef HVM_PARAM_BUFIOREQ_EVTCHN
+#define HVM_PARAM_BUFIOREQ_EVTCHN 26
+#endif
+
+#define IOREQ_TYPE_PCI_CONFIG 2
+
+typedef uint32_t ioservid_t;
+
+static inline void xen_map_memory_section(XenXC xc, domid_t dom,
+  ioservid_t ioservid,
+  MemoryRegionSection *section)
+{
+}
+
+static inline void xen_unmap_memory_section(XenXC xc, domid_t dom,
+ioservid_t ioservid,
+MemoryRegionSection *section)
+{
+}
+
+static inline void xen_map_io_section(XenXC xc, domid_t dom,
+  ioservid_t ioservid,
+  MemoryRegionSection *section)
+{
+}
+
+static inline void xen_unmap_io_section(XenXC xc, domid_t dom,
+ioservid_t ioservid,
+MemoryRegionSection *section)
+{
+}
+
+static inline void xen_map_pcidev(XenXC xc, domid_t dom,
+  ioservid_t ioservid,
+  PCIDevice *pci_dev)
+{
+}
+
+static inline void xen_unmap_pcidev(XenXC xc, domid_t dom,
+ioservid_t ioservid,
+PCIDevice *pci_dev)
+{
+}
+
+static inline int xen_create_ioreq_server(XenXC xc, domid_t dom,
+  ioservid_t *ioservid)
+{
+return 0;
+}
+
+static inline void xen_destroy_ioreq_server(XenXC xc, domid_t dom,
+ioservid_t ioservid)
+{
+}
+
+static inline int xen_get_ioreq_server_info(XenXC xc, domid_t dom,
+ioservid_t ioservid,
+xen_pfn_t *ioreq_pfn,
+xen_pfn_t 

Re: [Qemu-devel] [PATCH v2 2/2] Xen: Use the ioreq-server API when available

2014-10-13 Thread Stefano Stabellini
On Mon, 13 Oct 2014, Paul Durrant wrote:
 The ioreq-server API added to Xen 4.5 offers better security than
 the existing Xen/QEMU interface because the shared pages that are
 used to pass emulation request/results back and forth are removed
 from the guest's memory space before any requests are serviced.
 This prevents the guest from mapping these pages (they are in a
 well known location) and attempting to attack QEMU by synthesizing
 its own request structures. Hence, this patch modifies configure
 to detect whether the API is available, and adds the necessary
 code to use the API if it is.
 
 Signed-off-by: Paul Durrant paul.durr...@citrix.com

I think the patch is pretty good, just one comment below.


 Cc: Stefano Stabellini stefano.stabell...@eu.citrix.com
 Cc: Peter Maydell peter.mayd...@linaro.org
 Cc: Paolo Bonzini pbonz...@redhat.com
 Cc: Michael Tokarev m...@tls.msk.ru
 Cc: Stefan Hajnoczi stefa...@redhat.com
 Cc: Stefan Weil s...@weilnetz.de
 Cc: Olaf Hering o...@aepfle.de
 Cc: Gerd Hoffmann kra...@redhat.com
 Cc: Alexey Kardashevskiy a...@ozlabs.ru
 Cc: Alexander Graf ag...@suse.de
 ---
  configure   |   29 ++
  include/hw/xen/xen_common.h |  222 
 +++
  trace-events|8 ++
  xen-hvm.c   |  163 +++
  4 files changed, 403 insertions(+), 19 deletions(-)
 
 diff --git a/configure b/configure
 index 9ac2600..c2db574 100755
 --- a/configure
 +++ b/configure
 @@ -1876,6 +1876,32 @@ int main(void) {
xc_gnttab_open(NULL, 0);
xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
xc_hvm_inject_msi(xc, 0, 0xf000, 0x);
 +  xc_hvm_create_ioreq_server(xc, 0, 0, NULL);
 +  return 0;
 +}
 +EOF
 +  compile_prog  $xen_libs
 +then
 +xen_ctrl_version=450
 +xen=yes
 +
 +  elif
 +  cat  $TMPC EOF 
 +#include xenctrl.h
 +#include xenstore.h
 +#include stdint.h
 +#include xen/hvm/hvm_info_table.h
 +#if !defined(HVM_MAX_VCPUS)
 +# error HVM_MAX_VCPUS not defined
 +#endif
 +int main(void) {
 +  xc_interface *xc;
 +  xs_daemon_open();
 +  xc = xc_interface_open(0, 0, 0);
 +  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
 +  xc_gnttab_open(NULL, 0);
 +  xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
 +  xc_hvm_inject_msi(xc, 0, 0xf000, 0x);
return 0;
  }
  EOF
 @@ -4282,6 +4308,9 @@ if test -n $sparc_cpu; then
  echo Target Sparc Arch $sparc_cpu
  fi
  echo xen support   $xen
 +if test $xen = yes ; then
 +  echo xen ctrl version  $xen_ctrl_version
 +fi
  echo brlapi support$brlapi
  echo bluez  support$bluez
  echo Documentation $docs
 diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
 index 07731b9..7040506 100644
 --- a/include/hw/xen/xen_common.h
 +++ b/include/hw/xen/xen_common.h
 @@ -16,7 +16,9 @@
  
  #include hw/hw.h
  #include hw/xen/xen.h
 +#include hw/pci/pci.h
  #include qemu/queue.h
 +#include trace.h
  
  /*
   * We don't support Xen prior to 3.3.0.
 @@ -164,4 +166,224 @@ void destroy_hvm_domain(bool reboot);
  /* shutdown/destroy current domain because of an error */
  void xen_shutdown_fatal_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
  
 +/* Xen before 4.5 */
 +#if CONFIG_XEN_CTRL_INTERFACE_VERSION  450
 +
 +#ifndef HVM_PARAM_BUFIOREQ_EVTCHN
 +#define HVM_PARAM_BUFIOREQ_EVTCHN 26
 +#endif
 +
 +#define IOREQ_TYPE_PCI_CONFIG 2
 +
 +typedef uint32_t ioservid_t;
 +
 +static inline void xen_map_memory_section(XenXC xc, domid_t dom,
 +  ioservid_t ioservid,
 +  MemoryRegionSection *section)
 +{
 +}
 +
 +static inline void xen_unmap_memory_section(XenXC xc, domid_t dom,
 +ioservid_t ioservid,
 +MemoryRegionSection *section)
 +{
 +}
 +
 +static inline void xen_map_io_section(XenXC xc, domid_t dom,
 +  ioservid_t ioservid,
 +  MemoryRegionSection *section)
 +{
 +}
 +
 +static inline void xen_unmap_io_section(XenXC xc, domid_t dom,
 +ioservid_t ioservid,
 +MemoryRegionSection *section)
 +{
 +}
 +
 +static inline void xen_map_pcidev(XenXC xc, domid_t dom,
 +  ioservid_t ioservid,
 +  PCIDevice *pci_dev)
 +{
 +}
 +
 +static inline void xen_unmap_pcidev(XenXC xc, domid_t dom,
 +ioservid_t ioservid,
 +PCIDevice *pci_dev)
 +{
 +}
 +
 +static inline int xen_create_ioreq_server(XenXC xc, domid_t dom,
 +  ioservid_t *ioservid)
 +{
 +return 0;
 +}
 +
 +static inline void xen_destroy_ioreq_server(XenXC xc, domid_t dom,
 +ioservid_t ioservid)
 +{
 +}
 +
 

Re: [Qemu-devel] [PATCH v2 2/2] Xen: Use the ioreq-server API when available

2014-10-13 Thread Paul Durrant
 -Original Message-
 From: Stefano Stabellini [mailto:stefano.stabell...@eu.citrix.com]
 Sent: 13 October 2014 16:53
 To: Paul Durrant
 Cc: qemu-devel@nongnu.org; xen-de...@lists.xenproject.org; Stefano
 Stabellini; Peter Maydell; Paolo Bonzini; Michael Tokarev; Stefan Hajnoczi;
 Stefan Weil; Olaf Hering; Gerd Hoffmann; Alexey Kardashevskiy; Alexander
 Graf
 Subject: Re: [PATCH v2 2/2] Xen: Use the ioreq-server API when available
 
 On Mon, 13 Oct 2014, Paul Durrant wrote:
  The ioreq-server API added to Xen 4.5 offers better security than
  the existing Xen/QEMU interface because the shared pages that are
  used to pass emulation request/results back and forth are removed
  from the guest's memory space before any requests are serviced.
  This prevents the guest from mapping these pages (they are in a
  well known location) and attempting to attack QEMU by synthesizing
  its own request structures. Hence, this patch modifies configure
  to detect whether the API is available, and adds the necessary
  code to use the API if it is.
 
  Signed-off-by: Paul Durrant paul.durr...@citrix.com
 
 I think the patch is pretty good, just one comment below.
 
[snip]
  @@ -487,9 +494,52 @@ static void xen_region_del(MemoryListener
 *listener,
  MemoryRegionSection *section)
   {
   xen_set_memory(listener, section, false);
  +
  +if (section-mr != ram_memory) {
  +XenIOState *state = container_of(listener, XenIOState,
 memory_listener);
  +
  +xen_unmap_memory_section(xen_xc, xen_domid, state-ioservid,
 section);
  +}
  +
   memory_region_unref(section-mr);
   }
 
 I would prefer if you could move the xen_unmap_memory_section and
 xen_map_memory_section calls to xen_set_memory, where we already
 have a
 ram_memory check. Could you reuse it?
 

Sure, I can do that.

  Paul