diff mbox

[V3,29/29] x86/vvtd: save and restore emulated VT-d

Message ID 1506049330-11196-30-git-send-email-tianyu.lan@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

lan,Tianyu Sept. 22, 2017, 3:02 a.m. UTC
From: Chao Gao <chao.gao@intel.com>

Provide a save-restore pair to save/restore registers and non-register
status.

Signed-off-by: Chao Gao <chao.gao@intel.com>
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
---
v3:
 - use one entry to save both vvtd registers and other intermediate
 state
---
 xen/drivers/passthrough/vtd/vvtd.c     | 66 ++++++++++++++++++++++++++--------
 xen/include/public/arch-x86/hvm/save.h | 25 ++++++++++++-
 2 files changed, 76 insertions(+), 15 deletions(-)

Comments

Roger Pau Monné Oct. 20, 2017, 11:25 a.m. UTC | #1
On Thu, Sep 21, 2017 at 11:02:10PM -0400, Lan Tianyu wrote:
> From: Chao Gao <chao.gao@intel.com>
> 
> Provide a save-restore pair to save/restore registers and non-register
> status.
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
> ---
> v3:
>  - use one entry to save both vvtd registers and other intermediate
>  state
> ---
>  xen/drivers/passthrough/vtd/vvtd.c     | 66 ++++++++++++++++++++++++++--------
>  xen/include/public/arch-x86/hvm/save.h | 25 ++++++++++++-
>  2 files changed, 76 insertions(+), 15 deletions(-)
> 
> diff --git a/xen/drivers/passthrough/vtd/vvtd.c b/xen/drivers/passthrough/vtd/vvtd.c
> index 668d0c9..2aecd93 100644
> --- a/xen/drivers/passthrough/vtd/vvtd.c
> +++ b/xen/drivers/passthrough/vtd/vvtd.c
> @@ -28,11 +28,13 @@
>  #include <asm/current.h>
>  #include <asm/event.h>
>  #include <asm/hvm/domain.h>
> +#include <asm/hvm/save.h>
>  #include <asm/hvm/support.h>
>  #include <asm/io_apic.h>
>  #include <asm/page.h>
>  #include <asm/p2m.h>
>  #include <asm/viommu.h>
> +#include <public/hvm/save.h>
>  
>  #include "iommu.h"
>  #include "vtd.h"
> @@ -40,20 +42,6 @@
>  /* Supported capabilities by vvtd */
>  unsigned int vvtd_caps = VIOMMU_CAP_IRQ_REMAPPING;
>  
> -struct hvm_hw_vvtd_status {
> -    uint32_t eim_enabled : 1,
> -             intremap_enabled : 1;
> -    uint32_t fault_index;
> -    uint32_t irt_max_entry;
> -    /* Interrupt remapping table base gfn */
> -    uint64_t irt;
> -};
> -
> -union hvm_hw_vvtd_regs {
> -    uint32_t data32[256];
> -    uint64_t data64[128];
> -};
> -
>  struct vvtd {
>      /* Address range of remapping hardware register-set */
>      uint64_t base_addr;
> @@ -1057,6 +1045,56 @@ static bool vvtd_is_remapping(struct domain *d,
>      return 0;
>  }
>  
> +static int vvtd_load(struct domain *d, hvm_domain_context_t *h)
> +{
> +    struct hvm_hw_vvtd *hw_vvtd;
> +
> +    if ( !domain_vvtd(d) )
> +        return -ENODEV;
> +
> +    hw_vvtd = xmalloc(struct hvm_hw_vvtd);
> +    if ( !hw_vvtd )
> +        return -ENOMEM;
> +
> +    if ( hvm_load_entry(VVTD, h, hw_vvtd) )
> +    {
> +        xfree(hw_vvtd);
> +        return -EINVAL;
> +    }

If you declare hvm_hw_vvtd_regs as a field inside of
hvm_hw_vvtd_status you won't need to do this alloc + memcpy, bnecause
you could directly load it to domain_vvtd.

In any case, I think the code here is going to change due to all the
other comments on the previous patches.

Thanks, Roger.
diff mbox

Patch

diff --git a/xen/drivers/passthrough/vtd/vvtd.c b/xen/drivers/passthrough/vtd/vvtd.c
index 668d0c9..2aecd93 100644
--- a/xen/drivers/passthrough/vtd/vvtd.c
+++ b/xen/drivers/passthrough/vtd/vvtd.c
@@ -28,11 +28,13 @@ 
 #include <asm/current.h>
 #include <asm/event.h>
 #include <asm/hvm/domain.h>
+#include <asm/hvm/save.h>
 #include <asm/hvm/support.h>
 #include <asm/io_apic.h>
 #include <asm/page.h>
 #include <asm/p2m.h>
 #include <asm/viommu.h>
+#include <public/hvm/save.h>
 
 #include "iommu.h"
 #include "vtd.h"
@@ -40,20 +42,6 @@ 
 /* Supported capabilities by vvtd */
 unsigned int vvtd_caps = VIOMMU_CAP_IRQ_REMAPPING;
 
-struct hvm_hw_vvtd_status {
-    uint32_t eim_enabled : 1,
-             intremap_enabled : 1;
-    uint32_t fault_index;
-    uint32_t irt_max_entry;
-    /* Interrupt remapping table base gfn */
-    uint64_t irt;
-};
-
-union hvm_hw_vvtd_regs {
-    uint32_t data32[256];
-    uint64_t data64[128];
-};
-
 struct vvtd {
     /* Address range of remapping hardware register-set */
     uint64_t base_addr;
@@ -1057,6 +1045,56 @@  static bool vvtd_is_remapping(struct domain *d,
     return 0;
 }
 
+static int vvtd_load(struct domain *d, hvm_domain_context_t *h)
+{
+    struct hvm_hw_vvtd *hw_vvtd;
+
+    if ( !domain_vvtd(d) )
+        return -ENODEV;
+
+    hw_vvtd = xmalloc(struct hvm_hw_vvtd);
+    if ( !hw_vvtd )
+        return -ENOMEM;
+
+    if ( hvm_load_entry(VVTD, h, hw_vvtd) )
+    {
+        xfree(hw_vvtd);
+        return -EINVAL;
+    }
+
+    memcpy(&domain_vvtd(d)->status, &hw_vvtd->status,
+           sizeof(struct hvm_hw_vvtd_status));
+    memcpy(domain_vvtd(d)->regs, &hw_vvtd->regs,
+           sizeof(union hvm_hw_vvtd_regs));
+    xfree(hw_vvtd);
+
+    return 0;
+}
+
+static int vvtd_save(struct domain *d, hvm_domain_context_t *h)
+{
+    struct hvm_hw_vvtd *hw_vvtd;
+    int ret;
+
+    if ( !domain_vvtd(d) )
+        return 0;
+
+    hw_vvtd = xmalloc(struct hvm_hw_vvtd);
+    if ( !hw_vvtd )
+        return -ENOMEM;
+
+    memcpy(&hw_vvtd->status, &domain_vvtd(d)->status,
+           sizeof(struct hvm_hw_vvtd_status));
+    memcpy(&hw_vvtd->regs, domain_vvtd(d)->regs,
+           sizeof(union hvm_hw_vvtd_regs));
+    ret = hvm_save_entry(VVTD, 0, h, hw_vvtd);
+    xfree(hw_vvtd);
+
+    return ret;
+}
+
+HVM_REGISTER_SAVE_RESTORE(VVTD, vvtd_save, vvtd_load, 1, HVMSR_PER_DOM);
+
 static void vvtd_reset(struct vvtd *vvtd, uint64_t capability)
 {
     uint64_t cap = cap_set_num_fault_regs(1ULL) |
diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/arch-x86/hvm/save.h
index fd7bf3f..181abb2 100644
--- a/xen/include/public/arch-x86/hvm/save.h
+++ b/xen/include/public/arch-x86/hvm/save.h
@@ -639,10 +639,33 @@  struct hvm_msr {
 
 #define CPU_MSR_CODE  20
 
+union hvm_hw_vvtd_regs {
+    uint32_t data32[256];
+    uint64_t data64[128];
+};
+
+struct hvm_hw_vvtd_status
+{
+    uint32_t eim_enabled : 1,
+             intremap_enabled : 1;
+    uint32_t fault_index;
+    uint32_t irt_max_entry;
+    /* Interrupt remapping table base gfn */
+    uint64_t irt;
+};
+
+struct hvm_hw_vvtd
+{
+    union hvm_hw_vvtd_regs regs;
+    struct hvm_hw_vvtd_status status;
+};
+
+DECLARE_HVM_SAVE_TYPE(VVTD, 21, struct hvm_hw_vvtd);
+
 /* 
  * Largest type-code in use
  */
-#define HVM_SAVE_CODE_MAX 20
+#define HVM_SAVE_CODE_MAX 21
 
 #endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */