• Wanpeng Li's avatar
    KVM: X86: Fix load RFLAGS w/o the fixed bit · c9b53383
    Wanpeng Li authored
    commit d73235d1 upstream.
    
     *** Guest State ***
     CR0: actual=0x0000000000000030, shadow=0x0000000060000010, gh_mask=fffffffffffffff7
     CR4: actual=0x0000000000002050, shadow=0x0000000000000000, gh_mask=ffffffffffffe871
     CR3 = 0x00000000fffbc000
     RSP = 0x0000000000000000  RIP = 0x0000000000000000
     RFLAGS=0x00000000         DR7 = 0x0000000000000400
            ^^^^^^^^^^
    
    The failed vmentry is triggered by the following testcase when ept=Y:
    
        #include <unistd.h>
        #include <sys/syscall.h>
        #include <string.h>
        #include <stdint.h>
        #include <linux/kvm.h>
        #include <fcntl.h>
        #include <sys/ioctl.h>
    
        long r[5];
        int main()
        {
        	r[2] = open("/dev/kvm", O_RDONLY);
        	r[3] = ioctl(r[2], KVM_CREATE_VM, 0);
        	r[4] = ioctl(r[3], KVM_CREATE_VCPU, 7);
        	struct kvm_regs regs = {
        		.rflags = 0,
        	};
        	ioctl(r[4], KVM_SET_REGS, &regs);
        	ioctl(r[4], KVM_RUN, 0);
        }
    
    X86 RFLAGS bit 1 is fixed set, userspace can simply clearing bit 1
    of RFLAGS with KVM_SET_REGS ioctl which results in vmentry fails.
    This patch fixes it by oring X86_EFLAGS_FIXED during ioctl.
    Suggested-by: default avatarJim Mattson <jmattson@google.com>
    Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
    Reviewed-by: default avatarQuan Xu <quan.xu0@gmail.com>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Cc: Radim Krčmář <rkrcmar@redhat.com>
    Cc: Jim Mattson <jmattson@google.com>
    Signed-off-by: default avatarWanpeng Li <wanpeng.li@hotmail.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    c9b53383
x86.c 213 KB