diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/Kconfig | 8 | ||||
-rw-r--r-- | arch/mips/bcm63xx/nvram.c | 11 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/pci.h | 5 | ||||
-rw-r--r-- | arch/mips/kernel/prom.c | 3 | ||||
-rw-r--r-- | arch/mips/kernel/vpe.c | 17 | ||||
-rw-r--r-- | arch/mips/kvm/kvm_locore.S | 969 | ||||
-rw-r--r-- | arch/mips/kvm/kvm_mips.c | 4 | ||||
-rw-r--r-- | arch/mips/mm/fault.c | 8 | ||||
-rw-r--r-- | arch/mips/mm/hugetlbpage.c | 5 | ||||
-rw-r--r-- | arch/mips/oprofile/common.c | 20 | ||||
-rw-r--r-- | arch/mips/pci/pci.c | 1 | ||||
-rw-r--r-- | arch/mips/sni/a20r.c | 1 |
13 files changed, 534 insertions, 520 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c2917906caaa..a9668d4653c2 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -726,7 +726,6 @@ config CAVIUM_OCTEON_SOC | |||
726 | select SYS_HAS_CPU_CAVIUM_OCTEON | 726 | select SYS_HAS_CPU_CAVIUM_OCTEON |
727 | select SWAP_IO_SPACE | 727 | select SWAP_IO_SPACE |
728 | select HW_HAS_PCI | 728 | select HW_HAS_PCI |
729 | select ARCH_SUPPORTS_MSI | ||
730 | select ZONE_DMA32 | 729 | select ZONE_DMA32 |
731 | select USB_ARCH_HAS_OHCI | 730 | select USB_ARCH_HAS_OHCI |
732 | select USB_ARCH_HAS_EHCI | 731 | select USB_ARCH_HAS_EHCI |
@@ -763,7 +762,6 @@ config NLM_XLR_BOARD | |||
763 | select CEVT_R4K | 762 | select CEVT_R4K |
764 | select CSRC_R4K | 763 | select CSRC_R4K |
765 | select IRQ_CPU | 764 | select IRQ_CPU |
766 | select ARCH_SUPPORTS_MSI | ||
767 | select ZONE_DMA32 if 64BIT | 765 | select ZONE_DMA32 if 64BIT |
768 | select SYNC_R4K | 766 | select SYNC_R4K |
769 | select SYS_HAS_EARLY_PRINTK | 767 | select SYS_HAS_EARLY_PRINTK |
@@ -2296,9 +2294,9 @@ config KEXEC | |||
2296 | 2294 | ||
2297 | It is an ongoing process to be certain the hardware in a machine | 2295 | It is an ongoing process to be certain the hardware in a machine |
2298 | is properly shutdown, so do not be surprised if this code does not | 2296 | is properly shutdown, so do not be surprised if this code does not |
2299 | initially work for you. It may help to enable device hotplugging | 2297 | initially work for you. As of this writing the exact hardware |
2300 | support. As of this writing the exact hardware interface is | 2298 | interface is strongly in flux, so no good recommendation can be |
2301 | strongly in flux, so no good recommendation can be made. | 2299 | made. |
2302 | 2300 | ||
2303 | config CRASH_DUMP | 2301 | config CRASH_DUMP |
2304 | bool "Kernel crash dumps" | 2302 | bool "Kernel crash dumps" |
diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index e652e578a679..4b50d40f7451 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c | |||
@@ -35,6 +35,8 @@ struct bcm963xx_nvram { | |||
35 | u32 checksum_high; | 35 | u32 checksum_high; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #define BCM63XX_DEFAULT_PSI_SIZE 64 | ||
39 | |||
38 | static struct bcm963xx_nvram nvram; | 40 | static struct bcm963xx_nvram nvram; |
39 | static int mac_addr_used; | 41 | static int mac_addr_used; |
40 | 42 | ||
@@ -114,3 +116,12 @@ int bcm63xx_nvram_get_mac_address(u8 *mac) | |||
114 | return 0; | 116 | return 0; |
115 | } | 117 | } |
116 | EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); | 118 | EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); |
119 | |||
120 | int bcm63xx_nvram_get_psi_size(void) | ||
121 | { | ||
122 | if (nvram.psi_size > 0) | ||
123 | return nvram.psi_size; | ||
124 | |||
125 | return BCM63XX_DEFAULT_PSI_SIZE; | ||
126 | } | ||
127 | EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size); | ||
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h index 4e0b6bc1165e..348df49dcc9f 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | |||
@@ -30,4 +30,6 @@ u8 *bcm63xx_nvram_get_name(void); | |||
30 | */ | 30 | */ |
31 | int bcm63xx_nvram_get_mac_address(u8 *mac); | 31 | int bcm63xx_nvram_get_mac_address(u8 *mac); |
32 | 32 | ||
33 | int bcm63xx_nvram_get_psi_size(void); | ||
34 | |||
33 | #endif /* BCM63XX_NVRAM_H */ | 35 | #endif /* BCM63XX_NVRAM_H */ |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index fa8e0aa250ca..f194c08bd057 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h | |||
@@ -136,11 +136,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | |||
136 | return channel ? 15 : 14; | 136 | return channel ? 15 : 14; |
137 | } | 137 | } |
138 | 138 | ||
139 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | ||
140 | /* MSI arch hook for OCTEON */ | ||
141 | #define arch_setup_msi_irqs arch_setup_msi_irqs | ||
142 | #endif | ||
143 | |||
144 | extern char * (*pcibios_plat_setup)(char *str); | 139 | extern char * (*pcibios_plat_setup)(char *str); |
145 | 140 | ||
146 | #ifdef CONFIG_OF | 141 | #ifdef CONFIG_OF |
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 7e954042f252..0fa0b69cdd53 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
@@ -58,8 +58,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | #ifdef CONFIG_BLK_DEV_INITRD | 60 | #ifdef CONFIG_BLK_DEV_INITRD |
61 | void __init early_init_dt_setup_initrd_arch(unsigned long start, | 61 | void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) |
62 | unsigned long end) | ||
63 | { | 62 | { |
64 | initrd_start = (unsigned long)__va(start); | 63 | initrd_start = (unsigned long)__va(start); |
65 | initrd_end = (unsigned long)__va(end); | 64 | initrd_end = (unsigned long)__va(end); |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 1765bab000a0..faf84c5f2629 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -1335,8 +1335,9 @@ static ssize_t store_kill(struct device *dev, struct device_attribute *attr, | |||
1335 | 1335 | ||
1336 | return len; | 1336 | return len; |
1337 | } | 1337 | } |
1338 | static DEVICE_ATTR(kill, S_IWUSR, NULL, store_kill); | ||
1338 | 1339 | ||
1339 | static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr, | 1340 | static ssize_t ntcs_show(struct device *cd, struct device_attribute *attr, |
1340 | char *buf) | 1341 | char *buf) |
1341 | { | 1342 | { |
1342 | struct vpe *vpe = get_vpe(tclimit); | 1343 | struct vpe *vpe = get_vpe(tclimit); |
@@ -1344,7 +1345,7 @@ static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr, | |||
1344 | return sprintf(buf, "%d\n", vpe->ntcs); | 1345 | return sprintf(buf, "%d\n", vpe->ntcs); |
1345 | } | 1346 | } |
1346 | 1347 | ||
1347 | static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, | 1348 | static ssize_t ntcs_store(struct device *dev, struct device_attribute *attr, |
1348 | const char *buf, size_t len) | 1349 | const char *buf, size_t len) |
1349 | { | 1350 | { |
1350 | struct vpe *vpe = get_vpe(tclimit); | 1351 | struct vpe *vpe = get_vpe(tclimit); |
@@ -1365,12 +1366,14 @@ static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, | |||
1365 | out_einval: | 1366 | out_einval: |
1366 | return -EINVAL; | 1367 | return -EINVAL; |
1367 | } | 1368 | } |
1369 | static DEVICE_ATTR_RW(ntcs); | ||
1368 | 1370 | ||
1369 | static struct device_attribute vpe_class_attributes[] = { | 1371 | static struct attribute vpe_attrs[] = { |
1370 | __ATTR(kill, S_IWUSR, NULL, store_kill), | 1372 | &dev_attr_kill.attr, |
1371 | __ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs), | 1373 | &dev_attr_ntcs.attr, |
1372 | {} | 1374 | NULL, |
1373 | }; | 1375 | }; |
1376 | ATTRIBUTE_GROUPS(vpe); | ||
1374 | 1377 | ||
1375 | static void vpe_device_release(struct device *cd) | 1378 | static void vpe_device_release(struct device *cd) |
1376 | { | 1379 | { |
@@ -1381,7 +1384,7 @@ struct class vpe_class = { | |||
1381 | .name = "vpe", | 1384 | .name = "vpe", |
1382 | .owner = THIS_MODULE, | 1385 | .owner = THIS_MODULE, |
1383 | .dev_release = vpe_device_release, | 1386 | .dev_release = vpe_device_release, |
1384 | .dev_attrs = vpe_class_attributes, | 1387 | .dev_groups = vpe_groups, |
1385 | }; | 1388 | }; |
1386 | 1389 | ||
1387 | struct device vpe_device; | 1390 | struct device vpe_device; |
diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S index dca2aa665993..bbace092ad0a 100644 --- a/arch/mips/kvm/kvm_locore.S +++ b/arch/mips/kvm/kvm_locore.S | |||
@@ -1,13 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * This file is subject to the terms and conditions of the GNU General Public | 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 | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Main entry point for the guest, exception handling. | 6 | * Main entry point for the guest, exception handling. |
7 | * | 7 | * |
8 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | 8 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. |
9 | * Authors: Sanjay Lal <sanjayl@kymasys.com> | 9 | * Authors: Sanjay Lal <sanjayl@kymasys.com> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <asm/asm.h> | 12 | #include <asm/asm.h> |
13 | #include <asm/asmmacro.h> | 13 | #include <asm/asmmacro.h> |
@@ -55,195 +55,193 @@ | |||
55 | * a0: run | 55 | * a0: run |
56 | * a1: vcpu | 56 | * a1: vcpu |
57 | */ | 57 | */ |
58 | .set noreorder | ||
59 | .set noat | ||
58 | 60 | ||
59 | FEXPORT(__kvm_mips_vcpu_run) | 61 | FEXPORT(__kvm_mips_vcpu_run) |
60 | .set push | 62 | /* k0/k1 not being used in host kernel context */ |
61 | .set noreorder | 63 | INT_ADDIU k1, sp, -PT_SIZE |
62 | .set noat | 64 | LONG_S $0, PT_R0(k1) |
63 | 65 | LONG_S $1, PT_R1(k1) | |
64 | /* k0/k1 not being used in host kernel context */ | 66 | LONG_S $2, PT_R2(k1) |
65 | addiu k1,sp, -PT_SIZE | 67 | LONG_S $3, PT_R3(k1) |
66 | LONG_S $0, PT_R0(k1) | 68 | |
67 | LONG_S $1, PT_R1(k1) | 69 | LONG_S $4, PT_R4(k1) |
68 | LONG_S $2, PT_R2(k1) | 70 | LONG_S $5, PT_R5(k1) |
69 | LONG_S $3, PT_R3(k1) | 71 | LONG_S $6, PT_R6(k1) |
70 | 72 | LONG_S $7, PT_R7(k1) | |
71 | LONG_S $4, PT_R4(k1) | 73 | |
72 | LONG_S $5, PT_R5(k1) | 74 | LONG_S $8, PT_R8(k1) |
73 | LONG_S $6, PT_R6(k1) | 75 | LONG_S $9, PT_R9(k1) |
74 | LONG_S $7, PT_R7(k1) | 76 | LONG_S $10, PT_R10(k1) |
75 | 77 | LONG_S $11, PT_R11(k1) | |
76 | LONG_S $8, PT_R8(k1) | 78 | LONG_S $12, PT_R12(k1) |
77 | LONG_S $9, PT_R9(k1) | 79 | LONG_S $13, PT_R13(k1) |
78 | LONG_S $10, PT_R10(k1) | 80 | LONG_S $14, PT_R14(k1) |
79 | LONG_S $11, PT_R11(k1) | 81 | LONG_S $15, PT_R15(k1) |
80 | LONG_S $12, PT_R12(k1) | 82 | LONG_S $16, PT_R16(k1) |
81 | LONG_S $13, PT_R13(k1) | 83 | LONG_S $17, PT_R17(k1) |
82 | LONG_S $14, PT_R14(k1) | 84 | |
83 | LONG_S $15, PT_R15(k1) | 85 | LONG_S $18, PT_R18(k1) |
84 | LONG_S $16, PT_R16(k1) | 86 | LONG_S $19, PT_R19(k1) |
85 | LONG_S $17, PT_R17(k1) | 87 | LONG_S $20, PT_R20(k1) |
86 | 88 | LONG_S $21, PT_R21(k1) | |
87 | LONG_S $18, PT_R18(k1) | 89 | LONG_S $22, PT_R22(k1) |
88 | LONG_S $19, PT_R19(k1) | 90 | LONG_S $23, PT_R23(k1) |
89 | LONG_S $20, PT_R20(k1) | 91 | LONG_S $24, PT_R24(k1) |
90 | LONG_S $21, PT_R21(k1) | 92 | LONG_S $25, PT_R25(k1) |
91 | LONG_S $22, PT_R22(k1) | ||
92 | LONG_S $23, PT_R23(k1) | ||
93 | LONG_S $24, PT_R24(k1) | ||
94 | LONG_S $25, PT_R25(k1) | ||
95 | 93 | ||
96 | /* XXXKYMA k0/k1 not saved, not being used if we got here through an ioctl() */ | 94 | /* XXXKYMA k0/k1 not saved, not being used if we got here through an ioctl() */ |
97 | 95 | ||
98 | LONG_S $28, PT_R28(k1) | 96 | LONG_S $28, PT_R28(k1) |
99 | LONG_S $29, PT_R29(k1) | 97 | LONG_S $29, PT_R29(k1) |
100 | LONG_S $30, PT_R30(k1) | 98 | LONG_S $30, PT_R30(k1) |
101 | LONG_S $31, PT_R31(k1) | 99 | LONG_S $31, PT_R31(k1) |
102 | 100 | ||
103 | /* Save hi/lo */ | 101 | /* Save hi/lo */ |
104 | mflo v0 | 102 | mflo v0 |
105 | LONG_S v0, PT_LO(k1) | 103 | LONG_S v0, PT_LO(k1) |
106 | mfhi v1 | 104 | mfhi v1 |
107 | LONG_S v1, PT_HI(k1) | 105 | LONG_S v1, PT_HI(k1) |
108 | 106 | ||
109 | /* Save host status */ | 107 | /* Save host status */ |
110 | mfc0 v0, CP0_STATUS | 108 | mfc0 v0, CP0_STATUS |
111 | LONG_S v0, PT_STATUS(k1) | 109 | LONG_S v0, PT_STATUS(k1) |
112 | 110 | ||
113 | /* Save host ASID, shove it into the BVADDR location */ | 111 | /* Save host ASID, shove it into the BVADDR location */ |
114 | mfc0 v1,CP0_ENTRYHI | 112 | mfc0 v1, CP0_ENTRYHI |
115 | andi v1, 0xff | 113 | andi v1, 0xff |
116 | LONG_S v1, PT_HOST_ASID(k1) | 114 | LONG_S v1, PT_HOST_ASID(k1) |
117 | 115 | ||
118 | /* Save DDATA_LO, will be used to store pointer to vcpu */ | 116 | /* Save DDATA_LO, will be used to store pointer to vcpu */ |
119 | mfc0 v1, CP0_DDATA_LO | 117 | mfc0 v1, CP0_DDATA_LO |
120 | LONG_S v1, PT_HOST_USERLOCAL(k1) | 118 | LONG_S v1, PT_HOST_USERLOCAL(k1) |
121 | 119 | ||
122 | /* DDATA_LO has pointer to vcpu */ | 120 | /* DDATA_LO has pointer to vcpu */ |
123 | mtc0 a1,CP0_DDATA_LO | 121 | mtc0 a1, CP0_DDATA_LO |
124 | 122 | ||
125 | /* Offset into vcpu->arch */ | 123 | /* Offset into vcpu->arch */ |
126 | addiu k1, a1, VCPU_HOST_ARCH | 124 | INT_ADDIU k1, a1, VCPU_HOST_ARCH |
127 | 125 | ||
128 | /* Save the host stack to VCPU, used for exception processing when we exit from the Guest */ | 126 | /* |
129 | LONG_S sp, VCPU_HOST_STACK(k1) | 127 | * Save the host stack to VCPU, used for exception processing |
128 | * when we exit from the Guest | ||
129 | */ | ||
130 | LONG_S sp, VCPU_HOST_STACK(k1) | ||
130 | 131 | ||
131 | /* Save the kernel gp as well */ | 132 | /* Save the kernel gp as well */ |
132 | LONG_S gp, VCPU_HOST_GP(k1) | 133 | LONG_S gp, VCPU_HOST_GP(k1) |
133 | 134 | ||
134 | /* Setup status register for running the guest in UM, interrupts are disabled */ | 135 | /* Setup status register for running the guest in UM, interrupts are disabled */ |
135 | li k0,(ST0_EXL | KSU_USER| ST0_BEV) | 136 | li k0, (ST0_EXL | KSU_USER | ST0_BEV) |
136 | mtc0 k0,CP0_STATUS | 137 | mtc0 k0, CP0_STATUS |
137 | ehb | 138 | ehb |
138 | 139 | ||
139 | /* load up the new EBASE */ | 140 | /* load up the new EBASE */ |
140 | LONG_L k0, VCPU_GUEST_EBASE(k1) | 141 | LONG_L k0, VCPU_GUEST_EBASE(k1) |
141 | mtc0 k0,CP0_EBASE | 142 | mtc0 k0, CP0_EBASE |
142 | 143 | ||
143 | /* Now that the new EBASE has been loaded, unset BEV, set interrupt mask as it was | 144 | /* |
144 | * but make sure that timer interrupts are enabled | 145 | * Now that the new EBASE has been loaded, unset BEV, set |
145 | */ | 146 | * interrupt mask as it was but make sure that timer interrupts |
146 | li k0,(ST0_EXL | KSU_USER | ST0_IE) | 147 | * are enabled |
147 | andi v0, v0, ST0_IM | 148 | */ |
148 | or k0, k0, v0 | 149 | li k0, (ST0_EXL | KSU_USER | ST0_IE) |
149 | mtc0 k0,CP0_STATUS | 150 | andi v0, v0, ST0_IM |
150 | ehb | 151 | or k0, k0, v0 |
152 | mtc0 k0, CP0_STATUS | ||
153 | ehb | ||
151 | 154 | ||
152 | 155 | ||
153 | /* Set Guest EPC */ | 156 | /* Set Guest EPC */ |
154 | LONG_L t0, VCPU_PC(k1) | 157 | LONG_L t0, VCPU_PC(k1) |
155 | mtc0 t0, CP0_EPC | 158 | mtc0 t0, CP0_EPC |
156 | 159 | ||
157 | FEXPORT(__kvm_mips_load_asid) | 160 | FEXPORT(__kvm_mips_load_asid) |
158 | /* Set the ASID for the Guest Kernel */ | 161 | /* Set the ASID for the Guest Kernel */ |
159 | sll t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ | 162 | INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ |
160 | /* addresses shift to 0x80000000 */ | 163 | /* addresses shift to 0x80000000 */ |
161 | bltz t0, 1f /* If kernel */ | 164 | bltz t0, 1f /* If kernel */ |
162 | addiu t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ | 165 | INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ |
163 | addiu t1, k1, VCPU_GUEST_USER_ASID /* else user */ | 166 | INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */ |
164 | 1: | 167 | 1: |
165 | /* t1: contains the base of the ASID array, need to get the cpu id */ | 168 | /* t1: contains the base of the ASID array, need to get the cpu id */ |
166 | LONG_L t2, TI_CPU($28) /* smp_processor_id */ | 169 | LONG_L t2, TI_CPU($28) /* smp_processor_id */ |
167 | sll t2, t2, 2 /* x4 */ | 170 | INT_SLL t2, t2, 2 /* x4 */ |
168 | addu t3, t1, t2 | 171 | REG_ADDU t3, t1, t2 |
169 | LONG_L k0, (t3) | 172 | LONG_L k0, (t3) |
170 | andi k0, k0, 0xff | 173 | andi k0, k0, 0xff |
171 | mtc0 k0,CP0_ENTRYHI | 174 | mtc0 k0, CP0_ENTRYHI |
172 | ehb | 175 | ehb |
173 | 176 | ||
174 | /* Disable RDHWR access */ | 177 | /* Disable RDHWR access */ |
175 | mtc0 zero, CP0_HWRENA | 178 | mtc0 zero, CP0_HWRENA |
176 | 179 | ||
177 | /* Now load up the Guest Context from VCPU */ | 180 | /* Now load up the Guest Context from VCPU */ |
178 | LONG_L $1, VCPU_R1(k1) | 181 | LONG_L $1, VCPU_R1(k1) |
179 | LONG_L $2, VCPU_R2(k1) | 182 | LONG_L $2, VCPU_R2(k1) |
180 | LONG_L $3, VCPU_R3(k1) | 183 | LONG_L $3, VCPU_R3(k1) |
181 | 184 | ||
182 | LONG_L $4, VCPU_R4(k1) | 185 | LONG_L $4, VCPU_R4(k1) |
183 | LONG_L $5, VCPU_R5(k1) | 186 | LONG_L $5, VCPU_R5(k1) |
184 | LONG_L $6, VCPU_R6(k1) | 187 | LONG_L $6, VCPU_R6(k1) |
185 | LONG_L $7, VCPU_R7(k1) | 188 | LONG_L $7, VCPU_R7(k1) |
186 | 189 | ||
187 | LONG_L $8, VCPU_R8(k1) | 190 | LONG_L $8, VCPU_R8(k1) |
188 | LONG_L $9, VCPU_R9(k1) | 191 | LONG_L $9, VCPU_R9(k1) |
189 | LONG_L $10, VCPU_R10(k1) | 192 | LONG_L $10, VCPU_R10(k1) |
190 | LONG_L $11, VCPU_R11(k1) | 193 | LONG_L $11, VCPU_R11(k1) |
191 | LONG_L $12, VCPU_R12(k1) | 194 | LONG_L $12, VCPU_R12(k1) |
192 | LONG_L $13, VCPU_R13(k1) | 195 | LONG_L $13, VCPU_R13(k1) |
193 | LONG_L $14, VCPU_R14(k1) | 196 | LONG_L $14, VCPU_R14(k1) |
194 | LONG_L $15, VCPU_R15(k1) | 197 | LONG_L $15, VCPU_R15(k1) |
195 | LONG_L $16, VCPU_R16(k1) | 198 | LONG_L $16, VCPU_R16(k1) |
196 | LONG_L $17, VCPU_R17(k1) | 199 | LONG_L $17, VCPU_R17(k1) |
197 | LONG_L $18, VCPU_R18(k1) | 200 | LONG_L $18, VCPU_R18(k1) |
198 | LONG_L $19, VCPU_R19(k1) | 201 | LONG_L $19, VCPU_R19(k1) |
199 | LONG_L $20, VCPU_R20(k1) | 202 | LONG_L $20, VCPU_R20(k1) |
200 | LONG_L $21, VCPU_R21(k1) | 203 | LONG_L $21, VCPU_R21(k1) |
201 | LONG_L $22, VCPU_R22(k1) | 204 | LONG_L $22, VCPU_R22(k1) |
202 | LONG_L $23, VCPU_R23(k1) | 205 | LONG_L $23, VCPU_R23(k1) |
203 | LONG_L $24, VCPU_R24(k1) | 206 | LONG_L $24, VCPU_R24(k1) |
204 | LONG_L $25, VCPU_R25(k1) | 207 | LONG_L $25, VCPU_R25(k1) |
205 | 208 | ||
206 | /* k0/k1 loaded up later */ | 209 | /* k0/k1 loaded up later */ |
207 | 210 | ||
208 | LONG_L $28, VCPU_R28(k1) | 211 | LONG_L $28, VCPU_R28(k1) |
209 | LONG_L $29, VCPU_R29(k1) | 212 | LONG_L $29, VCPU_R29(k1) |
210 | LONG_L $30, VCPU_R30(k1) | 213 | LONG_L $30, VCPU_R30(k1) |
211 | LONG_L $31, VCPU_R31(k1) | 214 | LONG_L $31, VCPU_R31(k1) |
212 | 215 | ||
213 | /* Restore hi/lo */ | 216 | /* Restore hi/lo */ |
214 | LONG_L k0, VCPU_LO(k1) | 217 | LONG_L k0, VCPU_LO(k1) |
215 | mtlo k0 | 218 | mtlo k0 |
216 | 219 | ||
217 | LONG_L k0, VCPU_HI(k1) | 220 | LONG_L k0, VCPU_HI(k1) |
218 | mthi k0 | 221 | mthi k0 |
219 | 222 | ||
220 | FEXPORT(__kvm_mips_load_k0k1) | 223 | FEXPORT(__kvm_mips_load_k0k1) |
221 | /* Restore the guest's k0/k1 registers */ | 224 | /* Restore the guest's k0/k1 registers */ |
222 | LONG_L k0, VCPU_R26(k1) | 225 | LONG_L k0, VCPU_R26(k1) |
223 | LONG_L k1, VCPU_R27(k1) | 226 | LONG_L k1, VCPU_R27(k1) |
224 | 227 | ||
225 | /* Jump to guest */ | 228 | /* Jump to guest */ |
226 | eret | 229 | eret |
227 | .set pop | ||
228 | 230 | ||
229 | VECTOR(MIPSX(exception), unknown) | 231 | VECTOR(MIPSX(exception), unknown) |
230 | /* | 232 | /* |
231 | * Find out what mode we came from and jump to the proper handler. | 233 | * Find out what mode we came from and jump to the proper handler. |
232 | */ | 234 | */ |
233 | .set push | 235 | mtc0 k0, CP0_ERROREPC #01: Save guest k0 |
234 | .set noat | 236 | ehb #02: |
235 | .set noreorder | 237 | |
236 | mtc0 k0, CP0_ERROREPC #01: Save guest k0 | 238 | mfc0 k0, CP0_EBASE #02: Get EBASE |
237 | ehb #02: | 239 | INT_SRL k0, k0, 10 #03: Get rid of CPUNum |
238 | 240 | INT_SLL k0, k0, 10 #04 | |
239 | mfc0 k0, CP0_EBASE #02: Get EBASE | 241 | LONG_S k1, 0x3000(k0) #05: Save k1 @ offset 0x3000 |
240 | srl k0, k0, 10 #03: Get rid of CPUNum | 242 | INT_ADDIU k0, k0, 0x2000 #06: Exception handler is installed @ offset 0x2000 |
241 | sll k0, k0, 10 #04 | 243 | j k0 #07: jump to the function |
242 | LONG_S k1, 0x3000(k0) #05: Save k1 @ offset 0x3000 | 244 | nop #08: branch delay slot |
243 | addiu k0, k0, 0x2000 #06: Exception handler is installed @ offset 0x2000 | ||
244 | j k0 #07: jump to the function | ||
245 | nop #08: branch delay slot | ||
246 | .set push | ||
247 | VECTOR_END(MIPSX(exceptionEnd)) | 245 | VECTOR_END(MIPSX(exceptionEnd)) |
248 | .end MIPSX(exception) | 246 | .end MIPSX(exception) |
249 | 247 | ||
@@ -253,329 +251,327 @@ VECTOR_END(MIPSX(exceptionEnd)) | |||
253 | * | 251 | * |
254 | */ | 252 | */ |
255 | NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) | 253 | NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) |
256 | .set push | 254 | /* Get the VCPU pointer from DDTATA_LO */ |
257 | .set noat | 255 | mfc0 k1, CP0_DDATA_LO |
258 | .set noreorder | 256 | INT_ADDIU k1, k1, VCPU_HOST_ARCH |
259 | 257 | ||
260 | /* Get the VCPU pointer from DDTATA_LO */ | 258 | /* Start saving Guest context to VCPU */ |
261 | mfc0 k1, CP0_DDATA_LO | 259 | LONG_S $0, VCPU_R0(k1) |
262 | addiu k1, k1, VCPU_HOST_ARCH | 260 | LONG_S $1, VCPU_R1(k1) |
263 | 261 | LONG_S $2, VCPU_R2(k1) | |
264 | /* Start saving Guest context to VCPU */ | 262 | LONG_S $3, VCPU_R3(k1) |
265 | LONG_S $0, VCPU_R0(k1) | 263 | LONG_S $4, VCPU_R4(k1) |
266 | LONG_S $1, VCPU_R1(k1) | 264 | LONG_S $5, VCPU_R5(k1) |
267 | LONG_S $2, VCPU_R2(k1) | 265 | LONG_S $6, VCPU_R6(k1) |
268 | LONG_S $3, VCPU_R3(k1) | 266 | LONG_S $7, VCPU_R7(k1) |
269 | LONG_S $4, VCPU_R4(k1) | 267 | LONG_S $8, VCPU_R8(k1) |
270 | LONG_S $5, VCPU_R5(k1) | 268 | LONG_S $9, VCPU_R9(k1) |
271 | LONG_S $6, VCPU_R6(k1) | 269 | LONG_S $10, VCPU_R10(k1) |
272 | LONG_S $7, VCPU_R7(k1) | 270 | LONG_S $11, VCPU_R11(k1) |
273 | LONG_S $8, VCPU_R8(k1) | 271 | LONG_S $12, VCPU_R12(k1) |
274 | LONG_S $9, VCPU_R9(k1) | 272 | LONG_S $13, VCPU_R13(k1) |
275 | LONG_S $10, VCPU_R10(k1) | 273 | LONG_S $14, VCPU_R14(k1) |
276 | LONG_S $11, VCPU_R11(k1) | 274 | LONG_S $15, VCPU_R15(k1) |
277 | LONG_S $12, VCPU_R12(k1) | 275 | LONG_S $16, VCPU_R16(k1) |
278 | LONG_S $13, VCPU_R13(k1) | 276 | LONG_S $17, VCPU_R17(k1) |
279 | LONG_S $14, VCPU_R14(k1) | 277 | LONG_S $18, VCPU_R18(k1) |
280 | LONG_S $15, VCPU_R15(k1) | 278 | LONG_S $19, VCPU_R19(k1) |
281 | LONG_S $16, VCPU_R16(k1) | 279 | LONG_S $20, VCPU_R20(k1) |
282 | LONG_S $17,VCPU_R17(k1) | 280 | LONG_S $21, VCPU_R21(k1) |
283 | LONG_S $18, VCPU_R18(k1) | 281 | LONG_S $22, VCPU_R22(k1) |
284 | LONG_S $19, VCPU_R19(k1) | 282 | LONG_S $23, VCPU_R23(k1) |
285 | LONG_S $20, VCPU_R20(k1) | 283 | LONG_S $24, VCPU_R24(k1) |
286 | LONG_S $21, VCPU_R21(k1) | 284 | LONG_S $25, VCPU_R25(k1) |
287 | LONG_S $22, VCPU_R22(k1) | 285 | |
288 | LONG_S $23, VCPU_R23(k1) | 286 | /* Guest k0/k1 saved later */ |
289 | LONG_S $24, VCPU_R24(k1) | 287 | |
290 | LONG_S $25, VCPU_R25(k1) | 288 | LONG_S $28, VCPU_R28(k1) |
291 | 289 | LONG_S $29, VCPU_R29(k1) | |
292 | /* Guest k0/k1 saved later */ | 290 | LONG_S $30, VCPU_R30(k1) |
293 | 291 | LONG_S $31, VCPU_R31(k1) | |
294 | LONG_S $28, VCPU_R28(k1) | 292 | |
295 | LONG_S $29, VCPU_R29(k1) | 293 | /* We need to save hi/lo and restore them on |
296 | LONG_S $30, VCPU_R30(k1) | 294 | * the way out |
297 | LONG_S $31, VCPU_R31(k1) | 295 | */ |
298 | 296 | mfhi t0 | |
299 | /* We need to save hi/lo and restore them on | 297 | LONG_S t0, VCPU_HI(k1) |
300 | * the way out | 298 | |
301 | */ | 299 | mflo t0 |
302 | mfhi t0 | 300 | LONG_S t0, VCPU_LO(k1) |
303 | LONG_S t0, VCPU_HI(k1) | 301 | |
304 | 302 | /* Finally save guest k0/k1 to VCPU */ | |
305 | mflo t0 | 303 | mfc0 t0, CP0_ERROREPC |
306 | LONG_S t0, VCPU_LO(k1) | 304 | LONG_S t0, VCPU_R26(k1) |
307 | 305 | ||
308 | /* Finally save guest k0/k1 to VCPU */ | 306 | /* Get GUEST k1 and save it in VCPU */ |
309 | mfc0 t0, CP0_ERROREPC | 307 | PTR_LI t1, ~0x2ff |
310 | LONG_S t0, VCPU_R26(k1) | 308 | mfc0 t0, CP0_EBASE |
311 | 309 | and t0, t0, t1 | |
312 | /* Get GUEST k1 and save it in VCPU */ | 310 | LONG_L t0, 0x3000(t0) |
313 | la t1, ~0x2ff | 311 | LONG_S t0, VCPU_R27(k1) |
314 | mfc0 t0, CP0_EBASE | 312 | |
315 | and t0, t0, t1 | 313 | /* Now that context has been saved, we can use other registers */ |
316 | LONG_L t0, 0x3000(t0) | 314 | |
317 | LONG_S t0, VCPU_R27(k1) | 315 | /* Restore vcpu */ |
318 | 316 | mfc0 a1, CP0_DDATA_LO | |
319 | /* Now that context has been saved, we can use other registers */ | 317 | move s1, a1 |
320 | 318 | ||
321 | /* Restore vcpu */ | 319 | /* Restore run (vcpu->run) */ |
322 | mfc0 a1, CP0_DDATA_LO | 320 | LONG_L a0, VCPU_RUN(a1) |
323 | move s1, a1 | 321 | /* Save pointer to run in s0, will be saved by the compiler */ |
324 | 322 | move s0, a0 | |
325 | /* Restore run (vcpu->run) */ | 323 | |
326 | LONG_L a0, VCPU_RUN(a1) | 324 | /* Save Host level EPC, BadVaddr and Cause to VCPU, useful to |
327 | /* Save pointer to run in s0, will be saved by the compiler */ | 325 | * process the exception */ |
328 | move s0, a0 | 326 | mfc0 k0,CP0_EPC |
329 | 327 | LONG_S k0, VCPU_PC(k1) | |
330 | 328 | ||
331 | /* Save Host level EPC, BadVaddr and Cause to VCPU, useful to process the exception */ | 329 | mfc0 k0, CP0_BADVADDR |
332 | mfc0 k0,CP0_EPC | 330 | LONG_S k0, VCPU_HOST_CP0_BADVADDR(k1) |
333 | LONG_S k0, VCPU_PC(k1) | 331 | |
334 | 332 | mfc0 k0, CP0_CAUSE | |
335 | mfc0 k0, CP0_BADVADDR | 333 | LONG_S k0, VCPU_HOST_CP0_CAUSE(k1) |
336 | LONG_S k0, VCPU_HOST_CP0_BADVADDR(k1) | 334 | |
337 | 335 | mfc0 k0, CP0_ENTRYHI | |
338 | mfc0 k0, CP0_CAUSE | 336 | LONG_S k0, VCPU_HOST_ENTRYHI(k1) |
339 | LONG_S k0, VCPU_HOST_CP0_CAUSE(k1) | 337 | |
340 | 338 | /* Now restore the host state just enough to run the handlers */ | |
341 | mfc0 k0, CP0_ENTRYHI | 339 | |
342 | LONG_S k0, VCPU_HOST_ENTRYHI(k1) | 340 | /* Swtich EBASE to the one used by Linux */ |
343 | 341 | /* load up the host EBASE */ | |
344 | /* Now restore the host state just enough to run the handlers */ | 342 | mfc0 v0, CP0_STATUS |
345 | 343 | ||
346 | /* Swtich EBASE to the one used by Linux */ | 344 | .set at |
347 | /* load up the host EBASE */ | 345 | or k0, v0, ST0_BEV |
348 | mfc0 v0, CP0_STATUS | 346 | .set noat |
349 | 347 | ||
350 | .set at | 348 | mtc0 k0, CP0_STATUS |
351 | or k0, v0, ST0_BEV | 349 | ehb |
352 | .set noat | 350 | |
353 | 351 | LONG_L k0, VCPU_HOST_EBASE(k1) | |
354 | mtc0 k0, CP0_STATUS | 352 | mtc0 k0,CP0_EBASE |
355 | ehb | 353 | |
356 | |||
357 | LONG_L k0, VCPU_HOST_EBASE(k1) | ||
358 | mtc0 k0,CP0_EBASE | ||
359 | |||
360 | |||
361 | /* Now that the new EBASE has been loaded, unset BEV and KSU_USER */ | ||
362 | .set at | ||
363 | and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE) | ||
364 | or v0, v0, ST0_CU0 | ||
365 | .set noat | ||
366 | mtc0 v0, CP0_STATUS | ||
367 | ehb | ||
368 | |||
369 | /* Load up host GP */ | ||
370 | LONG_L gp, VCPU_HOST_GP(k1) | ||
371 | |||
372 | /* Need a stack before we can jump to "C" */ | ||
373 | LONG_L sp, VCPU_HOST_STACK(k1) | ||
374 | |||
375 | /* Saved host state */ | ||
376 | addiu sp,sp, -PT_SIZE | ||
377 | 354 | ||
378 | /* XXXKYMA do we need to load the host ASID, maybe not because the | 355 | /* Now that the new EBASE has been loaded, unset BEV and KSU_USER */ |
379 | * kernel entries are marked GLOBAL, need to verify | 356 | .set at |
380 | */ | 357 | and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE) |
358 | or v0, v0, ST0_CU0 | ||
359 | .set noat | ||
360 | mtc0 v0, CP0_STATUS | ||
361 | ehb | ||
362 | |||
363 | /* Load up host GP */ | ||
364 | LONG_L gp, VCPU_HOST_GP(k1) | ||
365 | |||
366 | /* Need a stack before we can jump to "C" */ | ||
367 | LONG_L sp, VCPU_HOST_STACK(k1) | ||
368 | |||
369 | /* Saved host state */ | ||
370 | INT_ADDIU sp, sp, -PT_SIZE | ||
381 | 371 | ||
382 | /* Restore host DDATA_LO */ | 372 | /* XXXKYMA do we need to load the host ASID, maybe not because the |
383 | LONG_L k0, PT_HOST_USERLOCAL(sp) | 373 | * kernel entries are marked GLOBAL, need to verify |
384 | mtc0 k0, CP0_DDATA_LO | 374 | */ |
385 | 375 | ||
386 | /* Restore RDHWR access */ | 376 | /* Restore host DDATA_LO */ |
387 | la k0, 0x2000000F | 377 | LONG_L k0, PT_HOST_USERLOCAL(sp) |
388 | mtc0 k0, CP0_HWRENA | 378 | mtc0 k0, CP0_DDATA_LO |
389 | 379 | ||
390 | /* Jump to handler */ | 380 | /* Restore RDHWR access */ |
381 | PTR_LI k0, 0x2000000F | ||
382 | mtc0 k0, CP0_HWRENA | ||
383 | |||
384 | /* Jump to handler */ | ||
391 | FEXPORT(__kvm_mips_jump_to_handler) | 385 | FEXPORT(__kvm_mips_jump_to_handler) |
392 | /* XXXKYMA: not sure if this is safe, how large is the stack?? */ | 386 | /* XXXKYMA: not sure if this is safe, how large is the stack?? |
393 | /* Now jump to the kvm_mips_handle_exit() to see if we can deal with this in the kernel */ | 387 | * Now jump to the kvm_mips_handle_exit() to see if we can deal |
394 | la t9,kvm_mips_handle_exit | 388 | * with this in the kernel */ |
395 | jalr.hb t9 | 389 | PTR_LA t9, kvm_mips_handle_exit |
396 | addiu sp,sp, -CALLFRAME_SIZ /* BD Slot */ | 390 | jalr.hb t9 |
397 | 391 | INT_ADDIU sp, sp, -CALLFRAME_SIZ /* BD Slot */ | |
398 | /* Return from handler Make sure interrupts are disabled */ | 392 | |
399 | di | 393 | /* Return from handler Make sure interrupts are disabled */ |
400 | ehb | 394 | di |
401 | 395 | ehb | |
402 | /* XXXKYMA: k0/k1 could have been blown away if we processed an exception | 396 | |
403 | * while we were handling the exception from the guest, reload k1 | 397 | /* XXXKYMA: k0/k1 could have been blown away if we processed |
404 | */ | 398 | * an exception while we were handling the exception from the |
405 | move k1, s1 | 399 | * guest, reload k1 |
406 | addiu k1, k1, VCPU_HOST_ARCH | 400 | */ |
407 | 401 | ||
408 | /* Check return value, should tell us if we are returning to the host (handle I/O etc) | 402 | move k1, s1 |
409 | * or resuming the guest | 403 | INT_ADDIU k1, k1, VCPU_HOST_ARCH |
410 | */ | 404 | |
411 | andi t0, v0, RESUME_HOST | 405 | /* Check return value, should tell us if we are returning to the |
412 | bnez t0, __kvm_mips_return_to_host | 406 | * host (handle I/O etc)or resuming the guest |
413 | nop | 407 | */ |
408 | andi t0, v0, RESUME_HOST | ||
409 | bnez t0, __kvm_mips_return_to_host | ||
410 | nop | ||
414 | 411 | ||
415 | __kvm_mips_return_to_guest: | 412 | __kvm_mips_return_to_guest: |
416 | /* Put the saved pointer to vcpu (s1) back into the DDATA_LO Register */ | 413 | /* Put the saved pointer to vcpu (s1) back into the DDATA_LO Register */ |
417 | mtc0 s1, CP0_DDATA_LO | 414 | mtc0 s1, CP0_DDATA_LO |
418 | |||
419 | /* Load up the Guest EBASE to minimize the window where BEV is set */ | ||
420 | LONG_L t0, VCPU_GUEST_EBASE(k1) | ||
421 | |||
422 | /* Switch EBASE back to the one used by KVM */ | ||
423 | mfc0 v1, CP0_STATUS | ||
424 | .set at | ||
425 | or k0, v1, ST0_BEV | ||
426 | .set noat | ||
427 | mtc0 k0, CP0_STATUS | ||
428 | ehb | ||
429 | mtc0 t0,CP0_EBASE | ||
430 | |||
431 | /* Setup status register for running guest in UM */ | ||
432 | .set at | ||
433 | or v1, v1, (ST0_EXL | KSU_USER | ST0_IE) | ||
434 | and v1, v1, ~ST0_CU0 | ||
435 | .set noat | ||
436 | mtc0 v1, CP0_STATUS | ||
437 | ehb | ||
438 | 415 | ||
416 | /* Load up the Guest EBASE to minimize the window where BEV is set */ | ||
417 | LONG_L t0, VCPU_GUEST_EBASE(k1) | ||
418 | |||
419 | /* Switch EBASE back to the one used by KVM */ | ||
420 | mfc0 v1, CP0_STATUS | ||
421 | .set at | ||
422 | or k0, v1, ST0_BEV | ||
423 | .set noat | ||
424 | mtc0 k0, CP0_STATUS | ||
425 | ehb | ||
426 | mtc0 t0, CP0_EBASE | ||
427 | |||
428 | /* Setup status register for running guest in UM */ | ||
429 | .set at | ||
430 | or v1, v1, (ST0_EXL | KSU_USER | ST0_IE) | ||
431 | and v1, v1, ~ST0_CU0 | ||
432 | .set noat | ||
433 | mtc0 v1, CP0_STATUS | ||
434 | ehb | ||
439 | 435 | ||
440 | /* Set Guest EPC */ | 436 | /* Set Guest EPC */ |
441 | LONG_L t0, VCPU_PC(k1) | 437 | LONG_L t0, VCPU_PC(k1) |
442 | mtc0 t0, CP0_EPC | 438 | mtc0 t0, CP0_EPC |
443 | 439 | ||
444 | /* Set the ASID for the Guest Kernel */ | 440 | /* Set the ASID for the Guest Kernel */ |
445 | sll t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ | 441 | INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ |
446 | /* addresses shift to 0x80000000 */ | 442 | /* addresses shift to 0x80000000 */ |
447 | bltz t0, 1f /* If kernel */ | 443 | bltz t0, 1f /* If kernel */ |
448 | addiu t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ | 444 | INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ |
449 | addiu t1, k1, VCPU_GUEST_USER_ASID /* else user */ | 445 | INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */ |
450 | 1: | 446 | 1: |
451 | /* t1: contains the base of the ASID array, need to get the cpu id */ | 447 | /* t1: contains the base of the ASID array, need to get the cpu id */ |
452 | LONG_L t2, TI_CPU($28) /* smp_processor_id */ | 448 | LONG_L t2, TI_CPU($28) /* smp_processor_id */ |
453 | sll t2, t2, 2 /* x4 */ | 449 | INT_SLL t2, t2, 2 /* x4 */ |
454 | addu t3, t1, t2 | 450 | REG_ADDU t3, t1, t2 |
455 | LONG_L k0, (t3) | 451 | LONG_L k0, (t3) |
456 | andi k0, k0, 0xff | 452 | andi k0, k0, 0xff |
457 | mtc0 k0,CP0_ENTRYHI | 453 | mtc0 k0,CP0_ENTRYHI |
458 | ehb | 454 | ehb |
459 | 455 | ||
460 | /* Disable RDHWR access */ | 456 | /* Disable RDHWR access */ |
461 | mtc0 zero, CP0_HWRENA | 457 | mtc0 zero, CP0_HWRENA |
462 | 458 | ||
463 | /* load the guest context from VCPU and return */ | 459 | /* load the guest context from VCPU and return */ |
464 | LONG_L $0, VCPU_R0(k1) | 460 | LONG_L $0, VCPU_R0(k1) |
465 | LONG_L $1, VCPU_R1(k1) | 461 | LONG_L $1, VCPU_R1(k1) |
466 | LONG_L $2, VCPU_R2(k1) | 462 | LONG_L $2, VCPU_R2(k1) |
467 | LONG_L $3, VCPU_R3(k1) | 463 | LONG_L $3, VCPU_R3(k1) |
468 | LONG_L $4, VCPU_R4(k1) | 464 | LONG_L $4, VCPU_R4(k1) |
469 | LONG_L $5, VCPU_R5(k1) | 465 | LONG_L $5, VCPU_R5(k1) |
470 | LONG_L $6, VCPU_R6(k1) | 466 | LONG_L $6, VCPU_R6(k1) |
471 | LONG_L $7, VCPU_R7(k1) | 467 | LONG_L $7, VCPU_R7(k1) |
472 | LONG_L $8, VCPU_R8(k1) | 468 | LONG_L $8, VCPU_R8(k1) |
473 | LONG_L $9, VCPU_R9(k1) | 469 | LONG_L $9, VCPU_R9(k1) |
474 | LONG_L $10, VCPU_R10(k1) | 470 | LONG_L $10, VCPU_R10(k1) |
475 | LONG_L $11, VCPU_R11(k1) | 471 | LONG_L $11, VCPU_R11(k1) |
476 | LONG_L $12, VCPU_R12(k1) | 472 | LONG_L $12, VCPU_R12(k1) |
477 | LONG_L $13, VCPU_R13(k1) | 473 | LONG_L $13, VCPU_R13(k1) |
478 | LONG_L $14, VCPU_R14(k1) | 474 | LONG_L $14, VCPU_R14(k1) |
479 | LONG_L $15, VCPU_R15(k1) | 475 | LONG_L $15, VCPU_R15(k1) |
480 | LONG_L $16, VCPU_R16(k1) | 476 | LONG_L $16, VCPU_R16(k1) |
481 | LONG_L $17, VCPU_R17(k1) | 477 | LONG_L $17, VCPU_R17(k1) |
482 | LONG_L $18, VCPU_R18(k1) | 478 | LONG_L $18, VCPU_R18(k1) |
483 | LONG_L $19, VCPU_R19(k1) | 479 | LONG_L $19, VCPU_R19(k1) |
484 | LONG_L $20, VCPU_R20(k1) | 480 | LONG_L $20, VCPU_R20(k1) |
485 | LONG_L $21, VCPU_R21(k1) | 481 | LONG_L $21, VCPU_R21(k1) |
486 | LONG_L $22, VCPU_R22(k1) | 482 | LONG_L $22, VCPU_R22(k1) |
487 | LONG_L $23, VCPU_R23(k1) | 483 | LONG_L $23, VCPU_R23(k1) |
488 | LONG_L $24, VCPU_R24(k1) | 484 | LONG_L $24, VCPU_R24(k1) |
489 | LONG_L $25, VCPU_R25(k1) | 485 | LONG_L $25, VCPU_R25(k1) |
490 | 486 | ||
491 | /* $/k1 loaded later */ | 487 | /* $/k1 loaded later */ |
492 | LONG_L $28, VCPU_R28(k1) | 488 | LONG_L $28, VCPU_R28(k1) |
493 | LONG_L $29, VCPU_R29(k1) | 489 | LONG_L $29, VCPU_R29(k1) |
494 | LONG_L $30, VCPU_R30(k1) | 490 | LONG_L $30, VCPU_R30(k1) |
495 | LONG_L $31, VCPU_R31(k1) | 491 | LONG_L $31, VCPU_R31(k1) |
496 | 492 | ||
497 | FEXPORT(__kvm_mips_skip_guest_restore) | 493 | FEXPORT(__kvm_mips_skip_guest_restore) |
498 | LONG_L k0, VCPU_HI(k1) | 494 | LONG_L k0, VCPU_HI(k1) |
499 | mthi k0 | 495 | mthi k0 |
500 | 496 | ||
501 | LONG_L k0, VCPU_LO(k1) | 497 | LONG_L k0, VCPU_LO(k1) |
502 | mtlo k0 | 498 | mtlo k0 |
503 | 499 | ||
504 | LONG_L k0, VCPU_R26(k1) | 500 | LONG_L k0, VCPU_R26(k1) |
505 | LONG_L k1, VCPU_R27(k1) | 501 | LONG_L k1, VCPU_R27(k1) |
506 | 502 | ||
507 | eret | 503 | eret |
508 | 504 | ||
509 | __kvm_mips_return_to_host: | 505 | __kvm_mips_return_to_host: |
510 | /* EBASE is already pointing to Linux */ | 506 | /* EBASE is already pointing to Linux */ |
511 | LONG_L k1, VCPU_HOST_STACK(k1) | 507 | LONG_L k1, VCPU_HOST_STACK(k1) |
512 | addiu k1,k1, -PT_SIZE | 508 | INT_ADDIU k1,k1, -PT_SIZE |
513 | 509 | ||
514 | /* Restore host DDATA_LO */ | 510 | /* Restore host DDATA_LO */ |
515 | LONG_L k0, PT_HOST_USERLOCAL(k1) | 511 | LONG_L k0, PT_HOST_USERLOCAL(k1) |
516 | mtc0 k0, CP0_DDATA_LO | 512 | mtc0 k0, CP0_DDATA_LO |
517 | 513 | ||
518 | /* Restore host ASID */ | 514 | /* Restore host ASID */ |
519 | LONG_L k0, PT_HOST_ASID(sp) | 515 | LONG_L k0, PT_HOST_ASID(sp) |
520 | andi k0, 0xff | 516 | andi k0, 0xff |
521 | mtc0 k0,CP0_ENTRYHI | 517 | mtc0 k0,CP0_ENTRYHI |
522 | ehb | 518 | ehb |
523 | 519 | ||
524 | /* Load context saved on the host stack */ | 520 | /* Load context saved on the host stack */ |
525 | LONG_L $0, PT_R0(k1) | 521 | LONG_L $0, PT_R0(k1) |
526 | LONG_L $1, PT_R1(k1) | 522 | LONG_L $1, PT_R1(k1) |
527 | 523 | ||
528 | /* r2/v0 is the return code, shift it down by 2 (arithmetic) to recover the err code */ | 524 | /* r2/v0 is the return code, shift it down by 2 (arithmetic) |
529 | sra k0, v0, 2 | 525 | * to recover the err code */ |
530 | move $2, k0 | 526 | INT_SRA k0, v0, 2 |
531 | 527 | move $2, k0 | |
532 | LONG_L $3, PT_R3(k1) | 528 | |
533 | LONG_L $4, PT_R4(k1) | 529 | LONG_L $3, PT_R3(k1) |
534 | LONG_L $5, PT_R5(k1) | 530 | LONG_L $4, PT_R4(k1) |
535 | LONG_L $6, PT_R6(k1) | 531 | LONG_L $5, PT_R5(k1) |
536 | LONG_L $7, PT_R7(k1) | 532 | LONG_L $6, PT_R6(k1) |
537 | LONG_L $8, PT_R8(k1) | 533 | LONG_L $7, PT_R7(k1) |
538 | LONG_L $9, PT_R9(k1) | 534 | LONG_L $8, PT_R8(k1) |
539 | LONG_L $10, PT_R10(k1) | 535 | LONG_L $9, PT_R9(k1) |
540 | LONG_L $11, PT_R11(k1) | 536 | LONG_L $10, PT_R10(k1) |
541 | LONG_L $12, PT_R12(k1) | 537 | LONG_L $11, PT_R11(k1) |
542 | LONG_L $13, PT_R13(k1) | 538 | LONG_L $12, PT_R12(k1) |
543 | LONG_L $14, PT_R14(k1) | 539 | LONG_L $13, PT_R13(k1) |
544 | LONG_L $15, PT_R15(k1) | 540 | LONG_L $14, PT_R14(k1) |
545 | LONG_L $16, PT_R16(k1) | 541 | LONG_L $15, PT_R15(k1) |
546 | LONG_L $17, PT_R17(k1) | 542 | LONG_L $16, PT_R16(k1) |
547 | LONG_L $18, PT_R18(k1) | 543 | LONG_L $17, PT_R17(k1) |
548 | LONG_L $19, PT_R19(k1) | 544 | LONG_L $18, PT_R18(k1) |
549 | LONG_L $20, PT_R20(k1) | 545 | LONG_L $19, PT_R19(k1) |
550 | LONG_L $21, PT_R21(k1) | 546 | LONG_L $20, PT_R20(k1) |
551 | LONG_L $22, PT_R22(k1) | 547 | LONG_L $21, PT_R21(k1) |
552 | LONG_L $23, PT_R23(k1) | 548 | LONG_L $22, PT_R22(k1) |
553 | LONG_L $24, PT_R24(k1) | 549 | LONG_L $23, PT_R23(k1) |
554 | LONG_L $25, PT_R25(k1) | 550 | LONG_L $24, PT_R24(k1) |
555 | 551 | LONG_L $25, PT_R25(k1) | |
556 | /* Host k0/k1 were not saved */ | 552 | |
557 | 553 | /* Host k0/k1 were not saved */ | |
558 | LONG_L $28, PT_R28(k1) | 554 | |
559 | LONG_L $29, PT_R29(k1) | 555 | LONG_L $28, PT_R28(k1) |
560 | LONG_L $30, PT_R30(k1) | 556 | LONG_L $29, PT_R29(k1) |
561 | 557 | LONG_L $30, PT_R30(k1) | |
562 | LONG_L k0, PT_HI(k1) | 558 | |
563 | mthi k0 | 559 | LONG_L k0, PT_HI(k1) |
564 | 560 | mthi k0 | |
565 | LONG_L k0, PT_LO(k1) | 561 | |
566 | mtlo k0 | 562 | LONG_L k0, PT_LO(k1) |
567 | 563 | mtlo k0 | |
568 | /* Restore RDHWR access */ | 564 | |
569 | la k0, 0x2000000F | 565 | /* Restore RDHWR access */ |
570 | mtc0 k0, CP0_HWRENA | 566 | PTR_LI k0, 0x2000000F |
571 | 567 | mtc0 k0, CP0_HWRENA | |
572 | 568 | ||
573 | /* Restore RA, which is the address we will return to */ | 569 | |
574 | LONG_L ra, PT_R31(k1) | 570 | /* Restore RA, which is the address we will return to */ |
575 | j ra | 571 | LONG_L ra, PT_R31(k1) |
576 | nop | 572 | j ra |
577 | 573 | nop | |
578 | .set pop | 574 | |
579 | VECTOR_END(MIPSX(GuestExceptionEnd)) | 575 | VECTOR_END(MIPSX(GuestExceptionEnd)) |
580 | .end MIPSX(GuestException) | 576 | .end MIPSX(GuestException) |
581 | 577 | ||
@@ -627,24 +623,23 @@ MIPSX(exceptions): | |||
627 | 623 | ||
628 | #define HW_SYNCI_Step $1 | 624 | #define HW_SYNCI_Step $1 |
629 | LEAF(MIPSX(SyncICache)) | 625 | LEAF(MIPSX(SyncICache)) |
630 | .set push | 626 | .set push |
631 | .set mips32r2 | 627 | .set mips32r2 |
632 | beq a1, zero, 20f | 628 | beq a1, zero, 20f |
633 | nop | 629 | nop |
634 | addu a1, a0, a1 | 630 | REG_ADDU a1, a0, a1 |
635 | rdhwr v0, HW_SYNCI_Step | 631 | rdhwr v0, HW_SYNCI_Step |
636 | beq v0, zero, 20f | 632 | beq v0, zero, 20f |
637 | nop | 633 | nop |
638 | |||
639 | 10: | 634 | 10: |
640 | synci 0(a0) | 635 | synci 0(a0) |
641 | addu a0, a0, v0 | 636 | REG_ADDU a0, a0, v0 |
642 | sltu v1, a0, a1 | 637 | sltu v1, a0, a1 |
643 | bne v1, zero, 10b | 638 | bne v1, zero, 10b |
644 | nop | 639 | nop |
645 | sync | 640 | sync |
646 | 20: | 641 | 20: |
647 | jr.hb ra | 642 | jr.hb ra |
648 | nop | 643 | nop |
649 | .set pop | 644 | .set pop |
650 | END(MIPSX(SyncICache)) | 645 | END(MIPSX(SyncICache)) |
diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c index dd203e59e6fd..a7b044536de4 100644 --- a/arch/mips/kvm/kvm_mips.c +++ b/arch/mips/kvm/kvm_mips.c | |||
@@ -208,6 +208,10 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | |||
208 | return 0; | 208 | return 0; |
209 | } | 209 | } |
210 | 210 | ||
211 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
212 | { | ||
213 | } | ||
214 | |||
211 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 215 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
212 | struct kvm_memory_slot *memslot, | 216 | struct kvm_memory_slot *memslot, |
213 | struct kvm_userspace_memory_region *mem, | 217 | struct kvm_userspace_memory_region *mem, |
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 85df1cd8d446..becc42bb1849 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c | |||
@@ -42,8 +42,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write, | |||
42 | const int field = sizeof(unsigned long) * 2; | 42 | const int field = sizeof(unsigned long) * 2; |
43 | siginfo_t info; | 43 | siginfo_t info; |
44 | int fault; | 44 | int fault; |
45 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | | 45 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
46 | (write ? FAULT_FLAG_WRITE : 0); | ||
47 | 46 | ||
48 | #if 0 | 47 | #if 0 |
49 | printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(), | 48 | printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(), |
@@ -93,6 +92,8 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write, | |||
93 | if (in_atomic() || !mm) | 92 | if (in_atomic() || !mm) |
94 | goto bad_area_nosemaphore; | 93 | goto bad_area_nosemaphore; |
95 | 94 | ||
95 | if (user_mode(regs)) | ||
96 | flags |= FAULT_FLAG_USER; | ||
96 | retry: | 97 | retry: |
97 | down_read(&mm->mmap_sem); | 98 | down_read(&mm->mmap_sem); |
98 | vma = find_vma(mm, address); | 99 | vma = find_vma(mm, address); |
@@ -114,6 +115,7 @@ good_area: | |||
114 | if (write) { | 115 | if (write) { |
115 | if (!(vma->vm_flags & VM_WRITE)) | 116 | if (!(vma->vm_flags & VM_WRITE)) |
116 | goto bad_area; | 117 | goto bad_area; |
118 | flags |= FAULT_FLAG_WRITE; | ||
117 | } else { | 119 | } else { |
118 | if (cpu_has_rixi) { | 120 | if (cpu_has_rixi) { |
119 | if (address == regs->cp0_epc && !(vma->vm_flags & VM_EXEC)) { | 121 | if (address == regs->cp0_epc && !(vma->vm_flags & VM_EXEC)) { |
@@ -241,6 +243,8 @@ out_of_memory: | |||
241 | * (which will retry the fault, or kill us if we got oom-killed). | 243 | * (which will retry the fault, or kill us if we got oom-killed). |
242 | */ | 244 | */ |
243 | up_read(&mm->mmap_sem); | 245 | up_read(&mm->mmap_sem); |
246 | if (!user_mode(regs)) | ||
247 | goto no_context; | ||
244 | pagefault_out_of_memory(); | 248 | pagefault_out_of_memory(); |
245 | return; | 249 | return; |
246 | 250 | ||
diff --git a/arch/mips/mm/hugetlbpage.c b/arch/mips/mm/hugetlbpage.c index a7fee0dfb7a9..01fda4419ed0 100644 --- a/arch/mips/mm/hugetlbpage.c +++ b/arch/mips/mm/hugetlbpage.c | |||
@@ -85,6 +85,11 @@ int pud_huge(pud_t pud) | |||
85 | return (pud_val(pud) & _PAGE_HUGE) != 0; | 85 | return (pud_val(pud) & _PAGE_HUGE) != 0; |
86 | } | 86 | } |
87 | 87 | ||
88 | int pmd_huge_support(void) | ||
89 | { | ||
90 | return 1; | ||
91 | } | ||
92 | |||
88 | struct page * | 93 | struct page * |
89 | follow_huge_pmd(struct mm_struct *mm, unsigned long address, | 94 | follow_huge_pmd(struct mm_struct *mm, unsigned long address, |
90 | pmd_t *pmd, int write) | 95 | pmd_t *pmd, int write) |
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index af763e838fdd..5e5424753b56 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
@@ -33,7 +33,7 @@ static int op_mips_setup(void) | |||
33 | return 0; | 33 | return 0; |
34 | } | 34 | } |
35 | 35 | ||
36 | static int op_mips_create_files(struct super_block *sb, struct dentry *root) | 36 | static int op_mips_create_files(struct dentry *root) |
37 | { | 37 | { |
38 | int i; | 38 | int i; |
39 | 39 | ||
@@ -42,16 +42,16 @@ static int op_mips_create_files(struct super_block *sb, struct dentry *root) | |||
42 | char buf[4]; | 42 | char buf[4]; |
43 | 43 | ||
44 | snprintf(buf, sizeof buf, "%d", i); | 44 | snprintf(buf, sizeof buf, "%d", i); |
45 | dir = oprofilefs_mkdir(sb, root, buf); | 45 | dir = oprofilefs_mkdir(root, buf); |
46 | 46 | ||
47 | oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); | 47 | oprofilefs_create_ulong(dir, "enabled", &ctr[i].enabled); |
48 | oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); | 48 | oprofilefs_create_ulong(dir, "event", &ctr[i].event); |
49 | oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); | 49 | oprofilefs_create_ulong(dir, "count", &ctr[i].count); |
50 | oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); | 50 | oprofilefs_create_ulong(dir, "kernel", &ctr[i].kernel); |
51 | oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); | 51 | oprofilefs_create_ulong(dir, "user", &ctr[i].user); |
52 | oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl); | 52 | oprofilefs_create_ulong(dir, "exl", &ctr[i].exl); |
53 | /* Dummy. */ | 53 | /* Dummy. */ |
54 | oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); | 54 | oprofilefs_create_ulong(dir, "unit_mask", &ctr[i].unit_mask); |
55 | } | 55 | } |
56 | 56 | ||
57 | return 0; | 57 | return 0; |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 594e60d6a43b..33e7aa52d9c4 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -113,7 +113,6 @@ static void pcibios_scanbus(struct pci_controller *hose) | |||
113 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 113 | if (!pci_has_flag(PCI_PROBE_ONLY)) { |
114 | pci_bus_size_bridges(bus); | 114 | pci_bus_size_bridges(bus); |
115 | pci_bus_assign_resources(bus); | 115 | pci_bus_assign_resources(bus); |
116 | pci_enable_bridges(bus); | ||
117 | } | 116 | } |
118 | } | 117 | } |
119 | } | 118 | } |
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index dd0ab982d77e..f9407e170476 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c | |||
@@ -122,7 +122,6 @@ static struct resource sc26xx_rsrc[] = { | |||
122 | 122 | ||
123 | static struct sccnxp_pdata sccnxp_data = { | 123 | static struct sccnxp_pdata sccnxp_data = { |
124 | .reg_shift = 2, | 124 | .reg_shift = 2, |
125 | .frequency = 3686400, | ||
126 | .mctrl_cfg[0] = MCTRL_SIG(DTR_OP, LINE_OP7) | | 125 | .mctrl_cfg[0] = MCTRL_SIG(DTR_OP, LINE_OP7) | |
127 | MCTRL_SIG(RTS_OP, LINE_OP3) | | 126 | MCTRL_SIG(RTS_OP, LINE_OP3) | |
128 | MCTRL_SIG(DSR_IP, LINE_IP5) | | 127 | MCTRL_SIG(DSR_IP, LINE_IP5) | |