.. | .. |
---|
15 | 15 | #include <linux/kvm_host.h> |
---|
16 | 16 | #include <linux/vmalloc.h> |
---|
17 | 17 | #include <linux/fs.h> |
---|
18 | | -#include <linux/bootmem.h> |
---|
| 18 | +#include <linux/memblock.h> |
---|
19 | 19 | #include <linux/random.h> |
---|
20 | 20 | #include <asm/page.h> |
---|
21 | 21 | #include <asm/cacheflush.h> |
---|
.. | .. |
---|
64 | 64 | switch (insn.r_format.func) { |
---|
65 | 65 | case jalr_op: |
---|
66 | 66 | arch->gprs[insn.r_format.rd] = epc + 8; |
---|
67 | | - /* Fall through */ |
---|
| 67 | + fallthrough; |
---|
68 | 68 | case jr_op: |
---|
69 | 69 | nextpc = arch->gprs[insn.r_format.rs]; |
---|
70 | 70 | break; |
---|
.. | .. |
---|
140 | 140 | /* These are unconditional and in j_format. */ |
---|
141 | 141 | case jal_op: |
---|
142 | 142 | arch->gprs[31] = instpc + 8; |
---|
| 143 | + fallthrough; |
---|
143 | 144 | case j_op: |
---|
144 | 145 | epc += 4; |
---|
145 | 146 | epc >>= 28; |
---|
.. | .. |
---|
1016 | 1017 | */ |
---|
1017 | 1018 | preempt_disable(); |
---|
1018 | 1019 | cpu = smp_processor_id(); |
---|
1019 | | - get_new_mmu_context(kern_mm, cpu); |
---|
| 1020 | + get_new_mmu_context(kern_mm); |
---|
1020 | 1021 | for_each_possible_cpu(i) |
---|
1021 | 1022 | if (i != cpu) |
---|
1022 | | - cpu_context(i, kern_mm) = 0; |
---|
| 1023 | + set_cpu_context(i, kern_mm, 0); |
---|
1023 | 1024 | preempt_enable(); |
---|
1024 | 1025 | } |
---|
1025 | 1026 | kvm_write_c0_guest_entryhi(cop0, entryhi); |
---|
.. | .. |
---|
1090 | 1091 | if (i == cpu) |
---|
1091 | 1092 | continue; |
---|
1092 | 1093 | if (user) |
---|
1093 | | - cpu_context(i, user_mm) = 0; |
---|
1094 | | - cpu_context(i, kern_mm) = 0; |
---|
| 1094 | + set_cpu_context(i, user_mm, 0); |
---|
| 1095 | + set_cpu_context(i, kern_mm, 0); |
---|
1095 | 1096 | } |
---|
1096 | 1097 | |
---|
1097 | 1098 | preempt_enable(); |
---|
.. | .. |
---|
1141 | 1142 | unsigned long pc = vcpu->arch.pc; |
---|
1142 | 1143 | int index; |
---|
1143 | 1144 | |
---|
1144 | | - get_random_bytes(&index, sizeof(index)); |
---|
1145 | | - index &= (KVM_MIPS_GUEST_TLB_SIZE - 1); |
---|
1146 | | - |
---|
| 1145 | + index = prandom_u32_max(KVM_MIPS_GUEST_TLB_SIZE); |
---|
1147 | 1146 | tlb = &vcpu->arch.guest_tlb[index]; |
---|
1148 | 1147 | |
---|
1149 | 1148 | kvm_mips_invalidate_guest_tlb(vcpu, tlb); |
---|
.. | .. |
---|
1263 | 1262 | |
---|
1264 | 1263 | enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst, |
---|
1265 | 1264 | u32 *opc, u32 cause, |
---|
1266 | | - struct kvm_run *run, |
---|
1267 | 1265 | struct kvm_vcpu *vcpu) |
---|
1268 | 1266 | { |
---|
1269 | 1267 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
1598 | 1596 | |
---|
1599 | 1597 | enum emulation_result kvm_mips_emulate_store(union mips_instruction inst, |
---|
1600 | 1598 | u32 cause, |
---|
1601 | | - struct kvm_run *run, |
---|
1602 | 1599 | struct kvm_vcpu *vcpu) |
---|
1603 | 1600 | { |
---|
| 1601 | + int r; |
---|
1604 | 1602 | enum emulation_result er; |
---|
1605 | 1603 | u32 rt; |
---|
| 1604 | + struct kvm_run *run = vcpu->run; |
---|
1606 | 1605 | void *data = run->mmio.data; |
---|
| 1606 | + unsigned int imme; |
---|
1607 | 1607 | unsigned long curr_pc; |
---|
1608 | 1608 | |
---|
1609 | 1609 | /* |
---|
.. | .. |
---|
1661 | 1661 | vcpu->arch.gprs[rt], *(u8 *)data); |
---|
1662 | 1662 | break; |
---|
1663 | 1663 | |
---|
| 1664 | + case swl_op: |
---|
| 1665 | + run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa( |
---|
| 1666 | + vcpu->arch.host_cp0_badvaddr) & (~0x3); |
---|
| 1667 | + run->mmio.len = 4; |
---|
| 1668 | + imme = vcpu->arch.host_cp0_badvaddr & 0x3; |
---|
| 1669 | + switch (imme) { |
---|
| 1670 | + case 0: |
---|
| 1671 | + *(u32 *)data = ((*(u32 *)data) & 0xffffff00) | |
---|
| 1672 | + (vcpu->arch.gprs[rt] >> 24); |
---|
| 1673 | + break; |
---|
| 1674 | + case 1: |
---|
| 1675 | + *(u32 *)data = ((*(u32 *)data) & 0xffff0000) | |
---|
| 1676 | + (vcpu->arch.gprs[rt] >> 16); |
---|
| 1677 | + break; |
---|
| 1678 | + case 2: |
---|
| 1679 | + *(u32 *)data = ((*(u32 *)data) & 0xff000000) | |
---|
| 1680 | + (vcpu->arch.gprs[rt] >> 8); |
---|
| 1681 | + break; |
---|
| 1682 | + case 3: |
---|
| 1683 | + *(u32 *)data = vcpu->arch.gprs[rt]; |
---|
| 1684 | + break; |
---|
| 1685 | + default: |
---|
| 1686 | + break; |
---|
| 1687 | + } |
---|
| 1688 | + |
---|
| 1689 | + kvm_debug("[%#lx] OP_SWL: eaddr: %#lx, gpr: %#lx, data: %#x\n", |
---|
| 1690 | + vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, |
---|
| 1691 | + vcpu->arch.gprs[rt], *(u32 *)data); |
---|
| 1692 | + break; |
---|
| 1693 | + |
---|
| 1694 | + case swr_op: |
---|
| 1695 | + run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa( |
---|
| 1696 | + vcpu->arch.host_cp0_badvaddr) & (~0x3); |
---|
| 1697 | + run->mmio.len = 4; |
---|
| 1698 | + imme = vcpu->arch.host_cp0_badvaddr & 0x3; |
---|
| 1699 | + switch (imme) { |
---|
| 1700 | + case 0: |
---|
| 1701 | + *(u32 *)data = vcpu->arch.gprs[rt]; |
---|
| 1702 | + break; |
---|
| 1703 | + case 1: |
---|
| 1704 | + *(u32 *)data = ((*(u32 *)data) & 0xff) | |
---|
| 1705 | + (vcpu->arch.gprs[rt] << 8); |
---|
| 1706 | + break; |
---|
| 1707 | + case 2: |
---|
| 1708 | + *(u32 *)data = ((*(u32 *)data) & 0xffff) | |
---|
| 1709 | + (vcpu->arch.gprs[rt] << 16); |
---|
| 1710 | + break; |
---|
| 1711 | + case 3: |
---|
| 1712 | + *(u32 *)data = ((*(u32 *)data) & 0xffffff) | |
---|
| 1713 | + (vcpu->arch.gprs[rt] << 24); |
---|
| 1714 | + break; |
---|
| 1715 | + default: |
---|
| 1716 | + break; |
---|
| 1717 | + } |
---|
| 1718 | + |
---|
| 1719 | + kvm_debug("[%#lx] OP_SWR: eaddr: %#lx, gpr: %#lx, data: %#x\n", |
---|
| 1720 | + vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, |
---|
| 1721 | + vcpu->arch.gprs[rt], *(u32 *)data); |
---|
| 1722 | + break; |
---|
| 1723 | + |
---|
| 1724 | +#if defined(CONFIG_64BIT) && defined(CONFIG_KVM_MIPS_VZ) |
---|
| 1725 | + case sdl_op: |
---|
| 1726 | + run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa( |
---|
| 1727 | + vcpu->arch.host_cp0_badvaddr) & (~0x7); |
---|
| 1728 | + |
---|
| 1729 | + run->mmio.len = 8; |
---|
| 1730 | + imme = vcpu->arch.host_cp0_badvaddr & 0x7; |
---|
| 1731 | + switch (imme) { |
---|
| 1732 | + case 0: |
---|
| 1733 | + *(u64 *)data = ((*(u64 *)data) & 0xffffffffffffff00) | |
---|
| 1734 | + ((vcpu->arch.gprs[rt] >> 56) & 0xff); |
---|
| 1735 | + break; |
---|
| 1736 | + case 1: |
---|
| 1737 | + *(u64 *)data = ((*(u64 *)data) & 0xffffffffffff0000) | |
---|
| 1738 | + ((vcpu->arch.gprs[rt] >> 48) & 0xffff); |
---|
| 1739 | + break; |
---|
| 1740 | + case 2: |
---|
| 1741 | + *(u64 *)data = ((*(u64 *)data) & 0xffffffffff000000) | |
---|
| 1742 | + ((vcpu->arch.gprs[rt] >> 40) & 0xffffff); |
---|
| 1743 | + break; |
---|
| 1744 | + case 3: |
---|
| 1745 | + *(u64 *)data = ((*(u64 *)data) & 0xffffffff00000000) | |
---|
| 1746 | + ((vcpu->arch.gprs[rt] >> 32) & 0xffffffff); |
---|
| 1747 | + break; |
---|
| 1748 | + case 4: |
---|
| 1749 | + *(u64 *)data = ((*(u64 *)data) & 0xffffff0000000000) | |
---|
| 1750 | + ((vcpu->arch.gprs[rt] >> 24) & 0xffffffffff); |
---|
| 1751 | + break; |
---|
| 1752 | + case 5: |
---|
| 1753 | + *(u64 *)data = ((*(u64 *)data) & 0xffff000000000000) | |
---|
| 1754 | + ((vcpu->arch.gprs[rt] >> 16) & 0xffffffffffff); |
---|
| 1755 | + break; |
---|
| 1756 | + case 6: |
---|
| 1757 | + *(u64 *)data = ((*(u64 *)data) & 0xff00000000000000) | |
---|
| 1758 | + ((vcpu->arch.gprs[rt] >> 8) & 0xffffffffffffff); |
---|
| 1759 | + break; |
---|
| 1760 | + case 7: |
---|
| 1761 | + *(u64 *)data = vcpu->arch.gprs[rt]; |
---|
| 1762 | + break; |
---|
| 1763 | + default: |
---|
| 1764 | + break; |
---|
| 1765 | + } |
---|
| 1766 | + |
---|
| 1767 | + kvm_debug("[%#lx] OP_SDL: eaddr: %#lx, gpr: %#lx, data: %llx\n", |
---|
| 1768 | + vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, |
---|
| 1769 | + vcpu->arch.gprs[rt], *(u64 *)data); |
---|
| 1770 | + break; |
---|
| 1771 | + |
---|
| 1772 | + case sdr_op: |
---|
| 1773 | + run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa( |
---|
| 1774 | + vcpu->arch.host_cp0_badvaddr) & (~0x7); |
---|
| 1775 | + |
---|
| 1776 | + run->mmio.len = 8; |
---|
| 1777 | + imme = vcpu->arch.host_cp0_badvaddr & 0x7; |
---|
| 1778 | + switch (imme) { |
---|
| 1779 | + case 0: |
---|
| 1780 | + *(u64 *)data = vcpu->arch.gprs[rt]; |
---|
| 1781 | + break; |
---|
| 1782 | + case 1: |
---|
| 1783 | + *(u64 *)data = ((*(u64 *)data) & 0xff) | |
---|
| 1784 | + (vcpu->arch.gprs[rt] << 8); |
---|
| 1785 | + break; |
---|
| 1786 | + case 2: |
---|
| 1787 | + *(u64 *)data = ((*(u64 *)data) & 0xffff) | |
---|
| 1788 | + (vcpu->arch.gprs[rt] << 16); |
---|
| 1789 | + break; |
---|
| 1790 | + case 3: |
---|
| 1791 | + *(u64 *)data = ((*(u64 *)data) & 0xffffff) | |
---|
| 1792 | + (vcpu->arch.gprs[rt] << 24); |
---|
| 1793 | + break; |
---|
| 1794 | + case 4: |
---|
| 1795 | + *(u64 *)data = ((*(u64 *)data) & 0xffffffff) | |
---|
| 1796 | + (vcpu->arch.gprs[rt] << 32); |
---|
| 1797 | + break; |
---|
| 1798 | + case 5: |
---|
| 1799 | + *(u64 *)data = ((*(u64 *)data) & 0xffffffffff) | |
---|
| 1800 | + (vcpu->arch.gprs[rt] << 40); |
---|
| 1801 | + break; |
---|
| 1802 | + case 6: |
---|
| 1803 | + *(u64 *)data = ((*(u64 *)data) & 0xffffffffffff) | |
---|
| 1804 | + (vcpu->arch.gprs[rt] << 48); |
---|
| 1805 | + break; |
---|
| 1806 | + case 7: |
---|
| 1807 | + *(u64 *)data = ((*(u64 *)data) & 0xffffffffffffff) | |
---|
| 1808 | + (vcpu->arch.gprs[rt] << 56); |
---|
| 1809 | + break; |
---|
| 1810 | + default: |
---|
| 1811 | + break; |
---|
| 1812 | + } |
---|
| 1813 | + |
---|
| 1814 | + kvm_debug("[%#lx] OP_SDR: eaddr: %#lx, gpr: %#lx, data: %llx\n", |
---|
| 1815 | + vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, |
---|
| 1816 | + vcpu->arch.gprs[rt], *(u64 *)data); |
---|
| 1817 | + break; |
---|
| 1818 | +#endif |
---|
| 1819 | + |
---|
| 1820 | +#ifdef CONFIG_CPU_LOONGSON64 |
---|
| 1821 | + case sdc2_op: |
---|
| 1822 | + rt = inst.loongson3_lsdc2_format.rt; |
---|
| 1823 | + switch (inst.loongson3_lsdc2_format.opcode1) { |
---|
| 1824 | + /* |
---|
| 1825 | + * Loongson-3 overridden sdc2 instructions. |
---|
| 1826 | + * opcode1 instruction |
---|
| 1827 | + * 0x0 gssbx: store 1 bytes from GPR |
---|
| 1828 | + * 0x1 gsshx: store 2 bytes from GPR |
---|
| 1829 | + * 0x2 gsswx: store 4 bytes from GPR |
---|
| 1830 | + * 0x3 gssdx: store 8 bytes from GPR |
---|
| 1831 | + */ |
---|
| 1832 | + case 0x0: |
---|
| 1833 | + run->mmio.len = 1; |
---|
| 1834 | + *(u8 *)data = vcpu->arch.gprs[rt]; |
---|
| 1835 | + |
---|
| 1836 | + kvm_debug("[%#lx] OP_GSSBX: eaddr: %#lx, gpr: %#lx, data: %#x\n", |
---|
| 1837 | + vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, |
---|
| 1838 | + vcpu->arch.gprs[rt], *(u8 *)data); |
---|
| 1839 | + break; |
---|
| 1840 | + case 0x1: |
---|
| 1841 | + run->mmio.len = 2; |
---|
| 1842 | + *(u16 *)data = vcpu->arch.gprs[rt]; |
---|
| 1843 | + |
---|
| 1844 | + kvm_debug("[%#lx] OP_GSSSHX: eaddr: %#lx, gpr: %#lx, data: %#x\n", |
---|
| 1845 | + vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, |
---|
| 1846 | + vcpu->arch.gprs[rt], *(u16 *)data); |
---|
| 1847 | + break; |
---|
| 1848 | + case 0x2: |
---|
| 1849 | + run->mmio.len = 4; |
---|
| 1850 | + *(u32 *)data = vcpu->arch.gprs[rt]; |
---|
| 1851 | + |
---|
| 1852 | + kvm_debug("[%#lx] OP_GSSWX: eaddr: %#lx, gpr: %#lx, data: %#x\n", |
---|
| 1853 | + vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, |
---|
| 1854 | + vcpu->arch.gprs[rt], *(u32 *)data); |
---|
| 1855 | + break; |
---|
| 1856 | + case 0x3: |
---|
| 1857 | + run->mmio.len = 8; |
---|
| 1858 | + *(u64 *)data = vcpu->arch.gprs[rt]; |
---|
| 1859 | + |
---|
| 1860 | + kvm_debug("[%#lx] OP_GSSDX: eaddr: %#lx, gpr: %#lx, data: %#llx\n", |
---|
| 1861 | + vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr, |
---|
| 1862 | + vcpu->arch.gprs[rt], *(u64 *)data); |
---|
| 1863 | + break; |
---|
| 1864 | + default: |
---|
| 1865 | + kvm_err("Godson Extended GS-Store not yet supported (inst=0x%08x)\n", |
---|
| 1866 | + inst.word); |
---|
| 1867 | + break; |
---|
| 1868 | + } |
---|
| 1869 | + break; |
---|
| 1870 | +#endif |
---|
1664 | 1871 | default: |
---|
1665 | 1872 | kvm_err("Store not yet supported (inst=0x%08x)\n", |
---|
1666 | 1873 | inst.word); |
---|
1667 | 1874 | goto out_fail; |
---|
1668 | 1875 | } |
---|
1669 | 1876 | |
---|
1670 | | - run->mmio.is_write = 1; |
---|
1671 | 1877 | vcpu->mmio_needed = 1; |
---|
| 1878 | + run->mmio.is_write = 1; |
---|
1672 | 1879 | vcpu->mmio_is_write = 1; |
---|
| 1880 | + |
---|
| 1881 | + r = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, |
---|
| 1882 | + run->mmio.phys_addr, run->mmio.len, data); |
---|
| 1883 | + |
---|
| 1884 | + if (!r) { |
---|
| 1885 | + vcpu->mmio_needed = 0; |
---|
| 1886 | + return EMULATE_DONE; |
---|
| 1887 | + } |
---|
| 1888 | + |
---|
1673 | 1889 | return EMULATE_DO_MMIO; |
---|
1674 | 1890 | |
---|
1675 | 1891 | out_fail: |
---|
.. | .. |
---|
1679 | 1895 | } |
---|
1680 | 1896 | |
---|
1681 | 1897 | enum emulation_result kvm_mips_emulate_load(union mips_instruction inst, |
---|
1682 | | - u32 cause, struct kvm_run *run, |
---|
1683 | | - struct kvm_vcpu *vcpu) |
---|
| 1898 | + u32 cause, struct kvm_vcpu *vcpu) |
---|
1684 | 1899 | { |
---|
| 1900 | + struct kvm_run *run = vcpu->run; |
---|
| 1901 | + int r; |
---|
1685 | 1902 | enum emulation_result er; |
---|
1686 | 1903 | unsigned long curr_pc; |
---|
1687 | 1904 | u32 op, rt; |
---|
| 1905 | + unsigned int imme; |
---|
1688 | 1906 | |
---|
1689 | 1907 | rt = inst.i_format.rt; |
---|
1690 | 1908 | op = inst.i_format.opcode; |
---|
.. | .. |
---|
1717 | 1935 | |
---|
1718 | 1936 | case lwu_op: |
---|
1719 | 1937 | vcpu->mmio_needed = 1; /* unsigned */ |
---|
1720 | | - /* fall through */ |
---|
| 1938 | + fallthrough; |
---|
1721 | 1939 | #endif |
---|
1722 | 1940 | case lw_op: |
---|
1723 | 1941 | run->mmio.len = 4; |
---|
.. | .. |
---|
1725 | 1943 | |
---|
1726 | 1944 | case lhu_op: |
---|
1727 | 1945 | vcpu->mmio_needed = 1; /* unsigned */ |
---|
1728 | | - /* fall through */ |
---|
| 1946 | + fallthrough; |
---|
1729 | 1947 | case lh_op: |
---|
1730 | 1948 | run->mmio.len = 2; |
---|
1731 | 1949 | break; |
---|
1732 | 1950 | |
---|
1733 | 1951 | case lbu_op: |
---|
1734 | 1952 | vcpu->mmio_needed = 1; /* unsigned */ |
---|
1735 | | - /* fall through */ |
---|
| 1953 | + fallthrough; |
---|
1736 | 1954 | case lb_op: |
---|
1737 | 1955 | run->mmio.len = 1; |
---|
1738 | 1956 | break; |
---|
| 1957 | + |
---|
| 1958 | + case lwl_op: |
---|
| 1959 | + run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa( |
---|
| 1960 | + vcpu->arch.host_cp0_badvaddr) & (~0x3); |
---|
| 1961 | + |
---|
| 1962 | + run->mmio.len = 4; |
---|
| 1963 | + imme = vcpu->arch.host_cp0_badvaddr & 0x3; |
---|
| 1964 | + switch (imme) { |
---|
| 1965 | + case 0: |
---|
| 1966 | + vcpu->mmio_needed = 3; /* 1 byte */ |
---|
| 1967 | + break; |
---|
| 1968 | + case 1: |
---|
| 1969 | + vcpu->mmio_needed = 4; /* 2 bytes */ |
---|
| 1970 | + break; |
---|
| 1971 | + case 2: |
---|
| 1972 | + vcpu->mmio_needed = 5; /* 3 bytes */ |
---|
| 1973 | + break; |
---|
| 1974 | + case 3: |
---|
| 1975 | + vcpu->mmio_needed = 6; /* 4 bytes */ |
---|
| 1976 | + break; |
---|
| 1977 | + default: |
---|
| 1978 | + break; |
---|
| 1979 | + } |
---|
| 1980 | + break; |
---|
| 1981 | + |
---|
| 1982 | + case lwr_op: |
---|
| 1983 | + run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa( |
---|
| 1984 | + vcpu->arch.host_cp0_badvaddr) & (~0x3); |
---|
| 1985 | + |
---|
| 1986 | + run->mmio.len = 4; |
---|
| 1987 | + imme = vcpu->arch.host_cp0_badvaddr & 0x3; |
---|
| 1988 | + switch (imme) { |
---|
| 1989 | + case 0: |
---|
| 1990 | + vcpu->mmio_needed = 7; /* 4 bytes */ |
---|
| 1991 | + break; |
---|
| 1992 | + case 1: |
---|
| 1993 | + vcpu->mmio_needed = 8; /* 3 bytes */ |
---|
| 1994 | + break; |
---|
| 1995 | + case 2: |
---|
| 1996 | + vcpu->mmio_needed = 9; /* 2 bytes */ |
---|
| 1997 | + break; |
---|
| 1998 | + case 3: |
---|
| 1999 | + vcpu->mmio_needed = 10; /* 1 byte */ |
---|
| 2000 | + break; |
---|
| 2001 | + default: |
---|
| 2002 | + break; |
---|
| 2003 | + } |
---|
| 2004 | + break; |
---|
| 2005 | + |
---|
| 2006 | +#if defined(CONFIG_64BIT) && defined(CONFIG_KVM_MIPS_VZ) |
---|
| 2007 | + case ldl_op: |
---|
| 2008 | + run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa( |
---|
| 2009 | + vcpu->arch.host_cp0_badvaddr) & (~0x7); |
---|
| 2010 | + |
---|
| 2011 | + run->mmio.len = 8; |
---|
| 2012 | + imme = vcpu->arch.host_cp0_badvaddr & 0x7; |
---|
| 2013 | + switch (imme) { |
---|
| 2014 | + case 0: |
---|
| 2015 | + vcpu->mmio_needed = 11; /* 1 byte */ |
---|
| 2016 | + break; |
---|
| 2017 | + case 1: |
---|
| 2018 | + vcpu->mmio_needed = 12; /* 2 bytes */ |
---|
| 2019 | + break; |
---|
| 2020 | + case 2: |
---|
| 2021 | + vcpu->mmio_needed = 13; /* 3 bytes */ |
---|
| 2022 | + break; |
---|
| 2023 | + case 3: |
---|
| 2024 | + vcpu->mmio_needed = 14; /* 4 bytes */ |
---|
| 2025 | + break; |
---|
| 2026 | + case 4: |
---|
| 2027 | + vcpu->mmio_needed = 15; /* 5 bytes */ |
---|
| 2028 | + break; |
---|
| 2029 | + case 5: |
---|
| 2030 | + vcpu->mmio_needed = 16; /* 6 bytes */ |
---|
| 2031 | + break; |
---|
| 2032 | + case 6: |
---|
| 2033 | + vcpu->mmio_needed = 17; /* 7 bytes */ |
---|
| 2034 | + break; |
---|
| 2035 | + case 7: |
---|
| 2036 | + vcpu->mmio_needed = 18; /* 8 bytes */ |
---|
| 2037 | + break; |
---|
| 2038 | + default: |
---|
| 2039 | + break; |
---|
| 2040 | + } |
---|
| 2041 | + break; |
---|
| 2042 | + |
---|
| 2043 | + case ldr_op: |
---|
| 2044 | + run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa( |
---|
| 2045 | + vcpu->arch.host_cp0_badvaddr) & (~0x7); |
---|
| 2046 | + |
---|
| 2047 | + run->mmio.len = 8; |
---|
| 2048 | + imme = vcpu->arch.host_cp0_badvaddr & 0x7; |
---|
| 2049 | + switch (imme) { |
---|
| 2050 | + case 0: |
---|
| 2051 | + vcpu->mmio_needed = 19; /* 8 bytes */ |
---|
| 2052 | + break; |
---|
| 2053 | + case 1: |
---|
| 2054 | + vcpu->mmio_needed = 20; /* 7 bytes */ |
---|
| 2055 | + break; |
---|
| 2056 | + case 2: |
---|
| 2057 | + vcpu->mmio_needed = 21; /* 6 bytes */ |
---|
| 2058 | + break; |
---|
| 2059 | + case 3: |
---|
| 2060 | + vcpu->mmio_needed = 22; /* 5 bytes */ |
---|
| 2061 | + break; |
---|
| 2062 | + case 4: |
---|
| 2063 | + vcpu->mmio_needed = 23; /* 4 bytes */ |
---|
| 2064 | + break; |
---|
| 2065 | + case 5: |
---|
| 2066 | + vcpu->mmio_needed = 24; /* 3 bytes */ |
---|
| 2067 | + break; |
---|
| 2068 | + case 6: |
---|
| 2069 | + vcpu->mmio_needed = 25; /* 2 bytes */ |
---|
| 2070 | + break; |
---|
| 2071 | + case 7: |
---|
| 2072 | + vcpu->mmio_needed = 26; /* 1 byte */ |
---|
| 2073 | + break; |
---|
| 2074 | + default: |
---|
| 2075 | + break; |
---|
| 2076 | + } |
---|
| 2077 | + break; |
---|
| 2078 | +#endif |
---|
| 2079 | + |
---|
| 2080 | +#ifdef CONFIG_CPU_LOONGSON64 |
---|
| 2081 | + case ldc2_op: |
---|
| 2082 | + rt = inst.loongson3_lsdc2_format.rt; |
---|
| 2083 | + switch (inst.loongson3_lsdc2_format.opcode1) { |
---|
| 2084 | + /* |
---|
| 2085 | + * Loongson-3 overridden ldc2 instructions. |
---|
| 2086 | + * opcode1 instruction |
---|
| 2087 | + * 0x0 gslbx: store 1 bytes from GPR |
---|
| 2088 | + * 0x1 gslhx: store 2 bytes from GPR |
---|
| 2089 | + * 0x2 gslwx: store 4 bytes from GPR |
---|
| 2090 | + * 0x3 gsldx: store 8 bytes from GPR |
---|
| 2091 | + */ |
---|
| 2092 | + case 0x0: |
---|
| 2093 | + run->mmio.len = 1; |
---|
| 2094 | + vcpu->mmio_needed = 27; /* signed */ |
---|
| 2095 | + break; |
---|
| 2096 | + case 0x1: |
---|
| 2097 | + run->mmio.len = 2; |
---|
| 2098 | + vcpu->mmio_needed = 28; /* signed */ |
---|
| 2099 | + break; |
---|
| 2100 | + case 0x2: |
---|
| 2101 | + run->mmio.len = 4; |
---|
| 2102 | + vcpu->mmio_needed = 29; /* signed */ |
---|
| 2103 | + break; |
---|
| 2104 | + case 0x3: |
---|
| 2105 | + run->mmio.len = 8; |
---|
| 2106 | + vcpu->mmio_needed = 30; /* signed */ |
---|
| 2107 | + break; |
---|
| 2108 | + default: |
---|
| 2109 | + kvm_err("Godson Extended GS-Load for float not yet supported (inst=0x%08x)\n", |
---|
| 2110 | + inst.word); |
---|
| 2111 | + break; |
---|
| 2112 | + } |
---|
| 2113 | + break; |
---|
| 2114 | +#endif |
---|
1739 | 2115 | |
---|
1740 | 2116 | default: |
---|
1741 | 2117 | kvm_err("Load not yet supported (inst=0x%08x)\n", |
---|
.. | .. |
---|
1746 | 2122 | |
---|
1747 | 2123 | run->mmio.is_write = 0; |
---|
1748 | 2124 | vcpu->mmio_is_write = 0; |
---|
| 2125 | + |
---|
| 2126 | + r = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, |
---|
| 2127 | + run->mmio.phys_addr, run->mmio.len, run->mmio.data); |
---|
| 2128 | + |
---|
| 2129 | + if (!r) { |
---|
| 2130 | + kvm_mips_complete_mmio_load(vcpu); |
---|
| 2131 | + vcpu->mmio_needed = 0; |
---|
| 2132 | + return EMULATE_DONE; |
---|
| 2133 | + } |
---|
| 2134 | + |
---|
1749 | 2135 | return EMULATE_DO_MMIO; |
---|
1750 | 2136 | } |
---|
1751 | 2137 | |
---|
.. | .. |
---|
1753 | 2139 | static enum emulation_result kvm_mips_guest_cache_op(int (*fn)(unsigned long), |
---|
1754 | 2140 | unsigned long curr_pc, |
---|
1755 | 2141 | unsigned long addr, |
---|
1756 | | - struct kvm_run *run, |
---|
1757 | 2142 | struct kvm_vcpu *vcpu, |
---|
1758 | 2143 | u32 cause) |
---|
1759 | 2144 | { |
---|
.. | .. |
---|
1781 | 2166 | /* no matching guest TLB */ |
---|
1782 | 2167 | vcpu->arch.host_cp0_badvaddr = addr; |
---|
1783 | 2168 | vcpu->arch.pc = curr_pc; |
---|
1784 | | - kvm_mips_emulate_tlbmiss_ld(cause, NULL, run, vcpu); |
---|
| 2169 | + kvm_mips_emulate_tlbmiss_ld(cause, NULL, vcpu); |
---|
1785 | 2170 | return EMULATE_EXCEPT; |
---|
1786 | 2171 | case KVM_MIPS_TLBINV: |
---|
1787 | 2172 | /* invalid matching guest TLB */ |
---|
1788 | 2173 | vcpu->arch.host_cp0_badvaddr = addr; |
---|
1789 | 2174 | vcpu->arch.pc = curr_pc; |
---|
1790 | | - kvm_mips_emulate_tlbinv_ld(cause, NULL, run, vcpu); |
---|
| 2175 | + kvm_mips_emulate_tlbinv_ld(cause, NULL, vcpu); |
---|
1791 | 2176 | return EMULATE_EXCEPT; |
---|
1792 | 2177 | default: |
---|
1793 | 2178 | break; |
---|
1794 | | - }; |
---|
| 2179 | + } |
---|
1795 | 2180 | } |
---|
1796 | 2181 | } |
---|
1797 | 2182 | |
---|
1798 | 2183 | enum emulation_result kvm_mips_emulate_cache(union mips_instruction inst, |
---|
1799 | 2184 | u32 *opc, u32 cause, |
---|
1800 | | - struct kvm_run *run, |
---|
1801 | 2185 | struct kvm_vcpu *vcpu) |
---|
1802 | 2186 | { |
---|
1803 | 2187 | enum emulation_result er = EMULATE_DONE; |
---|
.. | .. |
---|
1887 | 2271 | * guest's behalf. |
---|
1888 | 2272 | */ |
---|
1889 | 2273 | er = kvm_mips_guest_cache_op(protected_writeback_dcache_line, |
---|
1890 | | - curr_pc, va, run, vcpu, cause); |
---|
| 2274 | + curr_pc, va, vcpu, cause); |
---|
1891 | 2275 | if (er != EMULATE_DONE) |
---|
1892 | 2276 | goto done; |
---|
1893 | 2277 | #ifdef CONFIG_KVM_MIPS_DYN_TRANS |
---|
.. | .. |
---|
1900 | 2284 | } else if (op_inst == Hit_Invalidate_I) { |
---|
1901 | 2285 | /* Perform the icache synchronisation on the guest's behalf */ |
---|
1902 | 2286 | er = kvm_mips_guest_cache_op(protected_writeback_dcache_line, |
---|
1903 | | - curr_pc, va, run, vcpu, cause); |
---|
| 2287 | + curr_pc, va, vcpu, cause); |
---|
1904 | 2288 | if (er != EMULATE_DONE) |
---|
1905 | 2289 | goto done; |
---|
1906 | 2290 | er = kvm_mips_guest_cache_op(protected_flush_icache_line, |
---|
1907 | | - curr_pc, va, run, vcpu, cause); |
---|
| 2291 | + curr_pc, va, vcpu, cause); |
---|
1908 | 2292 | if (er != EMULATE_DONE) |
---|
1909 | 2293 | goto done; |
---|
1910 | 2294 | |
---|
.. | .. |
---|
1930 | 2314 | } |
---|
1931 | 2315 | |
---|
1932 | 2316 | enum emulation_result kvm_mips_emulate_inst(u32 cause, u32 *opc, |
---|
1933 | | - struct kvm_run *run, |
---|
1934 | 2317 | struct kvm_vcpu *vcpu) |
---|
1935 | 2318 | { |
---|
1936 | 2319 | union mips_instruction inst; |
---|
.. | .. |
---|
1946 | 2329 | |
---|
1947 | 2330 | switch (inst.r_format.opcode) { |
---|
1948 | 2331 | case cop0_op: |
---|
1949 | | - er = kvm_mips_emulate_CP0(inst, opc, cause, run, vcpu); |
---|
| 2332 | + er = kvm_mips_emulate_CP0(inst, opc, cause, vcpu); |
---|
1950 | 2333 | break; |
---|
1951 | 2334 | |
---|
1952 | 2335 | #ifndef CONFIG_CPU_MIPSR6 |
---|
1953 | 2336 | case cache_op: |
---|
1954 | 2337 | ++vcpu->stat.cache_exits; |
---|
1955 | 2338 | trace_kvm_exit(vcpu, KVM_TRACE_EXIT_CACHE); |
---|
1956 | | - er = kvm_mips_emulate_cache(inst, opc, cause, run, vcpu); |
---|
| 2339 | + er = kvm_mips_emulate_cache(inst, opc, cause, vcpu); |
---|
1957 | 2340 | break; |
---|
1958 | 2341 | #else |
---|
1959 | 2342 | case spec3_op: |
---|
.. | .. |
---|
1961 | 2344 | case cache6_op: |
---|
1962 | 2345 | ++vcpu->stat.cache_exits; |
---|
1963 | 2346 | trace_kvm_exit(vcpu, KVM_TRACE_EXIT_CACHE); |
---|
1964 | | - er = kvm_mips_emulate_cache(inst, opc, cause, run, |
---|
| 2347 | + er = kvm_mips_emulate_cache(inst, opc, cause, |
---|
1965 | 2348 | vcpu); |
---|
1966 | 2349 | break; |
---|
1967 | 2350 | default: |
---|
1968 | 2351 | goto unknown; |
---|
1969 | | - }; |
---|
| 2352 | + } |
---|
1970 | 2353 | break; |
---|
1971 | 2354 | unknown: |
---|
1972 | 2355 | #endif |
---|
.. | .. |
---|
2001 | 2384 | |
---|
2002 | 2385 | enum emulation_result kvm_mips_emulate_syscall(u32 cause, |
---|
2003 | 2386 | u32 *opc, |
---|
2004 | | - struct kvm_run *run, |
---|
2005 | 2387 | struct kvm_vcpu *vcpu) |
---|
2006 | 2388 | { |
---|
2007 | 2389 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2036 | 2418 | |
---|
2037 | 2419 | enum emulation_result kvm_mips_emulate_tlbmiss_ld(u32 cause, |
---|
2038 | 2420 | u32 *opc, |
---|
2039 | | - struct kvm_run *run, |
---|
2040 | 2421 | struct kvm_vcpu *vcpu) |
---|
2041 | 2422 | { |
---|
2042 | 2423 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2080 | 2461 | |
---|
2081 | 2462 | enum emulation_result kvm_mips_emulate_tlbinv_ld(u32 cause, |
---|
2082 | 2463 | u32 *opc, |
---|
2083 | | - struct kvm_run *run, |
---|
2084 | 2464 | struct kvm_vcpu *vcpu) |
---|
2085 | 2465 | { |
---|
2086 | 2466 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2122 | 2502 | |
---|
2123 | 2503 | enum emulation_result kvm_mips_emulate_tlbmiss_st(u32 cause, |
---|
2124 | 2504 | u32 *opc, |
---|
2125 | | - struct kvm_run *run, |
---|
2126 | 2505 | struct kvm_vcpu *vcpu) |
---|
2127 | 2506 | { |
---|
2128 | 2507 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2164 | 2543 | |
---|
2165 | 2544 | enum emulation_result kvm_mips_emulate_tlbinv_st(u32 cause, |
---|
2166 | 2545 | u32 *opc, |
---|
2167 | | - struct kvm_run *run, |
---|
2168 | 2546 | struct kvm_vcpu *vcpu) |
---|
2169 | 2547 | { |
---|
2170 | 2548 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2205 | 2583 | |
---|
2206 | 2584 | enum emulation_result kvm_mips_emulate_tlbmod(u32 cause, |
---|
2207 | 2585 | u32 *opc, |
---|
2208 | | - struct kvm_run *run, |
---|
2209 | 2586 | struct kvm_vcpu *vcpu) |
---|
2210 | 2587 | { |
---|
2211 | 2588 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2245 | 2622 | |
---|
2246 | 2623 | enum emulation_result kvm_mips_emulate_fpu_exc(u32 cause, |
---|
2247 | 2624 | u32 *opc, |
---|
2248 | | - struct kvm_run *run, |
---|
2249 | 2625 | struct kvm_vcpu *vcpu) |
---|
2250 | 2626 | { |
---|
2251 | 2627 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2274 | 2650 | |
---|
2275 | 2651 | enum emulation_result kvm_mips_emulate_ri_exc(u32 cause, |
---|
2276 | 2652 | u32 *opc, |
---|
2277 | | - struct kvm_run *run, |
---|
2278 | 2653 | struct kvm_vcpu *vcpu) |
---|
2279 | 2654 | { |
---|
2280 | 2655 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2309 | 2684 | |
---|
2310 | 2685 | enum emulation_result kvm_mips_emulate_bp_exc(u32 cause, |
---|
2311 | 2686 | u32 *opc, |
---|
2312 | | - struct kvm_run *run, |
---|
2313 | 2687 | struct kvm_vcpu *vcpu) |
---|
2314 | 2688 | { |
---|
2315 | 2689 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2344 | 2718 | |
---|
2345 | 2719 | enum emulation_result kvm_mips_emulate_trap_exc(u32 cause, |
---|
2346 | 2720 | u32 *opc, |
---|
2347 | | - struct kvm_run *run, |
---|
2348 | 2721 | struct kvm_vcpu *vcpu) |
---|
2349 | 2722 | { |
---|
2350 | 2723 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2379 | 2752 | |
---|
2380 | 2753 | enum emulation_result kvm_mips_emulate_msafpe_exc(u32 cause, |
---|
2381 | 2754 | u32 *opc, |
---|
2382 | | - struct kvm_run *run, |
---|
2383 | 2755 | struct kvm_vcpu *vcpu) |
---|
2384 | 2756 | { |
---|
2385 | 2757 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2414 | 2786 | |
---|
2415 | 2787 | enum emulation_result kvm_mips_emulate_fpe_exc(u32 cause, |
---|
2416 | 2788 | u32 *opc, |
---|
2417 | | - struct kvm_run *run, |
---|
2418 | 2789 | struct kvm_vcpu *vcpu) |
---|
2419 | 2790 | { |
---|
2420 | 2791 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2449 | 2820 | |
---|
2450 | 2821 | enum emulation_result kvm_mips_emulate_msadis_exc(u32 cause, |
---|
2451 | 2822 | u32 *opc, |
---|
2452 | | - struct kvm_run *run, |
---|
2453 | 2823 | struct kvm_vcpu *vcpu) |
---|
2454 | 2824 | { |
---|
2455 | 2825 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2483 | 2853 | } |
---|
2484 | 2854 | |
---|
2485 | 2855 | enum emulation_result kvm_mips_handle_ri(u32 cause, u32 *opc, |
---|
2486 | | - struct kvm_run *run, |
---|
2487 | 2856 | struct kvm_vcpu *vcpu) |
---|
2488 | 2857 | { |
---|
2489 | 2858 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
---|
.. | .. |
---|
2572 | 2941 | * branch target), and pass the RI exception to the guest OS. |
---|
2573 | 2942 | */ |
---|
2574 | 2943 | vcpu->arch.pc = curr_pc; |
---|
2575 | | - return kvm_mips_emulate_ri_exc(cause, opc, run, vcpu); |
---|
| 2944 | + return kvm_mips_emulate_ri_exc(cause, opc, vcpu); |
---|
2576 | 2945 | } |
---|
2577 | 2946 | |
---|
2578 | | -enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, |
---|
2579 | | - struct kvm_run *run) |
---|
| 2947 | +enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu) |
---|
2580 | 2948 | { |
---|
| 2949 | + struct kvm_run *run = vcpu->run; |
---|
2581 | 2950 | unsigned long *gpr = &vcpu->arch.gprs[vcpu->arch.io_gpr]; |
---|
2582 | 2951 | enum emulation_result er = EMULATE_DONE; |
---|
2583 | 2952 | |
---|
.. | .. |
---|
2592 | 2961 | |
---|
2593 | 2962 | switch (run->mmio.len) { |
---|
2594 | 2963 | case 8: |
---|
2595 | | - *gpr = *(s64 *)run->mmio.data; |
---|
| 2964 | + switch (vcpu->mmio_needed) { |
---|
| 2965 | + case 11: |
---|
| 2966 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffffff) | |
---|
| 2967 | + (((*(s64 *)run->mmio.data) & 0xff) << 56); |
---|
| 2968 | + break; |
---|
| 2969 | + case 12: |
---|
| 2970 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffff) | |
---|
| 2971 | + (((*(s64 *)run->mmio.data) & 0xffff) << 48); |
---|
| 2972 | + break; |
---|
| 2973 | + case 13: |
---|
| 2974 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffff) | |
---|
| 2975 | + (((*(s64 *)run->mmio.data) & 0xffffff) << 40); |
---|
| 2976 | + break; |
---|
| 2977 | + case 14: |
---|
| 2978 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffff) | |
---|
| 2979 | + (((*(s64 *)run->mmio.data) & 0xffffffff) << 32); |
---|
| 2980 | + break; |
---|
| 2981 | + case 15: |
---|
| 2982 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff) | |
---|
| 2983 | + (((*(s64 *)run->mmio.data) & 0xffffffffff) << 24); |
---|
| 2984 | + break; |
---|
| 2985 | + case 16: |
---|
| 2986 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff) | |
---|
| 2987 | + (((*(s64 *)run->mmio.data) & 0xffffffffffff) << 16); |
---|
| 2988 | + break; |
---|
| 2989 | + case 17: |
---|
| 2990 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff) | |
---|
| 2991 | + (((*(s64 *)run->mmio.data) & 0xffffffffffffff) << 8); |
---|
| 2992 | + break; |
---|
| 2993 | + case 18: |
---|
| 2994 | + case 19: |
---|
| 2995 | + *gpr = *(s64 *)run->mmio.data; |
---|
| 2996 | + break; |
---|
| 2997 | + case 20: |
---|
| 2998 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff00000000000000) | |
---|
| 2999 | + ((((*(s64 *)run->mmio.data)) >> 8) & 0xffffffffffffff); |
---|
| 3000 | + break; |
---|
| 3001 | + case 21: |
---|
| 3002 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff000000000000) | |
---|
| 3003 | + ((((*(s64 *)run->mmio.data)) >> 16) & 0xffffffffffff); |
---|
| 3004 | + break; |
---|
| 3005 | + case 22: |
---|
| 3006 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff0000000000) | |
---|
| 3007 | + ((((*(s64 *)run->mmio.data)) >> 24) & 0xffffffffff); |
---|
| 3008 | + break; |
---|
| 3009 | + case 23: |
---|
| 3010 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffff00000000) | |
---|
| 3011 | + ((((*(s64 *)run->mmio.data)) >> 32) & 0xffffffff); |
---|
| 3012 | + break; |
---|
| 3013 | + case 24: |
---|
| 3014 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffff000000) | |
---|
| 3015 | + ((((*(s64 *)run->mmio.data)) >> 40) & 0xffffff); |
---|
| 3016 | + break; |
---|
| 3017 | + case 25: |
---|
| 3018 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffff0000) | |
---|
| 3019 | + ((((*(s64 *)run->mmio.data)) >> 48) & 0xffff); |
---|
| 3020 | + break; |
---|
| 3021 | + case 26: |
---|
| 3022 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffffff00) | |
---|
| 3023 | + ((((*(s64 *)run->mmio.data)) >> 56) & 0xff); |
---|
| 3024 | + break; |
---|
| 3025 | + default: |
---|
| 3026 | + *gpr = *(s64 *)run->mmio.data; |
---|
| 3027 | + } |
---|
2596 | 3028 | break; |
---|
2597 | 3029 | |
---|
2598 | 3030 | case 4: |
---|
2599 | | - if (vcpu->mmio_needed == 2) |
---|
2600 | | - *gpr = *(s32 *)run->mmio.data; |
---|
2601 | | - else |
---|
| 3031 | + switch (vcpu->mmio_needed) { |
---|
| 3032 | + case 1: |
---|
2602 | 3033 | *gpr = *(u32 *)run->mmio.data; |
---|
| 3034 | + break; |
---|
| 3035 | + case 2: |
---|
| 3036 | + *gpr = *(s32 *)run->mmio.data; |
---|
| 3037 | + break; |
---|
| 3038 | + case 3: |
---|
| 3039 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff) | |
---|
| 3040 | + (((*(s32 *)run->mmio.data) & 0xff) << 24); |
---|
| 3041 | + break; |
---|
| 3042 | + case 4: |
---|
| 3043 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff) | |
---|
| 3044 | + (((*(s32 *)run->mmio.data) & 0xffff) << 16); |
---|
| 3045 | + break; |
---|
| 3046 | + case 5: |
---|
| 3047 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff) | |
---|
| 3048 | + (((*(s32 *)run->mmio.data) & 0xffffff) << 8); |
---|
| 3049 | + break; |
---|
| 3050 | + case 6: |
---|
| 3051 | + case 7: |
---|
| 3052 | + *gpr = *(s32 *)run->mmio.data; |
---|
| 3053 | + break; |
---|
| 3054 | + case 8: |
---|
| 3055 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff000000) | |
---|
| 3056 | + ((((*(s32 *)run->mmio.data)) >> 8) & 0xffffff); |
---|
| 3057 | + break; |
---|
| 3058 | + case 9: |
---|
| 3059 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff0000) | |
---|
| 3060 | + ((((*(s32 *)run->mmio.data)) >> 16) & 0xffff); |
---|
| 3061 | + break; |
---|
| 3062 | + case 10: |
---|
| 3063 | + *gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff00) | |
---|
| 3064 | + ((((*(s32 *)run->mmio.data)) >> 24) & 0xff); |
---|
| 3065 | + break; |
---|
| 3066 | + default: |
---|
| 3067 | + *gpr = *(s32 *)run->mmio.data; |
---|
| 3068 | + } |
---|
2603 | 3069 | break; |
---|
2604 | 3070 | |
---|
2605 | 3071 | case 2: |
---|
2606 | | - if (vcpu->mmio_needed == 2) |
---|
2607 | | - *gpr = *(s16 *) run->mmio.data; |
---|
2608 | | - else |
---|
| 3072 | + if (vcpu->mmio_needed == 1) |
---|
2609 | 3073 | *gpr = *(u16 *)run->mmio.data; |
---|
| 3074 | + else |
---|
| 3075 | + *gpr = *(s16 *)run->mmio.data; |
---|
2610 | 3076 | |
---|
2611 | 3077 | break; |
---|
2612 | 3078 | case 1: |
---|
2613 | | - if (vcpu->mmio_needed == 2) |
---|
2614 | | - *gpr = *(s8 *) run->mmio.data; |
---|
| 3079 | + if (vcpu->mmio_needed == 1) |
---|
| 3080 | + *gpr = *(u8 *)run->mmio.data; |
---|
2615 | 3081 | else |
---|
2616 | | - *gpr = *(u8 *) run->mmio.data; |
---|
| 3082 | + *gpr = *(s8 *)run->mmio.data; |
---|
2617 | 3083 | break; |
---|
2618 | 3084 | } |
---|
2619 | 3085 | |
---|
.. | .. |
---|
2623 | 3089 | |
---|
2624 | 3090 | static enum emulation_result kvm_mips_emulate_exc(u32 cause, |
---|
2625 | 3091 | u32 *opc, |
---|
2626 | | - struct kvm_run *run, |
---|
2627 | 3092 | struct kvm_vcpu *vcpu) |
---|
2628 | 3093 | { |
---|
2629 | 3094 | u32 exccode = (cause >> CAUSEB_EXCCODE) & 0x1f; |
---|
.. | .. |
---|
2661 | 3126 | |
---|
2662 | 3127 | enum emulation_result kvm_mips_check_privilege(u32 cause, |
---|
2663 | 3128 | u32 *opc, |
---|
2664 | | - struct kvm_run *run, |
---|
2665 | 3129 | struct kvm_vcpu *vcpu) |
---|
2666 | 3130 | { |
---|
2667 | 3131 | enum emulation_result er = EMULATE_DONE; |
---|
.. | .. |
---|
2743 | 3207 | } |
---|
2744 | 3208 | |
---|
2745 | 3209 | if (er == EMULATE_PRIV_FAIL) |
---|
2746 | | - kvm_mips_emulate_exc(cause, opc, run, vcpu); |
---|
| 3210 | + kvm_mips_emulate_exc(cause, opc, vcpu); |
---|
2747 | 3211 | |
---|
2748 | 3212 | return er; |
---|
2749 | 3213 | } |
---|
.. | .. |
---|
2757 | 3221 | */ |
---|
2758 | 3222 | enum emulation_result kvm_mips_handle_tlbmiss(u32 cause, |
---|
2759 | 3223 | u32 *opc, |
---|
2760 | | - struct kvm_run *run, |
---|
2761 | 3224 | struct kvm_vcpu *vcpu, |
---|
2762 | 3225 | bool write_fault) |
---|
2763 | 3226 | { |
---|
.. | .. |
---|
2781 | 3244 | KVM_ENTRYHI_ASID)); |
---|
2782 | 3245 | if (index < 0) { |
---|
2783 | 3246 | if (exccode == EXCCODE_TLBL) { |
---|
2784 | | - er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu); |
---|
| 3247 | + er = kvm_mips_emulate_tlbmiss_ld(cause, opc, vcpu); |
---|
2785 | 3248 | } else if (exccode == EXCCODE_TLBS) { |
---|
2786 | | - er = kvm_mips_emulate_tlbmiss_st(cause, opc, run, vcpu); |
---|
| 3249 | + er = kvm_mips_emulate_tlbmiss_st(cause, opc, vcpu); |
---|
2787 | 3250 | } else { |
---|
2788 | 3251 | kvm_err("%s: invalid exc code: %d\n", __func__, |
---|
2789 | 3252 | exccode); |
---|
.. | .. |
---|
2798 | 3261 | */ |
---|
2799 | 3262 | if (!TLB_IS_VALID(*tlb, va)) { |
---|
2800 | 3263 | if (exccode == EXCCODE_TLBL) { |
---|
2801 | | - er = kvm_mips_emulate_tlbinv_ld(cause, opc, run, |
---|
| 3264 | + er = kvm_mips_emulate_tlbinv_ld(cause, opc, |
---|
2802 | 3265 | vcpu); |
---|
2803 | 3266 | } else if (exccode == EXCCODE_TLBS) { |
---|
2804 | | - er = kvm_mips_emulate_tlbinv_st(cause, opc, run, |
---|
| 3267 | + er = kvm_mips_emulate_tlbinv_st(cause, opc, |
---|
2805 | 3268 | vcpu); |
---|
2806 | 3269 | } else { |
---|
2807 | 3270 | kvm_err("%s: invalid exc code: %d\n", __func__, |
---|