KVM: x86: Shrink the usercopy region of the emulation context
authorSean Christopherson <sean.j.christopherson@intel.com>
Tue, 18 Feb 2020 23:29:50 +0000 (15:29 -0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 16 Mar 2020 16:57:53 +0000 (17:57 +0100)
Shuffle a few operand structs to the end of struct x86_emulate_ctxt and
update the cache creation to whitelist only the region of the emulation
context that is expected to be copied to/from user memory, e.g. the
instruction operands, registers, and fetch/io/mem caches.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/kvm_emulate.h
arch/x86/kvm/x86.c

index 3a66f80..f86fe6b 100644 (file)
@@ -334,9 +334,6 @@ struct x86_emulate_ctxt {
        u8 intercept;
        u8 op_bytes;
        u8 ad_bytes;
-       struct operand src;
-       struct operand src2;
-       struct operand dst;
        union {
                int (*execute)(struct x86_emulate_ctxt *ctxt);
                fastop_t fop;
@@ -364,6 +361,11 @@ struct x86_emulate_ctxt {
        u8 seg_override;
        u64 d;
        unsigned long _eip;
+
+       /* Here begins the usercopy section. */
+       struct operand src;
+       struct operand src2;
+       struct operand dst;
        struct operand memop;
        /* Fields above regs are cleared together. */
        unsigned long _regs[NR_VCPU_REGS];
index f558990..a69f7bf 100644 (file)
@@ -235,13 +235,13 @@ static struct kmem_cache *x86_emulator_cache;
 
 static struct kmem_cache *kvm_alloc_emulator_cache(void)
 {
-       return kmem_cache_create_usercopy("x86_emulator",
-                                         sizeof(struct x86_emulate_ctxt),
+       unsigned int useroffset = offsetof(struct x86_emulate_ctxt, src);
+       unsigned int size = sizeof(struct x86_emulate_ctxt);
+
+       return kmem_cache_create_usercopy("x86_emulator", size,
                                          __alignof__(struct x86_emulate_ctxt),
-                                         SLAB_ACCOUNT,
-                                         0,
-                                         sizeof(struct x86_emulate_ctxt),
-                                         NULL);
+                                         SLAB_ACCOUNT, useroffset,
+                                         size - useroffset, NULL);
 }
 
 static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt);