Message ID | 1506049330-11196-30-git-send-email-tianyu.lan@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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 --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__ */