aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/tests/test_x86_emulator.c1
-rw-r--r--xen/arch/x86/hvm/emulate.c1
-rw-r--r--xen/arch/x86/mm.c1
-rw-r--r--xen/arch/x86/mm/shadow/common.c1
-rw-r--r--xen/arch/x86/x86_emulate.c4
-rw-r--r--xen/include/asm-x86/x86_emulate.h27
6 files changed, 22 insertions, 13 deletions
diff --git a/tools/tests/test_x86_emulator.c b/tools/tests/test_x86_emulator.c
index f261e7f4da..fe48921b59 100644
--- a/tools/tests/test_x86_emulator.c
+++ b/tools/tests/test_x86_emulator.c
@@ -118,6 +118,7 @@ int main(int argc, char **argv)
#endif
ctxt.regs = &regs;
+ ctxt.force_writeback = 0;
ctxt.addr_size = 32;
ctxt.sp_size = 32;
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index 73649313ac..2bbdb505e9 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -722,6 +722,7 @@ void hvm_emulate_prepare(
struct cpu_user_regs *regs)
{
hvmemul_ctxt->ctxt.regs = regs;
+ hvmemul_ctxt->ctxt.force_writeback = 1;
hvmemul_ctxt->seg_reg_accessed = 0;
hvmemul_ctxt->seg_reg_dirty = 0;
hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt);
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 469842787e..e84b185598 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -3671,6 +3671,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr,
goto bail;
ptwr_ctxt.ctxt.regs = regs;
+ ptwr_ctxt.ctxt.force_writeback = 0;
ptwr_ctxt.ctxt.addr_size = ptwr_ctxt.ctxt.sp_size =
is_pv_32on64_domain(d) ? 32 : BITS_PER_LONG;
ptwr_ctxt.cr2 = addr;
diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
index d30e7e721a..240d9100f0 100644
--- a/xen/arch/x86/mm/shadow/common.c
+++ b/xen/arch/x86/mm/shadow/common.c
@@ -385,6 +385,7 @@ struct x86_emulate_ops *shadow_init_emulation(
unsigned long addr;
sh_ctxt->ctxt.regs = regs;
+ sh_ctxt->ctxt.force_writeback = 0;
if ( !is_hvm_vcpu(v) )
{
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index b240a0a48e..fb3280d505 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -24,6 +24,7 @@
#ifndef __XEN__
#include <stddef.h>
#include <stdint.h>
+#include <string.h>
#include <public/xen.h>
#else
#include <xen/config.h>
@@ -1983,7 +1984,8 @@ x86_emulate(
}
break;
case OP_MEM:
- if ( !(d & Mov) && (dst.orig_val == dst.val) )
+ if ( !(d & Mov) && (dst.orig_val == dst.val) &&
+ !ctxt->force_writeback )
/* nothing to do */;
else if ( lock_prefix )
rc = ops->cmpxchg(
diff --git a/xen/include/asm-x86/x86_emulate.h b/xen/include/asm-x86/x86_emulate.h
index 53d12f52be..d92df355d3 100644
--- a/xen/include/asm-x86/x86_emulate.h
+++ b/xen/include/asm-x86/x86_emulate.h
@@ -56,17 +56,17 @@ enum x86_segment {
* segment descriptor. It happens to match the format of an AMD SVM VMCB.
*/
typedef union segment_attributes {
- u16 bytes;
+ uint16_t bytes;
struct
{
- u16 type:4; /* 0; Bit 40-43 */
- u16 s: 1; /* 4; Bit 44 */
- u16 dpl: 2; /* 5; Bit 45-46 */
- u16 p: 1; /* 7; Bit 47 */
- u16 avl: 1; /* 8; Bit 52 */
- u16 l: 1; /* 9; Bit 53 */
- u16 db: 1; /* 10; Bit 54 */
- u16 g: 1; /* 11; Bit 55 */
+ uint16_t type:4; /* 0; Bit 40-43 */
+ uint16_t s: 1; /* 4; Bit 44 */
+ uint16_t dpl: 2; /* 5; Bit 45-46 */
+ uint16_t p: 1; /* 7; Bit 47 */
+ uint16_t avl: 1; /* 8; Bit 52 */
+ uint16_t l: 1; /* 9; Bit 53 */
+ uint16_t db: 1; /* 10; Bit 54 */
+ uint16_t g: 1; /* 11; Bit 55 */
} fields;
} __attribute__ ((packed)) segment_attributes_t;
@@ -75,10 +75,10 @@ typedef union segment_attributes {
* Again, this happens to match the format of an AMD SVM VMCB.
*/
struct segment_register {
- u16 sel;
+ uint16_t sel;
segment_attributes_t attr;
- u32 limit;
- u64 base;
+ uint32_t limit;
+ uint64_t base;
} __attribute__ ((packed));
/*
@@ -368,6 +368,9 @@ struct x86_emulate_ctxt
/* Stack pointer width in bits (16, 32 or 64). */
unsigned int sp_size;
+
+ /* Set this if writes may have side effects. */
+ int force_writeback;
};
/*