This patch adds the old value param and the onchangeonly option
to the VM_EVENT_REASON_MOV_TO_MSR event.
The param was added to the vm_event_mov_to_msr struct and to the
hvm_monitor_msr function. Finally I've changed the bool_t param
to a bool for the hvm_msr_write_intercept function.
Signed-off-by: Alexandru Isaila
Acked-by: Tamas K Lengyel
---
Changes since V1:
- Removed Stray blanks inside the inner parentheses
- Added space after the if statement
- Added * 8 to the set/clear/test_bit statements
- Removed the blank line after monitored_msr.
---
tools/libxc/include/xenctrl.h | 2 +-
tools/libxc/xc_monitor.c | 3 ++-
xen/arch/x86/hvm/hvm.c| 10 --
xen/arch/x86/hvm/monitor.c| 9 ++---
xen/arch/x86/monitor.c| 26 +++---
xen/include/asm-x86/hvm/monitor.h | 2 +-
xen/include/asm-x86/hvm/support.h | 2 +-
xen/include/asm-x86/monitor.h | 1 +
xen/include/public/domctl.h | 2 ++
xen/include/public/vm_event.h | 5 +++--
10 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 3bcab3c..b99d6eb 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2048,7 +2048,7 @@ int xc_monitor_write_ctrlreg(xc_interface *xch, domid_t
domain_id,
* non-architectural indices.
*/
int xc_monitor_mov_to_msr(xc_interface *xch, domid_t domain_id, uint32_t msr,
- bool enable);
+ bool enable, bool onchangeonly);
int xc_monitor_singlestep(xc_interface *xch, domid_t domain_id, bool enable);
int xc_monitor_software_breakpoint(xc_interface *xch, domid_t domain_id,
bool enable);
diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index 6046680..09d04be 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -90,7 +90,7 @@ int xc_monitor_write_ctrlreg(xc_interface *xch, domid_t
domain_id,
}
int xc_monitor_mov_to_msr(xc_interface *xch, domid_t domain_id, uint32_t msr,
- bool enable)
+ bool enable, bool onchangeonly)
{
DECLARE_DOMCTL;
@@ -100,6 +100,7 @@ int xc_monitor_mov_to_msr(xc_interface *xch, domid_t
domain_id, uint32_t msr,
: XEN_DOMCTL_MONITOR_OP_DISABLE;
domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR;
domctl.u.monitor_op.u.mov_to_msr.msr = msr;
+domctl.u.monitor_op.u.mov_to_msr.onchangeonly = onchangeonly;
return do_domctl(xch, );
}
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 205b4cb..0238787 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3489,7 +3489,7 @@ int hvm_msr_read_intercept(unsigned int msr, uint64_t
*msr_content)
}
int hvm_msr_write_intercept(unsigned int msr, uint64_t msr_content,
-bool_t may_defer)
+bool may_defer)
{
struct vcpu *v = current;
struct domain *d = v->domain;
@@ -3500,6 +3500,12 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t
msr_content,
if ( may_defer && unlikely(monitored_msr(v->domain, msr)) )
{
+uint64_t msr_old_content;
+
+ret = hvm_msr_read_intercept(msr, _old_content);
+if ( ret != X86EMUL_OKAY )
+return ret;
+
ASSERT(v->arch.vm_event);
/* The actual write will occur in hvm_do_resume() (if permitted). */
@@ -3507,7 +3513,7 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t
msr_content,
v->arch.vm_event->write_data.msr = msr;
v->arch.vm_event->write_data.value = msr_content;
-hvm_monitor_msr(msr, msr_content);
+hvm_monitor_msr(msr, msr_content, msr_old_content);
return X86EMUL_OKAY;
}
diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c
index 4ce778c..131b852 100644
--- a/xen/arch/x86/hvm/monitor.c
+++ b/xen/arch/x86/hvm/monitor.c
@@ -74,16 +74,19 @@ bool hvm_monitor_emul_unimplemented(void)
monitor_traps(curr, true, ) == 1;
}
-void hvm_monitor_msr(unsigned int msr, uint64_t value)
+void hvm_monitor_msr(unsigned int msr, uint64_t new_value, uint64_t old_value)
{
struct vcpu *curr = current;
-if ( monitored_msr(curr->domain, msr) )
+if ( monitored_msr(curr->domain, msr) &&
+ (!monitored_msr_onchangeonly(curr->domain, msr) ||
+ new_value != old_value) )
{
vm_event_request_t req = {
.reason = VM_EVENT_REASON_MOV_TO_MSR,
.u.mov_to_msr.msr = msr,
-.u.mov_to_msr.value = value,
+.u.mov_to_msr.new_value = new_value,
+.u.mov_to_msr.old_value = old_value
};
monitor_traps(curr, 1, );
diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c
index e59f1f5..ecfa9e5