diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2012-08-26 12:58:41 -0400 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2012-08-26 12:58:41 -0400 |
commit | c78aa4c4b94b5b148be576a9f1570e31fe282b46 (patch) | |
tree | 6d5801eb3e60bcec6a91c7b13a334c6d2ea11b05 /arch/x86/kvm/emulate.c | |
parent | 90993cdd1800dc6ef9587431a0c625b978584e81 (diff) | |
parent | 9acb172543aecb783e2e1e53e3f447d4c0f5c150 (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.c | 30 |
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 | ||
478 | static void masked_increment(ulong *reg, ulong mask, int inc) | ||
479 | { | ||
480 | assign_masked(reg, *reg + inc, mask); | ||
481 | } | ||
482 | |||
478 | static inline void | 483 | static inline void |
479 | register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc) | 484 | register_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 | |||
495 | static 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 | ||
487 | static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) | 500 | static 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 | ||