]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/x86/kvm/emulate.c
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas...
[karo-tx-linux.git] / arch / x86 / kvm / emulate.c
index 97d9a9914ba8d772e522911252261110cfa58677..a3b57a27be880649ac7b0ae4144bc62faf105cbc 100644 (file)
@@ -475,13 +475,26 @@ register_address(struct x86_emulate_ctxt *ctxt, unsigned long reg)
        return address_mask(ctxt, reg);
 }
 
+static void masked_increment(ulong *reg, ulong mask, int inc)
+{
+       assign_masked(reg, *reg + inc, mask);
+}
+
 static inline void
 register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc)
 {
+       ulong mask;
+
        if (ctxt->ad_bytes == sizeof(unsigned long))
-               *reg += inc;
+               mask = ~0UL;
        else
-               *reg = (*reg & ~ad_mask(ctxt)) | ((*reg + inc) & ad_mask(ctxt));
+               mask = ad_mask(ctxt);
+       masked_increment(reg, mask, inc);
+}
+
+static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc)
+{
+       masked_increment(&ctxt->regs[VCPU_REGS_RSP], stack_mask(ctxt), inc);
 }
 
 static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
@@ -1522,8 +1535,8 @@ static int push(struct x86_emulate_ctxt *ctxt, void *data, int bytes)
 {
        struct segmented_address addr;
 
-       register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], -bytes);
-       addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]);
+       rsp_increment(ctxt, -bytes);
+       addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);
        addr.seg = VCPU_SREG_SS;
 
        return segmented_write(ctxt, addr, data, bytes);
@@ -1542,13 +1555,13 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt,
        int rc;
        struct segmented_address addr;
 
-       addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]);
+       addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);
        addr.seg = VCPU_SREG_SS;
        rc = segmented_read(ctxt, addr, dest, len);
        if (rc != X86EMUL_CONTINUE)
                return rc;
 
-       register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], len);
+       rsp_increment(ctxt, len);
        return rc;
 }
 
@@ -1688,8 +1701,7 @@ static int em_popa(struct x86_emulate_ctxt *ctxt)
 
        while (reg >= VCPU_REGS_RAX) {
                if (reg == VCPU_REGS_RSP) {
-                       register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP],
-                                                       ctxt->op_bytes);
+                       rsp_increment(ctxt, ctxt->op_bytes);
                        --reg;
                }
 
@@ -2825,7 +2837,7 @@ static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
        rc = emulate_pop(ctxt, &ctxt->dst.val, ctxt->op_bytes);
        if (rc != X86EMUL_CONTINUE)
                return rc;
-       register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], ctxt->src.val);
+       rsp_increment(ctxt, ctxt->src.val);
        return X86EMUL_CONTINUE;
 }