| 1881 | #define IDT_VE 20 /* Virtualization Exception (Intel specific) */ |
| 1882 | |
| 1883 | static enum exc_class |
| 1884 | exception_class(uint64_t info) |
| 1885 | { |
| 1886 | int type, vector; |
| 1887 | |
| 1888 | KASSERT(info & VM_INTINFO_VALID, ("intinfo must be valid: %#lx", info)); |
| 1889 | type = info & VM_INTINFO_TYPE; |
| 1890 | vector = info & 0xff; |
| 1891 | |
| 1892 | /* Table 6-4, "Interrupt and Exception Classes", Intel SDM, Vol 3 */ |
| 1893 | switch (type) { |
| 1894 | case VM_INTINFO_HWINTR: |
| 1895 | case VM_INTINFO_SWINTR: |
| 1896 | case VM_INTINFO_NMI: |
| 1897 | return (EXC_BENIGN); |
| 1898 | default: |
| 1899 | /* |
| 1900 | * Hardware exception. |
| 1901 | * |
| 1902 | * SVM and VT-x use identical type values to represent NMI, |
| 1903 | * hardware interrupt and software interrupt. |
| 1904 | * |
| 1905 | * SVM uses type '3' for all exceptions. VT-x uses type '3' |
| 1906 | * for exceptions except #BP and #OF. #BP and #OF use a type |
| 1907 | * value of '5' or '6'. Therefore we don't check for explicit |
| 1908 | * values of 'type' to classify 'intinfo' into a hardware |
| 1909 | * exception. |
| 1910 | */ |
| 1911 | break; |
| 1912 | } |
| 1913 | |
| 1914 | switch (vector) { |
| 1915 | case IDT_PF: |
| 1916 | case IDT_VE: |
| 1917 | return (EXC_PAGEFAULT); |
| 1918 | case IDT_DE: |
| 1919 | case IDT_TS: |
| 1920 | case IDT_NP: |
| 1921 | case IDT_SS: |
| 1922 | case IDT_GP: |
| 1923 | return (EXC_CONTRIBUTORY); |
| 1924 | default: |
| 1925 | return (EXC_BENIGN); |
| 1926 | } |
| 1927 | } |
| 1928 | |
| 1929 | static int |
| 1930 | nested_fault(struct vm *vm, int vcpuid, uint64_t info1, uint64_t info2, |