diff options
Diffstat (limited to 'arch/powerpc')
26 files changed, 436 insertions, 215 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index bbe149c26518..369d93e7377c 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -19,6 +19,9 @@ config WORD_SIZE | |||
19 | default 64 if PPC64 | 19 | default 64 if PPC64 |
20 | default 32 if !PPC64 | 20 | default 32 if !PPC64 |
21 | 21 | ||
22 | config ARCH_PHYS_ADDR_T_64BIT | ||
23 | def_bool PPC64 || PHYS_64BIT | ||
24 | |||
22 | config MMU | 25 | config MMU |
23 | bool | 26 | bool |
24 | default y | 27 | default y |
@@ -224,6 +227,8 @@ config PPC_OF_PLATFORM_PCI | |||
224 | 227 | ||
225 | source "init/Kconfig" | 228 | source "init/Kconfig" |
226 | 229 | ||
230 | source "kernel/Kconfig.freezer" | ||
231 | |||
227 | source "arch/powerpc/sysdev/Kconfig" | 232 | source "arch/powerpc/sysdev/Kconfig" |
228 | source "arch/powerpc/platforms/Kconfig" | 233 | source "arch/powerpc/platforms/Kconfig" |
229 | 234 | ||
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index 64c6ee22eefd..d812929390e4 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h | |||
@@ -232,7 +232,7 @@ typedef elf_vrregset_t elf_fpxregset_t; | |||
232 | #endif /* __powerpc64__ */ | 232 | #endif /* __powerpc64__ */ |
233 | 233 | ||
234 | #ifdef __powerpc64__ | 234 | #ifdef __powerpc64__ |
235 | # define SET_PERSONALITY(ex, ibcs2) \ | 235 | # define SET_PERSONALITY(ex) \ |
236 | do { \ | 236 | do { \ |
237 | unsigned long new_flags = 0; \ | 237 | unsigned long new_flags = 0; \ |
238 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | 238 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ |
@@ -256,7 +256,7 @@ do { \ | |||
256 | # define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \ | 256 | # define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \ |
257 | (exec_stk != EXSTACK_DISABLE_X) : 0) | 257 | (exec_stk != EXSTACK_DISABLE_X) : 0) |
258 | #else | 258 | #else |
259 | # define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) | 259 | # define SET_PERSONALITY(ex) set_personality(PER_LINUX) |
260 | #endif /* __powerpc64__ */ | 260 | #endif /* __powerpc64__ */ |
261 | 261 | ||
262 | extern int dcache_bsize; | 262 | extern int dcache_bsize; |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 2655e2a4831e..34b52b7180cd 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -81,11 +81,17 @@ struct kvm_vcpu_arch { | |||
81 | struct tlbe shadow_tlb[PPC44x_TLB_SIZE]; | 81 | struct tlbe shadow_tlb[PPC44x_TLB_SIZE]; |
82 | /* Pages which are referenced in the shadow TLB. */ | 82 | /* Pages which are referenced in the shadow TLB. */ |
83 | struct page *shadow_pages[PPC44x_TLB_SIZE]; | 83 | struct page *shadow_pages[PPC44x_TLB_SIZE]; |
84 | /* Copy of the host's TLB. */ | 84 | |
85 | struct tlbe host_tlb[PPC44x_TLB_SIZE]; | 85 | /* Track which TLB entries we've modified in the current exit. */ |
86 | u8 shadow_tlb_mod[PPC44x_TLB_SIZE]; | ||
86 | 87 | ||
87 | u32 host_stack; | 88 | u32 host_stack; |
88 | u32 host_pid; | 89 | u32 host_pid; |
90 | u32 host_dbcr0; | ||
91 | u32 host_dbcr1; | ||
92 | u32 host_dbcr2; | ||
93 | u32 host_iac[4]; | ||
94 | u32 host_msr; | ||
89 | 95 | ||
90 | u64 fpr[32]; | 96 | u64 fpr[32]; |
91 | u32 gpr[32]; | 97 | u32 gpr[32]; |
@@ -123,7 +129,11 @@ struct kvm_vcpu_arch { | |||
123 | u32 ivor[16]; | 129 | u32 ivor[16]; |
124 | u32 ivpr; | 130 | u32 ivpr; |
125 | u32 pir; | 131 | u32 pir; |
132 | |||
133 | u32 shadow_pid; | ||
126 | u32 pid; | 134 | u32 pid; |
135 | u32 swap_pid; | ||
136 | |||
127 | u32 pvr; | 137 | u32 pvr; |
128 | u32 ccr0; | 138 | u32 ccr0; |
129 | u32 ccr1; | 139 | u32 ccr1; |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index a8b068792260..8931ba729d2b 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -64,6 +64,10 @@ extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, | |||
64 | extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, | 64 | extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, |
65 | gva_t eend, u32 asid); | 65 | gva_t eend, u32 asid); |
66 | extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode); | 66 | extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode); |
67 | extern void kvmppc_mmu_switch_pid(struct kvm_vcpu *vcpu, u32 pid); | ||
68 | |||
69 | /* XXX Book E specific */ | ||
70 | extern void kvmppc_tlbe_set_modified(struct kvm_vcpu *vcpu, unsigned int i); | ||
67 | 71 | ||
68 | extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu); | 72 | extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu); |
69 | 73 | ||
@@ -92,4 +96,12 @@ static inline void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr) | |||
92 | kvm_vcpu_block(vcpu); | 96 | kvm_vcpu_block(vcpu); |
93 | } | 97 | } |
94 | 98 | ||
99 | static inline void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid) | ||
100 | { | ||
101 | if (vcpu->arch.pid != new_pid) { | ||
102 | vcpu->arch.pid = new_pid; | ||
103 | vcpu->arch.swap_pid = 1; | ||
104 | } | ||
105 | } | ||
106 | |||
95 | #endif /* __POWERPC_KVM_PPC_H__ */ | 107 | #endif /* __POWERPC_KVM_PPC_H__ */ |
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 120f4d494257..c0b8d4a29a91 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h | |||
@@ -10,11 +10,13 @@ | |||
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <asm/asm-compat.h> | ||
14 | #include <asm/kdump.h> | ||
15 | #ifndef __ASSEMBLY__ | 13 | #ifndef __ASSEMBLY__ |
16 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #else | ||
16 | #include <asm/types.h> | ||
17 | #endif | 17 | #endif |
18 | #include <asm/asm-compat.h> | ||
19 | #include <asm/kdump.h> | ||
18 | 20 | ||
19 | /* | 21 | /* |
20 | * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software | 22 | * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index ae2ea803a0f2..9047af7baa69 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -74,6 +74,13 @@ struct pci_controller { | |||
74 | unsigned long pci_io_size; | 74 | unsigned long pci_io_size; |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | /* Some machines have a special region to forward the ISA | ||
78 | * "memory" cycles such as VGA memory regions. Left to 0 | ||
79 | * if unsupported | ||
80 | */ | ||
81 | resource_size_t isa_mem_phys; | ||
82 | resource_size_t isa_mem_size; | ||
83 | |||
77 | struct pci_ops *ops; | 84 | struct pci_ops *ops; |
78 | unsigned int __iomem *cfg_addr; | 85 | unsigned int __iomem *cfg_addr; |
79 | void __iomem *cfg_data; | 86 | void __iomem *cfg_data; |
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index 0e52c7828ea4..39d547fde956 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h | |||
@@ -123,6 +123,16 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, | |||
123 | /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ | 123 | /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ |
124 | #define HAVE_PCI_MMAP 1 | 124 | #define HAVE_PCI_MMAP 1 |
125 | 125 | ||
126 | extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, | ||
127 | size_t count); | ||
128 | extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, | ||
129 | size_t count); | ||
130 | extern int pci_mmap_legacy_page_range(struct pci_bus *bus, | ||
131 | struct vm_area_struct *vma, | ||
132 | enum pci_mmap_state mmap_state); | ||
133 | |||
134 | #define HAVE_PCI_LEGACY 1 | ||
135 | |||
126 | #if defined(CONFIG_PPC64) || defined(CONFIG_NOT_COHERENT_CACHE) | 136 | #if defined(CONFIG_PPC64) || defined(CONFIG_NOT_COHERENT_CACHE) |
127 | /* | 137 | /* |
128 | * For 64-bit kernels, pci_unmap_{single,page} is not a nop. | 138 | * For 64-bit kernels, pci_unmap_{single,page} is not a nop. |
@@ -226,5 +236,6 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
226 | extern void pcibios_do_bus_setup(struct pci_bus *bus); | 236 | extern void pcibios_do_bus_setup(struct pci_bus *bus); |
227 | extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus); | 237 | extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus); |
228 | 238 | ||
239 | |||
229 | #endif /* __KERNEL__ */ | 240 | #endif /* __KERNEL__ */ |
230 | #endif /* __ASM_POWERPC_PCI_H */ | 241 | #endif /* __ASM_POWERPC_PCI_H */ |
diff --git a/arch/powerpc/include/asm/ps3av.h b/arch/powerpc/include/asm/ps3av.h index fda98715cd35..5aa22cffdbd6 100644 --- a/arch/powerpc/include/asm/ps3av.h +++ b/arch/powerpc/include/asm/ps3av.h | |||
@@ -678,6 +678,8 @@ struct ps3av_pkt_avb_param { | |||
678 | u8 buf[PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE]; | 678 | u8 buf[PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE]; |
679 | }; | 679 | }; |
680 | 680 | ||
681 | /* channel status */ | ||
682 | extern u8 ps3av_mode_cs_info[]; | ||
681 | 683 | ||
682 | /** command status **/ | 684 | /** command status **/ |
683 | #define PS3AV_STATUS_SUCCESS 0x0000 /* success */ | 685 | #define PS3AV_STATUS_SUCCESS 0x0000 /* success */ |
@@ -735,6 +737,7 @@ extern int ps3av_get_mode(void); | |||
735 | extern int ps3av_video_mode2res(u32, u32 *, u32 *); | 737 | extern int ps3av_video_mode2res(u32, u32 *, u32 *); |
736 | extern int ps3av_video_mute(int); | 738 | extern int ps3av_video_mute(int); |
737 | extern int ps3av_audio_mute(int); | 739 | extern int ps3av_audio_mute(int); |
740 | extern int ps3av_audio_mute_analog(int); | ||
738 | extern int ps3av_dev_open(void); | 741 | extern int ps3av_dev_open(void); |
739 | extern int ps3av_dev_close(void); | 742 | extern int ps3av_dev_close(void); |
740 | extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data), | 743 | extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data), |
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 734e0754fb9b..280a90cc9894 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h | |||
@@ -129,7 +129,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno, | |||
129 | #define CHECK_FULL_REGS(regs) \ | 129 | #define CHECK_FULL_REGS(regs) \ |
130 | do { \ | 130 | do { \ |
131 | if ((regs)->trap & 1) \ | 131 | if ((regs)->trap & 1) \ |
132 | printk(KERN_CRIT "%s: partial register set\n", __FUNCTION__); \ | 132 | printk(KERN_CRIT "%s: partial register set\n", __func__); \ |
133 | } while (0) | 133 | } while (0) |
134 | #endif /* __powerpc64__ */ | 134 | #endif /* __powerpc64__ */ |
135 | 135 | ||
diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h index a9a9262e84a3..c004c13f291e 100644 --- a/arch/powerpc/include/asm/types.h +++ b/arch/powerpc/include/asm/types.h | |||
@@ -48,13 +48,6 @@ typedef struct { | |||
48 | 48 | ||
49 | typedef __vector128 vector128; | 49 | typedef __vector128 vector128; |
50 | 50 | ||
51 | /* Physical address used by some IO functions */ | ||
52 | #if defined(CONFIG_PPC64) || defined(CONFIG_PHYS_64BIT) | ||
53 | typedef u64 phys_addr_t; | ||
54 | #else | ||
55 | typedef u32 phys_addr_t; | ||
56 | #endif | ||
57 | |||
58 | #if defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT) | 51 | #if defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT) |
59 | typedef u64 dma_addr_t; | 52 | typedef u64 dma_addr_t; |
60 | #else | 53 | #else |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 09febc582584..75c5dd0138fd 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -359,8 +359,8 @@ int main(void) | |||
359 | 359 | ||
360 | DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); | 360 | DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); |
361 | DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); | 361 | DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); |
362 | DEFINE(VCPU_HOST_TLB, offsetof(struct kvm_vcpu, arch.host_tlb)); | ||
363 | DEFINE(VCPU_SHADOW_TLB, offsetof(struct kvm_vcpu, arch.shadow_tlb)); | 362 | DEFINE(VCPU_SHADOW_TLB, offsetof(struct kvm_vcpu, arch.shadow_tlb)); |
363 | DEFINE(VCPU_SHADOW_MOD, offsetof(struct kvm_vcpu, arch.shadow_tlb_mod)); | ||
364 | DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr)); | 364 | DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr)); |
365 | DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); | 365 | DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); |
366 | DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr)); | 366 | DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr)); |
@@ -372,7 +372,7 @@ int main(void) | |||
372 | DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5)); | 372 | DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5)); |
373 | DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6)); | 373 | DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6)); |
374 | DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7)); | 374 | DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7)); |
375 | DEFINE(VCPU_PID, offsetof(struct kvm_vcpu, arch.pid)); | 375 | DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid)); |
376 | 376 | ||
377 | DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); | 377 | DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); |
378 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); | 378 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); |
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index a323c9b32ee1..97e056379728 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #define DBG(fmt...) | 27 | #define DBG(fmt...) |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | /* Stores the physical address of elf header of crash image. */ | ||
31 | unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; | ||
32 | |||
30 | void __init reserve_kdump_trampoline(void) | 33 | void __init reserve_kdump_trampoline(void) |
31 | { | 34 | { |
32 | lmb_reserve(0, KDUMP_RESERVE_LIMIT); | 35 | lmb_reserve(0, KDUMP_RESERVE_LIMIT); |
@@ -66,7 +69,11 @@ void __init setup_kdump_trampoline(void) | |||
66 | DBG(" <- setup_kdump_trampoline()\n"); | 69 | DBG(" <- setup_kdump_trampoline()\n"); |
67 | } | 70 | } |
68 | 71 | ||
69 | #ifdef CONFIG_PROC_VMCORE | 72 | /* |
73 | * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by | ||
74 | * is_kdump_kernel() to determine if we are booting after a panic. Hence | ||
75 | * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE. | ||
76 | */ | ||
70 | static int __init parse_elfcorehdr(char *p) | 77 | static int __init parse_elfcorehdr(char *p) |
71 | { | 78 | { |
72 | if (p) | 79 | if (p) |
@@ -75,7 +82,6 @@ static int __init parse_elfcorehdr(char *p) | |||
75 | return 1; | 82 | return 1; |
76 | } | 83 | } |
77 | __setup("elfcorehdr=", parse_elfcorehdr); | 84 | __setup("elfcorehdr=", parse_elfcorehdr); |
78 | #endif | ||
79 | 85 | ||
80 | static int __init parse_savemaxmem(char *p) | 86 | static int __init parse_savemaxmem(char *p) |
81 | { | 87 | { |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 550a19399bfa..ea1ba89f9c90 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -51,17 +51,6 @@ static int protect4gb = 1; | |||
51 | 51 | ||
52 | static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int); | 52 | static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int); |
53 | 53 | ||
54 | static inline unsigned long iommu_num_pages(unsigned long vaddr, | ||
55 | unsigned long slen) | ||
56 | { | ||
57 | unsigned long npages; | ||
58 | |||
59 | npages = IOMMU_PAGE_ALIGN(vaddr + slen) - (vaddr & IOMMU_PAGE_MASK); | ||
60 | npages >>= IOMMU_PAGE_SHIFT; | ||
61 | |||
62 | return npages; | ||
63 | } | ||
64 | |||
65 | static int __init setup_protect4gb(char *str) | 54 | static int __init setup_protect4gb(char *str) |
66 | { | 55 | { |
67 | if (strcmp(str, "on") == 0) | 56 | if (strcmp(str, "on") == 0) |
@@ -325,7 +314,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
325 | } | 314 | } |
326 | /* Allocate iommu entries for that segment */ | 315 | /* Allocate iommu entries for that segment */ |
327 | vaddr = (unsigned long) sg_virt(s); | 316 | vaddr = (unsigned long) sg_virt(s); |
328 | npages = iommu_num_pages(vaddr, slen); | 317 | npages = iommu_num_pages(vaddr, slen, IOMMU_PAGE_SIZE); |
329 | align = 0; | 318 | align = 0; |
330 | if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE && | 319 | if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE && |
331 | (vaddr & ~PAGE_MASK) == 0) | 320 | (vaddr & ~PAGE_MASK) == 0) |
@@ -418,7 +407,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
418 | unsigned long vaddr, npages; | 407 | unsigned long vaddr, npages; |
419 | 408 | ||
420 | vaddr = s->dma_address & IOMMU_PAGE_MASK; | 409 | vaddr = s->dma_address & IOMMU_PAGE_MASK; |
421 | npages = iommu_num_pages(s->dma_address, s->dma_length); | 410 | npages = iommu_num_pages(s->dma_address, s->dma_length, |
411 | IOMMU_PAGE_SIZE); | ||
422 | __iommu_free(tbl, vaddr, npages); | 412 | __iommu_free(tbl, vaddr, npages); |
423 | s->dma_address = DMA_ERROR_CODE; | 413 | s->dma_address = DMA_ERROR_CODE; |
424 | s->dma_length = 0; | 414 | s->dma_length = 0; |
@@ -452,7 +442,8 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
452 | 442 | ||
453 | if (sg->dma_length == 0) | 443 | if (sg->dma_length == 0) |
454 | break; | 444 | break; |
455 | npages = iommu_num_pages(dma_handle, sg->dma_length); | 445 | npages = iommu_num_pages(dma_handle, sg->dma_length, |
446 | IOMMU_PAGE_SIZE); | ||
456 | __iommu_free(tbl, dma_handle, npages); | 447 | __iommu_free(tbl, dma_handle, npages); |
457 | sg = sg_next(sg); | 448 | sg = sg_next(sg); |
458 | } | 449 | } |
@@ -584,7 +575,7 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl, | |||
584 | BUG_ON(direction == DMA_NONE); | 575 | BUG_ON(direction == DMA_NONE); |
585 | 576 | ||
586 | uaddr = (unsigned long)vaddr; | 577 | uaddr = (unsigned long)vaddr; |
587 | npages = iommu_num_pages(uaddr, size); | 578 | npages = iommu_num_pages(uaddr, size, IOMMU_PAGE_SIZE); |
588 | 579 | ||
589 | if (tbl) { | 580 | if (tbl) { |
590 | align = 0; | 581 | align = 0; |
@@ -617,7 +608,7 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, | |||
617 | BUG_ON(direction == DMA_NONE); | 608 | BUG_ON(direction == DMA_NONE); |
618 | 609 | ||
619 | if (tbl) { | 610 | if (tbl) { |
620 | npages = iommu_num_pages(dma_handle, size); | 611 | npages = iommu_num_pages(dma_handle, size, IOMMU_PAGE_SIZE); |
621 | iommu_free(tbl, dma_handle, npages); | 612 | iommu_free(tbl, dma_handle, npages); |
622 | } | 613 | } |
623 | } | 614 | } |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 01ce8c38bae6..3815d84a1ef4 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -451,7 +451,8 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
451 | pci_dev_put(pdev); | 451 | pci_dev_put(pdev); |
452 | } | 452 | } |
453 | 453 | ||
454 | DBG("non-PCI map for %lx, prot: %lx\n", offset, prot); | 454 | DBG("non-PCI map for %llx, prot: %lx\n", |
455 | (unsigned long long)offset, prot); | ||
455 | 456 | ||
456 | return __pgprot(prot); | 457 | return __pgprot(prot); |
457 | } | 458 | } |
@@ -490,6 +491,131 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
490 | return ret; | 491 | return ret; |
491 | } | 492 | } |
492 | 493 | ||
494 | /* This provides legacy IO read access on a bus */ | ||
495 | int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size) | ||
496 | { | ||
497 | unsigned long offset; | ||
498 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
499 | struct resource *rp = &hose->io_resource; | ||
500 | void __iomem *addr; | ||
501 | |||
502 | /* Check if port can be supported by that bus. We only check | ||
503 | * the ranges of the PHB though, not the bus itself as the rules | ||
504 | * for forwarding legacy cycles down bridges are not our problem | ||
505 | * here. So if the host bridge supports it, we do it. | ||
506 | */ | ||
507 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
508 | offset += port; | ||
509 | |||
510 | if (!(rp->flags & IORESOURCE_IO)) | ||
511 | return -ENXIO; | ||
512 | if (offset < rp->start || (offset + size) > rp->end) | ||
513 | return -ENXIO; | ||
514 | addr = hose->io_base_virt + port; | ||
515 | |||
516 | switch(size) { | ||
517 | case 1: | ||
518 | *((u8 *)val) = in_8(addr); | ||
519 | return 1; | ||
520 | case 2: | ||
521 | if (port & 1) | ||
522 | return -EINVAL; | ||
523 | *((u16 *)val) = in_le16(addr); | ||
524 | return 2; | ||
525 | case 4: | ||
526 | if (port & 3) | ||
527 | return -EINVAL; | ||
528 | *((u32 *)val) = in_le32(addr); | ||
529 | return 4; | ||
530 | } | ||
531 | return -EINVAL; | ||
532 | } | ||
533 | |||
534 | /* This provides legacy IO write access on a bus */ | ||
535 | int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size) | ||
536 | { | ||
537 | unsigned long offset; | ||
538 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
539 | struct resource *rp = &hose->io_resource; | ||
540 | void __iomem *addr; | ||
541 | |||
542 | /* Check if port can be supported by that bus. We only check | ||
543 | * the ranges of the PHB though, not the bus itself as the rules | ||
544 | * for forwarding legacy cycles down bridges are not our problem | ||
545 | * here. So if the host bridge supports it, we do it. | ||
546 | */ | ||
547 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
548 | offset += port; | ||
549 | |||
550 | if (!(rp->flags & IORESOURCE_IO)) | ||
551 | return -ENXIO; | ||
552 | if (offset < rp->start || (offset + size) > rp->end) | ||
553 | return -ENXIO; | ||
554 | addr = hose->io_base_virt + port; | ||
555 | |||
556 | /* WARNING: The generic code is idiotic. It gets passed a pointer | ||
557 | * to what can be a 1, 2 or 4 byte quantity and always reads that | ||
558 | * as a u32, which means that we have to correct the location of | ||
559 | * the data read within those 32 bits for size 1 and 2 | ||
560 | */ | ||
561 | switch(size) { | ||
562 | case 1: | ||
563 | out_8(addr, val >> 24); | ||
564 | return 1; | ||
565 | case 2: | ||
566 | if (port & 1) | ||
567 | return -EINVAL; | ||
568 | out_le16(addr, val >> 16); | ||
569 | return 2; | ||
570 | case 4: | ||
571 | if (port & 3) | ||
572 | return -EINVAL; | ||
573 | out_le32(addr, val); | ||
574 | return 4; | ||
575 | } | ||
576 | return -EINVAL; | ||
577 | } | ||
578 | |||
579 | /* This provides legacy IO or memory mmap access on a bus */ | ||
580 | int pci_mmap_legacy_page_range(struct pci_bus *bus, | ||
581 | struct vm_area_struct *vma, | ||
582 | enum pci_mmap_state mmap_state) | ||
583 | { | ||
584 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
585 | resource_size_t offset = | ||
586 | ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT; | ||
587 | resource_size_t size = vma->vm_end - vma->vm_start; | ||
588 | struct resource *rp; | ||
589 | |||
590 | pr_debug("pci_mmap_legacy_page_range(%04x:%02x, %s @%llx..%llx)\n", | ||
591 | pci_domain_nr(bus), bus->number, | ||
592 | mmap_state == pci_mmap_mem ? "MEM" : "IO", | ||
593 | (unsigned long long)offset, | ||
594 | (unsigned long long)(offset + size - 1)); | ||
595 | |||
596 | if (mmap_state == pci_mmap_mem) { | ||
597 | if ((offset + size) > hose->isa_mem_size) | ||
598 | return -ENXIO; | ||
599 | offset += hose->isa_mem_phys; | ||
600 | } else { | ||
601 | unsigned long io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
602 | unsigned long roffset = offset + io_offset; | ||
603 | rp = &hose->io_resource; | ||
604 | if (!(rp->flags & IORESOURCE_IO)) | ||
605 | return -ENXIO; | ||
606 | if (roffset < rp->start || (roffset + size) > rp->end) | ||
607 | return -ENXIO; | ||
608 | offset += hose->io_base_phys; | ||
609 | } | ||
610 | pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset); | ||
611 | |||
612 | vma->vm_pgoff = offset >> PAGE_SHIFT; | ||
613 | vma->vm_page_prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | ||
614 | return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | ||
615 | vma->vm_end - vma->vm_start, | ||
616 | vma->vm_page_prot); | ||
617 | } | ||
618 | |||
493 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | 619 | void pci_resource_to_user(const struct pci_dev *dev, int bar, |
494 | const struct resource *rsrc, | 620 | const struct resource *rsrc, |
495 | resource_size_t *start, resource_size_t *end) | 621 | resource_size_t *start, resource_size_t *end) |
@@ -592,6 +718,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
592 | cpu_addr = of_translate_address(dev, ranges + 3); | 718 | cpu_addr = of_translate_address(dev, ranges + 3); |
593 | size = of_read_number(ranges + pna + 3, 2); | 719 | size = of_read_number(ranges + pna + 3, 2); |
594 | ranges += np; | 720 | ranges += np; |
721 | |||
722 | /* If we failed translation or got a zero-sized region | ||
723 | * (some FW try to feed us with non sensical zero sized regions | ||
724 | * such as power3 which look like some kind of attempt at exposing | ||
725 | * the VGA memory hole) | ||
726 | */ | ||
595 | if (cpu_addr == OF_BAD_ADDR || size == 0) | 727 | if (cpu_addr == OF_BAD_ADDR || size == 0) |
596 | continue; | 728 | continue; |
597 | 729 | ||
@@ -665,6 +797,8 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
665 | isa_hole = memno; | 797 | isa_hole = memno; |
666 | if (primary || isa_mem_base == 0) | 798 | if (primary || isa_mem_base == 0) |
667 | isa_mem_base = cpu_addr; | 799 | isa_mem_base = cpu_addr; |
800 | hose->isa_mem_phys = cpu_addr; | ||
801 | hose->isa_mem_size = size; | ||
668 | } | 802 | } |
669 | 803 | ||
670 | /* We get the PCI/Mem offset from the first range or | 804 | /* We get the PCI/Mem offset from the first range or |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index ff7de7b0797e..bb1cfcfdbbbb 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -61,42 +61,6 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, | |||
61 | return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x)); | 61 | return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x)); |
62 | } | 62 | } |
63 | 63 | ||
64 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | ||
65 | { | ||
66 | compat_ino_t ino; | ||
67 | long err; | ||
68 | |||
69 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || | ||
70 | !new_valid_dev(stat->rdev)) | ||
71 | return -EOVERFLOW; | ||
72 | |||
73 | ino = stat->ino; | ||
74 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
75 | return -EOVERFLOW; | ||
76 | |||
77 | err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; | ||
78 | err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); | ||
79 | err |= __put_user(ino, &statbuf->st_ino); | ||
80 | err |= __put_user(stat->mode, &statbuf->st_mode); | ||
81 | err |= __put_user(stat->nlink, &statbuf->st_nlink); | ||
82 | err |= __put_user(stat->uid, &statbuf->st_uid); | ||
83 | err |= __put_user(stat->gid, &statbuf->st_gid); | ||
84 | err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev); | ||
85 | err |= __put_user(stat->size, &statbuf->st_size); | ||
86 | err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime); | ||
87 | err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec); | ||
88 | err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime); | ||
89 | err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec); | ||
90 | err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime); | ||
91 | err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec); | ||
92 | err |= __put_user(stat->blksize, &statbuf->st_blksize); | ||
93 | err |= __put_user(stat->blocks, &statbuf->st_blocks); | ||
94 | err |= __put_user(0, &statbuf->__unused4[0]); | ||
95 | err |= __put_user(0, &statbuf->__unused4[1]); | ||
96 | |||
97 | return err; | ||
98 | } | ||
99 | |||
100 | /* Note: it is necessary to treat option as an unsigned int, | 64 | /* Note: it is necessary to treat option as an unsigned int, |
101 | * with the corresponding cast to a signed int to insure that the | 65 | * with the corresponding cast to a signed int to insure that the |
102 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | 66 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) |
@@ -107,69 +71,6 @@ asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2) | |||
107 | return sys_sysfs((int)option, arg1, arg2); | 71 | return sys_sysfs((int)option, arg1, arg2); |
108 | } | 72 | } |
109 | 73 | ||
110 | static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) | ||
111 | { | ||
112 | long usec; | ||
113 | |||
114 | if (!access_ok(VERIFY_READ, i, sizeof(*i))) | ||
115 | return -EFAULT; | ||
116 | if (__get_user(o->tv_sec, &i->tv_sec)) | ||
117 | return -EFAULT; | ||
118 | if (__get_user(usec, &i->tv_usec)) | ||
119 | return -EFAULT; | ||
120 | o->tv_nsec = usec * 1000; | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) | ||
125 | { | ||
126 | return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || | ||
127 | (__put_user(i->tv_sec, &o->tv_sec) | | ||
128 | __put_user(i->tv_usec, &o->tv_usec))); | ||
129 | } | ||
130 | |||
131 | |||
132 | |||
133 | |||
134 | /* Translations due to time_t size differences. Which affects all | ||
135 | sorts of things, like timeval and itimerval. */ | ||
136 | extern struct timezone sys_tz; | ||
137 | |||
138 | asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) | ||
139 | { | ||
140 | if (tv) { | ||
141 | struct timeval ktv; | ||
142 | do_gettimeofday(&ktv); | ||
143 | if (put_tv32(tv, &ktv)) | ||
144 | return -EFAULT; | ||
145 | } | ||
146 | if (tz) { | ||
147 | if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) | ||
148 | return -EFAULT; | ||
149 | } | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | |||
155 | |||
156 | asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) | ||
157 | { | ||
158 | struct timespec kts; | ||
159 | struct timezone ktz; | ||
160 | |||
161 | if (tv) { | ||
162 | if (get_ts32(&kts, tv)) | ||
163 | return -EFAULT; | ||
164 | } | ||
165 | if (tz) { | ||
166 | if (copy_from_user(&ktz, tz, sizeof(ktz))) | ||
167 | return -EFAULT; | ||
168 | } | ||
169 | |||
170 | return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); | ||
171 | } | ||
172 | |||
173 | #ifdef CONFIG_SYSVIPC | 74 | #ifdef CONFIG_SYSVIPC |
174 | long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, | 75 | long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, |
175 | u32 fifth) | 76 | u32 fifth) |
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index 5a5602da5091..2e227a412bc2 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/kvm.h> | ||
22 | #include <linux/kvm_host.h> | 23 | #include <linux/kvm_host.h> |
23 | #include <linux/highmem.h> | 24 | #include <linux/highmem.h> |
24 | #include <asm/mmu-44x.h> | 25 | #include <asm/mmu-44x.h> |
@@ -109,7 +110,6 @@ static int kvmppc_44x_tlbe_is_writable(struct tlbe *tlbe) | |||
109 | return tlbe->word2 & (PPC44x_TLB_SW|PPC44x_TLB_UW); | 110 | return tlbe->word2 & (PPC44x_TLB_SW|PPC44x_TLB_UW); |
110 | } | 111 | } |
111 | 112 | ||
112 | /* Must be called with mmap_sem locked for writing. */ | ||
113 | static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu, | 113 | static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu, |
114 | unsigned int index) | 114 | unsigned int index) |
115 | { | 115 | { |
@@ -124,6 +124,11 @@ static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu, | |||
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
127 | void kvmppc_tlbe_set_modified(struct kvm_vcpu *vcpu, unsigned int i) | ||
128 | { | ||
129 | vcpu->arch.shadow_tlb_mod[i] = 1; | ||
130 | } | ||
131 | |||
127 | /* Caller must ensure that the specified guest TLB entry is safe to insert into | 132 | /* Caller must ensure that the specified guest TLB entry is safe to insert into |
128 | * the shadow TLB. */ | 133 | * the shadow TLB. */ |
129 | void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, | 134 | void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, |
@@ -142,19 +147,16 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, | |||
142 | stlbe = &vcpu->arch.shadow_tlb[victim]; | 147 | stlbe = &vcpu->arch.shadow_tlb[victim]; |
143 | 148 | ||
144 | /* Get reference to new page. */ | 149 | /* Get reference to new page. */ |
145 | down_read(¤t->mm->mmap_sem); | ||
146 | new_page = gfn_to_page(vcpu->kvm, gfn); | 150 | new_page = gfn_to_page(vcpu->kvm, gfn); |
147 | if (is_error_page(new_page)) { | 151 | if (is_error_page(new_page)) { |
148 | printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n", gfn); | 152 | printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n", gfn); |
149 | kvm_release_page_clean(new_page); | 153 | kvm_release_page_clean(new_page); |
150 | up_read(¤t->mm->mmap_sem); | ||
151 | return; | 154 | return; |
152 | } | 155 | } |
153 | hpaddr = page_to_phys(new_page); | 156 | hpaddr = page_to_phys(new_page); |
154 | 157 | ||
155 | /* Drop reference to old page. */ | 158 | /* Drop reference to old page. */ |
156 | kvmppc_44x_shadow_release(vcpu, victim); | 159 | kvmppc_44x_shadow_release(vcpu, victim); |
157 | up_read(¤t->mm->mmap_sem); | ||
158 | 160 | ||
159 | vcpu->arch.shadow_pages[victim] = new_page; | 161 | vcpu->arch.shadow_pages[victim] = new_page; |
160 | 162 | ||
@@ -164,27 +166,30 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, | |||
164 | 166 | ||
165 | /* XXX what about AS? */ | 167 | /* XXX what about AS? */ |
166 | 168 | ||
167 | stlbe->tid = asid & 0xff; | 169 | stlbe->tid = !(asid & 0xff); |
168 | 170 | ||
169 | /* Force TS=1 for all guest mappings. */ | 171 | /* Force TS=1 for all guest mappings. */ |
170 | /* For now we hardcode 4KB mappings, but it will be important to | 172 | /* For now we hardcode 4KB mappings, but it will be important to |
171 | * use host large pages in the future. */ | 173 | * use host large pages in the future. */ |
172 | stlbe->word0 = (gvaddr & PAGE_MASK) | PPC44x_TLB_VALID | PPC44x_TLB_TS | 174 | stlbe->word0 = (gvaddr & PAGE_MASK) | PPC44x_TLB_VALID | PPC44x_TLB_TS |
173 | | PPC44x_TLB_4K; | 175 | | PPC44x_TLB_4K; |
174 | |||
175 | stlbe->word1 = (hpaddr & 0xfffffc00) | ((hpaddr >> 32) & 0xf); | 176 | stlbe->word1 = (hpaddr & 0xfffffc00) | ((hpaddr >> 32) & 0xf); |
176 | stlbe->word2 = kvmppc_44x_tlb_shadow_attrib(flags, | 177 | stlbe->word2 = kvmppc_44x_tlb_shadow_attrib(flags, |
177 | vcpu->arch.msr & MSR_PR); | 178 | vcpu->arch.msr & MSR_PR); |
179 | kvmppc_tlbe_set_modified(vcpu, victim); | ||
180 | |||
181 | KVMTRACE_5D(STLB_WRITE, vcpu, victim, | ||
182 | stlbe->tid, stlbe->word0, stlbe->word1, stlbe->word2, | ||
183 | handler); | ||
178 | } | 184 | } |
179 | 185 | ||
180 | void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, | 186 | void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, |
181 | gva_t eend, u32 asid) | 187 | gva_t eend, u32 asid) |
182 | { | 188 | { |
183 | unsigned int pid = asid & 0xff; | 189 | unsigned int pid = !(asid & 0xff); |
184 | int i; | 190 | int i; |
185 | 191 | ||
186 | /* XXX Replace loop with fancy data structures. */ | 192 | /* XXX Replace loop with fancy data structures. */ |
187 | down_write(¤t->mm->mmap_sem); | ||
188 | for (i = 0; i <= tlb_44x_hwater; i++) { | 193 | for (i = 0; i <= tlb_44x_hwater; i++) { |
189 | struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i]; | 194 | struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i]; |
190 | unsigned int tid; | 195 | unsigned int tid; |
@@ -204,21 +209,35 @@ void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
204 | 209 | ||
205 | kvmppc_44x_shadow_release(vcpu, i); | 210 | kvmppc_44x_shadow_release(vcpu, i); |
206 | stlbe->word0 = 0; | 211 | stlbe->word0 = 0; |
212 | kvmppc_tlbe_set_modified(vcpu, i); | ||
213 | KVMTRACE_5D(STLB_INVAL, vcpu, i, | ||
214 | stlbe->tid, stlbe->word0, stlbe->word1, | ||
215 | stlbe->word2, handler); | ||
207 | } | 216 | } |
208 | up_write(¤t->mm->mmap_sem); | ||
209 | } | 217 | } |
210 | 218 | ||
211 | /* Invalidate all mappings, so that when they fault back in they will get the | 219 | /* Invalidate all mappings on the privilege switch after PID has been changed. |
212 | * proper permission bits. */ | 220 | * The guest always runs with PID=1, so we must clear the entire TLB when |
221 | * switching address spaces. */ | ||
213 | void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode) | 222 | void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode) |
214 | { | 223 | { |
215 | int i; | 224 | int i; |
216 | 225 | ||
217 | /* XXX Replace loop with fancy data structures. */ | 226 | if (vcpu->arch.swap_pid) { |
218 | down_write(¤t->mm->mmap_sem); | 227 | /* XXX Replace loop with fancy data structures. */ |
219 | for (i = 0; i <= tlb_44x_hwater; i++) { | 228 | for (i = 0; i <= tlb_44x_hwater; i++) { |
220 | kvmppc_44x_shadow_release(vcpu, i); | 229 | struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i]; |
221 | vcpu->arch.shadow_tlb[i].word0 = 0; | 230 | |
231 | /* Future optimization: clear only userspace mappings. */ | ||
232 | kvmppc_44x_shadow_release(vcpu, i); | ||
233 | stlbe->word0 = 0; | ||
234 | kvmppc_tlbe_set_modified(vcpu, i); | ||
235 | KVMTRACE_5D(STLB_INVAL, vcpu, i, | ||
236 | stlbe->tid, stlbe->word0, stlbe->word1, | ||
237 | stlbe->word2, handler); | ||
238 | } | ||
239 | vcpu->arch.swap_pid = 0; | ||
222 | } | 240 | } |
223 | up_write(¤t->mm->mmap_sem); | 241 | |
242 | vcpu->arch.shadow_pid = !usermode; | ||
224 | } | 243 | } |
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 6b076010213b..53aaa66b25e5 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig | |||
@@ -37,6 +37,17 @@ config KVM_BOOKE_HOST | |||
37 | Provides host support for KVM on Book E PowerPC processors. Currently | 37 | Provides host support for KVM on Book E PowerPC processors. Currently |
38 | this works on 440 processors only. | 38 | this works on 440 processors only. |
39 | 39 | ||
40 | config KVM_TRACE | ||
41 | bool "KVM trace support" | ||
42 | depends on KVM && MARKERS && SYSFS | ||
43 | select RELAY | ||
44 | select DEBUG_FS | ||
45 | default n | ||
46 | ---help--- | ||
47 | This option allows reading a trace of kvm-related events through | ||
48 | relayfs. Note the ABI is not considered stable and will be | ||
49 | modified in future updates. | ||
50 | |||
40 | source drivers/virtio/Kconfig | 51 | source drivers/virtio/Kconfig |
41 | 52 | ||
42 | endif # VIRTUALIZATION | 53 | endif # VIRTUALIZATION |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 04e3449e1f42..2a5d4397ac4b 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
@@ -4,9 +4,11 @@ | |||
4 | 4 | ||
5 | EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm | 5 | EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm |
6 | 6 | ||
7 | common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) | 7 | common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) |
8 | 8 | ||
9 | kvm-objs := $(common-objs) powerpc.o emulate.o booke_guest.o | 9 | common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o) |
10 | |||
11 | kvm-objs := $(common-objs-y) powerpc.o emulate.o booke_guest.o | ||
10 | obj-$(CONFIG_KVM) += kvm.o | 12 | obj-$(CONFIG_KVM) += kvm.o |
11 | 13 | ||
12 | AFLAGS_booke_interrupts.o := -I$(obj) | 14 | AFLAGS_booke_interrupts.o := -I$(obj) |
diff --git a/arch/powerpc/kvm/booke_guest.c b/arch/powerpc/kvm/booke_guest.c index 9c8ad850c6e3..7b2591e26bae 100644 --- a/arch/powerpc/kvm/booke_guest.c +++ b/arch/powerpc/kvm/booke_guest.c | |||
@@ -410,6 +410,21 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
410 | break; | 410 | break; |
411 | } | 411 | } |
412 | 412 | ||
413 | case BOOKE_INTERRUPT_DEBUG: { | ||
414 | u32 dbsr; | ||
415 | |||
416 | vcpu->arch.pc = mfspr(SPRN_CSRR0); | ||
417 | |||
418 | /* clear IAC events in DBSR register */ | ||
419 | dbsr = mfspr(SPRN_DBSR); | ||
420 | dbsr &= DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4; | ||
421 | mtspr(SPRN_DBSR, dbsr); | ||
422 | |||
423 | run->exit_reason = KVM_EXIT_DEBUG; | ||
424 | r = RESUME_HOST; | ||
425 | break; | ||
426 | } | ||
427 | |||
413 | default: | 428 | default: |
414 | printk(KERN_EMERG "exit_nr %d\n", exit_nr); | 429 | printk(KERN_EMERG "exit_nr %d\n", exit_nr); |
415 | BUG(); | 430 | BUG(); |
@@ -471,6 +486,8 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
471 | vcpu->arch.msr = 0; | 486 | vcpu->arch.msr = 0; |
472 | vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */ | 487 | vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */ |
473 | 488 | ||
489 | vcpu->arch.shadow_pid = 1; | ||
490 | |||
474 | /* Eye-catching number so we know if the guest takes an interrupt | 491 | /* Eye-catching number so we know if the guest takes an interrupt |
475 | * before it's programmed its own IVPR. */ | 492 | * before it's programmed its own IVPR. */ |
476 | vcpu->arch.ivpr = 0x55550000; | 493 | vcpu->arch.ivpr = 0x55550000; |
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 3b653b5309b8..95e165baf85f 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S | |||
@@ -42,7 +42,8 @@ | |||
42 | #define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */ | 42 | #define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */ |
43 | 43 | ||
44 | #define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \ | 44 | #define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \ |
45 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) | 45 | (1<<BOOKE_INTERRUPT_DTLB_MISS) | \ |
46 | (1<<BOOKE_INTERRUPT_DEBUG)) | ||
46 | 47 | ||
47 | #define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ | 48 | #define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ |
48 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) | 49 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) |
@@ -331,51 +332,57 @@ lightweight_exit: | |||
331 | 332 | ||
332 | mfspr r3, SPRN_PID | 333 | mfspr r3, SPRN_PID |
333 | stw r3, VCPU_HOST_PID(r4) | 334 | stw r3, VCPU_HOST_PID(r4) |
334 | lwz r3, VCPU_PID(r4) | 335 | lwz r3, VCPU_SHADOW_PID(r4) |
335 | mtspr SPRN_PID, r3 | 336 | mtspr SPRN_PID, r3 |
336 | 337 | ||
337 | /* Prevent all TLB updates. */ | 338 | /* Prevent all asynchronous TLB updates. */ |
338 | mfmsr r5 | 339 | mfmsr r5 |
339 | lis r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@h | 340 | lis r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@h |
340 | ori r6, r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l | 341 | ori r6, r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l |
341 | andc r6, r5, r6 | 342 | andc r6, r5, r6 |
342 | mtmsr r6 | 343 | mtmsr r6 |
343 | 344 | ||
344 | /* Save the host's non-pinned TLB mappings, and load the guest mappings | 345 | /* Load the guest mappings, leaving the host's "pinned" kernel mappings |
345 | * over them. Leave the host's "pinned" kernel mappings in place. */ | 346 | * in place. */ |
346 | /* XXX optimization: use generation count to avoid swapping unmodified | ||
347 | * entries. */ | ||
348 | mfspr r10, SPRN_MMUCR /* Save host MMUCR. */ | 347 | mfspr r10, SPRN_MMUCR /* Save host MMUCR. */ |
349 | lis r8, tlb_44x_hwater@ha | 348 | li r5, PPC44x_TLB_SIZE |
350 | lwz r8, tlb_44x_hwater@l(r8) | 349 | lis r5, tlb_44x_hwater@ha |
351 | addi r3, r4, VCPU_HOST_TLB - 4 | 350 | lwz r5, tlb_44x_hwater@l(r5) |
352 | addi r9, r4, VCPU_SHADOW_TLB - 4 | 351 | mtctr r5 |
353 | li r6, 0 | 352 | addi r9, r4, VCPU_SHADOW_TLB |
353 | addi r5, r4, VCPU_SHADOW_MOD | ||
354 | li r3, 0 | ||
354 | 1: | 355 | 1: |
355 | /* Save host entry. */ | 356 | lbzx r7, r3, r5 |
356 | tlbre r7, r6, PPC44x_TLB_PAGEID | 357 | cmpwi r7, 0 |
357 | mfspr r5, SPRN_MMUCR | 358 | beq 3f |
358 | stwu r5, 4(r3) | 359 | |
359 | stwu r7, 4(r3) | ||
360 | tlbre r7, r6, PPC44x_TLB_XLAT | ||
361 | stwu r7, 4(r3) | ||
362 | tlbre r7, r6, PPC44x_TLB_ATTRIB | ||
363 | stwu r7, 4(r3) | ||
364 | /* Load guest entry. */ | 360 | /* Load guest entry. */ |
365 | lwzu r7, 4(r9) | 361 | mulli r11, r3, TLBE_BYTES |
362 | add r11, r11, r9 | ||
363 | lwz r7, 0(r11) | ||
366 | mtspr SPRN_MMUCR, r7 | 364 | mtspr SPRN_MMUCR, r7 |
367 | lwzu r7, 4(r9) | 365 | lwz r7, 4(r11) |
368 | tlbwe r7, r6, PPC44x_TLB_PAGEID | 366 | tlbwe r7, r3, PPC44x_TLB_PAGEID |
369 | lwzu r7, 4(r9) | 367 | lwz r7, 8(r11) |
370 | tlbwe r7, r6, PPC44x_TLB_XLAT | 368 | tlbwe r7, r3, PPC44x_TLB_XLAT |
371 | lwzu r7, 4(r9) | 369 | lwz r7, 12(r11) |
372 | tlbwe r7, r6, PPC44x_TLB_ATTRIB | 370 | tlbwe r7, r3, PPC44x_TLB_ATTRIB |
373 | /* Increment index. */ | 371 | 3: |
374 | addi r6, r6, 1 | 372 | addi r3, r3, 1 /* Increment index. */ |
375 | cmpw r6, r8 | 373 | bdnz 1b |
376 | blt 1b | 374 | |
377 | mtspr SPRN_MMUCR, r10 /* Restore host MMUCR. */ | 375 | mtspr SPRN_MMUCR, r10 /* Restore host MMUCR. */ |
378 | 376 | ||
377 | /* Clear bitmap of modified TLB entries */ | ||
378 | li r5, PPC44x_TLB_SIZE>>2 | ||
379 | mtctr r5 | ||
380 | addi r5, r4, VCPU_SHADOW_MOD - 4 | ||
381 | li r6, 0 | ||
382 | 1: | ||
383 | stwu r6, 4(r5) | ||
384 | bdnz 1b | ||
385 | |||
379 | iccci 0, 0 /* XXX hack */ | 386 | iccci 0, 0 /* XXX hack */ |
380 | 387 | ||
381 | /* Load some guest volatiles. */ | 388 | /* Load some guest volatiles. */ |
@@ -431,6 +438,14 @@ lightweight_exit: | |||
431 | oris r3, r3, KVMPPC_MSR_MASK@h | 438 | oris r3, r3, KVMPPC_MSR_MASK@h |
432 | ori r3, r3, KVMPPC_MSR_MASK@l | 439 | ori r3, r3, KVMPPC_MSR_MASK@l |
433 | mtsrr1 r3 | 440 | mtsrr1 r3 |
441 | |||
442 | /* Clear any debug events which occurred since we disabled MSR[DE]. | ||
443 | * XXX This gives us a 3-instruction window in which a breakpoint | ||
444 | * intended for guest context could fire in the host instead. */ | ||
445 | lis r3, 0xffff | ||
446 | ori r3, r3, 0xffff | ||
447 | mtspr SPRN_DBSR, r3 | ||
448 | |||
434 | lwz r3, VCPU_GPR(r3)(r4) | 449 | lwz r3, VCPU_GPR(r3)(r4) |
435 | lwz r4, VCPU_GPR(r4)(r4) | 450 | lwz r4, VCPU_GPR(r4)(r4) |
436 | rfi | 451 | rfi |
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 8c605d0a5488..0fce4fbdc20d 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
@@ -170,6 +170,10 @@ static int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u32 inst) | |||
170 | kvmppc_mmu_map(vcpu, eaddr, raddr >> PAGE_SHIFT, asid, flags); | 170 | kvmppc_mmu_map(vcpu, eaddr, raddr >> PAGE_SHIFT, asid, flags); |
171 | } | 171 | } |
172 | 172 | ||
173 | KVMTRACE_5D(GTLB_WRITE, vcpu, index, | ||
174 | tlbe->tid, tlbe->word0, tlbe->word1, tlbe->word2, | ||
175 | handler); | ||
176 | |||
173 | return EMULATE_DONE; | 177 | return EMULATE_DONE; |
174 | } | 178 | } |
175 | 179 | ||
@@ -504,7 +508,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
504 | case SPRN_MMUCR: | 508 | case SPRN_MMUCR: |
505 | vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break; | 509 | vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break; |
506 | case SPRN_PID: | 510 | case SPRN_PID: |
507 | vcpu->arch.pid = vcpu->arch.gpr[rs]; break; | 511 | kvmppc_set_pid(vcpu, vcpu->arch.gpr[rs]); break; |
508 | case SPRN_CCR0: | 512 | case SPRN_CCR0: |
509 | vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break; | 513 | vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break; |
510 | case SPRN_CCR1: | 514 | case SPRN_CCR1: |
@@ -765,6 +769,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
765 | break; | 769 | break; |
766 | } | 770 | } |
767 | 771 | ||
772 | KVMTRACE_3D(PPC_INSTR, vcpu, inst, vcpu->arch.pc, emulated, entryexit); | ||
773 | |||
768 | if (advance) | 774 | if (advance) |
769 | vcpu->arch.pc += 4; /* Advance past emulated instruction. */ | 775 | vcpu->arch.pc += 4; /* Advance past emulated instruction. */ |
770 | 776 | ||
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 53826a5f6c06..90a6fc422b23 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/cputable.h> | 27 | #include <asm/cputable.h> |
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/kvm_ppc.h> | 29 | #include <asm/kvm_ppc.h> |
30 | #include <asm/tlbflush.h> | ||
30 | 31 | ||
31 | 32 | ||
32 | gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) | 33 | gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) |
@@ -239,18 +240,114 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | |||
239 | { | 240 | { |
240 | } | 241 | } |
241 | 242 | ||
243 | /* Note: clearing MSR[DE] just means that the debug interrupt will not be | ||
244 | * delivered *immediately*. Instead, it simply sets the appropriate DBSR bits. | ||
245 | * If those DBSR bits are still set when MSR[DE] is re-enabled, the interrupt | ||
246 | * will be delivered as an "imprecise debug event" (which is indicated by | ||
247 | * DBSR[IDE]. | ||
248 | */ | ||
249 | static void kvmppc_disable_debug_interrupts(void) | ||
250 | { | ||
251 | mtmsr(mfmsr() & ~MSR_DE); | ||
252 | } | ||
253 | |||
254 | static void kvmppc_restore_host_debug_state(struct kvm_vcpu *vcpu) | ||
255 | { | ||
256 | kvmppc_disable_debug_interrupts(); | ||
257 | |||
258 | mtspr(SPRN_IAC1, vcpu->arch.host_iac[0]); | ||
259 | mtspr(SPRN_IAC2, vcpu->arch.host_iac[1]); | ||
260 | mtspr(SPRN_IAC3, vcpu->arch.host_iac[2]); | ||
261 | mtspr(SPRN_IAC4, vcpu->arch.host_iac[3]); | ||
262 | mtspr(SPRN_DBCR1, vcpu->arch.host_dbcr1); | ||
263 | mtspr(SPRN_DBCR2, vcpu->arch.host_dbcr2); | ||
264 | mtspr(SPRN_DBCR0, vcpu->arch.host_dbcr0); | ||
265 | mtmsr(vcpu->arch.host_msr); | ||
266 | } | ||
267 | |||
268 | static void kvmppc_load_guest_debug_registers(struct kvm_vcpu *vcpu) | ||
269 | { | ||
270 | struct kvm_guest_debug *dbg = &vcpu->guest_debug; | ||
271 | u32 dbcr0 = 0; | ||
272 | |||
273 | vcpu->arch.host_msr = mfmsr(); | ||
274 | kvmppc_disable_debug_interrupts(); | ||
275 | |||
276 | /* Save host debug register state. */ | ||
277 | vcpu->arch.host_iac[0] = mfspr(SPRN_IAC1); | ||
278 | vcpu->arch.host_iac[1] = mfspr(SPRN_IAC2); | ||
279 | vcpu->arch.host_iac[2] = mfspr(SPRN_IAC3); | ||
280 | vcpu->arch.host_iac[3] = mfspr(SPRN_IAC4); | ||
281 | vcpu->arch.host_dbcr0 = mfspr(SPRN_DBCR0); | ||
282 | vcpu->arch.host_dbcr1 = mfspr(SPRN_DBCR1); | ||
283 | vcpu->arch.host_dbcr2 = mfspr(SPRN_DBCR2); | ||
284 | |||
285 | /* set registers up for guest */ | ||
286 | |||
287 | if (dbg->bp[0]) { | ||
288 | mtspr(SPRN_IAC1, dbg->bp[0]); | ||
289 | dbcr0 |= DBCR0_IAC1 | DBCR0_IDM; | ||
290 | } | ||
291 | if (dbg->bp[1]) { | ||
292 | mtspr(SPRN_IAC2, dbg->bp[1]); | ||
293 | dbcr0 |= DBCR0_IAC2 | DBCR0_IDM; | ||
294 | } | ||
295 | if (dbg->bp[2]) { | ||
296 | mtspr(SPRN_IAC3, dbg->bp[2]); | ||
297 | dbcr0 |= DBCR0_IAC3 | DBCR0_IDM; | ||
298 | } | ||
299 | if (dbg->bp[3]) { | ||
300 | mtspr(SPRN_IAC4, dbg->bp[3]); | ||
301 | dbcr0 |= DBCR0_IAC4 | DBCR0_IDM; | ||
302 | } | ||
303 | |||
304 | mtspr(SPRN_DBCR0, dbcr0); | ||
305 | mtspr(SPRN_DBCR1, 0); | ||
306 | mtspr(SPRN_DBCR2, 0); | ||
307 | } | ||
308 | |||
242 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 309 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
243 | { | 310 | { |
311 | int i; | ||
312 | |||
313 | if (vcpu->guest_debug.enabled) | ||
314 | kvmppc_load_guest_debug_registers(vcpu); | ||
315 | |||
316 | /* Mark every guest entry in the shadow TLB entry modified, so that they | ||
317 | * will all be reloaded on the next vcpu run (instead of being | ||
318 | * demand-faulted). */ | ||
319 | for (i = 0; i <= tlb_44x_hwater; i++) | ||
320 | kvmppc_tlbe_set_modified(vcpu, i); | ||
244 | } | 321 | } |
245 | 322 | ||
246 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 323 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
247 | { | 324 | { |
325 | if (vcpu->guest_debug.enabled) | ||
326 | kvmppc_restore_host_debug_state(vcpu); | ||
327 | |||
328 | /* Don't leave guest TLB entries resident when being de-scheduled. */ | ||
329 | /* XXX It would be nice to differentiate between heavyweight exit and | ||
330 | * sched_out here, since we could avoid the TLB flush for heavyweight | ||
331 | * exits. */ | ||
332 | _tlbia(); | ||
248 | } | 333 | } |
249 | 334 | ||
250 | int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, | 335 | int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, |
251 | struct kvm_debug_guest *dbg) | 336 | struct kvm_debug_guest *dbg) |
252 | { | 337 | { |
253 | return -ENOTSUPP; | 338 | int i; |
339 | |||
340 | vcpu->guest_debug.enabled = dbg->enabled; | ||
341 | if (vcpu->guest_debug.enabled) { | ||
342 | for (i=0; i < ARRAY_SIZE(vcpu->guest_debug.bp); i++) { | ||
343 | if (dbg->breakpoints[i].enabled) | ||
344 | vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address; | ||
345 | else | ||
346 | vcpu->guest_debug.bp[i] = 0; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | return 0; | ||
254 | } | 351 | } |
255 | 352 | ||
256 | static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, | 353 | static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 98d7bf99533a..b9e1a1da6e52 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
@@ -134,23 +134,6 @@ int arch_add_memory(int nid, u64 start, u64 size) | |||
134 | 134 | ||
135 | return __add_pages(zone, start_pfn, nr_pages); | 135 | return __add_pages(zone, start_pfn, nr_pages); |
136 | } | 136 | } |
137 | |||
138 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
139 | int remove_memory(u64 start, u64 size) | ||
140 | { | ||
141 | unsigned long start_pfn, end_pfn; | ||
142 | int ret; | ||
143 | |||
144 | start_pfn = start >> PAGE_SHIFT; | ||
145 | end_pfn = start_pfn + (size >> PAGE_SHIFT); | ||
146 | ret = offline_pages(start_pfn, end_pfn, 120 * HZ); | ||
147 | if (ret) | ||
148 | goto out; | ||
149 | /* Arch-specific calls go here - next patch */ | ||
150 | out: | ||
151 | return ret; | ||
152 | } | ||
153 | #endif /* CONFIG_MEMORY_HOTREMOVE */ | ||
154 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 137 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
155 | 138 | ||
156 | /* | 139 | /* |
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 439c5ba34ecf..548efa55c8fe 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
@@ -135,7 +135,6 @@ config PTE_64BIT | |||
135 | config PHYS_64BIT | 135 | config PHYS_64BIT |
136 | bool 'Large physical address support' if E500 || PPC_86xx | 136 | bool 'Large physical address support' if E500 || PPC_86xx |
137 | depends on (44x || E500 || PPC_86xx) && !PPC_83xx && !PPC_82xx | 137 | depends on (44x || E500 || PPC_86xx) && !PPC_83xx && !PPC_82xx |
138 | select RESOURCES_64BIT | ||
139 | ---help--- | 138 | ---help--- |
140 | This option enables kernel support for larger than 32-bit physical | 139 | This option enables kernel support for larger than 32-bit physical |
141 | addresses. This feature may not be available on all cores. | 140 | addresses. This feature may not be available on all cores. |
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c index a2460e2e1928..d0b1f3f4d9c8 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/arch/powerpc/platforms/cell/spufs/sputrace.c | |||
@@ -263,6 +263,7 @@ static void __exit sputrace_exit(void) | |||
263 | 263 | ||
264 | remove_proc_entry("sputrace", NULL); | 264 | remove_proc_entry("sputrace", NULL); |
265 | kfree(sputrace_log); | 265 | kfree(sputrace_log); |
266 | marker_synchronize_unregister(); | ||
266 | } | 267 | } |
267 | 268 | ||
268 | module_init(sputrace_init); | 269 | module_init(sputrace_init); |
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 9f6f73d584d6..d3e4d61030b5 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
@@ -39,13 +39,10 @@ static int dma_offset_set; | |||
39 | #define U64_TO_U32_LOW(val) ((u32)((val) & 0x00000000ffffffffULL)) | 39 | #define U64_TO_U32_LOW(val) ((u32)((val) & 0x00000000ffffffffULL)) |
40 | #define U64_TO_U32_HIGH(val) ((u32)((val) >> 32)) | 40 | #define U64_TO_U32_HIGH(val) ((u32)((val) >> 32)) |
41 | 41 | ||
42 | #ifdef CONFIG_RESOURCES_64BIT | 42 | #define RES_TO_U32_LOW(val) \ |
43 | #define RES_TO_U32_LOW(val) U64_TO_U32_LOW(val) | 43 | ((sizeof(resource_size_t) > sizeof(u32)) ? U64_TO_U32_LOW(val) : (val)) |
44 | #define RES_TO_U32_HIGH(val) U64_TO_U32_HIGH(val) | 44 | #define RES_TO_U32_HIGH(val) \ |
45 | #else | 45 | ((sizeof(resource_size_t) > sizeof(u32)) ? U64_TO_U32_HIGH(val) : (0)) |
46 | #define RES_TO_U32_LOW(val) (val) | ||
47 | #define RES_TO_U32_HIGH(val) (0) | ||
48 | #endif | ||
49 | 46 | ||
50 | static inline int ppc440spe_revA(void) | 47 | static inline int ppc440spe_revA(void) |
51 | { | 48 | { |
@@ -144,12 +141,11 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, | |||
144 | 141 | ||
145 | /* Use that */ | 142 | /* Use that */ |
146 | res->start = pci_addr; | 143 | res->start = pci_addr; |
147 | #ifndef CONFIG_RESOURCES_64BIT | ||
148 | /* Beware of 32 bits resources */ | 144 | /* Beware of 32 bits resources */ |
149 | if ((pci_addr + size) > 0x100000000ull) | 145 | if (sizeof(resource_size_t) == sizeof(u32) && |
146 | (pci_addr + size) > 0x100000000ull) | ||
150 | res->end = 0xffffffff; | 147 | res->end = 0xffffffff; |
151 | else | 148 | else |
152 | #endif | ||
153 | res->end = res->start + size - 1; | 149 | res->end = res->start + size - 1; |
154 | break; | 150 | break; |
155 | } | 151 | } |