Merge tag '6.8-rc-smb-server-fixes-part2' of git://git.samba.org/ksmbd
[linux-2.6-microblaze.git] / arch / x86 / kvm / emulate.c
index 2673cd5..e223043 100644 (file)
@@ -687,8 +687,8 @@ static unsigned insn_alignment(struct x86_emulate_ctxt *ctxt, unsigned size)
 static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
                                       struct segmented_address addr,
                                       unsigned *max_size, unsigned size,
-                                      bool write, bool fetch,
-                                      enum x86emul_mode mode, ulong *linear)
+                                      enum x86emul_mode mode, ulong *linear,
+                                      unsigned int flags)
 {
        struct desc_struct desc;
        bool usable;
@@ -701,7 +701,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
        *max_size = 0;
        switch (mode) {
        case X86EMUL_MODE_PROT64:
-               *linear = la;
+               *linear = la = ctxt->ops->get_untagged_addr(ctxt, la, flags);
                va_bits = ctxt_virt_addr_bits(ctxt);
                if (!__is_canonical_address(la, va_bits))
                        goto bad;
@@ -717,11 +717,11 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
                if (!usable)
                        goto bad;
                /* code segment in protected mode or read-only data segment */
-               if ((((ctxt->mode != X86EMUL_MODE_REAL) && (desc.type & 8))
-                                       || !(desc.type & 2)) && write)
+               if ((((ctxt->mode != X86EMUL_MODE_REAL) && (desc.type & 8)) || !(desc.type & 2)) &&
+                   (flags & X86EMUL_F_WRITE))
                        goto bad;
                /* unreadable code segment */
-               if (!fetch && (desc.type & 8) && !(desc.type & 2))
+               if (!(flags & X86EMUL_F_FETCH) && (desc.type & 8) && !(desc.type & 2))
                        goto bad;
                lim = desc_limit_scaled(&desc);
                if (!(desc.type & 8) && (desc.type & 4)) {
@@ -757,8 +757,8 @@ static int linearize(struct x86_emulate_ctxt *ctxt,
                     ulong *linear)
 {
        unsigned max_size;
-       return __linearize(ctxt, addr, &max_size, size, write, false,
-                          ctxt->mode, linear);
+       return __linearize(ctxt, addr, &max_size, size, ctxt->mode, linear,
+                          write ? X86EMUL_F_WRITE : 0);
 }
 
 static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst)
@@ -771,7 +771,8 @@ static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst)
 
        if (ctxt->op_bytes != sizeof(unsigned long))
                addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1);
-       rc = __linearize(ctxt, addr, &max_size, 1, false, true, ctxt->mode, &linear);
+       rc = __linearize(ctxt, addr, &max_size, 1, ctxt->mode, &linear,
+                        X86EMUL_F_FETCH);
        if (rc == X86EMUL_CONTINUE)
                ctxt->_eip = addr.ea;
        return rc;
@@ -907,8 +908,8 @@ static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size)
         * boundary check itself.  Instead, we use max_size to check
         * against op_size.
         */
-       rc = __linearize(ctxt, addr, &max_size, 0, false, true, ctxt->mode,
-                        &linear);
+       rc = __linearize(ctxt, addr, &max_size, 0, ctxt->mode, &linear,
+                        X86EMUL_F_FETCH);
        if (unlikely(rc != X86EMUL_CONTINUE))
                return rc;
 
@@ -3439,8 +3440,10 @@ static int em_invlpg(struct x86_emulate_ctxt *ctxt)
 {
        int rc;
        ulong linear;
+       unsigned int max_size;
 
-       rc = linearize(ctxt, ctxt->src.addr.mem, 1, false, &linear);
+       rc = __linearize(ctxt, ctxt->src.addr.mem, &max_size, 1, ctxt->mode,
+                        &linear, X86EMUL_F_INVLPG);
        if (rc == X86EMUL_CONTINUE)
                ctxt->ops->invlpg(ctxt, linear);
        /* Disable writeback. */