| .. | .. |
|---|
| 23 | 23 | #include <asm/inst.h> |
|---|
| 24 | 24 | #include <asm/mipsregs.h> |
|---|
| 25 | 25 | |
|---|
| 26 | +#include <kvm/iodev.h> |
|---|
| 27 | + |
|---|
| 26 | 28 | /* MIPS KVM register ids */ |
|---|
| 27 | 29 | #define MIPS_CP0_32(_R, _S) \ |
|---|
| 28 | 30 | (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) |
|---|
| .. | .. |
|---|
| 66 | 68 | #define KVM_REG_MIPS_CP0_CONFIG3 MIPS_CP0_32(16, 3) |
|---|
| 67 | 69 | #define KVM_REG_MIPS_CP0_CONFIG4 MIPS_CP0_32(16, 4) |
|---|
| 68 | 70 | #define KVM_REG_MIPS_CP0_CONFIG5 MIPS_CP0_32(16, 5) |
|---|
| 71 | +#define KVM_REG_MIPS_CP0_CONFIG6 MIPS_CP0_32(16, 6) |
|---|
| 69 | 72 | #define KVM_REG_MIPS_CP0_CONFIG7 MIPS_CP0_32(16, 7) |
|---|
| 70 | 73 | #define KVM_REG_MIPS_CP0_MAARI MIPS_CP0_64(17, 2) |
|---|
| 71 | 74 | #define KVM_REG_MIPS_CP0_XCONTEXT MIPS_CP0_64(20, 0) |
|---|
| 75 | +#define KVM_REG_MIPS_CP0_DIAG MIPS_CP0_32(22, 0) |
|---|
| 72 | 76 | #define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0) |
|---|
| 73 | 77 | #define KVM_REG_MIPS_CP0_KSCRATCH1 MIPS_CP0_64(31, 2) |
|---|
| 74 | 78 | #define KVM_REG_MIPS_CP0_KSCRATCH2 MIPS_CP0_64(31, 3) |
|---|
| .. | .. |
|---|
| 78 | 82 | #define KVM_REG_MIPS_CP0_KSCRATCH6 MIPS_CP0_64(31, 7) |
|---|
| 79 | 83 | |
|---|
| 80 | 84 | |
|---|
| 81 | | -#define KVM_MAX_VCPUS 8 |
|---|
| 82 | | -#define KVM_USER_MEM_SLOTS 8 |
|---|
| 85 | +#define KVM_MAX_VCPUS 16 |
|---|
| 86 | +#define KVM_USER_MEM_SLOTS 16 |
|---|
| 83 | 87 | /* memory slots that does not exposed to userspace */ |
|---|
| 84 | 88 | #define KVM_PRIVATE_MEM_SLOTS 0 |
|---|
| 85 | 89 | |
|---|
| .. | .. |
|---|
| 171 | 175 | u64 vz_ghfc_exits; |
|---|
| 172 | 176 | u64 vz_gpa_exits; |
|---|
| 173 | 177 | u64 vz_resvd_exits; |
|---|
| 178 | +#ifdef CONFIG_CPU_LOONGSON64 |
|---|
| 179 | + u64 vz_cpucfg_exits; |
|---|
| 180 | +#endif |
|---|
| 174 | 181 | #endif |
|---|
| 175 | 182 | u64 halt_successful_poll; |
|---|
| 176 | 183 | u64 halt_attempted_poll; |
|---|
| 184 | + u64 halt_poll_success_ns; |
|---|
| 185 | + u64 halt_poll_fail_ns; |
|---|
| 177 | 186 | u64 halt_poll_invalid; |
|---|
| 178 | 187 | u64 halt_wakeup; |
|---|
| 179 | 188 | }; |
|---|
| .. | .. |
|---|
| 181 | 190 | struct kvm_arch_memory_slot { |
|---|
| 182 | 191 | }; |
|---|
| 183 | 192 | |
|---|
| 193 | +#ifdef CONFIG_CPU_LOONGSON64 |
|---|
| 194 | +struct ipi_state { |
|---|
| 195 | + uint32_t status; |
|---|
| 196 | + uint32_t en; |
|---|
| 197 | + uint32_t set; |
|---|
| 198 | + uint32_t clear; |
|---|
| 199 | + uint64_t buf[4]; |
|---|
| 200 | +}; |
|---|
| 201 | + |
|---|
| 202 | +struct loongson_kvm_ipi; |
|---|
| 203 | + |
|---|
| 204 | +struct ipi_io_device { |
|---|
| 205 | + int node_id; |
|---|
| 206 | + struct loongson_kvm_ipi *ipi; |
|---|
| 207 | + struct kvm_io_device device; |
|---|
| 208 | +}; |
|---|
| 209 | + |
|---|
| 210 | +struct loongson_kvm_ipi { |
|---|
| 211 | + spinlock_t lock; |
|---|
| 212 | + struct kvm *kvm; |
|---|
| 213 | + struct ipi_state ipistate[16]; |
|---|
| 214 | + struct ipi_io_device dev_ipi[4]; |
|---|
| 215 | +}; |
|---|
| 216 | +#endif |
|---|
| 217 | + |
|---|
| 184 | 218 | struct kvm_arch { |
|---|
| 185 | 219 | /* Guest physical mm */ |
|---|
| 186 | 220 | struct mm_struct gpa_mm; |
|---|
| 187 | 221 | /* Mask of CPUs needing GPA ASID flush */ |
|---|
| 188 | 222 | cpumask_t asid_flush_mask; |
|---|
| 223 | +#ifdef CONFIG_CPU_LOONGSON64 |
|---|
| 224 | + struct loongson_kvm_ipi ipi; |
|---|
| 225 | +#endif |
|---|
| 189 | 226 | }; |
|---|
| 190 | 227 | |
|---|
| 191 | 228 | #define N_MIPS_COPROC_REGS 32 |
|---|
| .. | .. |
|---|
| 223 | 260 | #define MIPS_CP0_WATCH_LO 18 |
|---|
| 224 | 261 | #define MIPS_CP0_WATCH_HI 19 |
|---|
| 225 | 262 | #define MIPS_CP0_TLB_XCONTEXT 20 |
|---|
| 263 | +#define MIPS_CP0_DIAG 22 |
|---|
| 226 | 264 | #define MIPS_CP0_ECC 26 |
|---|
| 227 | 265 | #define MIPS_CP0_CACHE_ERR 27 |
|---|
| 228 | 266 | #define MIPS_CP0_TAG_LO 28 |
|---|
| .. | .. |
|---|
| 297 | 335 | long tlb_lo[2]; |
|---|
| 298 | 336 | }; |
|---|
| 299 | 337 | |
|---|
| 300 | | -#define KVM_NR_MEM_OBJS 4 |
|---|
| 301 | | - |
|---|
| 302 | | -/* |
|---|
| 303 | | - * We don't want allocation failures within the mmu code, so we preallocate |
|---|
| 304 | | - * enough memory for a single page fault in a cache. |
|---|
| 305 | | - */ |
|---|
| 306 | | -struct kvm_mmu_memory_cache { |
|---|
| 307 | | - int nobjs; |
|---|
| 308 | | - void *objects[KVM_NR_MEM_OBJS]; |
|---|
| 309 | | -}; |
|---|
| 310 | | - |
|---|
| 311 | 338 | #define KVM_MIPS_AUX_FPU 0x1 |
|---|
| 312 | 339 | #define KVM_MIPS_AUX_MSA 0x2 |
|---|
| 313 | 340 | |
|---|
| 314 | 341 | #define KVM_MIPS_GUEST_TLB_SIZE 64 |
|---|
| 315 | 342 | struct kvm_vcpu_arch { |
|---|
| 316 | 343 | void *guest_ebase; |
|---|
| 317 | | - int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu); |
|---|
| 344 | + int (*vcpu_run)(struct kvm_vcpu *vcpu); |
|---|
| 318 | 345 | |
|---|
| 319 | 346 | /* Host registers preserved across guest mode execution */ |
|---|
| 320 | 347 | unsigned long host_stack; |
|---|
| .. | .. |
|---|
| 415 | 442 | unsigned long temp; |
|---|
| 416 | 443 | do { |
|---|
| 417 | 444 | __asm__ __volatile__( |
|---|
| 445 | + " .set push \n" |
|---|
| 418 | 446 | " .set "MIPS_ISA_ARCH_LEVEL" \n" |
|---|
| 419 | 447 | " " __LL "%0, %1 \n" |
|---|
| 420 | 448 | " or %0, %2 \n" |
|---|
| 421 | 449 | " " __SC "%0, %1 \n" |
|---|
| 422 | | - " .set mips0 \n" |
|---|
| 450 | + " .set pop \n" |
|---|
| 423 | 451 | : "=&r" (temp), "+m" (*reg) |
|---|
| 424 | 452 | : "r" (val)); |
|---|
| 425 | 453 | } while (unlikely(!temp)); |
|---|
| .. | .. |
|---|
| 431 | 459 | unsigned long temp; |
|---|
| 432 | 460 | do { |
|---|
| 433 | 461 | __asm__ __volatile__( |
|---|
| 462 | + " .set push \n" |
|---|
| 434 | 463 | " .set "MIPS_ISA_ARCH_LEVEL" \n" |
|---|
| 435 | 464 | " " __LL "%0, %1 \n" |
|---|
| 436 | 465 | " and %0, %2 \n" |
|---|
| 437 | 466 | " " __SC "%0, %1 \n" |
|---|
| 438 | | - " .set mips0 \n" |
|---|
| 467 | + " .set pop \n" |
|---|
| 439 | 468 | : "=&r" (temp), "+m" (*reg) |
|---|
| 440 | 469 | : "r" (~val)); |
|---|
| 441 | 470 | } while (unlikely(!temp)); |
|---|
| .. | .. |
|---|
| 448 | 477 | unsigned long temp; |
|---|
| 449 | 478 | do { |
|---|
| 450 | 479 | __asm__ __volatile__( |
|---|
| 480 | + " .set push \n" |
|---|
| 451 | 481 | " .set "MIPS_ISA_ARCH_LEVEL" \n" |
|---|
| 452 | 482 | " " __LL "%0, %1 \n" |
|---|
| 453 | 483 | " and %0, %2 \n" |
|---|
| 454 | 484 | " or %0, %3 \n" |
|---|
| 455 | 485 | " " __SC "%0, %1 \n" |
|---|
| 456 | | - " .set mips0 \n" |
|---|
| 486 | + " .set pop \n" |
|---|
| 457 | 487 | : "=&r" (temp), "+m" (*reg) |
|---|
| 458 | 488 | : "r" (~change), "r" (val & change)); |
|---|
| 459 | 489 | } while (unlikely(!temp)); |
|---|
| .. | .. |
|---|
| 813 | 843 | const struct kvm_one_reg *reg, s64 v); |
|---|
| 814 | 844 | int (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu); |
|---|
| 815 | 845 | int (*vcpu_put)(struct kvm_vcpu *vcpu, int cpu); |
|---|
| 816 | | - int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu); |
|---|
| 817 | | - void (*vcpu_reenter)(struct kvm_run *run, struct kvm_vcpu *vcpu); |
|---|
| 846 | + int (*vcpu_run)(struct kvm_vcpu *vcpu); |
|---|
| 847 | + void (*vcpu_reenter)(struct kvm_vcpu *vcpu); |
|---|
| 818 | 848 | }; |
|---|
| 819 | 849 | extern struct kvm_mips_callbacks *kvm_mips_callbacks; |
|---|
| 820 | 850 | int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks); |
|---|
| .. | .. |
|---|
| 822 | 852 | /* Debug: dump vcpu state */ |
|---|
| 823 | 853 | int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu); |
|---|
| 824 | 854 | |
|---|
| 825 | | -extern int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu); |
|---|
| 855 | +extern int kvm_mips_handle_exit(struct kvm_vcpu *vcpu); |
|---|
| 826 | 856 | |
|---|
| 827 | 857 | /* Building of entry/exception code */ |
|---|
| 828 | 858 | int kvm_mips_entry_setup(void); |
|---|
| .. | .. |
|---|
| 869 | 899 | |
|---|
| 870 | 900 | extern enum emulation_result kvm_mips_handle_tlbmiss(u32 cause, |
|---|
| 871 | 901 | u32 *opc, |
|---|
| 872 | | - struct kvm_run *run, |
|---|
| 873 | 902 | struct kvm_vcpu *vcpu, |
|---|
| 874 | 903 | bool write_fault); |
|---|
| 875 | 904 | |
|---|
| .. | .. |
|---|
| 891 | 920 | unsigned int count); |
|---|
| 892 | 921 | void kvm_vz_load_guesttlb(const struct kvm_mips_tlb *buf, unsigned int index, |
|---|
| 893 | 922 | unsigned int count); |
|---|
| 923 | +#ifdef CONFIG_CPU_LOONGSON64 |
|---|
| 924 | +void kvm_loongson_clear_guest_vtlb(void); |
|---|
| 925 | +void kvm_loongson_clear_guest_ftlb(void); |
|---|
| 926 | +#endif |
|---|
| 894 | 927 | #endif |
|---|
| 895 | 928 | |
|---|
| 896 | 929 | void kvm_mips_suspend_mm(int cpu); |
|---|
| .. | .. |
|---|
| 936 | 969 | |
|---|
| 937 | 970 | #define KVM_ARCH_WANT_MMU_NOTIFIER |
|---|
| 938 | 971 | int kvm_unmap_hva_range(struct kvm *kvm, |
|---|
| 939 | | - unsigned long start, unsigned long end, bool blockable); |
|---|
| 940 | | -void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
|---|
| 972 | + unsigned long start, unsigned long end, unsigned flags); |
|---|
| 973 | +int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
|---|
| 941 | 974 | int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); |
|---|
| 942 | 975 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); |
|---|
| 943 | 976 | |
|---|
| .. | .. |
|---|
| 976 | 1009 | |
|---|
| 977 | 1010 | extern enum emulation_result kvm_mips_emulate_inst(u32 cause, |
|---|
| 978 | 1011 | u32 *opc, |
|---|
| 979 | | - struct kvm_run *run, |
|---|
| 980 | 1012 | struct kvm_vcpu *vcpu); |
|---|
| 981 | 1013 | |
|---|
| 982 | 1014 | long kvm_mips_guest_exception_base(struct kvm_vcpu *vcpu); |
|---|
| 983 | 1015 | |
|---|
| 984 | 1016 | extern enum emulation_result kvm_mips_emulate_syscall(u32 cause, |
|---|
| 985 | 1017 | u32 *opc, |
|---|
| 986 | | - struct kvm_run *run, |
|---|
| 987 | 1018 | struct kvm_vcpu *vcpu); |
|---|
| 988 | 1019 | |
|---|
| 989 | 1020 | extern enum emulation_result kvm_mips_emulate_tlbmiss_ld(u32 cause, |
|---|
| 990 | 1021 | u32 *opc, |
|---|
| 991 | | - struct kvm_run *run, |
|---|
| 992 | 1022 | struct kvm_vcpu *vcpu); |
|---|
| 993 | 1023 | |
|---|
| 994 | 1024 | extern enum emulation_result kvm_mips_emulate_tlbinv_ld(u32 cause, |
|---|
| 995 | 1025 | u32 *opc, |
|---|
| 996 | | - struct kvm_run *run, |
|---|
| 997 | 1026 | struct kvm_vcpu *vcpu); |
|---|
| 998 | 1027 | |
|---|
| 999 | 1028 | extern enum emulation_result kvm_mips_emulate_tlbmiss_st(u32 cause, |
|---|
| 1000 | 1029 | u32 *opc, |
|---|
| 1001 | | - struct kvm_run *run, |
|---|
| 1002 | 1030 | struct kvm_vcpu *vcpu); |
|---|
| 1003 | 1031 | |
|---|
| 1004 | 1032 | extern enum emulation_result kvm_mips_emulate_tlbinv_st(u32 cause, |
|---|
| 1005 | 1033 | u32 *opc, |
|---|
| 1006 | | - struct kvm_run *run, |
|---|
| 1007 | 1034 | struct kvm_vcpu *vcpu); |
|---|
| 1008 | 1035 | |
|---|
| 1009 | 1036 | extern enum emulation_result kvm_mips_emulate_tlbmod(u32 cause, |
|---|
| 1010 | 1037 | u32 *opc, |
|---|
| 1011 | | - struct kvm_run *run, |
|---|
| 1012 | 1038 | struct kvm_vcpu *vcpu); |
|---|
| 1013 | 1039 | |
|---|
| 1014 | 1040 | extern enum emulation_result kvm_mips_emulate_fpu_exc(u32 cause, |
|---|
| 1015 | 1041 | u32 *opc, |
|---|
| 1016 | | - struct kvm_run *run, |
|---|
| 1017 | 1042 | struct kvm_vcpu *vcpu); |
|---|
| 1018 | 1043 | |
|---|
| 1019 | 1044 | extern enum emulation_result kvm_mips_handle_ri(u32 cause, |
|---|
| 1020 | 1045 | u32 *opc, |
|---|
| 1021 | | - struct kvm_run *run, |
|---|
| 1022 | 1046 | struct kvm_vcpu *vcpu); |
|---|
| 1023 | 1047 | |
|---|
| 1024 | 1048 | extern enum emulation_result kvm_mips_emulate_ri_exc(u32 cause, |
|---|
| 1025 | 1049 | u32 *opc, |
|---|
| 1026 | | - struct kvm_run *run, |
|---|
| 1027 | 1050 | struct kvm_vcpu *vcpu); |
|---|
| 1028 | 1051 | |
|---|
| 1029 | 1052 | extern enum emulation_result kvm_mips_emulate_bp_exc(u32 cause, |
|---|
| 1030 | 1053 | u32 *opc, |
|---|
| 1031 | | - struct kvm_run *run, |
|---|
| 1032 | 1054 | struct kvm_vcpu *vcpu); |
|---|
| 1033 | 1055 | |
|---|
| 1034 | 1056 | extern enum emulation_result kvm_mips_emulate_trap_exc(u32 cause, |
|---|
| 1035 | 1057 | u32 *opc, |
|---|
| 1036 | | - struct kvm_run *run, |
|---|
| 1037 | 1058 | struct kvm_vcpu *vcpu); |
|---|
| 1038 | 1059 | |
|---|
| 1039 | 1060 | extern enum emulation_result kvm_mips_emulate_msafpe_exc(u32 cause, |
|---|
| 1040 | 1061 | u32 *opc, |
|---|
| 1041 | | - struct kvm_run *run, |
|---|
| 1042 | 1062 | struct kvm_vcpu *vcpu); |
|---|
| 1043 | 1063 | |
|---|
| 1044 | 1064 | extern enum emulation_result kvm_mips_emulate_fpe_exc(u32 cause, |
|---|
| 1045 | 1065 | u32 *opc, |
|---|
| 1046 | | - struct kvm_run *run, |
|---|
| 1047 | 1066 | struct kvm_vcpu *vcpu); |
|---|
| 1048 | 1067 | |
|---|
| 1049 | 1068 | extern enum emulation_result kvm_mips_emulate_msadis_exc(u32 cause, |
|---|
| 1050 | 1069 | u32 *opc, |
|---|
| 1051 | | - struct kvm_run *run, |
|---|
| 1052 | 1070 | struct kvm_vcpu *vcpu); |
|---|
| 1053 | 1071 | |
|---|
| 1054 | | -extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, |
|---|
| 1055 | | - struct kvm_run *run); |
|---|
| 1072 | +extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu); |
|---|
| 1056 | 1073 | |
|---|
| 1057 | 1074 | u32 kvm_mips_read_count(struct kvm_vcpu *vcpu); |
|---|
| 1058 | 1075 | void kvm_mips_write_count(struct kvm_vcpu *vcpu, u32 count); |
|---|
| .. | .. |
|---|
| 1081 | 1098 | |
|---|
| 1082 | 1099 | enum emulation_result kvm_mips_check_privilege(u32 cause, |
|---|
| 1083 | 1100 | u32 *opc, |
|---|
| 1084 | | - struct kvm_run *run, |
|---|
| 1085 | 1101 | struct kvm_vcpu *vcpu); |
|---|
| 1086 | 1102 | |
|---|
| 1087 | 1103 | enum emulation_result kvm_mips_emulate_cache(union mips_instruction inst, |
|---|
| 1088 | 1104 | u32 *opc, |
|---|
| 1089 | 1105 | u32 cause, |
|---|
| 1090 | | - struct kvm_run *run, |
|---|
| 1091 | 1106 | struct kvm_vcpu *vcpu); |
|---|
| 1092 | 1107 | enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst, |
|---|
| 1093 | 1108 | u32 *opc, |
|---|
| 1094 | 1109 | u32 cause, |
|---|
| 1095 | | - struct kvm_run *run, |
|---|
| 1096 | 1110 | struct kvm_vcpu *vcpu); |
|---|
| 1097 | 1111 | enum emulation_result kvm_mips_emulate_store(union mips_instruction inst, |
|---|
| 1098 | 1112 | u32 cause, |
|---|
| 1099 | | - struct kvm_run *run, |
|---|
| 1100 | 1113 | struct kvm_vcpu *vcpu); |
|---|
| 1101 | 1114 | enum emulation_result kvm_mips_emulate_load(union mips_instruction inst, |
|---|
| 1102 | 1115 | u32 cause, |
|---|
| 1103 | | - struct kvm_run *run, |
|---|
| 1104 | 1116 | struct kvm_vcpu *vcpu); |
|---|
| 1105 | 1117 | |
|---|
| 1106 | 1118 | /* COP0 */ |
|---|
| .. | .. |
|---|
| 1130 | 1142 | /* Misc */ |
|---|
| 1131 | 1143 | extern void kvm_mips_dump_stats(struct kvm_vcpu *vcpu); |
|---|
| 1132 | 1144 | extern unsigned long kvm_mips_get_ramsize(struct kvm *kvm); |
|---|
| 1145 | +extern int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, |
|---|
| 1146 | + struct kvm_mips_interrupt *irq); |
|---|
| 1133 | 1147 | |
|---|
| 1134 | 1148 | static inline void kvm_arch_hardware_unsetup(void) {} |
|---|
| 1135 | 1149 | static inline void kvm_arch_sync_events(struct kvm *kvm) {} |
|---|
| 1136 | 1150 | static inline void kvm_arch_free_memslot(struct kvm *kvm, |
|---|
| 1137 | | - struct kvm_memory_slot *free, struct kvm_memory_slot *dont) {} |
|---|
| 1151 | + struct kvm_memory_slot *slot) {} |
|---|
| 1138 | 1152 | static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {} |
|---|
| 1139 | 1153 | static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} |
|---|
| 1140 | 1154 | static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {} |
|---|