vz.c (273819a6a5ab493500c14889b161bf5bc2265736) | vz.c (d42a008f86ba3d715d31788fc5143a4de5685d33) |
---|---|
1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * KVM/MIPS: Support for hardware virtualization extensions 7 * 8 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. --- 120 unchanged lines hidden (view full) --- 129/* 130 * VZ optionally allows these additional Config bits to be written by root: 131 * Config: M, [MT] 132 * Config1: M, [MMUSize-1, C2, MD, PC, WR, CA], FP 133 * Config2: M 134 * Config3: M, MSAP, [BPG], ULRI, [DSP2P, DSPP], CTXTC, [ITL, LPA, VEIC, 135 * VInt, SP, CDMM, MT, SM, TL] 136 * Config4: M, [VTLBSizeExt, MMUSizeExt] | 1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * KVM/MIPS: Support for hardware virtualization extensions 7 * 8 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. --- 120 unchanged lines hidden (view full) --- 129/* 130 * VZ optionally allows these additional Config bits to be written by root: 131 * Config: M, [MT] 132 * Config1: M, [MMUSize-1, C2, MD, PC, WR, CA], FP 133 * Config2: M 134 * Config3: M, MSAP, [BPG], ULRI, [DSP2P, DSPP], CTXTC, [ITL, LPA, VEIC, 135 * VInt, SP, CDMM, MT, SM, TL] 136 * Config4: M, [VTLBSizeExt, MMUSizeExt] |
137 * Config5: [MRP] | 137 * Config5: MRP |
138 */ 139 140static inline unsigned int kvm_vz_config_user_wrmask(struct kvm_vcpu *vcpu) 141{ 142 return kvm_vz_config_guest_wrmask(vcpu) | MIPS_CONF_M; 143} 144 145static inline unsigned int kvm_vz_config1_user_wrmask(struct kvm_vcpu *vcpu) --- 26 unchanged lines hidden (view full) --- 172 173static inline unsigned int kvm_vz_config4_user_wrmask(struct kvm_vcpu *vcpu) 174{ 175 return kvm_vz_config4_guest_wrmask(vcpu) | MIPS_CONF_M; 176} 177 178static inline unsigned int kvm_vz_config5_user_wrmask(struct kvm_vcpu *vcpu) 179{ | 138 */ 139 140static inline unsigned int kvm_vz_config_user_wrmask(struct kvm_vcpu *vcpu) 141{ 142 return kvm_vz_config_guest_wrmask(vcpu) | MIPS_CONF_M; 143} 144 145static inline unsigned int kvm_vz_config1_user_wrmask(struct kvm_vcpu *vcpu) --- 26 unchanged lines hidden (view full) --- 172 173static inline unsigned int kvm_vz_config4_user_wrmask(struct kvm_vcpu *vcpu) 174{ 175 return kvm_vz_config4_guest_wrmask(vcpu) | MIPS_CONF_M; 176} 177 178static inline unsigned int kvm_vz_config5_user_wrmask(struct kvm_vcpu *vcpu) 179{ |
180 return kvm_vz_config5_guest_wrmask(vcpu); | 180 return kvm_vz_config5_guest_wrmask(vcpu) | MIPS_CONF5_MRP; |
181} 182 183static gpa_t kvm_vz_gva_to_gpa_cb(gva_t gva) 184{ 185 /* VZ guest has already converted gva to gpa */ 186 return gva; 187} 188 --- 491 unchanged lines hidden (view full) --- 680 kvm_err("Exception Code: %d not handled @ PC: %p, inst: 0x%08x BadVaddr: %#lx Status: %#x\n", 681 exccode, opc, inst, badvaddr, 682 read_gc0_status()); 683 kvm_arch_vcpu_dump_regs(vcpu); 684 vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; 685 return RESUME_HOST; 686} 687 | 181} 182 183static gpa_t kvm_vz_gva_to_gpa_cb(gva_t gva) 184{ 185 /* VZ guest has already converted gva to gpa */ 186 return gva; 187} 188 --- 491 unchanged lines hidden (view full) --- 680 kvm_err("Exception Code: %d not handled @ PC: %p, inst: 0x%08x BadVaddr: %#lx Status: %#x\n", 681 exccode, opc, inst, badvaddr, 682 read_gc0_status()); 683 kvm_arch_vcpu_dump_regs(vcpu); 684 vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; 685 return RESUME_HOST; 686} 687 |
688static unsigned long mips_process_maar(unsigned int op, unsigned long val) 689{ 690 /* Mask off unused bits */ 691 unsigned long mask = 0xfffff000 | MIPS_MAAR_S | MIPS_MAAR_VL; 692 693 if (read_gc0_pagegrain() & PG_ELPA) 694 mask |= 0x00ffffff00000000ull; 695 if (cpu_guest_has_mvh) 696 mask |= MIPS_MAAR_VH; 697 698 /* Set or clear VH */ 699 if (op == mtc_op) { 700 /* clear VH */ 701 val &= ~MIPS_MAAR_VH; 702 } else if (op == dmtc_op) { 703 /* set VH to match VL */ 704 val &= ~MIPS_MAAR_VH; 705 if (val & MIPS_MAAR_VL) 706 val |= MIPS_MAAR_VH; 707 } 708 709 return val & mask; 710} 711 712static void kvm_write_maari(struct kvm_vcpu *vcpu, unsigned long val) 713{ 714 struct mips_coproc *cop0 = vcpu->arch.cop0; 715 716 val &= MIPS_MAARI_INDEX; 717 if (val == MIPS_MAARI_INDEX) 718 kvm_write_sw_gc0_maari(cop0, ARRAY_SIZE(vcpu->arch.maar) - 1); 719 else if (val < ARRAY_SIZE(vcpu->arch.maar)) 720 kvm_write_sw_gc0_maari(cop0, val); 721} 722 |
|
688static enum emulation_result kvm_vz_gpsi_cop0(union mips_instruction inst, 689 u32 *opc, u32 cause, 690 struct kvm_run *run, 691 struct kvm_vcpu *vcpu) 692{ 693 struct mips_coproc *cop0 = vcpu->arch.cop0; 694 enum emulation_result er = EMULATE_DONE; 695 u32 rt, rd, sel; --- 36 unchanged lines hidden (view full) --- 732 val = read_gc0_compare(); 733 } else if (rd == MIPS_CP0_LLADDR && 734 sel == 0) { /* LLAddr */ 735 if (cpu_guest_has_rw_llb) 736 val = read_gc0_lladdr() & 737 MIPS_LLADDR_LLB; 738 else 739 val = 0; | 723static enum emulation_result kvm_vz_gpsi_cop0(union mips_instruction inst, 724 u32 *opc, u32 cause, 725 struct kvm_run *run, 726 struct kvm_vcpu *vcpu) 727{ 728 struct mips_coproc *cop0 = vcpu->arch.cop0; 729 enum emulation_result er = EMULATE_DONE; 730 u32 rt, rd, sel; --- 36 unchanged lines hidden (view full) --- 767 val = read_gc0_compare(); 768 } else if (rd == MIPS_CP0_LLADDR && 769 sel == 0) { /* LLAddr */ 770 if (cpu_guest_has_rw_llb) 771 val = read_gc0_lladdr() & 772 MIPS_LLADDR_LLB; 773 else 774 val = 0; |
775 } else if (rd == MIPS_CP0_LLADDR && 776 sel == 1 && /* MAAR */ 777 cpu_guest_has_maar && 778 !cpu_guest_has_dyn_maar) { 779 /* MAARI must be in range */ 780 BUG_ON(kvm_read_sw_gc0_maari(cop0) >= 781 ARRAY_SIZE(vcpu->arch.maar)); 782 val = vcpu->arch.maar[ 783 kvm_read_sw_gc0_maari(cop0)]; |
|
740 } else if ((rd == MIPS_CP0_PRID && 741 (sel == 0 || /* PRid */ 742 sel == 2 || /* CDMMBase */ 743 sel == 3)) || /* CMGCRBase */ 744 (rd == MIPS_CP0_STATUS && 745 (sel == 2 || /* SRSCtl */ 746 sel == 3)) || /* SRSMap */ 747 (rd == MIPS_CP0_CONFIG && 748 (sel == 7)) || /* Config7 */ | 784 } else if ((rd == MIPS_CP0_PRID && 785 (sel == 0 || /* PRid */ 786 sel == 2 || /* CDMMBase */ 787 sel == 3)) || /* CMGCRBase */ 788 (rd == MIPS_CP0_STATUS && 789 (sel == 2 || /* SRSCtl */ 790 sel == 3)) || /* SRSMap */ 791 (rd == MIPS_CP0_CONFIG && 792 (sel == 7)) || /* Config7 */ |
793 (rd == MIPS_CP0_LLADDR && 794 (sel == 2) && /* MAARI */ 795 cpu_guest_has_maar && 796 !cpu_guest_has_dyn_maar) || |
|
749 (rd == MIPS_CP0_ERRCTL && 750 (sel == 0))) { /* ErrCtl */ 751 val = cop0->reg[rd][sel]; 752 } else { 753 val = 0; 754 er = EMULATE_FAIL; 755 } 756 --- 31 unchanged lines hidden (view full) --- 788 sel == 0) { /* LLAddr */ 789 /* 790 * P5600 generates GPSI on guest MTC0 LLAddr. 791 * Only allow the guest to clear LLB. 792 */ 793 if (cpu_guest_has_rw_llb && 794 !(val & MIPS_LLADDR_LLB)) 795 write_gc0_lladdr(0); | 797 (rd == MIPS_CP0_ERRCTL && 798 (sel == 0))) { /* ErrCtl */ 799 val = cop0->reg[rd][sel]; 800 } else { 801 val = 0; 802 er = EMULATE_FAIL; 803 } 804 --- 31 unchanged lines hidden (view full) --- 836 sel == 0) { /* LLAddr */ 837 /* 838 * P5600 generates GPSI on guest MTC0 LLAddr. 839 * Only allow the guest to clear LLB. 840 */ 841 if (cpu_guest_has_rw_llb && 842 !(val & MIPS_LLADDR_LLB)) 843 write_gc0_lladdr(0); |
844 } else if (rd == MIPS_CP0_LLADDR && 845 sel == 1 && /* MAAR */ 846 cpu_guest_has_maar && 847 !cpu_guest_has_dyn_maar) { 848 val = mips_process_maar(inst.c0r_format.rs, 849 val); 850 851 /* MAARI must be in range */ 852 BUG_ON(kvm_read_sw_gc0_maari(cop0) >= 853 ARRAY_SIZE(vcpu->arch.maar)); 854 vcpu->arch.maar[kvm_read_sw_gc0_maari(cop0)] = 855 val; 856 } else if (rd == MIPS_CP0_LLADDR && 857 (sel == 2) && /* MAARI */ 858 cpu_guest_has_maar && 859 !cpu_guest_has_dyn_maar) { 860 kvm_write_maari(vcpu, val); |
|
796 } else if (rd == MIPS_CP0_ERRCTL && 797 (sel == 0)) { /* ErrCtl */ 798 /* ignore the written value */ 799 } else { 800 er = EMULATE_FAIL; 801 } 802 break; 803 --- 632 unchanged lines hidden (view full) --- 1436 if (cpu_guest_has_badinstrp) 1437 ++ret; 1438 if (cpu_guest_has_contextconfig) 1439 ret += ARRAY_SIZE(kvm_vz_get_one_regs_contextconfig); 1440 if (cpu_guest_has_segments) 1441 ret += ARRAY_SIZE(kvm_vz_get_one_regs_segments); 1442 if (cpu_guest_has_htw) 1443 ret += ARRAY_SIZE(kvm_vz_get_one_regs_htw); | 861 } else if (rd == MIPS_CP0_ERRCTL && 862 (sel == 0)) { /* ErrCtl */ 863 /* ignore the written value */ 864 } else { 865 er = EMULATE_FAIL; 866 } 867 break; 868 --- 632 unchanged lines hidden (view full) --- 1501 if (cpu_guest_has_badinstrp) 1502 ++ret; 1503 if (cpu_guest_has_contextconfig) 1504 ret += ARRAY_SIZE(kvm_vz_get_one_regs_contextconfig); 1505 if (cpu_guest_has_segments) 1506 ret += ARRAY_SIZE(kvm_vz_get_one_regs_segments); 1507 if (cpu_guest_has_htw) 1508 ret += ARRAY_SIZE(kvm_vz_get_one_regs_htw); |
1509 if (cpu_guest_has_maar && !cpu_guest_has_dyn_maar) 1510 ret += 1 + ARRAY_SIZE(vcpu->arch.maar); |
|
1444 ret += __arch_hweight8(cpu_data[0].guest.kscratch_mask); 1445 1446 return ret; 1447} 1448 1449static int kvm_vz_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices) 1450{ 1451 u64 index; --- 35 unchanged lines hidden (view full) --- 1487 indices += ARRAY_SIZE(kvm_vz_get_one_regs_segments); 1488 } 1489 if (cpu_guest_has_htw) { 1490 if (copy_to_user(indices, kvm_vz_get_one_regs_htw, 1491 sizeof(kvm_vz_get_one_regs_htw))) 1492 return -EFAULT; 1493 indices += ARRAY_SIZE(kvm_vz_get_one_regs_htw); 1494 } | 1511 ret += __arch_hweight8(cpu_data[0].guest.kscratch_mask); 1512 1513 return ret; 1514} 1515 1516static int kvm_vz_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices) 1517{ 1518 u64 index; --- 35 unchanged lines hidden (view full) --- 1554 indices += ARRAY_SIZE(kvm_vz_get_one_regs_segments); 1555 } 1556 if (cpu_guest_has_htw) { 1557 if (copy_to_user(indices, kvm_vz_get_one_regs_htw, 1558 sizeof(kvm_vz_get_one_regs_htw))) 1559 return -EFAULT; 1560 indices += ARRAY_SIZE(kvm_vz_get_one_regs_htw); 1561 } |
1562 if (cpu_guest_has_maar && !cpu_guest_has_dyn_maar) { 1563 for (i = 0; i < ARRAY_SIZE(vcpu->arch.maar); ++i) { 1564 index = KVM_REG_MIPS_CP0_MAAR(i); 1565 if (copy_to_user(indices, &index, sizeof(index))) 1566 return -EFAULT; 1567 ++indices; 1568 } 1569 1570 index = KVM_REG_MIPS_CP0_MAARI; 1571 if (copy_to_user(indices, &index, sizeof(index))) 1572 return -EFAULT; 1573 ++indices; 1574 } |
|
1495 for (i = 0; i < 6; ++i) { 1496 if (!cpu_guest_has_kscr(i + 2)) 1497 continue; 1498 1499 if (copy_to_user(indices, &kvm_vz_get_one_regs_kscratch[i], 1500 sizeof(kvm_vz_get_one_regs_kscratch[i]))) 1501 return -EFAULT; 1502 ++indices; --- 181 unchanged lines hidden (view full) --- 1684 return -EINVAL; 1685 *v = read_gc0_config4(); 1686 break; 1687 case KVM_REG_MIPS_CP0_CONFIG5: 1688 if (!cpu_guest_has_conf5) 1689 return -EINVAL; 1690 *v = read_gc0_config5(); 1691 break; | 1575 for (i = 0; i < 6; ++i) { 1576 if (!cpu_guest_has_kscr(i + 2)) 1577 continue; 1578 1579 if (copy_to_user(indices, &kvm_vz_get_one_regs_kscratch[i], 1580 sizeof(kvm_vz_get_one_regs_kscratch[i]))) 1581 return -EFAULT; 1582 ++indices; --- 181 unchanged lines hidden (view full) --- 1764 return -EINVAL; 1765 *v = read_gc0_config4(); 1766 break; 1767 case KVM_REG_MIPS_CP0_CONFIG5: 1768 if (!cpu_guest_has_conf5) 1769 return -EINVAL; 1770 *v = read_gc0_config5(); 1771 break; |
1772 case KVM_REG_MIPS_CP0_MAAR(0) ... KVM_REG_MIPS_CP0_MAAR(0x3f): 1773 if (!cpu_guest_has_maar || cpu_guest_has_dyn_maar) 1774 return -EINVAL; 1775 idx = reg->id - KVM_REG_MIPS_CP0_MAAR(0); 1776 if (idx >= ARRAY_SIZE(vcpu->arch.maar)) 1777 return -EINVAL; 1778 *v = vcpu->arch.maar[idx]; 1779 break; 1780 case KVM_REG_MIPS_CP0_MAARI: 1781 if (!cpu_guest_has_maar || cpu_guest_has_dyn_maar) 1782 return -EINVAL; 1783 *v = kvm_read_sw_gc0_maari(vcpu->arch.cop0); 1784 break; |
|
1692#ifdef CONFIG_64BIT 1693 case KVM_REG_MIPS_CP0_XCONTEXT: 1694 *v = read_gc0_xcontext(); 1695 break; 1696#endif 1697 case KVM_REG_MIPS_CP0_ERROREPC: 1698 *v = (long)read_gc0_errorepc(); 1699 break; --- 233 unchanged lines hidden (view full) --- 1933 break; 1934 cur = read_gc0_config5(); 1935 change = (cur ^ v) & kvm_vz_config5_user_wrmask(vcpu); 1936 if (change) { 1937 v = cur ^ change; 1938 write_gc0_config5(v); 1939 } 1940 break; | 1785#ifdef CONFIG_64BIT 1786 case KVM_REG_MIPS_CP0_XCONTEXT: 1787 *v = read_gc0_xcontext(); 1788 break; 1789#endif 1790 case KVM_REG_MIPS_CP0_ERROREPC: 1791 *v = (long)read_gc0_errorepc(); 1792 break; --- 233 unchanged lines hidden (view full) --- 2026 break; 2027 cur = read_gc0_config5(); 2028 change = (cur ^ v) & kvm_vz_config5_user_wrmask(vcpu); 2029 if (change) { 2030 v = cur ^ change; 2031 write_gc0_config5(v); 2032 } 2033 break; |
2034 case KVM_REG_MIPS_CP0_MAAR(0) ... KVM_REG_MIPS_CP0_MAAR(0x3f): 2035 if (!cpu_guest_has_maar || cpu_guest_has_dyn_maar) 2036 return -EINVAL; 2037 idx = reg->id - KVM_REG_MIPS_CP0_MAAR(0); 2038 if (idx >= ARRAY_SIZE(vcpu->arch.maar)) 2039 return -EINVAL; 2040 vcpu->arch.maar[idx] = mips_process_maar(dmtc_op, v); 2041 break; 2042 case KVM_REG_MIPS_CP0_MAARI: 2043 if (!cpu_guest_has_maar || cpu_guest_has_dyn_maar) 2044 return -EINVAL; 2045 kvm_write_maari(vcpu, v); 2046 break; |
|
1941#ifdef CONFIG_64BIT 1942 case KVM_REG_MIPS_CP0_XCONTEXT: 1943 write_gc0_xcontext(v); 1944 break; 1945#endif 1946 case KVM_REG_MIPS_CP0_ERROREPC: 1947 write_gc0_errorepc(v); 1948 break; --- 881 unchanged lines hidden --- | 2047#ifdef CONFIG_64BIT 2048 case KVM_REG_MIPS_CP0_XCONTEXT: 2049 write_gc0_xcontext(v); 2050 break; 2051#endif 2052 case KVM_REG_MIPS_CP0_ERROREPC: 2053 write_gc0_errorepc(v); 2054 break; --- 881 unchanged lines hidden --- |