diff options
author | Avi Kivity <avi@redhat.com> | 2009-01-04 16:26:52 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-03-24 05:02:59 -0400 |
commit | 1872a3f411ffe95c8e92300e0986a3532db55ce9 (patch) | |
tree | 950136940ee6c41eb688f9f4b1939a39f349286c /arch/x86/kvm/vmx.c | |
parent | bb3a8a178dec1e46df3138a30f76acf67fe12397 (diff) |
KVM: VMX: Fix guest state validity checks
The vmx guest state validity checks are full of bugs. Make them
conform to the manual.
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 3312047664a4..be9441056ff2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1784,14 +1784,16 @@ static bool code_segment_valid(struct kvm_vcpu *vcpu) | |||
1784 | vmx_get_segment(vcpu, &cs, VCPU_SREG_CS); | 1784 | vmx_get_segment(vcpu, &cs, VCPU_SREG_CS); |
1785 | cs_rpl = cs.selector & SELECTOR_RPL_MASK; | 1785 | cs_rpl = cs.selector & SELECTOR_RPL_MASK; |
1786 | 1786 | ||
1787 | if (cs.unusable) | ||
1788 | return false; | ||
1787 | if (~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_ACCESSES_MASK)) | 1789 | if (~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_ACCESSES_MASK)) |
1788 | return false; | 1790 | return false; |
1789 | if (!cs.s) | 1791 | if (!cs.s) |
1790 | return false; | 1792 | return false; |
1791 | if (!(~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_WRITEABLE_MASK))) { | 1793 | if (cs.type & AR_TYPE_WRITEABLE_MASK) { |
1792 | if (cs.dpl > cs_rpl) | 1794 | if (cs.dpl > cs_rpl) |
1793 | return false; | 1795 | return false; |
1794 | } else if (cs.type & AR_TYPE_CODE_MASK) { | 1796 | } else { |
1795 | if (cs.dpl != cs_rpl) | 1797 | if (cs.dpl != cs_rpl) |
1796 | return false; | 1798 | return false; |
1797 | } | 1799 | } |
@@ -1810,7 +1812,9 @@ static bool stack_segment_valid(struct kvm_vcpu *vcpu) | |||
1810 | vmx_get_segment(vcpu, &ss, VCPU_SREG_SS); | 1812 | vmx_get_segment(vcpu, &ss, VCPU_SREG_SS); |
1811 | ss_rpl = ss.selector & SELECTOR_RPL_MASK; | 1813 | ss_rpl = ss.selector & SELECTOR_RPL_MASK; |
1812 | 1814 | ||
1813 | if ((ss.type != 3) || (ss.type != 7)) | 1815 | if (ss.unusable) |
1816 | return true; | ||
1817 | if (ss.type != 3 && ss.type != 7) | ||
1814 | return false; | 1818 | return false; |
1815 | if (!ss.s) | 1819 | if (!ss.s) |
1816 | return false; | 1820 | return false; |
@@ -1830,6 +1834,8 @@ static bool data_segment_valid(struct kvm_vcpu *vcpu, int seg) | |||
1830 | vmx_get_segment(vcpu, &var, seg); | 1834 | vmx_get_segment(vcpu, &var, seg); |
1831 | rpl = var.selector & SELECTOR_RPL_MASK; | 1835 | rpl = var.selector & SELECTOR_RPL_MASK; |
1832 | 1836 | ||
1837 | if (var.unusable) | ||
1838 | return true; | ||
1833 | if (!var.s) | 1839 | if (!var.s) |
1834 | return false; | 1840 | return false; |
1835 | if (!var.present) | 1841 | if (!var.present) |
@@ -1851,9 +1857,11 @@ static bool tr_valid(struct kvm_vcpu *vcpu) | |||
1851 | 1857 | ||
1852 | vmx_get_segment(vcpu, &tr, VCPU_SREG_TR); | 1858 | vmx_get_segment(vcpu, &tr, VCPU_SREG_TR); |
1853 | 1859 | ||
1860 | if (tr.unusable) | ||
1861 | return false; | ||
1854 | if (tr.selector & SELECTOR_TI_MASK) /* TI = 1 */ | 1862 | if (tr.selector & SELECTOR_TI_MASK) /* TI = 1 */ |
1855 | return false; | 1863 | return false; |
1856 | if ((tr.type != 3) || (tr.type != 11)) /* TODO: Check if guest is in IA32e mode */ | 1864 | if (tr.type != 3 && tr.type != 11) /* TODO: Check if guest is in IA32e mode */ |
1857 | return false; | 1865 | return false; |
1858 | if (!tr.present) | 1866 | if (!tr.present) |
1859 | return false; | 1867 | return false; |
@@ -1867,6 +1875,8 @@ static bool ldtr_valid(struct kvm_vcpu *vcpu) | |||
1867 | 1875 | ||
1868 | vmx_get_segment(vcpu, &ldtr, VCPU_SREG_LDTR); | 1876 | vmx_get_segment(vcpu, &ldtr, VCPU_SREG_LDTR); |
1869 | 1877 | ||
1878 | if (ldtr.unusable) | ||
1879 | return true; | ||
1870 | if (ldtr.selector & SELECTOR_TI_MASK) /* TI = 1 */ | 1880 | if (ldtr.selector & SELECTOR_TI_MASK) /* TI = 1 */ |
1871 | return false; | 1881 | return false; |
1872 | if (ldtr.type != 2) | 1882 | if (ldtr.type != 2) |