|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V3 29/29] x86/vvtd: save and restore emulated VT-d
From: Chao Gao <chao.gao@xxxxxxxxx>
Provide a save-restore pair to save/restore registers and non-register
status.
Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx>
Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx>
---
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;
+ }
+
+ 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__ */
--
1.8.3.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |