aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2012-08-26 12:58:41 -0400
committerMarcelo Tosatti <mtosatti@redhat.com>2012-08-26 12:58:41 -0400
commitc78aa4c4b94b5b148be576a9f1570e31fe282b46 (patch)
tree6d5801eb3e60bcec6a91c7b13a334c6d2ea11b05 /arch/x86/kvm/emulate.c
parent90993cdd1800dc6ef9587431a0c625b978584e81 (diff)
parent9acb172543aecb783e2e1e53e3f447d4c0f5c150 (diff)
Merge remote-tracking branch 'upstream/master' into queue
Merging critical fixes from upstream required for development. * upstream/master: (809 commits) libata: Add a space to " 2GB ATA Flash Disk" DMA blacklist entry Revert "powerpc: Update g5_defconfig" powerpc/perf: Use pmc_overflow() to detect rolled back events powerpc: Fix VMX in interrupt check in POWER7 copy loops powerpc: POWER7 copy_to_user/copy_from_user patch applied twice powerpc: Fix personality handling in ppc64_personality() powerpc/dma-iommu: Fix IOMMU window check powerpc: Remove unnecessary ifdefs powerpc/kgdb: Restore current_thread_info properly powerpc/kgdb: Bail out of KGDB when we've been triggered powerpc/kgdb: Do not set kgdb_single_step on ppc powerpc/mpic_msgr: Add missing includes powerpc: Fix null pointer deref in perf hardware breakpoints powerpc: Fixup whitespace in xmon powerpc: Fix xmon dl command for new printk implementation xfs: check for possible overflow in xfs_ioc_trim xfs: unlock the AGI buffer when looping in xfs_dialloc xfs: fix uninitialised variable in xfs_rtbuf_get() powerpc/fsl: fix "Failed to mount /dev: No such device" errors powerpc/fsl: update defconfigs ... Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 10f0136f50c1..e8fb6c5c6c0a 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -475,13 +475,26 @@ register_address(struct x86_emulate_ctxt *ctxt, unsigned long reg)
475 return address_mask(ctxt, reg); 475 return address_mask(ctxt, reg);
476} 476}
477 477
478static void masked_increment(ulong *reg, ulong mask, int inc)
479{
480 assign_masked(reg, *reg + inc, mask);
481}
482
478static inline void 483static inline void
479register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc) 484register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc)
480{ 485{
486 ulong mask;
487
481 if (ctxt->ad_bytes == sizeof(unsigned long)) 488 if (ctxt->ad_bytes == sizeof(unsigned long))
482 *reg += inc; 489 mask = ~0UL;
483 else 490 else
484 *reg = (*reg & ~ad_mask(ctxt)) | ((*reg + inc) & ad_mask(ctxt)); 491 mask = ad_mask(ctxt);
492 masked_increment(reg, mask, inc);
493}
494
495static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc)
496{
497 masked_increment(&ctxt->regs[VCPU_REGS_RSP], stack_mask(ctxt), inc);
485} 498}
486 499
487static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) 500static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
@@ -1519,8 +1532,8 @@ static int push(struct x86_emulate_ctxt *ctxt, void *data, int bytes)
1519{ 1532{
1520 struct segmented_address addr; 1533 struct segmented_address addr;
1521 1534
1522 register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], -bytes); 1535 rsp_increment(ctxt, -bytes);
1523 addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]); 1536 addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);
1524 addr.seg = VCPU_SREG_SS; 1537 addr.seg = VCPU_SREG_SS;
1525 1538
1526 return segmented_write(ctxt, addr, data, bytes); 1539 return segmented_write(ctxt, addr, data, bytes);
@@ -1539,13 +1552,13 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt,
1539 int rc; 1552 int rc;
1540 struct segmented_address addr; 1553 struct segmented_address addr;
1541 1554
1542 addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]); 1555 addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);
1543 addr.seg = VCPU_SREG_SS; 1556 addr.seg = VCPU_SREG_SS;
1544 rc = segmented_read(ctxt, addr, dest, len); 1557 rc = segmented_read(ctxt, addr, dest, len);
1545 if (rc != X86EMUL_CONTINUE) 1558 if (rc != X86EMUL_CONTINUE)
1546 return rc; 1559 return rc;
1547 1560
1548 register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], len); 1561 rsp_increment(ctxt, len);
1549 return rc; 1562 return rc;
1550} 1563}
1551 1564
@@ -1685,8 +1698,7 @@ static int em_popa(struct x86_emulate_ctxt *ctxt)
1685 1698
1686 while (reg >= VCPU_REGS_RAX) { 1699 while (reg >= VCPU_REGS_RAX) {
1687 if (reg == VCPU_REGS_RSP) { 1700 if (reg == VCPU_REGS_RSP) {
1688 register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], 1701 rsp_increment(ctxt, ctxt->op_bytes);
1689 ctxt->op_bytes);
1690 --reg; 1702 --reg;
1691 } 1703 }
1692 1704
@@ -2819,7 +2831,7 @@ static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
2819 rc = emulate_pop(ctxt, &ctxt->dst.val, ctxt->op_bytes); 2831 rc = emulate_pop(ctxt, &ctxt->dst.val, ctxt->op_bytes);
2820 if (rc != X86EMUL_CONTINUE) 2832 if (rc != X86EMUL_CONTINUE)
2821 return rc; 2833 return rc;
2822 register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], ctxt->src.val); 2834 rsp_increment(ctxt, ctxt->src.val);
2823 return X86EMUL_CONTINUE; 2835 return X86EMUL_CONTINUE;
2824} 2836}
2825 2837