• Michael Chapman's avatar
    target-i386: kvm: clear unusable segments' flags in migration · 4cae9c97
    Michael Chapman authored
    This commit fixes migration of a QEMU/KVM guest from kernel >= v3.9 to
    kernel <= v3.7 (e.g. from RHEL 7 to RHEL 6). Without this commit a guest
    migrated across these kernel versions fails to resume on the target host
    as its segment descriptors are invalid.
    
    Two separate kernel commits combined together to result in this bug:
    
      commit f0495f9b9992f80f82b14306946444b287193390
      Author: Avi Kivity <avi@redhat.com>
      Date:   Thu Jun 7 17:06:10 2012 +0300
    
          KVM: VMX: Relax check on unusable segment
    
          Some userspace (e.g. QEMU 1.1) munge the d and g bits of segment
          descriptors, causing us not to recognize them as unusable segments
          with emulate_invalid_guest_state=1.  Relax the check by testing for
          segment not present (a non-present segment cannot be usable).
    Signed-off-by: 's avatarAvi Kivity <avi@redhat.com>
    
      commit 25391454e73e3156202264eb3c473825afe4bc94
      Author: Gleb Natapov <gleb@redhat.com>
      Date:   Mon Jan 21 15:36:46 2013 +0200
    
          KVM: VMX: don't clobber segment AR of unusable segments.
    
          Usability is returned in unusable field, so not need to clobber entire
          AR. Callers have to know how to deal with unusable segments already
          since if emulate_invalid_guest_state=true AR is not zeroed.
    Signed-off-by: 's avatarGleb Natapov <gleb@redhat.com>
    Signed-off-by: 's avatarMarcelo Tosatti <mtosatti@redhat.com>
    
    The first commit changed the KVM_SET_SREGS ioctl so that it did no treat
    segment flags == 0 as an unusable segment, instead only looking at the
    "present" flag.
    
    The second commit changed KVM_GET_SREGS so that it did not clear the
    flags of an unusable segment.
    
    Since QEMU does not itself maintain the "unusable" flag across a
    migration, the end result is that unusable segments read from a kernel
    with these commits and loaded into a kernel without these commits are
    not properly recognised as being unusable.
    
    This commit updates both get_seg and set_seg so that the problem is
    avoided even when migrating to or migrating from a QEMU without this
    commit. In get_seg, we clear the segment flags if the segment is marked
    unusable. In set_seg, we mark the segment unusable if the segment's
    "present" flag is not set.
    Signed-off-by: 's avatarMichael Chapman <mike@very.puzzling.org>
    Message-Id: <1449464047-17467-1-git-send-email-mike@very.puzzling.org>
    Signed-off-by: 's avatarPaolo Bonzini <pbonzini@redhat.com>
    4cae9c97
kvm.c 96.9 KB