diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-02 16:11:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-02 16:11:27 -0400 |
commit | 221bb8a46e230b9824204ae86537183d9991ff2a (patch) | |
tree | 92510d72285b2285be7cb87288bf088cb28af4c1 /arch/mips/include | |
parent | f7b32e4c021fd788f13f6785e17efbc3eb05b351 (diff) | |
parent | 23528bb21ee2c9b27f3feddd77a2a3351a8df148 (diff) |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM updates from Paolo Bonzini:
- ARM: GICv3 ITS emulation and various fixes. Removal of the
old VGIC implementation.
- s390: support for trapping software breakpoints, nested
virtualization (vSIE), the STHYI opcode, initial extensions
for CPU model support.
- MIPS: support for MIPS64 hosts (32-bit guests only) and lots
of cleanups, preliminary to this and the upcoming support for
hardware virtualization extensions.
- x86: support for execute-only mappings in nested EPT; reduced
vmexit latency for TSC deadline timer (by about 30%) on Intel
hosts; support for more than 255 vCPUs.
- PPC: bugfixes.
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (302 commits)
KVM: PPC: Introduce KVM_CAP_PPC_HTM
MIPS: Select HAVE_KVM for MIPS64_R{2,6}
MIPS: KVM: Reset CP0_PageMask during host TLB flush
MIPS: KVM: Fix ptr->int cast via KVM_GUEST_KSEGX()
MIPS: KVM: Sign extend MFC0/RDHWR results
MIPS: KVM: Fix 64-bit big endian dynamic translation
MIPS: KVM: Fail if ebase doesn't fit in CP0_EBase
MIPS: KVM: Use 64-bit CP0_EBase when appropriate
MIPS: KVM: Set CP0_Status.KX on MIPS64
MIPS: KVM: Make entry code MIPS64 friendly
MIPS: KVM: Use kmap instead of CKSEG0ADDR()
MIPS: KVM: Use virt_to_phys() to get commpage PFN
MIPS: Fix definition of KSEGX() for 64-bit
KVM: VMX: Add VMCS to CPU's loaded VMCSs before VMPTRLD
kvm: x86: nVMX: maintain internal copy of current VMCS
KVM: PPC: Book3S HV: Save/restore TM state in H_CEDE
KVM: PPC: Book3S HV: Pull out TM state save/restore into separate procedures
KVM: arm64: vgic-its: Simplify MAPI error handling
KVM: arm64: vgic-its: Make vgic_its_cmd_handle_mapi similar to other handlers
KVM: arm64: vgic-its: Turn device_id validation into generic ID validation
...
Diffstat (limited to 'arch/mips/include')
-rw-r--r-- | arch/mips/include/asm/addrspace.h | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/kvm_host.h | 315 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/mipsregs.h | 21 | ||||
-rw-r--r-- | arch/mips/include/asm/setup.h | 1 | ||||
-rw-r--r-- | arch/mips/include/asm/uasm.h | 7 | ||||
-rw-r--r-- | arch/mips/include/uapi/asm/inst.h | 114 |
7 files changed, 263 insertions, 199 deletions
diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h index 3b0e51d5a613..c5b04e752e97 100644 --- a/arch/mips/include/asm/addrspace.h +++ b/arch/mips/include/asm/addrspace.h | |||
@@ -45,7 +45,7 @@ | |||
45 | /* | 45 | /* |
46 | * Returns the kernel segment base of a given address | 46 | * Returns the kernel segment base of a given address |
47 | */ | 47 | */ |
48 | #define KSEGX(a) ((_ACAST32_ (a)) & 0xe0000000) | 48 | #define KSEGX(a) ((_ACAST32_(a)) & _ACAST32_(0xe0000000)) |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Returns the physical address of a CKSEGx / XKPHYS address | 51 | * Returns the physical address of a CKSEGx / XKPHYS address |
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 36a391d289aa..b54bcadd8aec 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h | |||
@@ -19,6 +19,9 @@ | |||
19 | #include <linux/threads.h> | 19 | #include <linux/threads.h> |
20 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
21 | 21 | ||
22 | #include <asm/inst.h> | ||
23 | #include <asm/mipsregs.h> | ||
24 | |||
22 | /* MIPS KVM register ids */ | 25 | /* MIPS KVM register ids */ |
23 | #define MIPS_CP0_32(_R, _S) \ | 26 | #define MIPS_CP0_32(_R, _S) \ |
24 | (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) | 27 | (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) |
@@ -53,6 +56,12 @@ | |||
53 | #define KVM_REG_MIPS_CP0_CONFIG7 MIPS_CP0_32(16, 7) | 56 | #define KVM_REG_MIPS_CP0_CONFIG7 MIPS_CP0_32(16, 7) |
54 | #define KVM_REG_MIPS_CP0_XCONTEXT MIPS_CP0_64(20, 0) | 57 | #define KVM_REG_MIPS_CP0_XCONTEXT MIPS_CP0_64(20, 0) |
55 | #define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0) | 58 | #define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0) |
59 | #define KVM_REG_MIPS_CP0_KSCRATCH1 MIPS_CP0_64(31, 2) | ||
60 | #define KVM_REG_MIPS_CP0_KSCRATCH2 MIPS_CP0_64(31, 3) | ||
61 | #define KVM_REG_MIPS_CP0_KSCRATCH3 MIPS_CP0_64(31, 4) | ||
62 | #define KVM_REG_MIPS_CP0_KSCRATCH4 MIPS_CP0_64(31, 5) | ||
63 | #define KVM_REG_MIPS_CP0_KSCRATCH5 MIPS_CP0_64(31, 6) | ||
64 | #define KVM_REG_MIPS_CP0_KSCRATCH6 MIPS_CP0_64(31, 7) | ||
56 | 65 | ||
57 | 66 | ||
58 | #define KVM_MAX_VCPUS 1 | 67 | #define KVM_MAX_VCPUS 1 |
@@ -65,8 +74,14 @@ | |||
65 | 74 | ||
66 | 75 | ||
67 | 76 | ||
68 | /* Special address that contains the comm page, used for reducing # of traps */ | 77 | /* |
69 | #define KVM_GUEST_COMMPAGE_ADDR 0x0 | 78 | * Special address that contains the comm page, used for reducing # of traps |
79 | * This needs to be within 32Kb of 0x0 (so the zero register can be used), but | ||
80 | * preferably not at 0x0 so that most kernel NULL pointer dereferences can be | ||
81 | * caught. | ||
82 | */ | ||
83 | #define KVM_GUEST_COMMPAGE_ADDR ((PAGE_SIZE > 0x8000) ? 0 : \ | ||
84 | (0x8000 - PAGE_SIZE)) | ||
70 | 85 | ||
71 | #define KVM_GUEST_KERNEL_MODE(vcpu) ((kvm_read_c0_guest_status(vcpu->arch.cop0) & (ST0_EXL | ST0_ERL)) || \ | 86 | #define KVM_GUEST_KERNEL_MODE(vcpu) ((kvm_read_c0_guest_status(vcpu->arch.cop0) & (ST0_EXL | ST0_ERL)) || \ |
72 | ((kvm_read_c0_guest_status(vcpu->arch.cop0) & KSU_USER) == 0)) | 87 | ((kvm_read_c0_guest_status(vcpu->arch.cop0) & KSU_USER) == 0)) |
@@ -93,9 +108,6 @@ | |||
93 | #define KVM_INVALID_ADDR 0xdeadbeef | 108 | #define KVM_INVALID_ADDR 0xdeadbeef |
94 | 109 | ||
95 | extern atomic_t kvm_mips_instance; | 110 | extern atomic_t kvm_mips_instance; |
96 | extern kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn); | ||
97 | extern void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn); | ||
98 | extern bool (*kvm_mips_is_error_pfn)(kvm_pfn_t pfn); | ||
99 | 111 | ||
100 | struct kvm_vm_stat { | 112 | struct kvm_vm_stat { |
101 | u32 remote_tlb_flush; | 113 | u32 remote_tlb_flush; |
@@ -126,28 +138,6 @@ struct kvm_vcpu_stat { | |||
126 | u32 halt_wakeup; | 138 | u32 halt_wakeup; |
127 | }; | 139 | }; |
128 | 140 | ||
129 | enum kvm_mips_exit_types { | ||
130 | WAIT_EXITS, | ||
131 | CACHE_EXITS, | ||
132 | SIGNAL_EXITS, | ||
133 | INT_EXITS, | ||
134 | COP_UNUSABLE_EXITS, | ||
135 | TLBMOD_EXITS, | ||
136 | TLBMISS_LD_EXITS, | ||
137 | TLBMISS_ST_EXITS, | ||
138 | ADDRERR_ST_EXITS, | ||
139 | ADDRERR_LD_EXITS, | ||
140 | SYSCALL_EXITS, | ||
141 | RESVD_INST_EXITS, | ||
142 | BREAK_INST_EXITS, | ||
143 | TRAP_INST_EXITS, | ||
144 | MSA_FPE_EXITS, | ||
145 | FPE_EXITS, | ||
146 | MSA_DISABLED_EXITS, | ||
147 | FLUSH_DCACHE_EXITS, | ||
148 | MAX_KVM_MIPS_EXIT_TYPES | ||
149 | }; | ||
150 | |||
151 | struct kvm_arch_memory_slot { | 141 | struct kvm_arch_memory_slot { |
152 | }; | 142 | }; |
153 | 143 | ||
@@ -215,73 +205,6 @@ struct mips_coproc { | |||
215 | #define MIPS_CP0_CONFIG4_SEL 4 | 205 | #define MIPS_CP0_CONFIG4_SEL 4 |
216 | #define MIPS_CP0_CONFIG5_SEL 5 | 206 | #define MIPS_CP0_CONFIG5_SEL 5 |
217 | 207 | ||
218 | /* Config0 register bits */ | ||
219 | #define CP0C0_M 31 | ||
220 | #define CP0C0_K23 28 | ||
221 | #define CP0C0_KU 25 | ||
222 | #define CP0C0_MDU 20 | ||
223 | #define CP0C0_MM 17 | ||
224 | #define CP0C0_BM 16 | ||
225 | #define CP0C0_BE 15 | ||
226 | #define CP0C0_AT 13 | ||
227 | #define CP0C0_AR 10 | ||
228 | #define CP0C0_MT 7 | ||
229 | #define CP0C0_VI 3 | ||
230 | #define CP0C0_K0 0 | ||
231 | |||
232 | /* Config1 register bits */ | ||
233 | #define CP0C1_M 31 | ||
234 | #define CP0C1_MMU 25 | ||
235 | #define CP0C1_IS 22 | ||
236 | #define CP0C1_IL 19 | ||
237 | #define CP0C1_IA 16 | ||
238 | #define CP0C1_DS 13 | ||
239 | #define CP0C1_DL 10 | ||
240 | #define CP0C1_DA 7 | ||
241 | #define CP0C1_C2 6 | ||
242 | #define CP0C1_MD 5 | ||
243 | #define CP0C1_PC 4 | ||
244 | #define CP0C1_WR 3 | ||
245 | #define CP0C1_CA 2 | ||
246 | #define CP0C1_EP 1 | ||
247 | #define CP0C1_FP 0 | ||
248 | |||
249 | /* Config2 Register bits */ | ||
250 | #define CP0C2_M 31 | ||
251 | #define CP0C2_TU 28 | ||
252 | #define CP0C2_TS 24 | ||
253 | #define CP0C2_TL 20 | ||
254 | #define CP0C2_TA 16 | ||
255 | #define CP0C2_SU 12 | ||
256 | #define CP0C2_SS 8 | ||
257 | #define CP0C2_SL 4 | ||
258 | #define CP0C2_SA 0 | ||
259 | |||
260 | /* Config3 Register bits */ | ||
261 | #define CP0C3_M 31 | ||
262 | #define CP0C3_ISA_ON_EXC 16 | ||
263 | #define CP0C3_ULRI 13 | ||
264 | #define CP0C3_DSPP 10 | ||
265 | #define CP0C3_LPA 7 | ||
266 | #define CP0C3_VEIC 6 | ||
267 | #define CP0C3_VInt 5 | ||
268 | #define CP0C3_SP 4 | ||
269 | #define CP0C3_MT 2 | ||
270 | #define CP0C3_SM 1 | ||
271 | #define CP0C3_TL 0 | ||
272 | |||
273 | /* MMU types, the first four entries have the same layout as the | ||
274 | CP0C0_MT field. */ | ||
275 | enum mips_mmu_types { | ||
276 | MMU_TYPE_NONE, | ||
277 | MMU_TYPE_R4000, | ||
278 | MMU_TYPE_RESERVED, | ||
279 | MMU_TYPE_FMT, | ||
280 | MMU_TYPE_R3000, | ||
281 | MMU_TYPE_R6000, | ||
282 | MMU_TYPE_R8000 | ||
283 | }; | ||
284 | |||
285 | /* Resume Flags */ | 208 | /* Resume Flags */ |
286 | #define RESUME_FLAG_DR (1<<0) /* Reload guest nonvolatile state? */ | 209 | #define RESUME_FLAG_DR (1<<0) /* Reload guest nonvolatile state? */ |
287 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ | 210 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ |
@@ -298,11 +221,6 @@ enum emulation_result { | |||
298 | EMULATE_PRIV_FAIL, | 221 | EMULATE_PRIV_FAIL, |
299 | }; | 222 | }; |
300 | 223 | ||
301 | #define MIPS3_PG_G 0x00000001 /* Global; ignore ASID if in lo0 & lo1 */ | ||
302 | #define MIPS3_PG_V 0x00000002 /* Valid */ | ||
303 | #define MIPS3_PG_NV 0x00000000 | ||
304 | #define MIPS3_PG_D 0x00000004 /* Dirty */ | ||
305 | |||
306 | #define mips3_paddr_to_tlbpfn(x) \ | 224 | #define mips3_paddr_to_tlbpfn(x) \ |
307 | (((unsigned long)(x) >> MIPS3_PG_SHIFT) & MIPS3_PG_FRAME) | 225 | (((unsigned long)(x) >> MIPS3_PG_SHIFT) & MIPS3_PG_FRAME) |
308 | #define mips3_tlbpfn_to_paddr(x) \ | 226 | #define mips3_tlbpfn_to_paddr(x) \ |
@@ -313,13 +231,11 @@ enum emulation_result { | |||
313 | 231 | ||
314 | #define VPN2_MASK 0xffffe000 | 232 | #define VPN2_MASK 0xffffe000 |
315 | #define KVM_ENTRYHI_ASID MIPS_ENTRYHI_ASID | 233 | #define KVM_ENTRYHI_ASID MIPS_ENTRYHI_ASID |
316 | #define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && \ | 234 | #define TLB_IS_GLOBAL(x) ((x).tlb_lo[0] & (x).tlb_lo[1] & ENTRYLO_G) |
317 | ((x).tlb_lo1 & MIPS3_PG_G)) | ||
318 | #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) | 235 | #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) |
319 | #define TLB_ASID(x) ((x).tlb_hi & KVM_ENTRYHI_ASID) | 236 | #define TLB_ASID(x) ((x).tlb_hi & KVM_ENTRYHI_ASID) |
320 | #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) \ | 237 | #define TLB_LO_IDX(x, va) (((va) >> PAGE_SHIFT) & 1) |
321 | ? ((x).tlb_lo1 & MIPS3_PG_V) \ | 238 | #define TLB_IS_VALID(x, va) ((x).tlb_lo[TLB_LO_IDX(x, va)] & ENTRYLO_V) |
322 | : ((x).tlb_lo0 & MIPS3_PG_V)) | ||
323 | #define TLB_HI_VPN2_HIT(x, y) ((TLB_VPN2(x) & ~(x).tlb_mask) == \ | 239 | #define TLB_HI_VPN2_HIT(x, y) ((TLB_VPN2(x) & ~(x).tlb_mask) == \ |
324 | ((y) & VPN2_MASK & ~(x).tlb_mask)) | 240 | ((y) & VPN2_MASK & ~(x).tlb_mask)) |
325 | #define TLB_HI_ASID_HIT(x, y) (TLB_IS_GLOBAL(x) || \ | 241 | #define TLB_HI_ASID_HIT(x, y) (TLB_IS_GLOBAL(x) || \ |
@@ -328,26 +244,23 @@ enum emulation_result { | |||
328 | struct kvm_mips_tlb { | 244 | struct kvm_mips_tlb { |
329 | long tlb_mask; | 245 | long tlb_mask; |
330 | long tlb_hi; | 246 | long tlb_hi; |
331 | long tlb_lo0; | 247 | long tlb_lo[2]; |
332 | long tlb_lo1; | ||
333 | }; | 248 | }; |
334 | 249 | ||
335 | #define KVM_MIPS_FPU_FPU 0x1 | 250 | #define KVM_MIPS_AUX_FPU 0x1 |
336 | #define KVM_MIPS_FPU_MSA 0x2 | 251 | #define KVM_MIPS_AUX_MSA 0x2 |
337 | 252 | ||
338 | #define KVM_MIPS_GUEST_TLB_SIZE 64 | 253 | #define KVM_MIPS_GUEST_TLB_SIZE 64 |
339 | struct kvm_vcpu_arch { | 254 | struct kvm_vcpu_arch { |
340 | void *host_ebase, *guest_ebase; | 255 | void *guest_ebase; |
341 | int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu); | 256 | int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu); |
342 | unsigned long host_stack; | 257 | unsigned long host_stack; |
343 | unsigned long host_gp; | 258 | unsigned long host_gp; |
344 | 259 | ||
345 | /* Host CP0 registers used when handling exits from guest */ | 260 | /* Host CP0 registers used when handling exits from guest */ |
346 | unsigned long host_cp0_badvaddr; | 261 | unsigned long host_cp0_badvaddr; |
347 | unsigned long host_cp0_cause; | ||
348 | unsigned long host_cp0_epc; | 262 | unsigned long host_cp0_epc; |
349 | unsigned long host_cp0_entryhi; | 263 | u32 host_cp0_cause; |
350 | uint32_t guest_inst; | ||
351 | 264 | ||
352 | /* GPRS */ | 265 | /* GPRS */ |
353 | unsigned long gprs[32]; | 266 | unsigned long gprs[32]; |
@@ -357,8 +270,8 @@ struct kvm_vcpu_arch { | |||
357 | 270 | ||
358 | /* FPU State */ | 271 | /* FPU State */ |
359 | struct mips_fpu_struct fpu; | 272 | struct mips_fpu_struct fpu; |
360 | /* Which FPU state is loaded (KVM_MIPS_FPU_*) */ | 273 | /* Which auxiliary state is loaded (KVM_MIPS_AUX_*) */ |
361 | unsigned int fpu_inuse; | 274 | unsigned int aux_inuse; |
362 | 275 | ||
363 | /* COP0 State */ | 276 | /* COP0 State */ |
364 | struct mips_coproc *cop0; | 277 | struct mips_coproc *cop0; |
@@ -370,11 +283,11 @@ struct kvm_vcpu_arch { | |||
370 | 283 | ||
371 | struct hrtimer comparecount_timer; | 284 | struct hrtimer comparecount_timer; |
372 | /* Count timer control KVM register */ | 285 | /* Count timer control KVM register */ |
373 | uint32_t count_ctl; | 286 | u32 count_ctl; |
374 | /* Count bias from the raw time */ | 287 | /* Count bias from the raw time */ |
375 | uint32_t count_bias; | 288 | u32 count_bias; |
376 | /* Frequency of timer in Hz */ | 289 | /* Frequency of timer in Hz */ |
377 | uint32_t count_hz; | 290 | u32 count_hz; |
378 | /* Dynamic nanosecond bias (multiple of count_period) to avoid overflow */ | 291 | /* Dynamic nanosecond bias (multiple of count_period) to avoid overflow */ |
379 | s64 count_dyn_bias; | 292 | s64 count_dyn_bias; |
380 | /* Resume time */ | 293 | /* Resume time */ |
@@ -388,7 +301,7 @@ struct kvm_vcpu_arch { | |||
388 | /* Bitmask of pending exceptions to be cleared */ | 301 | /* Bitmask of pending exceptions to be cleared */ |
389 | unsigned long pending_exceptions_clr; | 302 | unsigned long pending_exceptions_clr; |
390 | 303 | ||
391 | unsigned long pending_load_cause; | 304 | u32 pending_load_cause; |
392 | 305 | ||
393 | /* Save/Restore the entryhi register when are are preempted/scheduled back in */ | 306 | /* Save/Restore the entryhi register when are are preempted/scheduled back in */ |
394 | unsigned long preempt_entryhi; | 307 | unsigned long preempt_entryhi; |
@@ -397,8 +310,8 @@ struct kvm_vcpu_arch { | |||
397 | struct kvm_mips_tlb guest_tlb[KVM_MIPS_GUEST_TLB_SIZE]; | 310 | struct kvm_mips_tlb guest_tlb[KVM_MIPS_GUEST_TLB_SIZE]; |
398 | 311 | ||
399 | /* Cached guest kernel/user ASIDs */ | 312 | /* Cached guest kernel/user ASIDs */ |
400 | uint32_t guest_user_asid[NR_CPUS]; | 313 | u32 guest_user_asid[NR_CPUS]; |
401 | uint32_t guest_kernel_asid[NR_CPUS]; | 314 | u32 guest_kernel_asid[NR_CPUS]; |
402 | struct mm_struct guest_kernel_mm, guest_user_mm; | 315 | struct mm_struct guest_kernel_mm, guest_user_mm; |
403 | 316 | ||
404 | int last_sched_cpu; | 317 | int last_sched_cpu; |
@@ -408,6 +321,7 @@ struct kvm_vcpu_arch { | |||
408 | 321 | ||
409 | u8 fpu_enabled; | 322 | u8 fpu_enabled; |
410 | u8 msa_enabled; | 323 | u8 msa_enabled; |
324 | u8 kscratch_enabled; | ||
411 | }; | 325 | }; |
412 | 326 | ||
413 | 327 | ||
@@ -461,6 +375,18 @@ struct kvm_vcpu_arch { | |||
461 | #define kvm_write_c0_guest_config7(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][7] = (val)) | 375 | #define kvm_write_c0_guest_config7(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][7] = (val)) |
462 | #define kvm_read_c0_guest_errorepc(cop0) (cop0->reg[MIPS_CP0_ERROR_PC][0]) | 376 | #define kvm_read_c0_guest_errorepc(cop0) (cop0->reg[MIPS_CP0_ERROR_PC][0]) |
463 | #define kvm_write_c0_guest_errorepc(cop0, val) (cop0->reg[MIPS_CP0_ERROR_PC][0] = (val)) | 377 | #define kvm_write_c0_guest_errorepc(cop0, val) (cop0->reg[MIPS_CP0_ERROR_PC][0] = (val)) |
378 | #define kvm_read_c0_guest_kscratch1(cop0) (cop0->reg[MIPS_CP0_DESAVE][2]) | ||
379 | #define kvm_read_c0_guest_kscratch2(cop0) (cop0->reg[MIPS_CP0_DESAVE][3]) | ||
380 | #define kvm_read_c0_guest_kscratch3(cop0) (cop0->reg[MIPS_CP0_DESAVE][4]) | ||
381 | #define kvm_read_c0_guest_kscratch4(cop0) (cop0->reg[MIPS_CP0_DESAVE][5]) | ||
382 | #define kvm_read_c0_guest_kscratch5(cop0) (cop0->reg[MIPS_CP0_DESAVE][6]) | ||
383 | #define kvm_read_c0_guest_kscratch6(cop0) (cop0->reg[MIPS_CP0_DESAVE][7]) | ||
384 | #define kvm_write_c0_guest_kscratch1(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][2] = (val)) | ||
385 | #define kvm_write_c0_guest_kscratch2(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][3] = (val)) | ||
386 | #define kvm_write_c0_guest_kscratch3(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][4] = (val)) | ||
387 | #define kvm_write_c0_guest_kscratch4(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][5] = (val)) | ||
388 | #define kvm_write_c0_guest_kscratch5(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][6] = (val)) | ||
389 | #define kvm_write_c0_guest_kscratch6(cop0, val) (cop0->reg[MIPS_CP0_DESAVE][7] = (val)) | ||
464 | 390 | ||
465 | /* | 391 | /* |
466 | * Some of the guest registers may be modified asynchronously (e.g. from a | 392 | * Some of the guest registers may be modified asynchronously (e.g. from a |
@@ -474,7 +400,7 @@ static inline void _kvm_atomic_set_c0_guest_reg(unsigned long *reg, | |||
474 | unsigned long temp; | 400 | unsigned long temp; |
475 | do { | 401 | do { |
476 | __asm__ __volatile__( | 402 | __asm__ __volatile__( |
477 | " .set mips3 \n" | 403 | " .set "MIPS_ISA_ARCH_LEVEL" \n" |
478 | " " __LL "%0, %1 \n" | 404 | " " __LL "%0, %1 \n" |
479 | " or %0, %2 \n" | 405 | " or %0, %2 \n" |
480 | " " __SC "%0, %1 \n" | 406 | " " __SC "%0, %1 \n" |
@@ -490,7 +416,7 @@ static inline void _kvm_atomic_clear_c0_guest_reg(unsigned long *reg, | |||
490 | unsigned long temp; | 416 | unsigned long temp; |
491 | do { | 417 | do { |
492 | __asm__ __volatile__( | 418 | __asm__ __volatile__( |
493 | " .set mips3 \n" | 419 | " .set "MIPS_ISA_ARCH_LEVEL" \n" |
494 | " " __LL "%0, %1 \n" | 420 | " " __LL "%0, %1 \n" |
495 | " and %0, %2 \n" | 421 | " and %0, %2 \n" |
496 | " " __SC "%0, %1 \n" | 422 | " " __SC "%0, %1 \n" |
@@ -507,7 +433,7 @@ static inline void _kvm_atomic_change_c0_guest_reg(unsigned long *reg, | |||
507 | unsigned long temp; | 433 | unsigned long temp; |
508 | do { | 434 | do { |
509 | __asm__ __volatile__( | 435 | __asm__ __volatile__( |
510 | " .set mips3 \n" | 436 | " .set "MIPS_ISA_ARCH_LEVEL" \n" |
511 | " " __LL "%0, %1 \n" | 437 | " " __LL "%0, %1 \n" |
512 | " and %0, %2 \n" | 438 | " and %0, %2 \n" |
513 | " or %0, %3 \n" | 439 | " or %0, %3 \n" |
@@ -542,7 +468,7 @@ static inline void _kvm_atomic_change_c0_guest_reg(unsigned long *reg, | |||
542 | 468 | ||
543 | static inline bool kvm_mips_guest_can_have_fpu(struct kvm_vcpu_arch *vcpu) | 469 | static inline bool kvm_mips_guest_can_have_fpu(struct kvm_vcpu_arch *vcpu) |
544 | { | 470 | { |
545 | return (!__builtin_constant_p(cpu_has_fpu) || cpu_has_fpu) && | 471 | return (!__builtin_constant_p(raw_cpu_has_fpu) || raw_cpu_has_fpu) && |
546 | vcpu->fpu_enabled; | 472 | vcpu->fpu_enabled; |
547 | } | 473 | } |
548 | 474 | ||
@@ -589,9 +515,11 @@ struct kvm_mips_callbacks { | |||
589 | void (*dequeue_io_int)(struct kvm_vcpu *vcpu, | 515 | void (*dequeue_io_int)(struct kvm_vcpu *vcpu, |
590 | struct kvm_mips_interrupt *irq); | 516 | struct kvm_mips_interrupt *irq); |
591 | int (*irq_deliver)(struct kvm_vcpu *vcpu, unsigned int priority, | 517 | int (*irq_deliver)(struct kvm_vcpu *vcpu, unsigned int priority, |
592 | uint32_t cause); | 518 | u32 cause); |
593 | int (*irq_clear)(struct kvm_vcpu *vcpu, unsigned int priority, | 519 | int (*irq_clear)(struct kvm_vcpu *vcpu, unsigned int priority, |
594 | uint32_t cause); | 520 | u32 cause); |
521 | unsigned long (*num_regs)(struct kvm_vcpu *vcpu); | ||
522 | int (*copy_reg_indices)(struct kvm_vcpu *vcpu, u64 __user *indices); | ||
595 | int (*get_one_reg)(struct kvm_vcpu *vcpu, | 523 | int (*get_one_reg)(struct kvm_vcpu *vcpu, |
596 | const struct kvm_one_reg *reg, s64 *v); | 524 | const struct kvm_one_reg *reg, s64 *v); |
597 | int (*set_one_reg)(struct kvm_vcpu *vcpu, | 525 | int (*set_one_reg)(struct kvm_vcpu *vcpu, |
@@ -605,8 +533,13 @@ int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks); | |||
605 | /* Debug: dump vcpu state */ | 533 | /* Debug: dump vcpu state */ |
606 | int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu); | 534 | int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu); |
607 | 535 | ||
608 | /* Trampoline ASM routine to start running in "Guest" context */ | 536 | extern int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu); |
609 | extern int __kvm_mips_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu); | 537 | |
538 | /* Building of entry/exception code */ | ||
539 | int kvm_mips_entry_setup(void); | ||
540 | void *kvm_mips_build_vcpu_run(void *addr); | ||
541 | void *kvm_mips_build_exception(void *addr, void *handler); | ||
542 | void *kvm_mips_build_exit(void *addr); | ||
610 | 543 | ||
611 | /* FPU/MSA context management */ | 544 | /* FPU/MSA context management */ |
612 | void __kvm_save_fpu(struct kvm_vcpu_arch *vcpu); | 545 | void __kvm_save_fpu(struct kvm_vcpu_arch *vcpu); |
@@ -622,11 +555,11 @@ void kvm_drop_fpu(struct kvm_vcpu *vcpu); | |||
622 | void kvm_lose_fpu(struct kvm_vcpu *vcpu); | 555 | void kvm_lose_fpu(struct kvm_vcpu *vcpu); |
623 | 556 | ||
624 | /* TLB handling */ | 557 | /* TLB handling */ |
625 | uint32_t kvm_get_kernel_asid(struct kvm_vcpu *vcpu); | 558 | u32 kvm_get_kernel_asid(struct kvm_vcpu *vcpu); |
626 | 559 | ||
627 | uint32_t kvm_get_user_asid(struct kvm_vcpu *vcpu); | 560 | u32 kvm_get_user_asid(struct kvm_vcpu *vcpu); |
628 | 561 | ||
629 | uint32_t kvm_get_commpage_asid (struct kvm_vcpu *vcpu); | 562 | u32 kvm_get_commpage_asid (struct kvm_vcpu *vcpu); |
630 | 563 | ||
631 | extern int kvm_mips_handle_kseg0_tlb_fault(unsigned long badbaddr, | 564 | extern int kvm_mips_handle_kseg0_tlb_fault(unsigned long badbaddr, |
632 | struct kvm_vcpu *vcpu); | 565 | struct kvm_vcpu *vcpu); |
@@ -635,22 +568,24 @@ extern int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr, | |||
635 | struct kvm_vcpu *vcpu); | 568 | struct kvm_vcpu *vcpu); |
636 | 569 | ||
637 | extern int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, | 570 | extern int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, |
638 | struct kvm_mips_tlb *tlb, | 571 | struct kvm_mips_tlb *tlb); |
639 | unsigned long *hpa0, | ||
640 | unsigned long *hpa1); | ||
641 | 572 | ||
642 | extern enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause, | 573 | extern enum emulation_result kvm_mips_handle_tlbmiss(u32 cause, |
643 | uint32_t *opc, | 574 | u32 *opc, |
644 | struct kvm_run *run, | 575 | struct kvm_run *run, |
645 | struct kvm_vcpu *vcpu); | 576 | struct kvm_vcpu *vcpu); |
646 | 577 | ||
647 | extern enum emulation_result kvm_mips_handle_tlbmod(unsigned long cause, | 578 | extern enum emulation_result kvm_mips_handle_tlbmod(u32 cause, |
648 | uint32_t *opc, | 579 | u32 *opc, |
649 | struct kvm_run *run, | 580 | struct kvm_run *run, |
650 | struct kvm_vcpu *vcpu); | 581 | struct kvm_vcpu *vcpu); |
651 | 582 | ||
652 | extern void kvm_mips_dump_host_tlbs(void); | 583 | extern void kvm_mips_dump_host_tlbs(void); |
653 | extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu); | 584 | extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu); |
585 | extern int kvm_mips_host_tlb_write(struct kvm_vcpu *vcpu, unsigned long entryhi, | ||
586 | unsigned long entrylo0, | ||
587 | unsigned long entrylo1, | ||
588 | int flush_dcache_mask); | ||
654 | extern void kvm_mips_flush_host_tlb(int skip_kseg0); | 589 | extern void kvm_mips_flush_host_tlb(int skip_kseg0); |
655 | extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi); | 590 | extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi); |
656 | 591 | ||
@@ -667,90 +602,90 @@ extern void kvm_mips_vcpu_load(struct kvm_vcpu *vcpu, int cpu); | |||
667 | extern void kvm_mips_vcpu_put(struct kvm_vcpu *vcpu); | 602 | extern void kvm_mips_vcpu_put(struct kvm_vcpu *vcpu); |
668 | 603 | ||
669 | /* Emulation */ | 604 | /* Emulation */ |
670 | uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu); | 605 | u32 kvm_get_inst(u32 *opc, struct kvm_vcpu *vcpu); |
671 | enum emulation_result update_pc(struct kvm_vcpu *vcpu, uint32_t cause); | 606 | enum emulation_result update_pc(struct kvm_vcpu *vcpu, u32 cause); |
672 | 607 | ||
673 | extern enum emulation_result kvm_mips_emulate_inst(unsigned long cause, | 608 | extern enum emulation_result kvm_mips_emulate_inst(u32 cause, |
674 | uint32_t *opc, | 609 | u32 *opc, |
675 | struct kvm_run *run, | 610 | struct kvm_run *run, |
676 | struct kvm_vcpu *vcpu); | 611 | struct kvm_vcpu *vcpu); |
677 | 612 | ||
678 | extern enum emulation_result kvm_mips_emulate_syscall(unsigned long cause, | 613 | extern enum emulation_result kvm_mips_emulate_syscall(u32 cause, |
679 | uint32_t *opc, | 614 | u32 *opc, |
680 | struct kvm_run *run, | 615 | struct kvm_run *run, |
681 | struct kvm_vcpu *vcpu); | 616 | struct kvm_vcpu *vcpu); |
682 | 617 | ||
683 | extern enum emulation_result kvm_mips_emulate_tlbmiss_ld(unsigned long cause, | 618 | extern enum emulation_result kvm_mips_emulate_tlbmiss_ld(u32 cause, |
684 | uint32_t *opc, | 619 | u32 *opc, |
685 | struct kvm_run *run, | 620 | struct kvm_run *run, |
686 | struct kvm_vcpu *vcpu); | 621 | struct kvm_vcpu *vcpu); |
687 | 622 | ||
688 | extern enum emulation_result kvm_mips_emulate_tlbinv_ld(unsigned long cause, | 623 | extern enum emulation_result kvm_mips_emulate_tlbinv_ld(u32 cause, |
689 | uint32_t *opc, | 624 | u32 *opc, |
690 | struct kvm_run *run, | 625 | struct kvm_run *run, |
691 | struct kvm_vcpu *vcpu); | 626 | struct kvm_vcpu *vcpu); |
692 | 627 | ||
693 | extern enum emulation_result kvm_mips_emulate_tlbmiss_st(unsigned long cause, | 628 | extern enum emulation_result kvm_mips_emulate_tlbmiss_st(u32 cause, |
694 | uint32_t *opc, | 629 | u32 *opc, |
695 | struct kvm_run *run, | 630 | struct kvm_run *run, |
696 | struct kvm_vcpu *vcpu); | 631 | struct kvm_vcpu *vcpu); |
697 | 632 | ||
698 | extern enum emulation_result kvm_mips_emulate_tlbinv_st(unsigned long cause, | 633 | extern enum emulation_result kvm_mips_emulate_tlbinv_st(u32 cause, |
699 | uint32_t *opc, | 634 | u32 *opc, |
700 | struct kvm_run *run, | 635 | struct kvm_run *run, |
701 | struct kvm_vcpu *vcpu); | 636 | struct kvm_vcpu *vcpu); |
702 | 637 | ||
703 | extern enum emulation_result kvm_mips_emulate_tlbmod(unsigned long cause, | 638 | extern enum emulation_result kvm_mips_emulate_tlbmod(u32 cause, |
704 | uint32_t *opc, | 639 | u32 *opc, |
705 | struct kvm_run *run, | 640 | struct kvm_run *run, |
706 | struct kvm_vcpu *vcpu); | 641 | struct kvm_vcpu *vcpu); |
707 | 642 | ||
708 | extern enum emulation_result kvm_mips_emulate_fpu_exc(unsigned long cause, | 643 | extern enum emulation_result kvm_mips_emulate_fpu_exc(u32 cause, |
709 | uint32_t *opc, | 644 | u32 *opc, |
710 | struct kvm_run *run, | 645 | struct kvm_run *run, |
711 | struct kvm_vcpu *vcpu); | 646 | struct kvm_vcpu *vcpu); |
712 | 647 | ||
713 | extern enum emulation_result kvm_mips_handle_ri(unsigned long cause, | 648 | extern enum emulation_result kvm_mips_handle_ri(u32 cause, |
714 | uint32_t *opc, | 649 | u32 *opc, |
715 | struct kvm_run *run, | 650 | struct kvm_run *run, |
716 | struct kvm_vcpu *vcpu); | 651 | struct kvm_vcpu *vcpu); |
717 | 652 | ||
718 | extern enum emulation_result kvm_mips_emulate_ri_exc(unsigned long cause, | 653 | extern enum emulation_result kvm_mips_emulate_ri_exc(u32 cause, |
719 | uint32_t *opc, | 654 | u32 *opc, |
720 | struct kvm_run *run, | 655 | struct kvm_run *run, |
721 | struct kvm_vcpu *vcpu); | 656 | struct kvm_vcpu *vcpu); |
722 | 657 | ||
723 | extern enum emulation_result kvm_mips_emulate_bp_exc(unsigned long cause, | 658 | extern enum emulation_result kvm_mips_emulate_bp_exc(u32 cause, |
724 | uint32_t *opc, | 659 | u32 *opc, |
725 | struct kvm_run *run, | 660 | struct kvm_run *run, |
726 | struct kvm_vcpu *vcpu); | 661 | struct kvm_vcpu *vcpu); |
727 | 662 | ||
728 | extern enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause, | 663 | extern enum emulation_result kvm_mips_emulate_trap_exc(u32 cause, |
729 | uint32_t *opc, | 664 | u32 *opc, |
730 | struct kvm_run *run, | 665 | struct kvm_run *run, |
731 | struct kvm_vcpu *vcpu); | 666 | struct kvm_vcpu *vcpu); |
732 | 667 | ||
733 | extern enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause, | 668 | extern enum emulation_result kvm_mips_emulate_msafpe_exc(u32 cause, |
734 | uint32_t *opc, | 669 | u32 *opc, |
735 | struct kvm_run *run, | 670 | struct kvm_run *run, |
736 | struct kvm_vcpu *vcpu); | 671 | struct kvm_vcpu *vcpu); |
737 | 672 | ||
738 | extern enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause, | 673 | extern enum emulation_result kvm_mips_emulate_fpe_exc(u32 cause, |
739 | uint32_t *opc, | 674 | u32 *opc, |
740 | struct kvm_run *run, | 675 | struct kvm_run *run, |
741 | struct kvm_vcpu *vcpu); | 676 | struct kvm_vcpu *vcpu); |
742 | 677 | ||
743 | extern enum emulation_result kvm_mips_emulate_msadis_exc(unsigned long cause, | 678 | extern enum emulation_result kvm_mips_emulate_msadis_exc(u32 cause, |
744 | uint32_t *opc, | 679 | u32 *opc, |
745 | struct kvm_run *run, | 680 | struct kvm_run *run, |
746 | struct kvm_vcpu *vcpu); | 681 | struct kvm_vcpu *vcpu); |
747 | 682 | ||
748 | extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, | 683 | extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, |
749 | struct kvm_run *run); | 684 | struct kvm_run *run); |
750 | 685 | ||
751 | uint32_t kvm_mips_read_count(struct kvm_vcpu *vcpu); | 686 | u32 kvm_mips_read_count(struct kvm_vcpu *vcpu); |
752 | void kvm_mips_write_count(struct kvm_vcpu *vcpu, uint32_t count); | 687 | void kvm_mips_write_count(struct kvm_vcpu *vcpu, u32 count); |
753 | void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack); | 688 | void kvm_mips_write_compare(struct kvm_vcpu *vcpu, u32 compare, bool ack); |
754 | void kvm_mips_init_count(struct kvm_vcpu *vcpu); | 689 | void kvm_mips_init_count(struct kvm_vcpu *vcpu); |
755 | int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl); | 690 | int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl); |
756 | int kvm_mips_set_count_resume(struct kvm_vcpu *vcpu, s64 count_resume); | 691 | int kvm_mips_set_count_resume(struct kvm_vcpu *vcpu, s64 count_resume); |
@@ -759,27 +694,27 @@ void kvm_mips_count_enable_cause(struct kvm_vcpu *vcpu); | |||
759 | void kvm_mips_count_disable_cause(struct kvm_vcpu *vcpu); | 694 | void kvm_mips_count_disable_cause(struct kvm_vcpu *vcpu); |
760 | enum hrtimer_restart kvm_mips_count_timeout(struct kvm_vcpu *vcpu); | 695 | enum hrtimer_restart kvm_mips_count_timeout(struct kvm_vcpu *vcpu); |
761 | 696 | ||
762 | enum emulation_result kvm_mips_check_privilege(unsigned long cause, | 697 | enum emulation_result kvm_mips_check_privilege(u32 cause, |
763 | uint32_t *opc, | 698 | u32 *opc, |
764 | struct kvm_run *run, | 699 | struct kvm_run *run, |
765 | struct kvm_vcpu *vcpu); | 700 | struct kvm_vcpu *vcpu); |
766 | 701 | ||
767 | enum emulation_result kvm_mips_emulate_cache(uint32_t inst, | 702 | enum emulation_result kvm_mips_emulate_cache(union mips_instruction inst, |
768 | uint32_t *opc, | 703 | u32 *opc, |
769 | uint32_t cause, | 704 | u32 cause, |
770 | struct kvm_run *run, | 705 | struct kvm_run *run, |
771 | struct kvm_vcpu *vcpu); | 706 | struct kvm_vcpu *vcpu); |
772 | enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, | 707 | enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst, |
773 | uint32_t *opc, | 708 | u32 *opc, |
774 | uint32_t cause, | 709 | u32 cause, |
775 | struct kvm_run *run, | 710 | struct kvm_run *run, |
776 | struct kvm_vcpu *vcpu); | 711 | struct kvm_vcpu *vcpu); |
777 | enum emulation_result kvm_mips_emulate_store(uint32_t inst, | 712 | enum emulation_result kvm_mips_emulate_store(union mips_instruction inst, |
778 | uint32_t cause, | 713 | u32 cause, |
779 | struct kvm_run *run, | 714 | struct kvm_run *run, |
780 | struct kvm_vcpu *vcpu); | 715 | struct kvm_vcpu *vcpu); |
781 | enum emulation_result kvm_mips_emulate_load(uint32_t inst, | 716 | enum emulation_result kvm_mips_emulate_load(union mips_instruction inst, |
782 | uint32_t cause, | 717 | u32 cause, |
783 | struct kvm_run *run, | 718 | struct kvm_run *run, |
784 | struct kvm_vcpu *vcpu); | 719 | struct kvm_vcpu *vcpu); |
785 | 720 | ||
@@ -789,13 +724,13 @@ unsigned int kvm_mips_config4_wrmask(struct kvm_vcpu *vcpu); | |||
789 | unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu); | 724 | unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu); |
790 | 725 | ||
791 | /* Dynamic binary translation */ | 726 | /* Dynamic binary translation */ |
792 | extern int kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc, | 727 | extern int kvm_mips_trans_cache_index(union mips_instruction inst, |
793 | struct kvm_vcpu *vcpu); | 728 | u32 *opc, struct kvm_vcpu *vcpu); |
794 | extern int kvm_mips_trans_cache_va(uint32_t inst, uint32_t *opc, | 729 | extern int kvm_mips_trans_cache_va(union mips_instruction inst, u32 *opc, |
795 | struct kvm_vcpu *vcpu); | 730 | struct kvm_vcpu *vcpu); |
796 | extern int kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, | 731 | extern int kvm_mips_trans_mfc0(union mips_instruction inst, u32 *opc, |
797 | struct kvm_vcpu *vcpu); | 732 | struct kvm_vcpu *vcpu); |
798 | extern int kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, | 733 | extern int kvm_mips_trans_mtc0(union mips_instruction inst, u32 *opc, |
799 | struct kvm_vcpu *vcpu); | 734 | struct kvm_vcpu *vcpu); |
800 | 735 | ||
801 | /* Misc */ | 736 | /* Misc */ |
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h index d68e685cde60..bd8b9bbe1771 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h | |||
@@ -55,7 +55,7 @@ | |||
55 | #define cpu_has_mipsmt 0 | 55 | #define cpu_has_mipsmt 0 |
56 | #define cpu_has_vint 0 | 56 | #define cpu_has_vint 0 |
57 | #define cpu_has_veic 0 | 57 | #define cpu_has_veic 0 |
58 | #define cpu_hwrena_impl_bits 0xc0000000 | 58 | #define cpu_hwrena_impl_bits (MIPS_HWRENA_IMPL1 | MIPS_HWRENA_IMPL2) |
59 | #define cpu_has_wsbh 1 | 59 | #define cpu_has_wsbh 1 |
60 | 60 | ||
61 | #define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON) | 61 | #define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON) |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index e1ca65c62f6a..def9d8d13f6e 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define CP0_SEGCTL2 $5, 4 | 53 | #define CP0_SEGCTL2 $5, 4 |
54 | #define CP0_WIRED $6 | 54 | #define CP0_WIRED $6 |
55 | #define CP0_INFO $7 | 55 | #define CP0_INFO $7 |
56 | #define CP0_HWRENA $7, 0 | 56 | #define CP0_HWRENA $7 |
57 | #define CP0_BADVADDR $8 | 57 | #define CP0_BADVADDR $8 |
58 | #define CP0_BADINSTR $8, 1 | 58 | #define CP0_BADINSTR $8, 1 |
59 | #define CP0_COUNT $9 | 59 | #define CP0_COUNT $9 |
@@ -533,6 +533,7 @@ | |||
533 | #define TX49_CONF_CWFON (_ULCAST_(1) << 27) | 533 | #define TX49_CONF_CWFON (_ULCAST_(1) << 27) |
534 | 534 | ||
535 | /* Bits specific to the MIPS32/64 PRA. */ | 535 | /* Bits specific to the MIPS32/64 PRA. */ |
536 | #define MIPS_CONF_VI (_ULCAST_(1) << 3) | ||
536 | #define MIPS_CONF_MT (_ULCAST_(7) << 7) | 537 | #define MIPS_CONF_MT (_ULCAST_(7) << 7) |
537 | #define MIPS_CONF_MT_TLB (_ULCAST_(1) << 7) | 538 | #define MIPS_CONF_MT_TLB (_ULCAST_(1) << 7) |
538 | #define MIPS_CONF_MT_FTLB (_ULCAST_(4) << 7) | 539 | #define MIPS_CONF_MT_FTLB (_ULCAST_(4) << 7) |
@@ -853,6 +854,24 @@ | |||
853 | #define MIPS_CDMMBASE_ADDR_SHIFT 11 | 854 | #define MIPS_CDMMBASE_ADDR_SHIFT 11 |
854 | #define MIPS_CDMMBASE_ADDR_START 15 | 855 | #define MIPS_CDMMBASE_ADDR_START 15 |
855 | 856 | ||
857 | /* RDHWR register numbers */ | ||
858 | #define MIPS_HWR_CPUNUM 0 /* CPU number */ | ||
859 | #define MIPS_HWR_SYNCISTEP 1 /* SYNCI step size */ | ||
860 | #define MIPS_HWR_CC 2 /* Cycle counter */ | ||
861 | #define MIPS_HWR_CCRES 3 /* Cycle counter resolution */ | ||
862 | #define MIPS_HWR_ULR 29 /* UserLocal */ | ||
863 | #define MIPS_HWR_IMPL1 30 /* Implementation dependent */ | ||
864 | #define MIPS_HWR_IMPL2 31 /* Implementation dependent */ | ||
865 | |||
866 | /* Bits in HWREna register */ | ||
867 | #define MIPS_HWRENA_CPUNUM (_ULCAST_(1) << MIPS_HWR_CPUNUM) | ||
868 | #define MIPS_HWRENA_SYNCISTEP (_ULCAST_(1) << MIPS_HWR_SYNCISTEP) | ||
869 | #define MIPS_HWRENA_CC (_ULCAST_(1) << MIPS_HWR_CC) | ||
870 | #define MIPS_HWRENA_CCRES (_ULCAST_(1) << MIPS_HWR_CCRES) | ||
871 | #define MIPS_HWRENA_ULR (_ULCAST_(1) << MIPS_HWR_ULR) | ||
872 | #define MIPS_HWRENA_IMPL1 (_ULCAST_(1) << MIPS_HWR_IMPL1) | ||
873 | #define MIPS_HWRENA_IMPL2 (_ULCAST_(1) << MIPS_HWR_IMPL2) | ||
874 | |||
856 | /* | 875 | /* |
857 | * Bitfields in the TX39 family CP0 Configuration Register 3 | 876 | * Bitfields in the TX39 family CP0 Configuration Register 3 |
858 | */ | 877 | */ |
diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h index d7bfdeba9e84..4f5279a8308d 100644 --- a/arch/mips/include/asm/setup.h +++ b/arch/mips/include/asm/setup.h | |||
@@ -21,6 +21,7 @@ extern void *set_vi_handler(int n, vi_handler_t addr); | |||
21 | 21 | ||
22 | extern void *set_except_vector(int n, void *addr); | 22 | extern void *set_except_vector(int n, void *addr); |
23 | extern unsigned long ebase; | 23 | extern unsigned long ebase; |
24 | extern unsigned int hwrena; | ||
24 | extern void per_cpu_trap_init(bool); | 25 | extern void per_cpu_trap_init(bool); |
25 | extern void cpu_cache_init(void); | 26 | extern void cpu_cache_init(void); |
26 | 27 | ||
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index b6ecfeee4dbe..f7929f65f7ca 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h | |||
@@ -104,8 +104,13 @@ Ip_u1s2(_bltz); | |||
104 | Ip_u1s2(_bltzl); | 104 | Ip_u1s2(_bltzl); |
105 | Ip_u1u2s3(_bne); | 105 | Ip_u1u2s3(_bne); |
106 | Ip_u2s3u1(_cache); | 106 | Ip_u2s3u1(_cache); |
107 | Ip_u1u2(_cfc1); | ||
108 | Ip_u2u1(_cfcmsa); | ||
109 | Ip_u1u2(_ctc1); | ||
110 | Ip_u2u1(_ctcmsa); | ||
107 | Ip_u2u1s3(_daddiu); | 111 | Ip_u2u1s3(_daddiu); |
108 | Ip_u3u1u2(_daddu); | 112 | Ip_u3u1u2(_daddu); |
113 | Ip_u1(_di); | ||
109 | Ip_u2u1msbu3(_dins); | 114 | Ip_u2u1msbu3(_dins); |
110 | Ip_u2u1msbu3(_dinsm); | 115 | Ip_u2u1msbu3(_dinsm); |
111 | Ip_u1u2(_divu); | 116 | Ip_u1u2(_divu); |
@@ -141,6 +146,8 @@ Ip_u1(_mfhi); | |||
141 | Ip_u1(_mflo); | 146 | Ip_u1(_mflo); |
142 | Ip_u1u2u3(_mtc0); | 147 | Ip_u1u2u3(_mtc0); |
143 | Ip_u1u2u3(_mthc0); | 148 | Ip_u1u2u3(_mthc0); |
149 | Ip_u1(_mthi); | ||
150 | Ip_u1(_mtlo); | ||
144 | Ip_u3u1u2(_mul); | 151 | Ip_u3u1u2(_mul); |
145 | Ip_u3u1u2(_or); | 152 | Ip_u3u1u2(_or); |
146 | Ip_u2u1u3(_ori); | 153 | Ip_u2u1u3(_ori); |
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index 8051f9aa1379..77429d1622b3 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h | |||
@@ -21,20 +21,20 @@ | |||
21 | enum major_op { | 21 | enum major_op { |
22 | spec_op, bcond_op, j_op, jal_op, | 22 | spec_op, bcond_op, j_op, jal_op, |
23 | beq_op, bne_op, blez_op, bgtz_op, | 23 | beq_op, bne_op, blez_op, bgtz_op, |
24 | addi_op, cbcond0_op = addi_op, addiu_op, slti_op, sltiu_op, | 24 | addi_op, pop10_op = addi_op, addiu_op, slti_op, sltiu_op, |
25 | andi_op, ori_op, xori_op, lui_op, | 25 | andi_op, ori_op, xori_op, lui_op, |
26 | cop0_op, cop1_op, cop2_op, cop1x_op, | 26 | cop0_op, cop1_op, cop2_op, cop1x_op, |
27 | beql_op, bnel_op, blezl_op, bgtzl_op, | 27 | beql_op, bnel_op, blezl_op, bgtzl_op, |
28 | daddi_op, cbcond1_op = daddi_op, daddiu_op, ldl_op, ldr_op, | 28 | daddi_op, pop30_op = daddi_op, daddiu_op, ldl_op, ldr_op, |
29 | spec2_op, jalx_op, mdmx_op, msa_op = mdmx_op, spec3_op, | 29 | spec2_op, jalx_op, mdmx_op, msa_op = mdmx_op, spec3_op, |
30 | lb_op, lh_op, lwl_op, lw_op, | 30 | lb_op, lh_op, lwl_op, lw_op, |
31 | lbu_op, lhu_op, lwr_op, lwu_op, | 31 | lbu_op, lhu_op, lwr_op, lwu_op, |
32 | sb_op, sh_op, swl_op, sw_op, | 32 | sb_op, sh_op, swl_op, sw_op, |
33 | sdl_op, sdr_op, swr_op, cache_op, | 33 | sdl_op, sdr_op, swr_op, cache_op, |
34 | ll_op, lwc1_op, lwc2_op, bc6_op = lwc2_op, pref_op, | 34 | ll_op, lwc1_op, lwc2_op, bc6_op = lwc2_op, pref_op, |
35 | lld_op, ldc1_op, ldc2_op, beqzcjic_op = ldc2_op, ld_op, | 35 | lld_op, ldc1_op, ldc2_op, pop66_op = ldc2_op, ld_op, |
36 | sc_op, swc1_op, swc2_op, balc6_op = swc2_op, major_3b_op, | 36 | sc_op, swc1_op, swc2_op, balc6_op = swc2_op, major_3b_op, |
37 | scd_op, sdc1_op, sdc2_op, bnezcjialc_op = sdc2_op, sd_op | 37 | scd_op, sdc1_op, sdc2_op, pop76_op = sdc2_op, sd_op |
38 | }; | 38 | }; |
39 | 39 | ||
40 | /* | 40 | /* |
@@ -93,6 +93,50 @@ enum spec3_op { | |||
93 | }; | 93 | }; |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * Bits 10-6 minor opcode for r6 spec mult/div encodings | ||
97 | */ | ||
98 | enum mult_op { | ||
99 | mult_mult_op = 0x0, | ||
100 | mult_mul_op = 0x2, | ||
101 | mult_muh_op = 0x3, | ||
102 | }; | ||
103 | enum multu_op { | ||
104 | multu_multu_op = 0x0, | ||
105 | multu_mulu_op = 0x2, | ||
106 | multu_muhu_op = 0x3, | ||
107 | }; | ||
108 | enum div_op { | ||
109 | div_div_op = 0x0, | ||
110 | div_div6_op = 0x2, | ||
111 | div_mod_op = 0x3, | ||
112 | }; | ||
113 | enum divu_op { | ||
114 | divu_divu_op = 0x0, | ||
115 | divu_divu6_op = 0x2, | ||
116 | divu_modu_op = 0x3, | ||
117 | }; | ||
118 | enum dmult_op { | ||
119 | dmult_dmult_op = 0x0, | ||
120 | dmult_dmul_op = 0x2, | ||
121 | dmult_dmuh_op = 0x3, | ||
122 | }; | ||
123 | enum dmultu_op { | ||
124 | dmultu_dmultu_op = 0x0, | ||
125 | dmultu_dmulu_op = 0x2, | ||
126 | dmultu_dmuhu_op = 0x3, | ||
127 | }; | ||
128 | enum ddiv_op { | ||
129 | ddiv_ddiv_op = 0x0, | ||
130 | ddiv_ddiv6_op = 0x2, | ||
131 | ddiv_dmod_op = 0x3, | ||
132 | }; | ||
133 | enum ddivu_op { | ||
134 | ddivu_ddivu_op = 0x0, | ||
135 | ddivu_ddivu6_op = 0x2, | ||
136 | ddivu_dmodu_op = 0x3, | ||
137 | }; | ||
138 | |||
139 | /* | ||
96 | * rt field of bcond opcodes. | 140 | * rt field of bcond opcodes. |
97 | */ | 141 | */ |
98 | enum rt_op { | 142 | enum rt_op { |
@@ -103,7 +147,7 @@ enum rt_op { | |||
103 | bltzal_op, bgezal_op, bltzall_op, bgezall_op, | 147 | bltzal_op, bgezal_op, bltzall_op, bgezall_op, |
104 | rt_op_0x14, rt_op_0x15, rt_op_0x16, rt_op_0x17, | 148 | rt_op_0x14, rt_op_0x15, rt_op_0x16, rt_op_0x17, |
105 | rt_op_0x18, rt_op_0x19, rt_op_0x1a, rt_op_0x1b, | 149 | rt_op_0x18, rt_op_0x19, rt_op_0x1a, rt_op_0x1b, |
106 | bposge32_op, rt_op_0x1d, rt_op_0x1e, rt_op_0x1f | 150 | bposge32_op, rt_op_0x1d, rt_op_0x1e, synci_op |
107 | }; | 151 | }; |
108 | 152 | ||
109 | /* | 153 | /* |
@@ -238,6 +282,21 @@ enum bshfl_func { | |||
238 | }; | 282 | }; |
239 | 283 | ||
240 | /* | 284 | /* |
285 | * MSA minor opcodes. | ||
286 | */ | ||
287 | enum msa_func { | ||
288 | msa_elm_op = 0x19, | ||
289 | }; | ||
290 | |||
291 | /* | ||
292 | * MSA ELM opcodes. | ||
293 | */ | ||
294 | enum msa_elm { | ||
295 | msa_ctc_op = 0x3e, | ||
296 | msa_cfc_op = 0x7e, | ||
297 | }; | ||
298 | |||
299 | /* | ||
241 | * func field for MSA MI10 format. | 300 | * func field for MSA MI10 format. |
242 | */ | 301 | */ |
243 | enum msa_mi10_func { | 302 | enum msa_mi10_func { |
@@ -264,7 +323,7 @@ enum mm_major_op { | |||
264 | mm_pool32b_op, mm_pool16b_op, mm_lhu16_op, mm_andi16_op, | 323 | mm_pool32b_op, mm_pool16b_op, mm_lhu16_op, mm_andi16_op, |
265 | mm_addiu32_op, mm_lhu32_op, mm_sh32_op, mm_lh32_op, | 324 | mm_addiu32_op, mm_lhu32_op, mm_sh32_op, mm_lh32_op, |
266 | mm_pool32i_op, mm_pool16c_op, mm_lwsp16_op, mm_pool16d_op, | 325 | mm_pool32i_op, mm_pool16c_op, mm_lwsp16_op, mm_pool16d_op, |
267 | mm_ori32_op, mm_pool32f_op, mm_reserved1_op, mm_reserved2_op, | 326 | mm_ori32_op, mm_pool32f_op, mm_pool32s_op, mm_reserved2_op, |
268 | mm_pool32c_op, mm_lwgp16_op, mm_lw16_op, mm_pool16e_op, | 327 | mm_pool32c_op, mm_lwgp16_op, mm_lw16_op, mm_pool16e_op, |
269 | mm_xori32_op, mm_jals32_op, mm_addiupc_op, mm_reserved3_op, | 328 | mm_xori32_op, mm_jals32_op, mm_addiupc_op, mm_reserved3_op, |
270 | mm_reserved4_op, mm_pool16f_op, mm_sb16_op, mm_beqz16_op, | 329 | mm_reserved4_op, mm_pool16f_op, mm_sb16_op, mm_beqz16_op, |
@@ -360,7 +419,10 @@ enum mm_32axf_minor_op { | |||
360 | mm_mflo32_op = 0x075, | 419 | mm_mflo32_op = 0x075, |
361 | mm_jalrhb_op = 0x07c, | 420 | mm_jalrhb_op = 0x07c, |
362 | mm_tlbwi_op = 0x08d, | 421 | mm_tlbwi_op = 0x08d, |
422 | mm_mthi32_op = 0x0b5, | ||
363 | mm_tlbwr_op = 0x0cd, | 423 | mm_tlbwr_op = 0x0cd, |
424 | mm_mtlo32_op = 0x0f5, | ||
425 | mm_di_op = 0x11d, | ||
364 | mm_jalrs_op = 0x13c, | 426 | mm_jalrs_op = 0x13c, |
365 | mm_jalrshb_op = 0x17c, | 427 | mm_jalrshb_op = 0x17c, |
366 | mm_sync_op = 0x1ad, | 428 | mm_sync_op = 0x1ad, |
@@ -479,6 +541,13 @@ enum mm_32f_73_minor_op { | |||
479 | }; | 541 | }; |
480 | 542 | ||
481 | /* | 543 | /* |
544 | * (microMIPS) POOL32S minor opcodes. | ||
545 | */ | ||
546 | enum mm_32s_minor_op { | ||
547 | mm_32s_elm_op = 0x16, | ||
548 | }; | ||
549 | |||
550 | /* | ||
482 | * (microMIPS) POOL16C minor opcodes. | 551 | * (microMIPS) POOL16C minor opcodes. |
483 | */ | 552 | */ |
484 | enum mm_16c_minor_op { | 553 | enum mm_16c_minor_op { |
@@ -586,6 +655,36 @@ struct r_format { /* Register format */ | |||
586 | ;)))))) | 655 | ;)))))) |
587 | }; | 656 | }; |
588 | 657 | ||
658 | struct c0r_format { /* C0 register format */ | ||
659 | __BITFIELD_FIELD(unsigned int opcode : 6, | ||
660 | __BITFIELD_FIELD(unsigned int rs : 5, | ||
661 | __BITFIELD_FIELD(unsigned int rt : 5, | ||
662 | __BITFIELD_FIELD(unsigned int rd : 5, | ||
663 | __BITFIELD_FIELD(unsigned int z: 8, | ||
664 | __BITFIELD_FIELD(unsigned int sel : 3, | ||
665 | ;)))))) | ||
666 | }; | ||
667 | |||
668 | struct mfmc0_format { /* MFMC0 register format */ | ||
669 | __BITFIELD_FIELD(unsigned int opcode : 6, | ||
670 | __BITFIELD_FIELD(unsigned int rs : 5, | ||
671 | __BITFIELD_FIELD(unsigned int rt : 5, | ||
672 | __BITFIELD_FIELD(unsigned int rd : 5, | ||
673 | __BITFIELD_FIELD(unsigned int re : 5, | ||
674 | __BITFIELD_FIELD(unsigned int sc : 1, | ||
675 | __BITFIELD_FIELD(unsigned int : 2, | ||
676 | __BITFIELD_FIELD(unsigned int sel : 3, | ||
677 | ;)))))))) | ||
678 | }; | ||
679 | |||
680 | struct co_format { /* C0 CO format */ | ||
681 | __BITFIELD_FIELD(unsigned int opcode : 6, | ||
682 | __BITFIELD_FIELD(unsigned int co : 1, | ||
683 | __BITFIELD_FIELD(unsigned int code : 19, | ||
684 | __BITFIELD_FIELD(unsigned int func : 6, | ||
685 | ;)))) | ||
686 | }; | ||
687 | |||
589 | struct p_format { /* Performance counter format (R10000) */ | 688 | struct p_format { /* Performance counter format (R10000) */ |
590 | __BITFIELD_FIELD(unsigned int opcode : 6, | 689 | __BITFIELD_FIELD(unsigned int opcode : 6, |
591 | __BITFIELD_FIELD(unsigned int rs : 5, | 690 | __BITFIELD_FIELD(unsigned int rs : 5, |
@@ -937,6 +1036,9 @@ union mips_instruction { | |||
937 | struct u_format u_format; | 1036 | struct u_format u_format; |
938 | struct c_format c_format; | 1037 | struct c_format c_format; |
939 | struct r_format r_format; | 1038 | struct r_format r_format; |
1039 | struct c0r_format c0r_format; | ||
1040 | struct mfmc0_format mfmc0_format; | ||
1041 | struct co_format co_format; | ||
940 | struct p_format p_format; | 1042 | struct p_format p_format; |
941 | struct f_format f_format; | 1043 | struct f_format f_format; |
942 | struct ma_format ma_format; | 1044 | struct ma_format ma_format; |