diff options
Diffstat (limited to 'arch')
329 files changed, 6840 insertions, 2841 deletions
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index 4e547296831d..52312cb5dbe2 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h | |||
@@ -47,9 +47,6 @@ struct thread_struct { | |||
47 | /* Forward declaration, a strange C thing */ | 47 | /* Forward declaration, a strange C thing */ |
48 | struct task_struct; | 48 | struct task_struct; |
49 | 49 | ||
50 | /* Return saved PC of a blocked thread */ | ||
51 | unsigned long thread_saved_pc(struct task_struct *t); | ||
52 | |||
53 | #define task_pt_regs(p) \ | 50 | #define task_pt_regs(p) \ |
54 | ((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1) | 51 | ((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1) |
55 | 52 | ||
@@ -72,18 +69,21 @@ unsigned long thread_saved_pc(struct task_struct *t); | |||
72 | #define release_segments(mm) do { } while (0) | 69 | #define release_segments(mm) do { } while (0) |
73 | 70 | ||
74 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ret) | 71 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ret) |
72 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp) | ||
75 | 73 | ||
76 | /* | 74 | /* |
77 | * Where abouts of Task's sp, fp, blink when it was last seen in kernel mode. | 75 | * Where abouts of Task's sp, fp, blink when it was last seen in kernel mode. |
78 | * Look in process.c for details of kernel stack layout | 76 | * Look in process.c for details of kernel stack layout |
79 | */ | 77 | */ |
80 | #define KSTK_ESP(tsk) (tsk->thread.ksp) | 78 | #define TSK_K_ESP(tsk) (tsk->thread.ksp) |
81 | 79 | ||
82 | #define KSTK_REG(tsk, off) (*((unsigned int *)(KSTK_ESP(tsk) + \ | 80 | #define TSK_K_REG(tsk, off) (*((unsigned int *)(TSK_K_ESP(tsk) + \ |
83 | sizeof(struct callee_regs) + off))) | 81 | sizeof(struct callee_regs) + off))) |
84 | 82 | ||
85 | #define KSTK_BLINK(tsk) KSTK_REG(tsk, 4) | 83 | #define TSK_K_BLINK(tsk) TSK_K_REG(tsk, 4) |
86 | #define KSTK_FP(tsk) KSTK_REG(tsk, 0) | 84 | #define TSK_K_FP(tsk) TSK_K_REG(tsk, 0) |
85 | |||
86 | #define thread_saved_pc(tsk) TSK_K_BLINK(tsk) | ||
87 | 87 | ||
88 | extern void start_thread(struct pt_regs * regs, unsigned long pc, | 88 | extern void start_thread(struct pt_regs * regs, unsigned long pc, |
89 | unsigned long usp); | 89 | unsigned long usp); |
diff --git a/arch/arc/include/asm/stacktrace.h b/arch/arc/include/asm/stacktrace.h new file mode 100644 index 000000000000..b29b6064ea14 --- /dev/null +++ b/arch/arc/include/asm/stacktrace.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) | ||
3 | * Copyright (C) 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #ifndef __ASM_STACKTRACE_H | ||
11 | #define __ASM_STACKTRACE_H | ||
12 | |||
13 | #include <linux/sched.h> | ||
14 | |||
15 | /** | ||
16 | * arc_unwind_core - Unwind the kernel mode stack for an execution context | ||
17 | * @tsk: NULL for current task, specific task otherwise | ||
18 | * @regs: pt_regs used to seed the unwinder {SP, FP, BLINK, PC} | ||
19 | * If NULL, use pt_regs of @tsk (if !NULL) otherwise | ||
20 | * use the current values of {SP, FP, BLINK, PC} | ||
21 | * @consumer_fn: Callback invoked for each frame unwound | ||
22 | * Returns 0 to continue unwinding, -1 to stop | ||
23 | * @arg: Arg to callback | ||
24 | * | ||
25 | * Returns the address of first function in stack | ||
26 | * | ||
27 | * Semantics: | ||
28 | * - synchronous unwinding (e.g. dump_stack): @tsk NULL, @regs NULL | ||
29 | * - Asynchronous unwinding of sleeping task: @tsk !NULL, @regs NULL | ||
30 | * - Asynchronous unwinding of intr/excp etc: @tsk !NULL, @regs !NULL | ||
31 | */ | ||
32 | notrace noinline unsigned int arc_unwind_core( | ||
33 | struct task_struct *tsk, struct pt_regs *regs, | ||
34 | int (*consumer_fn) (unsigned int, void *), | ||
35 | void *arg); | ||
36 | |||
37 | #endif /* __ASM_STACKTRACE_H */ | ||
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index fdd89715d2d3..98c00a2d4dd9 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c | |||
@@ -192,29 +192,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) | |||
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | /* | ||
196 | * API: expected by schedular Code: If thread is sleeping where is that. | ||
197 | * What is this good for? it will be always the scheduler or ret_from_fork. | ||
198 | * So we hard code that anyways. | ||
199 | */ | ||
200 | unsigned long thread_saved_pc(struct task_struct *t) | ||
201 | { | ||
202 | struct pt_regs *regs = task_pt_regs(t); | ||
203 | unsigned long blink = 0; | ||
204 | |||
205 | /* | ||
206 | * If the thread being queried for in not itself calling this, then it | ||
207 | * implies it is not executing, which in turn implies it is sleeping, | ||
208 | * which in turn implies it got switched OUT by the schedular. | ||
209 | * In that case, it's kernel mode blink can reliably retrieved as per | ||
210 | * the picture above (right above pt_regs). | ||
211 | */ | ||
212 | if (t != current && t->state != TASK_RUNNING) | ||
213 | blink = *((unsigned int *)regs - 1); | ||
214 | |||
215 | return blink; | ||
216 | } | ||
217 | |||
218 | int elf_check_arch(const struct elf32_hdr *x) | 195 | int elf_check_arch(const struct elf32_hdr *x) |
219 | { | 196 | { |
220 | unsigned int eflags; | 197 | unsigned int eflags; |
diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index 114234e83caa..edda76fae83f 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c | |||
@@ -67,7 +67,7 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs, | |||
67 | sigset_t *set) | 67 | sigset_t *set) |
68 | { | 68 | { |
69 | int err; | 69 | int err; |
70 | err = __copy_to_user(&(sf->uc.uc_mcontext.regs), regs, | 70 | err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), regs, |
71 | sizeof(sf->uc.uc_mcontext.regs.scratch)); | 71 | sizeof(sf->uc.uc_mcontext.regs.scratch)); |
72 | err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t)); | 72 | err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t)); |
73 | 73 | ||
@@ -83,7 +83,7 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf) | |||
83 | if (!err) | 83 | if (!err) |
84 | set_current_blocked(&set); | 84 | set_current_blocked(&set); |
85 | 85 | ||
86 | err |= __copy_from_user(regs, &(sf->uc.uc_mcontext.regs), | 86 | err |= __copy_from_user(regs, &(sf->uc.uc_mcontext.regs.scratch), |
87 | sizeof(sf->uc.uc_mcontext.regs.scratch)); | 87 | sizeof(sf->uc.uc_mcontext.regs.scratch)); |
88 | 88 | ||
89 | return err; | 89 | return err; |
@@ -131,6 +131,15 @@ SYSCALL_DEFINE0(rt_sigreturn) | |||
131 | /* Don't restart from sigreturn */ | 131 | /* Don't restart from sigreturn */ |
132 | syscall_wont_restart(regs); | 132 | syscall_wont_restart(regs); |
133 | 133 | ||
134 | /* | ||
135 | * Ensure that sigreturn always returns to user mode (in case the | ||
136 | * regs saved on user stack got fudged between save and sigreturn) | ||
137 | * Otherwise it is easy to panic the kernel with a custom | ||
138 | * signal handler and/or restorer which clobberes the status32/ret | ||
139 | * to return to a bogus location in kernel mode. | ||
140 | */ | ||
141 | regs->status32 |= STATUS_U_MASK; | ||
142 | |||
134 | return regs->r0; | 143 | return regs->r0; |
135 | 144 | ||
136 | badframe: | 145 | badframe: |
@@ -229,8 +238,11 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) | |||
229 | 238 | ||
230 | /* | 239 | /* |
231 | * handler returns using sigreturn stub provided already by userpsace | 240 | * handler returns using sigreturn stub provided already by userpsace |
241 | * If not, nuke the process right away | ||
232 | */ | 242 | */ |
233 | BUG_ON(!(ksig->ka.sa.sa_flags & SA_RESTORER)); | 243 | if(!(ksig->ka.sa.sa_flags & SA_RESTORER)) |
244 | return 1; | ||
245 | |||
234 | regs->blink = (unsigned long)ksig->ka.sa.sa_restorer; | 246 | regs->blink = (unsigned long)ksig->ka.sa.sa_restorer; |
235 | 247 | ||
236 | /* User Stack for signal handler will be above the frame just carved */ | 248 | /* User Stack for signal handler will be above the frame just carved */ |
@@ -296,12 +308,12 @@ static void | |||
296 | handle_signal(struct ksignal *ksig, struct pt_regs *regs) | 308 | handle_signal(struct ksignal *ksig, struct pt_regs *regs) |
297 | { | 309 | { |
298 | sigset_t *oldset = sigmask_to_save(); | 310 | sigset_t *oldset = sigmask_to_save(); |
299 | int ret; | 311 | int failed; |
300 | 312 | ||
301 | /* Set up the stack frame */ | 313 | /* Set up the stack frame */ |
302 | ret = setup_rt_frame(ksig, oldset, regs); | 314 | failed = setup_rt_frame(ksig, oldset, regs); |
303 | 315 | ||
304 | signal_setup_done(ret, ksig, 0); | 316 | signal_setup_done(failed, ksig, 0); |
305 | } | 317 | } |
306 | 318 | ||
307 | void do_signal(struct pt_regs *regs) | 319 | void do_signal(struct pt_regs *regs) |
diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index 9ce47cfe2303..92320d6f737c 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c | |||
@@ -43,6 +43,10 @@ static void seed_unwind_frame_info(struct task_struct *tsk, | |||
43 | struct pt_regs *regs, | 43 | struct pt_regs *regs, |
44 | struct unwind_frame_info *frame_info) | 44 | struct unwind_frame_info *frame_info) |
45 | { | 45 | { |
46 | /* | ||
47 | * synchronous unwinding (e.g. dump_stack) | ||
48 | * - uses current values of SP and friends | ||
49 | */ | ||
46 | if (tsk == NULL && regs == NULL) { | 50 | if (tsk == NULL && regs == NULL) { |
47 | unsigned long fp, sp, blink, ret; | 51 | unsigned long fp, sp, blink, ret; |
48 | frame_info->task = current; | 52 | frame_info->task = current; |
@@ -61,12 +65,17 @@ static void seed_unwind_frame_info(struct task_struct *tsk, | |||
61 | frame_info->regs.r63 = ret; | 65 | frame_info->regs.r63 = ret; |
62 | frame_info->call_frame = 0; | 66 | frame_info->call_frame = 0; |
63 | } else if (regs == NULL) { | 67 | } else if (regs == NULL) { |
68 | /* | ||
69 | * Asynchronous unwinding of sleeping task | ||
70 | * - Gets SP etc from task's pt_regs (saved bottom of kernel | ||
71 | * mode stack of task) | ||
72 | */ | ||
64 | 73 | ||
65 | frame_info->task = tsk; | 74 | frame_info->task = tsk; |
66 | 75 | ||
67 | frame_info->regs.r27 = KSTK_FP(tsk); | 76 | frame_info->regs.r27 = TSK_K_FP(tsk); |
68 | frame_info->regs.r28 = KSTK_ESP(tsk); | 77 | frame_info->regs.r28 = TSK_K_ESP(tsk); |
69 | frame_info->regs.r31 = KSTK_BLINK(tsk); | 78 | frame_info->regs.r31 = TSK_K_BLINK(tsk); |
70 | frame_info->regs.r63 = (unsigned int)__switch_to; | 79 | frame_info->regs.r63 = (unsigned int)__switch_to; |
71 | 80 | ||
72 | /* In the prologue of __switch_to, first FP is saved on stack | 81 | /* In the prologue of __switch_to, first FP is saved on stack |
@@ -83,6 +92,10 @@ static void seed_unwind_frame_info(struct task_struct *tsk, | |||
83 | frame_info->call_frame = 0; | 92 | frame_info->call_frame = 0; |
84 | 93 | ||
85 | } else { | 94 | } else { |
95 | /* | ||
96 | * Asynchronous unwinding of intr/exception | ||
97 | * - Just uses the pt_regs passed | ||
98 | */ | ||
86 | frame_info->task = tsk; | 99 | frame_info->task = tsk; |
87 | 100 | ||
88 | frame_info->regs.r27 = regs->fp; | 101 | frame_info->regs.r27 = regs->fp; |
@@ -95,7 +108,7 @@ static void seed_unwind_frame_info(struct task_struct *tsk, | |||
95 | 108 | ||
96 | #endif | 109 | #endif |
97 | 110 | ||
98 | static noinline unsigned int | 111 | notrace noinline unsigned int |
99 | arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, | 112 | arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, |
100 | int (*consumer_fn) (unsigned int, void *), void *arg) | 113 | int (*consumer_fn) (unsigned int, void *), void *arg) |
101 | { | 114 | { |
diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c index 7ff5b5c183bb..74db59b6f392 100644 --- a/arch/arc/kernel/unaligned.c +++ b/arch/arc/kernel/unaligned.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/perf_event.h> | ||
15 | #include <linux/ptrace.h> | 16 | #include <linux/ptrace.h> |
16 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
17 | #include <asm/disasm.h> | 18 | #include <asm/disasm.h> |
@@ -253,6 +254,7 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs, | |||
253 | } | 254 | } |
254 | } | 255 | } |
255 | 256 | ||
257 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, address); | ||
256 | return 0; | 258 | return 0; |
257 | 259 | ||
258 | fault: | 260 | fault: |
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c index 563cb27e37f5..6a2e006cbcce 100644 --- a/arch/arc/mm/fault.c +++ b/arch/arc/mm/fault.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/ptrace.h> | 14 | #include <linux/ptrace.h> |
15 | #include <linux/uaccess.h> | 15 | #include <linux/uaccess.h> |
16 | #include <linux/kdebug.h> | 16 | #include <linux/kdebug.h> |
17 | #include <linux/perf_event.h> | ||
17 | #include <asm/pgalloc.h> | 18 | #include <asm/pgalloc.h> |
18 | #include <asm/mmu.h> | 19 | #include <asm/mmu.h> |
19 | 20 | ||
@@ -139,13 +140,20 @@ good_area: | |||
139 | return; | 140 | return; |
140 | } | 141 | } |
141 | 142 | ||
143 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); | ||
144 | |||
142 | if (likely(!(fault & VM_FAULT_ERROR))) { | 145 | if (likely(!(fault & VM_FAULT_ERROR))) { |
143 | if (flags & FAULT_FLAG_ALLOW_RETRY) { | 146 | if (flags & FAULT_FLAG_ALLOW_RETRY) { |
144 | /* To avoid updating stats twice for retry case */ | 147 | /* To avoid updating stats twice for retry case */ |
145 | if (fault & VM_FAULT_MAJOR) | 148 | if (fault & VM_FAULT_MAJOR) { |
146 | tsk->maj_flt++; | 149 | tsk->maj_flt++; |
147 | else | 150 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, |
151 | regs, address); | ||
152 | } else { | ||
148 | tsk->min_flt++; | 153 | tsk->min_flt++; |
154 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, | ||
155 | regs, address); | ||
156 | } | ||
149 | 157 | ||
150 | if (fault & VM_FAULT_RETRY) { | 158 | if (fault & VM_FAULT_RETRY) { |
151 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | 159 | flags &= ~FAULT_FLAG_ALLOW_RETRY; |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9f1f09a2bc9b..cf4c0c99aa25 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -619,6 +619,7 @@ config ARCH_PXA | |||
619 | select GENERIC_CLOCKEVENTS | 619 | select GENERIC_CLOCKEVENTS |
620 | select GPIO_PXA | 620 | select GPIO_PXA |
621 | select HAVE_IDE | 621 | select HAVE_IDE |
622 | select IRQ_DOMAIN | ||
622 | select MULTI_IRQ_HANDLER | 623 | select MULTI_IRQ_HANDLER |
623 | select PLAT_PXA | 624 | select PLAT_PXA |
624 | select SPARSE_IRQ | 625 | select SPARSE_IRQ |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 7f99cd652203..eb7bb511f853 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -150,6 +150,7 @@ machine-$(CONFIG_ARCH_BERLIN) += berlin | |||
150 | machine-$(CONFIG_ARCH_CLPS711X) += clps711x | 150 | machine-$(CONFIG_ARCH_CLPS711X) += clps711x |
151 | machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx | 151 | machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx |
152 | machine-$(CONFIG_ARCH_DAVINCI) += davinci | 152 | machine-$(CONFIG_ARCH_DAVINCI) += davinci |
153 | machine-$(CONFIG_ARCH_DIGICOLOR) += digicolor | ||
153 | machine-$(CONFIG_ARCH_DOVE) += dove | 154 | machine-$(CONFIG_ARCH_DOVE) += dove |
154 | machine-$(CONFIG_ARCH_EBSA110) += ebsa110 | 155 | machine-$(CONFIG_ARCH_EBSA110) += ebsa110 |
155 | machine-$(CONFIG_ARCH_EFM32) += efm32 | 156 | machine-$(CONFIG_ARCH_EFM32) += efm32 |
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index 6cc25ed912ee..c3255e0c90aa 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi | |||
@@ -195,6 +195,7 @@ | |||
195 | 195 | ||
196 | &usb0 { | 196 | &usb0 { |
197 | status = "okay"; | 197 | status = "okay"; |
198 | dr_mode = "peripheral"; | ||
198 | }; | 199 | }; |
199 | 200 | ||
200 | &usb1 { | 201 | &usb1 { |
@@ -300,3 +301,11 @@ | |||
300 | cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; | 301 | cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; |
301 | cd-inverted; | 302 | cd-inverted; |
302 | }; | 303 | }; |
304 | |||
305 | &aes { | ||
306 | status = "okay"; | ||
307 | }; | ||
308 | |||
309 | &sham { | ||
310 | status = "okay"; | ||
311 | }; | ||
diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts index 83d40f7655e5..6b8493720424 100644 --- a/arch/arm/boot/dts/am335x-bone.dts +++ b/arch/arm/boot/dts/am335x-bone.dts | |||
@@ -24,11 +24,3 @@ | |||
24 | &mmc1 { | 24 | &mmc1 { |
25 | vmmc-supply = <&ldo3_reg>; | 25 | vmmc-supply = <&ldo3_reg>; |
26 | }; | 26 | }; |
27 | |||
28 | &sham { | ||
29 | status = "okay"; | ||
30 | }; | ||
31 | |||
32 | &aes { | ||
33 | status = "okay"; | ||
34 | }; | ||
diff --git a/arch/arm/boot/dts/am335x-lxm.dts b/arch/arm/boot/dts/am335x-lxm.dts index 7266a00aab2e..5c5667a3624d 100644 --- a/arch/arm/boot/dts/am335x-lxm.dts +++ b/arch/arm/boot/dts/am335x-lxm.dts | |||
@@ -328,6 +328,10 @@ | |||
328 | dual_emac_res_vlan = <3>; | 328 | dual_emac_res_vlan = <3>; |
329 | }; | 329 | }; |
330 | 330 | ||
331 | &phy_sel { | ||
332 | rmii-clock-ext; | ||
333 | }; | ||
334 | |||
331 | &mac { | 335 | &mac { |
332 | pinctrl-names = "default", "sleep"; | 336 | pinctrl-names = "default", "sleep"; |
333 | pinctrl-0 = <&cpsw_default>; | 337 | pinctrl-0 = <&cpsw_default>; |
diff --git a/arch/arm/boot/dts/am33xx-clocks.dtsi b/arch/arm/boot/dts/am33xx-clocks.dtsi index 712edce7d6fb..071b56aa0c7e 100644 --- a/arch/arm/boot/dts/am33xx-clocks.dtsi +++ b/arch/arm/boot/dts/am33xx-clocks.dtsi | |||
@@ -99,7 +99,7 @@ | |||
99 | ehrpwm0_tbclk: ehrpwm0_tbclk@44e10664 { | 99 | ehrpwm0_tbclk: ehrpwm0_tbclk@44e10664 { |
100 | #clock-cells = <0>; | 100 | #clock-cells = <0>; |
101 | compatible = "ti,gate-clock"; | 101 | compatible = "ti,gate-clock"; |
102 | clocks = <&dpll_per_m2_ck>; | 102 | clocks = <&l4ls_gclk>; |
103 | ti,bit-shift = <0>; | 103 | ti,bit-shift = <0>; |
104 | reg = <0x0664>; | 104 | reg = <0x0664>; |
105 | }; | 105 | }; |
@@ -107,7 +107,7 @@ | |||
107 | ehrpwm1_tbclk: ehrpwm1_tbclk@44e10664 { | 107 | ehrpwm1_tbclk: ehrpwm1_tbclk@44e10664 { |
108 | #clock-cells = <0>; | 108 | #clock-cells = <0>; |
109 | compatible = "ti,gate-clock"; | 109 | compatible = "ti,gate-clock"; |
110 | clocks = <&dpll_per_m2_ck>; | 110 | clocks = <&l4ls_gclk>; |
111 | ti,bit-shift = <1>; | 111 | ti,bit-shift = <1>; |
112 | reg = <0x0664>; | 112 | reg = <0x0664>; |
113 | }; | 113 | }; |
@@ -115,7 +115,7 @@ | |||
115 | ehrpwm2_tbclk: ehrpwm2_tbclk@44e10664 { | 115 | ehrpwm2_tbclk: ehrpwm2_tbclk@44e10664 { |
116 | #clock-cells = <0>; | 116 | #clock-cells = <0>; |
117 | compatible = "ti,gate-clock"; | 117 | compatible = "ti,gate-clock"; |
118 | clocks = <&dpll_per_m2_ck>; | 118 | clocks = <&l4ls_gclk>; |
119 | ti,bit-shift = <2>; | 119 | ti,bit-shift = <2>; |
120 | reg = <0x0664>; | 120 | reg = <0x0664>; |
121 | }; | 121 | }; |
diff --git a/arch/arm/boot/dts/am437x-idk-evm.dts b/arch/arm/boot/dts/am437x-idk-evm.dts index f9a17e2ca8cb..0198f5a62b96 100644 --- a/arch/arm/boot/dts/am437x-idk-evm.dts +++ b/arch/arm/boot/dts/am437x-idk-evm.dts | |||
@@ -133,20 +133,6 @@ | |||
133 | >; | 133 | >; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | i2c1_pins_default: i2c1_pins_default { | ||
137 | pinctrl-single,pins = < | ||
138 | 0x15c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2) /* spi0_cs0.i2c1_scl */ | ||
139 | 0x158 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2) /* spi0_d1.i2c1_sda */ | ||
140 | >; | ||
141 | }; | ||
142 | |||
143 | i2c1_pins_sleep: i2c1_pins_sleep { | ||
144 | pinctrl-single,pins = < | ||
145 | 0x15c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_cs0.i2c1_scl */ | ||
146 | 0x158 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_d1.i2c1_sda */ | ||
147 | >; | ||
148 | }; | ||
149 | |||
150 | mmc1_pins_default: pinmux_mmc1_pins_default { | 136 | mmc1_pins_default: pinmux_mmc1_pins_default { |
151 | pinctrl-single,pins = < | 137 | pinctrl-single,pins = < |
152 | 0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */ | 138 | 0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */ |
@@ -254,7 +240,7 @@ | |||
254 | status = "okay"; | 240 | status = "okay"; |
255 | pinctrl-names = "default", "sleep"; | 241 | pinctrl-names = "default", "sleep"; |
256 | pinctrl-0 = <&i2c0_pins_default>; | 242 | pinctrl-0 = <&i2c0_pins_default>; |
257 | pinctrl-1 = <&i2c0_pins_default>; | 243 | pinctrl-1 = <&i2c0_pins_sleep>; |
258 | clock-frequency = <400000>; | 244 | clock-frequency = <400000>; |
259 | 245 | ||
260 | at24@50 { | 246 | at24@50 { |
@@ -262,17 +248,10 @@ | |||
262 | pagesize = <64>; | 248 | pagesize = <64>; |
263 | reg = <0x50>; | 249 | reg = <0x50>; |
264 | }; | 250 | }; |
265 | }; | ||
266 | |||
267 | &i2c1 { | ||
268 | status = "okay"; | ||
269 | pinctrl-names = "default", "sleep"; | ||
270 | pinctrl-0 = <&i2c1_pins_default>; | ||
271 | pinctrl-1 = <&i2c1_pins_default>; | ||
272 | clock-frequency = <400000>; | ||
273 | 251 | ||
274 | tps: tps62362@60 { | 252 | tps: tps62362@60 { |
275 | compatible = "ti,tps62362"; | 253 | compatible = "ti,tps62362"; |
254 | reg = <0x60>; | ||
276 | regulator-name = "VDD_MPU"; | 255 | regulator-name = "VDD_MPU"; |
277 | regulator-min-microvolt = <950000>; | 256 | regulator-min-microvolt = <950000>; |
278 | regulator-max-microvolt = <1330000>; | 257 | regulator-max-microvolt = <1330000>; |
diff --git a/arch/arm/boot/dts/am43xx-clocks.dtsi b/arch/arm/boot/dts/am43xx-clocks.dtsi index c7dc9dab93a4..cfb49686ab6a 100644 --- a/arch/arm/boot/dts/am43xx-clocks.dtsi +++ b/arch/arm/boot/dts/am43xx-clocks.dtsi | |||
@@ -107,7 +107,7 @@ | |||
107 | ehrpwm0_tbclk: ehrpwm0_tbclk { | 107 | ehrpwm0_tbclk: ehrpwm0_tbclk { |
108 | #clock-cells = <0>; | 108 | #clock-cells = <0>; |
109 | compatible = "ti,gate-clock"; | 109 | compatible = "ti,gate-clock"; |
110 | clocks = <&dpll_per_m2_ck>; | 110 | clocks = <&l4ls_gclk>; |
111 | ti,bit-shift = <0>; | 111 | ti,bit-shift = <0>; |
112 | reg = <0x0664>; | 112 | reg = <0x0664>; |
113 | }; | 113 | }; |
@@ -115,7 +115,7 @@ | |||
115 | ehrpwm1_tbclk: ehrpwm1_tbclk { | 115 | ehrpwm1_tbclk: ehrpwm1_tbclk { |
116 | #clock-cells = <0>; | 116 | #clock-cells = <0>; |
117 | compatible = "ti,gate-clock"; | 117 | compatible = "ti,gate-clock"; |
118 | clocks = <&dpll_per_m2_ck>; | 118 | clocks = <&l4ls_gclk>; |
119 | ti,bit-shift = <1>; | 119 | ti,bit-shift = <1>; |
120 | reg = <0x0664>; | 120 | reg = <0x0664>; |
121 | }; | 121 | }; |
@@ -123,7 +123,7 @@ | |||
123 | ehrpwm2_tbclk: ehrpwm2_tbclk { | 123 | ehrpwm2_tbclk: ehrpwm2_tbclk { |
124 | #clock-cells = <0>; | 124 | #clock-cells = <0>; |
125 | compatible = "ti,gate-clock"; | 125 | compatible = "ti,gate-clock"; |
126 | clocks = <&dpll_per_m2_ck>; | 126 | clocks = <&l4ls_gclk>; |
127 | ti,bit-shift = <2>; | 127 | ti,bit-shift = <2>; |
128 | reg = <0x0664>; | 128 | reg = <0x0664>; |
129 | }; | 129 | }; |
@@ -131,7 +131,7 @@ | |||
131 | ehrpwm3_tbclk: ehrpwm3_tbclk { | 131 | ehrpwm3_tbclk: ehrpwm3_tbclk { |
132 | #clock-cells = <0>; | 132 | #clock-cells = <0>; |
133 | compatible = "ti,gate-clock"; | 133 | compatible = "ti,gate-clock"; |
134 | clocks = <&dpll_per_m2_ck>; | 134 | clocks = <&l4ls_gclk>; |
135 | ti,bit-shift = <4>; | 135 | ti,bit-shift = <4>; |
136 | reg = <0x0664>; | 136 | reg = <0x0664>; |
137 | }; | 137 | }; |
@@ -139,7 +139,7 @@ | |||
139 | ehrpwm4_tbclk: ehrpwm4_tbclk { | 139 | ehrpwm4_tbclk: ehrpwm4_tbclk { |
140 | #clock-cells = <0>; | 140 | #clock-cells = <0>; |
141 | compatible = "ti,gate-clock"; | 141 | compatible = "ti,gate-clock"; |
142 | clocks = <&dpll_per_m2_ck>; | 142 | clocks = <&l4ls_gclk>; |
143 | ti,bit-shift = <5>; | 143 | ti,bit-shift = <5>; |
144 | reg = <0x0664>; | 144 | reg = <0x0664>; |
145 | }; | 145 | }; |
@@ -147,7 +147,7 @@ | |||
147 | ehrpwm5_tbclk: ehrpwm5_tbclk { | 147 | ehrpwm5_tbclk: ehrpwm5_tbclk { |
148 | #clock-cells = <0>; | 148 | #clock-cells = <0>; |
149 | compatible = "ti,gate-clock"; | 149 | compatible = "ti,gate-clock"; |
150 | clocks = <&dpll_per_m2_ck>; | 150 | clocks = <&l4ls_gclk>; |
151 | ti,bit-shift = <6>; | 151 | ti,bit-shift = <6>; |
152 | reg = <0x0664>; | 152 | reg = <0x0664>; |
153 | }; | 153 | }; |
diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index 03750af3b49a..6463f9ef2b54 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts | |||
@@ -549,14 +549,6 @@ | |||
549 | pinctrl-0 = <&usb1_pins>; | 549 | pinctrl-0 = <&usb1_pins>; |
550 | }; | 550 | }; |
551 | 551 | ||
552 | &omap_dwc3_1 { | ||
553 | extcon = <&extcon_usb1>; | ||
554 | }; | ||
555 | |||
556 | &omap_dwc3_2 { | ||
557 | extcon = <&extcon_usb2>; | ||
558 | }; | ||
559 | |||
560 | &usb2 { | 552 | &usb2 { |
561 | dr_mode = "peripheral"; | 553 | dr_mode = "peripheral"; |
562 | }; | 554 | }; |
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index fff0ee69aab4..e7f0a4ae271c 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi | |||
@@ -494,12 +494,12 @@ | |||
494 | 494 | ||
495 | pinctrl_usart3_rts: usart3_rts-0 { | 495 | pinctrl_usart3_rts: usart3_rts-0 { |
496 | atmel,pins = | 496 | atmel,pins = |
497 | <AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC8 periph B */ | 497 | <AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_NONE>; |
498 | }; | 498 | }; |
499 | 499 | ||
500 | pinctrl_usart3_cts: usart3_cts-0 { | 500 | pinctrl_usart3_cts: usart3_cts-0 { |
501 | atmel,pins = | 501 | atmel,pins = |
502 | <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC10 periph B */ | 502 | <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_NONE>; |
503 | }; | 503 | }; |
504 | }; | 504 | }; |
505 | 505 | ||
@@ -853,7 +853,7 @@ | |||
853 | }; | 853 | }; |
854 | 854 | ||
855 | usb1: gadget@fffa4000 { | 855 | usb1: gadget@fffa4000 { |
856 | compatible = "atmel,at91rm9200-udc"; | 856 | compatible = "atmel,at91sam9260-udc"; |
857 | reg = <0xfffa4000 0x4000>; | 857 | reg = <0xfffa4000 0x4000>; |
858 | interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>; | 858 | interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>; |
859 | clocks = <&udc_clk>, <&udpck>; | 859 | clocks = <&udc_clk>, <&udpck>; |
@@ -976,7 +976,6 @@ | |||
976 | atmel,watchdog-type = "hardware"; | 976 | atmel,watchdog-type = "hardware"; |
977 | atmel,reset-type = "all"; | 977 | atmel,reset-type = "all"; |
978 | atmel,dbg-halt; | 978 | atmel,dbg-halt; |
979 | atmel,idle-halt; | ||
980 | status = "disabled"; | 979 | status = "disabled"; |
981 | }; | 980 | }; |
982 | 981 | ||
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi index e247b0b5fdab..d55fdf2487ef 100644 --- a/arch/arm/boot/dts/at91sam9261.dtsi +++ b/arch/arm/boot/dts/at91sam9261.dtsi | |||
@@ -124,11 +124,12 @@ | |||
124 | }; | 124 | }; |
125 | 125 | ||
126 | usb1: gadget@fffa4000 { | 126 | usb1: gadget@fffa4000 { |
127 | compatible = "atmel,at91rm9200-udc"; | 127 | compatible = "atmel,at91sam9261-udc"; |
128 | reg = <0xfffa4000 0x4000>; | 128 | reg = <0xfffa4000 0x4000>; |
129 | interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>; | 129 | interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>; |
130 | clocks = <&usb>, <&udc_clk>, <&udpck>; | 130 | clocks = <&udc_clk>, <&udpck>; |
131 | clock-names = "usb_clk", "udc_clk", "udpck"; | 131 | clock-names = "pclk", "hclk"; |
132 | atmel,matrix = <&matrix>; | ||
132 | status = "disabled"; | 133 | status = "disabled"; |
133 | }; | 134 | }; |
134 | 135 | ||
@@ -262,7 +263,7 @@ | |||
262 | }; | 263 | }; |
263 | 264 | ||
264 | matrix: matrix@ffffee00 { | 265 | matrix: matrix@ffffee00 { |
265 | compatible = "atmel,at91sam9260-bus-matrix"; | 266 | compatible = "atmel,at91sam9260-bus-matrix", "syscon"; |
266 | reg = <0xffffee00 0x200>; | 267 | reg = <0xffffee00 0x200>; |
267 | }; | 268 | }; |
268 | 269 | ||
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 1f67bb4c144e..fce301c4e9d6 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi | |||
@@ -69,7 +69,7 @@ | |||
69 | 69 | ||
70 | sram1: sram@00500000 { | 70 | sram1: sram@00500000 { |
71 | compatible = "mmio-sram"; | 71 | compatible = "mmio-sram"; |
72 | reg = <0x00300000 0x4000>; | 72 | reg = <0x00500000 0x4000>; |
73 | }; | 73 | }; |
74 | 74 | ||
75 | ahb { | 75 | ahb { |
@@ -856,7 +856,7 @@ | |||
856 | }; | 856 | }; |
857 | 857 | ||
858 | usb1: gadget@fff78000 { | 858 | usb1: gadget@fff78000 { |
859 | compatible = "atmel,at91rm9200-udc"; | 859 | compatible = "atmel,at91sam9263-udc"; |
860 | reg = <0xfff78000 0x4000>; | 860 | reg = <0xfff78000 0x4000>; |
861 | interrupts = <24 IRQ_TYPE_LEVEL_HIGH 2>; | 861 | interrupts = <24 IRQ_TYPE_LEVEL_HIGH 2>; |
862 | clocks = <&udc_clk>, <&udpck>; | 862 | clocks = <&udc_clk>, <&udpck>; |
@@ -905,7 +905,6 @@ | |||
905 | atmel,watchdog-type = "hardware"; | 905 | atmel,watchdog-type = "hardware"; |
906 | atmel,reset-type = "all"; | 906 | atmel,reset-type = "all"; |
907 | atmel,dbg-halt; | 907 | atmel,dbg-halt; |
908 | atmel,idle-halt; | ||
909 | status = "disabled"; | 908 | status = "disabled"; |
910 | }; | 909 | }; |
911 | 910 | ||
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index ee80aa9c0759..488af63d5174 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi | |||
@@ -1116,7 +1116,6 @@ | |||
1116 | atmel,watchdog-type = "hardware"; | 1116 | atmel,watchdog-type = "hardware"; |
1117 | atmel,reset-type = "all"; | 1117 | atmel,reset-type = "all"; |
1118 | atmel,dbg-halt; | 1118 | atmel,dbg-halt; |
1119 | atmel,idle-halt; | ||
1120 | status = "disabled"; | 1119 | status = "disabled"; |
1121 | }; | 1120 | }; |
1122 | 1121 | ||
@@ -1301,7 +1300,7 @@ | |||
1301 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; | 1300 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; |
1302 | reg = <0x00800000 0x100000>; | 1301 | reg = <0x00800000 0x100000>; |
1303 | interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; | 1302 | interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; |
1304 | clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; | 1303 | clocks = <&utmi>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; |
1305 | clock-names = "usb_clk", "ehci_clk", "hclk", "uhpck"; | 1304 | clock-names = "usb_clk", "ehci_clk", "hclk", "uhpck"; |
1306 | status = "disabled"; | 1305 | status = "disabled"; |
1307 | }; | 1306 | }; |
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index c2666a7cb5b1..0c53a375ba99 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi | |||
@@ -894,7 +894,6 @@ | |||
894 | atmel,watchdog-type = "hardware"; | 894 | atmel,watchdog-type = "hardware"; |
895 | atmel,reset-type = "all"; | 895 | atmel,reset-type = "all"; |
896 | atmel,dbg-halt; | 896 | atmel,dbg-halt; |
897 | atmel,idle-halt; | ||
898 | status = "disabled"; | 897 | status = "disabled"; |
899 | }; | 898 | }; |
900 | 899 | ||
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 818dabdd8c0e..d221179d0f1a 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi | |||
@@ -1066,7 +1066,7 @@ | |||
1066 | reg = <0x00500000 0x80000 | 1066 | reg = <0x00500000 0x80000 |
1067 | 0xf803c000 0x400>; | 1067 | 0xf803c000 0x400>; |
1068 | interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>; | 1068 | interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>; |
1069 | clocks = <&usb>, <&udphs_clk>; | 1069 | clocks = <&utmi>, <&udphs_clk>; |
1070 | clock-names = "hclk", "pclk"; | 1070 | clock-names = "hclk", "pclk"; |
1071 | status = "disabled"; | 1071 | status = "disabled"; |
1072 | 1072 | ||
@@ -1130,7 +1130,6 @@ | |||
1130 | atmel,watchdog-type = "hardware"; | 1130 | atmel,watchdog-type = "hardware"; |
1131 | atmel,reset-type = "all"; | 1131 | atmel,reset-type = "all"; |
1132 | atmel,dbg-halt; | 1132 | atmel,dbg-halt; |
1133 | atmel,idle-halt; | ||
1134 | status = "disabled"; | 1133 | status = "disabled"; |
1135 | }; | 1134 | }; |
1136 | 1135 | ||
@@ -1186,7 +1185,7 @@ | |||
1186 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; | 1185 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; |
1187 | reg = <0x00700000 0x100000>; | 1186 | reg = <0x00700000 0x100000>; |
1188 | interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; | 1187 | interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; |
1189 | clocks = <&usb>, <&uhphs_clk>, <&uhpck>; | 1188 | clocks = <&utmi>, <&uhphs_clk>, <&uhpck>; |
1190 | clock-names = "usb_clk", "ehci_clk", "uhpck"; | 1189 | clock-names = "usb_clk", "ehci_clk", "uhpck"; |
1191 | status = "disabled"; | 1190 | status = "disabled"; |
1192 | }; | 1191 | }; |
diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts index 857d0289ad4d..afe678f6d2e9 100644 --- a/arch/arm/boot/dts/dm8168-evm.dts +++ b/arch/arm/boot/dts/dm8168-evm.dts | |||
@@ -35,6 +35,32 @@ | |||
35 | DM816X_IOPAD(0x0aac, PIN_INPUT | MUX_MODE0) /* SPI_D1 */ | 35 | DM816X_IOPAD(0x0aac, PIN_INPUT | MUX_MODE0) /* SPI_D1 */ |
36 | >; | 36 | >; |
37 | }; | 37 | }; |
38 | |||
39 | mmc_pins: pinmux_mmc_pins { | ||
40 | pinctrl-single,pins = < | ||
41 | DM816X_IOPAD(0x0a70, MUX_MODE0) /* SD_POW */ | ||
42 | DM816X_IOPAD(0x0a74, MUX_MODE0) /* SD_CLK */ | ||
43 | DM816X_IOPAD(0x0a78, MUX_MODE0) /* SD_CMD */ | ||
44 | DM816X_IOPAD(0x0a7C, MUX_MODE0) /* SD_DAT0 */ | ||
45 | DM816X_IOPAD(0x0a80, MUX_MODE0) /* SD_DAT1 */ | ||
46 | DM816X_IOPAD(0x0a84, MUX_MODE0) /* SD_DAT2 */ | ||
47 | DM816X_IOPAD(0x0a88, MUX_MODE0) /* SD_DAT2 */ | ||
48 | DM816X_IOPAD(0x0a8c, MUX_MODE2) /* GP1[7] */ | ||
49 | DM816X_IOPAD(0x0a90, MUX_MODE2) /* GP1[8] */ | ||
50 | >; | ||
51 | }; | ||
52 | |||
53 | usb0_pins: pinmux_usb0_pins { | ||
54 | pinctrl-single,pins = < | ||
55 | DM816X_IOPAD(0x0d00, MUX_MODE0) /* USB0_DRVVBUS */ | ||
56 | >; | ||
57 | }; | ||
58 | |||
59 | usb1_pins: pinmux_usb0_pins { | ||
60 | pinctrl-single,pins = < | ||
61 | DM816X_IOPAD(0x0d04, MUX_MODE0) /* USB1_DRVVBUS */ | ||
62 | >; | ||
63 | }; | ||
38 | }; | 64 | }; |
39 | 65 | ||
40 | &i2c1 { | 66 | &i2c1 { |
@@ -125,5 +151,23 @@ | |||
125 | }; | 151 | }; |
126 | 152 | ||
127 | &mmc1 { | 153 | &mmc1 { |
154 | pinctrl-names = "default"; | ||
155 | pinctrl-0 = <&mmc_pins>; | ||
128 | vmmc-supply = <&vmmcsd_fixed>; | 156 | vmmc-supply = <&vmmcsd_fixed>; |
157 | bus-width = <4>; | ||
158 | cd-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; | ||
159 | wp-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; | ||
160 | }; | ||
161 | |||
162 | /* At least dm8168-evm rev c won't support multipoint, later may */ | ||
163 | &usb0 { | ||
164 | pinctrl-names = "default"; | ||
165 | pinctrl-0 = <&usb0_pins>; | ||
166 | mentor,multipoint = <0>; | ||
167 | }; | ||
168 | |||
169 | &usb1 { | ||
170 | pinctrl-names = "default"; | ||
171 | pinctrl-0 = <&usb1_pins>; | ||
172 | mentor,multipoint = <0>; | ||
129 | }; | 173 | }; |
diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi index d98d0f7de380..f35715bc6992 100644 --- a/arch/arm/boot/dts/dm816x.dtsi +++ b/arch/arm/boot/dts/dm816x.dtsi | |||
@@ -97,10 +97,31 @@ | |||
97 | 97 | ||
98 | /* Device Configuration Registers */ | 98 | /* Device Configuration Registers */ |
99 | scm_conf: syscon@600 { | 99 | scm_conf: syscon@600 { |
100 | compatible = "syscon"; | 100 | compatible = "syscon", "simple-bus"; |
101 | reg = <0x600 0x110>; | 101 | reg = <0x600 0x110>; |
102 | #address-cells = <1>; | 102 | #address-cells = <1>; |
103 | #size-cells = <1>; | 103 | #size-cells = <1>; |
104 | ranges = <0 0x600 0x110>; | ||
105 | |||
106 | usb_phy0: usb-phy@20 { | ||
107 | compatible = "ti,dm8168-usb-phy"; | ||
108 | reg = <0x20 0x8>; | ||
109 | reg-names = "phy"; | ||
110 | clocks = <&main_fapll 6>; | ||
111 | clock-names = "refclk"; | ||
112 | #phy-cells = <0>; | ||
113 | syscon = <&scm_conf>; | ||
114 | }; | ||
115 | |||
116 | usb_phy1: usb-phy@28 { | ||
117 | compatible = "ti,dm8168-usb-phy"; | ||
118 | reg = <0x28 0x8>; | ||
119 | reg-names = "phy"; | ||
120 | clocks = <&main_fapll 6>; | ||
121 | clock-names = "refclk"; | ||
122 | #phy-cells = <0>; | ||
123 | syscon = <&scm_conf>; | ||
124 | }; | ||
104 | }; | 125 | }; |
105 | 126 | ||
106 | scrm_clocks: clocks { | 127 | scrm_clocks: clocks { |
@@ -129,17 +150,27 @@ | |||
129 | }; | 150 | }; |
130 | 151 | ||
131 | gpio1: gpio@48032000 { | 152 | gpio1: gpio@48032000 { |
132 | compatible = "ti,omap3-gpio"; | 153 | compatible = "ti,omap4-gpio"; |
133 | ti,hwmods = "gpio1"; | 154 | ti,hwmods = "gpio1"; |
155 | ti,gpio-always-on; | ||
134 | reg = <0x48032000 0x1000>; | 156 | reg = <0x48032000 0x1000>; |
135 | interrupts = <97>; | 157 | interrupts = <96>; |
158 | gpio-controller; | ||
159 | #gpio-cells = <2>; | ||
160 | interrupt-controller; | ||
161 | #interrupt-cells = <2>; | ||
136 | }; | 162 | }; |
137 | 163 | ||
138 | gpio2: gpio@4804c000 { | 164 | gpio2: gpio@4804c000 { |
139 | compatible = "ti,omap3-gpio"; | 165 | compatible = "ti,omap4-gpio"; |
140 | ti,hwmods = "gpio2"; | 166 | ti,hwmods = "gpio2"; |
167 | ti,gpio-always-on; | ||
141 | reg = <0x4804c000 0x1000>; | 168 | reg = <0x4804c000 0x1000>; |
142 | interrupts = <99>; | 169 | interrupts = <98>; |
170 | gpio-controller; | ||
171 | #gpio-cells = <2>; | ||
172 | interrupt-controller; | ||
173 | #interrupt-cells = <2>; | ||
143 | }; | 174 | }; |
144 | 175 | ||
145 | gpmc: gpmc@50000000 { | 176 | gpmc: gpmc@50000000 { |
@@ -357,7 +388,10 @@ | |||
357 | reg-names = "mc", "control"; | 388 | reg-names = "mc", "control"; |
358 | interrupts = <18>; | 389 | interrupts = <18>; |
359 | interrupt-names = "mc"; | 390 | interrupt-names = "mc"; |
360 | dr_mode = "otg"; | 391 | dr_mode = "host"; |
392 | interface-type = <0>; | ||
393 | phys = <&usb_phy0>; | ||
394 | phy-names = "usb2-phy"; | ||
361 | mentor,multipoint = <1>; | 395 | mentor,multipoint = <1>; |
362 | mentor,num-eps = <16>; | 396 | mentor,num-eps = <16>; |
363 | mentor,ram-bits = <12>; | 397 | mentor,ram-bits = <12>; |
@@ -366,13 +400,15 @@ | |||
366 | 400 | ||
367 | usb1: usb@47401800 { | 401 | usb1: usb@47401800 { |
368 | compatible = "ti,musb-am33xx"; | 402 | compatible = "ti,musb-am33xx"; |
369 | status = "disabled"; | ||
370 | reg = <0x47401c00 0x400 | 403 | reg = <0x47401c00 0x400 |
371 | 0x47401800 0x200>; | 404 | 0x47401800 0x200>; |
372 | reg-names = "mc", "control"; | 405 | reg-names = "mc", "control"; |
373 | interrupts = <19>; | 406 | interrupts = <19>; |
374 | interrupt-names = "mc"; | 407 | interrupt-names = "mc"; |
375 | dr_mode = "otg"; | 408 | dr_mode = "host"; |
409 | interface-type = <0>; | ||
410 | phys = <&usb_phy1>; | ||
411 | phy-names = "usb2-phy"; | ||
376 | mentor,multipoint = <1>; | 412 | mentor,multipoint = <1>; |
377 | mentor,num-eps = <16>; | 413 | mentor,num-eps = <16>; |
378 | mentor,ram-bits = <12>; | 414 | mentor,ram-bits = <12>; |
diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index 746cddb1b8f5..7563d7ce01bb 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts | |||
@@ -263,17 +263,15 @@ | |||
263 | 263 | ||
264 | dcan1_pins_default: dcan1_pins_default { | 264 | dcan1_pins_default: dcan1_pins_default { |
265 | pinctrl-single,pins = < | 265 | pinctrl-single,pins = < |
266 | 0x3d0 (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */ | 266 | 0x3d0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */ |
267 | 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ | 267 | 0x418 (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */ |
268 | 0x418 (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */ | ||
269 | >; | 268 | >; |
270 | }; | 269 | }; |
271 | 270 | ||
272 | dcan1_pins_sleep: dcan1_pins_sleep { | 271 | dcan1_pins_sleep: dcan1_pins_sleep { |
273 | pinctrl-single,pins = < | 272 | pinctrl-single,pins = < |
274 | 0x3d0 (MUX_MODE15) /* dcan1_tx.off */ | 273 | 0x3d0 (MUX_MODE15 | PULL_UP) /* dcan1_tx.off */ |
275 | 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ | 274 | 0x418 (MUX_MODE15 | PULL_UP) /* wakeup0.off */ |
276 | 0x418 (MUX_MODE15) /* wakeup0.off */ | ||
277 | >; | 275 | >; |
278 | }; | 276 | }; |
279 | }; | 277 | }; |
@@ -543,14 +541,6 @@ | |||
543 | }; | 541 | }; |
544 | }; | 542 | }; |
545 | 543 | ||
546 | &omap_dwc3_1 { | ||
547 | extcon = <&extcon_usb1>; | ||
548 | }; | ||
549 | |||
550 | &omap_dwc3_2 { | ||
551 | extcon = <&extcon_usb2>; | ||
552 | }; | ||
553 | |||
554 | &usb1 { | 544 | &usb1 { |
555 | dr_mode = "peripheral"; | 545 | dr_mode = "peripheral"; |
556 | pinctrl-names = "default"; | 546 | pinctrl-names = "default"; |
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 5827fedafd43..c4659a979c41 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi | |||
@@ -249,8 +249,8 @@ | |||
249 | <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, | 249 | <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, |
250 | <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; | 250 | <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; |
251 | #dma-cells = <1>; | 251 | #dma-cells = <1>; |
252 | #dma-channels = <32>; | 252 | dma-channels = <32>; |
253 | #dma-requests = <127>; | 253 | dma-requests = <127>; |
254 | }; | 254 | }; |
255 | 255 | ||
256 | gpio1: gpio@4ae10000 { | 256 | gpio1: gpio@4ae10000 { |
@@ -1090,8 +1090,8 @@ | |||
1090 | <0x4A096800 0x40>; /* pll_ctrl */ | 1090 | <0x4A096800 0x40>; /* pll_ctrl */ |
1091 | reg-names = "phy_rx", "phy_tx", "pll_ctrl"; | 1091 | reg-names = "phy_rx", "phy_tx", "pll_ctrl"; |
1092 | ctrl-module = <&omap_control_sata>; | 1092 | ctrl-module = <&omap_control_sata>; |
1093 | clocks = <&sys_clkin1>; | 1093 | clocks = <&sys_clkin1>, <&sata_ref_clk>; |
1094 | clock-names = "sysclk"; | 1094 | clock-names = "sysclk", "refclk"; |
1095 | #phy-cells = <0>; | 1095 | #phy-cells = <0>; |
1096 | }; | 1096 | }; |
1097 | 1097 | ||
@@ -1111,7 +1111,6 @@ | |||
1111 | "wkupclk", "refclk", | 1111 | "wkupclk", "refclk", |
1112 | "div-clk", "phy-div"; | 1112 | "div-clk", "phy-div"; |
1113 | #phy-cells = <0>; | 1113 | #phy-cells = <0>; |
1114 | ti,hwmods = "pcie1-phy"; | ||
1115 | }; | 1114 | }; |
1116 | 1115 | ||
1117 | pcie2_phy: pciephy@4a095000 { | 1116 | pcie2_phy: pciephy@4a095000 { |
@@ -1130,7 +1129,6 @@ | |||
1130 | "wkupclk", "refclk", | 1129 | "wkupclk", "refclk", |
1131 | "div-clk", "phy-div"; | 1130 | "div-clk", "phy-div"; |
1132 | #phy-cells = <0>; | 1131 | #phy-cells = <0>; |
1133 | ti,hwmods = "pcie2-phy"; | ||
1134 | status = "disabled"; | 1132 | status = "disabled"; |
1135 | }; | 1133 | }; |
1136 | }; | 1134 | }; |
diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index 4d8711713610..40ed539ce474 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts | |||
@@ -119,17 +119,15 @@ | |||
119 | 119 | ||
120 | dcan1_pins_default: dcan1_pins_default { | 120 | dcan1_pins_default: dcan1_pins_default { |
121 | pinctrl-single,pins = < | 121 | pinctrl-single,pins = < |
122 | 0x3d0 (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */ | 122 | 0x3d0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */ |
123 | 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ | 123 | 0x418 (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */ |
124 | 0x418 (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */ | ||
125 | >; | 124 | >; |
126 | }; | 125 | }; |
127 | 126 | ||
128 | dcan1_pins_sleep: dcan1_pins_sleep { | 127 | dcan1_pins_sleep: dcan1_pins_sleep { |
129 | pinctrl-single,pins = < | 128 | pinctrl-single,pins = < |
130 | 0x3d0 (MUX_MODE15) /* dcan1_tx.off */ | 129 | 0x3d0 (MUX_MODE15 | PULL_UP) /* dcan1_tx.off */ |
131 | 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ | 130 | 0x418 (MUX_MODE15 | PULL_UP) /* wakeup0.off */ |
132 | 0x418 (MUX_MODE15) /* wakeup0.off */ | ||
133 | >; | 131 | >; |
134 | }; | 132 | }; |
135 | 133 | ||
@@ -380,14 +378,6 @@ | |||
380 | phy-supply = <&ldo4_reg>; | 378 | phy-supply = <&ldo4_reg>; |
381 | }; | 379 | }; |
382 | 380 | ||
383 | &omap_dwc3_1 { | ||
384 | extcon = <&extcon_usb1>; | ||
385 | }; | ||
386 | |||
387 | &omap_dwc3_2 { | ||
388 | extcon = <&extcon_usb2>; | ||
389 | }; | ||
390 | |||
391 | &usb1 { | 381 | &usb1 { |
392 | dr_mode = "peripheral"; | 382 | dr_mode = "peripheral"; |
393 | pinctrl-names = "default"; | 383 | pinctrl-names = "default"; |
diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index 4bdcbd61ce47..99b09a44e269 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi | |||
@@ -243,10 +243,18 @@ | |||
243 | ti,invert-autoidle-bit; | 243 | ti,invert-autoidle-bit; |
244 | }; | 244 | }; |
245 | 245 | ||
246 | dpll_core_byp_mux: dpll_core_byp_mux { | ||
247 | #clock-cells = <0>; | ||
248 | compatible = "ti,mux-clock"; | ||
249 | clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | ||
250 | ti,bit-shift = <23>; | ||
251 | reg = <0x012c>; | ||
252 | }; | ||
253 | |||
246 | dpll_core_ck: dpll_core_ck { | 254 | dpll_core_ck: dpll_core_ck { |
247 | #clock-cells = <0>; | 255 | #clock-cells = <0>; |
248 | compatible = "ti,omap4-dpll-core-clock"; | 256 | compatible = "ti,omap4-dpll-core-clock"; |
249 | clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | 257 | clocks = <&sys_clkin1>, <&dpll_core_byp_mux>; |
250 | reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>; | 258 | reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>; |
251 | }; | 259 | }; |
252 | 260 | ||
@@ -309,10 +317,18 @@ | |||
309 | clock-div = <1>; | 317 | clock-div = <1>; |
310 | }; | 318 | }; |
311 | 319 | ||
320 | dpll_dsp_byp_mux: dpll_dsp_byp_mux { | ||
321 | #clock-cells = <0>; | ||
322 | compatible = "ti,mux-clock"; | ||
323 | clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; | ||
324 | ti,bit-shift = <23>; | ||
325 | reg = <0x0240>; | ||
326 | }; | ||
327 | |||
312 | dpll_dsp_ck: dpll_dsp_ck { | 328 | dpll_dsp_ck: dpll_dsp_ck { |
313 | #clock-cells = <0>; | 329 | #clock-cells = <0>; |
314 | compatible = "ti,omap4-dpll-clock"; | 330 | compatible = "ti,omap4-dpll-clock"; |
315 | clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; | 331 | clocks = <&sys_clkin1>, <&dpll_dsp_byp_mux>; |
316 | reg = <0x0234>, <0x0238>, <0x0240>, <0x023c>; | 332 | reg = <0x0234>, <0x0238>, <0x0240>, <0x023c>; |
317 | }; | 333 | }; |
318 | 334 | ||
@@ -335,10 +351,18 @@ | |||
335 | clock-div = <1>; | 351 | clock-div = <1>; |
336 | }; | 352 | }; |
337 | 353 | ||
354 | dpll_iva_byp_mux: dpll_iva_byp_mux { | ||
355 | #clock-cells = <0>; | ||
356 | compatible = "ti,mux-clock"; | ||
357 | clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; | ||
358 | ti,bit-shift = <23>; | ||
359 | reg = <0x01ac>; | ||
360 | }; | ||
361 | |||
338 | dpll_iva_ck: dpll_iva_ck { | 362 | dpll_iva_ck: dpll_iva_ck { |
339 | #clock-cells = <0>; | 363 | #clock-cells = <0>; |
340 | compatible = "ti,omap4-dpll-clock"; | 364 | compatible = "ti,omap4-dpll-clock"; |
341 | clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; | 365 | clocks = <&sys_clkin1>, <&dpll_iva_byp_mux>; |
342 | reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; | 366 | reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; |
343 | }; | 367 | }; |
344 | 368 | ||
@@ -361,10 +385,18 @@ | |||
361 | clock-div = <1>; | 385 | clock-div = <1>; |
362 | }; | 386 | }; |
363 | 387 | ||
388 | dpll_gpu_byp_mux: dpll_gpu_byp_mux { | ||
389 | #clock-cells = <0>; | ||
390 | compatible = "ti,mux-clock"; | ||
391 | clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | ||
392 | ti,bit-shift = <23>; | ||
393 | reg = <0x02e4>; | ||
394 | }; | ||
395 | |||
364 | dpll_gpu_ck: dpll_gpu_ck { | 396 | dpll_gpu_ck: dpll_gpu_ck { |
365 | #clock-cells = <0>; | 397 | #clock-cells = <0>; |
366 | compatible = "ti,omap4-dpll-clock"; | 398 | compatible = "ti,omap4-dpll-clock"; |
367 | clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | 399 | clocks = <&sys_clkin1>, <&dpll_gpu_byp_mux>; |
368 | reg = <0x02d8>, <0x02dc>, <0x02e4>, <0x02e0>; | 400 | reg = <0x02d8>, <0x02dc>, <0x02e4>, <0x02e0>; |
369 | }; | 401 | }; |
370 | 402 | ||
@@ -398,10 +430,18 @@ | |||
398 | clock-div = <1>; | 430 | clock-div = <1>; |
399 | }; | 431 | }; |
400 | 432 | ||
433 | dpll_ddr_byp_mux: dpll_ddr_byp_mux { | ||
434 | #clock-cells = <0>; | ||
435 | compatible = "ti,mux-clock"; | ||
436 | clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | ||
437 | ti,bit-shift = <23>; | ||
438 | reg = <0x021c>; | ||
439 | }; | ||
440 | |||
401 | dpll_ddr_ck: dpll_ddr_ck { | 441 | dpll_ddr_ck: dpll_ddr_ck { |
402 | #clock-cells = <0>; | 442 | #clock-cells = <0>; |
403 | compatible = "ti,omap4-dpll-clock"; | 443 | compatible = "ti,omap4-dpll-clock"; |
404 | clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | 444 | clocks = <&sys_clkin1>, <&dpll_ddr_byp_mux>; |
405 | reg = <0x0210>, <0x0214>, <0x021c>, <0x0218>; | 445 | reg = <0x0210>, <0x0214>, <0x021c>, <0x0218>; |
406 | }; | 446 | }; |
407 | 447 | ||
@@ -416,10 +456,18 @@ | |||
416 | ti,invert-autoidle-bit; | 456 | ti,invert-autoidle-bit; |
417 | }; | 457 | }; |
418 | 458 | ||
459 | dpll_gmac_byp_mux: dpll_gmac_byp_mux { | ||
460 | #clock-cells = <0>; | ||
461 | compatible = "ti,mux-clock"; | ||
462 | clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | ||
463 | ti,bit-shift = <23>; | ||
464 | reg = <0x02b4>; | ||
465 | }; | ||
466 | |||
419 | dpll_gmac_ck: dpll_gmac_ck { | 467 | dpll_gmac_ck: dpll_gmac_ck { |
420 | #clock-cells = <0>; | 468 | #clock-cells = <0>; |
421 | compatible = "ti,omap4-dpll-clock"; | 469 | compatible = "ti,omap4-dpll-clock"; |
422 | clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | 470 | clocks = <&sys_clkin1>, <&dpll_gmac_byp_mux>; |
423 | reg = <0x02a8>, <0x02ac>, <0x02b4>, <0x02b0>; | 471 | reg = <0x02a8>, <0x02ac>, <0x02b4>, <0x02b0>; |
424 | }; | 472 | }; |
425 | 473 | ||
@@ -482,10 +530,18 @@ | |||
482 | clock-div = <1>; | 530 | clock-div = <1>; |
483 | }; | 531 | }; |
484 | 532 | ||
533 | dpll_eve_byp_mux: dpll_eve_byp_mux { | ||
534 | #clock-cells = <0>; | ||
535 | compatible = "ti,mux-clock"; | ||
536 | clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; | ||
537 | ti,bit-shift = <23>; | ||
538 | reg = <0x0290>; | ||
539 | }; | ||
540 | |||
485 | dpll_eve_ck: dpll_eve_ck { | 541 | dpll_eve_ck: dpll_eve_ck { |
486 | #clock-cells = <0>; | 542 | #clock-cells = <0>; |
487 | compatible = "ti,omap4-dpll-clock"; | 543 | compatible = "ti,omap4-dpll-clock"; |
488 | clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; | 544 | clocks = <&sys_clkin1>, <&dpll_eve_byp_mux>; |
489 | reg = <0x0284>, <0x0288>, <0x0290>, <0x028c>; | 545 | reg = <0x0284>, <0x0288>, <0x0290>, <0x028c>; |
490 | }; | 546 | }; |
491 | 547 | ||
@@ -1249,10 +1305,18 @@ | |||
1249 | clock-div = <1>; | 1305 | clock-div = <1>; |
1250 | }; | 1306 | }; |
1251 | 1307 | ||
1308 | dpll_per_byp_mux: dpll_per_byp_mux { | ||
1309 | #clock-cells = <0>; | ||
1310 | compatible = "ti,mux-clock"; | ||
1311 | clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; | ||
1312 | ti,bit-shift = <23>; | ||
1313 | reg = <0x014c>; | ||
1314 | }; | ||
1315 | |||
1252 | dpll_per_ck: dpll_per_ck { | 1316 | dpll_per_ck: dpll_per_ck { |
1253 | #clock-cells = <0>; | 1317 | #clock-cells = <0>; |
1254 | compatible = "ti,omap4-dpll-clock"; | 1318 | compatible = "ti,omap4-dpll-clock"; |
1255 | clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; | 1319 | clocks = <&sys_clkin1>, <&dpll_per_byp_mux>; |
1256 | reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>; | 1320 | reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>; |
1257 | }; | 1321 | }; |
1258 | 1322 | ||
@@ -1275,10 +1339,18 @@ | |||
1275 | clock-div = <1>; | 1339 | clock-div = <1>; |
1276 | }; | 1340 | }; |
1277 | 1341 | ||
1342 | dpll_usb_byp_mux: dpll_usb_byp_mux { | ||
1343 | #clock-cells = <0>; | ||
1344 | compatible = "ti,mux-clock"; | ||
1345 | clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; | ||
1346 | ti,bit-shift = <23>; | ||
1347 | reg = <0x018c>; | ||
1348 | }; | ||
1349 | |||
1278 | dpll_usb_ck: dpll_usb_ck { | 1350 | dpll_usb_ck: dpll_usb_ck { |
1279 | #clock-cells = <0>; | 1351 | #clock-cells = <0>; |
1280 | compatible = "ti,omap4-dpll-j-type-clock"; | 1352 | compatible = "ti,omap4-dpll-j-type-clock"; |
1281 | clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; | 1353 | clocks = <&sys_clkin1>, <&dpll_usb_byp_mux>; |
1282 | reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>; | 1354 | reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>; |
1283 | }; | 1355 | }; |
1284 | 1356 | ||
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index 277b48b0b6f9..ac6b0ae42caf 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include "skeleton.dtsi" | 20 | #include "skeleton.dtsi" |
21 | #include "exynos4-cpu-thermal.dtsi" | ||
21 | #include <dt-bindings/clock/exynos3250.h> | 22 | #include <dt-bindings/clock/exynos3250.h> |
22 | 23 | ||
23 | / { | 24 | / { |
@@ -193,6 +194,7 @@ | |||
193 | interrupts = <0 216 0>; | 194 | interrupts = <0 216 0>; |
194 | clocks = <&cmu CLK_TMU_APBIF>; | 195 | clocks = <&cmu CLK_TMU_APBIF>; |
195 | clock-names = "tmu_apbif"; | 196 | clock-names = "tmu_apbif"; |
197 | #include "exynos4412-tmu-sensor-conf.dtsi" | ||
196 | status = "disabled"; | 198 | status = "disabled"; |
197 | }; | 199 | }; |
198 | 200 | ||
diff --git a/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi b/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi new file mode 100644 index 000000000000..735cb2f10817 --- /dev/null +++ b/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * Device tree sources for Exynos4 thermal zone | ||
3 | * | ||
4 | * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <dt-bindings/thermal/thermal.h> | ||
13 | |||
14 | / { | ||
15 | thermal-zones { | ||
16 | cpu_thermal: cpu-thermal { | ||
17 | thermal-sensors = <&tmu 0>; | ||
18 | polling-delay-passive = <0>; | ||
19 | polling-delay = <0>; | ||
20 | trips { | ||
21 | cpu_alert0: cpu-alert-0 { | ||
22 | temperature = <70000>; /* millicelsius */ | ||
23 | hysteresis = <10000>; /* millicelsius */ | ||
24 | type = "active"; | ||
25 | }; | ||
26 | cpu_alert1: cpu-alert-1 { | ||
27 | temperature = <95000>; /* millicelsius */ | ||
28 | hysteresis = <10000>; /* millicelsius */ | ||
29 | type = "active"; | ||
30 | }; | ||
31 | cpu_alert2: cpu-alert-2 { | ||
32 | temperature = <110000>; /* millicelsius */ | ||
33 | hysteresis = <10000>; /* millicelsius */ | ||
34 | type = "active"; | ||
35 | }; | ||
36 | cpu_crit0: cpu-crit-0 { | ||
37 | temperature = <120000>; /* millicelsius */ | ||
38 | hysteresis = <0>; /* millicelsius */ | ||
39 | type = "critical"; | ||
40 | }; | ||
41 | }; | ||
42 | cooling-maps { | ||
43 | map0 { | ||
44 | trip = <&cpu_alert0>; | ||
45 | }; | ||
46 | map1 { | ||
47 | trip = <&cpu_alert1>; | ||
48 | }; | ||
49 | }; | ||
50 | }; | ||
51 | }; | ||
52 | }; | ||
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index 76173cacd450..77ea547768f4 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi | |||
@@ -38,6 +38,7 @@ | |||
38 | i2c5 = &i2c_5; | 38 | i2c5 = &i2c_5; |
39 | i2c6 = &i2c_6; | 39 | i2c6 = &i2c_6; |
40 | i2c7 = &i2c_7; | 40 | i2c7 = &i2c_7; |
41 | i2c8 = &i2c_8; | ||
41 | csis0 = &csis_0; | 42 | csis0 = &csis_0; |
42 | csis1 = &csis_1; | 43 | csis1 = &csis_1; |
43 | fimc0 = &fimc_0; | 44 | fimc0 = &fimc_0; |
@@ -104,6 +105,7 @@ | |||
104 | compatible = "samsung,exynos4210-pd"; | 105 | compatible = "samsung,exynos4210-pd"; |
105 | reg = <0x10023C20 0x20>; | 106 | reg = <0x10023C20 0x20>; |
106 | #power-domain-cells = <0>; | 107 | #power-domain-cells = <0>; |
108 | power-domains = <&pd_lcd0>; | ||
107 | }; | 109 | }; |
108 | 110 | ||
109 | pd_cam: cam-power-domain@10023C00 { | 111 | pd_cam: cam-power-domain@10023C00 { |
@@ -554,6 +556,22 @@ | |||
554 | status = "disabled"; | 556 | status = "disabled"; |
555 | }; | 557 | }; |
556 | 558 | ||
559 | i2c_8: i2c@138E0000 { | ||
560 | #address-cells = <1>; | ||
561 | #size-cells = <0>; | ||
562 | compatible = "samsung,s3c2440-hdmiphy-i2c"; | ||
563 | reg = <0x138E0000 0x100>; | ||
564 | interrupts = <0 93 0>; | ||
565 | clocks = <&clock CLK_I2C_HDMI>; | ||
566 | clock-names = "i2c"; | ||
567 | status = "disabled"; | ||
568 | |||
569 | hdmi_i2c_phy: hdmiphy@38 { | ||
570 | compatible = "exynos4210-hdmiphy"; | ||
571 | reg = <0x38>; | ||
572 | }; | ||
573 | }; | ||
574 | |||
557 | spi_0: spi@13920000 { | 575 | spi_0: spi@13920000 { |
558 | compatible = "samsung,exynos4210-spi"; | 576 | compatible = "samsung,exynos4210-spi"; |
559 | reg = <0x13920000 0x100>; | 577 | reg = <0x13920000 0x100>; |
@@ -663,6 +681,33 @@ | |||
663 | status = "disabled"; | 681 | status = "disabled"; |
664 | }; | 682 | }; |
665 | 683 | ||
684 | tmu: tmu@100C0000 { | ||
685 | #include "exynos4412-tmu-sensor-conf.dtsi" | ||
686 | }; | ||
687 | |||
688 | hdmi: hdmi@12D00000 { | ||
689 | compatible = "samsung,exynos4210-hdmi"; | ||
690 | reg = <0x12D00000 0x70000>; | ||
691 | interrupts = <0 92 0>; | ||
692 | clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy", | ||
693 | "mout_hdmi"; | ||
694 | clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>, | ||
695 | <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>, | ||
696 | <&clock CLK_MOUT_HDMI>; | ||
697 | phy = <&hdmi_i2c_phy>; | ||
698 | power-domains = <&pd_tv>; | ||
699 | samsung,syscon-phandle = <&pmu_system_controller>; | ||
700 | status = "disabled"; | ||
701 | }; | ||
702 | |||
703 | mixer: mixer@12C10000 { | ||
704 | compatible = "samsung,exynos4210-mixer"; | ||
705 | interrupts = <0 91 0>; | ||
706 | reg = <0x12C10000 0x2100>, <0x12c00000 0x300>; | ||
707 | power-domains = <&pd_tv>; | ||
708 | status = "disabled"; | ||
709 | }; | ||
710 | |||
666 | ppmu_dmc0: ppmu_dmc0@106a0000 { | 711 | ppmu_dmc0: ppmu_dmc0@106a0000 { |
667 | compatible = "samsung,exynos-ppmu"; | 712 | compatible = "samsung,exynos-ppmu"; |
668 | reg = <0x106a0000 0x2000>; | 713 | reg = <0x106a0000 0x2000>; |
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts index 3d6652a4b6cb..32c5fd8f6269 100644 --- a/arch/arm/boot/dts/exynos4210-trats.dts +++ b/arch/arm/boot/dts/exynos4210-trats.dts | |||
@@ -426,6 +426,25 @@ | |||
426 | status = "okay"; | 426 | status = "okay"; |
427 | }; | 427 | }; |
428 | 428 | ||
429 | tmu@100C0000 { | ||
430 | status = "okay"; | ||
431 | }; | ||
432 | |||
433 | thermal-zones { | ||
434 | cpu_thermal: cpu-thermal { | ||
435 | cooling-maps { | ||
436 | map0 { | ||
437 | /* Corresponds to 800MHz at freq_table */ | ||
438 | cooling-device = <&cpu0 2 2>; | ||
439 | }; | ||
440 | map1 { | ||
441 | /* Corresponds to 200MHz at freq_table */ | ||
442 | cooling-device = <&cpu0 4 4>; | ||
443 | }; | ||
444 | }; | ||
445 | }; | ||
446 | }; | ||
447 | |||
429 | camera { | 448 | camera { |
430 | pinctrl-names = "default"; | 449 | pinctrl-names = "default"; |
431 | pinctrl-0 = <>; | 450 | pinctrl-0 = <>; |
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts index b57e6b82ea20..d4f2b11319dd 100644 --- a/arch/arm/boot/dts/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts | |||
@@ -505,6 +505,63 @@ | |||
505 | assigned-clock-rates = <0>, <160000000>; | 505 | assigned-clock-rates = <0>, <160000000>; |
506 | }; | 506 | }; |
507 | }; | 507 | }; |
508 | |||
509 | hdmi_en: voltage-regulator-hdmi-5v { | ||
510 | compatible = "regulator-fixed"; | ||
511 | regulator-name = "HDMI_5V"; | ||
512 | regulator-min-microvolt = <5000000>; | ||
513 | regulator-max-microvolt = <5000000>; | ||
514 | gpio = <&gpe0 1 0>; | ||
515 | enable-active-high; | ||
516 | }; | ||
517 | |||
518 | hdmi_ddc: i2c-ddc { | ||
519 | compatible = "i2c-gpio"; | ||
520 | gpios = <&gpe4 2 0 &gpe4 3 0>; | ||
521 | i2c-gpio,delay-us = <100>; | ||
522 | #address-cells = <1>; | ||
523 | #size-cells = <0>; | ||
524 | |||
525 | pinctrl-0 = <&i2c_ddc_bus>; | ||
526 | pinctrl-names = "default"; | ||
527 | status = "okay"; | ||
528 | }; | ||
529 | |||
530 | mixer@12C10000 { | ||
531 | status = "okay"; | ||
532 | }; | ||
533 | |||
534 | hdmi@12D00000 { | ||
535 | hpd-gpio = <&gpx3 7 0>; | ||
536 | pinctrl-names = "default"; | ||
537 | pinctrl-0 = <&hdmi_hpd>; | ||
538 | hdmi-en-supply = <&hdmi_en>; | ||
539 | vdd-supply = <&ldo3_reg>; | ||
540 | vdd_osc-supply = <&ldo4_reg>; | ||
541 | vdd_pll-supply = <&ldo3_reg>; | ||
542 | ddc = <&hdmi_ddc>; | ||
543 | status = "okay"; | ||
544 | }; | ||
545 | |||
546 | i2c@138E0000 { | ||
547 | status = "okay"; | ||
548 | }; | ||
549 | }; | ||
550 | |||
551 | &pinctrl_1 { | ||
552 | hdmi_hpd: hdmi-hpd { | ||
553 | samsung,pins = "gpx3-7"; | ||
554 | samsung,pin-pud = <0>; | ||
555 | }; | ||
556 | }; | ||
557 | |||
558 | &pinctrl_0 { | ||
559 | i2c_ddc_bus: i2c-ddc-bus { | ||
560 | samsung,pins = "gpe4-2", "gpe4-3"; | ||
561 | samsung,pin-function = <2>; | ||
562 | samsung,pin-pud = <3>; | ||
563 | samsung,pin-drv = <0>; | ||
564 | }; | ||
508 | }; | 565 | }; |
509 | 566 | ||
510 | &mdma1 { | 567 | &mdma1 { |
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi index 67c832c9dcf1..be89f83f70e7 100644 --- a/arch/arm/boot/dts/exynos4210.dtsi +++ b/arch/arm/boot/dts/exynos4210.dtsi | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include "exynos4.dtsi" | 22 | #include "exynos4.dtsi" |
23 | #include "exynos4210-pinctrl.dtsi" | 23 | #include "exynos4210-pinctrl.dtsi" |
24 | #include "exynos4-cpu-thermal.dtsi" | ||
24 | 25 | ||
25 | / { | 26 | / { |
26 | compatible = "samsung,exynos4210", "samsung,exynos4"; | 27 | compatible = "samsung,exynos4210", "samsung,exynos4"; |
@@ -35,10 +36,13 @@ | |||
35 | #address-cells = <1>; | 36 | #address-cells = <1>; |
36 | #size-cells = <0>; | 37 | #size-cells = <0>; |
37 | 38 | ||
38 | cpu@900 { | 39 | cpu0: cpu@900 { |
39 | device_type = "cpu"; | 40 | device_type = "cpu"; |
40 | compatible = "arm,cortex-a9"; | 41 | compatible = "arm,cortex-a9"; |
41 | reg = <0x900>; | 42 | reg = <0x900>; |
43 | cooling-min-level = <4>; | ||
44 | cooling-max-level = <2>; | ||
45 | #cooling-cells = <2>; /* min followed by max */ | ||
42 | }; | 46 | }; |
43 | 47 | ||
44 | cpu@901 { | 48 | cpu@901 { |
@@ -153,16 +157,38 @@ | |||
153 | reg = <0x03860000 0x1000>; | 157 | reg = <0x03860000 0x1000>; |
154 | }; | 158 | }; |
155 | 159 | ||
156 | tmu@100C0000 { | 160 | tmu: tmu@100C0000 { |
157 | compatible = "samsung,exynos4210-tmu"; | 161 | compatible = "samsung,exynos4210-tmu"; |
158 | interrupt-parent = <&combiner>; | 162 | interrupt-parent = <&combiner>; |
159 | reg = <0x100C0000 0x100>; | 163 | reg = <0x100C0000 0x100>; |
160 | interrupts = <2 4>; | 164 | interrupts = <2 4>; |
161 | clocks = <&clock CLK_TMU_APBIF>; | 165 | clocks = <&clock CLK_TMU_APBIF>; |
162 | clock-names = "tmu_apbif"; | 166 | clock-names = "tmu_apbif"; |
167 | samsung,tmu_gain = <15>; | ||
168 | samsung,tmu_reference_voltage = <7>; | ||
163 | status = "disabled"; | 169 | status = "disabled"; |
164 | }; | 170 | }; |
165 | 171 | ||
172 | thermal-zones { | ||
173 | cpu_thermal: cpu-thermal { | ||
174 | polling-delay-passive = <0>; | ||
175 | polling-delay = <0>; | ||
176 | thermal-sensors = <&tmu 0>; | ||
177 | |||
178 | trips { | ||
179 | cpu_alert0: cpu-alert-0 { | ||
180 | temperature = <85000>; /* millicelsius */ | ||
181 | }; | ||
182 | cpu_alert1: cpu-alert-1 { | ||
183 | temperature = <100000>; /* millicelsius */ | ||
184 | }; | ||
185 | cpu_alert2: cpu-alert-2 { | ||
186 | temperature = <110000>; /* millicelsius */ | ||
187 | }; | ||
188 | }; | ||
189 | }; | ||
190 | }; | ||
191 | |||
166 | g2d@12800000 { | 192 | g2d@12800000 { |
167 | compatible = "samsung,s5pv210-g2d"; | 193 | compatible = "samsung,s5pv210-g2d"; |
168 | reg = <0x12800000 0x1000>; | 194 | reg = <0x12800000 0x1000>; |
@@ -203,6 +229,14 @@ | |||
203 | }; | 229 | }; |
204 | }; | 230 | }; |
205 | 231 | ||
232 | mixer: mixer@12C10000 { | ||
233 | clock-names = "mixer", "hdmi", "sclk_hdmi", "vp", "mout_mixer", | ||
234 | "sclk_mixer"; | ||
235 | clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, | ||
236 | <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>, | ||
237 | <&clock CLK_MOUT_MIXER>, <&clock CLK_SCLK_MIXER>; | ||
238 | }; | ||
239 | |||
206 | ppmu_lcd1: ppmu_lcd1@12240000 { | 240 | ppmu_lcd1: ppmu_lcd1@12240000 { |
207 | compatible = "samsung,exynos-ppmu"; | 241 | compatible = "samsung,exynos-ppmu"; |
208 | reg = <0x12240000 0x2000>; | 242 | reg = <0x12240000 0x2000>; |
diff --git a/arch/arm/boot/dts/exynos4212.dtsi b/arch/arm/boot/dts/exynos4212.dtsi index dd0a43ec56da..5be03288f1ee 100644 --- a/arch/arm/boot/dts/exynos4212.dtsi +++ b/arch/arm/boot/dts/exynos4212.dtsi | |||
@@ -26,10 +26,13 @@ | |||
26 | #address-cells = <1>; | 26 | #address-cells = <1>; |
27 | #size-cells = <0>; | 27 | #size-cells = <0>; |
28 | 28 | ||
29 | cpu@A00 { | 29 | cpu0: cpu@A00 { |
30 | device_type = "cpu"; | 30 | device_type = "cpu"; |
31 | compatible = "arm,cortex-a9"; | 31 | compatible = "arm,cortex-a9"; |
32 | reg = <0xA00>; | 32 | reg = <0xA00>; |
33 | cooling-min-level = <13>; | ||
34 | cooling-max-level = <7>; | ||
35 | #cooling-cells = <2>; /* min followed by max */ | ||
33 | }; | 36 | }; |
34 | 37 | ||
35 | cpu@A01 { | 38 | cpu@A01 { |
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index de80b5bba204..adb4f6a97a1d 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi | |||
@@ -249,6 +249,20 @@ | |||
249 | regulator-always-on; | 249 | regulator-always-on; |
250 | }; | 250 | }; |
251 | 251 | ||
252 | ldo8_reg: ldo@8 { | ||
253 | regulator-compatible = "LDO8"; | ||
254 | regulator-name = "VDD10_HDMI_1.0V"; | ||
255 | regulator-min-microvolt = <1000000>; | ||
256 | regulator-max-microvolt = <1000000>; | ||
257 | }; | ||
258 | |||
259 | ldo10_reg: ldo@10 { | ||
260 | regulator-compatible = "LDO10"; | ||
261 | regulator-name = "VDDQ_MIPIHSI_1.8V"; | ||
262 | regulator-min-microvolt = <1800000>; | ||
263 | regulator-max-microvolt = <1800000>; | ||
264 | }; | ||
265 | |||
252 | ldo11_reg: LDO11 { | 266 | ldo11_reg: LDO11 { |
253 | regulator-name = "VDD18_ABB1_1.8V"; | 267 | regulator-name = "VDD18_ABB1_1.8V"; |
254 | regulator-min-microvolt = <1800000>; | 268 | regulator-min-microvolt = <1800000>; |
@@ -411,6 +425,51 @@ | |||
411 | ehci: ehci@12580000 { | 425 | ehci: ehci@12580000 { |
412 | status = "okay"; | 426 | status = "okay"; |
413 | }; | 427 | }; |
428 | |||
429 | tmu@100C0000 { | ||
430 | vtmu-supply = <&ldo10_reg>; | ||
431 | status = "okay"; | ||
432 | }; | ||
433 | |||
434 | thermal-zones { | ||
435 | cpu_thermal: cpu-thermal { | ||
436 | cooling-maps { | ||
437 | map0 { | ||
438 | /* Corresponds to 800MHz at freq_table */ | ||
439 | cooling-device = <&cpu0 7 7>; | ||
440 | }; | ||
441 | map1 { | ||
442 | /* Corresponds to 200MHz at freq_table */ | ||
443 | cooling-device = <&cpu0 13 13>; | ||
444 | }; | ||
445 | }; | ||
446 | }; | ||
447 | }; | ||
448 | |||
449 | mixer: mixer@12C10000 { | ||
450 | status = "okay"; | ||
451 | }; | ||
452 | |||
453 | hdmi@12D00000 { | ||
454 | hpd-gpio = <&gpx3 7 0>; | ||
455 | pinctrl-names = "default"; | ||
456 | pinctrl-0 = <&hdmi_hpd>; | ||
457 | vdd-supply = <&ldo8_reg>; | ||
458 | vdd_osc-supply = <&ldo10_reg>; | ||
459 | vdd_pll-supply = <&ldo8_reg>; | ||
460 | ddc = <&hdmi_ddc>; | ||
461 | status = "okay"; | ||
462 | }; | ||
463 | |||
464 | hdmi_ddc: i2c@13880000 { | ||
465 | status = "okay"; | ||
466 | pinctrl-names = "default"; | ||
467 | pinctrl-0 = <&i2c2_bus>; | ||
468 | }; | ||
469 | |||
470 | i2c@138E0000 { | ||
471 | status = "okay"; | ||
472 | }; | ||
414 | }; | 473 | }; |
415 | 474 | ||
416 | &pinctrl_1 { | 475 | &pinctrl_1 { |
@@ -425,4 +484,9 @@ | |||
425 | samsung,pin-pud = <0>; | 484 | samsung,pin-pud = <0>; |
426 | samsung,pin-drv = <0>; | 485 | samsung,pin-drv = <0>; |
427 | }; | 486 | }; |
487 | |||
488 | hdmi_hpd: hdmi-hpd { | ||
489 | samsung,pins = "gpx3-7"; | ||
490 | samsung,pin-pud = <1>; | ||
491 | }; | ||
428 | }; | 492 | }; |
diff --git a/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi new file mode 100644 index 000000000000..e3f7934d19d0 --- /dev/null +++ b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Device tree sources for Exynos4412 TMU sensor configuration | ||
3 | * | ||
4 | * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <dt-bindings/thermal/thermal_exynos.h> | ||
13 | |||
14 | #thermal-sensor-cells = <0>; | ||
15 | samsung,tmu_gain = <8>; | ||
16 | samsung,tmu_reference_voltage = <16>; | ||
17 | samsung,tmu_noise_cancel_mode = <4>; | ||
18 | samsung,tmu_efuse_value = <55>; | ||
19 | samsung,tmu_min_efuse_value = <40>; | ||
20 | samsung,tmu_max_efuse_value = <100>; | ||
21 | samsung,tmu_first_point_trim = <25>; | ||
22 | samsung,tmu_second_point_trim = <85>; | ||
23 | samsung,tmu_default_temp_offset = <50>; | ||
24 | samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>; | ||
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 21f748083586..173ffa479ad3 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts | |||
@@ -927,6 +927,21 @@ | |||
927 | pulldown-ohm = <100000>; /* 100K */ | 927 | pulldown-ohm = <100000>; /* 100K */ |
928 | io-channels = <&adc 2>; /* Battery temperature */ | 928 | io-channels = <&adc 2>; /* Battery temperature */ |
929 | }; | 929 | }; |
930 | |||
931 | thermal-zones { | ||
932 | cpu_thermal: cpu-thermal { | ||
933 | cooling-maps { | ||
934 | map0 { | ||
935 | /* Corresponds to 800MHz at freq_table */ | ||
936 | cooling-device = <&cpu0 7 7>; | ||
937 | }; | ||
938 | map1 { | ||
939 | /* Corresponds to 200MHz at freq_table */ | ||
940 | cooling-device = <&cpu0 13 13>; | ||
941 | }; | ||
942 | }; | ||
943 | }; | ||
944 | }; | ||
930 | }; | 945 | }; |
931 | 946 | ||
932 | &pmu_system_controller { | 947 | &pmu_system_controller { |
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi index 0f6ec93bb1d8..68ad43b391ae 100644 --- a/arch/arm/boot/dts/exynos4412.dtsi +++ b/arch/arm/boot/dts/exynos4412.dtsi | |||
@@ -26,10 +26,13 @@ | |||
26 | #address-cells = <1>; | 26 | #address-cells = <1>; |
27 | #size-cells = <0>; | 27 | #size-cells = <0>; |
28 | 28 | ||
29 | cpu@A00 { | 29 | cpu0: cpu@A00 { |
30 | device_type = "cpu"; | 30 | device_type = "cpu"; |
31 | compatible = "arm,cortex-a9"; | 31 | compatible = "arm,cortex-a9"; |
32 | reg = <0xA00>; | 32 | reg = <0xA00>; |
33 | cooling-min-level = <13>; | ||
34 | cooling-max-level = <7>; | ||
35 | #cooling-cells = <2>; /* min followed by max */ | ||
33 | }; | 36 | }; |
34 | 37 | ||
35 | cpu@A01 { | 38 | cpu@A01 { |
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi index f5e0ae780d6c..6a6abe14fd9b 100644 --- a/arch/arm/boot/dts/exynos4x12.dtsi +++ b/arch/arm/boot/dts/exynos4x12.dtsi | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include "exynos4.dtsi" | 20 | #include "exynos4.dtsi" |
21 | #include "exynos4x12-pinctrl.dtsi" | 21 | #include "exynos4x12-pinctrl.dtsi" |
22 | #include "exynos4-cpu-thermal.dtsi" | ||
22 | 23 | ||
23 | / { | 24 | / { |
24 | aliases { | 25 | aliases { |
@@ -297,4 +298,15 @@ | |||
297 | clock-names = "tmu_apbif"; | 298 | clock-names = "tmu_apbif"; |
298 | status = "disabled"; | 299 | status = "disabled"; |
299 | }; | 300 | }; |
301 | |||
302 | hdmi: hdmi@12D00000 { | ||
303 | compatible = "samsung,exynos4212-hdmi"; | ||
304 | }; | ||
305 | |||
306 | mixer: mixer@12C10000 { | ||
307 | compatible = "samsung,exynos4212-mixer"; | ||
308 | clock-names = "mixer", "hdmi", "sclk_hdmi", "vp"; | ||
309 | clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, | ||
310 | <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>; | ||
311 | }; | ||
300 | }; | 312 | }; |
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 9bb1b0b738f5..adbde1adad95 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <dt-bindings/clock/exynos5250.h> | 20 | #include <dt-bindings/clock/exynos5250.h> |
21 | #include "exynos5.dtsi" | 21 | #include "exynos5.dtsi" |
22 | #include "exynos5250-pinctrl.dtsi" | 22 | #include "exynos5250-pinctrl.dtsi" |
23 | 23 | #include "exynos4-cpu-thermal.dtsi" | |
24 | #include <dt-bindings/clock/exynos-audss-clk.h> | 24 | #include <dt-bindings/clock/exynos-audss-clk.h> |
25 | 25 | ||
26 | / { | 26 | / { |
@@ -58,11 +58,14 @@ | |||
58 | #address-cells = <1>; | 58 | #address-cells = <1>; |
59 | #size-cells = <0>; | 59 | #size-cells = <0>; |
60 | 60 | ||
61 | cpu@0 { | 61 | cpu0: cpu@0 { |
62 | device_type = "cpu"; | 62 | device_type = "cpu"; |
63 | compatible = "arm,cortex-a15"; | 63 | compatible = "arm,cortex-a15"; |
64 | reg = <0>; | 64 | reg = <0>; |
65 | clock-frequency = <1700000000>; | 65 | clock-frequency = <1700000000>; |
66 | cooling-min-level = <15>; | ||
67 | cooling-max-level = <9>; | ||
68 | #cooling-cells = <2>; /* min followed by max */ | ||
66 | }; | 69 | }; |
67 | cpu@1 { | 70 | cpu@1 { |
68 | device_type = "cpu"; | 71 | device_type = "cpu"; |
@@ -102,6 +105,12 @@ | |||
102 | #power-domain-cells = <0>; | 105 | #power-domain-cells = <0>; |
103 | }; | 106 | }; |
104 | 107 | ||
108 | pd_disp1: disp1-power-domain@100440A0 { | ||
109 | compatible = "samsung,exynos4210-pd"; | ||
110 | reg = <0x100440A0 0x20>; | ||
111 | #power-domain-cells = <0>; | ||
112 | }; | ||
113 | |||
105 | clock: clock-controller@10010000 { | 114 | clock: clock-controller@10010000 { |
106 | compatible = "samsung,exynos5250-clock"; | 115 | compatible = "samsung,exynos5250-clock"; |
107 | reg = <0x10010000 0x30000>; | 116 | reg = <0x10010000 0x30000>; |
@@ -235,12 +244,32 @@ | |||
235 | status = "disabled"; | 244 | status = "disabled"; |
236 | }; | 245 | }; |
237 | 246 | ||
238 | tmu@10060000 { | 247 | tmu: tmu@10060000 { |
239 | compatible = "samsung,exynos5250-tmu"; | 248 | compatible = "samsung,exynos5250-tmu"; |
240 | reg = <0x10060000 0x100>; | 249 | reg = <0x10060000 0x100>; |
241 | interrupts = <0 65 0>; | 250 | interrupts = <0 65 0>; |
242 | clocks = <&clock CLK_TMU>; | 251 | clocks = <&clock CLK_TMU>; |
243 | clock-names = "tmu_apbif"; | 252 | clock-names = "tmu_apbif"; |
253 | #include "exynos4412-tmu-sensor-conf.dtsi" | ||
254 | }; | ||
255 | |||
256 | thermal-zones { | ||
257 | cpu_thermal: cpu-thermal { | ||
258 | polling-delay-passive = <0>; | ||
259 | polling-delay = <0>; | ||
260 | thermal-sensors = <&tmu 0>; | ||
261 | |||
262 | cooling-maps { | ||
263 | map0 { | ||
264 | /* Corresponds to 800MHz at freq_table */ | ||
265 | cooling-device = <&cpu0 9 9>; | ||
266 | }; | ||
267 | map1 { | ||
268 | /* Corresponds to 200MHz at freq_table */ | ||
269 | cooling-device = <&cpu0 15 15>; | ||
270 | }; | ||
271 | }; | ||
272 | }; | ||
244 | }; | 273 | }; |
245 | 274 | ||
246 | serial@12C00000 { | 275 | serial@12C00000 { |
@@ -719,6 +748,7 @@ | |||
719 | hdmi: hdmi { | 748 | hdmi: hdmi { |
720 | compatible = "samsung,exynos4212-hdmi"; | 749 | compatible = "samsung,exynos4212-hdmi"; |
721 | reg = <0x14530000 0x70000>; | 750 | reg = <0x14530000 0x70000>; |
751 | power-domains = <&pd_disp1>; | ||
722 | interrupts = <0 95 0>; | 752 | interrupts = <0 95 0>; |
723 | clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>, | 753 | clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>, |
724 | <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>, | 754 | <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>, |
@@ -731,9 +761,11 @@ | |||
731 | mixer { | 761 | mixer { |
732 | compatible = "samsung,exynos5250-mixer"; | 762 | compatible = "samsung,exynos5250-mixer"; |
733 | reg = <0x14450000 0x10000>; | 763 | reg = <0x14450000 0x10000>; |
764 | power-domains = <&pd_disp1>; | ||
734 | interrupts = <0 94 0>; | 765 | interrupts = <0 94 0>; |
735 | clocks = <&clock CLK_MIXER>, <&clock CLK_SCLK_HDMI>; | 766 | clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, |
736 | clock-names = "mixer", "sclk_hdmi"; | 767 | <&clock CLK_SCLK_HDMI>; |
768 | clock-names = "mixer", "hdmi", "sclk_hdmi"; | ||
737 | }; | 769 | }; |
738 | 770 | ||
739 | dp_phy: video-phy@10040720 { | 771 | dp_phy: video-phy@10040720 { |
@@ -743,6 +775,7 @@ | |||
743 | }; | 775 | }; |
744 | 776 | ||
745 | dp: dp-controller@145B0000 { | 777 | dp: dp-controller@145B0000 { |
778 | power-domains = <&pd_disp1>; | ||
746 | clocks = <&clock CLK_DP>; | 779 | clocks = <&clock CLK_DP>; |
747 | clock-names = "dp"; | 780 | clock-names = "dp"; |
748 | phys = <&dp_phy>; | 781 | phys = <&dp_phy>; |
@@ -750,6 +783,7 @@ | |||
750 | }; | 783 | }; |
751 | 784 | ||
752 | fimd: fimd@14400000 { | 785 | fimd: fimd@14400000 { |
786 | power-domains = <&pd_disp1>; | ||
753 | clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>; | 787 | clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>; |
754 | clock-names = "sclk_fimd", "fimd"; | 788 | clock-names = "sclk_fimd", "fimd"; |
755 | }; | 789 | }; |
diff --git a/arch/arm/boot/dts/exynos5420-trip-points.dtsi b/arch/arm/boot/dts/exynos5420-trip-points.dtsi new file mode 100644 index 000000000000..5d31fc140823 --- /dev/null +++ b/arch/arm/boot/dts/exynos5420-trip-points.dtsi | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Device tree sources for default Exynos5420 thermal zone definition | ||
3 | * | ||
4 | * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | polling-delay-passive = <0>; | ||
13 | polling-delay = <0>; | ||
14 | trips { | ||
15 | cpu-alert-0 { | ||
16 | temperature = <85000>; /* millicelsius */ | ||
17 | hysteresis = <10000>; /* millicelsius */ | ||
18 | type = "active"; | ||
19 | }; | ||
20 | cpu-alert-1 { | ||
21 | temperature = <103000>; /* millicelsius */ | ||
22 | hysteresis = <10000>; /* millicelsius */ | ||
23 | type = "active"; | ||
24 | }; | ||
25 | cpu-alert-2 { | ||
26 | temperature = <110000>; /* millicelsius */ | ||
27 | hysteresis = <10000>; /* millicelsius */ | ||
28 | type = "active"; | ||
29 | }; | ||
30 | cpu-crit-0 { | ||
31 | temperature = <1200000>; /* millicelsius */ | ||
32 | hysteresis = <0>; /* millicelsius */ | ||
33 | type = "critical"; | ||
34 | }; | ||
35 | }; | ||
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 9dc2e9773b30..c0e98cf3514f 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi | |||
@@ -740,8 +740,9 @@ | |||
740 | compatible = "samsung,exynos5420-mixer"; | 740 | compatible = "samsung,exynos5420-mixer"; |
741 | reg = <0x14450000 0x10000>; | 741 | reg = <0x14450000 0x10000>; |
742 | interrupts = <0 94 0>; | 742 | interrupts = <0 94 0>; |
743 | clocks = <&clock CLK_MIXER>, <&clock CLK_SCLK_HDMI>; | 743 | clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, |
744 | clock-names = "mixer", "sclk_hdmi"; | 744 | <&clock CLK_SCLK_HDMI>; |
745 | clock-names = "mixer", "hdmi", "sclk_hdmi"; | ||
745 | power-domains = <&disp_pd>; | 746 | power-domains = <&disp_pd>; |
746 | }; | 747 | }; |
747 | 748 | ||
@@ -782,6 +783,7 @@ | |||
782 | interrupts = <0 65 0>; | 783 | interrupts = <0 65 0>; |
783 | clocks = <&clock CLK_TMU>; | 784 | clocks = <&clock CLK_TMU>; |
784 | clock-names = "tmu_apbif"; | 785 | clock-names = "tmu_apbif"; |
786 | #include "exynos4412-tmu-sensor-conf.dtsi" | ||
785 | }; | 787 | }; |
786 | 788 | ||
787 | tmu_cpu1: tmu@10064000 { | 789 | tmu_cpu1: tmu@10064000 { |
@@ -790,6 +792,7 @@ | |||
790 | interrupts = <0 183 0>; | 792 | interrupts = <0 183 0>; |
791 | clocks = <&clock CLK_TMU>; | 793 | clocks = <&clock CLK_TMU>; |
792 | clock-names = "tmu_apbif"; | 794 | clock-names = "tmu_apbif"; |
795 | #include "exynos4412-tmu-sensor-conf.dtsi" | ||
793 | }; | 796 | }; |
794 | 797 | ||
795 | tmu_cpu2: tmu@10068000 { | 798 | tmu_cpu2: tmu@10068000 { |
@@ -798,6 +801,7 @@ | |||
798 | interrupts = <0 184 0>; | 801 | interrupts = <0 184 0>; |
799 | clocks = <&clock CLK_TMU>, <&clock CLK_TMU>; | 802 | clocks = <&clock CLK_TMU>, <&clock CLK_TMU>; |
800 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; | 803 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; |
804 | #include "exynos4412-tmu-sensor-conf.dtsi" | ||
801 | }; | 805 | }; |
802 | 806 | ||
803 | tmu_cpu3: tmu@1006c000 { | 807 | tmu_cpu3: tmu@1006c000 { |
@@ -806,6 +810,7 @@ | |||
806 | interrupts = <0 185 0>; | 810 | interrupts = <0 185 0>; |
807 | clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>; | 811 | clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>; |
808 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; | 812 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; |
813 | #include "exynos4412-tmu-sensor-conf.dtsi" | ||
809 | }; | 814 | }; |
810 | 815 | ||
811 | tmu_gpu: tmu@100a0000 { | 816 | tmu_gpu: tmu@100a0000 { |
@@ -814,6 +819,30 @@ | |||
814 | interrupts = <0 215 0>; | 819 | interrupts = <0 215 0>; |
815 | clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>; | 820 | clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>; |
816 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; | 821 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; |
822 | #include "exynos4412-tmu-sensor-conf.dtsi" | ||
823 | }; | ||
824 | |||
825 | thermal-zones { | ||
826 | cpu0_thermal: cpu0-thermal { | ||
827 | thermal-sensors = <&tmu_cpu0>; | ||
828 | #include "exynos5420-trip-points.dtsi" | ||
829 | }; | ||
830 | cpu1_thermal: cpu1-thermal { | ||
831 | thermal-sensors = <&tmu_cpu1>; | ||
832 | #include "exynos5420-trip-points.dtsi" | ||
833 | }; | ||
834 | cpu2_thermal: cpu2-thermal { | ||
835 | thermal-sensors = <&tmu_cpu2>; | ||
836 | #include "exynos5420-trip-points.dtsi" | ||
837 | }; | ||
838 | cpu3_thermal: cpu3-thermal { | ||
839 | thermal-sensors = <&tmu_cpu3>; | ||
840 | #include "exynos5420-trip-points.dtsi" | ||
841 | }; | ||
842 | gpu_thermal: gpu-thermal { | ||
843 | thermal-sensors = <&tmu_gpu>; | ||
844 | #include "exynos5420-trip-points.dtsi" | ||
845 | }; | ||
817 | }; | 846 | }; |
818 | 847 | ||
819 | watchdog: watchdog@101D0000 { | 848 | watchdog: watchdog@101D0000 { |
diff --git a/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi new file mode 100644 index 000000000000..7b2fba0ae92b --- /dev/null +++ b/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Device tree sources for Exynos5440 TMU sensor configuration | ||
3 | * | ||
4 | * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <dt-bindings/thermal/thermal_exynos.h> | ||
13 | |||
14 | #thermal-sensor-cells = <0>; | ||
15 | samsung,tmu_gain = <5>; | ||
16 | samsung,tmu_reference_voltage = <16>; | ||
17 | samsung,tmu_noise_cancel_mode = <4>; | ||
18 | samsung,tmu_efuse_value = <0x5d2d>; | ||
19 | samsung,tmu_min_efuse_value = <16>; | ||
20 | samsung,tmu_max_efuse_value = <76>; | ||
21 | samsung,tmu_first_point_trim = <25>; | ||
22 | samsung,tmu_second_point_trim = <70>; | ||
23 | samsung,tmu_default_temp_offset = <25>; | ||
24 | samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>; | ||
diff --git a/arch/arm/boot/dts/exynos5440-trip-points.dtsi b/arch/arm/boot/dts/exynos5440-trip-points.dtsi new file mode 100644 index 000000000000..48adfa8f4300 --- /dev/null +++ b/arch/arm/boot/dts/exynos5440-trip-points.dtsi | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Device tree sources for default Exynos5440 thermal zone definition | ||
3 | * | ||
4 | * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | polling-delay-passive = <0>; | ||
13 | polling-delay = <0>; | ||
14 | trips { | ||
15 | cpu-alert-0 { | ||
16 | temperature = <100000>; /* millicelsius */ | ||
17 | hysteresis = <0>; /* millicelsius */ | ||
18 | type = "active"; | ||
19 | }; | ||
20 | cpu-crit-0 { | ||
21 | temperature = <1050000>; /* millicelsius */ | ||
22 | hysteresis = <0>; /* millicelsius */ | ||
23 | type = "critical"; | ||
24 | }; | ||
25 | }; | ||
diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi index 8f3373cd7b87..59d9416b3b03 100644 --- a/arch/arm/boot/dts/exynos5440.dtsi +++ b/arch/arm/boot/dts/exynos5440.dtsi | |||
@@ -219,6 +219,7 @@ | |||
219 | interrupts = <0 58 0>; | 219 | interrupts = <0 58 0>; |
220 | clocks = <&clock CLK_B_125>; | 220 | clocks = <&clock CLK_B_125>; |
221 | clock-names = "tmu_apbif"; | 221 | clock-names = "tmu_apbif"; |
222 | #include "exynos5440-tmu-sensor-conf.dtsi" | ||
222 | }; | 223 | }; |
223 | 224 | ||
224 | tmuctrl_1: tmuctrl@16011C { | 225 | tmuctrl_1: tmuctrl@16011C { |
@@ -227,6 +228,7 @@ | |||
227 | interrupts = <0 58 0>; | 228 | interrupts = <0 58 0>; |
228 | clocks = <&clock CLK_B_125>; | 229 | clocks = <&clock CLK_B_125>; |
229 | clock-names = "tmu_apbif"; | 230 | clock-names = "tmu_apbif"; |
231 | #include "exynos5440-tmu-sensor-conf.dtsi" | ||
230 | }; | 232 | }; |
231 | 233 | ||
232 | tmuctrl_2: tmuctrl@160120 { | 234 | tmuctrl_2: tmuctrl@160120 { |
@@ -235,6 +237,22 @@ | |||
235 | interrupts = <0 58 0>; | 237 | interrupts = <0 58 0>; |
236 | clocks = <&clock CLK_B_125>; | 238 | clocks = <&clock CLK_B_125>; |
237 | clock-names = "tmu_apbif"; | 239 | clock-names = "tmu_apbif"; |
240 | #include "exynos5440-tmu-sensor-conf.dtsi" | ||
241 | }; | ||
242 | |||
243 | thermal-zones { | ||
244 | cpu0_thermal: cpu0-thermal { | ||
245 | thermal-sensors = <&tmuctrl_0>; | ||
246 | #include "exynos5440-trip-points.dtsi" | ||
247 | }; | ||
248 | cpu1_thermal: cpu1-thermal { | ||
249 | thermal-sensors = <&tmuctrl_1>; | ||
250 | #include "exynos5440-trip-points.dtsi" | ||
251 | }; | ||
252 | cpu2_thermal: cpu2-thermal { | ||
253 | thermal-sensors = <&tmuctrl_2>; | ||
254 | #include "exynos5440-trip-points.dtsi" | ||
255 | }; | ||
238 | }; | 256 | }; |
239 | 257 | ||
240 | sata@210000 { | 258 | sata@210000 { |
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index f1cd2147421d..a626e6dd8022 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi | |||
@@ -35,6 +35,7 @@ | |||
35 | regulator-max-microvolt = <5000000>; | 35 | regulator-max-microvolt = <5000000>; |
36 | gpio = <&gpio3 22 0>; | 36 | gpio = <&gpio3 22 0>; |
37 | enable-active-high; | 37 | enable-active-high; |
38 | vin-supply = <&swbst_reg>; | ||
38 | }; | 39 | }; |
39 | 40 | ||
40 | reg_usb_h1_vbus: regulator@1 { | 41 | reg_usb_h1_vbus: regulator@1 { |
@@ -45,6 +46,7 @@ | |||
45 | regulator-max-microvolt = <5000000>; | 46 | regulator-max-microvolt = <5000000>; |
46 | gpio = <&gpio1 29 0>; | 47 | gpio = <&gpio1 29 0>; |
47 | enable-active-high; | 48 | enable-active-high; |
49 | vin-supply = <&swbst_reg>; | ||
48 | }; | 50 | }; |
49 | 51 | ||
50 | reg_audio: regulator@2 { | 52 | reg_audio: regulator@2 { |
diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts index fda4932faefd..945887d3fdb3 100644 --- a/arch/arm/boot/dts/imx6sl-evk.dts +++ b/arch/arm/boot/dts/imx6sl-evk.dts | |||
@@ -52,6 +52,7 @@ | |||
52 | regulator-max-microvolt = <5000000>; | 52 | regulator-max-microvolt = <5000000>; |
53 | gpio = <&gpio4 0 0>; | 53 | gpio = <&gpio4 0 0>; |
54 | enable-active-high; | 54 | enable-active-high; |
55 | vin-supply = <&swbst_reg>; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | reg_usb_otg2_vbus: regulator@1 { | 58 | reg_usb_otg2_vbus: regulator@1 { |
@@ -62,6 +63,7 @@ | |||
62 | regulator-max-microvolt = <5000000>; | 63 | regulator-max-microvolt = <5000000>; |
63 | gpio = <&gpio4 2 0>; | 64 | gpio = <&gpio4 2 0>; |
64 | enable-active-high; | 65 | enable-active-high; |
66 | vin-supply = <&swbst_reg>; | ||
65 | }; | 67 | }; |
66 | 68 | ||
67 | reg_aud3v: regulator@2 { | 69 | reg_aud3v: regulator@2 { |
diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index 59d1c297bb30..578fa2a54dce 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi | |||
@@ -87,8 +87,8 @@ | |||
87 | <14>, | 87 | <14>, |
88 | <15>; | 88 | <15>; |
89 | #dma-cells = <1>; | 89 | #dma-cells = <1>; |
90 | #dma-channels = <32>; | 90 | dma-channels = <32>; |
91 | #dma-requests = <64>; | 91 | dma-requests = <64>; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | i2c1: i2c@48070000 { | 94 | i2c1: i2c@48070000 { |
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 60403273f83e..db80f9d376fa 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts | |||
@@ -16,6 +16,13 @@ | |||
16 | model = "Nokia N900"; | 16 | model = "Nokia N900"; |
17 | compatible = "nokia,omap3-n900", "ti,omap3430", "ti,omap3"; | 17 | compatible = "nokia,omap3-n900", "ti,omap3430", "ti,omap3"; |
18 | 18 | ||
19 | aliases { | ||
20 | i2c0; | ||
21 | i2c1 = &i2c1; | ||
22 | i2c2 = &i2c2; | ||
23 | i2c3 = &i2c3; | ||
24 | }; | ||
25 | |||
19 | cpus { | 26 | cpus { |
20 | cpu@0 { | 27 | cpu@0 { |
21 | cpu0-supply = <&vcc>; | 28 | cpu0-supply = <&vcc>; |
@@ -704,7 +711,7 @@ | |||
704 | compatible = "smsc,lan91c94"; | 711 | compatible = "smsc,lan91c94"; |
705 | interrupt-parent = <&gpio2>; | 712 | interrupt-parent = <&gpio2>; |
706 | interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; /* gpio54 */ | 713 | interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; /* gpio54 */ |
707 | reg = <1 0x300 0xf>; /* 16 byte IO range at offset 0x300 */ | 714 | reg = <1 0 0xf>; /* 16 byte IO range */ |
708 | bank-width = <2>; | 715 | bank-width = <2>; |
709 | pinctrl-names = "default"; | 716 | pinctrl-names = "default"; |
710 | pinctrl-0 = <ðernet_pins>; | 717 | pinctrl-0 = <ðernet_pins>; |
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index 01b71111bd55..3fdc84fddb70 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi | |||
@@ -92,6 +92,8 @@ | |||
92 | ti,hwmods = "aes"; | 92 | ti,hwmods = "aes"; |
93 | reg = <0x480c5000 0x50>; | 93 | reg = <0x480c5000 0x50>; |
94 | interrupts = <0>; | 94 | interrupts = <0>; |
95 | dmas = <&sdma 65 &sdma 66>; | ||
96 | dma-names = "tx", "rx"; | ||
95 | }; | 97 | }; |
96 | 98 | ||
97 | prm: prm@48306000 { | 99 | prm: prm@48306000 { |
@@ -155,8 +157,8 @@ | |||
155 | <14>, | 157 | <14>, |
156 | <15>; | 158 | <15>; |
157 | #dma-cells = <1>; | 159 | #dma-cells = <1>; |
158 | #dma-channels = <32>; | 160 | dma-channels = <32>; |
159 | #dma-requests = <96>; | 161 | dma-requests = <96>; |
160 | }; | 162 | }; |
161 | 163 | ||
162 | omap3_pmx_core: pinmux@48002030 { | 164 | omap3_pmx_core: pinmux@48002030 { |
@@ -550,6 +552,8 @@ | |||
550 | ti,hwmods = "sham"; | 552 | ti,hwmods = "sham"; |
551 | reg = <0x480c3000 0x64>; | 553 | reg = <0x480c3000 0x64>; |
552 | interrupts = <49>; | 554 | interrupts = <49>; |
555 | dmas = <&sdma 69>; | ||
556 | dma-names = "rx"; | ||
553 | }; | 557 | }; |
554 | 558 | ||
555 | smartreflex_core: smartreflex@480cb000 { | 559 | smartreflex_core: smartreflex@480cb000 { |
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 074147cebae4..87401d9f4d8b 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi | |||
@@ -223,8 +223,8 @@ | |||
223 | <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>, | 223 | <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>, |
224 | <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; | 224 | <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; |
225 | #dma-cells = <1>; | 225 | #dma-cells = <1>; |
226 | #dma-channels = <32>; | 226 | dma-channels = <32>; |
227 | #dma-requests = <127>; | 227 | dma-requests = <127>; |
228 | }; | 228 | }; |
229 | 229 | ||
230 | gpio1: gpio@4a310000 { | 230 | gpio1: gpio@4a310000 { |
diff --git a/arch/arm/boot/dts/omap5-core-thermal.dtsi b/arch/arm/boot/dts/omap5-core-thermal.dtsi index 19212ac6eef0..de8a3d456cf7 100644 --- a/arch/arm/boot/dts/omap5-core-thermal.dtsi +++ b/arch/arm/boot/dts/omap5-core-thermal.dtsi | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | core_thermal: core_thermal { | 14 | core_thermal: core_thermal { |
15 | polling-delay-passive = <250>; /* milliseconds */ | 15 | polling-delay-passive = <250>; /* milliseconds */ |
16 | polling-delay = <1000>; /* milliseconds */ | 16 | polling-delay = <500>; /* milliseconds */ |
17 | 17 | ||
18 | /* sensor ID */ | 18 | /* sensor ID */ |
19 | thermal-sensors = <&bandgap 2>; | 19 | thermal-sensors = <&bandgap 2>; |
diff --git a/arch/arm/boot/dts/omap5-gpu-thermal.dtsi b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi index 1b87aca88b77..bc3090f2e84b 100644 --- a/arch/arm/boot/dts/omap5-gpu-thermal.dtsi +++ b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | gpu_thermal: gpu_thermal { | 14 | gpu_thermal: gpu_thermal { |
15 | polling-delay-passive = <250>; /* milliseconds */ | 15 | polling-delay-passive = <250>; /* milliseconds */ |
16 | polling-delay = <1000>; /* milliseconds */ | 16 | polling-delay = <500>; /* milliseconds */ |
17 | 17 | ||
18 | /* sensor ID */ | 18 | /* sensor ID */ |
19 | thermal-sensors = <&bandgap 1>; | 19 | thermal-sensors = <&bandgap 1>; |
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index b321fdf42c9f..4a485b63a141 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi | |||
@@ -238,8 +238,8 @@ | |||
238 | <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>, | 238 | <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>, |
239 | <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; | 239 | <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; |
240 | #dma-cells = <1>; | 240 | #dma-cells = <1>; |
241 | #dma-channels = <32>; | 241 | dma-channels = <32>; |
242 | #dma-requests = <127>; | 242 | dma-requests = <127>; |
243 | }; | 243 | }; |
244 | 244 | ||
245 | gpio1: gpio@4ae10000 { | 245 | gpio1: gpio@4ae10000 { |
@@ -929,8 +929,8 @@ | |||
929 | <0x4A096800 0x40>; /* pll_ctrl */ | 929 | <0x4A096800 0x40>; /* pll_ctrl */ |
930 | reg-names = "phy_rx", "phy_tx", "pll_ctrl"; | 930 | reg-names = "phy_rx", "phy_tx", "pll_ctrl"; |
931 | ctrl-module = <&omap_control_sata>; | 931 | ctrl-module = <&omap_control_sata>; |
932 | clocks = <&sys_clkin>; | 932 | clocks = <&sys_clkin>, <&sata_ref_clk>; |
933 | clock-names = "sysclk"; | 933 | clock-names = "sysclk", "refclk"; |
934 | #phy-cells = <0>; | 934 | #phy-cells = <0>; |
935 | }; | 935 | }; |
936 | }; | 936 | }; |
@@ -1079,4 +1079,8 @@ | |||
1079 | }; | 1079 | }; |
1080 | }; | 1080 | }; |
1081 | 1081 | ||
1082 | &cpu_thermal { | ||
1083 | polling-delay = <500>; /* milliseconds */ | ||
1084 | }; | ||
1085 | |||
1082 | /include/ "omap54xx-clocks.dtsi" | 1086 | /include/ "omap54xx-clocks.dtsi" |
diff --git a/arch/arm/boot/dts/omap54xx-clocks.dtsi b/arch/arm/boot/dts/omap54xx-clocks.dtsi index 58c27466f012..83b425fb3ac2 100644 --- a/arch/arm/boot/dts/omap54xx-clocks.dtsi +++ b/arch/arm/boot/dts/omap54xx-clocks.dtsi | |||
@@ -167,10 +167,18 @@ | |||
167 | ti,index-starts-at-one; | 167 | ti,index-starts-at-one; |
168 | }; | 168 | }; |
169 | 169 | ||
170 | dpll_core_byp_mux: dpll_core_byp_mux { | ||
171 | #clock-cells = <0>; | ||
172 | compatible = "ti,mux-clock"; | ||
173 | clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>; | ||
174 | ti,bit-shift = <23>; | ||
175 | reg = <0x012c>; | ||
176 | }; | ||
177 | |||
170 | dpll_core_ck: dpll_core_ck { | 178 | dpll_core_ck: dpll_core_ck { |
171 | #clock-cells = <0>; | 179 | #clock-cells = <0>; |
172 | compatible = "ti,omap4-dpll-core-clock"; | 180 | compatible = "ti,omap4-dpll-core-clock"; |
173 | clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>; | 181 | clocks = <&sys_clkin>, <&dpll_core_byp_mux>; |
174 | reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>; | 182 | reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>; |
175 | }; | 183 | }; |
176 | 184 | ||
@@ -294,10 +302,18 @@ | |||
294 | clock-div = <1>; | 302 | clock-div = <1>; |
295 | }; | 303 | }; |
296 | 304 | ||
305 | dpll_iva_byp_mux: dpll_iva_byp_mux { | ||
306 | #clock-cells = <0>; | ||
307 | compatible = "ti,mux-clock"; | ||
308 | clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>; | ||
309 | ti,bit-shift = <23>; | ||
310 | reg = <0x01ac>; | ||
311 | }; | ||
312 | |||
297 | dpll_iva_ck: dpll_iva_ck { | 313 | dpll_iva_ck: dpll_iva_ck { |
298 | #clock-cells = <0>; | 314 | #clock-cells = <0>; |
299 | compatible = "ti,omap4-dpll-clock"; | 315 | compatible = "ti,omap4-dpll-clock"; |
300 | clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>; | 316 | clocks = <&sys_clkin>, <&dpll_iva_byp_mux>; |
301 | reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; | 317 | reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; |
302 | }; | 318 | }; |
303 | 319 | ||
@@ -599,10 +615,19 @@ | |||
599 | }; | 615 | }; |
600 | }; | 616 | }; |
601 | &cm_core_clocks { | 617 | &cm_core_clocks { |
618 | |||
619 | dpll_per_byp_mux: dpll_per_byp_mux { | ||
620 | #clock-cells = <0>; | ||
621 | compatible = "ti,mux-clock"; | ||
622 | clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>; | ||
623 | ti,bit-shift = <23>; | ||
624 | reg = <0x014c>; | ||
625 | }; | ||
626 | |||
602 | dpll_per_ck: dpll_per_ck { | 627 | dpll_per_ck: dpll_per_ck { |
603 | #clock-cells = <0>; | 628 | #clock-cells = <0>; |
604 | compatible = "ti,omap4-dpll-clock"; | 629 | compatible = "ti,omap4-dpll-clock"; |
605 | clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>; | 630 | clocks = <&sys_clkin>, <&dpll_per_byp_mux>; |
606 | reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>; | 631 | reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>; |
607 | }; | 632 | }; |
608 | 633 | ||
@@ -714,10 +739,18 @@ | |||
714 | ti,index-starts-at-one; | 739 | ti,index-starts-at-one; |
715 | }; | 740 | }; |
716 | 741 | ||
742 | dpll_usb_byp_mux: dpll_usb_byp_mux { | ||
743 | #clock-cells = <0>; | ||
744 | compatible = "ti,mux-clock"; | ||
745 | clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>; | ||
746 | ti,bit-shift = <23>; | ||
747 | reg = <0x018c>; | ||
748 | }; | ||
749 | |||
717 | dpll_usb_ck: dpll_usb_ck { | 750 | dpll_usb_ck: dpll_usb_ck { |
718 | #clock-cells = <0>; | 751 | #clock-cells = <0>; |
719 | compatible = "ti,omap4-dpll-j-type-clock"; | 752 | compatible = "ti,omap4-dpll-j-type-clock"; |
720 | clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>; | 753 | clocks = <&sys_clkin>, <&dpll_usb_byp_mux>; |
721 | reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>; | 754 | reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>; |
722 | }; | 755 | }; |
723 | 756 | ||
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index d771f687a13b..eccc78d3220b 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi | |||
@@ -411,6 +411,7 @@ | |||
411 | "mac_clk_rx", "mac_clk_tx", | 411 | "mac_clk_rx", "mac_clk_tx", |
412 | "clk_mac_ref", "clk_mac_refout", | 412 | "clk_mac_ref", "clk_mac_refout", |
413 | "aclk_mac", "pclk_mac"; | 413 | "aclk_mac", "pclk_mac"; |
414 | status = "disabled"; | ||
414 | }; | 415 | }; |
415 | 416 | ||
416 | usb_host0_ehci: usb@ff500000 { | 417 | usb_host0_ehci: usb@ff500000 { |
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 261311bdf65b..367af53c1b84 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi | |||
@@ -1248,7 +1248,6 @@ | |||
1248 | atmel,watchdog-type = "hardware"; | 1248 | atmel,watchdog-type = "hardware"; |
1249 | atmel,reset-type = "all"; | 1249 | atmel,reset-type = "all"; |
1250 | atmel,dbg-halt; | 1250 | atmel,dbg-halt; |
1251 | atmel,idle-halt; | ||
1252 | status = "disabled"; | 1251 | status = "disabled"; |
1253 | }; | 1252 | }; |
1254 | 1253 | ||
@@ -1416,7 +1415,7 @@ | |||
1416 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; | 1415 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; |
1417 | reg = <0x00700000 0x100000>; | 1416 | reg = <0x00700000 0x100000>; |
1418 | interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>; | 1417 | interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>; |
1419 | clocks = <&usb>, <&uhphs_clk>, <&uhpck>; | 1418 | clocks = <&utmi>, <&uhphs_clk>, <&uhpck>; |
1420 | clock-names = "usb_clk", "ehci_clk", "uhpck"; | 1419 | clock-names = "usb_clk", "ehci_clk", "uhpck"; |
1421 | status = "disabled"; | 1420 | status = "disabled"; |
1422 | }; | 1421 | }; |
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index d986b41b9654..4303874889c6 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi | |||
@@ -66,6 +66,7 @@ | |||
66 | gpio4 = &pioE; | 66 | gpio4 = &pioE; |
67 | tcb0 = &tcb0; | 67 | tcb0 = &tcb0; |
68 | tcb1 = &tcb1; | 68 | tcb1 = &tcb1; |
69 | i2c0 = &i2c0; | ||
69 | i2c2 = &i2c2; | 70 | i2c2 = &i2c2; |
70 | }; | 71 | }; |
71 | cpus { | 72 | cpus { |
@@ -259,7 +260,7 @@ | |||
259 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; | 260 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; |
260 | reg = <0x00600000 0x100000>; | 261 | reg = <0x00600000 0x100000>; |
261 | interrupts = <46 IRQ_TYPE_LEVEL_HIGH 2>; | 262 | interrupts = <46 IRQ_TYPE_LEVEL_HIGH 2>; |
262 | clocks = <&usb>, <&uhphs_clk>, <&uhpck>; | 263 | clocks = <&utmi>, <&uhphs_clk>, <&uhpck>; |
263 | clock-names = "usb_clk", "ehci_clk", "uhpck"; | 264 | clock-names = "usb_clk", "ehci_clk", "uhpck"; |
264 | status = "disabled"; | 265 | status = "disabled"; |
265 | }; | 266 | }; |
@@ -461,8 +462,8 @@ | |||
461 | 462 | ||
462 | lcdck: lcdck { | 463 | lcdck: lcdck { |
463 | #clock-cells = <0>; | 464 | #clock-cells = <0>; |
464 | reg = <4>; | 465 | reg = <3>; |
465 | clocks = <&smd>; | 466 | clocks = <&mck>; |
466 | }; | 467 | }; |
467 | 468 | ||
468 | smdck: smdck { | 469 | smdck: smdck { |
@@ -770,7 +771,7 @@ | |||
770 | reg = <50>; | 771 | reg = <50>; |
771 | }; | 772 | }; |
772 | 773 | ||
773 | lcd_clk: lcd_clk { | 774 | lcdc_clk: lcdc_clk { |
774 | #clock-cells = <0>; | 775 | #clock-cells = <0>; |
775 | reg = <51>; | 776 | reg = <51>; |
776 | }; | 777 | }; |
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index 252c3d1bda50..d9176e606173 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi | |||
@@ -660,7 +660,7 @@ | |||
660 | #address-cells = <1>; | 660 | #address-cells = <1>; |
661 | #size-cells = <0>; | 661 | #size-cells = <0>; |
662 | reg = <0xfff01000 0x1000>; | 662 | reg = <0xfff01000 0x1000>; |
663 | interrupts = <0 156 4>; | 663 | interrupts = <0 155 4>; |
664 | num-cs = <4>; | 664 | num-cs = <4>; |
665 | clocks = <&spi_m_clk>; | 665 | clocks = <&spi_m_clk>; |
666 | status = "disabled"; | 666 | status = "disabled"; |
@@ -713,6 +713,9 @@ | |||
713 | reg-shift = <2>; | 713 | reg-shift = <2>; |
714 | reg-io-width = <4>; | 714 | reg-io-width = <4>; |
715 | clocks = <&l4_sp_clk>; | 715 | clocks = <&l4_sp_clk>; |
716 | dmas = <&pdma 28>, | ||
717 | <&pdma 29>; | ||
718 | dma-names = "tx", "rx"; | ||
716 | }; | 719 | }; |
717 | 720 | ||
718 | uart1: serial1@ffc03000 { | 721 | uart1: serial1@ffc03000 { |
@@ -722,6 +725,9 @@ | |||
722 | reg-shift = <2>; | 725 | reg-shift = <2>; |
723 | reg-io-width = <4>; | 726 | reg-io-width = <4>; |
724 | clocks = <&l4_sp_clk>; | 727 | clocks = <&l4_sp_clk>; |
728 | dmas = <&pdma 30>, | ||
729 | <&pdma 31>; | ||
730 | dma-names = "tx", "rx"; | ||
725 | }; | 731 | }; |
726 | 732 | ||
727 | rst: rstmgr@ffd05000 { | 733 | rst: rstmgr@ffd05000 { |
diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts index ab7891c43231..75742f8f96f3 100644 --- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts +++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts | |||
@@ -56,6 +56,22 @@ | |||
56 | model = "Olimex A10-OLinuXino-LIME"; | 56 | model = "Olimex A10-OLinuXino-LIME"; |
57 | compatible = "olimex,a10-olinuxino-lime", "allwinner,sun4i-a10"; | 57 | compatible = "olimex,a10-olinuxino-lime", "allwinner,sun4i-a10"; |
58 | 58 | ||
59 | cpus { | ||
60 | cpu0: cpu@0 { | ||
61 | /* | ||
62 | * The A10-Lime is known to be unstable | ||
63 | * when running at 1008 MHz | ||
64 | */ | ||
65 | operating-points = < | ||
66 | /* kHz uV */ | ||
67 | 912000 1350000 | ||
68 | 864000 1300000 | ||
69 | 624000 1250000 | ||
70 | >; | ||
71 | cooling-max-level = <2>; | ||
72 | }; | ||
73 | }; | ||
74 | |||
59 | soc@01c00000 { | 75 | soc@01c00000 { |
60 | emac: ethernet@01c0b000 { | 76 | emac: ethernet@01c0b000 { |
61 | pinctrl-names = "default"; | 77 | pinctrl-names = "default"; |
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 5c2925831f20..eebb7853e00b 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi | |||
@@ -75,7 +75,6 @@ | |||
75 | clock-latency = <244144>; /* 8 32k periods */ | 75 | clock-latency = <244144>; /* 8 32k periods */ |
76 | operating-points = < | 76 | operating-points = < |
77 | /* kHz uV */ | 77 | /* kHz uV */ |
78 | 1056000 1500000 | ||
79 | 1008000 1400000 | 78 | 1008000 1400000 |
80 | 912000 1350000 | 79 | 912000 1350000 |
81 | 864000 1300000 | 80 | 864000 1300000 |
@@ -83,7 +82,7 @@ | |||
83 | >; | 82 | >; |
84 | #cooling-cells = <2>; | 83 | #cooling-cells = <2>; |
85 | cooling-min-level = <0>; | 84 | cooling-min-level = <0>; |
86 | cooling-max-level = <4>; | 85 | cooling-max-level = <3>; |
87 | }; | 86 | }; |
88 | }; | 87 | }; |
89 | 88 | ||
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index f8818f1edbbe..883cb4873688 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi | |||
@@ -47,7 +47,6 @@ | |||
47 | clock-latency = <244144>; /* 8 32k periods */ | 47 | clock-latency = <244144>; /* 8 32k periods */ |
48 | operating-points = < | 48 | operating-points = < |
49 | /* kHz uV */ | 49 | /* kHz uV */ |
50 | 1104000 1500000 | ||
51 | 1008000 1400000 | 50 | 1008000 1400000 |
52 | 912000 1350000 | 51 | 912000 1350000 |
53 | 864000 1300000 | 52 | 864000 1300000 |
@@ -57,7 +56,7 @@ | |||
57 | >; | 56 | >; |
58 | #cooling-cells = <2>; | 57 | #cooling-cells = <2>; |
59 | cooling-min-level = <0>; | 58 | cooling-min-level = <0>; |
60 | cooling-max-level = <6>; | 59 | cooling-max-level = <5>; |
61 | }; | 60 | }; |
62 | }; | 61 | }; |
63 | 62 | ||
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 3a8530b79f1c..fdd181792b4b 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi | |||
@@ -105,7 +105,6 @@ | |||
105 | clock-latency = <244144>; /* 8 32k periods */ | 105 | clock-latency = <244144>; /* 8 32k periods */ |
106 | operating-points = < | 106 | operating-points = < |
107 | /* kHz uV */ | 107 | /* kHz uV */ |
108 | 1008000 1450000 | ||
109 | 960000 1400000 | 108 | 960000 1400000 |
110 | 912000 1400000 | 109 | 912000 1400000 |
111 | 864000 1300000 | 110 | 864000 1300000 |
@@ -116,7 +115,7 @@ | |||
116 | >; | 115 | >; |
117 | #cooling-cells = <2>; | 116 | #cooling-cells = <2>; |
118 | cooling-min-level = <0>; | 117 | cooling-min-level = <0>; |
119 | cooling-max-level = <7>; | 118 | cooling-max-level = <6>; |
120 | }; | 119 | }; |
121 | 120 | ||
122 | cpu@1 { | 121 | cpu@1 { |
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig index f2670f638e97..811e72bbe642 100644 --- a/arch/arm/configs/at91_dt_defconfig +++ b/arch/arm/configs/at91_dt_defconfig | |||
@@ -70,6 +70,7 @@ CONFIG_SCSI=y | |||
70 | CONFIG_BLK_DEV_SD=y | 70 | CONFIG_BLK_DEV_SD=y |
71 | # CONFIG_SCSI_LOWLEVEL is not set | 71 | # CONFIG_SCSI_LOWLEVEL is not set |
72 | CONFIG_NETDEVICES=y | 72 | CONFIG_NETDEVICES=y |
73 | CONFIG_ARM_AT91_ETHER=y | ||
73 | CONFIG_MACB=y | 74 | CONFIG_MACB=y |
74 | # CONFIG_NET_VENDOR_BROADCOM is not set | 75 | # CONFIG_NET_VENDOR_BROADCOM is not set |
75 | CONFIG_DM9000=y | 76 | CONFIG_DM9000=y |
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index e8a4c955241b..06075b6d2463 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig | |||
@@ -62,6 +62,17 @@ CONFIG_MACH_SPEAR1340=y | |||
62 | CONFIG_ARCH_STI=y | 62 | CONFIG_ARCH_STI=y |
63 | CONFIG_ARCH_EXYNOS=y | 63 | CONFIG_ARCH_EXYNOS=y |
64 | CONFIG_EXYNOS5420_MCPM=y | 64 | CONFIG_EXYNOS5420_MCPM=y |
65 | CONFIG_ARCH_SHMOBILE_MULTI=y | ||
66 | CONFIG_ARCH_EMEV2=y | ||
67 | CONFIG_ARCH_R7S72100=y | ||
68 | CONFIG_ARCH_R8A73A4=y | ||
69 | CONFIG_ARCH_R8A7740=y | ||
70 | CONFIG_ARCH_R8A7779=y | ||
71 | CONFIG_ARCH_R8A7790=y | ||
72 | CONFIG_ARCH_R8A7791=y | ||
73 | CONFIG_ARCH_R8A7794=y | ||
74 | CONFIG_ARCH_SH73A0=y | ||
75 | CONFIG_MACH_MARZEN=y | ||
65 | CONFIG_ARCH_SUNXI=y | 76 | CONFIG_ARCH_SUNXI=y |
66 | CONFIG_ARCH_SIRF=y | 77 | CONFIG_ARCH_SIRF=y |
67 | CONFIG_ARCH_TEGRA=y | 78 | CONFIG_ARCH_TEGRA=y |
@@ -84,9 +95,11 @@ CONFIG_PCI_KEYSTONE=y | |||
84 | CONFIG_PCI_MSI=y | 95 | CONFIG_PCI_MSI=y |
85 | CONFIG_PCI_MVEBU=y | 96 | CONFIG_PCI_MVEBU=y |
86 | CONFIG_PCI_TEGRA=y | 97 | CONFIG_PCI_TEGRA=y |
98 | CONFIG_PCI_RCAR_GEN2=y | ||
99 | CONFIG_PCI_RCAR_GEN2_PCIE=y | ||
87 | CONFIG_PCIEPORTBUS=y | 100 | CONFIG_PCIEPORTBUS=y |
88 | CONFIG_SMP=y | 101 | CONFIG_SMP=y |
89 | CONFIG_NR_CPUS=8 | 102 | CONFIG_NR_CPUS=16 |
90 | CONFIG_HIGHPTE=y | 103 | CONFIG_HIGHPTE=y |
91 | CONFIG_CMA=y | 104 | CONFIG_CMA=y |
92 | CONFIG_ARM_APPENDED_DTB=y | 105 | CONFIG_ARM_APPENDED_DTB=y |
@@ -130,6 +143,7 @@ CONFIG_DEVTMPFS_MOUNT=y | |||
130 | CONFIG_DMA_CMA=y | 143 | CONFIG_DMA_CMA=y |
131 | CONFIG_CMA_SIZE_MBYTES=64 | 144 | CONFIG_CMA_SIZE_MBYTES=64 |
132 | CONFIG_OMAP_OCP2SCP=y | 145 | CONFIG_OMAP_OCP2SCP=y |
146 | CONFIG_SIMPLE_PM_BUS=y | ||
133 | CONFIG_MTD=y | 147 | CONFIG_MTD=y |
134 | CONFIG_MTD_CMDLINE_PARTS=y | 148 | CONFIG_MTD_CMDLINE_PARTS=y |
135 | CONFIG_MTD_BLOCK=y | 149 | CONFIG_MTD_BLOCK=y |
@@ -157,6 +171,7 @@ CONFIG_AHCI_SUNXI=y | |||
157 | CONFIG_AHCI_TEGRA=y | 171 | CONFIG_AHCI_TEGRA=y |
158 | CONFIG_SATA_HIGHBANK=y | 172 | CONFIG_SATA_HIGHBANK=y |
159 | CONFIG_SATA_MV=y | 173 | CONFIG_SATA_MV=y |
174 | CONFIG_SATA_RCAR=y | ||
160 | CONFIG_NETDEVICES=y | 175 | CONFIG_NETDEVICES=y |
161 | CONFIG_HIX5HD2_GMAC=y | 176 | CONFIG_HIX5HD2_GMAC=y |
162 | CONFIG_SUN4I_EMAC=y | 177 | CONFIG_SUN4I_EMAC=y |
@@ -167,14 +182,17 @@ CONFIG_MV643XX_ETH=y | |||
167 | CONFIG_MVNETA=y | 182 | CONFIG_MVNETA=y |
168 | CONFIG_KS8851=y | 183 | CONFIG_KS8851=y |
169 | CONFIG_R8169=y | 184 | CONFIG_R8169=y |
185 | CONFIG_SH_ETH=y | ||
170 | CONFIG_SMSC911X=y | 186 | CONFIG_SMSC911X=y |
171 | CONFIG_STMMAC_ETH=y | 187 | CONFIG_STMMAC_ETH=y |
172 | CONFIG_TI_CPSW=y | 188 | CONFIG_TI_CPSW=y |
173 | CONFIG_XILINX_EMACLITE=y | 189 | CONFIG_XILINX_EMACLITE=y |
174 | CONFIG_AT803X_PHY=y | 190 | CONFIG_AT803X_PHY=y |
175 | CONFIG_MARVELL_PHY=y | 191 | CONFIG_MARVELL_PHY=y |
192 | CONFIG_SMSC_PHY=y | ||
176 | CONFIG_BROADCOM_PHY=y | 193 | CONFIG_BROADCOM_PHY=y |
177 | CONFIG_ICPLUS_PHY=y | 194 | CONFIG_ICPLUS_PHY=y |
195 | CONFIG_MICREL_PHY=y | ||
178 | CONFIG_USB_PEGASUS=y | 196 | CONFIG_USB_PEGASUS=y |
179 | CONFIG_USB_USBNET=y | 197 | CONFIG_USB_USBNET=y |
180 | CONFIG_USB_NET_SMSC75XX=y | 198 | CONFIG_USB_NET_SMSC75XX=y |
@@ -192,15 +210,18 @@ CONFIG_KEYBOARD_CROS_EC=y | |||
192 | CONFIG_MOUSE_PS2_ELANTECH=y | 210 | CONFIG_MOUSE_PS2_ELANTECH=y |
193 | CONFIG_INPUT_TOUCHSCREEN=y | 211 | CONFIG_INPUT_TOUCHSCREEN=y |
194 | CONFIG_TOUCHSCREEN_ATMEL_MXT=y | 212 | CONFIG_TOUCHSCREEN_ATMEL_MXT=y |
213 | CONFIG_TOUCHSCREEN_ST1232=m | ||
195 | CONFIG_TOUCHSCREEN_STMPE=y | 214 | CONFIG_TOUCHSCREEN_STMPE=y |
196 | CONFIG_TOUCHSCREEN_SUN4I=y | 215 | CONFIG_TOUCHSCREEN_SUN4I=y |
197 | CONFIG_INPUT_MISC=y | 216 | CONFIG_INPUT_MISC=y |
198 | CONFIG_INPUT_MPU3050=y | 217 | CONFIG_INPUT_MPU3050=y |
199 | CONFIG_INPUT_AXP20X_PEK=y | 218 | CONFIG_INPUT_AXP20X_PEK=y |
219 | CONFIG_INPUT_ADXL34X=m | ||
200 | CONFIG_SERIO_AMBAKMI=y | 220 | CONFIG_SERIO_AMBAKMI=y |
201 | CONFIG_SERIAL_8250=y | 221 | CONFIG_SERIAL_8250=y |
202 | CONFIG_SERIAL_8250_CONSOLE=y | 222 | CONFIG_SERIAL_8250_CONSOLE=y |
203 | CONFIG_SERIAL_8250_DW=y | 223 | CONFIG_SERIAL_8250_DW=y |
224 | CONFIG_SERIAL_8250_EM=y | ||
204 | CONFIG_SERIAL_8250_MT6577=y | 225 | CONFIG_SERIAL_8250_MT6577=y |
205 | CONFIG_SERIAL_AMBA_PL011=y | 226 | CONFIG_SERIAL_AMBA_PL011=y |
206 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | 227 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y |
@@ -213,6 +234,9 @@ CONFIG_SERIAL_SIRFSOC_CONSOLE=y | |||
213 | CONFIG_SERIAL_TEGRA=y | 234 | CONFIG_SERIAL_TEGRA=y |
214 | CONFIG_SERIAL_IMX=y | 235 | CONFIG_SERIAL_IMX=y |
215 | CONFIG_SERIAL_IMX_CONSOLE=y | 236 | CONFIG_SERIAL_IMX_CONSOLE=y |
237 | CONFIG_SERIAL_SH_SCI=y | ||
238 | CONFIG_SERIAL_SH_SCI_NR_UARTS=20 | ||
239 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
216 | CONFIG_SERIAL_MSM=y | 240 | CONFIG_SERIAL_MSM=y |
217 | CONFIG_SERIAL_MSM_CONSOLE=y | 241 | CONFIG_SERIAL_MSM_CONSOLE=y |
218 | CONFIG_SERIAL_VT8500=y | 242 | CONFIG_SERIAL_VT8500=y |
@@ -233,19 +257,26 @@ CONFIG_I2C_MUX_PCA954x=y | |||
233 | CONFIG_I2C_MUX_PINCTRL=y | 257 | CONFIG_I2C_MUX_PINCTRL=y |
234 | CONFIG_I2C_CADENCE=y | 258 | CONFIG_I2C_CADENCE=y |
235 | CONFIG_I2C_DESIGNWARE_PLATFORM=y | 259 | CONFIG_I2C_DESIGNWARE_PLATFORM=y |
260 | CONFIG_I2C_GPIO=m | ||
236 | CONFIG_I2C_EXYNOS5=y | 261 | CONFIG_I2C_EXYNOS5=y |
237 | CONFIG_I2C_MV64XXX=y | 262 | CONFIG_I2C_MV64XXX=y |
263 | CONFIG_I2C_RIIC=y | ||
238 | CONFIG_I2C_S3C2410=y | 264 | CONFIG_I2C_S3C2410=y |
265 | CONFIG_I2C_SH_MOBILE=y | ||
239 | CONFIG_I2C_SIRF=y | 266 | CONFIG_I2C_SIRF=y |
240 | CONFIG_I2C_TEGRA=y | ||
241 | CONFIG_I2C_ST=y | 267 | CONFIG_I2C_ST=y |
242 | CONFIG_SPI=y | 268 | CONFIG_I2C_TEGRA=y |
243 | CONFIG_I2C_XILINX=y | 269 | CONFIG_I2C_XILINX=y |
244 | CONFIG_SPI_DAVINCI=y | 270 | CONFIG_I2C_RCAR=y |
271 | CONFIG_SPI=y | ||
245 | CONFIG_SPI_CADENCE=y | 272 | CONFIG_SPI_CADENCE=y |
273 | CONFIG_SPI_DAVINCI=y | ||
246 | CONFIG_SPI_OMAP24XX=y | 274 | CONFIG_SPI_OMAP24XX=y |
247 | CONFIG_SPI_ORION=y | 275 | CONFIG_SPI_ORION=y |
248 | CONFIG_SPI_PL022=y | 276 | CONFIG_SPI_PL022=y |
277 | CONFIG_SPI_RSPI=y | ||
278 | CONFIG_SPI_SH_MSIOF=m | ||
279 | CONFIG_SPI_SH_HSPI=y | ||
249 | CONFIG_SPI_SIRF=y | 280 | CONFIG_SPI_SIRF=y |
250 | CONFIG_SPI_SUN4I=y | 281 | CONFIG_SPI_SUN4I=y |
251 | CONFIG_SPI_SUN6I=y | 282 | CONFIG_SPI_SUN6I=y |
@@ -259,12 +290,15 @@ CONFIG_PINCTRL_PALMAS=y | |||
259 | CONFIG_PINCTRL_APQ8084=y | 290 | CONFIG_PINCTRL_APQ8084=y |
260 | CONFIG_GPIO_SYSFS=y | 291 | CONFIG_GPIO_SYSFS=y |
261 | CONFIG_GPIO_GENERIC_PLATFORM=y | 292 | CONFIG_GPIO_GENERIC_PLATFORM=y |
262 | CONFIG_GPIO_DWAPB=y | ||
263 | CONFIG_GPIO_DAVINCI=y | 293 | CONFIG_GPIO_DAVINCI=y |
294 | CONFIG_GPIO_DWAPB=y | ||
295 | CONFIG_GPIO_EM=y | ||
296 | CONFIG_GPIO_RCAR=y | ||
264 | CONFIG_GPIO_XILINX=y | 297 | CONFIG_GPIO_XILINX=y |
265 | CONFIG_GPIO_ZYNQ=y | 298 | CONFIG_GPIO_ZYNQ=y |
266 | CONFIG_GPIO_PCA953X=y | 299 | CONFIG_GPIO_PCA953X=y |
267 | CONFIG_GPIO_PCA953X_IRQ=y | 300 | CONFIG_GPIO_PCA953X_IRQ=y |
301 | CONFIG_GPIO_PCF857X=y | ||
268 | CONFIG_GPIO_TWL4030=y | 302 | CONFIG_GPIO_TWL4030=y |
269 | CONFIG_GPIO_PALMAS=y | 303 | CONFIG_GPIO_PALMAS=y |
270 | CONFIG_GPIO_SYSCON=y | 304 | CONFIG_GPIO_SYSCON=y |
@@ -276,10 +310,12 @@ CONFIG_POWER_RESET_AS3722=y | |||
276 | CONFIG_POWER_RESET_GPIO=y | 310 | CONFIG_POWER_RESET_GPIO=y |
277 | CONFIG_POWER_RESET_KEYSTONE=y | 311 | CONFIG_POWER_RESET_KEYSTONE=y |
278 | CONFIG_POWER_RESET_SUN6I=y | 312 | CONFIG_POWER_RESET_SUN6I=y |
313 | CONFIG_POWER_RESET_RMOBILE=y | ||
279 | CONFIG_SENSORS_LM90=y | 314 | CONFIG_SENSORS_LM90=y |
280 | CONFIG_SENSORS_LM95245=y | 315 | CONFIG_SENSORS_LM95245=y |
281 | CONFIG_THERMAL=y | 316 | CONFIG_THERMAL=y |
282 | CONFIG_CPU_THERMAL=y | 317 | CONFIG_CPU_THERMAL=y |
318 | CONFIG_RCAR_THERMAL=y | ||
283 | CONFIG_ARMADA_THERMAL=y | 319 | CONFIG_ARMADA_THERMAL=y |
284 | CONFIG_DAVINCI_WATCHDOG | 320 | CONFIG_DAVINCI_WATCHDOG |
285 | CONFIG_ST_THERMAL_SYSCFG=y | 321 | CONFIG_ST_THERMAL_SYSCFG=y |
@@ -290,6 +326,7 @@ CONFIG_ARM_SP805_WATCHDOG=y | |||
290 | CONFIG_ORION_WATCHDOG=y | 326 | CONFIG_ORION_WATCHDOG=y |
291 | CONFIG_SUNXI_WATCHDOG=y | 327 | CONFIG_SUNXI_WATCHDOG=y |
292 | CONFIG_MESON_WATCHDOG=y | 328 | CONFIG_MESON_WATCHDOG=y |
329 | CONFIG_MFD_AS3711=y | ||
293 | CONFIG_MFD_AS3722=y | 330 | CONFIG_MFD_AS3722=y |
294 | CONFIG_MFD_BCM590XX=y | 331 | CONFIG_MFD_BCM590XX=y |
295 | CONFIG_MFD_AXP20X=y | 332 | CONFIG_MFD_AXP20X=y |
@@ -304,13 +341,16 @@ CONFIG_MFD_TPS65090=y | |||
304 | CONFIG_MFD_TPS6586X=y | 341 | CONFIG_MFD_TPS6586X=y |
305 | CONFIG_MFD_TPS65910=y | 342 | CONFIG_MFD_TPS65910=y |
306 | CONFIG_REGULATOR_AB8500=y | 343 | CONFIG_REGULATOR_AB8500=y |
344 | CONFIG_REGULATOR_AS3711=y | ||
307 | CONFIG_REGULATOR_AS3722=y | 345 | CONFIG_REGULATOR_AS3722=y |
308 | CONFIG_REGULATOR_AXP20X=y | 346 | CONFIG_REGULATOR_AXP20X=y |
309 | CONFIG_REGULATOR_BCM590XX=y | 347 | CONFIG_REGULATOR_BCM590XX=y |
348 | CONFIG_REGULATOR_DA9210=y | ||
310 | CONFIG_REGULATOR_GPIO=y | 349 | CONFIG_REGULATOR_GPIO=y |
311 | CONFIG_MFD_SYSCON=y | 350 | CONFIG_MFD_SYSCON=y |
312 | CONFIG_POWER_RESET_SYSCON=y | 351 | CONFIG_POWER_RESET_SYSCON=y |
313 | CONFIG_REGULATOR_MAX8907=y | 352 | CONFIG_REGULATOR_MAX8907=y |
353 | CONFIG_REGULATOR_MAX8973=y | ||
314 | CONFIG_REGULATOR_MAX77686=y | 354 | CONFIG_REGULATOR_MAX77686=y |
315 | CONFIG_REGULATOR_PALMAS=y | 355 | CONFIG_REGULATOR_PALMAS=y |
316 | CONFIG_REGULATOR_S2MPS11=y | 356 | CONFIG_REGULATOR_S2MPS11=y |
@@ -324,18 +364,32 @@ CONFIG_REGULATOR_TWL4030=y | |||
324 | CONFIG_REGULATOR_VEXPRESS=y | 364 | CONFIG_REGULATOR_VEXPRESS=y |
325 | CONFIG_MEDIA_SUPPORT=y | 365 | CONFIG_MEDIA_SUPPORT=y |
326 | CONFIG_MEDIA_CAMERA_SUPPORT=y | 366 | CONFIG_MEDIA_CAMERA_SUPPORT=y |
367 | CONFIG_MEDIA_CONTROLLER=y | ||
368 | CONFIG_VIDEO_V4L2_SUBDEV_API=y | ||
327 | CONFIG_MEDIA_USB_SUPPORT=y | 369 | CONFIG_MEDIA_USB_SUPPORT=y |
328 | CONFIG_USB_VIDEO_CLASS=y | 370 | CONFIG_USB_VIDEO_CLASS=y |
329 | CONFIG_USB_GSPCA=y | 371 | CONFIG_USB_GSPCA=y |
372 | CONFIG_V4L_PLATFORM_DRIVERS=y | ||
373 | CONFIG_SOC_CAMERA=m | ||
374 | CONFIG_SOC_CAMERA_PLATFORM=m | ||
375 | CONFIG_VIDEO_RCAR_VIN=m | ||
376 | CONFIG_V4L_MEM2MEM_DRIVERS=y | ||
377 | CONFIG_VIDEO_RENESAS_VSP1=m | ||
378 | # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set | ||
379 | CONFIG_VIDEO_ADV7180=m | ||
330 | CONFIG_DRM=y | 380 | CONFIG_DRM=y |
381 | CONFIG_DRM_RCAR_DU=m | ||
331 | CONFIG_DRM_TEGRA=y | 382 | CONFIG_DRM_TEGRA=y |
332 | CONFIG_DRM_PANEL_SIMPLE=y | 383 | CONFIG_DRM_PANEL_SIMPLE=y |
333 | CONFIG_FB_ARMCLCD=y | 384 | CONFIG_FB_ARMCLCD=y |
334 | CONFIG_FB_WM8505=y | 385 | CONFIG_FB_WM8505=y |
386 | CONFIG_FB_SH_MOBILE_LCDC=y | ||
335 | CONFIG_FB_SIMPLE=y | 387 | CONFIG_FB_SIMPLE=y |
388 | CONFIG_FB_SH_MOBILE_MERAM=y | ||
336 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | 389 | CONFIG_BACKLIGHT_LCD_SUPPORT=y |
337 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | 390 | CONFIG_BACKLIGHT_CLASS_DEVICE=y |
338 | CONFIG_BACKLIGHT_PWM=y | 391 | CONFIG_BACKLIGHT_PWM=y |
392 | CONFIG_BACKLIGHT_AS3711=y | ||
339 | CONFIG_FRAMEBUFFER_CONSOLE=y | 393 | CONFIG_FRAMEBUFFER_CONSOLE=y |
340 | CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y | 394 | CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y |
341 | CONFIG_SOUND=y | 395 | CONFIG_SOUND=y |
@@ -343,6 +397,8 @@ CONFIG_SND=y | |||
343 | CONFIG_SND_DYNAMIC_MINORS=y | 397 | CONFIG_SND_DYNAMIC_MINORS=y |
344 | CONFIG_SND_USB_AUDIO=y | 398 | CONFIG_SND_USB_AUDIO=y |
345 | CONFIG_SND_SOC=y | 399 | CONFIG_SND_SOC=y |
400 | CONFIG_SND_SOC_SH4_FSI=m | ||
401 | CONFIG_SND_SOC_RCAR=m | ||
346 | CONFIG_SND_SOC_TEGRA=y | 402 | CONFIG_SND_SOC_TEGRA=y |
347 | CONFIG_SND_SOC_TEGRA_RT5640=y | 403 | CONFIG_SND_SOC_TEGRA_RT5640=y |
348 | CONFIG_SND_SOC_TEGRA_WM8753=y | 404 | CONFIG_SND_SOC_TEGRA_WM8753=y |
@@ -350,6 +406,8 @@ CONFIG_SND_SOC_TEGRA_WM8903=y | |||
350 | CONFIG_SND_SOC_TEGRA_TRIMSLICE=y | 406 | CONFIG_SND_SOC_TEGRA_TRIMSLICE=y |
351 | CONFIG_SND_SOC_TEGRA_ALC5632=y | 407 | CONFIG_SND_SOC_TEGRA_ALC5632=y |
352 | CONFIG_SND_SOC_TEGRA_MAX98090=y | 408 | CONFIG_SND_SOC_TEGRA_MAX98090=y |
409 | CONFIG_SND_SOC_AK4642=m | ||
410 | CONFIG_SND_SOC_WM8978=m | ||
353 | CONFIG_USB=y | 411 | CONFIG_USB=y |
354 | CONFIG_USB_XHCI_HCD=y | 412 | CONFIG_USB_XHCI_HCD=y |
355 | CONFIG_USB_XHCI_MVEBU=y | 413 | CONFIG_USB_XHCI_MVEBU=y |
@@ -362,6 +420,8 @@ CONFIG_USB_ISP1760_HCD=y | |||
362 | CONFIG_USB_OHCI_HCD=y | 420 | CONFIG_USB_OHCI_HCD=y |
363 | CONFIG_USB_OHCI_HCD_STI=y | 421 | CONFIG_USB_OHCI_HCD_STI=y |
364 | CONFIG_USB_OHCI_HCD_PLATFORM=y | 422 | CONFIG_USB_OHCI_HCD_PLATFORM=y |
423 | CONFIG_USB_R8A66597_HCD=m | ||
424 | CONFIG_USB_RENESAS_USBHS=m | ||
365 | CONFIG_USB_STORAGE=y | 425 | CONFIG_USB_STORAGE=y |
366 | CONFIG_USB_DWC3=y | 426 | CONFIG_USB_DWC3=y |
367 | CONFIG_USB_CHIPIDEA=y | 427 | CONFIG_USB_CHIPIDEA=y |
@@ -374,6 +434,10 @@ CONFIG_SAMSUNG_USB3PHY=y | |||
374 | CONFIG_USB_GPIO_VBUS=y | 434 | CONFIG_USB_GPIO_VBUS=y |
375 | CONFIG_USB_ISP1301=y | 435 | CONFIG_USB_ISP1301=y |
376 | CONFIG_USB_MXS_PHY=y | 436 | CONFIG_USB_MXS_PHY=y |
437 | CONFIG_USB_RCAR_PHY=m | ||
438 | CONFIG_USB_RCAR_GEN2_PHY=m | ||
439 | CONFIG_USB_GADGET=y | ||
440 | CONFIG_USB_RENESAS_USBHS_UDC=m | ||
377 | CONFIG_MMC=y | 441 | CONFIG_MMC=y |
378 | CONFIG_MMC_BLOCK_MINORS=16 | 442 | CONFIG_MMC_BLOCK_MINORS=16 |
379 | CONFIG_MMC_ARMMMCI=y | 443 | CONFIG_MMC_ARMMMCI=y |
@@ -392,12 +456,14 @@ CONFIG_MMC_SDHCI_ST=y | |||
392 | CONFIG_MMC_OMAP=y | 456 | CONFIG_MMC_OMAP=y |
393 | CONFIG_MMC_OMAP_HS=y | 457 | CONFIG_MMC_OMAP_HS=y |
394 | CONFIG_MMC_MVSDIO=y | 458 | CONFIG_MMC_MVSDIO=y |
395 | CONFIG_MMC_SUNXI=y | 459 | CONFIG_MMC_SDHI=y |
396 | CONFIG_MMC_DW=y | 460 | CONFIG_MMC_DW=y |
397 | CONFIG_MMC_DW_IDMAC=y | 461 | CONFIG_MMC_DW_IDMAC=y |
398 | CONFIG_MMC_DW_PLTFM=y | 462 | CONFIG_MMC_DW_PLTFM=y |
399 | CONFIG_MMC_DW_EXYNOS=y | 463 | CONFIG_MMC_DW_EXYNOS=y |
400 | CONFIG_MMC_DW_ROCKCHIP=y | 464 | CONFIG_MMC_DW_ROCKCHIP=y |
465 | CONFIG_MMC_SH_MMCIF=y | ||
466 | CONFIG_MMC_SUNXI=y | ||
401 | CONFIG_NEW_LEDS=y | 467 | CONFIG_NEW_LEDS=y |
402 | CONFIG_LEDS_CLASS=y | 468 | CONFIG_LEDS_CLASS=y |
403 | CONFIG_LEDS_GPIO=y | 469 | CONFIG_LEDS_GPIO=y |
@@ -421,10 +487,12 @@ CONFIG_RTC_DRV_AS3722=y | |||
421 | CONFIG_RTC_DRV_DS1307=y | 487 | CONFIG_RTC_DRV_DS1307=y |
422 | CONFIG_RTC_DRV_MAX8907=y | 488 | CONFIG_RTC_DRV_MAX8907=y |
423 | CONFIG_RTC_DRV_MAX77686=y | 489 | CONFIG_RTC_DRV_MAX77686=y |
490 | CONFIG_RTC_DRV_RS5C372=m | ||
424 | CONFIG_RTC_DRV_PALMAS=y | 491 | CONFIG_RTC_DRV_PALMAS=y |
425 | CONFIG_RTC_DRV_TWL4030=y | 492 | CONFIG_RTC_DRV_TWL4030=y |
426 | CONFIG_RTC_DRV_TPS6586X=y | 493 | CONFIG_RTC_DRV_TPS6586X=y |
427 | CONFIG_RTC_DRV_TPS65910=y | 494 | CONFIG_RTC_DRV_TPS65910=y |
495 | CONFIG_RTC_DRV_S35390A=m | ||
428 | CONFIG_RTC_DRV_EM3027=y | 496 | CONFIG_RTC_DRV_EM3027=y |
429 | CONFIG_RTC_DRV_PL031=y | 497 | CONFIG_RTC_DRV_PL031=y |
430 | CONFIG_RTC_DRV_VT8500=y | 498 | CONFIG_RTC_DRV_VT8500=y |
@@ -436,6 +504,9 @@ CONFIG_DMADEVICES=y | |||
436 | CONFIG_DW_DMAC=y | 504 | CONFIG_DW_DMAC=y |
437 | CONFIG_MV_XOR=y | 505 | CONFIG_MV_XOR=y |
438 | CONFIG_TEGRA20_APB_DMA=y | 506 | CONFIG_TEGRA20_APB_DMA=y |
507 | CONFIG_SH_DMAE=y | ||
508 | CONFIG_RCAR_AUDMAC_PP=m | ||
509 | CONFIG_RCAR_DMAC=y | ||
439 | CONFIG_STE_DMA40=y | 510 | CONFIG_STE_DMA40=y |
440 | CONFIG_SIRF_DMA=y | 511 | CONFIG_SIRF_DMA=y |
441 | CONFIG_TI_EDMA=y | 512 | CONFIG_TI_EDMA=y |
@@ -468,6 +539,7 @@ CONFIG_IIO=y | |||
468 | CONFIG_XILINX_XADC=y | 539 | CONFIG_XILINX_XADC=y |
469 | CONFIG_AK8975=y | 540 | CONFIG_AK8975=y |
470 | CONFIG_PWM=y | 541 | CONFIG_PWM=y |
542 | CONFIG_PWM_RENESAS_TPU=y | ||
471 | CONFIG_PWM_TEGRA=y | 543 | CONFIG_PWM_TEGRA=y |
472 | CONFIG_PWM_VT8500=y | 544 | CONFIG_PWM_VT8500=y |
473 | CONFIG_PHY_HIX5HD2_SATA=y | 545 | CONFIG_PHY_HIX5HD2_SATA=y |
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index b7386524c356..8e108599e1af 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig | |||
@@ -114,6 +114,7 @@ CONFIG_MTD_PHYSMAP_OF=y | |||
114 | CONFIG_MTD_NAND=y | 114 | CONFIG_MTD_NAND=y |
115 | CONFIG_MTD_NAND_ECC_BCH=y | 115 | CONFIG_MTD_NAND_ECC_BCH=y |
116 | CONFIG_MTD_NAND_OMAP2=y | 116 | CONFIG_MTD_NAND_OMAP2=y |
117 | CONFIG_MTD_NAND_OMAP_BCH=y | ||
117 | CONFIG_MTD_ONENAND=y | 118 | CONFIG_MTD_ONENAND=y |
118 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y | 119 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y |
119 | CONFIG_MTD_ONENAND_OMAP2=y | 120 | CONFIG_MTD_ONENAND_OMAP2=y |
@@ -248,6 +249,7 @@ CONFIG_TWL6040_CORE=y | |||
248 | CONFIG_REGULATOR_PALMAS=y | 249 | CONFIG_REGULATOR_PALMAS=y |
249 | CONFIG_REGULATOR_PBIAS=y | 250 | CONFIG_REGULATOR_PBIAS=y |
250 | CONFIG_REGULATOR_TI_ABB=y | 251 | CONFIG_REGULATOR_TI_ABB=y |
252 | CONFIG_REGULATOR_TPS62360=m | ||
251 | CONFIG_REGULATOR_TPS65023=y | 253 | CONFIG_REGULATOR_TPS65023=y |
252 | CONFIG_REGULATOR_TPS6507X=y | 254 | CONFIG_REGULATOR_TPS6507X=y |
253 | CONFIG_REGULATOR_TPS65217=y | 255 | CONFIG_REGULATOR_TPS65217=y |
@@ -374,7 +376,8 @@ CONFIG_PWM_TIEHRPWM=m | |||
374 | CONFIG_PWM_TWL=m | 376 | CONFIG_PWM_TWL=m |
375 | CONFIG_PWM_TWL_LED=m | 377 | CONFIG_PWM_TWL_LED=m |
376 | CONFIG_OMAP_USB2=m | 378 | CONFIG_OMAP_USB2=m |
377 | CONFIG_TI_PIPE3=m | 379 | CONFIG_TI_PIPE3=y |
380 | CONFIG_TWL4030_USB=m | ||
378 | CONFIG_EXT2_FS=y | 381 | CONFIG_EXT2_FS=y |
379 | CONFIG_EXT3_FS=y | 382 | CONFIG_EXT3_FS=y |
380 | # CONFIG_EXT3_FS_XATTR is not set | 383 | # CONFIG_EXT3_FS_XATTR is not set |
diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig index 41d856effe6c..510c747c65b4 100644 --- a/arch/arm/configs/sama5_defconfig +++ b/arch/arm/configs/sama5_defconfig | |||
@@ -3,8 +3,6 @@ | |||
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_IRQ_DOMAIN_DEBUG=y | 4 | CONFIG_IRQ_DOMAIN_DEBUG=y |
5 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
6 | CONFIG_SYSFS_DEPRECATED=y | ||
7 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
8 | CONFIG_BLK_DEV_INITRD=y | 6 | CONFIG_BLK_DEV_INITRD=y |
9 | CONFIG_EMBEDDED=y | 7 | CONFIG_EMBEDDED=y |
10 | CONFIG_SLAB=y | 8 | CONFIG_SLAB=y |
diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index 38840a812924..8f6a5702b696 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig | |||
@@ -4,6 +4,7 @@ CONFIG_BLK_DEV_INITRD=y | |||
4 | CONFIG_PERF_EVENTS=y | 4 | CONFIG_PERF_EVENTS=y |
5 | CONFIG_ARCH_SUNXI=y | 5 | CONFIG_ARCH_SUNXI=y |
6 | CONFIG_SMP=y | 6 | CONFIG_SMP=y |
7 | CONFIG_NR_CPUS=8 | ||
7 | CONFIG_AEABI=y | 8 | CONFIG_AEABI=y |
8 | CONFIG_HIGHMEM=y | 9 | CONFIG_HIGHMEM=y |
9 | CONFIG_HIGHPTE=y | 10 | CONFIG_HIGHPTE=y |
diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig index f489fdaa19b8..37fe607a4ede 100644 --- a/arch/arm/configs/vexpress_defconfig +++ b/arch/arm/configs/vexpress_defconfig | |||
@@ -118,8 +118,8 @@ CONFIG_HID_ZEROPLUS=y | |||
118 | CONFIG_USB=y | 118 | CONFIG_USB=y |
119 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y | 119 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y |
120 | CONFIG_USB_MON=y | 120 | CONFIG_USB_MON=y |
121 | CONFIG_USB_ISP1760_HCD=y | ||
122 | CONFIG_USB_STORAGE=y | 121 | CONFIG_USB_STORAGE=y |
122 | CONFIG_USB_ISP1760=y | ||
123 | CONFIG_MMC=y | 123 | CONFIG_MMC=y |
124 | CONFIG_MMC_ARMMMCI=y | 124 | CONFIG_MMC_ARMMMCI=y |
125 | CONFIG_NEW_LEDS=y | 125 | CONFIG_NEW_LEDS=y |
diff --git a/arch/arm/crypto/aesbs-core.S_shipped b/arch/arm/crypto/aesbs-core.S_shipped index 71e5fc7cfb18..1d1800f71c5b 100644 --- a/arch/arm/crypto/aesbs-core.S_shipped +++ b/arch/arm/crypto/aesbs-core.S_shipped | |||
@@ -58,14 +58,18 @@ | |||
58 | # define VFP_ABI_FRAME 0 | 58 | # define VFP_ABI_FRAME 0 |
59 | # define BSAES_ASM_EXTENDED_KEY | 59 | # define BSAES_ASM_EXTENDED_KEY |
60 | # define XTS_CHAIN_TWEAK | 60 | # define XTS_CHAIN_TWEAK |
61 | # define __ARM_ARCH__ 7 | 61 | # define __ARM_ARCH__ __LINUX_ARM_ARCH__ |
62 | # define __ARM_MAX_ARCH__ 7 | ||
62 | #endif | 63 | #endif |
63 | 64 | ||
64 | #ifdef __thumb__ | 65 | #ifdef __thumb__ |
65 | # define adrl adr | 66 | # define adrl adr |
66 | #endif | 67 | #endif |
67 | 68 | ||
68 | #if __ARM_ARCH__>=7 | 69 | #if __ARM_MAX_ARCH__>=7 |
70 | .arch armv7-a | ||
71 | .fpu neon | ||
72 | |||
69 | .text | 73 | .text |
70 | .syntax unified @ ARMv7-capable assembler is expected to handle this | 74 | .syntax unified @ ARMv7-capable assembler is expected to handle this |
71 | #ifdef __thumb2__ | 75 | #ifdef __thumb2__ |
@@ -74,8 +78,6 @@ | |||
74 | .code 32 | 78 | .code 32 |
75 | #endif | 79 | #endif |
76 | 80 | ||
77 | .fpu neon | ||
78 | |||
79 | .type _bsaes_decrypt8,%function | 81 | .type _bsaes_decrypt8,%function |
80 | .align 4 | 82 | .align 4 |
81 | _bsaes_decrypt8: | 83 | _bsaes_decrypt8: |
@@ -2095,9 +2097,11 @@ bsaes_xts_decrypt: | |||
2095 | vld1.8 {q8}, [r0] @ initial tweak | 2097 | vld1.8 {q8}, [r0] @ initial tweak |
2096 | adr r2, .Lxts_magic | 2098 | adr r2, .Lxts_magic |
2097 | 2099 | ||
2100 | #ifndef XTS_CHAIN_TWEAK | ||
2098 | tst r9, #0xf @ if not multiple of 16 | 2101 | tst r9, #0xf @ if not multiple of 16 |
2099 | it ne @ Thumb2 thing, sanity check in ARM | 2102 | it ne @ Thumb2 thing, sanity check in ARM |
2100 | subne r9, #0x10 @ subtract another 16 bytes | 2103 | subne r9, #0x10 @ subtract another 16 bytes |
2104 | #endif | ||
2101 | subs r9, #0x80 | 2105 | subs r9, #0x80 |
2102 | 2106 | ||
2103 | blo .Lxts_dec_short | 2107 | blo .Lxts_dec_short |
diff --git a/arch/arm/crypto/bsaes-armv7.pl b/arch/arm/crypto/bsaes-armv7.pl index be068db960ee..a4d3856e7d24 100644 --- a/arch/arm/crypto/bsaes-armv7.pl +++ b/arch/arm/crypto/bsaes-armv7.pl | |||
@@ -701,14 +701,18 @@ $code.=<<___; | |||
701 | # define VFP_ABI_FRAME 0 | 701 | # define VFP_ABI_FRAME 0 |
702 | # define BSAES_ASM_EXTENDED_KEY | 702 | # define BSAES_ASM_EXTENDED_KEY |
703 | # define XTS_CHAIN_TWEAK | 703 | # define XTS_CHAIN_TWEAK |
704 | # define __ARM_ARCH__ 7 | 704 | # define __ARM_ARCH__ __LINUX_ARM_ARCH__ |
705 | # define __ARM_MAX_ARCH__ 7 | ||
705 | #endif | 706 | #endif |
706 | 707 | ||
707 | #ifdef __thumb__ | 708 | #ifdef __thumb__ |
708 | # define adrl adr | 709 | # define adrl adr |
709 | #endif | 710 | #endif |
710 | 711 | ||
711 | #if __ARM_ARCH__>=7 | 712 | #if __ARM_MAX_ARCH__>=7 |
713 | .arch armv7-a | ||
714 | .fpu neon | ||
715 | |||
712 | .text | 716 | .text |
713 | .syntax unified @ ARMv7-capable assembler is expected to handle this | 717 | .syntax unified @ ARMv7-capable assembler is expected to handle this |
714 | #ifdef __thumb2__ | 718 | #ifdef __thumb2__ |
@@ -717,8 +721,6 @@ $code.=<<___; | |||
717 | .code 32 | 721 | .code 32 |
718 | #endif | 722 | #endif |
719 | 723 | ||
720 | .fpu neon | ||
721 | |||
722 | .type _bsaes_decrypt8,%function | 724 | .type _bsaes_decrypt8,%function |
723 | .align 4 | 725 | .align 4 |
724 | _bsaes_decrypt8: | 726 | _bsaes_decrypt8: |
@@ -2076,9 +2078,11 @@ bsaes_xts_decrypt: | |||
2076 | vld1.8 {@XMM[8]}, [r0] @ initial tweak | 2078 | vld1.8 {@XMM[8]}, [r0] @ initial tweak |
2077 | adr $magic, .Lxts_magic | 2079 | adr $magic, .Lxts_magic |
2078 | 2080 | ||
2081 | #ifndef XTS_CHAIN_TWEAK | ||
2079 | tst $len, #0xf @ if not multiple of 16 | 2082 | tst $len, #0xf @ if not multiple of 16 |
2080 | it ne @ Thumb2 thing, sanity check in ARM | 2083 | it ne @ Thumb2 thing, sanity check in ARM |
2081 | subne $len, #0x10 @ subtract another 16 bytes | 2084 | subne $len, #0x10 @ subtract another 16 bytes |
2085 | #endif | ||
2082 | subs $len, #0x80 | 2086 | subs $len, #0x80 |
2083 | 2087 | ||
2084 | blo .Lxts_dec_short | 2088 | blo .Lxts_dec_short |
diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index 816db0bf2dd8..d995821f1698 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h | |||
@@ -185,6 +185,7 @@ | |||
185 | #define HSR_COND (0xfU << HSR_COND_SHIFT) | 185 | #define HSR_COND (0xfU << HSR_COND_SHIFT) |
186 | 186 | ||
187 | #define FSC_FAULT (0x04) | 187 | #define FSC_FAULT (0x04) |
188 | #define FSC_ACCESS (0x08) | ||
188 | #define FSC_PERM (0x0c) | 189 | #define FSC_PERM (0x0c) |
189 | 190 | ||
190 | /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ | 191 | /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ |
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 41008cd7c53f..d71607c16601 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <asm/fpstate.h> | 27 | #include <asm/fpstate.h> |
28 | #include <kvm/arm_arch_timer.h> | 28 | #include <kvm/arm_arch_timer.h> |
29 | 29 | ||
30 | #define __KVM_HAVE_ARCH_INTC_INITIALIZED | ||
31 | |||
30 | #if defined(CONFIG_KVM_ARM_MAX_VCPUS) | 32 | #if defined(CONFIG_KVM_ARM_MAX_VCPUS) |
31 | #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS | 33 | #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS |
32 | #else | 34 | #else |
@@ -165,19 +167,10 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | |||
165 | 167 | ||
166 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); | 168 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); |
167 | int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); | 169 | int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); |
170 | int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); | ||
171 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | ||
168 | 172 | ||
169 | /* We do not have shadow page tables, hence the empty hooks */ | 173 | /* We do not have shadow page tables, hence the empty hooks */ |
170 | static inline int kvm_age_hva(struct kvm *kvm, unsigned long start, | ||
171 | unsigned long end) | ||
172 | { | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) | ||
177 | { | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, | 174 | static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, |
182 | unsigned long address) | 175 | unsigned long address) |
183 | { | 176 | { |
diff --git a/arch/arm/include/asm/kvm_mmio.h b/arch/arm/include/asm/kvm_mmio.h index 3f83db2f6cf0..d8e90c8cb5fa 100644 --- a/arch/arm/include/asm/kvm_mmio.h +++ b/arch/arm/include/asm/kvm_mmio.h | |||
@@ -28,28 +28,6 @@ struct kvm_decode { | |||
28 | bool sign_extend; | 28 | bool sign_extend; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | /* | ||
32 | * The in-kernel MMIO emulation code wants to use a copy of run->mmio, | ||
33 | * which is an anonymous type. Use our own type instead. | ||
34 | */ | ||
35 | struct kvm_exit_mmio { | ||
36 | phys_addr_t phys_addr; | ||
37 | u8 data[8]; | ||
38 | u32 len; | ||
39 | bool is_write; | ||
40 | void *private; | ||
41 | }; | ||
42 | |||
43 | static inline void kvm_prepare_mmio(struct kvm_run *run, | ||
44 | struct kvm_exit_mmio *mmio) | ||
45 | { | ||
46 | run->mmio.phys_addr = mmio->phys_addr; | ||
47 | run->mmio.len = mmio->len; | ||
48 | run->mmio.is_write = mmio->is_write; | ||
49 | memcpy(run->mmio.data, mmio->data, mmio->len); | ||
50 | run->exit_reason = KVM_EXIT_MMIO; | ||
51 | } | ||
52 | |||
53 | int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run); | 31 | int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run); |
54 | int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, | 32 | int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, |
55 | phys_addr_t fault_ipa); | 33 | phys_addr_t fault_ipa); |
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 37ca2a4c6f09..4cf48c3aca13 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h | |||
@@ -149,29 +149,28 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd) | |||
149 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ | 149 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ |
150 | }) | 150 | }) |
151 | 151 | ||
152 | #define kvm_pgd_index(addr) pgd_index(addr) | ||
153 | |||
152 | static inline bool kvm_page_empty(void *ptr) | 154 | static inline bool kvm_page_empty(void *ptr) |
153 | { | 155 | { |
154 | struct page *ptr_page = virt_to_page(ptr); | 156 | struct page *ptr_page = virt_to_page(ptr); |
155 | return page_count(ptr_page) == 1; | 157 | return page_count(ptr_page) == 1; |
156 | } | 158 | } |
157 | 159 | ||
158 | |||
159 | #define kvm_pte_table_empty(kvm, ptep) kvm_page_empty(ptep) | 160 | #define kvm_pte_table_empty(kvm, ptep) kvm_page_empty(ptep) |
160 | #define kvm_pmd_table_empty(kvm, pmdp) kvm_page_empty(pmdp) | 161 | #define kvm_pmd_table_empty(kvm, pmdp) kvm_page_empty(pmdp) |
161 | #define kvm_pud_table_empty(kvm, pudp) (0) | 162 | #define kvm_pud_table_empty(kvm, pudp) (0) |
162 | 163 | ||
163 | #define KVM_PREALLOC_LEVEL 0 | 164 | #define KVM_PREALLOC_LEVEL 0 |
164 | 165 | ||
165 | static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd) | 166 | static inline void *kvm_get_hwpgd(struct kvm *kvm) |
166 | { | 167 | { |
167 | return 0; | 168 | return kvm->arch.pgd; |
168 | } | 169 | } |
169 | 170 | ||
170 | static inline void kvm_free_hwpgd(struct kvm *kvm) { } | 171 | static inline unsigned int kvm_get_hwpgd_size(void) |
171 | |||
172 | static inline void *kvm_get_hwpgd(struct kvm *kvm) | ||
173 | { | 172 | { |
174 | return kvm->arch.pgd; | 173 | return PTRS_PER_S2_PGD * sizeof(pgd_t); |
175 | } | 174 | } |
176 | 175 | ||
177 | struct kvm; | 176 | struct kvm; |
@@ -207,7 +206,7 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn, | |||
207 | 206 | ||
208 | bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached; | 207 | bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached; |
209 | 208 | ||
210 | VM_BUG_ON(size & PAGE_MASK); | 209 | VM_BUG_ON(size & ~PAGE_MASK); |
211 | 210 | ||
212 | if (!need_flush && !icache_is_pipt()) | 211 | if (!need_flush && !icache_is_pipt()) |
213 | goto vipt_cache; | 212 | goto vipt_cache; |
diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S index 80a6501b4d50..c3c45e628e33 100644 --- a/arch/arm/include/debug/at91.S +++ b/arch/arm/include/debug/at91.S | |||
@@ -18,8 +18,11 @@ | |||
18 | #define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */ | 18 | #define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */ |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | /* Keep in sync with mach-at91/include/mach/hardware.h */ | 21 | #ifdef CONFIG_MMU |
22 | #define AT91_IO_P2V(x) ((x) - 0x01000000) | 22 | #define AT91_IO_P2V(x) ((x) - 0x01000000) |
23 | #else | ||
24 | #define AT91_IO_P2V(x) (x) | ||
25 | #endif | ||
23 | 26 | ||
24 | #define AT91_DBGU_SR (0x14) /* Status Register */ | 27 | #define AT91_DBGU_SR (0x14) /* Status Register */ |
25 | #define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */ | 28 | #define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */ |
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index 0db25bc32864..2499867dd0d8 100644 --- a/arch/arm/include/uapi/asm/kvm.h +++ b/arch/arm/include/uapi/asm/kvm.h | |||
@@ -198,6 +198,9 @@ struct kvm_arch_memory_slot { | |||
198 | /* Highest supported SPI, from VGIC_NR_IRQS */ | 198 | /* Highest supported SPI, from VGIC_NR_IRQS */ |
199 | #define KVM_ARM_IRQ_GIC_MAX 127 | 199 | #define KVM_ARM_IRQ_GIC_MAX 127 |
200 | 200 | ||
201 | /* One single KVM irqchip, ie. the VGIC */ | ||
202 | #define KVM_NR_IRQCHIPS 1 | ||
203 | |||
201 | /* PSCI interface */ | 204 | /* PSCI interface */ |
202 | #define KVM_PSCI_FN_BASE 0x95c1ba5e | 205 | #define KVM_PSCI_FN_BASE 0x95c1ba5e |
203 | #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) | 206 | #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) |
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 2d2d6087b9b1..488eaac56028 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c | |||
@@ -190,7 +190,6 @@ int main(void) | |||
190 | DEFINE(VCPU_HxFAR, offsetof(struct kvm_vcpu, arch.fault.hxfar)); | 190 | DEFINE(VCPU_HxFAR, offsetof(struct kvm_vcpu, arch.fault.hxfar)); |
191 | DEFINE(VCPU_HPFAR, offsetof(struct kvm_vcpu, arch.fault.hpfar)); | 191 | DEFINE(VCPU_HPFAR, offsetof(struct kvm_vcpu, arch.fault.hpfar)); |
192 | DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc)); | 192 | DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc)); |
193 | #ifdef CONFIG_KVM_ARM_VGIC | ||
194 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); | 193 | DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); |
195 | DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr)); | 194 | DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr)); |
196 | DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr)); | 195 | DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr)); |
@@ -200,14 +199,11 @@ int main(void) | |||
200 | DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr)); | 199 | DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr)); |
201 | DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr)); | 200 | DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr)); |
202 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); | 201 | DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); |
203 | #ifdef CONFIG_KVM_ARM_TIMER | ||
204 | DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); | 202 | DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); |
205 | DEFINE(VCPU_TIMER_CNTV_CVAL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval)); | 203 | DEFINE(VCPU_TIMER_CNTV_CVAL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval)); |
206 | DEFINE(KVM_TIMER_CNTVOFF, offsetof(struct kvm, arch.timer.cntvoff)); | 204 | DEFINE(KVM_TIMER_CNTVOFF, offsetof(struct kvm, arch.timer.cntvoff)); |
207 | DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled)); | 205 | DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled)); |
208 | #endif | ||
209 | DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); | 206 | DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); |
210 | #endif | ||
211 | DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); | 207 | DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); |
212 | #endif | 208 | #endif |
213 | return 0; | 209 | return 0; |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index e55408e96559..1d60bebea4b8 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -246,12 +246,9 @@ static int __get_cpu_architecture(void) | |||
246 | if (cpu_arch) | 246 | if (cpu_arch) |
247 | cpu_arch += CPU_ARCH_ARMv3; | 247 | cpu_arch += CPU_ARCH_ARMv3; |
248 | } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { | 248 | } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { |
249 | unsigned int mmfr0; | ||
250 | |||
251 | /* Revised CPUID format. Read the Memory Model Feature | 249 | /* Revised CPUID format. Read the Memory Model Feature |
252 | * Register 0 and check for VMSAv7 or PMSAv7 */ | 250 | * Register 0 and check for VMSAv7 or PMSAv7 */ |
253 | asm("mrc p15, 0, %0, c0, c1, 4" | 251 | unsigned int mmfr0 = read_cpuid_ext(CPUID_EXT_MMFR0); |
254 | : "=r" (mmfr0)); | ||
255 | if ((mmfr0 & 0x0000000f) >= 0x00000003 || | 252 | if ((mmfr0 & 0x0000000f) >= 0x00000003 || |
256 | (mmfr0 & 0x000000f0) >= 0x00000030) | 253 | (mmfr0 & 0x000000f0) >= 0x00000030) |
257 | cpu_arch = CPU_ARCH_ARMv7; | 254 | cpu_arch = CPU_ARCH_ARMv7; |
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 338ace78ed18..f1f79d104309 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig | |||
@@ -18,6 +18,7 @@ if VIRTUALIZATION | |||
18 | 18 | ||
19 | config KVM | 19 | config KVM |
20 | bool "Kernel-based Virtual Machine (KVM) support" | 20 | bool "Kernel-based Virtual Machine (KVM) support" |
21 | depends on MMU && OF | ||
21 | select PREEMPT_NOTIFIERS | 22 | select PREEMPT_NOTIFIERS |
22 | select ANON_INODES | 23 | select ANON_INODES |
23 | select HAVE_KVM_CPU_RELAX_INTERCEPT | 24 | select HAVE_KVM_CPU_RELAX_INTERCEPT |
@@ -26,10 +27,12 @@ config KVM | |||
26 | select KVM_ARM_HOST | 27 | select KVM_ARM_HOST |
27 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT | 28 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT |
28 | select SRCU | 29 | select SRCU |
29 | depends on ARM_VIRT_EXT && ARM_LPAE | 30 | select MMU_NOTIFIER |
31 | select HAVE_KVM_EVENTFD | ||
32 | select HAVE_KVM_IRQFD | ||
33 | depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER | ||
30 | ---help--- | 34 | ---help--- |
31 | Support hosting virtualized guest machines. You will also | 35 | Support hosting virtualized guest machines. |
32 | need to select one or more of the processor modules below. | ||
33 | 36 | ||
34 | This module provides access to the hardware capabilities through | 37 | This module provides access to the hardware capabilities through |
35 | a character device node named /dev/kvm. | 38 | a character device node named /dev/kvm. |
@@ -37,10 +40,7 @@ config KVM | |||
37 | If unsure, say N. | 40 | If unsure, say N. |
38 | 41 | ||
39 | config KVM_ARM_HOST | 42 | config KVM_ARM_HOST |
40 | bool "KVM host support for ARM cpus." | 43 | bool |
41 | depends on KVM | ||
42 | depends on MMU | ||
43 | select MMU_NOTIFIER | ||
44 | ---help--- | 44 | ---help--- |
45 | Provides host support for ARM processors. | 45 | Provides host support for ARM processors. |
46 | 46 | ||
@@ -55,20 +55,4 @@ config KVM_ARM_MAX_VCPUS | |||
55 | large, so only choose a reasonable number that you expect to | 55 | large, so only choose a reasonable number that you expect to |
56 | actually use. | 56 | actually use. |
57 | 57 | ||
58 | config KVM_ARM_VGIC | ||
59 | bool "KVM support for Virtual GIC" | ||
60 | depends on KVM_ARM_HOST && OF | ||
61 | select HAVE_KVM_IRQCHIP | ||
62 | default y | ||
63 | ---help--- | ||
64 | Adds support for a hardware assisted, in-kernel GIC emulation. | ||
65 | |||
66 | config KVM_ARM_TIMER | ||
67 | bool "KVM support for Architected Timers" | ||
68 | depends on KVM_ARM_VGIC && ARM_ARCH_TIMER | ||
69 | select HAVE_KVM_IRQCHIP | ||
70 | default y | ||
71 | ---help--- | ||
72 | Adds support for the Architected Timers in virtual machines | ||
73 | |||
74 | endif # VIRTUALIZATION | 58 | endif # VIRTUALIZATION |
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index 443b8bea43e9..139e46c08b6e 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile | |||
@@ -7,7 +7,7 @@ ifeq ($(plus_virt),+virt) | |||
7 | plus_virt_def := -DREQUIRES_VIRT=1 | 7 | plus_virt_def := -DREQUIRES_VIRT=1 |
8 | endif | 8 | endif |
9 | 9 | ||
10 | ccflags-y += -Ivirt/kvm -Iarch/arm/kvm | 10 | ccflags-y += -Iarch/arm/kvm |
11 | CFLAGS_arm.o := -I. $(plus_virt_def) | 11 | CFLAGS_arm.o := -I. $(plus_virt_def) |
12 | CFLAGS_mmu.o := -I. | 12 | CFLAGS_mmu.o := -I. |
13 | 13 | ||
@@ -15,12 +15,12 @@ AFLAGS_init.o := -Wa,-march=armv7-a$(plus_virt) | |||
15 | AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt) | 15 | AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt) |
16 | 16 | ||
17 | KVM := ../../../virt/kvm | 17 | KVM := ../../../virt/kvm |
18 | kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o | 18 | kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o |
19 | 19 | ||
20 | obj-y += kvm-arm.o init.o interrupts.o | 20 | obj-y += kvm-arm.o init.o interrupts.o |
21 | obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o | 21 | obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o |
22 | obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o | 22 | obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o |
23 | obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o | 23 | obj-y += $(KVM)/arm/vgic.o |
24 | obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o | 24 | obj-y += $(KVM)/arm/vgic-v2.o |
25 | obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2-emul.o | 25 | obj-y += $(KVM)/arm/vgic-v2-emul.o |
26 | obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o | 26 | obj-y += $(KVM)/arm/arch_timer.o |
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 07e7eb1d7ab6..6f536451ab78 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -61,8 +61,6 @@ static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); | |||
61 | static u8 kvm_next_vmid; | 61 | static u8 kvm_next_vmid; |
62 | static DEFINE_SPINLOCK(kvm_vmid_lock); | 62 | static DEFINE_SPINLOCK(kvm_vmid_lock); |
63 | 63 | ||
64 | static bool vgic_present; | ||
65 | |||
66 | static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) | 64 | static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) |
67 | { | 65 | { |
68 | BUG_ON(preemptible()); | 66 | BUG_ON(preemptible()); |
@@ -173,8 +171,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
173 | int r; | 171 | int r; |
174 | switch (ext) { | 172 | switch (ext) { |
175 | case KVM_CAP_IRQCHIP: | 173 | case KVM_CAP_IRQCHIP: |
176 | r = vgic_present; | 174 | case KVM_CAP_IRQFD: |
177 | break; | 175 | case KVM_CAP_IOEVENTFD: |
178 | case KVM_CAP_DEVICE_CTRL: | 176 | case KVM_CAP_DEVICE_CTRL: |
179 | case KVM_CAP_USER_MEMORY: | 177 | case KVM_CAP_USER_MEMORY: |
180 | case KVM_CAP_SYNC_MMU: | 178 | case KVM_CAP_SYNC_MMU: |
@@ -183,6 +181,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
183 | case KVM_CAP_ARM_PSCI: | 181 | case KVM_CAP_ARM_PSCI: |
184 | case KVM_CAP_ARM_PSCI_0_2: | 182 | case KVM_CAP_ARM_PSCI_0_2: |
185 | case KVM_CAP_READONLY_MEM: | 183 | case KVM_CAP_READONLY_MEM: |
184 | case KVM_CAP_MP_STATE: | ||
186 | r = 1; | 185 | r = 1; |
187 | break; | 186 | break; |
188 | case KVM_CAP_COALESCED_MMIO: | 187 | case KVM_CAP_COALESCED_MMIO: |
@@ -268,7 +267,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | |||
268 | 267 | ||
269 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) | 268 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) |
270 | { | 269 | { |
271 | return 0; | 270 | return kvm_timer_should_fire(vcpu); |
272 | } | 271 | } |
273 | 272 | ||
274 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | 273 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) |
@@ -313,13 +312,29 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | |||
313 | int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, | 312 | int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, |
314 | struct kvm_mp_state *mp_state) | 313 | struct kvm_mp_state *mp_state) |
315 | { | 314 | { |
316 | return -EINVAL; | 315 | if (vcpu->arch.pause) |
316 | mp_state->mp_state = KVM_MP_STATE_STOPPED; | ||
317 | else | ||
318 | mp_state->mp_state = KVM_MP_STATE_RUNNABLE; | ||
319 | |||
320 | return 0; | ||
317 | } | 321 | } |
318 | 322 | ||
319 | int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, | 323 | int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, |
320 | struct kvm_mp_state *mp_state) | 324 | struct kvm_mp_state *mp_state) |
321 | { | 325 | { |
322 | return -EINVAL; | 326 | switch (mp_state->mp_state) { |
327 | case KVM_MP_STATE_RUNNABLE: | ||
328 | vcpu->arch.pause = false; | ||
329 | break; | ||
330 | case KVM_MP_STATE_STOPPED: | ||
331 | vcpu->arch.pause = true; | ||
332 | break; | ||
333 | default: | ||
334 | return -EINVAL; | ||
335 | } | ||
336 | |||
337 | return 0; | ||
323 | } | 338 | } |
324 | 339 | ||
325 | /** | 340 | /** |
@@ -452,6 +467,11 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) | |||
452 | return 0; | 467 | return 0; |
453 | } | 468 | } |
454 | 469 | ||
470 | bool kvm_arch_intc_initialized(struct kvm *kvm) | ||
471 | { | ||
472 | return vgic_initialized(kvm); | ||
473 | } | ||
474 | |||
455 | static void vcpu_pause(struct kvm_vcpu *vcpu) | 475 | static void vcpu_pause(struct kvm_vcpu *vcpu) |
456 | { | 476 | { |
457 | wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu); | 477 | wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu); |
@@ -540,7 +560,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
540 | 560 | ||
541 | vcpu->mode = OUTSIDE_GUEST_MODE; | 561 | vcpu->mode = OUTSIDE_GUEST_MODE; |
542 | kvm_guest_exit(); | 562 | kvm_guest_exit(); |
543 | trace_kvm_exit(*vcpu_pc(vcpu)); | 563 | trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu)); |
544 | /* | 564 | /* |
545 | * We may have taken a host interrupt in HYP mode (ie | 565 | * We may have taken a host interrupt in HYP mode (ie |
546 | * while executing the guest). This interrupt is still | 566 | * while executing the guest). This interrupt is still |
@@ -831,8 +851,6 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm, | |||
831 | 851 | ||
832 | switch (dev_id) { | 852 | switch (dev_id) { |
833 | case KVM_ARM_DEVICE_VGIC_V2: | 853 | case KVM_ARM_DEVICE_VGIC_V2: |
834 | if (!vgic_present) | ||
835 | return -ENXIO; | ||
836 | return kvm_vgic_addr(kvm, type, &dev_addr->addr, true); | 854 | return kvm_vgic_addr(kvm, type, &dev_addr->addr, true); |
837 | default: | 855 | default: |
838 | return -ENODEV; | 856 | return -ENODEV; |
@@ -847,10 +865,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
847 | 865 | ||
848 | switch (ioctl) { | 866 | switch (ioctl) { |
849 | case KVM_CREATE_IRQCHIP: { | 867 | case KVM_CREATE_IRQCHIP: { |
850 | if (vgic_present) | 868 | return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2); |
851 | return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2); | ||
852 | else | ||
853 | return -ENXIO; | ||
854 | } | 869 | } |
855 | case KVM_ARM_SET_DEVICE_ADDR: { | 870 | case KVM_ARM_SET_DEVICE_ADDR: { |
856 | struct kvm_arm_device_addr dev_addr; | 871 | struct kvm_arm_device_addr dev_addr; |
@@ -1035,10 +1050,6 @@ static int init_hyp_mode(void) | |||
1035 | if (err) | 1050 | if (err) |
1036 | goto out_free_context; | 1051 | goto out_free_context; |
1037 | 1052 | ||
1038 | #ifdef CONFIG_KVM_ARM_VGIC | ||
1039 | vgic_present = true; | ||
1040 | #endif | ||
1041 | |||
1042 | /* | 1053 | /* |
1043 | * Init HYP architected timer support | 1054 | * Init HYP architected timer support |
1044 | */ | 1055 | */ |
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c index 384bab67c462..d503fbb787d3 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c | |||
@@ -109,22 +109,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
109 | return -EINVAL; | 109 | return -EINVAL; |
110 | } | 110 | } |
111 | 111 | ||
112 | #ifndef CONFIG_KVM_ARM_TIMER | ||
113 | |||
114 | #define NUM_TIMER_REGS 0 | ||
115 | |||
116 | static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | ||
117 | { | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static bool is_timer_reg(u64 index) | ||
122 | { | ||
123 | return false; | ||
124 | } | ||
125 | |||
126 | #else | ||
127 | |||
128 | #define NUM_TIMER_REGS 3 | 112 | #define NUM_TIMER_REGS 3 |
129 | 113 | ||
130 | static bool is_timer_reg(u64 index) | 114 | static bool is_timer_reg(u64 index) |
@@ -152,8 +136,6 @@ static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | |||
152 | return 0; | 136 | return 0; |
153 | } | 137 | } |
154 | 138 | ||
155 | #endif | ||
156 | |||
157 | static int set_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | 139 | static int set_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) |
158 | { | 140 | { |
159 | void __user *uaddr = (void __user *)(long)reg->addr; | 141 | void __user *uaddr = (void __user *)(long)reg->addr; |
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 14d488388480..35e4a3a0c476 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S | |||
@@ -402,7 +402,6 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
402 | * Assumes vcpu pointer in vcpu reg | 402 | * Assumes vcpu pointer in vcpu reg |
403 | */ | 403 | */ |
404 | .macro save_vgic_state | 404 | .macro save_vgic_state |
405 | #ifdef CONFIG_KVM_ARM_VGIC | ||
406 | /* Get VGIC VCTRL base into r2 */ | 405 | /* Get VGIC VCTRL base into r2 */ |
407 | ldr r2, [vcpu, #VCPU_KVM] | 406 | ldr r2, [vcpu, #VCPU_KVM] |
408 | ldr r2, [r2, #KVM_VGIC_VCTRL] | 407 | ldr r2, [r2, #KVM_VGIC_VCTRL] |
@@ -460,7 +459,6 @@ ARM_BE8(rev r6, r6 ) | |||
460 | subs r4, r4, #1 | 459 | subs r4, r4, #1 |
461 | bne 1b | 460 | bne 1b |
462 | 2: | 461 | 2: |
463 | #endif | ||
464 | .endm | 462 | .endm |
465 | 463 | ||
466 | /* | 464 | /* |
@@ -469,7 +467,6 @@ ARM_BE8(rev r6, r6 ) | |||
469 | * Assumes vcpu pointer in vcpu reg | 467 | * Assumes vcpu pointer in vcpu reg |
470 | */ | 468 | */ |
471 | .macro restore_vgic_state | 469 | .macro restore_vgic_state |
472 | #ifdef CONFIG_KVM_ARM_VGIC | ||
473 | /* Get VGIC VCTRL base into r2 */ | 470 | /* Get VGIC VCTRL base into r2 */ |
474 | ldr r2, [vcpu, #VCPU_KVM] | 471 | ldr r2, [vcpu, #VCPU_KVM] |
475 | ldr r2, [r2, #KVM_VGIC_VCTRL] | 472 | ldr r2, [r2, #KVM_VGIC_VCTRL] |
@@ -501,7 +498,6 @@ ARM_BE8(rev r6, r6 ) | |||
501 | subs r4, r4, #1 | 498 | subs r4, r4, #1 |
502 | bne 1b | 499 | bne 1b |
503 | 2: | 500 | 2: |
504 | #endif | ||
505 | .endm | 501 | .endm |
506 | 502 | ||
507 | #define CNTHCTL_PL1PCTEN (1 << 0) | 503 | #define CNTHCTL_PL1PCTEN (1 << 0) |
@@ -515,7 +511,6 @@ ARM_BE8(rev r6, r6 ) | |||
515 | * Clobbers r2-r5 | 511 | * Clobbers r2-r5 |
516 | */ | 512 | */ |
517 | .macro save_timer_state | 513 | .macro save_timer_state |
518 | #ifdef CONFIG_KVM_ARM_TIMER | ||
519 | ldr r4, [vcpu, #VCPU_KVM] | 514 | ldr r4, [vcpu, #VCPU_KVM] |
520 | ldr r2, [r4, #KVM_TIMER_ENABLED] | 515 | ldr r2, [r4, #KVM_TIMER_ENABLED] |
521 | cmp r2, #0 | 516 | cmp r2, #0 |
@@ -537,7 +532,6 @@ ARM_BE8(rev r6, r6 ) | |||
537 | mcrr p15, 4, r2, r2, c14 @ CNTVOFF | 532 | mcrr p15, 4, r2, r2, c14 @ CNTVOFF |
538 | 533 | ||
539 | 1: | 534 | 1: |
540 | #endif | ||
541 | @ Allow physical timer/counter access for the host | 535 | @ Allow physical timer/counter access for the host |
542 | mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL | 536 | mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL |
543 | orr r2, r2, #(CNTHCTL_PL1PCEN | CNTHCTL_PL1PCTEN) | 537 | orr r2, r2, #(CNTHCTL_PL1PCEN | CNTHCTL_PL1PCTEN) |
@@ -559,7 +553,6 @@ ARM_BE8(rev r6, r6 ) | |||
559 | bic r2, r2, #CNTHCTL_PL1PCEN | 553 | bic r2, r2, #CNTHCTL_PL1PCEN |
560 | mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL | 554 | mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL |
561 | 555 | ||
562 | #ifdef CONFIG_KVM_ARM_TIMER | ||
563 | ldr r4, [vcpu, #VCPU_KVM] | 556 | ldr r4, [vcpu, #VCPU_KVM] |
564 | ldr r2, [r4, #KVM_TIMER_ENABLED] | 557 | ldr r2, [r4, #KVM_TIMER_ENABLED] |
565 | cmp r2, #0 | 558 | cmp r2, #0 |
@@ -579,7 +572,6 @@ ARM_BE8(rev r6, r6 ) | |||
579 | and r2, r2, #3 | 572 | and r2, r2, #3 |
580 | mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL | 573 | mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL |
581 | 1: | 574 | 1: |
582 | #endif | ||
583 | .endm | 575 | .endm |
584 | 576 | ||
585 | .equ vmentry, 0 | 577 | .equ vmentry, 0 |
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c index 5d3bfc0eb3f0..974b1c606d04 100644 --- a/arch/arm/kvm/mmio.c +++ b/arch/arm/kvm/mmio.c | |||
@@ -121,12 +121,11 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
121 | return 0; | 121 | return 0; |
122 | } | 122 | } |
123 | 123 | ||
124 | static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | 124 | static int decode_hsr(struct kvm_vcpu *vcpu, bool *is_write, int *len) |
125 | struct kvm_exit_mmio *mmio) | ||
126 | { | 125 | { |
127 | unsigned long rt; | 126 | unsigned long rt; |
128 | int len; | 127 | int access_size; |
129 | bool is_write, sign_extend; | 128 | bool sign_extend; |
130 | 129 | ||
131 | if (kvm_vcpu_dabt_isextabt(vcpu)) { | 130 | if (kvm_vcpu_dabt_isextabt(vcpu)) { |
132 | /* cache operation on I/O addr, tell guest unsupported */ | 131 | /* cache operation on I/O addr, tell guest unsupported */ |
@@ -140,17 +139,15 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
140 | return 1; | 139 | return 1; |
141 | } | 140 | } |
142 | 141 | ||
143 | len = kvm_vcpu_dabt_get_as(vcpu); | 142 | access_size = kvm_vcpu_dabt_get_as(vcpu); |
144 | if (unlikely(len < 0)) | 143 | if (unlikely(access_size < 0)) |
145 | return len; | 144 | return access_size; |
146 | 145 | ||
147 | is_write = kvm_vcpu_dabt_iswrite(vcpu); | 146 | *is_write = kvm_vcpu_dabt_iswrite(vcpu); |
148 | sign_extend = kvm_vcpu_dabt_issext(vcpu); | 147 | sign_extend = kvm_vcpu_dabt_issext(vcpu); |
149 | rt = kvm_vcpu_dabt_get_rd(vcpu); | 148 | rt = kvm_vcpu_dabt_get_rd(vcpu); |
150 | 149 | ||
151 | mmio->is_write = is_write; | 150 | *len = access_size; |
152 | mmio->phys_addr = fault_ipa; | ||
153 | mmio->len = len; | ||
154 | vcpu->arch.mmio_decode.sign_extend = sign_extend; | 151 | vcpu->arch.mmio_decode.sign_extend = sign_extend; |
155 | vcpu->arch.mmio_decode.rt = rt; | 152 | vcpu->arch.mmio_decode.rt = rt; |
156 | 153 | ||
@@ -165,20 +162,20 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
165 | int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, | 162 | int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, |
166 | phys_addr_t fault_ipa) | 163 | phys_addr_t fault_ipa) |
167 | { | 164 | { |
168 | struct kvm_exit_mmio mmio; | ||
169 | unsigned long data; | 165 | unsigned long data; |
170 | unsigned long rt; | 166 | unsigned long rt; |
171 | int ret; | 167 | int ret; |
168 | bool is_write; | ||
169 | int len; | ||
170 | u8 data_buf[8]; | ||
172 | 171 | ||
173 | /* | 172 | /* |
174 | * Prepare MMIO operation. First stash it in a private | 173 | * Prepare MMIO operation. First decode the syndrome data we get |
175 | * structure that we can use for in-kernel emulation. If the | 174 | * from the CPU. Then try if some in-kernel emulation feels |
176 | * kernel can't handle it, copy it into run->mmio and let user | 175 | * responsible, otherwise let user space do its magic. |
177 | * space do its magic. | ||
178 | */ | 176 | */ |
179 | |||
180 | if (kvm_vcpu_dabt_isvalid(vcpu)) { | 177 | if (kvm_vcpu_dabt_isvalid(vcpu)) { |
181 | ret = decode_hsr(vcpu, fault_ipa, &mmio); | 178 | ret = decode_hsr(vcpu, &is_write, &len); |
182 | if (ret) | 179 | if (ret) |
183 | return ret; | 180 | return ret; |
184 | } else { | 181 | } else { |
@@ -188,21 +185,34 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, | |||
188 | 185 | ||
189 | rt = vcpu->arch.mmio_decode.rt; | 186 | rt = vcpu->arch.mmio_decode.rt; |
190 | 187 | ||
191 | if (mmio.is_write) { | 188 | if (is_write) { |
192 | data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), | 189 | data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), len); |
193 | mmio.len); | 190 | |
191 | trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data); | ||
192 | mmio_write_buf(data_buf, len, data); | ||
194 | 193 | ||
195 | trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, mmio.len, | 194 | ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len, |
196 | fault_ipa, data); | 195 | data_buf); |
197 | mmio_write_buf(mmio.data, mmio.len, data); | ||
198 | } else { | 196 | } else { |
199 | trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, mmio.len, | 197 | trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len, |
200 | fault_ipa, 0); | 198 | fault_ipa, 0); |
199 | |||
200 | ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len, | ||
201 | data_buf); | ||
201 | } | 202 | } |
202 | 203 | ||
203 | if (vgic_handle_mmio(vcpu, run, &mmio)) | 204 | /* Now prepare kvm_run for the potential return to userland. */ |
205 | run->mmio.is_write = is_write; | ||
206 | run->mmio.phys_addr = fault_ipa; | ||
207 | run->mmio.len = len; | ||
208 | memcpy(run->mmio.data, data_buf, len); | ||
209 | |||
210 | if (!ret) { | ||
211 | /* We handled the access successfully in the kernel. */ | ||
212 | kvm_handle_mmio_return(vcpu, run); | ||
204 | return 1; | 213 | return 1; |
214 | } | ||
205 | 215 | ||
206 | kvm_prepare_mmio(run, &mmio); | 216 | run->exit_reason = KVM_EXIT_MMIO; |
207 | return 0; | 217 | return 0; |
208 | } | 218 | } |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 3e6859bc3e11..15b050d46fc9 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -290,7 +290,7 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp, | |||
290 | phys_addr_t addr = start, end = start + size; | 290 | phys_addr_t addr = start, end = start + size; |
291 | phys_addr_t next; | 291 | phys_addr_t next; |
292 | 292 | ||
293 | pgd = pgdp + pgd_index(addr); | 293 | pgd = pgdp + kvm_pgd_index(addr); |
294 | do { | 294 | do { |
295 | next = kvm_pgd_addr_end(addr, end); | 295 | next = kvm_pgd_addr_end(addr, end); |
296 | if (!pgd_none(*pgd)) | 296 | if (!pgd_none(*pgd)) |
@@ -355,7 +355,7 @@ static void stage2_flush_memslot(struct kvm *kvm, | |||
355 | phys_addr_t next; | 355 | phys_addr_t next; |
356 | pgd_t *pgd; | 356 | pgd_t *pgd; |
357 | 357 | ||
358 | pgd = kvm->arch.pgd + pgd_index(addr); | 358 | pgd = kvm->arch.pgd + kvm_pgd_index(addr); |
359 | do { | 359 | do { |
360 | next = kvm_pgd_addr_end(addr, end); | 360 | next = kvm_pgd_addr_end(addr, end); |
361 | stage2_flush_puds(kvm, pgd, addr, next); | 361 | stage2_flush_puds(kvm, pgd, addr, next); |
@@ -632,6 +632,20 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr) | |||
632 | __phys_to_pfn(phys_addr), PAGE_HYP_DEVICE); | 632 | __phys_to_pfn(phys_addr), PAGE_HYP_DEVICE); |
633 | } | 633 | } |
634 | 634 | ||
635 | /* Free the HW pgd, one page at a time */ | ||
636 | static void kvm_free_hwpgd(void *hwpgd) | ||
637 | { | ||
638 | free_pages_exact(hwpgd, kvm_get_hwpgd_size()); | ||
639 | } | ||
640 | |||
641 | /* Allocate the HW PGD, making sure that each page gets its own refcount */ | ||
642 | static void *kvm_alloc_hwpgd(void) | ||
643 | { | ||
644 | unsigned int size = kvm_get_hwpgd_size(); | ||
645 | |||
646 | return alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); | ||
647 | } | ||
648 | |||
635 | /** | 649 | /** |
636 | * kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation. | 650 | * kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation. |
637 | * @kvm: The KVM struct pointer for the VM. | 651 | * @kvm: The KVM struct pointer for the VM. |
@@ -645,15 +659,31 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr) | |||
645 | */ | 659 | */ |
646 | int kvm_alloc_stage2_pgd(struct kvm *kvm) | 660 | int kvm_alloc_stage2_pgd(struct kvm *kvm) |
647 | { | 661 | { |
648 | int ret; | ||
649 | pgd_t *pgd; | 662 | pgd_t *pgd; |
663 | void *hwpgd; | ||
650 | 664 | ||
651 | if (kvm->arch.pgd != NULL) { | 665 | if (kvm->arch.pgd != NULL) { |
652 | kvm_err("kvm_arch already initialized?\n"); | 666 | kvm_err("kvm_arch already initialized?\n"); |
653 | return -EINVAL; | 667 | return -EINVAL; |
654 | } | 668 | } |
655 | 669 | ||
670 | hwpgd = kvm_alloc_hwpgd(); | ||
671 | if (!hwpgd) | ||
672 | return -ENOMEM; | ||
673 | |||
674 | /* When the kernel uses more levels of page tables than the | ||
675 | * guest, we allocate a fake PGD and pre-populate it to point | ||
676 | * to the next-level page table, which will be the real | ||
677 | * initial page table pointed to by the VTTBR. | ||
678 | * | ||
679 | * When KVM_PREALLOC_LEVEL==2, we allocate a single page for | ||
680 | * the PMD and the kernel will use folded pud. | ||
681 | * When KVM_PREALLOC_LEVEL==1, we allocate 2 consecutive PUD | ||
682 | * pages. | ||
683 | */ | ||
656 | if (KVM_PREALLOC_LEVEL > 0) { | 684 | if (KVM_PREALLOC_LEVEL > 0) { |
685 | int i; | ||
686 | |||
657 | /* | 687 | /* |
658 | * Allocate fake pgd for the page table manipulation macros to | 688 | * Allocate fake pgd for the page table manipulation macros to |
659 | * work. This is not used by the hardware and we have no | 689 | * work. This is not used by the hardware and we have no |
@@ -661,30 +691,32 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm) | |||
661 | */ | 691 | */ |
662 | pgd = (pgd_t *)kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t), | 692 | pgd = (pgd_t *)kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t), |
663 | GFP_KERNEL | __GFP_ZERO); | 693 | GFP_KERNEL | __GFP_ZERO); |
694 | |||
695 | if (!pgd) { | ||
696 | kvm_free_hwpgd(hwpgd); | ||
697 | return -ENOMEM; | ||
698 | } | ||
699 | |||
700 | /* Plug the HW PGD into the fake one. */ | ||
701 | for (i = 0; i < PTRS_PER_S2_PGD; i++) { | ||
702 | if (KVM_PREALLOC_LEVEL == 1) | ||
703 | pgd_populate(NULL, pgd + i, | ||
704 | (pud_t *)hwpgd + i * PTRS_PER_PUD); | ||
705 | else if (KVM_PREALLOC_LEVEL == 2) | ||
706 | pud_populate(NULL, pud_offset(pgd, 0) + i, | ||
707 | (pmd_t *)hwpgd + i * PTRS_PER_PMD); | ||
708 | } | ||
664 | } else { | 709 | } else { |
665 | /* | 710 | /* |
666 | * Allocate actual first-level Stage-2 page table used by the | 711 | * Allocate actual first-level Stage-2 page table used by the |
667 | * hardware for Stage-2 page table walks. | 712 | * hardware for Stage-2 page table walks. |
668 | */ | 713 | */ |
669 | pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, S2_PGD_ORDER); | 714 | pgd = (pgd_t *)hwpgd; |
670 | } | 715 | } |
671 | 716 | ||
672 | if (!pgd) | ||
673 | return -ENOMEM; | ||
674 | |||
675 | ret = kvm_prealloc_hwpgd(kvm, pgd); | ||
676 | if (ret) | ||
677 | goto out_err; | ||
678 | |||
679 | kvm_clean_pgd(pgd); | 717 | kvm_clean_pgd(pgd); |
680 | kvm->arch.pgd = pgd; | 718 | kvm->arch.pgd = pgd; |
681 | return 0; | 719 | return 0; |
682 | out_err: | ||
683 | if (KVM_PREALLOC_LEVEL > 0) | ||
684 | kfree(pgd); | ||
685 | else | ||
686 | free_pages((unsigned long)pgd, S2_PGD_ORDER); | ||
687 | return ret; | ||
688 | } | 720 | } |
689 | 721 | ||
690 | /** | 722 | /** |
@@ -785,11 +817,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm) | |||
785 | return; | 817 | return; |
786 | 818 | ||
787 | unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); | 819 | unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); |
788 | kvm_free_hwpgd(kvm); | 820 | kvm_free_hwpgd(kvm_get_hwpgd(kvm)); |
789 | if (KVM_PREALLOC_LEVEL > 0) | 821 | if (KVM_PREALLOC_LEVEL > 0) |
790 | kfree(kvm->arch.pgd); | 822 | kfree(kvm->arch.pgd); |
791 | else | 823 | |
792 | free_pages((unsigned long)kvm->arch.pgd, S2_PGD_ORDER); | ||
793 | kvm->arch.pgd = NULL; | 824 | kvm->arch.pgd = NULL; |
794 | } | 825 | } |
795 | 826 | ||
@@ -799,7 +830,7 @@ static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache | |||
799 | pgd_t *pgd; | 830 | pgd_t *pgd; |
800 | pud_t *pud; | 831 | pud_t *pud; |
801 | 832 | ||
802 | pgd = kvm->arch.pgd + pgd_index(addr); | 833 | pgd = kvm->arch.pgd + kvm_pgd_index(addr); |
803 | if (WARN_ON(pgd_none(*pgd))) { | 834 | if (WARN_ON(pgd_none(*pgd))) { |
804 | if (!cache) | 835 | if (!cache) |
805 | return NULL; | 836 | return NULL; |
@@ -1089,7 +1120,7 @@ static void stage2_wp_range(struct kvm *kvm, phys_addr_t addr, phys_addr_t end) | |||
1089 | pgd_t *pgd; | 1120 | pgd_t *pgd; |
1090 | phys_addr_t next; | 1121 | phys_addr_t next; |
1091 | 1122 | ||
1092 | pgd = kvm->arch.pgd + pgd_index(addr); | 1123 | pgd = kvm->arch.pgd + kvm_pgd_index(addr); |
1093 | do { | 1124 | do { |
1094 | /* | 1125 | /* |
1095 | * Release kvm_mmu_lock periodically if the memory region is | 1126 | * Release kvm_mmu_lock periodically if the memory region is |
@@ -1299,10 +1330,51 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
1299 | 1330 | ||
1300 | out_unlock: | 1331 | out_unlock: |
1301 | spin_unlock(&kvm->mmu_lock); | 1332 | spin_unlock(&kvm->mmu_lock); |
1333 | kvm_set_pfn_accessed(pfn); | ||
1302 | kvm_release_pfn_clean(pfn); | 1334 | kvm_release_pfn_clean(pfn); |
1303 | return ret; | 1335 | return ret; |
1304 | } | 1336 | } |
1305 | 1337 | ||
1338 | /* | ||
1339 | * Resolve the access fault by making the page young again. | ||
1340 | * Note that because the faulting entry is guaranteed not to be | ||
1341 | * cached in the TLB, we don't need to invalidate anything. | ||
1342 | */ | ||
1343 | static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa) | ||
1344 | { | ||
1345 | pmd_t *pmd; | ||
1346 | pte_t *pte; | ||
1347 | pfn_t pfn; | ||
1348 | bool pfn_valid = false; | ||
1349 | |||
1350 | trace_kvm_access_fault(fault_ipa); | ||
1351 | |||
1352 | spin_lock(&vcpu->kvm->mmu_lock); | ||
1353 | |||
1354 | pmd = stage2_get_pmd(vcpu->kvm, NULL, fault_ipa); | ||
1355 | if (!pmd || pmd_none(*pmd)) /* Nothing there */ | ||
1356 | goto out; | ||
1357 | |||
1358 | if (kvm_pmd_huge(*pmd)) { /* THP, HugeTLB */ | ||
1359 | *pmd = pmd_mkyoung(*pmd); | ||
1360 | pfn = pmd_pfn(*pmd); | ||
1361 | pfn_valid = true; | ||
1362 | goto out; | ||
1363 | } | ||
1364 | |||
1365 | pte = pte_offset_kernel(pmd, fault_ipa); | ||
1366 | if (pte_none(*pte)) /* Nothing there either */ | ||
1367 | goto out; | ||
1368 | |||
1369 | *pte = pte_mkyoung(*pte); /* Just a page... */ | ||
1370 | pfn = pte_pfn(*pte); | ||
1371 | pfn_valid = true; | ||
1372 | out: | ||
1373 | spin_unlock(&vcpu->kvm->mmu_lock); | ||
1374 | if (pfn_valid) | ||
1375 | kvm_set_pfn_accessed(pfn); | ||
1376 | } | ||
1377 | |||
1306 | /** | 1378 | /** |
1307 | * kvm_handle_guest_abort - handles all 2nd stage aborts | 1379 | * kvm_handle_guest_abort - handles all 2nd stage aborts |
1308 | * @vcpu: the VCPU pointer | 1380 | * @vcpu: the VCPU pointer |
@@ -1333,7 +1405,8 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
1333 | 1405 | ||
1334 | /* Check the stage-2 fault is trans. fault or write fault */ | 1406 | /* Check the stage-2 fault is trans. fault or write fault */ |
1335 | fault_status = kvm_vcpu_trap_get_fault_type(vcpu); | 1407 | fault_status = kvm_vcpu_trap_get_fault_type(vcpu); |
1336 | if (fault_status != FSC_FAULT && fault_status != FSC_PERM) { | 1408 | if (fault_status != FSC_FAULT && fault_status != FSC_PERM && |
1409 | fault_status != FSC_ACCESS) { | ||
1337 | kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n", | 1410 | kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n", |
1338 | kvm_vcpu_trap_get_class(vcpu), | 1411 | kvm_vcpu_trap_get_class(vcpu), |
1339 | (unsigned long)kvm_vcpu_trap_get_fault(vcpu), | 1412 | (unsigned long)kvm_vcpu_trap_get_fault(vcpu), |
@@ -1369,6 +1442,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
1369 | /* Userspace should not be able to register out-of-bounds IPAs */ | 1442 | /* Userspace should not be able to register out-of-bounds IPAs */ |
1370 | VM_BUG_ON(fault_ipa >= KVM_PHYS_SIZE); | 1443 | VM_BUG_ON(fault_ipa >= KVM_PHYS_SIZE); |
1371 | 1444 | ||
1445 | if (fault_status == FSC_ACCESS) { | ||
1446 | handle_access_fault(vcpu, fault_ipa); | ||
1447 | ret = 1; | ||
1448 | goto out_unlock; | ||
1449 | } | ||
1450 | |||
1372 | ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status); | 1451 | ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status); |
1373 | if (ret == 0) | 1452 | if (ret == 0) |
1374 | ret = 1; | 1453 | ret = 1; |
@@ -1377,15 +1456,16 @@ out_unlock: | |||
1377 | return ret; | 1456 | return ret; |
1378 | } | 1457 | } |
1379 | 1458 | ||
1380 | static void handle_hva_to_gpa(struct kvm *kvm, | 1459 | static int handle_hva_to_gpa(struct kvm *kvm, |
1381 | unsigned long start, | 1460 | unsigned long start, |
1382 | unsigned long end, | 1461 | unsigned long end, |
1383 | void (*handler)(struct kvm *kvm, | 1462 | int (*handler)(struct kvm *kvm, |
1384 | gpa_t gpa, void *data), | 1463 | gpa_t gpa, void *data), |
1385 | void *data) | 1464 | void *data) |
1386 | { | 1465 | { |
1387 | struct kvm_memslots *slots; | 1466 | struct kvm_memslots *slots; |
1388 | struct kvm_memory_slot *memslot; | 1467 | struct kvm_memory_slot *memslot; |
1468 | int ret = 0; | ||
1389 | 1469 | ||
1390 | slots = kvm_memslots(kvm); | 1470 | slots = kvm_memslots(kvm); |
1391 | 1471 | ||
@@ -1409,14 +1489,17 @@ static void handle_hva_to_gpa(struct kvm *kvm, | |||
1409 | 1489 | ||
1410 | for (; gfn < gfn_end; ++gfn) { | 1490 | for (; gfn < gfn_end; ++gfn) { |
1411 | gpa_t gpa = gfn << PAGE_SHIFT; | 1491 | gpa_t gpa = gfn << PAGE_SHIFT; |
1412 | handler(kvm, gpa, data); | 1492 | ret |= handler(kvm, gpa, data); |
1413 | } | 1493 | } |
1414 | } | 1494 | } |
1495 | |||
1496 | return ret; | ||
1415 | } | 1497 | } |
1416 | 1498 | ||
1417 | static void kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) | 1499 | static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) |
1418 | { | 1500 | { |
1419 | unmap_stage2_range(kvm, gpa, PAGE_SIZE); | 1501 | unmap_stage2_range(kvm, gpa, PAGE_SIZE); |
1502 | return 0; | ||
1420 | } | 1503 | } |
1421 | 1504 | ||
1422 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) | 1505 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) |
@@ -1442,7 +1525,7 @@ int kvm_unmap_hva_range(struct kvm *kvm, | |||
1442 | return 0; | 1525 | return 0; |
1443 | } | 1526 | } |
1444 | 1527 | ||
1445 | static void kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data) | 1528 | static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data) |
1446 | { | 1529 | { |
1447 | pte_t *pte = (pte_t *)data; | 1530 | pte_t *pte = (pte_t *)data; |
1448 | 1531 | ||
@@ -1454,6 +1537,7 @@ static void kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data) | |||
1454 | * through this calling path. | 1537 | * through this calling path. |
1455 | */ | 1538 | */ |
1456 | stage2_set_pte(kvm, NULL, gpa, pte, 0); | 1539 | stage2_set_pte(kvm, NULL, gpa, pte, 0); |
1540 | return 0; | ||
1457 | } | 1541 | } |
1458 | 1542 | ||
1459 | 1543 | ||
@@ -1470,6 +1554,67 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) | |||
1470 | handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte); | 1554 | handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte); |
1471 | } | 1555 | } |
1472 | 1556 | ||
1557 | static int kvm_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) | ||
1558 | { | ||
1559 | pmd_t *pmd; | ||
1560 | pte_t *pte; | ||
1561 | |||
1562 | pmd = stage2_get_pmd(kvm, NULL, gpa); | ||
1563 | if (!pmd || pmd_none(*pmd)) /* Nothing there */ | ||
1564 | return 0; | ||
1565 | |||
1566 | if (kvm_pmd_huge(*pmd)) { /* THP, HugeTLB */ | ||
1567 | if (pmd_young(*pmd)) { | ||
1568 | *pmd = pmd_mkold(*pmd); | ||
1569 | return 1; | ||
1570 | } | ||
1571 | |||
1572 | return 0; | ||
1573 | } | ||
1574 | |||
1575 | pte = pte_offset_kernel(pmd, gpa); | ||
1576 | if (pte_none(*pte)) | ||
1577 | return 0; | ||
1578 | |||
1579 | if (pte_young(*pte)) { | ||
1580 | *pte = pte_mkold(*pte); /* Just a page... */ | ||
1581 | return 1; | ||
1582 | } | ||
1583 | |||
1584 | return 0; | ||
1585 | } | ||
1586 | |||
1587 | static int kvm_test_age_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) | ||
1588 | { | ||
1589 | pmd_t *pmd; | ||
1590 | pte_t *pte; | ||
1591 | |||
1592 | pmd = stage2_get_pmd(kvm, NULL, gpa); | ||
1593 | if (!pmd || pmd_none(*pmd)) /* Nothing there */ | ||
1594 | return 0; | ||
1595 | |||
1596 | if (kvm_pmd_huge(*pmd)) /* THP, HugeTLB */ | ||
1597 | return pmd_young(*pmd); | ||
1598 | |||
1599 | pte = pte_offset_kernel(pmd, gpa); | ||
1600 | if (!pte_none(*pte)) /* Just a page... */ | ||
1601 | return pte_young(*pte); | ||
1602 | |||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end) | ||
1607 | { | ||
1608 | trace_kvm_age_hva(start, end); | ||
1609 | return handle_hva_to_gpa(kvm, start, end, kvm_age_hva_handler, NULL); | ||
1610 | } | ||
1611 | |||
1612 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) | ||
1613 | { | ||
1614 | trace_kvm_test_age_hva(hva); | ||
1615 | return handle_hva_to_gpa(kvm, hva, hva, kvm_test_age_hva_handler, NULL); | ||
1616 | } | ||
1617 | |||
1473 | void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu) | 1618 | void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu) |
1474 | { | 1619 | { |
1475 | mmu_free_memory_cache(&vcpu->arch.mmu_page_cache); | 1620 | mmu_free_memory_cache(&vcpu->arch.mmu_page_cache); |
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h index 881874b1a036..0ec35392d208 100644 --- a/arch/arm/kvm/trace.h +++ b/arch/arm/kvm/trace.h | |||
@@ -25,18 +25,22 @@ TRACE_EVENT(kvm_entry, | |||
25 | ); | 25 | ); |
26 | 26 | ||
27 | TRACE_EVENT(kvm_exit, | 27 | TRACE_EVENT(kvm_exit, |
28 | TP_PROTO(unsigned long vcpu_pc), | 28 | TP_PROTO(unsigned int exit_reason, unsigned long vcpu_pc), |
29 | TP_ARGS(vcpu_pc), | 29 | TP_ARGS(exit_reason, vcpu_pc), |
30 | 30 | ||
31 | TP_STRUCT__entry( | 31 | TP_STRUCT__entry( |
32 | __field( unsigned int, exit_reason ) | ||
32 | __field( unsigned long, vcpu_pc ) | 33 | __field( unsigned long, vcpu_pc ) |
33 | ), | 34 | ), |
34 | 35 | ||
35 | TP_fast_assign( | 36 | TP_fast_assign( |
37 | __entry->exit_reason = exit_reason; | ||
36 | __entry->vcpu_pc = vcpu_pc; | 38 | __entry->vcpu_pc = vcpu_pc; |
37 | ), | 39 | ), |
38 | 40 | ||
39 | TP_printk("PC: 0x%08lx", __entry->vcpu_pc) | 41 | TP_printk("HSR_EC: 0x%04x, PC: 0x%08lx", |
42 | __entry->exit_reason, | ||
43 | __entry->vcpu_pc) | ||
40 | ); | 44 | ); |
41 | 45 | ||
42 | TRACE_EVENT(kvm_guest_fault, | 46 | TRACE_EVENT(kvm_guest_fault, |
@@ -64,6 +68,21 @@ TRACE_EVENT(kvm_guest_fault, | |||
64 | __entry->hxfar, __entry->vcpu_pc) | 68 | __entry->hxfar, __entry->vcpu_pc) |
65 | ); | 69 | ); |
66 | 70 | ||
71 | TRACE_EVENT(kvm_access_fault, | ||
72 | TP_PROTO(unsigned long ipa), | ||
73 | TP_ARGS(ipa), | ||
74 | |||
75 | TP_STRUCT__entry( | ||
76 | __field( unsigned long, ipa ) | ||
77 | ), | ||
78 | |||
79 | TP_fast_assign( | ||
80 | __entry->ipa = ipa; | ||
81 | ), | ||
82 | |||
83 | TP_printk("IPA: %lx", __entry->ipa) | ||
84 | ); | ||
85 | |||
67 | TRACE_EVENT(kvm_irq_line, | 86 | TRACE_EVENT(kvm_irq_line, |
68 | TP_PROTO(unsigned int type, int vcpu_idx, int irq_num, int level), | 87 | TP_PROTO(unsigned int type, int vcpu_idx, int irq_num, int level), |
69 | TP_ARGS(type, vcpu_idx, irq_num, level), | 88 | TP_ARGS(type, vcpu_idx, irq_num, level), |
@@ -206,6 +225,39 @@ TRACE_EVENT(kvm_set_spte_hva, | |||
206 | TP_printk("mmu notifier set pte hva: %#08lx", __entry->hva) | 225 | TP_printk("mmu notifier set pte hva: %#08lx", __entry->hva) |
207 | ); | 226 | ); |
208 | 227 | ||
228 | TRACE_EVENT(kvm_age_hva, | ||
229 | TP_PROTO(unsigned long start, unsigned long end), | ||
230 | TP_ARGS(start, end), | ||
231 | |||
232 | TP_STRUCT__entry( | ||
233 | __field( unsigned long, start ) | ||
234 | __field( unsigned long, end ) | ||
235 | ), | ||
236 | |||
237 | TP_fast_assign( | ||
238 | __entry->start = start; | ||
239 | __entry->end = end; | ||
240 | ), | ||
241 | |||
242 | TP_printk("mmu notifier age hva: %#08lx -- %#08lx", | ||
243 | __entry->start, __entry->end) | ||
244 | ); | ||
245 | |||
246 | TRACE_EVENT(kvm_test_age_hva, | ||
247 | TP_PROTO(unsigned long hva), | ||
248 | TP_ARGS(hva), | ||
249 | |||
250 | TP_STRUCT__entry( | ||
251 | __field( unsigned long, hva ) | ||
252 | ), | ||
253 | |||
254 | TP_fast_assign( | ||
255 | __entry->hva = hva; | ||
256 | ), | ||
257 | |||
258 | TP_printk("mmu notifier test age hva: %#08lx", __entry->hva) | ||
259 | ); | ||
260 | |||
209 | TRACE_EVENT(kvm_hvc, | 261 | TRACE_EVENT(kvm_hvc, |
210 | TP_PROTO(unsigned long vcpu_pc, unsigned long r0, unsigned long imm), | 262 | TP_PROTO(unsigned long vcpu_pc, unsigned long r0, unsigned long imm), |
211 | TP_ARGS(vcpu_pc, r0, imm), | 263 | TP_ARGS(vcpu_pc, r0, imm), |
diff --git a/arch/arm/mach-asm9260/Kconfig b/arch/arm/mach-asm9260/Kconfig index 8423be76080e..52241207a82a 100644 --- a/arch/arm/mach-asm9260/Kconfig +++ b/arch/arm/mach-asm9260/Kconfig | |||
@@ -2,5 +2,7 @@ config MACH_ASM9260 | |||
2 | bool "Alphascale ASM9260" | 2 | bool "Alphascale ASM9260" |
3 | depends on ARCH_MULTI_V5 | 3 | depends on ARCH_MULTI_V5 |
4 | select CPU_ARM926T | 4 | select CPU_ARM926T |
5 | select ASM9260_TIMER | ||
6 | select GENERIC_CLOCKEVENTS | ||
5 | help | 7 | help |
6 | Support for Alphascale ASM9260 based platform. | 8 | Support for Alphascale ASM9260 based platform. |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 5e34fb143309..aa4116e9452f 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -270,37 +270,35 @@ static void __init at91_pm_sram_init(void) | |||
270 | phys_addr_t sram_pbase; | 270 | phys_addr_t sram_pbase; |
271 | unsigned long sram_base; | 271 | unsigned long sram_base; |
272 | struct device_node *node; | 272 | struct device_node *node; |
273 | struct platform_device *pdev; | 273 | struct platform_device *pdev = NULL; |
274 | 274 | ||
275 | node = of_find_compatible_node(NULL, NULL, "mmio-sram"); | 275 | for_each_compatible_node(node, NULL, "mmio-sram") { |
276 | if (!node) { | 276 | pdev = of_find_device_by_node(node); |
277 | pr_warn("%s: failed to find sram node!\n", __func__); | 277 | if (pdev) { |
278 | return; | 278 | of_node_put(node); |
279 | break; | ||
280 | } | ||
279 | } | 281 | } |
280 | 282 | ||
281 | pdev = of_find_device_by_node(node); | ||
282 | if (!pdev) { | 283 | if (!pdev) { |
283 | pr_warn("%s: failed to find sram device!\n", __func__); | 284 | pr_warn("%s: failed to find sram device!\n", __func__); |
284 | goto put_node; | 285 | return; |
285 | } | 286 | } |
286 | 287 | ||
287 | sram_pool = dev_get_gen_pool(&pdev->dev); | 288 | sram_pool = dev_get_gen_pool(&pdev->dev); |
288 | if (!sram_pool) { | 289 | if (!sram_pool) { |
289 | pr_warn("%s: sram pool unavailable!\n", __func__); | 290 | pr_warn("%s: sram pool unavailable!\n", __func__); |
290 | goto put_node; | 291 | return; |
291 | } | 292 | } |
292 | 293 | ||
293 | sram_base = gen_pool_alloc(sram_pool, at91_slow_clock_sz); | 294 | sram_base = gen_pool_alloc(sram_pool, at91_slow_clock_sz); |
294 | if (!sram_base) { | 295 | if (!sram_base) { |
295 | pr_warn("%s: unable to alloc ocram!\n", __func__); | 296 | pr_warn("%s: unable to alloc ocram!\n", __func__); |
296 | goto put_node; | 297 | return; |
297 | } | 298 | } |
298 | 299 | ||
299 | sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base); | 300 | sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base); |
300 | slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false); | 301 | slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false); |
301 | |||
302 | put_node: | ||
303 | of_node_put(node); | ||
304 | } | 302 | } |
305 | #endif | 303 | #endif |
306 | 304 | ||
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index d2c89963af2d..86c0aa819d25 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h | |||
@@ -44,7 +44,7 @@ static inline void at91rm9200_standby(void) | |||
44 | " mcr p15, 0, %0, c7, c0, 4\n\t" | 44 | " mcr p15, 0, %0, c7, c0, 4\n\t" |
45 | " str %5, [%1, %2]" | 45 | " str %5, [%1, %2]" |
46 | : | 46 | : |
47 | : "r" (0), "r" (AT91_BASE_SYS), "r" (AT91RM9200_SDRAMC_LPR), | 47 | : "r" (0), "r" (at91_ramc_base[0]), "r" (AT91RM9200_SDRAMC_LPR), |
48 | "r" (1), "r" (AT91RM9200_SDRAMC_SRR), | 48 | "r" (1), "r" (AT91RM9200_SDRAMC_SRR), |
49 | "r" (lpr)); | 49 | "r" (lpr)); |
50 | } | 50 | } |
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 556151e85ec4..931f0e302c03 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S | |||
@@ -25,11 +25,6 @@ | |||
25 | */ | 25 | */ |
26 | #undef SLOWDOWN_MASTER_CLOCK | 26 | #undef SLOWDOWN_MASTER_CLOCK |
27 | 27 | ||
28 | #define MCKRDY_TIMEOUT 1000 | ||
29 | #define MOSCRDY_TIMEOUT 1000 | ||
30 | #define PLLALOCK_TIMEOUT 1000 | ||
31 | #define PLLBLOCK_TIMEOUT 1000 | ||
32 | |||
33 | pmc .req r0 | 28 | pmc .req r0 |
34 | sdramc .req r1 | 29 | sdramc .req r1 |
35 | ramc1 .req r2 | 30 | ramc1 .req r2 |
@@ -41,60 +36,42 @@ tmp2 .req r5 | |||
41 | * Wait until master clock is ready (after switching master clock source) | 36 | * Wait until master clock is ready (after switching master clock source) |
42 | */ | 37 | */ |
43 | .macro wait_mckrdy | 38 | .macro wait_mckrdy |
44 | mov tmp2, #MCKRDY_TIMEOUT | 39 | 1: ldr tmp1, [pmc, #AT91_PMC_SR] |
45 | 1: sub tmp2, tmp2, #1 | ||
46 | cmp tmp2, #0 | ||
47 | beq 2f | ||
48 | ldr tmp1, [pmc, #AT91_PMC_SR] | ||
49 | tst tmp1, #AT91_PMC_MCKRDY | 40 | tst tmp1, #AT91_PMC_MCKRDY |
50 | beq 1b | 41 | beq 1b |
51 | 2: | ||
52 | .endm | 42 | .endm |
53 | 43 | ||
54 | /* | 44 | /* |
55 | * Wait until master oscillator has stabilized. | 45 | * Wait until master oscillator has stabilized. |
56 | */ | 46 | */ |
57 | .macro wait_moscrdy | 47 | .macro wait_moscrdy |
58 | mov tmp2, #MOSCRDY_TIMEOUT | 48 | 1: ldr tmp1, [pmc, #AT91_PMC_SR] |
59 | 1: sub tmp2, tmp2, #1 | ||
60 | cmp tmp2, #0 | ||
61 | beq 2f | ||
62 | ldr tmp1, [pmc, #AT91_PMC_SR] | ||
63 | tst tmp1, #AT91_PMC_MOSCS | 49 | tst tmp1, #AT91_PMC_MOSCS |
64 | beq 1b | 50 | beq 1b |
65 | 2: | ||
66 | .endm | 51 | .endm |
67 | 52 | ||
68 | /* | 53 | /* |
69 | * Wait until PLLA has locked. | 54 | * Wait until PLLA has locked. |
70 | */ | 55 | */ |
71 | .macro wait_pllalock | 56 | .macro wait_pllalock |
72 | mov tmp2, #PLLALOCK_TIMEOUT | 57 | 1: ldr tmp1, [pmc, #AT91_PMC_SR] |
73 | 1: sub tmp2, tmp2, #1 | ||
74 | cmp tmp2, #0 | ||
75 | beq 2f | ||
76 | ldr tmp1, [pmc, #AT91_PMC_SR] | ||
77 | tst tmp1, #AT91_PMC_LOCKA | 58 | tst tmp1, #AT91_PMC_LOCKA |
78 | beq 1b | 59 | beq 1b |
79 | 2: | ||
80 | .endm | 60 | .endm |
81 | 61 | ||
82 | /* | 62 | /* |
83 | * Wait until PLLB has locked. | 63 | * Wait until PLLB has locked. |
84 | */ | 64 | */ |
85 | .macro wait_pllblock | 65 | .macro wait_pllblock |
86 | mov tmp2, #PLLBLOCK_TIMEOUT | 66 | 1: ldr tmp1, [pmc, #AT91_PMC_SR] |
87 | 1: sub tmp2, tmp2, #1 | ||
88 | cmp tmp2, #0 | ||
89 | beq 2f | ||
90 | ldr tmp1, [pmc, #AT91_PMC_SR] | ||
91 | tst tmp1, #AT91_PMC_LOCKB | 67 | tst tmp1, #AT91_PMC_LOCKB |
92 | beq 1b | 68 | beq 1b |
93 | 2: | ||
94 | .endm | 69 | .endm |
95 | 70 | ||
96 | .text | 71 | .text |
97 | 72 | ||
73 | .arm | ||
74 | |||
98 | /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, | 75 | /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, |
99 | * void __iomem *ramc1, int memctrl) | 76 | * void __iomem *ramc1, int memctrl) |
100 | */ | 77 | */ |
@@ -134,6 +111,16 @@ ddr_sr_enable: | |||
134 | cmp memctrl, #AT91_MEMCTRL_DDRSDR | 111 | cmp memctrl, #AT91_MEMCTRL_DDRSDR |
135 | bne sdr_sr_enable | 112 | bne sdr_sr_enable |
136 | 113 | ||
114 | /* LPDDR1 --> force DDR2 mode during self-refresh */ | ||
115 | ldr tmp1, [sdramc, #AT91_DDRSDRC_MDR] | ||
116 | str tmp1, .saved_sam9_mdr | ||
117 | bic tmp1, tmp1, #~AT91_DDRSDRC_MD | ||
118 | cmp tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR | ||
119 | ldreq tmp1, [sdramc, #AT91_DDRSDRC_MDR] | ||
120 | biceq tmp1, tmp1, #AT91_DDRSDRC_MD | ||
121 | orreq tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2 | ||
122 | streq tmp1, [sdramc, #AT91_DDRSDRC_MDR] | ||
123 | |||
137 | /* prepare for DDRAM self-refresh mode */ | 124 | /* prepare for DDRAM self-refresh mode */ |
138 | ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] | 125 | ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
139 | str tmp1, .saved_sam9_lpr | 126 | str tmp1, .saved_sam9_lpr |
@@ -142,14 +129,26 @@ ddr_sr_enable: | |||
142 | 129 | ||
143 | /* figure out if we use the second ram controller */ | 130 | /* figure out if we use the second ram controller */ |
144 | cmp ramc1, #0 | 131 | cmp ramc1, #0 |
145 | ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR] | 132 | beq ddr_no_2nd_ctrl |
146 | strne tmp2, .saved_sam9_lpr1 | 133 | |
147 | bicne tmp2, #AT91_DDRSDRC_LPCB | 134 | ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR] |
148 | orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH | 135 | str tmp2, .saved_sam9_mdr1 |
136 | bic tmp2, tmp2, #~AT91_DDRSDRC_MD | ||
137 | cmp tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR | ||
138 | ldreq tmp2, [ramc1, #AT91_DDRSDRC_MDR] | ||
139 | biceq tmp2, tmp2, #AT91_DDRSDRC_MD | ||
140 | orreq tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2 | ||
141 | streq tmp2, [ramc1, #AT91_DDRSDRC_MDR] | ||
142 | |||
143 | ldr tmp2, [ramc1, #AT91_DDRSDRC_LPR] | ||
144 | str tmp2, .saved_sam9_lpr1 | ||
145 | bic tmp2, #AT91_DDRSDRC_LPCB | ||
146 | orr tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH | ||
149 | 147 | ||
150 | /* Enable DDRAM self-refresh mode */ | 148 | /* Enable DDRAM self-refresh mode */ |
149 | str tmp2, [ramc1, #AT91_DDRSDRC_LPR] | ||
150 | ddr_no_2nd_ctrl: | ||
151 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] | 151 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
152 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] | ||
153 | 152 | ||
154 | b sdr_sr_done | 153 | b sdr_sr_done |
155 | 154 | ||
@@ -208,6 +207,7 @@ sdr_sr_done: | |||
208 | /* Turn off the main oscillator */ | 207 | /* Turn off the main oscillator */ |
209 | ldr tmp1, [pmc, #AT91_CKGR_MOR] | 208 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
210 | bic tmp1, tmp1, #AT91_PMC_MOSCEN | 209 | bic tmp1, tmp1, #AT91_PMC_MOSCEN |
210 | orr tmp1, tmp1, #AT91_PMC_KEY | ||
211 | str tmp1, [pmc, #AT91_CKGR_MOR] | 211 | str tmp1, [pmc, #AT91_CKGR_MOR] |
212 | 212 | ||
213 | /* Wait for interrupt */ | 213 | /* Wait for interrupt */ |
@@ -216,6 +216,7 @@ sdr_sr_done: | |||
216 | /* Turn on the main oscillator */ | 216 | /* Turn on the main oscillator */ |
217 | ldr tmp1, [pmc, #AT91_CKGR_MOR] | 217 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
218 | orr tmp1, tmp1, #AT91_PMC_MOSCEN | 218 | orr tmp1, tmp1, #AT91_PMC_MOSCEN |
219 | orr tmp1, tmp1, #AT91_PMC_KEY | ||
219 | str tmp1, [pmc, #AT91_CKGR_MOR] | 220 | str tmp1, [pmc, #AT91_CKGR_MOR] |
220 | 221 | ||
221 | wait_moscrdy | 222 | wait_moscrdy |
@@ -280,12 +281,17 @@ sdr_sr_done: | |||
280 | */ | 281 | */ |
281 | cmp memctrl, #AT91_MEMCTRL_DDRSDR | 282 | cmp memctrl, #AT91_MEMCTRL_DDRSDR |
282 | bne sdr_en_restore | 283 | bne sdr_en_restore |
284 | /* Restore MDR in case of LPDDR1 */ | ||
285 | ldr tmp1, .saved_sam9_mdr | ||
286 | str tmp1, [sdramc, #AT91_DDRSDRC_MDR] | ||
283 | /* Restore LPR on AT91 with DDRAM */ | 287 | /* Restore LPR on AT91 with DDRAM */ |
284 | ldr tmp1, .saved_sam9_lpr | 288 | ldr tmp1, .saved_sam9_lpr |
285 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] | 289 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
286 | 290 | ||
287 | /* if we use the second ram controller */ | 291 | /* if we use the second ram controller */ |
288 | cmp ramc1, #0 | 292 | cmp ramc1, #0 |
293 | ldrne tmp2, .saved_sam9_mdr1 | ||
294 | strne tmp2, [ramc1, #AT91_DDRSDRC_MDR] | ||
289 | ldrne tmp2, .saved_sam9_lpr1 | 295 | ldrne tmp2, .saved_sam9_lpr1 |
290 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] | 296 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] |
291 | 297 | ||
@@ -319,5 +325,11 @@ ram_restored: | |||
319 | .saved_sam9_lpr1: | 325 | .saved_sam9_lpr1: |
320 | .word 0 | 326 | .word 0 |
321 | 327 | ||
328 | .saved_sam9_mdr: | ||
329 | .word 0 | ||
330 | |||
331 | .saved_sam9_mdr1: | ||
332 | .word 0 | ||
333 | |||
322 | ENTRY(at91_slow_clock_sz) | 334 | ENTRY(at91_slow_clock_sz) |
323 | .word .-at91_slow_clock | 335 | .word .-at91_slow_clock |
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 3f32c47a6d74..d2e9f12d12f1 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c | |||
@@ -126,8 +126,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) | |||
126 | */ | 126 | */ |
127 | void exynos_cpu_power_down(int cpu) | 127 | void exynos_cpu_power_down(int cpu) |
128 | { | 128 | { |
129 | if (cpu == 0 && (of_machine_is_compatible("samsung,exynos5420") || | 129 | if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) { |
130 | of_machine_is_compatible("samsung,exynos5800"))) { | ||
131 | /* | 130 | /* |
132 | * Bypass power down for CPU0 during suspend. Check for | 131 | * Bypass power down for CPU0 during suspend. Check for |
133 | * the SYS_PWR_REG value to decide if we are suspending | 132 | * the SYS_PWR_REG value to decide if we are suspending |
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index 20f267121b3e..37266a826437 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c | |||
@@ -161,6 +161,34 @@ no_clk: | |||
161 | of_genpd_add_provider_simple(np, &pd->pd); | 161 | of_genpd_add_provider_simple(np, &pd->pd); |
162 | } | 162 | } |
163 | 163 | ||
164 | /* Assign the child power domains to their parents */ | ||
165 | for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { | ||
166 | struct generic_pm_domain *child_domain, *parent_domain; | ||
167 | struct of_phandle_args args; | ||
168 | |||
169 | args.np = np; | ||
170 | args.args_count = 0; | ||
171 | child_domain = of_genpd_get_from_provider(&args); | ||
172 | if (!child_domain) | ||
173 | continue; | ||
174 | |||
175 | if (of_parse_phandle_with_args(np, "power-domains", | ||
176 | "#power-domain-cells", 0, &args) != 0) | ||
177 | continue; | ||
178 | |||
179 | parent_domain = of_genpd_get_from_provider(&args); | ||
180 | if (!parent_domain) | ||
181 | continue; | ||
182 | |||
183 | if (pm_genpd_add_subdomain(parent_domain, child_domain)) | ||
184 | pr_warn("%s failed to add subdomain: %s\n", | ||
185 | parent_domain->name, child_domain->name); | ||
186 | else | ||
187 | pr_info("%s has as child subdomain: %s.\n", | ||
188 | parent_domain->name, child_domain->name); | ||
189 | of_node_put(np); | ||
190 | } | ||
191 | |||
164 | return 0; | 192 | return 0; |
165 | } | 193 | } |
166 | arch_initcall(exynos4_pm_init_power_domain); | 194 | arch_initcall(exynos4_pm_init_power_domain); |
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 52e2b1a2fddb..318d127df147 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c | |||
@@ -87,8 +87,8 @@ static unsigned int exynos_pmu_spare3; | |||
87 | static u32 exynos_irqwake_intmask = 0xffffffff; | 87 | static u32 exynos_irqwake_intmask = 0xffffffff; |
88 | 88 | ||
89 | static const struct exynos_wkup_irq exynos3250_wkup_irq[] = { | 89 | static const struct exynos_wkup_irq exynos3250_wkup_irq[] = { |
90 | { 73, BIT(1) }, /* RTC alarm */ | 90 | { 105, BIT(1) }, /* RTC alarm */ |
91 | { 74, BIT(2) }, /* RTC tick */ | 91 | { 106, BIT(2) }, /* RTC tick */ |
92 | { /* sentinel */ }, | 92 | { /* sentinel */ }, |
93 | }; | 93 | }; |
94 | 94 | ||
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 4ad6e473cf83..9de3412af406 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -211,8 +211,9 @@ static void __init imx6q_1588_init(void) | |||
211 | * set bit IOMUXC_GPR1[21]. Or the PTP clock must be from pad | 211 | * set bit IOMUXC_GPR1[21]. Or the PTP clock must be from pad |
212 | * (external OSC), and we need to clear the bit. | 212 | * (external OSC), and we need to clear the bit. |
213 | */ | 213 | */ |
214 | clksel = ptp_clk == enet_ref ? IMX6Q_GPR1_ENET_CLK_SEL_ANATOP : | 214 | clksel = clk_is_match(ptp_clk, enet_ref) ? |
215 | IMX6Q_GPR1_ENET_CLK_SEL_PAD; | 215 | IMX6Q_GPR1_ENET_CLK_SEL_ANATOP : |
216 | IMX6Q_GPR1_ENET_CLK_SEL_PAD; | ||
216 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); | 217 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); |
217 | if (!IS_ERR(gpr)) | 218 | if (!IS_ERR(gpr)) |
218 | regmap_update_bits(gpr, IOMUXC_GPR1, | 219 | regmap_update_bits(gpr, IOMUXC_GPR1, |
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index 61bfe584a9d7..fc832040c6e9 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/smc91x.h> | ||
23 | 24 | ||
24 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
25 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
@@ -46,15 +47,20 @@ static struct resource smc91x_resources[] = { | |||
46 | [1] = { | 47 | [1] = { |
47 | .start = MSM_GPIO_TO_INT(49), | 48 | .start = MSM_GPIO_TO_INT(49), |
48 | .end = MSM_GPIO_TO_INT(49), | 49 | .end = MSM_GPIO_TO_INT(49), |
49 | .flags = IORESOURCE_IRQ, | 50 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, |
50 | }, | 51 | }, |
51 | }; | 52 | }; |
52 | 53 | ||
54 | static struct smc91x_platdata smc91x_platdata = { | ||
55 | .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, | ||
56 | }; | ||
57 | |||
53 | static struct platform_device smc91x_device = { | 58 | static struct platform_device smc91x_device = { |
54 | .name = "smc91x", | 59 | .name = "smc91x", |
55 | .id = 0, | 60 | .id = 0, |
56 | .num_resources = ARRAY_SIZE(smc91x_resources), | 61 | .num_resources = ARRAY_SIZE(smc91x_resources), |
57 | .resource = smc91x_resources, | 62 | .resource = smc91x_resources, |
63 | .dev.platform_data = &smc91x_platdata, | ||
58 | }; | 64 | }; |
59 | 65 | ||
60 | static struct platform_device *devices[] __initdata = { | 66 | static struct platform_device *devices[] __initdata = { |
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index 4c748616ef47..10016a3bc698 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/usb/msm_hsusb.h> | 22 | #include <linux/usb/msm_hsusb.h> |
23 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/clkdev.h> | 24 | #include <linux/clkdev.h> |
25 | #include <linux/smc91x.h> | ||
25 | 26 | ||
26 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
27 | #include <asm/mach/arch.h> | 28 | #include <asm/mach/arch.h> |
@@ -49,15 +50,20 @@ static struct resource smc91x_resources[] = { | |||
49 | .flags = IORESOURCE_MEM, | 50 | .flags = IORESOURCE_MEM, |
50 | }, | 51 | }, |
51 | [1] = { | 52 | [1] = { |
52 | .flags = IORESOURCE_IRQ, | 53 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, |
53 | }, | 54 | }, |
54 | }; | 55 | }; |
55 | 56 | ||
57 | static struct smc91x_platdata smc91x_platdata = { | ||
58 | .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, | ||
59 | }; | ||
60 | |||
56 | static struct platform_device smc91x_device = { | 61 | static struct platform_device smc91x_device = { |
57 | .name = "smc91x", | 62 | .name = "smc91x", |
58 | .id = 0, | 63 | .id = 0, |
59 | .num_resources = ARRAY_SIZE(smc91x_resources), | 64 | .num_resources = ARRAY_SIZE(smc91x_resources), |
60 | .resource = smc91x_resources, | 65 | .resource = smc91x_resources, |
66 | .dev.platform_data = &smc91x_platdata, | ||
61 | }; | 67 | }; |
62 | 68 | ||
63 | static int __init msm_init_smc91x(void) | 69 | static int __init msm_init_smc91x(void) |
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 2a2f4d56e4c8..25f1beea453e 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c | |||
@@ -720,6 +720,8 @@ static const char * __init omap_get_family(void) | |||
720 | return kasprintf(GFP_KERNEL, "OMAP4"); | 720 | return kasprintf(GFP_KERNEL, "OMAP4"); |
721 | else if (soc_is_omap54xx()) | 721 | else if (soc_is_omap54xx()) |
722 | return kasprintf(GFP_KERNEL, "OMAP5"); | 722 | return kasprintf(GFP_KERNEL, "OMAP5"); |
723 | else if (soc_is_am33xx() || soc_is_am335x()) | ||
724 | return kasprintf(GFP_KERNEL, "AM33xx"); | ||
723 | else if (soc_is_am43xx()) | 725 | else if (soc_is_am43xx()) |
724 | return kasprintf(GFP_KERNEL, "AM43xx"); | 726 | return kasprintf(GFP_KERNEL, "AM43xx"); |
725 | else if (soc_is_dra7xx()) | 727 | else if (soc_is_dra7xx()) |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 92afb723dcfc..355b08936871 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -1692,16 +1692,15 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) | |||
1692 | if (ret == -EBUSY) | 1692 | if (ret == -EBUSY) |
1693 | pr_warn("omap_hwmod: %s: failed to hardreset\n", oh->name); | 1693 | pr_warn("omap_hwmod: %s: failed to hardreset\n", oh->name); |
1694 | 1694 | ||
1695 | if (!ret) { | 1695 | if (oh->clkdm) { |
1696 | /* | 1696 | /* |
1697 | * Set the clockdomain to HW_AUTO, assuming that the | 1697 | * Set the clockdomain to HW_AUTO, assuming that the |
1698 | * previous state was HW_AUTO. | 1698 | * previous state was HW_AUTO. |
1699 | */ | 1699 | */ |
1700 | if (oh->clkdm && hwsup) | 1700 | if (hwsup) |
1701 | clkdm_allow_idle(oh->clkdm); | 1701 | clkdm_allow_idle(oh->clkdm); |
1702 | } else { | 1702 | |
1703 | if (oh->clkdm) | 1703 | clkdm_hwmod_disable(oh->clkdm, oh); |
1704 | clkdm_hwmod_disable(oh->clkdm, oh); | ||
1705 | } | 1704 | } |
1706 | 1705 | ||
1707 | return ret; | 1706 | return ret; |
@@ -2698,6 +2697,7 @@ static int __init _register(struct omap_hwmod *oh) | |||
2698 | INIT_LIST_HEAD(&oh->master_ports); | 2697 | INIT_LIST_HEAD(&oh->master_ports); |
2699 | INIT_LIST_HEAD(&oh->slave_ports); | 2698 | INIT_LIST_HEAD(&oh->slave_ports); |
2700 | spin_lock_init(&oh->_lock); | 2699 | spin_lock_init(&oh->_lock); |
2700 | lockdep_set_class(&oh->_lock, &oh->hwmod_key); | ||
2701 | 2701 | ||
2702 | oh->_state = _HWMOD_STATE_REGISTERED; | 2702 | oh->_state = _HWMOD_STATE_REGISTERED; |
2703 | 2703 | ||
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 9d4bec6ee742..9611c91d9b82 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h | |||
@@ -674,6 +674,7 @@ struct omap_hwmod { | |||
674 | u32 _sysc_cache; | 674 | u32 _sysc_cache; |
675 | void __iomem *_mpu_rt_va; | 675 | void __iomem *_mpu_rt_va; |
676 | spinlock_t _lock; | 676 | spinlock_t _lock; |
677 | struct lock_class_key hwmod_key; /* unique lock class */ | ||
677 | struct list_head node; | 678 | struct list_head node; |
678 | struct omap_hwmod_ocp_if *_mpu_port; | 679 | struct omap_hwmod_ocp_if *_mpu_port; |
679 | unsigned int (*xlate_irq)(unsigned int); | 680 | unsigned int (*xlate_irq)(unsigned int); |
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index e8692e7675b8..16fe7a1b7a35 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c | |||
@@ -1466,55 +1466,18 @@ static struct omap_hwmod dra7xx_ocp2scp3_hwmod = { | |||
1466 | * | 1466 | * |
1467 | */ | 1467 | */ |
1468 | 1468 | ||
1469 | static struct omap_hwmod_class dra7xx_pcie_hwmod_class = { | 1469 | static struct omap_hwmod_class dra7xx_pciess_hwmod_class = { |
1470 | .name = "pcie", | 1470 | .name = "pcie", |
1471 | }; | 1471 | }; |
1472 | 1472 | ||
1473 | /* pcie1 */ | 1473 | /* pcie1 */ |
1474 | static struct omap_hwmod dra7xx_pcie1_hwmod = { | 1474 | static struct omap_hwmod dra7xx_pciess1_hwmod = { |
1475 | .name = "pcie1", | 1475 | .name = "pcie1", |
1476 | .class = &dra7xx_pcie_hwmod_class, | 1476 | .class = &dra7xx_pciess_hwmod_class, |
1477 | .clkdm_name = "pcie_clkdm", | 1477 | .clkdm_name = "pcie_clkdm", |
1478 | .main_clk = "l4_root_clk_div", | 1478 | .main_clk = "l4_root_clk_div", |
1479 | .prcm = { | 1479 | .prcm = { |
1480 | .omap4 = { | 1480 | .omap4 = { |
1481 | .clkctrl_offs = DRA7XX_CM_PCIE_CLKSTCTRL_OFFSET, | ||
1482 | .modulemode = MODULEMODE_SWCTRL, | ||
1483 | }, | ||
1484 | }, | ||
1485 | }; | ||
1486 | |||
1487 | /* pcie2 */ | ||
1488 | static struct omap_hwmod dra7xx_pcie2_hwmod = { | ||
1489 | .name = "pcie2", | ||
1490 | .class = &dra7xx_pcie_hwmod_class, | ||
1491 | .clkdm_name = "pcie_clkdm", | ||
1492 | .main_clk = "l4_root_clk_div", | ||
1493 | .prcm = { | ||
1494 | .omap4 = { | ||
1495 | .clkctrl_offs = DRA7XX_CM_PCIE_CLKSTCTRL_OFFSET, | ||
1496 | .modulemode = MODULEMODE_SWCTRL, | ||
1497 | }, | ||
1498 | }, | ||
1499 | }; | ||
1500 | |||
1501 | /* | ||
1502 | * 'PCIE PHY' class | ||
1503 | * | ||
1504 | */ | ||
1505 | |||
1506 | static struct omap_hwmod_class dra7xx_pcie_phy_hwmod_class = { | ||
1507 | .name = "pcie-phy", | ||
1508 | }; | ||
1509 | |||
1510 | /* pcie1 phy */ | ||
1511 | static struct omap_hwmod dra7xx_pcie1_phy_hwmod = { | ||
1512 | .name = "pcie1-phy", | ||
1513 | .class = &dra7xx_pcie_phy_hwmod_class, | ||
1514 | .clkdm_name = "l3init_clkdm", | ||
1515 | .main_clk = "l4_root_clk_div", | ||
1516 | .prcm = { | ||
1517 | .omap4 = { | ||
1518 | .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL_OFFSET, | 1481 | .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL_OFFSET, |
1519 | .context_offs = DRA7XX_RM_L3INIT_PCIESS1_CONTEXT_OFFSET, | 1482 | .context_offs = DRA7XX_RM_L3INIT_PCIESS1_CONTEXT_OFFSET, |
1520 | .modulemode = MODULEMODE_SWCTRL, | 1483 | .modulemode = MODULEMODE_SWCTRL, |
@@ -1522,11 +1485,11 @@ static struct omap_hwmod dra7xx_pcie1_phy_hwmod = { | |||
1522 | }, | 1485 | }, |
1523 | }; | 1486 | }; |
1524 | 1487 | ||
1525 | /* pcie2 phy */ | 1488 | /* pcie2 */ |
1526 | static struct omap_hwmod dra7xx_pcie2_phy_hwmod = { | 1489 | static struct omap_hwmod dra7xx_pciess2_hwmod = { |
1527 | .name = "pcie2-phy", | 1490 | .name = "pcie2", |
1528 | .class = &dra7xx_pcie_phy_hwmod_class, | 1491 | .class = &dra7xx_pciess_hwmod_class, |
1529 | .clkdm_name = "l3init_clkdm", | 1492 | .clkdm_name = "pcie_clkdm", |
1530 | .main_clk = "l4_root_clk_div", | 1493 | .main_clk = "l4_root_clk_div", |
1531 | .prcm = { | 1494 | .prcm = { |
1532 | .omap4 = { | 1495 | .omap4 = { |
@@ -2877,50 +2840,34 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp3 = { | |||
2877 | .user = OCP_USER_MPU | OCP_USER_SDMA, | 2840 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
2878 | }; | 2841 | }; |
2879 | 2842 | ||
2880 | /* l3_main_1 -> pcie1 */ | 2843 | /* l3_main_1 -> pciess1 */ |
2881 | static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pcie1 = { | 2844 | static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pciess1 = { |
2882 | .master = &dra7xx_l3_main_1_hwmod, | 2845 | .master = &dra7xx_l3_main_1_hwmod, |
2883 | .slave = &dra7xx_pcie1_hwmod, | 2846 | .slave = &dra7xx_pciess1_hwmod, |
2884 | .clk = "l3_iclk_div", | 2847 | .clk = "l3_iclk_div", |
2885 | .user = OCP_USER_MPU | OCP_USER_SDMA, | 2848 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
2886 | }; | 2849 | }; |
2887 | 2850 | ||
2888 | /* l4_cfg -> pcie1 */ | 2851 | /* l4_cfg -> pciess1 */ |
2889 | static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie1 = { | 2852 | static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pciess1 = { |
2890 | .master = &dra7xx_l4_cfg_hwmod, | 2853 | .master = &dra7xx_l4_cfg_hwmod, |
2891 | .slave = &dra7xx_pcie1_hwmod, | 2854 | .slave = &dra7xx_pciess1_hwmod, |
2892 | .clk = "l4_root_clk_div", | 2855 | .clk = "l4_root_clk_div", |
2893 | .user = OCP_USER_MPU | OCP_USER_SDMA, | 2856 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
2894 | }; | 2857 | }; |
2895 | 2858 | ||
2896 | /* l3_main_1 -> pcie2 */ | 2859 | /* l3_main_1 -> pciess2 */ |
2897 | static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pcie2 = { | 2860 | static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pciess2 = { |
2898 | .master = &dra7xx_l3_main_1_hwmod, | 2861 | .master = &dra7xx_l3_main_1_hwmod, |
2899 | .slave = &dra7xx_pcie2_hwmod, | 2862 | .slave = &dra7xx_pciess2_hwmod, |
2900 | .clk = "l3_iclk_div", | 2863 | .clk = "l3_iclk_div", |
2901 | .user = OCP_USER_MPU | OCP_USER_SDMA, | 2864 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
2902 | }; | 2865 | }; |
2903 | 2866 | ||
2904 | /* l4_cfg -> pcie2 */ | 2867 | /* l4_cfg -> pciess2 */ |
2905 | static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie2 = { | 2868 | static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pciess2 = { |
2906 | .master = &dra7xx_l4_cfg_hwmod, | ||
2907 | .slave = &dra7xx_pcie2_hwmod, | ||
2908 | .clk = "l4_root_clk_div", | ||
2909 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
2910 | }; | ||
2911 | |||
2912 | /* l4_cfg -> pcie1 phy */ | ||
2913 | static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie1_phy = { | ||
2914 | .master = &dra7xx_l4_cfg_hwmod, | ||
2915 | .slave = &dra7xx_pcie1_phy_hwmod, | ||
2916 | .clk = "l4_root_clk_div", | ||
2917 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
2918 | }; | ||
2919 | |||
2920 | /* l4_cfg -> pcie2 phy */ | ||
2921 | static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie2_phy = { | ||
2922 | .master = &dra7xx_l4_cfg_hwmod, | 2869 | .master = &dra7xx_l4_cfg_hwmod, |
2923 | .slave = &dra7xx_pcie2_phy_hwmod, | 2870 | .slave = &dra7xx_pciess2_hwmod, |
2924 | .clk = "l4_root_clk_div", | 2871 | .clk = "l4_root_clk_div", |
2925 | .user = OCP_USER_MPU | OCP_USER_SDMA, | 2872 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
2926 | }; | 2873 | }; |
@@ -3327,12 +3274,10 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { | |||
3327 | &dra7xx_l4_cfg__mpu, | 3274 | &dra7xx_l4_cfg__mpu, |
3328 | &dra7xx_l4_cfg__ocp2scp1, | 3275 | &dra7xx_l4_cfg__ocp2scp1, |
3329 | &dra7xx_l4_cfg__ocp2scp3, | 3276 | &dra7xx_l4_cfg__ocp2scp3, |
3330 | &dra7xx_l3_main_1__pcie1, | 3277 | &dra7xx_l3_main_1__pciess1, |
3331 | &dra7xx_l4_cfg__pcie1, | 3278 | &dra7xx_l4_cfg__pciess1, |
3332 | &dra7xx_l3_main_1__pcie2, | 3279 | &dra7xx_l3_main_1__pciess2, |
3333 | &dra7xx_l4_cfg__pcie2, | 3280 | &dra7xx_l4_cfg__pciess2, |
3334 | &dra7xx_l4_cfg__pcie1_phy, | ||
3335 | &dra7xx_l4_cfg__pcie2_phy, | ||
3336 | &dra7xx_l3_main_1__qspi, | 3281 | &dra7xx_l3_main_1__qspi, |
3337 | &dra7xx_l4_per3__rtcss, | 3282 | &dra7xx_l4_per3__rtcss, |
3338 | &dra7xx_l4_cfg__sata, | 3283 | &dra7xx_l4_cfg__sata, |
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 190fa43e7479..e642b079e9f3 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c | |||
@@ -173,6 +173,7 @@ static void __init omap3_igep0030_rev_g_legacy_init(void) | |||
173 | 173 | ||
174 | static void __init omap3_evm_legacy_init(void) | 174 | static void __init omap3_evm_legacy_init(void) |
175 | { | 175 | { |
176 | hsmmc2_internal_input_clk(); | ||
176 | legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149); | 177 | legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149); |
177 | } | 178 | } |
178 | 179 | ||
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index a08a617a6c11..d6d6bc39e05c 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c | |||
@@ -252,10 +252,10 @@ static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) | |||
252 | { | 252 | { |
253 | saved_mask[0] = | 253 | saved_mask[0] = |
254 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, | 254 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, |
255 | OMAP4_PRM_IRQSTATUS_MPU_OFFSET); | 255 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); |
256 | saved_mask[1] = | 256 | saved_mask[1] = |
257 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, | 257 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, |
258 | OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); | 258 | OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); |
259 | 259 | ||
260 | omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, | 260 | omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, |
261 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); | 261 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); |
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index 343c4e3a7c5d..f6d02e4cbcda 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/platform_data/video-pxafb.h> | 36 | #include <linux/platform_data/video-pxafb.h> |
37 | #include <mach/bitfield.h> | 37 | #include <mach/bitfield.h> |
38 | #include <linux/platform_data/mmc-pxamci.h> | 38 | #include <linux/platform_data/mmc-pxamci.h> |
39 | #include <linux/smc91x.h> | ||
39 | 40 | ||
40 | #include "generic.h" | 41 | #include "generic.h" |
41 | #include "devices.h" | 42 | #include "devices.h" |
@@ -81,11 +82,16 @@ static struct resource smc91x_resources[] = { | |||
81 | } | 82 | } |
82 | }; | 83 | }; |
83 | 84 | ||
85 | static struct smc91x_platdata smc91x_platdata = { | ||
86 | .flags = SMC91X_USE_32BIT | SMC91X_USE_DMA | SMC91X_NOWAIT, | ||
87 | }; | ||
88 | |||
84 | static struct platform_device smc91x_device = { | 89 | static struct platform_device smc91x_device = { |
85 | .name = "smc91x", | 90 | .name = "smc91x", |
86 | .id = 0, | 91 | .id = 0, |
87 | .num_resources = ARRAY_SIZE(smc91x_resources), | 92 | .num_resources = ARRAY_SIZE(smc91x_resources), |
88 | .resource = smc91x_resources, | 93 | .resource = smc91x_resources, |
94 | .dev.platform_data = &smc91x_platdata, | ||
89 | }; | 95 | }; |
90 | 96 | ||
91 | static void idp_backlight_power(int on) | 97 | static void idp_backlight_power(int on) |
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 0eecd83c624e..89a7c06570d3 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | #include <linux/bitops.h> | ||
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
@@ -40,7 +41,6 @@ | |||
40 | #define ICHP_VAL_IRQ (1 << 31) | 41 | #define ICHP_VAL_IRQ (1 << 31) |
41 | #define ICHP_IRQ(i) (((i) >> 16) & 0x7fff) | 42 | #define ICHP_IRQ(i) (((i) >> 16) & 0x7fff) |
42 | #define IPR_VALID (1 << 31) | 43 | #define IPR_VALID (1 << 31) |
43 | #define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f) | ||
44 | 44 | ||
45 | #define MAX_INTERNAL_IRQS 128 | 45 | #define MAX_INTERNAL_IRQS 128 |
46 | 46 | ||
@@ -51,6 +51,7 @@ | |||
51 | static void __iomem *pxa_irq_base; | 51 | static void __iomem *pxa_irq_base; |
52 | static int pxa_internal_irq_nr; | 52 | static int pxa_internal_irq_nr; |
53 | static bool cpu_has_ipr; | 53 | static bool cpu_has_ipr; |
54 | static struct irq_domain *pxa_irq_domain; | ||
54 | 55 | ||
55 | static inline void __iomem *irq_base(int i) | 56 | static inline void __iomem *irq_base(int i) |
56 | { | 57 | { |
@@ -66,18 +67,20 @@ static inline void __iomem *irq_base(int i) | |||
66 | void pxa_mask_irq(struct irq_data *d) | 67 | void pxa_mask_irq(struct irq_data *d) |
67 | { | 68 | { |
68 | void __iomem *base = irq_data_get_irq_chip_data(d); | 69 | void __iomem *base = irq_data_get_irq_chip_data(d); |
70 | irq_hw_number_t irq = irqd_to_hwirq(d); | ||
69 | uint32_t icmr = __raw_readl(base + ICMR); | 71 | uint32_t icmr = __raw_readl(base + ICMR); |
70 | 72 | ||
71 | icmr &= ~(1 << IRQ_BIT(d->irq)); | 73 | icmr &= ~BIT(irq & 0x1f); |
72 | __raw_writel(icmr, base + ICMR); | 74 | __raw_writel(icmr, base + ICMR); |
73 | } | 75 | } |
74 | 76 | ||
75 | void pxa_unmask_irq(struct irq_data *d) | 77 | void pxa_unmask_irq(struct irq_data *d) |
76 | { | 78 | { |
77 | void __iomem *base = irq_data_get_irq_chip_data(d); | 79 | void __iomem *base = irq_data_get_irq_chip_data(d); |
80 | irq_hw_number_t irq = irqd_to_hwirq(d); | ||
78 | uint32_t icmr = __raw_readl(base + ICMR); | 81 | uint32_t icmr = __raw_readl(base + ICMR); |
79 | 82 | ||
80 | icmr |= 1 << IRQ_BIT(d->irq); | 83 | icmr |= BIT(irq & 0x1f); |
81 | __raw_writel(icmr, base + ICMR); | 84 | __raw_writel(icmr, base + ICMR); |
82 | } | 85 | } |
83 | 86 | ||
@@ -118,40 +121,63 @@ asmlinkage void __exception_irq_entry ichp_handle_irq(struct pt_regs *regs) | |||
118 | } while (1); | 121 | } while (1); |
119 | } | 122 | } |
120 | 123 | ||
121 | void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int)) | 124 | static int pxa_irq_map(struct irq_domain *h, unsigned int virq, |
125 | irq_hw_number_t hw) | ||
122 | { | 126 | { |
123 | int irq, i, n; | 127 | void __iomem *base = irq_base(hw / 32); |
124 | 128 | ||
125 | BUG_ON(irq_nr > MAX_INTERNAL_IRQS); | 129 | /* initialize interrupt priority */ |
130 | if (cpu_has_ipr) | ||
131 | __raw_writel(hw | IPR_VALID, pxa_irq_base + IPR(hw)); | ||
132 | |||
133 | irq_set_chip_and_handler(virq, &pxa_internal_irq_chip, | ||
134 | handle_level_irq); | ||
135 | irq_set_chip_data(virq, base); | ||
136 | set_irq_flags(virq, IRQF_VALID); | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static struct irq_domain_ops pxa_irq_ops = { | ||
142 | .map = pxa_irq_map, | ||
143 | .xlate = irq_domain_xlate_onecell, | ||
144 | }; | ||
145 | |||
146 | static __init void | ||
147 | pxa_init_irq_common(struct device_node *node, int irq_nr, | ||
148 | int (*fn)(struct irq_data *, unsigned int)) | ||
149 | { | ||
150 | int n; | ||
126 | 151 | ||
127 | pxa_internal_irq_nr = irq_nr; | 152 | pxa_internal_irq_nr = irq_nr; |
128 | cpu_has_ipr = !cpu_is_pxa25x(); | 153 | pxa_irq_domain = irq_domain_add_legacy(node, irq_nr, |
129 | pxa_irq_base = io_p2v(0x40d00000); | 154 | PXA_IRQ(0), 0, |
155 | &pxa_irq_ops, NULL); | ||
156 | if (!pxa_irq_domain) | ||
157 | panic("Unable to add PXA IRQ domain\n"); | ||
158 | irq_set_default_host(pxa_irq_domain); | ||
130 | 159 | ||
131 | for (n = 0; n < irq_nr; n += 32) { | 160 | for (n = 0; n < irq_nr; n += 32) { |
132 | void __iomem *base = irq_base(n >> 5); | 161 | void __iomem *base = irq_base(n >> 5); |
133 | 162 | ||
134 | __raw_writel(0, base + ICMR); /* disable all IRQs */ | 163 | __raw_writel(0, base + ICMR); /* disable all IRQs */ |
135 | __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */ | 164 | __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */ |
136 | for (i = n; (i < (n + 32)) && (i < irq_nr); i++) { | ||
137 | /* initialize interrupt priority */ | ||
138 | if (cpu_has_ipr) | ||
139 | __raw_writel(i | IPR_VALID, pxa_irq_base + IPR(i)); | ||
140 | |||
141 | irq = PXA_IRQ(i); | ||
142 | irq_set_chip_and_handler(irq, &pxa_internal_irq_chip, | ||
143 | handle_level_irq); | ||
144 | irq_set_chip_data(irq, base); | ||
145 | set_irq_flags(irq, IRQF_VALID); | ||
146 | } | ||
147 | } | 165 | } |
148 | |||
149 | /* only unmasked interrupts kick us out of idle */ | 166 | /* only unmasked interrupts kick us out of idle */ |
150 | __raw_writel(1, irq_base(0) + ICCR); | 167 | __raw_writel(1, irq_base(0) + ICCR); |
151 | 168 | ||
152 | pxa_internal_irq_chip.irq_set_wake = fn; | 169 | pxa_internal_irq_chip.irq_set_wake = fn; |
153 | } | 170 | } |
154 | 171 | ||
172 | void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int)) | ||
173 | { | ||
174 | BUG_ON(irq_nr > MAX_INTERNAL_IRQS); | ||
175 | |||
176 | pxa_irq_base = io_p2v(0x40d00000); | ||
177 | cpu_has_ipr = !cpu_is_pxa25x(); | ||
178 | pxa_init_irq_common(NULL, irq_nr, fn); | ||
179 | } | ||
180 | |||
155 | #ifdef CONFIG_PM | 181 | #ifdef CONFIG_PM |
156 | static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32]; | 182 | static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32]; |
157 | static unsigned long saved_ipr[MAX_INTERNAL_IRQS]; | 183 | static unsigned long saved_ipr[MAX_INTERNAL_IRQS]; |
@@ -203,30 +229,6 @@ struct syscore_ops pxa_irq_syscore_ops = { | |||
203 | }; | 229 | }; |
204 | 230 | ||
205 | #ifdef CONFIG_OF | 231 | #ifdef CONFIG_OF |
206 | static struct irq_domain *pxa_irq_domain; | ||
207 | |||
208 | static int pxa_irq_map(struct irq_domain *h, unsigned int virq, | ||
209 | irq_hw_number_t hw) | ||
210 | { | ||
211 | void __iomem *base = irq_base(hw / 32); | ||
212 | |||
213 | /* initialize interrupt priority */ | ||
214 | if (cpu_has_ipr) | ||
215 | __raw_writel(hw | IPR_VALID, pxa_irq_base + IPR(hw)); | ||
216 | |||
217 | irq_set_chip_and_handler(hw, &pxa_internal_irq_chip, | ||
218 | handle_level_irq); | ||
219 | irq_set_chip_data(hw, base); | ||
220 | set_irq_flags(hw, IRQF_VALID); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static struct irq_domain_ops pxa_irq_ops = { | ||
226 | .map = pxa_irq_map, | ||
227 | .xlate = irq_domain_xlate_onecell, | ||
228 | }; | ||
229 | |||
230 | static const struct of_device_id intc_ids[] __initconst = { | 232 | static const struct of_device_id intc_ids[] __initconst = { |
231 | { .compatible = "marvell,pxa-intc", }, | 233 | { .compatible = "marvell,pxa-intc", }, |
232 | {} | 234 | {} |
@@ -236,7 +238,7 @@ void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int)) | |||
236 | { | 238 | { |
237 | struct device_node *node; | 239 | struct device_node *node; |
238 | struct resource res; | 240 | struct resource res; |
239 | int n, ret; | 241 | int ret; |
240 | 242 | ||
241 | node = of_find_matching_node(NULL, intc_ids); | 243 | node = of_find_matching_node(NULL, intc_ids); |
242 | if (!node) { | 244 | if (!node) { |
@@ -267,23 +269,6 @@ void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int)) | |||
267 | return; | 269 | return; |
268 | } | 270 | } |
269 | 271 | ||
270 | pxa_irq_domain = irq_domain_add_legacy(node, pxa_internal_irq_nr, 0, 0, | 272 | pxa_init_irq_common(node, pxa_internal_irq_nr, fn); |
271 | &pxa_irq_ops, NULL); | ||
272 | if (!pxa_irq_domain) | ||
273 | panic("Unable to add PXA IRQ domain\n"); | ||
274 | |||
275 | irq_set_default_host(pxa_irq_domain); | ||
276 | |||
277 | for (n = 0; n < pxa_internal_irq_nr; n += 32) { | ||
278 | void __iomem *base = irq_base(n >> 5); | ||
279 | |||
280 | __raw_writel(0, base + ICMR); /* disable all IRQs */ | ||
281 | __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */ | ||
282 | } | ||
283 | |||
284 | /* only unmasked interrupts kick us out of idle */ | ||
285 | __raw_writel(1, irq_base(0) + ICCR); | ||
286 | |||
287 | pxa_internal_irq_chip.irq_set_wake = fn; | ||
288 | } | 273 | } |
289 | #endif /* CONFIG_OF */ | 274 | #endif /* CONFIG_OF */ |
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index ad777b353bd5..eaee2c20b189 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
25 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
26 | #include <linux/pwm_backlight.h> | 26 | #include <linux/pwm_backlight.h> |
27 | #include <linux/smc91x.h> | ||
27 | 28 | ||
28 | #include <asm/types.h> | 29 | #include <asm/types.h> |
29 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
@@ -189,15 +190,20 @@ static struct resource smc91x_resources[] = { | |||
189 | [1] = { | 190 | [1] = { |
190 | .start = LPD270_ETHERNET_IRQ, | 191 | .start = LPD270_ETHERNET_IRQ, |
191 | .end = LPD270_ETHERNET_IRQ, | 192 | .end = LPD270_ETHERNET_IRQ, |
192 | .flags = IORESOURCE_IRQ, | 193 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, |
193 | }, | 194 | }, |
194 | }; | 195 | }; |
195 | 196 | ||
197 | struct smc91x_platdata smc91x_platdata = { | ||
198 | .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, | ||
199 | }; | ||
200 | |||
196 | static struct platform_device smc91x_device = { | 201 | static struct platform_device smc91x_device = { |
197 | .name = "smc91x", | 202 | .name = "smc91x", |
198 | .id = 0, | 203 | .id = 0, |
199 | .num_resources = ARRAY_SIZE(smc91x_resources), | 204 | .num_resources = ARRAY_SIZE(smc91x_resources), |
200 | .resource = smc91x_resources, | 205 | .resource = smc91x_resources, |
206 | .dev.platform_data = &smc91x_platdata, | ||
201 | }; | 207 | }; |
202 | 208 | ||
203 | static struct resource lpd270_flash_resources[] = { | 209 | static struct resource lpd270_flash_resources[] = { |
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 205f9bf3821e..ac2ae5c71ab4 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c | |||
@@ -412,7 +412,7 @@ static struct fixed_voltage_config can_regulator_pdata = { | |||
412 | }; | 412 | }; |
413 | 413 | ||
414 | static struct platform_device can_regulator_device = { | 414 | static struct platform_device can_regulator_device = { |
415 | .name = "reg-fixed-volage", | 415 | .name = "reg-fixed-voltage", |
416 | .id = 0, | 416 | .id = 0, |
417 | .dev = { | 417 | .dev = { |
418 | .platform_data = &can_regulator_pdata, | 418 | .platform_data = &can_regulator_pdata, |
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 850e506926df..c309593abdb2 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/platform_data/video-clcd-versatile.h> | 28 | #include <linux/platform_data/video-clcd-versatile.h> |
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | #include <linux/smsc911x.h> | 30 | #include <linux/smsc911x.h> |
31 | #include <linux/smc91x.h> | ||
31 | #include <linux/ata_platform.h> | 32 | #include <linux/ata_platform.h> |
32 | #include <linux/amba/mmci.h> | 33 | #include <linux/amba/mmci.h> |
33 | #include <linux/gfp.h> | 34 | #include <linux/gfp.h> |
@@ -94,6 +95,10 @@ static struct smsc911x_platform_config smsc911x_config = { | |||
94 | .phy_interface = PHY_INTERFACE_MODE_MII, | 95 | .phy_interface = PHY_INTERFACE_MODE_MII, |
95 | }; | 96 | }; |
96 | 97 | ||
98 | static struct smc91x_platdata smc91x_platdata = { | ||
99 | .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT, | ||
100 | }; | ||
101 | |||
97 | static struct platform_device realview_eth_device = { | 102 | static struct platform_device realview_eth_device = { |
98 | .name = "smsc911x", | 103 | .name = "smsc911x", |
99 | .id = 0, | 104 | .id = 0, |
@@ -107,6 +112,8 @@ int realview_eth_register(const char *name, struct resource *res) | |||
107 | realview_eth_device.resource = res; | 112 | realview_eth_device.resource = res; |
108 | if (strcmp(realview_eth_device.name, "smsc911x") == 0) | 113 | if (strcmp(realview_eth_device.name, "smsc911x") == 0) |
109 | realview_eth_device.dev.platform_data = &smsc911x_config; | 114 | realview_eth_device.dev.platform_data = &smsc911x_config; |
115 | else | ||
116 | realview_eth_device.dev.platform_data = &smc91x_platdata; | ||
110 | 117 | ||
111 | return platform_device_register(&realview_eth_device); | 118 | return platform_device_register(&realview_eth_device); |
112 | } | 119 | } |
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 64c88d657f9e..b3869cbbcc68 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c | |||
@@ -234,7 +234,7 @@ static struct resource realview_eb_eth_resources[] = { | |||
234 | [1] = { | 234 | [1] = { |
235 | .start = IRQ_EB_ETH, | 235 | .start = IRQ_EB_ETH, |
236 | .end = IRQ_EB_ETH, | 236 | .end = IRQ_EB_ETH, |
237 | .flags = IORESOURCE_IRQ, | 237 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, |
238 | }, | 238 | }, |
239 | }; | 239 | }; |
240 | 240 | ||
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 169262e3040d..af868d258e66 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/pm.h> | 12 | #include <linux/pm.h> |
13 | #include <linux/serial_core.h> | 13 | #include <linux/serial_core.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/smc91x.h> | ||
15 | 16 | ||
16 | #include <asm/mach-types.h> | 17 | #include <asm/mach-types.h> |
17 | #include <asm/mach/map.h> | 18 | #include <asm/mach/map.h> |
@@ -258,12 +259,17 @@ static int neponset_probe(struct platform_device *dev) | |||
258 | 0x02000000, "smc91x-attrib"), | 259 | 0x02000000, "smc91x-attrib"), |
259 | { .flags = IORESOURCE_IRQ }, | 260 | { .flags = IORESOURCE_IRQ }, |
260 | }; | 261 | }; |
262 | struct smc91x_platdata smc91x_platdata = { | ||
263 | .flags = SMC91X_USE_8BIT | SMC91X_IO_SHIFT_2 | SMC91X_NOWAIT, | ||
264 | }; | ||
261 | struct platform_device_info smc91x_devinfo = { | 265 | struct platform_device_info smc91x_devinfo = { |
262 | .parent = &dev->dev, | 266 | .parent = &dev->dev, |
263 | .name = "smc91x", | 267 | .name = "smc91x", |
264 | .id = 0, | 268 | .id = 0, |
265 | .res = smc91x_resources, | 269 | .res = smc91x_resources, |
266 | .num_res = ARRAY_SIZE(smc91x_resources), | 270 | .num_res = ARRAY_SIZE(smc91x_resources), |
271 | .data = &smc91x_platdata, | ||
272 | .size_data = sizeof(smc91x_platdata), | ||
267 | }; | 273 | }; |
268 | int ret, irq; | 274 | int ret, irq; |
269 | 275 | ||
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 091261878eff..1525d7b5f1b7 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
13 | #include <linux/mtd/partitions.h> | 13 | #include <linux/mtd/partitions.h> |
14 | #include <linux/smc91x.h> | ||
14 | 15 | ||
15 | #include <mach/hardware.h> | 16 | #include <mach/hardware.h> |
16 | #include <asm/setup.h> | 17 | #include <asm/setup.h> |
@@ -43,12 +44,18 @@ static struct resource smc91x_resources[] = { | |||
43 | #endif | 44 | #endif |
44 | }; | 45 | }; |
45 | 46 | ||
47 | static struct smc91x_platdata smc91x_platdata = { | ||
48 | .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, | ||
49 | }; | ||
46 | 50 | ||
47 | static struct platform_device smc91x_device = { | 51 | static struct platform_device smc91x_device = { |
48 | .name = "smc91x", | 52 | .name = "smc91x", |
49 | .id = 0, | 53 | .id = 0, |
50 | .num_resources = ARRAY_SIZE(smc91x_resources), | 54 | .num_resources = ARRAY_SIZE(smc91x_resources), |
51 | .resource = smc91x_resources, | 55 | .resource = smc91x_resources, |
56 | .dev = { | ||
57 | .platform_data = &smc91x_platdata, | ||
58 | }, | ||
52 | }; | 59 | }; |
53 | 60 | ||
54 | static struct platform_device *devices[] __initdata = { | 61 | static struct platform_device *devices[] __initdata = { |
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h index 483cb467bf65..a0f3b1cd497c 100644 --- a/arch/arm/mach-socfpga/core.h +++ b/arch/arm/mach-socfpga/core.h | |||
@@ -45,6 +45,6 @@ extern char secondary_trampoline, secondary_trampoline_end; | |||
45 | 45 | ||
46 | extern unsigned long socfpga_cpu1start_addr; | 46 | extern unsigned long socfpga_cpu1start_addr; |
47 | 47 | ||
48 | #define SOCFPGA_SCU_VIRT_BASE 0xfffec000 | 48 | #define SOCFPGA_SCU_VIRT_BASE 0xfee00000 |
49 | 49 | ||
50 | #endif | 50 | #endif |
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c index 383d61e138af..f5e597c207b9 100644 --- a/arch/arm/mach-socfpga/socfpga.c +++ b/arch/arm/mach-socfpga/socfpga.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <asm/hardware/cache-l2x0.h> | 23 | #include <asm/hardware/cache-l2x0.h> |
24 | #include <asm/mach/arch.h> | 24 | #include <asm/mach/arch.h> |
25 | #include <asm/mach/map.h> | 25 | #include <asm/mach/map.h> |
26 | #include <asm/cacheflush.h> | ||
26 | 27 | ||
27 | #include "core.h" | 28 | #include "core.h" |
28 | 29 | ||
@@ -73,6 +74,10 @@ void __init socfpga_sysmgr_init(void) | |||
73 | (u32 *) &socfpga_cpu1start_addr)) | 74 | (u32 *) &socfpga_cpu1start_addr)) |
74 | pr_err("SMP: Need cpu1-start-addr in device tree.\n"); | 75 | pr_err("SMP: Need cpu1-start-addr in device tree.\n"); |
75 | 76 | ||
77 | /* Ensure that socfpga_cpu1start_addr is visible to other CPUs */ | ||
78 | smp_wmb(); | ||
79 | sync_cache_w(&socfpga_cpu1start_addr); | ||
80 | |||
76 | sys_manager_base_addr = of_iomap(np, 0); | 81 | sys_manager_base_addr = of_iomap(np, 0); |
77 | 82 | ||
78 | np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); | 83 | np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); |
diff --git a/arch/arm/mach-sti/board-dt.c b/arch/arm/mach-sti/board-dt.c index b067390cef4e..b373acade338 100644 --- a/arch/arm/mach-sti/board-dt.c +++ b/arch/arm/mach-sti/board-dt.c | |||
@@ -18,6 +18,7 @@ static const char *stih41x_dt_match[] __initdata = { | |||
18 | "st,stih415", | 18 | "st,stih415", |
19 | "st,stih416", | 19 | "st,stih416", |
20 | "st,stih407", | 20 | "st,stih407", |
21 | "st,stih410", | ||
21 | "st,stih418", | 22 | "st,stih418", |
22 | NULL | 23 | NULL |
23 | }; | 24 | }; |
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index a77604fbaf25..81502b90dd91 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig | |||
@@ -1,10 +1,12 @@ | |||
1 | menuconfig ARCH_SUNXI | 1 | menuconfig ARCH_SUNXI |
2 | bool "Allwinner SoCs" if ARCH_MULTI_V7 | 2 | bool "Allwinner SoCs" if ARCH_MULTI_V7 |
3 | select ARCH_REQUIRE_GPIOLIB | 3 | select ARCH_REQUIRE_GPIOLIB |
4 | select ARCH_HAS_RESET_CONTROLLER | ||
4 | select CLKSRC_MMIO | 5 | select CLKSRC_MMIO |
5 | select GENERIC_IRQ_CHIP | 6 | select GENERIC_IRQ_CHIP |
6 | select PINCTRL | 7 | select PINCTRL |
7 | select SUN4I_TIMER | 8 | select SUN4I_TIMER |
9 | select RESET_CONTROLLER | ||
8 | 10 | ||
9 | if ARCH_SUNXI | 11 | if ARCH_SUNXI |
10 | 12 | ||
@@ -20,10 +22,8 @@ config MACH_SUN5I | |||
20 | config MACH_SUN6I | 22 | config MACH_SUN6I |
21 | bool "Allwinner A31 (sun6i) SoCs support" | 23 | bool "Allwinner A31 (sun6i) SoCs support" |
22 | default ARCH_SUNXI | 24 | default ARCH_SUNXI |
23 | select ARCH_HAS_RESET_CONTROLLER | ||
24 | select ARM_GIC | 25 | select ARM_GIC |
25 | select MFD_SUN6I_PRCM | 26 | select MFD_SUN6I_PRCM |
26 | select RESET_CONTROLLER | ||
27 | select SUN5I_HSTIMER | 27 | select SUN5I_HSTIMER |
28 | 28 | ||
29 | config MACH_SUN7I | 29 | config MACH_SUN7I |
@@ -37,16 +37,12 @@ config MACH_SUN7I | |||
37 | config MACH_SUN8I | 37 | config MACH_SUN8I |
38 | bool "Allwinner A23 (sun8i) SoCs support" | 38 | bool "Allwinner A23 (sun8i) SoCs support" |
39 | default ARCH_SUNXI | 39 | default ARCH_SUNXI |
40 | select ARCH_HAS_RESET_CONTROLLER | ||
41 | select ARM_GIC | 40 | select ARM_GIC |
42 | select MFD_SUN6I_PRCM | 41 | select MFD_SUN6I_PRCM |
43 | select RESET_CONTROLLER | ||
44 | 42 | ||
45 | config MACH_SUN9I | 43 | config MACH_SUN9I |
46 | bool "Allwinner (sun9i) SoCs support" | 44 | bool "Allwinner (sun9i) SoCs support" |
47 | default ARCH_SUNXI | 45 | default ARCH_SUNXI |
48 | select ARCH_HAS_RESET_CONTROLLER | ||
49 | select ARM_GIC | 46 | select ARM_GIC |
50 | select RESET_CONTROLLER | ||
51 | 47 | ||
52 | endif | 48 | endif |
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index c6c7696b8db9..8f15f70622a6 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -1131,23 +1131,22 @@ static void __init l2c310_of_parse(const struct device_node *np, | |||
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K); | 1133 | ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K); |
1134 | if (ret) | 1134 | if (!ret) { |
1135 | return; | 1135 | switch (assoc) { |
1136 | 1136 | case 16: | |
1137 | switch (assoc) { | 1137 | *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK; |
1138 | case 16: | 1138 | *aux_val |= L310_AUX_CTRL_ASSOCIATIVITY_16; |
1139 | *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK; | 1139 | *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK; |
1140 | *aux_val |= L310_AUX_CTRL_ASSOCIATIVITY_16; | 1140 | break; |
1141 | *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK; | 1141 | case 8: |
1142 | break; | 1142 | *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK; |
1143 | case 8: | 1143 | *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK; |
1144 | *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK; | 1144 | break; |
1145 | *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK; | 1145 | default: |
1146 | break; | 1146 | pr_err("L2C-310 OF cache associativity %d invalid, only 8 or 16 permitted\n", |
1147 | default: | 1147 | assoc); |
1148 | pr_err("L2C-310 OF cache associativity %d invalid, only 8 or 16 permitted\n", | 1148 | break; |
1149 | assoc); | 1149 | } |
1150 | break; | ||
1151 | } | 1150 | } |
1152 | 1151 | ||
1153 | prefetch = l2x0_saved_regs.prefetch_ctrl; | 1152 | prefetch = l2x0_saved_regs.prefetch_ctrl; |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 170a116d1b29..c27447653903 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -171,7 +171,7 @@ static int __dma_supported(struct device *dev, u64 mask, bool warn) | |||
171 | */ | 171 | */ |
172 | if (sizeof(mask) != sizeof(dma_addr_t) && | 172 | if (sizeof(mask) != sizeof(dma_addr_t) && |
173 | mask > (dma_addr_t)~0 && | 173 | mask > (dma_addr_t)~0 && |
174 | dma_to_pfn(dev, ~0) < max_pfn) { | 174 | dma_to_pfn(dev, ~0) < max_pfn - 1) { |
175 | if (warn) { | 175 | if (warn) { |
176 | dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", | 176 | dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", |
177 | mask); | 177 | mask); |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index a982dc3190df..6333d9c17875 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -552,6 +552,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
552 | 552 | ||
553 | pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n", | 553 | pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n", |
554 | inf->name, fsr, addr); | 554 | inf->name, fsr, addr); |
555 | show_pte(current->mm, addr); | ||
555 | 556 | ||
556 | info.si_signo = inf->sig; | 557 | info.si_signo = inf->sig; |
557 | info.si_errno = 0; | 558 | info.si_errno = 0; |
diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c index 004e35cdcfff..cf30daff8932 100644 --- a/arch/arm/mm/pageattr.c +++ b/arch/arm/mm/pageattr.c | |||
@@ -49,7 +49,10 @@ static int change_memory_common(unsigned long addr, int numpages, | |||
49 | WARN_ON_ONCE(1); | 49 | WARN_ON_ONCE(1); |
50 | } | 50 | } |
51 | 51 | ||
52 | if (!is_module_address(start) || !is_module_address(end - 1)) | 52 | if (start < MODULES_VADDR || start >= MODULES_END) |
53 | return -EINVAL; | ||
54 | |||
55 | if (end < MODULES_VADDR || start >= MODULES_END) | ||
53 | return -EINVAL; | 56 | return -EINVAL; |
54 | 57 | ||
55 | data.set_mask = set_mask; | 58 | data.set_mask = set_mask; |
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index db10169a08de..8ca94d379bc3 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
@@ -799,6 +799,7 @@ static int omap_dm_timer_probe(struct platform_device *pdev) | |||
799 | struct device *dev = &pdev->dev; | 799 | struct device *dev = &pdev->dev; |
800 | const struct of_device_id *match; | 800 | const struct of_device_id *match; |
801 | const struct dmtimer_platform_data *pdata; | 801 | const struct dmtimer_platform_data *pdata; |
802 | int ret; | ||
802 | 803 | ||
803 | match = of_match_device(of_match_ptr(omap_timer_match), dev); | 804 | match = of_match_device(of_match_ptr(omap_timer_match), dev); |
804 | pdata = match ? match->data : dev->platform_data; | 805 | pdata = match ? match->data : dev->platform_data; |
@@ -860,7 +861,12 @@ static int omap_dm_timer_probe(struct platform_device *pdev) | |||
860 | } | 861 | } |
861 | 862 | ||
862 | if (!timer->reserved) { | 863 | if (!timer->reserved) { |
863 | pm_runtime_get_sync(dev); | 864 | ret = pm_runtime_get_sync(dev); |
865 | if (ret < 0) { | ||
866 | dev_err(dev, "%s: pm_runtime_get_sync failed!\n", | ||
867 | __func__); | ||
868 | goto err_get_sync; | ||
869 | } | ||
864 | __omap_dm_timer_init_regs(timer); | 870 | __omap_dm_timer_init_regs(timer); |
865 | pm_runtime_put(dev); | 871 | pm_runtime_put(dev); |
866 | } | 872 | } |
@@ -873,6 +879,11 @@ static int omap_dm_timer_probe(struct platform_device *pdev) | |||
873 | dev_dbg(dev, "Device Probed.\n"); | 879 | dev_dbg(dev, "Device Probed.\n"); |
874 | 880 | ||
875 | return 0; | 881 | return 0; |
882 | |||
883 | err_get_sync: | ||
884 | pm_runtime_put_noidle(dev); | ||
885 | pm_runtime_disable(dev); | ||
886 | return ret; | ||
876 | } | 887 | } |
877 | 888 | ||
878 | /** | 889 | /** |
@@ -899,6 +910,8 @@ static int omap_dm_timer_remove(struct platform_device *pdev) | |||
899 | } | 910 | } |
900 | spin_unlock_irqrestore(&dm_timer_lock, flags); | 911 | spin_unlock_irqrestore(&dm_timer_lock, flags); |
901 | 912 | ||
913 | pm_runtime_disable(&pdev->dev); | ||
914 | |||
902 | return ret; | 915 | return ret; |
903 | } | 916 | } |
904 | 917 | ||
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index f1ad9c2ab2e9..a857794432d6 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi | |||
@@ -622,7 +622,7 @@ | |||
622 | }; | 622 | }; |
623 | 623 | ||
624 | sgenet0: ethernet@1f210000 { | 624 | sgenet0: ethernet@1f210000 { |
625 | compatible = "apm,xgene-enet"; | 625 | compatible = "apm,xgene1-sgenet"; |
626 | status = "disabled"; | 626 | status = "disabled"; |
627 | reg = <0x0 0x1f210000 0x0 0xd100>, | 627 | reg = <0x0 0x1f210000 0x0 0xd100>, |
628 | <0x0 0x1f200000 0x0 0Xc300>, | 628 | <0x0 0x1f200000 0x0 0Xc300>, |
@@ -636,7 +636,7 @@ | |||
636 | }; | 636 | }; |
637 | 637 | ||
638 | xgenet: ethernet@1f610000 { | 638 | xgenet: ethernet@1f610000 { |
639 | compatible = "apm,xgene-enet"; | 639 | compatible = "apm,xgene1-xgenet"; |
640 | status = "disabled"; | 640 | status = "disabled"; |
641 | reg = <0x0 0x1f610000 0x0 0xd100>, | 641 | reg = <0x0 0x1f610000 0x0 0xd100>, |
642 | <0x0 0x1f600000 0x0 0Xc300>, | 642 | <0x0 0x1f600000 0x0 0Xc300>, |
diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dts b/arch/arm64/boot/dts/arm/foundation-v8.dts index 27f32962e55c..4eac8dcea423 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dts +++ b/arch/arm64/boot/dts/arm/foundation-v8.dts | |||
@@ -34,6 +34,7 @@ | |||
34 | reg = <0x0 0x0>; | 34 | reg = <0x0 0x0>; |
35 | enable-method = "spin-table"; | 35 | enable-method = "spin-table"; |
36 | cpu-release-addr = <0x0 0x8000fff8>; | 36 | cpu-release-addr = <0x0 0x8000fff8>; |
37 | next-level-cache = <&L2_0>; | ||
37 | }; | 38 | }; |
38 | cpu@1 { | 39 | cpu@1 { |
39 | device_type = "cpu"; | 40 | device_type = "cpu"; |
@@ -41,6 +42,7 @@ | |||
41 | reg = <0x0 0x1>; | 42 | reg = <0x0 0x1>; |
42 | enable-method = "spin-table"; | 43 | enable-method = "spin-table"; |
43 | cpu-release-addr = <0x0 0x8000fff8>; | 44 | cpu-release-addr = <0x0 0x8000fff8>; |
45 | next-level-cache = <&L2_0>; | ||
44 | }; | 46 | }; |
45 | cpu@2 { | 47 | cpu@2 { |
46 | device_type = "cpu"; | 48 | device_type = "cpu"; |
@@ -48,6 +50,7 @@ | |||
48 | reg = <0x0 0x2>; | 50 | reg = <0x0 0x2>; |
49 | enable-method = "spin-table"; | 51 | enable-method = "spin-table"; |
50 | cpu-release-addr = <0x0 0x8000fff8>; | 52 | cpu-release-addr = <0x0 0x8000fff8>; |
53 | next-level-cache = <&L2_0>; | ||
51 | }; | 54 | }; |
52 | cpu@3 { | 55 | cpu@3 { |
53 | device_type = "cpu"; | 56 | device_type = "cpu"; |
@@ -55,6 +58,11 @@ | |||
55 | reg = <0x0 0x3>; | 58 | reg = <0x0 0x3>; |
56 | enable-method = "spin-table"; | 59 | enable-method = "spin-table"; |
57 | cpu-release-addr = <0x0 0x8000fff8>; | 60 | cpu-release-addr = <0x0 0x8000fff8>; |
61 | next-level-cache = <&L2_0>; | ||
62 | }; | ||
63 | |||
64 | L2_0: l2-cache0 { | ||
65 | compatible = "cache"; | ||
58 | }; | 66 | }; |
59 | }; | 67 | }; |
60 | 68 | ||
diff --git a/arch/arm64/boot/dts/arm/juno-clocks.dtsi b/arch/arm64/boot/dts/arm/juno-clocks.dtsi index ea2b5666a16f..c9b89efe0f56 100644 --- a/arch/arm64/boot/dts/arm/juno-clocks.dtsi +++ b/arch/arm64/boot/dts/arm/juno-clocks.dtsi | |||
@@ -8,7 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* SoC fixed clocks */ | 10 | /* SoC fixed clocks */ |
11 | soc_uartclk: refclk72738khz { | 11 | soc_uartclk: refclk7273800hz { |
12 | compatible = "fixed-clock"; | 12 | compatible = "fixed-clock"; |
13 | #clock-cells = <0>; | 13 | #clock-cells = <0>; |
14 | clock-frequency = <7273800>; | 14 | clock-frequency = <7273800>; |
diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts index d429129ecb3d..133ee59de2d7 100644 --- a/arch/arm64/boot/dts/arm/juno.dts +++ b/arch/arm64/boot/dts/arm/juno.dts | |||
@@ -39,6 +39,7 @@ | |||
39 | reg = <0x0 0x0>; | 39 | reg = <0x0 0x0>; |
40 | device_type = "cpu"; | 40 | device_type = "cpu"; |
41 | enable-method = "psci"; | 41 | enable-method = "psci"; |
42 | next-level-cache = <&A57_L2>; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | A57_1: cpu@1 { | 45 | A57_1: cpu@1 { |
@@ -46,6 +47,7 @@ | |||
46 | reg = <0x0 0x1>; | 47 | reg = <0x0 0x1>; |
47 | device_type = "cpu"; | 48 | device_type = "cpu"; |
48 | enable-method = "psci"; | 49 | enable-method = "psci"; |
50 | next-level-cache = <&A57_L2>; | ||
49 | }; | 51 | }; |
50 | 52 | ||
51 | A53_0: cpu@100 { | 53 | A53_0: cpu@100 { |
@@ -53,6 +55,7 @@ | |||
53 | reg = <0x0 0x100>; | 55 | reg = <0x0 0x100>; |
54 | device_type = "cpu"; | 56 | device_type = "cpu"; |
55 | enable-method = "psci"; | 57 | enable-method = "psci"; |
58 | next-level-cache = <&A53_L2>; | ||
56 | }; | 59 | }; |
57 | 60 | ||
58 | A53_1: cpu@101 { | 61 | A53_1: cpu@101 { |
@@ -60,6 +63,7 @@ | |||
60 | reg = <0x0 0x101>; | 63 | reg = <0x0 0x101>; |
61 | device_type = "cpu"; | 64 | device_type = "cpu"; |
62 | enable-method = "psci"; | 65 | enable-method = "psci"; |
66 | next-level-cache = <&A53_L2>; | ||
63 | }; | 67 | }; |
64 | 68 | ||
65 | A53_2: cpu@102 { | 69 | A53_2: cpu@102 { |
@@ -67,6 +71,7 @@ | |||
67 | reg = <0x0 0x102>; | 71 | reg = <0x0 0x102>; |
68 | device_type = "cpu"; | 72 | device_type = "cpu"; |
69 | enable-method = "psci"; | 73 | enable-method = "psci"; |
74 | next-level-cache = <&A53_L2>; | ||
70 | }; | 75 | }; |
71 | 76 | ||
72 | A53_3: cpu@103 { | 77 | A53_3: cpu@103 { |
@@ -74,6 +79,15 @@ | |||
74 | reg = <0x0 0x103>; | 79 | reg = <0x0 0x103>; |
75 | device_type = "cpu"; | 80 | device_type = "cpu"; |
76 | enable-method = "psci"; | 81 | enable-method = "psci"; |
82 | next-level-cache = <&A53_L2>; | ||
83 | }; | ||
84 | |||
85 | A57_L2: l2-cache0 { | ||
86 | compatible = "cache"; | ||
87 | }; | ||
88 | |||
89 | A53_L2: l2-cache1 { | ||
90 | compatible = "cache"; | ||
77 | }; | 91 | }; |
78 | }; | 92 | }; |
79 | 93 | ||
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts index efc59b3baf63..20addabbd127 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts +++ b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts | |||
@@ -37,6 +37,7 @@ | |||
37 | reg = <0x0 0x0>; | 37 | reg = <0x0 0x0>; |
38 | enable-method = "spin-table"; | 38 | enable-method = "spin-table"; |
39 | cpu-release-addr = <0x0 0x8000fff8>; | 39 | cpu-release-addr = <0x0 0x8000fff8>; |
40 | next-level-cache = <&L2_0>; | ||
40 | }; | 41 | }; |
41 | cpu@1 { | 42 | cpu@1 { |
42 | device_type = "cpu"; | 43 | device_type = "cpu"; |
@@ -44,6 +45,7 @@ | |||
44 | reg = <0x0 0x1>; | 45 | reg = <0x0 0x1>; |
45 | enable-method = "spin-table"; | 46 | enable-method = "spin-table"; |
46 | cpu-release-addr = <0x0 0x8000fff8>; | 47 | cpu-release-addr = <0x0 0x8000fff8>; |
48 | next-level-cache = <&L2_0>; | ||
47 | }; | 49 | }; |
48 | cpu@2 { | 50 | cpu@2 { |
49 | device_type = "cpu"; | 51 | device_type = "cpu"; |
@@ -51,6 +53,7 @@ | |||
51 | reg = <0x0 0x2>; | 53 | reg = <0x0 0x2>; |
52 | enable-method = "spin-table"; | 54 | enable-method = "spin-table"; |
53 | cpu-release-addr = <0x0 0x8000fff8>; | 55 | cpu-release-addr = <0x0 0x8000fff8>; |
56 | next-level-cache = <&L2_0>; | ||
54 | }; | 57 | }; |
55 | cpu@3 { | 58 | cpu@3 { |
56 | device_type = "cpu"; | 59 | device_type = "cpu"; |
@@ -58,6 +61,11 @@ | |||
58 | reg = <0x0 0x3>; | 61 | reg = <0x0 0x3>; |
59 | enable-method = "spin-table"; | 62 | enable-method = "spin-table"; |
60 | cpu-release-addr = <0x0 0x8000fff8>; | 63 | cpu-release-addr = <0x0 0x8000fff8>; |
64 | next-level-cache = <&L2_0>; | ||
65 | }; | ||
66 | |||
67 | L2_0: l2-cache0 { | ||
68 | compatible = "cache"; | ||
61 | }; | 69 | }; |
62 | }; | 70 | }; |
63 | 71 | ||
diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile index 5720608c50b1..abb79b3cfcfe 100644 --- a/arch/arm64/crypto/Makefile +++ b/arch/arm64/crypto/Makefile | |||
@@ -29,7 +29,7 @@ aes-ce-blk-y := aes-glue-ce.o aes-ce.o | |||
29 | obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o | 29 | obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o |
30 | aes-neon-blk-y := aes-glue-neon.o aes-neon.o | 30 | aes-neon-blk-y := aes-glue-neon.o aes-neon.o |
31 | 31 | ||
32 | AFLAGS_aes-ce.o := -DINTERLEAVE=2 -DINTERLEAVE_INLINE | 32 | AFLAGS_aes-ce.o := -DINTERLEAVE=4 |
33 | AFLAGS_aes-neon.o := -DINTERLEAVE=4 | 33 | AFLAGS_aes-neon.o := -DINTERLEAVE=4 |
34 | 34 | ||
35 | CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS | 35 | CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS |
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 5901480bfdca..750bac4e637e 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h | |||
@@ -20,6 +20,9 @@ | |||
20 | #error "Only include this from assembly code" | 20 | #error "Only include this from assembly code" |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #ifndef __ASM_ASSEMBLER_H | ||
24 | #define __ASM_ASSEMBLER_H | ||
25 | |||
23 | #include <asm/ptrace.h> | 26 | #include <asm/ptrace.h> |
24 | #include <asm/thread_info.h> | 27 | #include <asm/thread_info.h> |
25 | 28 | ||
@@ -155,3 +158,5 @@ lr .req x30 // link register | |||
155 | #endif | 158 | #endif |
156 | orr \rd, \lbits, \hbits, lsl #32 | 159 | orr \rd, \lbits, \hbits, lsl #32 |
157 | .endm | 160 | .endm |
161 | |||
162 | #endif /* __ASM_ASSEMBLER_H */ | ||
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h index cb9593079f29..d8c25b7b18fb 100644 --- a/arch/arm64/include/asm/cmpxchg.h +++ b/arch/arm64/include/asm/cmpxchg.h | |||
@@ -246,14 +246,30 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old, | |||
246 | __ret; \ | 246 | __ret; \ |
247 | }) | 247 | }) |
248 | 248 | ||
249 | #define this_cpu_cmpxchg_1(ptr, o, n) cmpxchg_local(raw_cpu_ptr(&(ptr)), o, n) | 249 | #define _protect_cmpxchg_local(pcp, o, n) \ |
250 | #define this_cpu_cmpxchg_2(ptr, o, n) cmpxchg_local(raw_cpu_ptr(&(ptr)), o, n) | 250 | ({ \ |
251 | #define this_cpu_cmpxchg_4(ptr, o, n) cmpxchg_local(raw_cpu_ptr(&(ptr)), o, n) | 251 | typeof(*raw_cpu_ptr(&(pcp))) __ret; \ |
252 | #define this_cpu_cmpxchg_8(ptr, o, n) cmpxchg_local(raw_cpu_ptr(&(ptr)), o, n) | 252 | preempt_disable(); \ |
253 | 253 | __ret = cmpxchg_local(raw_cpu_ptr(&(pcp)), o, n); \ | |
254 | #define this_cpu_cmpxchg_double_8(ptr1, ptr2, o1, o2, n1, n2) \ | 254 | preempt_enable(); \ |
255 | cmpxchg_double_local(raw_cpu_ptr(&(ptr1)), raw_cpu_ptr(&(ptr2)), \ | 255 | __ret; \ |
256 | o1, o2, n1, n2) | 256 | }) |
257 | |||
258 | #define this_cpu_cmpxchg_1(ptr, o, n) _protect_cmpxchg_local(ptr, o, n) | ||
259 | #define this_cpu_cmpxchg_2(ptr, o, n) _protect_cmpxchg_local(ptr, o, n) | ||
260 | #define this_cpu_cmpxchg_4(ptr, o, n) _protect_cmpxchg_local(ptr, o, n) | ||
261 | #define this_cpu_cmpxchg_8(ptr, o, n) _protect_cmpxchg_local(ptr, o, n) | ||
262 | |||
263 | #define this_cpu_cmpxchg_double_8(ptr1, ptr2, o1, o2, n1, n2) \ | ||
264 | ({ \ | ||
265 | int __ret; \ | ||
266 | preempt_disable(); \ | ||
267 | __ret = cmpxchg_double_local( raw_cpu_ptr(&(ptr1)), \ | ||
268 | raw_cpu_ptr(&(ptr2)), \ | ||
269 | o1, o2, n1, n2); \ | ||
270 | preempt_enable(); \ | ||
271 | __ret; \ | ||
272 | }) | ||
257 | 273 | ||
258 | #define cmpxchg64(ptr,o,n) cmpxchg((ptr),(o),(n)) | 274 | #define cmpxchg64(ptr,o,n) cmpxchg((ptr),(o),(n)) |
259 | #define cmpxchg64_local(ptr,o,n) cmpxchg_local((ptr),(o),(n)) | 275 | #define cmpxchg64_local(ptr,o,n) cmpxchg_local((ptr),(o),(n)) |
diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h index 0710654631e7..c60643f14cda 100644 --- a/arch/arm64/include/asm/cpuidle.h +++ b/arch/arm64/include/asm/cpuidle.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef __ASM_CPUIDLE_H | 1 | #ifndef __ASM_CPUIDLE_H |
2 | #define __ASM_CPUIDLE_H | 2 | #define __ASM_CPUIDLE_H |
3 | 3 | ||
4 | #include <asm/proc-fns.h> | ||
5 | |||
4 | #ifdef CONFIG_CPU_IDLE | 6 | #ifdef CONFIG_CPU_IDLE |
5 | extern int cpu_init_idle(unsigned int cpu); | 7 | extern int cpu_init_idle(unsigned int cpu); |
6 | extern int cpu_suspend(unsigned long arg); | 8 | extern int cpu_suspend(unsigned long arg); |
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 92bbae381598..70522450ca23 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h | |||
@@ -90,6 +90,7 @@ | |||
90 | #define ESR_ELx_FSC (0x3F) | 90 | #define ESR_ELx_FSC (0x3F) |
91 | #define ESR_ELx_FSC_TYPE (0x3C) | 91 | #define ESR_ELx_FSC_TYPE (0x3C) |
92 | #define ESR_ELx_FSC_EXTABT (0x10) | 92 | #define ESR_ELx_FSC_EXTABT (0x10) |
93 | #define ESR_ELx_FSC_ACCESS (0x08) | ||
93 | #define ESR_ELx_FSC_FAULT (0x04) | 94 | #define ESR_ELx_FSC_FAULT (0x04) |
94 | #define ESR_ELx_FSC_PERM (0x0C) | 95 | #define ESR_ELx_FSC_PERM (0x0C) |
95 | #define ESR_ELx_CV (UL(1) << 24) | 96 | #define ESR_ELx_CV (UL(1) << 24) |
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index e2ff32a93b5c..d2f49423c5dc 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h | |||
@@ -264,8 +264,10 @@ __AARCH64_INSN_FUNCS(ands, 0x7F200000, 0x6A000000) | |||
264 | __AARCH64_INSN_FUNCS(bics, 0x7F200000, 0x6A200000) | 264 | __AARCH64_INSN_FUNCS(bics, 0x7F200000, 0x6A200000) |
265 | __AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000) | 265 | __AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000) |
266 | __AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000) | 266 | __AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000) |
267 | __AARCH64_INSN_FUNCS(cbz, 0xFE000000, 0x34000000) | 267 | __AARCH64_INSN_FUNCS(cbz, 0x7F000000, 0x34000000) |
268 | __AARCH64_INSN_FUNCS(cbnz, 0xFE000000, 0x35000000) | 268 | __AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000) |
269 | __AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000) | ||
270 | __AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000) | ||
269 | __AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000) | 271 | __AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000) |
270 | __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001) | 272 | __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001) |
271 | __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002) | 273 | __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002) |
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 94674eb7e7bb..ac6fafb95fe7 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h | |||
@@ -129,6 +129,9 @@ | |||
129 | * 40 bits wide (T0SZ = 24). Systems with a PARange smaller than 40 bits are | 129 | * 40 bits wide (T0SZ = 24). Systems with a PARange smaller than 40 bits are |
130 | * not known to exist and will break with this configuration. | 130 | * not known to exist and will break with this configuration. |
131 | * | 131 | * |
132 | * VTCR_EL2.PS is extracted from ID_AA64MMFR0_EL1.PARange at boot time | ||
133 | * (see hyp-init.S). | ||
134 | * | ||
132 | * Note that when using 4K pages, we concatenate two first level page tables | 135 | * Note that when using 4K pages, we concatenate two first level page tables |
133 | * together. | 136 | * together. |
134 | * | 137 | * |
@@ -138,7 +141,6 @@ | |||
138 | #ifdef CONFIG_ARM64_64K_PAGES | 141 | #ifdef CONFIG_ARM64_64K_PAGES |
139 | /* | 142 | /* |
140 | * Stage2 translation configuration: | 143 | * Stage2 translation configuration: |
141 | * 40bits output (PS = 2) | ||
142 | * 40bits input (T0SZ = 24) | 144 | * 40bits input (T0SZ = 24) |
143 | * 64kB pages (TG0 = 1) | 145 | * 64kB pages (TG0 = 1) |
144 | * 2 level page tables (SL = 1) | 146 | * 2 level page tables (SL = 1) |
@@ -150,7 +152,6 @@ | |||
150 | #else | 152 | #else |
151 | /* | 153 | /* |
152 | * Stage2 translation configuration: | 154 | * Stage2 translation configuration: |
153 | * 40bits output (PS = 2) | ||
154 | * 40bits input (T0SZ = 24) | 155 | * 40bits input (T0SZ = 24) |
155 | * 4kB pages (TG0 = 0) | 156 | * 4kB pages (TG0 = 0) |
156 | * 3 level page tables (SL = 1) | 157 | * 3 level page tables (SL = 1) |
@@ -187,6 +188,7 @@ | |||
187 | 188 | ||
188 | /* For compatibility with fault code shared with 32-bit */ | 189 | /* For compatibility with fault code shared with 32-bit */ |
189 | #define FSC_FAULT ESR_ELx_FSC_FAULT | 190 | #define FSC_FAULT ESR_ELx_FSC_FAULT |
191 | #define FSC_ACCESS ESR_ELx_FSC_ACCESS | ||
190 | #define FSC_PERM ESR_ELx_FSC_PERM | 192 | #define FSC_PERM ESR_ELx_FSC_PERM |
191 | 193 | ||
192 | /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ | 194 | /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ |
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 8ac3c70fe3c6..f0f58c9beec0 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <asm/kvm_asm.h> | 28 | #include <asm/kvm_asm.h> |
29 | #include <asm/kvm_mmio.h> | 29 | #include <asm/kvm_mmio.h> |
30 | 30 | ||
31 | #define __KVM_HAVE_ARCH_INTC_INITIALIZED | ||
32 | |||
31 | #if defined(CONFIG_KVM_ARM_MAX_VCPUS) | 33 | #if defined(CONFIG_KVM_ARM_MAX_VCPUS) |
32 | #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS | 34 | #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS |
33 | #else | 35 | #else |
@@ -177,19 +179,10 @@ int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); | |||
177 | int kvm_unmap_hva_range(struct kvm *kvm, | 179 | int kvm_unmap_hva_range(struct kvm *kvm, |
178 | unsigned long start, unsigned long end); | 180 | unsigned long start, unsigned long end); |
179 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 181 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
182 | int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); | ||
183 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | ||
180 | 184 | ||
181 | /* We do not have shadow page tables, hence the empty hooks */ | 185 | /* We do not have shadow page tables, hence the empty hooks */ |
182 | static inline int kvm_age_hva(struct kvm *kvm, unsigned long start, | ||
183 | unsigned long end) | ||
184 | { | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) | ||
189 | { | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, | 186 | static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, |
194 | unsigned long address) | 187 | unsigned long address) |
195 | { | 188 | { |
diff --git a/arch/arm64/include/asm/kvm_mmio.h b/arch/arm64/include/asm/kvm_mmio.h index 9f52beb7cb13..889c908ee631 100644 --- a/arch/arm64/include/asm/kvm_mmio.h +++ b/arch/arm64/include/asm/kvm_mmio.h | |||
@@ -31,28 +31,6 @@ struct kvm_decode { | |||
31 | bool sign_extend; | 31 | bool sign_extend; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | /* | ||
35 | * The in-kernel MMIO emulation code wants to use a copy of run->mmio, | ||
36 | * which is an anonymous type. Use our own type instead. | ||
37 | */ | ||
38 | struct kvm_exit_mmio { | ||
39 | phys_addr_t phys_addr; | ||
40 | u8 data[8]; | ||
41 | u32 len; | ||
42 | bool is_write; | ||
43 | void *private; | ||
44 | }; | ||
45 | |||
46 | static inline void kvm_prepare_mmio(struct kvm_run *run, | ||
47 | struct kvm_exit_mmio *mmio) | ||
48 | { | ||
49 | run->mmio.phys_addr = mmio->phys_addr; | ||
50 | run->mmio.len = mmio->len; | ||
51 | run->mmio.is_write = mmio->is_write; | ||
52 | memcpy(run->mmio.data, mmio->data, mmio->len); | ||
53 | run->exit_reason = KVM_EXIT_MMIO; | ||
54 | } | ||
55 | |||
56 | int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run); | 34 | int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run); |
57 | int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, | 35 | int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, |
58 | phys_addr_t fault_ipa); | 36 | phys_addr_t fault_ipa); |
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 6458b5373142..bbfb600fa822 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h | |||
@@ -158,6 +158,8 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd) | |||
158 | #define PTRS_PER_S2_PGD (1 << PTRS_PER_S2_PGD_SHIFT) | 158 | #define PTRS_PER_S2_PGD (1 << PTRS_PER_S2_PGD_SHIFT) |
159 | #define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t)) | 159 | #define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t)) |
160 | 160 | ||
161 | #define kvm_pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_S2_PGD - 1)) | ||
162 | |||
161 | /* | 163 | /* |
162 | * If we are concatenating first level stage-2 page tables, we would have less | 164 | * If we are concatenating first level stage-2 page tables, we would have less |
163 | * than or equal to 16 pointers in the fake PGD, because that's what the | 165 | * than or equal to 16 pointers in the fake PGD, because that's what the |
@@ -171,43 +173,6 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd) | |||
171 | #define KVM_PREALLOC_LEVEL (0) | 173 | #define KVM_PREALLOC_LEVEL (0) |
172 | #endif | 174 | #endif |
173 | 175 | ||
174 | /** | ||
175 | * kvm_prealloc_hwpgd - allocate inital table for VTTBR | ||
176 | * @kvm: The KVM struct pointer for the VM. | ||
177 | * @pgd: The kernel pseudo pgd | ||
178 | * | ||
179 | * When the kernel uses more levels of page tables than the guest, we allocate | ||
180 | * a fake PGD and pre-populate it to point to the next-level page table, which | ||
181 | * will be the real initial page table pointed to by the VTTBR. | ||
182 | * | ||
183 | * When KVM_PREALLOC_LEVEL==2, we allocate a single page for the PMD and | ||
184 | * the kernel will use folded pud. When KVM_PREALLOC_LEVEL==1, we | ||
185 | * allocate 2 consecutive PUD pages. | ||
186 | */ | ||
187 | static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd) | ||
188 | { | ||
189 | unsigned int i; | ||
190 | unsigned long hwpgd; | ||
191 | |||
192 | if (KVM_PREALLOC_LEVEL == 0) | ||
193 | return 0; | ||
194 | |||
195 | hwpgd = __get_free_pages(GFP_KERNEL | __GFP_ZERO, PTRS_PER_S2_PGD_SHIFT); | ||
196 | if (!hwpgd) | ||
197 | return -ENOMEM; | ||
198 | |||
199 | for (i = 0; i < PTRS_PER_S2_PGD; i++) { | ||
200 | if (KVM_PREALLOC_LEVEL == 1) | ||
201 | pgd_populate(NULL, pgd + i, | ||
202 | (pud_t *)hwpgd + i * PTRS_PER_PUD); | ||
203 | else if (KVM_PREALLOC_LEVEL == 2) | ||
204 | pud_populate(NULL, pud_offset(pgd, 0) + i, | ||
205 | (pmd_t *)hwpgd + i * PTRS_PER_PMD); | ||
206 | } | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static inline void *kvm_get_hwpgd(struct kvm *kvm) | 176 | static inline void *kvm_get_hwpgd(struct kvm *kvm) |
212 | { | 177 | { |
213 | pgd_t *pgd = kvm->arch.pgd; | 178 | pgd_t *pgd = kvm->arch.pgd; |
@@ -224,12 +189,11 @@ static inline void *kvm_get_hwpgd(struct kvm *kvm) | |||
224 | return pmd_offset(pud, 0); | 189 | return pmd_offset(pud, 0); |
225 | } | 190 | } |
226 | 191 | ||
227 | static inline void kvm_free_hwpgd(struct kvm *kvm) | 192 | static inline unsigned int kvm_get_hwpgd_size(void) |
228 | { | 193 | { |
229 | if (KVM_PREALLOC_LEVEL > 0) { | 194 | if (KVM_PREALLOC_LEVEL > 0) |
230 | unsigned long hwpgd = (unsigned long)kvm_get_hwpgd(kvm); | 195 | return PTRS_PER_S2_PGD * PAGE_SIZE; |
231 | free_pages(hwpgd, PTRS_PER_S2_PGD_SHIFT); | 196 | return PTRS_PER_S2_PGD * sizeof(pgd_t); |
232 | } | ||
233 | } | 197 | } |
234 | 198 | ||
235 | static inline bool kvm_page_empty(void *ptr) | 199 | static inline bool kvm_page_empty(void *ptr) |
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index a9eee33dfa62..101a42bde728 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h | |||
@@ -151,6 +151,15 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
151 | { | 151 | { |
152 | unsigned int cpu = smp_processor_id(); | 152 | unsigned int cpu = smp_processor_id(); |
153 | 153 | ||
154 | /* | ||
155 | * init_mm.pgd does not contain any user mappings and it is always | ||
156 | * active for kernel addresses in TTBR1. Just set the reserved TTBR0. | ||
157 | */ | ||
158 | if (next == &init_mm) { | ||
159 | cpu_set_reserved_ttbr0(); | ||
160 | return; | ||
161 | } | ||
162 | |||
154 | if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) | 163 | if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) |
155 | check_and_switch_context(next, tsk); | 164 | check_and_switch_context(next, tsk); |
156 | } | 165 | } |
diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h index 09da25bc596f..4fde8c1df97f 100644 --- a/arch/arm64/include/asm/percpu.h +++ b/arch/arm64/include/asm/percpu.h | |||
@@ -204,25 +204,47 @@ static inline unsigned long __percpu_xchg(void *ptr, unsigned long val, | |||
204 | return ret; | 204 | return ret; |
205 | } | 205 | } |
206 | 206 | ||
207 | #define _percpu_read(pcp) \ | ||
208 | ({ \ | ||
209 | typeof(pcp) __retval; \ | ||
210 | preempt_disable(); \ | ||
211 | __retval = (typeof(pcp))__percpu_read(raw_cpu_ptr(&(pcp)), \ | ||
212 | sizeof(pcp)); \ | ||
213 | preempt_enable(); \ | ||
214 | __retval; \ | ||
215 | }) | ||
216 | |||
217 | #define _percpu_write(pcp, val) \ | ||
218 | do { \ | ||
219 | preempt_disable(); \ | ||
220 | __percpu_write(raw_cpu_ptr(&(pcp)), (unsigned long)(val), \ | ||
221 | sizeof(pcp)); \ | ||
222 | preempt_enable(); \ | ||
223 | } while(0) \ | ||
224 | |||
225 | #define _pcp_protect(operation, pcp, val) \ | ||
226 | ({ \ | ||
227 | typeof(pcp) __retval; \ | ||
228 | preempt_disable(); \ | ||
229 | __retval = (typeof(pcp))operation(raw_cpu_ptr(&(pcp)), \ | ||
230 | (val), sizeof(pcp)); \ | ||
231 | preempt_enable(); \ | ||
232 | __retval; \ | ||
233 | }) | ||
234 | |||
207 | #define _percpu_add(pcp, val) \ | 235 | #define _percpu_add(pcp, val) \ |
208 | __percpu_add(raw_cpu_ptr(&(pcp)), val, sizeof(pcp)) | 236 | _pcp_protect(__percpu_add, pcp, val) |
209 | 237 | ||
210 | #define _percpu_add_return(pcp, val) (typeof(pcp)) (_percpu_add(pcp, val)) | 238 | #define _percpu_add_return(pcp, val) _percpu_add(pcp, val) |
211 | 239 | ||
212 | #define _percpu_and(pcp, val) \ | 240 | #define _percpu_and(pcp, val) \ |
213 | __percpu_and(raw_cpu_ptr(&(pcp)), val, sizeof(pcp)) | 241 | _pcp_protect(__percpu_and, pcp, val) |
214 | 242 | ||
215 | #define _percpu_or(pcp, val) \ | 243 | #define _percpu_or(pcp, val) \ |
216 | __percpu_or(raw_cpu_ptr(&(pcp)), val, sizeof(pcp)) | 244 | _pcp_protect(__percpu_or, pcp, val) |
217 | |||
218 | #define _percpu_read(pcp) (typeof(pcp)) \ | ||
219 | (__percpu_read(raw_cpu_ptr(&(pcp)), sizeof(pcp))) | ||
220 | |||
221 | #define _percpu_write(pcp, val) \ | ||
222 | __percpu_write(raw_cpu_ptr(&(pcp)), (unsigned long)(val), sizeof(pcp)) | ||
223 | 245 | ||
224 | #define _percpu_xchg(pcp, val) (typeof(pcp)) \ | 246 | #define _percpu_xchg(pcp, val) (typeof(pcp)) \ |
225 | (__percpu_xchg(raw_cpu_ptr(&(pcp)), (unsigned long)(val), sizeof(pcp))) | 247 | _pcp_protect(__percpu_xchg, pcp, (unsigned long)(val)) |
226 | 248 | ||
227 | #define this_cpu_add_1(pcp, val) _percpu_add(pcp, val) | 249 | #define this_cpu_add_1(pcp, val) _percpu_add(pcp, val) |
228 | #define this_cpu_add_2(pcp, val) _percpu_add(pcp, val) | 250 | #define this_cpu_add_2(pcp, val) _percpu_add(pcp, val) |
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 16449c535e50..800ec0e87ed9 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
@@ -460,7 +460,7 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr) | |||
460 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 460 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
461 | { | 461 | { |
462 | const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | | 462 | const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | |
463 | PTE_PROT_NONE | PTE_VALID | PTE_WRITE; | 463 | PTE_PROT_NONE | PTE_WRITE | PTE_TYPE_MASK; |
464 | pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); | 464 | pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); |
465 | return pte; | 465 | return pte; |
466 | } | 466 | } |
diff --git a/arch/arm64/include/asm/proc-fns.h b/arch/arm64/include/asm/proc-fns.h index 9a8fd84f8fb2..941c375616e2 100644 --- a/arch/arm64/include/asm/proc-fns.h +++ b/arch/arm64/include/asm/proc-fns.h | |||
@@ -39,7 +39,11 @@ extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr); | |||
39 | 39 | ||
40 | #include <asm/memory.h> | 40 | #include <asm/memory.h> |
41 | 41 | ||
42 | #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) | 42 | #define cpu_switch_mm(pgd,mm) \ |
43 | do { \ | ||
44 | BUG_ON(pgd == swapper_pg_dir); \ | ||
45 | cpu_do_switch_mm(virt_to_phys(pgd),mm); \ | ||
46 | } while (0) | ||
43 | 47 | ||
44 | #define cpu_get_pgd() \ | 48 | #define cpu_get_pgd() \ |
45 | ({ \ | 49 | ({ \ |
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index f9be30ea1cbd..20e9591a60cf 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h | |||
@@ -45,7 +45,8 @@ | |||
45 | #define STACK_TOP STACK_TOP_MAX | 45 | #define STACK_TOP STACK_TOP_MAX |
46 | #endif /* CONFIG_COMPAT */ | 46 | #endif /* CONFIG_COMPAT */ |
47 | 47 | ||
48 | #define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK | 48 | extern phys_addr_t arm64_dma_phys_limit; |
49 | #define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1) | ||
49 | #endif /* __KERNEL__ */ | 50 | #endif /* __KERNEL__ */ |
50 | 51 | ||
51 | struct debug_info { | 52 | struct debug_info { |
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h index c028fe37456f..53d9c354219f 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h | |||
@@ -48,6 +48,7 @@ static inline void tlb_flush(struct mmu_gather *tlb) | |||
48 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | 48 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, |
49 | unsigned long addr) | 49 | unsigned long addr) |
50 | { | 50 | { |
51 | __flush_tlb_pgtable(tlb->mm, addr); | ||
51 | pgtable_page_dtor(pte); | 52 | pgtable_page_dtor(pte); |
52 | tlb_remove_entry(tlb, pte); | 53 | tlb_remove_entry(tlb, pte); |
53 | } | 54 | } |
@@ -56,6 +57,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | |||
56 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | 57 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, |
57 | unsigned long addr) | 58 | unsigned long addr) |
58 | { | 59 | { |
60 | __flush_tlb_pgtable(tlb->mm, addr); | ||
59 | tlb_remove_entry(tlb, virt_to_page(pmdp)); | 61 | tlb_remove_entry(tlb, virt_to_page(pmdp)); |
60 | } | 62 | } |
61 | #endif | 63 | #endif |
@@ -64,6 +66,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | |||
64 | static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp, | 66 | static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp, |
65 | unsigned long addr) | 67 | unsigned long addr) |
66 | { | 68 | { |
69 | __flush_tlb_pgtable(tlb->mm, addr); | ||
67 | tlb_remove_entry(tlb, virt_to_page(pudp)); | 70 | tlb_remove_entry(tlb, virt_to_page(pudp)); |
68 | } | 71 | } |
69 | #endif | 72 | #endif |
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h index 73f0ce570fb3..c3bb05b98616 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h | |||
@@ -24,11 +24,6 @@ | |||
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | #include <asm/cputype.h> | 25 | #include <asm/cputype.h> |
26 | 26 | ||
27 | extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *); | ||
28 | extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long); | ||
29 | |||
30 | extern struct cpu_tlb_fns cpu_tlb; | ||
31 | |||
32 | /* | 27 | /* |
33 | * TLB Management | 28 | * TLB Management |
34 | * ============== | 29 | * ============== |
@@ -149,6 +144,19 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end | |||
149 | } | 144 | } |
150 | 145 | ||
151 | /* | 146 | /* |
147 | * Used to invalidate the TLB (walk caches) corresponding to intermediate page | ||
148 | * table levels (pgd/pud/pmd). | ||
149 | */ | ||
150 | static inline void __flush_tlb_pgtable(struct mm_struct *mm, | ||
151 | unsigned long uaddr) | ||
152 | { | ||
153 | unsigned long addr = uaddr >> 12 | ((unsigned long)ASID(mm) << 48); | ||
154 | |||
155 | dsb(ishst); | ||
156 | asm("tlbi vae1is, %0" : : "r" (addr)); | ||
157 | dsb(ish); | ||
158 | } | ||
159 | /* | ||
152 | * On AArch64, the cache coherency is handled via the set_pte_at() function. | 160 | * On AArch64, the cache coherency is handled via the set_pte_at() function. |
153 | */ | 161 | */ |
154 | static inline void update_mmu_cache(struct vm_area_struct *vma, | 162 | static inline void update_mmu_cache(struct vm_area_struct *vma, |
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 3ef77a466018..c154c0b7eb60 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h | |||
@@ -191,6 +191,9 @@ struct kvm_arch_memory_slot { | |||
191 | /* Highest supported SPI, from VGIC_NR_IRQS */ | 191 | /* Highest supported SPI, from VGIC_NR_IRQS */ |
192 | #define KVM_ARM_IRQ_GIC_MAX 127 | 192 | #define KVM_ARM_IRQ_GIC_MAX 127 |
193 | 193 | ||
194 | /* One single KVM irqchip, ie. the VGIC */ | ||
195 | #define KVM_NR_IRQCHIPS 1 | ||
196 | |||
194 | /* PSCI interface */ | 197 | /* PSCI interface */ |
195 | #define KVM_PSCI_FN_BASE 0x95c1ba5e | 198 | #define KVM_PSCI_FN_BASE 0x95c1ba5e |
196 | #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) | 199 | #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) |
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index bef04afd6031..5ee07eee80c2 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
@@ -15,8 +15,9 @@ CFLAGS_REMOVE_return_address.o = -pg | |||
15 | arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ | 15 | arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ |
16 | entry-fpsimd.o process.o ptrace.o setup.o signal.o \ | 16 | entry-fpsimd.o process.o ptrace.o setup.o signal.o \ |
17 | sys.o stacktrace.o time.o traps.o io.o vdso.o \ | 17 | sys.o stacktrace.o time.o traps.o io.o vdso.o \ |
18 | hyp-stub.o psci.o cpu_ops.o insn.o return_address.o \ | 18 | hyp-stub.o psci.o psci-call.o cpu_ops.o insn.o \ |
19 | cpuinfo.o cpu_errata.o alternative.o cacheinfo.o | 19 | return_address.o cpuinfo.o cpu_errata.o \ |
20 | alternative.o cacheinfo.o | ||
20 | 21 | ||
21 | arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ | 22 | arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ |
22 | sys_compat.o entry32.o \ | 23 | sys_compat.o entry32.o \ |
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index b42c7b480e1e..ab21e0d58278 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c | |||
@@ -337,7 +337,11 @@ core_initcall(arm64_dmi_init); | |||
337 | 337 | ||
338 | static void efi_set_pgd(struct mm_struct *mm) | 338 | static void efi_set_pgd(struct mm_struct *mm) |
339 | { | 339 | { |
340 | cpu_switch_mm(mm->pgd, mm); | 340 | if (mm == &init_mm) |
341 | cpu_set_reserved_ttbr0(); | ||
342 | else | ||
343 | cpu_switch_mm(mm->pgd, mm); | ||
344 | |||
341 | flush_tlb_all(); | 345 | flush_tlb_all(); |
342 | if (icache_is_aivivt()) | 346 | if (icache_is_aivivt()) |
343 | __flush_icache_all(); | 347 | __flush_icache_all(); |
@@ -354,3 +358,12 @@ void efi_virtmap_unload(void) | |||
354 | efi_set_pgd(current->active_mm); | 358 | efi_set_pgd(current->active_mm); |
355 | preempt_enable(); | 359 | preempt_enable(); |
356 | } | 360 | } |
361 | |||
362 | /* | ||
363 | * UpdateCapsule() depends on the system being shutdown via | ||
364 | * ResetSystem(). | ||
365 | */ | ||
366 | bool efi_poweroff_required(void) | ||
367 | { | ||
368 | return efi_enabled(EFI_RUNTIME_SERVICES); | ||
369 | } | ||
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c index cf8556ae09d0..c851be795080 100644 --- a/arch/arm64/kernel/ftrace.c +++ b/arch/arm64/kernel/ftrace.c | |||
@@ -156,7 +156,7 @@ static int ftrace_modify_graph_caller(bool enable) | |||
156 | 156 | ||
157 | branch = aarch64_insn_gen_branch_imm(pc, | 157 | branch = aarch64_insn_gen_branch_imm(pc, |
158 | (unsigned long)ftrace_graph_caller, | 158 | (unsigned long)ftrace_graph_caller, |
159 | AARCH64_INSN_BRANCH_LINK); | 159 | AARCH64_INSN_BRANCH_NOLINK); |
160 | nop = aarch64_insn_gen_nop(); | 160 | nop = aarch64_insn_gen_nop(); |
161 | 161 | ||
162 | if (enable) | 162 | if (enable) |
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 8ce88e08c030..07f930540f4a 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -585,8 +585,8 @@ ENDPROC(set_cpu_boot_mode_flag) | |||
585 | * zeroing of .bss would clobber it. | 585 | * zeroing of .bss would clobber it. |
586 | */ | 586 | */ |
587 | .pushsection .data..cacheline_aligned | 587 | .pushsection .data..cacheline_aligned |
588 | ENTRY(__boot_cpu_mode) | ||
589 | .align L1_CACHE_SHIFT | 588 | .align L1_CACHE_SHIFT |
589 | ENTRY(__boot_cpu_mode) | ||
590 | .long BOOT_CPU_MODE_EL2 | 590 | .long BOOT_CPU_MODE_EL2 |
591 | .long 0 | 591 | .long 0 |
592 | .popsection | 592 | .popsection |
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index 27d4864577e5..c8eca88f12e6 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c | |||
@@ -87,8 +87,10 @@ static void __kprobes *patch_map(void *addr, int fixmap) | |||
87 | 87 | ||
88 | if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX)) | 88 | if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX)) |
89 | page = vmalloc_to_page(addr); | 89 | page = vmalloc_to_page(addr); |
90 | else | 90 | else if (!module && IS_ENABLED(CONFIG_DEBUG_RODATA)) |
91 | page = virt_to_page(addr); | 91 | page = virt_to_page(addr); |
92 | else | ||
93 | return addr; | ||
92 | 94 | ||
93 | BUG_ON(!page); | 95 | BUG_ON(!page); |
94 | set_fixmap(fixmap, page_to_phys(page)); | 96 | set_fixmap(fixmap, page_to_phys(page)); |
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index fde9923af859..c6b1f3b96f45 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <stdarg.h> | 21 | #include <stdarg.h> |
22 | 22 | ||
23 | #include <linux/compat.h> | 23 | #include <linux/compat.h> |
24 | #include <linux/efi.h> | ||
24 | #include <linux/export.h> | 25 | #include <linux/export.h> |
25 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
@@ -150,6 +151,13 @@ void machine_restart(char *cmd) | |||
150 | local_irq_disable(); | 151 | local_irq_disable(); |
151 | smp_send_stop(); | 152 | smp_send_stop(); |
152 | 153 | ||
154 | /* | ||
155 | * UpdateCapsule() depends on the system being reset via | ||
156 | * ResetSystem(). | ||
157 | */ | ||
158 | if (efi_enabled(EFI_RUNTIME_SERVICES)) | ||
159 | efi_reboot(reboot_mode, NULL); | ||
160 | |||
153 | /* Now call the architecture specific reboot code. */ | 161 | /* Now call the architecture specific reboot code. */ |
154 | if (arm_pm_restart) | 162 | if (arm_pm_restart) |
155 | arm_pm_restart(reboot_mode, cmd); | 163 | arm_pm_restart(reboot_mode, cmd); |
diff --git a/arch/arm64/kernel/psci-call.S b/arch/arm64/kernel/psci-call.S new file mode 100644 index 000000000000..cf83e61cd3b5 --- /dev/null +++ b/arch/arm64/kernel/psci-call.S | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * Copyright (C) 2015 ARM Limited | ||
12 | * | ||
13 | * Author: Will Deacon <will.deacon@arm.com> | ||
14 | */ | ||
15 | |||
16 | #include <linux/linkage.h> | ||
17 | |||
18 | /* int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */ | ||
19 | ENTRY(__invoke_psci_fn_hvc) | ||
20 | hvc #0 | ||
21 | ret | ||
22 | ENDPROC(__invoke_psci_fn_hvc) | ||
23 | |||
24 | /* int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */ | ||
25 | ENTRY(__invoke_psci_fn_smc) | ||
26 | smc #0 | ||
27 | ret | ||
28 | ENDPROC(__invoke_psci_fn_smc) | ||
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index 3425f311c49e..9b8a70ae64a1 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c | |||
@@ -57,6 +57,9 @@ static struct psci_operations psci_ops; | |||
57 | static int (*invoke_psci_fn)(u64, u64, u64, u64); | 57 | static int (*invoke_psci_fn)(u64, u64, u64, u64); |
58 | typedef int (*psci_initcall_t)(const struct device_node *); | 58 | typedef int (*psci_initcall_t)(const struct device_node *); |
59 | 59 | ||
60 | asmlinkage int __invoke_psci_fn_hvc(u64, u64, u64, u64); | ||
61 | asmlinkage int __invoke_psci_fn_smc(u64, u64, u64, u64); | ||
62 | |||
60 | enum psci_function { | 63 | enum psci_function { |
61 | PSCI_FN_CPU_SUSPEND, | 64 | PSCI_FN_CPU_SUSPEND, |
62 | PSCI_FN_CPU_ON, | 65 | PSCI_FN_CPU_ON, |
@@ -109,40 +112,6 @@ static void psci_power_state_unpack(u32 power_state, | |||
109 | PSCI_0_2_POWER_STATE_AFFL_SHIFT; | 112 | PSCI_0_2_POWER_STATE_AFFL_SHIFT; |
110 | } | 113 | } |
111 | 114 | ||
112 | /* | ||
113 | * The following two functions are invoked via the invoke_psci_fn pointer | ||
114 | * and will not be inlined, allowing us to piggyback on the AAPCS. | ||
115 | */ | ||
116 | static noinline int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, | ||
117 | u64 arg2) | ||
118 | { | ||
119 | asm volatile( | ||
120 | __asmeq("%0", "x0") | ||
121 | __asmeq("%1", "x1") | ||
122 | __asmeq("%2", "x2") | ||
123 | __asmeq("%3", "x3") | ||
124 | "hvc #0\n" | ||
125 | : "+r" (function_id) | ||
126 | : "r" (arg0), "r" (arg1), "r" (arg2)); | ||
127 | |||
128 | return function_id; | ||
129 | } | ||
130 | |||
131 | static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, | ||
132 | u64 arg2) | ||
133 | { | ||
134 | asm volatile( | ||
135 | __asmeq("%0", "x0") | ||
136 | __asmeq("%1", "x1") | ||
137 | __asmeq("%2", "x2") | ||
138 | __asmeq("%3", "x3") | ||
139 | "smc #0\n" | ||
140 | : "+r" (function_id) | ||
141 | : "r" (arg0), "r" (arg1), "r" (arg2)); | ||
142 | |||
143 | return function_id; | ||
144 | } | ||
145 | |||
146 | static int psci_get_version(void) | 115 | static int psci_get_version(void) |
147 | { | 116 | { |
148 | int err; | 117 | int err; |
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index c20a300e2213..d26fcd4cd6e6 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c | |||
@@ -154,8 +154,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) | |||
154 | case __SI_TIMER: | 154 | case __SI_TIMER: |
155 | err |= __put_user(from->si_tid, &to->si_tid); | 155 | err |= __put_user(from->si_tid, &to->si_tid); |
156 | err |= __put_user(from->si_overrun, &to->si_overrun); | 156 | err |= __put_user(from->si_overrun, &to->si_overrun); |
157 | err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, | 157 | err |= __put_user(from->si_int, &to->si_int); |
158 | &to->si_ptr); | ||
159 | break; | 158 | break; |
160 | case __SI_POLL: | 159 | case __SI_POLL: |
161 | err |= __put_user(from->si_band, &to->si_band); | 160 | err |= __put_user(from->si_band, &to->si_band); |
@@ -184,7 +183,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) | |||
184 | case __SI_MESGQ: /* But this is */ | 183 | case __SI_MESGQ: /* But this is */ |
185 | err |= __put_user(from->si_pid, &to->si_pid); | 184 | err |= __put_user(from->si_pid, &to->si_pid); |
186 | err |= __put_user(from->si_uid, &to->si_uid); | 185 | err |= __put_user(from->si_uid, &to->si_uid); |
187 | err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, &to->si_ptr); | 186 | err |= __put_user(from->si_int, &to->si_int); |
188 | break; | 187 | break; |
189 | case __SI_SYS: | 188 | case __SI_SYS: |
190 | err |= __put_user((compat_uptr_t)(unsigned long) | 189 | err |= __put_user((compat_uptr_t)(unsigned long) |
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S index fe652ffd34c2..efa79e8d4196 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S | |||
@@ -174,8 +174,6 @@ ENDPROC(__kernel_clock_gettime) | |||
174 | /* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */ | 174 | /* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */ |
175 | ENTRY(__kernel_clock_getres) | 175 | ENTRY(__kernel_clock_getres) |
176 | .cfi_startproc | 176 | .cfi_startproc |
177 | cbz w1, 3f | ||
178 | |||
179 | cmp w0, #CLOCK_REALTIME | 177 | cmp w0, #CLOCK_REALTIME |
180 | ccmp w0, #CLOCK_MONOTONIC, #0x4, ne | 178 | ccmp w0, #CLOCK_MONOTONIC, #0x4, ne |
181 | b.ne 1f | 179 | b.ne 1f |
@@ -188,6 +186,7 @@ ENTRY(__kernel_clock_getres) | |||
188 | b.ne 4f | 186 | b.ne 4f |
189 | ldr x2, 6f | 187 | ldr x2, 6f |
190 | 2: | 188 | 2: |
189 | cbz w1, 3f | ||
191 | stp xzr, x2, [x1] | 190 | stp xzr, x2, [x1] |
192 | 191 | ||
193 | 3: /* res == NULL. */ | 192 | 3: /* res == NULL. */ |
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index f5590c81d95f..5105e297ed5f 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig | |||
@@ -18,6 +18,7 @@ if VIRTUALIZATION | |||
18 | 18 | ||
19 | config KVM | 19 | config KVM |
20 | bool "Kernel-based Virtual Machine (KVM) support" | 20 | bool "Kernel-based Virtual Machine (KVM) support" |
21 | depends on OF | ||
21 | select MMU_NOTIFIER | 22 | select MMU_NOTIFIER |
22 | select PREEMPT_NOTIFIERS | 23 | select PREEMPT_NOTIFIERS |
23 | select ANON_INODES | 24 | select ANON_INODES |
@@ -25,10 +26,10 @@ config KVM | |||
25 | select HAVE_KVM_ARCH_TLB_FLUSH_ALL | 26 | select HAVE_KVM_ARCH_TLB_FLUSH_ALL |
26 | select KVM_MMIO | 27 | select KVM_MMIO |
27 | select KVM_ARM_HOST | 28 | select KVM_ARM_HOST |
28 | select KVM_ARM_VGIC | ||
29 | select KVM_ARM_TIMER | ||
30 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT | 29 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT |
31 | select SRCU | 30 | select SRCU |
31 | select HAVE_KVM_EVENTFD | ||
32 | select HAVE_KVM_IRQFD | ||
32 | ---help--- | 33 | ---help--- |
33 | Support hosting virtualized guest machines. | 34 | Support hosting virtualized guest machines. |
34 | 35 | ||
@@ -50,17 +51,4 @@ config KVM_ARM_MAX_VCPUS | |||
50 | large, so only choose a reasonable number that you expect to | 51 | large, so only choose a reasonable number that you expect to |
51 | actually use. | 52 | actually use. |
52 | 53 | ||
53 | config KVM_ARM_VGIC | ||
54 | bool | ||
55 | depends on KVM_ARM_HOST && OF | ||
56 | select HAVE_KVM_IRQCHIP | ||
57 | ---help--- | ||
58 | Adds support for a hardware assisted, in-kernel GIC emulation. | ||
59 | |||
60 | config KVM_ARM_TIMER | ||
61 | bool | ||
62 | depends on KVM_ARM_VGIC | ||
63 | ---help--- | ||
64 | Adds support for the Architected Timers in virtual machines. | ||
65 | |||
66 | endif # VIRTUALIZATION | 54 | endif # VIRTUALIZATION |
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 4e6e09ee4033..d5904f876cdb 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for Kernel-based Virtual Machine module | 2 | # Makefile for Kernel-based Virtual Machine module |
3 | # | 3 | # |
4 | 4 | ||
5 | ccflags-y += -Ivirt/kvm -Iarch/arm64/kvm | 5 | ccflags-y += -Iarch/arm64/kvm |
6 | CFLAGS_arm.o := -I. | 6 | CFLAGS_arm.o := -I. |
7 | CFLAGS_mmu.o := -I. | 7 | CFLAGS_mmu.o := -I. |
8 | 8 | ||
@@ -11,7 +11,7 @@ ARM=../../../arch/arm/kvm | |||
11 | 11 | ||
12 | obj-$(CONFIG_KVM_ARM_HOST) += kvm.o | 12 | obj-$(CONFIG_KVM_ARM_HOST) += kvm.o |
13 | 13 | ||
14 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o | 14 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o |
15 | kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o | 15 | kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o |
16 | kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o | 16 | kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o |
17 | 17 | ||
@@ -19,11 +19,11 @@ kvm-$(CONFIG_KVM_ARM_HOST) += emulate.o inject_fault.o regmap.o | |||
19 | kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o | 19 | kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o |
20 | kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o | 20 | kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o |
21 | 21 | ||
22 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o | 22 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic.o |
23 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o | 23 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v2.o |
24 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2-emul.o | 24 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v2-emul.o |
25 | kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v2-switch.o | 25 | kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v2-switch.o |
26 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v3.o | 26 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o |
27 | kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v3-emul.o | 27 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o |
28 | kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v3-switch.o | 28 | kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o |
29 | kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o | 29 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o |
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 0a24b9b8c698..ef7d112f5ce0 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c | |||
@@ -51,7 +51,7 @@ static int __init early_coherent_pool(char *p) | |||
51 | } | 51 | } |
52 | early_param("coherent_pool", early_coherent_pool); | 52 | early_param("coherent_pool", early_coherent_pool); |
53 | 53 | ||
54 | static void *__alloc_from_pool(size_t size, struct page **ret_page) | 54 | static void *__alloc_from_pool(size_t size, struct page **ret_page, gfp_t flags) |
55 | { | 55 | { |
56 | unsigned long val; | 56 | unsigned long val; |
57 | void *ptr = NULL; | 57 | void *ptr = NULL; |
@@ -67,6 +67,8 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) | |||
67 | 67 | ||
68 | *ret_page = phys_to_page(phys); | 68 | *ret_page = phys_to_page(phys); |
69 | ptr = (void *)val; | 69 | ptr = (void *)val; |
70 | if (flags & __GFP_ZERO) | ||
71 | memset(ptr, 0, size); | ||
70 | } | 72 | } |
71 | 73 | ||
72 | return ptr; | 74 | return ptr; |
@@ -101,6 +103,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size, | |||
101 | flags |= GFP_DMA; | 103 | flags |= GFP_DMA; |
102 | if (IS_ENABLED(CONFIG_DMA_CMA) && (flags & __GFP_WAIT)) { | 104 | if (IS_ENABLED(CONFIG_DMA_CMA) && (flags & __GFP_WAIT)) { |
103 | struct page *page; | 105 | struct page *page; |
106 | void *addr; | ||
104 | 107 | ||
105 | size = PAGE_ALIGN(size); | 108 | size = PAGE_ALIGN(size); |
106 | page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT, | 109 | page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT, |
@@ -109,7 +112,10 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size, | |||
109 | return NULL; | 112 | return NULL; |
110 | 113 | ||
111 | *dma_handle = phys_to_dma(dev, page_to_phys(page)); | 114 | *dma_handle = phys_to_dma(dev, page_to_phys(page)); |
112 | return page_address(page); | 115 | addr = page_address(page); |
116 | if (flags & __GFP_ZERO) | ||
117 | memset(addr, 0, size); | ||
118 | return addr; | ||
113 | } else { | 119 | } else { |
114 | return swiotlb_alloc_coherent(dev, size, dma_handle, flags); | 120 | return swiotlb_alloc_coherent(dev, size, dma_handle, flags); |
115 | } | 121 | } |
@@ -146,7 +152,7 @@ static void *__dma_alloc(struct device *dev, size_t size, | |||
146 | 152 | ||
147 | if (!coherent && !(flags & __GFP_WAIT)) { | 153 | if (!coherent && !(flags & __GFP_WAIT)) { |
148 | struct page *page = NULL; | 154 | struct page *page = NULL; |
149 | void *addr = __alloc_from_pool(size, &page); | 155 | void *addr = __alloc_from_pool(size, &page, flags); |
150 | 156 | ||
151 | if (addr) | 157 | if (addr) |
152 | *dma_handle = phys_to_dma(dev, page_to_phys(page)); | 158 | *dma_handle = phys_to_dma(dev, page_to_phys(page)); |
@@ -348,8 +354,6 @@ static struct dma_map_ops swiotlb_dma_ops = { | |||
348 | .mapping_error = swiotlb_dma_mapping_error, | 354 | .mapping_error = swiotlb_dma_mapping_error, |
349 | }; | 355 | }; |
350 | 356 | ||
351 | extern int swiotlb_late_init_with_default_size(size_t default_size); | ||
352 | |||
353 | static int __init atomic_pool_init(void) | 357 | static int __init atomic_pool_init(void) |
354 | { | 358 | { |
355 | pgprot_t prot = __pgprot(PROT_NORMAL_NC); | 359 | pgprot_t prot = __pgprot(PROT_NORMAL_NC); |
@@ -411,21 +415,13 @@ out: | |||
411 | return -ENOMEM; | 415 | return -ENOMEM; |
412 | } | 416 | } |
413 | 417 | ||
414 | static int __init swiotlb_late_init(void) | 418 | static int __init arm64_dma_init(void) |
415 | { | 419 | { |
416 | size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT); | 420 | int ret; |
417 | 421 | ||
418 | dma_ops = &swiotlb_dma_ops; | 422 | dma_ops = &swiotlb_dma_ops; |
419 | 423 | ||
420 | return swiotlb_late_init_with_default_size(swiotlb_size); | 424 | ret = atomic_pool_init(); |
421 | } | ||
422 | |||
423 | static int __init arm64_dma_init(void) | ||
424 | { | ||
425 | int ret = 0; | ||
426 | |||
427 | ret |= swiotlb_late_init(); | ||
428 | ret |= atomic_pool_init(); | ||
429 | 425 | ||
430 | return ret; | 426 | return ret; |
431 | } | 427 | } |
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 71145f952070..ae85da6307bb 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
34 | #include <linux/dma-contiguous.h> | 34 | #include <linux/dma-contiguous.h> |
35 | #include <linux/efi.h> | 35 | #include <linux/efi.h> |
36 | #include <linux/swiotlb.h> | ||
36 | 37 | ||
37 | #include <asm/fixmap.h> | 38 | #include <asm/fixmap.h> |
38 | #include <asm/memory.h> | 39 | #include <asm/memory.h> |
@@ -45,6 +46,7 @@ | |||
45 | #include "mm.h" | 46 | #include "mm.h" |
46 | 47 | ||
47 | phys_addr_t memstart_addr __read_mostly = 0; | 48 | phys_addr_t memstart_addr __read_mostly = 0; |
49 | phys_addr_t arm64_dma_phys_limit __read_mostly; | ||
48 | 50 | ||
49 | #ifdef CONFIG_BLK_DEV_INITRD | 51 | #ifdef CONFIG_BLK_DEV_INITRD |
50 | static int __init early_initrd(char *p) | 52 | static int __init early_initrd(char *p) |
@@ -85,7 +87,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) | |||
85 | 87 | ||
86 | /* 4GB maximum for 32-bit only capable devices */ | 88 | /* 4GB maximum for 32-bit only capable devices */ |
87 | if (IS_ENABLED(CONFIG_ZONE_DMA)) { | 89 | if (IS_ENABLED(CONFIG_ZONE_DMA)) { |
88 | max_dma = PFN_DOWN(max_zone_dma_phys()); | 90 | max_dma = PFN_DOWN(arm64_dma_phys_limit); |
89 | zone_size[ZONE_DMA] = max_dma - min; | 91 | zone_size[ZONE_DMA] = max_dma - min; |
90 | } | 92 | } |
91 | zone_size[ZONE_NORMAL] = max - max_dma; | 93 | zone_size[ZONE_NORMAL] = max - max_dma; |
@@ -156,8 +158,6 @@ early_param("mem", early_mem); | |||
156 | 158 | ||
157 | void __init arm64_memblock_init(void) | 159 | void __init arm64_memblock_init(void) |
158 | { | 160 | { |
159 | phys_addr_t dma_phys_limit = 0; | ||
160 | |||
161 | memblock_enforce_memory_limit(memory_limit); | 161 | memblock_enforce_memory_limit(memory_limit); |
162 | 162 | ||
163 | /* | 163 | /* |
@@ -174,8 +174,10 @@ void __init arm64_memblock_init(void) | |||
174 | 174 | ||
175 | /* 4GB maximum for 32-bit only capable devices */ | 175 | /* 4GB maximum for 32-bit only capable devices */ |
176 | if (IS_ENABLED(CONFIG_ZONE_DMA)) | 176 | if (IS_ENABLED(CONFIG_ZONE_DMA)) |
177 | dma_phys_limit = max_zone_dma_phys(); | 177 | arm64_dma_phys_limit = max_zone_dma_phys(); |
178 | dma_contiguous_reserve(dma_phys_limit); | 178 | else |
179 | arm64_dma_phys_limit = PHYS_MASK + 1; | ||
180 | dma_contiguous_reserve(arm64_dma_phys_limit); | ||
179 | 181 | ||
180 | memblock_allow_resize(); | 182 | memblock_allow_resize(); |
181 | memblock_dump_all(); | 183 | memblock_dump_all(); |
@@ -276,6 +278,8 @@ static void __init free_unused_memmap(void) | |||
276 | */ | 278 | */ |
277 | void __init mem_init(void) | 279 | void __init mem_init(void) |
278 | { | 280 | { |
281 | swiotlb_init(1); | ||
282 | |||
279 | set_max_mapnr(pfn_to_page(max_pfn) - mem_map); | 283 | set_max_mapnr(pfn_to_page(max_pfn) - mem_map); |
280 | 284 | ||
281 | #ifndef CONFIG_SPARSEMEM_VMEMMAP | 285 | #ifndef CONFIG_SPARSEMEM_VMEMMAP |
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index bb0ea94c4ba1..1d3ec3ddd84b 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c | |||
@@ -51,7 +51,10 @@ static int change_memory_common(unsigned long addr, int numpages, | |||
51 | WARN_ON_ONCE(1); | 51 | WARN_ON_ONCE(1); |
52 | } | 52 | } |
53 | 53 | ||
54 | if (!is_module_address(start) || !is_module_address(end - 1)) | 54 | if (start < MODULES_VADDR || start >= MODULES_END) |
55 | return -EINVAL; | ||
56 | |||
57 | if (end < MODULES_VADDR || end >= MODULES_END) | ||
55 | return -EINVAL; | 58 | return -EINVAL; |
56 | 59 | ||
57 | data.set_mask = set_mask; | 60 | data.set_mask = set_mask; |
diff --git a/arch/c6x/include/asm/pgtable.h b/arch/c6x/include/asm/pgtable.h index 78d4483ba40c..ec4db6df5e0d 100644 --- a/arch/c6x/include/asm/pgtable.h +++ b/arch/c6x/include/asm/pgtable.h | |||
@@ -67,6 +67,11 @@ extern unsigned long empty_zero_page; | |||
67 | */ | 67 | */ |
68 | #define pgtable_cache_init() do { } while (0) | 68 | #define pgtable_cache_init() do { } while (0) |
69 | 69 | ||
70 | /* | ||
71 | * c6x is !MMU, so define the simpliest implementation | ||
72 | */ | ||
73 | #define pgprot_writecombine pgprot_noncached | ||
74 | |||
70 | #include <asm-generic/pgtable.h> | 75 | #include <asm-generic/pgtable.h> |
71 | 76 | ||
72 | #endif /* _ASM_C6X_PGTABLE_H */ | 77 | #endif /* _ASM_C6X_PGTABLE_H */ |
diff --git a/arch/frv/include/asm/pgtable.h b/arch/frv/include/asm/pgtable.h index 93bcf2abd1a1..07d7a7ef8bd5 100644 --- a/arch/frv/include/asm/pgtable.h +++ b/arch/frv/include/asm/pgtable.h | |||
@@ -123,12 +123,14 @@ extern unsigned long empty_zero_page; | |||
123 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) | 123 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) |
124 | #define PTRS_PER_PGD 64 | 124 | #define PTRS_PER_PGD 64 |
125 | 125 | ||
126 | #define __PAGETABLE_PUD_FOLDED | ||
126 | #define PUD_SHIFT 26 | 127 | #define PUD_SHIFT 26 |
127 | #define PTRS_PER_PUD 1 | 128 | #define PTRS_PER_PUD 1 |
128 | #define PUD_SIZE (1UL << PUD_SHIFT) | 129 | #define PUD_SIZE (1UL << PUD_SHIFT) |
129 | #define PUD_MASK (~(PUD_SIZE - 1)) | 130 | #define PUD_MASK (~(PUD_SIZE - 1)) |
130 | #define PUE_SIZE 256 | 131 | #define PUE_SIZE 256 |
131 | 132 | ||
133 | #define __PAGETABLE_PMD_FOLDED | ||
132 | #define PMD_SHIFT 26 | 134 | #define PMD_SHIFT 26 |
133 | #define PMD_SIZE (1UL << PMD_SHIFT) | 135 | #define PMD_SIZE (1UL << PMD_SHIFT) |
134 | #define PMD_MASK (~(PMD_SIZE - 1)) | 136 | #define PMD_MASK (~(PMD_SIZE - 1)) |
diff --git a/arch/m32r/include/asm/pgtable-2level.h b/arch/m32r/include/asm/pgtable-2level.h index 8fd8ee70266a..421e6ba3a173 100644 --- a/arch/m32r/include/asm/pgtable-2level.h +++ b/arch/m32r/include/asm/pgtable-2level.h | |||
@@ -13,6 +13,7 @@ | |||
13 | * the M32R is two-level, so we don't really have any | 13 | * the M32R is two-level, so we don't really have any |
14 | * PMD directory physically. | 14 | * PMD directory physically. |
15 | */ | 15 | */ |
16 | #define __PAGETABLE_PMD_FOLDED | ||
16 | #define PMD_SHIFT 22 | 17 | #define PMD_SHIFT 22 |
17 | #define PTRS_PER_PMD 1 | 18 | #define PTRS_PER_PMD 1 |
18 | 19 | ||
diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h index 28a145bfbb71..35ed4a9981ae 100644 --- a/arch/m68k/include/asm/pgtable_mm.h +++ b/arch/m68k/include/asm/pgtable_mm.h | |||
@@ -54,10 +54,12 @@ | |||
54 | */ | 54 | */ |
55 | #ifdef CONFIG_SUN3 | 55 | #ifdef CONFIG_SUN3 |
56 | #define PTRS_PER_PTE 16 | 56 | #define PTRS_PER_PTE 16 |
57 | #define __PAGETABLE_PMD_FOLDED | ||
57 | #define PTRS_PER_PMD 1 | 58 | #define PTRS_PER_PMD 1 |
58 | #define PTRS_PER_PGD 2048 | 59 | #define PTRS_PER_PGD 2048 |
59 | #elif defined(CONFIG_COLDFIRE) | 60 | #elif defined(CONFIG_COLDFIRE) |
60 | #define PTRS_PER_PTE 512 | 61 | #define PTRS_PER_PTE 512 |
62 | #define __PAGETABLE_PMD_FOLDED | ||
61 | #define PTRS_PER_PMD 1 | 63 | #define PTRS_PER_PMD 1 |
62 | #define PTRS_PER_PGD 1024 | 64 | #define PTRS_PER_PGD 1024 |
63 | #else | 65 | #else |
diff --git a/arch/metag/include/asm/io.h b/arch/metag/include/asm/io.h index 9359e5048442..d5779b0ec573 100644 --- a/arch/metag/include/asm/io.h +++ b/arch/metag/include/asm/io.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ASM_METAG_IO_H | 2 | #define _ASM_METAG_IO_H |
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <asm/pgtable-bits.h> | ||
5 | 6 | ||
6 | #define IO_SPACE_LIMIT 0 | 7 | #define IO_SPACE_LIMIT 0 |
7 | 8 | ||
diff --git a/arch/metag/include/asm/pgtable-bits.h b/arch/metag/include/asm/pgtable-bits.h new file mode 100644 index 000000000000..25ba6729f496 --- /dev/null +++ b/arch/metag/include/asm/pgtable-bits.h | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * Meta page table definitions. | ||
3 | */ | ||
4 | |||
5 | #ifndef _METAG_PGTABLE_BITS_H | ||
6 | #define _METAG_PGTABLE_BITS_H | ||
7 | |||
8 | #include <asm/metag_mem.h> | ||
9 | |||
10 | /* | ||
11 | * Definitions for MMU descriptors | ||
12 | * | ||
13 | * These are the hardware bits in the MMCU pte entries. | ||
14 | * Derived from the Meta toolkit headers. | ||
15 | */ | ||
16 | #define _PAGE_PRESENT MMCU_ENTRY_VAL_BIT | ||
17 | #define _PAGE_WRITE MMCU_ENTRY_WR_BIT | ||
18 | #define _PAGE_PRIV MMCU_ENTRY_PRIV_BIT | ||
19 | /* Write combine bit - this can cause writes to occur out of order */ | ||
20 | #define _PAGE_WR_COMBINE MMCU_ENTRY_WRC_BIT | ||
21 | /* Sys coherent bit - this bit is never used by Linux */ | ||
22 | #define _PAGE_SYS_COHERENT MMCU_ENTRY_SYS_BIT | ||
23 | #define _PAGE_ALWAYS_ZERO_1 0x020 | ||
24 | #define _PAGE_CACHE_CTRL0 0x040 | ||
25 | #define _PAGE_CACHE_CTRL1 0x080 | ||
26 | #define _PAGE_ALWAYS_ZERO_2 0x100 | ||
27 | #define _PAGE_ALWAYS_ZERO_3 0x200 | ||
28 | #define _PAGE_ALWAYS_ZERO_4 0x400 | ||
29 | #define _PAGE_ALWAYS_ZERO_5 0x800 | ||
30 | |||
31 | /* These are software bits that we stuff into the gaps in the hardware | ||
32 | * pte entries that are not used. Note, these DO get stored in the actual | ||
33 | * hardware, but the hardware just does not use them. | ||
34 | */ | ||
35 | #define _PAGE_ACCESSED _PAGE_ALWAYS_ZERO_1 | ||
36 | #define _PAGE_DIRTY _PAGE_ALWAYS_ZERO_2 | ||
37 | |||
38 | /* Pages owned, and protected by, the kernel. */ | ||
39 | #define _PAGE_KERNEL _PAGE_PRIV | ||
40 | |||
41 | /* No cacheing of this page */ | ||
42 | #define _PAGE_CACHE_WIN0 (MMCU_CWIN_UNCACHED << MMCU_ENTRY_CWIN_S) | ||
43 | /* burst cacheing - good for data streaming */ | ||
44 | #define _PAGE_CACHE_WIN1 (MMCU_CWIN_BURST << MMCU_ENTRY_CWIN_S) | ||
45 | /* One cache way per thread */ | ||
46 | #define _PAGE_CACHE_WIN2 (MMCU_CWIN_C1SET << MMCU_ENTRY_CWIN_S) | ||
47 | /* Full on cacheing */ | ||
48 | #define _PAGE_CACHE_WIN3 (MMCU_CWIN_CACHED << MMCU_ENTRY_CWIN_S) | ||
49 | |||
50 | #define _PAGE_CACHEABLE (_PAGE_CACHE_WIN3 | _PAGE_WR_COMBINE) | ||
51 | |||
52 | /* which bits are used for cache control ... */ | ||
53 | #define _PAGE_CACHE_MASK (_PAGE_CACHE_CTRL0 | _PAGE_CACHE_CTRL1 | \ | ||
54 | _PAGE_WR_COMBINE) | ||
55 | |||
56 | /* This is a mask of the bits that pte_modify is allowed to change. */ | ||
57 | #define _PAGE_CHG_MASK (PAGE_MASK) | ||
58 | |||
59 | #define _PAGE_SZ_SHIFT 1 | ||
60 | #define _PAGE_SZ_4K (0x0) | ||
61 | #define _PAGE_SZ_8K (0x1 << _PAGE_SZ_SHIFT) | ||
62 | #define _PAGE_SZ_16K (0x2 << _PAGE_SZ_SHIFT) | ||
63 | #define _PAGE_SZ_32K (0x3 << _PAGE_SZ_SHIFT) | ||
64 | #define _PAGE_SZ_64K (0x4 << _PAGE_SZ_SHIFT) | ||
65 | #define _PAGE_SZ_128K (0x5 << _PAGE_SZ_SHIFT) | ||
66 | #define _PAGE_SZ_256K (0x6 << _PAGE_SZ_SHIFT) | ||
67 | #define _PAGE_SZ_512K (0x7 << _PAGE_SZ_SHIFT) | ||
68 | #define _PAGE_SZ_1M (0x8 << _PAGE_SZ_SHIFT) | ||
69 | #define _PAGE_SZ_2M (0x9 << _PAGE_SZ_SHIFT) | ||
70 | #define _PAGE_SZ_4M (0xa << _PAGE_SZ_SHIFT) | ||
71 | #define _PAGE_SZ_MASK (0xf << _PAGE_SZ_SHIFT) | ||
72 | |||
73 | #if defined(CONFIG_PAGE_SIZE_4K) | ||
74 | #define _PAGE_SZ (_PAGE_SZ_4K) | ||
75 | #elif defined(CONFIG_PAGE_SIZE_8K) | ||
76 | #define _PAGE_SZ (_PAGE_SZ_8K) | ||
77 | #elif defined(CONFIG_PAGE_SIZE_16K) | ||
78 | #define _PAGE_SZ (_PAGE_SZ_16K) | ||
79 | #endif | ||
80 | #define _PAGE_TABLE (_PAGE_SZ | _PAGE_PRESENT) | ||
81 | |||
82 | #if defined(CONFIG_HUGETLB_PAGE_SIZE_8K) | ||
83 | # define _PAGE_SZHUGE (_PAGE_SZ_8K) | ||
84 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_16K) | ||
85 | # define _PAGE_SZHUGE (_PAGE_SZ_16K) | ||
86 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_32K) | ||
87 | # define _PAGE_SZHUGE (_PAGE_SZ_32K) | ||
88 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K) | ||
89 | # define _PAGE_SZHUGE (_PAGE_SZ_64K) | ||
90 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_128K) | ||
91 | # define _PAGE_SZHUGE (_PAGE_SZ_128K) | ||
92 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) | ||
93 | # define _PAGE_SZHUGE (_PAGE_SZ_256K) | ||
94 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K) | ||
95 | # define _PAGE_SZHUGE (_PAGE_SZ_512K) | ||
96 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_1M) | ||
97 | # define _PAGE_SZHUGE (_PAGE_SZ_1M) | ||
98 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_2M) | ||
99 | # define _PAGE_SZHUGE (_PAGE_SZ_2M) | ||
100 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_4M) | ||
101 | # define _PAGE_SZHUGE (_PAGE_SZ_4M) | ||
102 | #endif | ||
103 | |||
104 | #endif /* _METAG_PGTABLE_BITS_H */ | ||
diff --git a/arch/metag/include/asm/pgtable.h b/arch/metag/include/asm/pgtable.h index d0604c0a8702..ffa3a3a2ecad 100644 --- a/arch/metag/include/asm/pgtable.h +++ b/arch/metag/include/asm/pgtable.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #ifndef _METAG_PGTABLE_H | 5 | #ifndef _METAG_PGTABLE_H |
6 | #define _METAG_PGTABLE_H | 6 | #define _METAG_PGTABLE_H |
7 | 7 | ||
8 | #include <asm/pgtable-bits.h> | ||
8 | #include <asm-generic/pgtable-nopmd.h> | 9 | #include <asm-generic/pgtable-nopmd.h> |
9 | 10 | ||
10 | /* Invalid regions on Meta: 0x00000000-0x001FFFFF and 0xFFFF0000-0xFFFFFFFF */ | 11 | /* Invalid regions on Meta: 0x00000000-0x001FFFFF and 0xFFFF0000-0xFFFFFFFF */ |
@@ -21,100 +22,6 @@ | |||
21 | #endif | 22 | #endif |
22 | 23 | ||
23 | /* | 24 | /* |
24 | * Definitions for MMU descriptors | ||
25 | * | ||
26 | * These are the hardware bits in the MMCU pte entries. | ||
27 | * Derived from the Meta toolkit headers. | ||
28 | */ | ||
29 | #define _PAGE_PRESENT MMCU_ENTRY_VAL_BIT | ||
30 | #define _PAGE_WRITE MMCU_ENTRY_WR_BIT | ||
31 | #define _PAGE_PRIV MMCU_ENTRY_PRIV_BIT | ||
32 | /* Write combine bit - this can cause writes to occur out of order */ | ||
33 | #define _PAGE_WR_COMBINE MMCU_ENTRY_WRC_BIT | ||
34 | /* Sys coherent bit - this bit is never used by Linux */ | ||
35 | #define _PAGE_SYS_COHERENT MMCU_ENTRY_SYS_BIT | ||
36 | #define _PAGE_ALWAYS_ZERO_1 0x020 | ||
37 | #define _PAGE_CACHE_CTRL0 0x040 | ||
38 | #define _PAGE_CACHE_CTRL1 0x080 | ||
39 | #define _PAGE_ALWAYS_ZERO_2 0x100 | ||
40 | #define _PAGE_ALWAYS_ZERO_3 0x200 | ||
41 | #define _PAGE_ALWAYS_ZERO_4 0x400 | ||
42 | #define _PAGE_ALWAYS_ZERO_5 0x800 | ||
43 | |||
44 | /* These are software bits that we stuff into the gaps in the hardware | ||
45 | * pte entries that are not used. Note, these DO get stored in the actual | ||
46 | * hardware, but the hardware just does not use them. | ||
47 | */ | ||
48 | #define _PAGE_ACCESSED _PAGE_ALWAYS_ZERO_1 | ||
49 | #define _PAGE_DIRTY _PAGE_ALWAYS_ZERO_2 | ||
50 | |||
51 | /* Pages owned, and protected by, the kernel. */ | ||
52 | #define _PAGE_KERNEL _PAGE_PRIV | ||
53 | |||
54 | /* No cacheing of this page */ | ||
55 | #define _PAGE_CACHE_WIN0 (MMCU_CWIN_UNCACHED << MMCU_ENTRY_CWIN_S) | ||
56 | /* burst cacheing - good for data streaming */ | ||
57 | #define _PAGE_CACHE_WIN1 (MMCU_CWIN_BURST << MMCU_ENTRY_CWIN_S) | ||
58 | /* One cache way per thread */ | ||
59 | #define _PAGE_CACHE_WIN2 (MMCU_CWIN_C1SET << MMCU_ENTRY_CWIN_S) | ||
60 | /* Full on cacheing */ | ||
61 | #define _PAGE_CACHE_WIN3 (MMCU_CWIN_CACHED << MMCU_ENTRY_CWIN_S) | ||
62 | |||
63 | #define _PAGE_CACHEABLE (_PAGE_CACHE_WIN3 | _PAGE_WR_COMBINE) | ||
64 | |||
65 | /* which bits are used for cache control ... */ | ||
66 | #define _PAGE_CACHE_MASK (_PAGE_CACHE_CTRL0 | _PAGE_CACHE_CTRL1 | \ | ||
67 | _PAGE_WR_COMBINE) | ||
68 | |||
69 | /* This is a mask of the bits that pte_modify is allowed to change. */ | ||
70 | #define _PAGE_CHG_MASK (PAGE_MASK) | ||
71 | |||
72 | #define _PAGE_SZ_SHIFT 1 | ||
73 | #define _PAGE_SZ_4K (0x0) | ||
74 | #define _PAGE_SZ_8K (0x1 << _PAGE_SZ_SHIFT) | ||
75 | #define _PAGE_SZ_16K (0x2 << _PAGE_SZ_SHIFT) | ||
76 | #define _PAGE_SZ_32K (0x3 << _PAGE_SZ_SHIFT) | ||
77 | #define _PAGE_SZ_64K (0x4 << _PAGE_SZ_SHIFT) | ||
78 | #define _PAGE_SZ_128K (0x5 << _PAGE_SZ_SHIFT) | ||
79 | #define _PAGE_SZ_256K (0x6 << _PAGE_SZ_SHIFT) | ||
80 | #define _PAGE_SZ_512K (0x7 << _PAGE_SZ_SHIFT) | ||
81 | #define _PAGE_SZ_1M (0x8 << _PAGE_SZ_SHIFT) | ||
82 | #define _PAGE_SZ_2M (0x9 << _PAGE_SZ_SHIFT) | ||
83 | #define _PAGE_SZ_4M (0xa << _PAGE_SZ_SHIFT) | ||
84 | #define _PAGE_SZ_MASK (0xf << _PAGE_SZ_SHIFT) | ||
85 | |||
86 | #if defined(CONFIG_PAGE_SIZE_4K) | ||
87 | #define _PAGE_SZ (_PAGE_SZ_4K) | ||
88 | #elif defined(CONFIG_PAGE_SIZE_8K) | ||
89 | #define _PAGE_SZ (_PAGE_SZ_8K) | ||
90 | #elif defined(CONFIG_PAGE_SIZE_16K) | ||
91 | #define _PAGE_SZ (_PAGE_SZ_16K) | ||
92 | #endif | ||
93 | #define _PAGE_TABLE (_PAGE_SZ | _PAGE_PRESENT) | ||
94 | |||
95 | #if defined(CONFIG_HUGETLB_PAGE_SIZE_8K) | ||
96 | # define _PAGE_SZHUGE (_PAGE_SZ_8K) | ||
97 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_16K) | ||
98 | # define _PAGE_SZHUGE (_PAGE_SZ_16K) | ||
99 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_32K) | ||
100 | # define _PAGE_SZHUGE (_PAGE_SZ_32K) | ||
101 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K) | ||
102 | # define _PAGE_SZHUGE (_PAGE_SZ_64K) | ||
103 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_128K) | ||
104 | # define _PAGE_SZHUGE (_PAGE_SZ_128K) | ||
105 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) | ||
106 | # define _PAGE_SZHUGE (_PAGE_SZ_256K) | ||
107 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K) | ||
108 | # define _PAGE_SZHUGE (_PAGE_SZ_512K) | ||
109 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_1M) | ||
110 | # define _PAGE_SZHUGE (_PAGE_SZ_1M) | ||
111 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_2M) | ||
112 | # define _PAGE_SZHUGE (_PAGE_SZ_2M) | ||
113 | #elif defined(CONFIG_HUGETLB_PAGE_SIZE_4M) | ||
114 | # define _PAGE_SZHUGE (_PAGE_SZ_4M) | ||
115 | #endif | ||
116 | |||
117 | /* | ||
118 | * The Linux memory management assumes a three-level page table setup. On | 25 | * The Linux memory management assumes a three-level page table setup. On |
119 | * Meta, we use that, but "fold" the mid level into the top-level page | 26 | * Meta, we use that, but "fold" the mid level into the top-level page |
120 | * table. | 27 | * table. |
diff --git a/arch/metag/include/asm/processor.h b/arch/metag/include/asm/processor.h index 881071c07942..13272fd5a5ba 100644 --- a/arch/metag/include/asm/processor.h +++ b/arch/metag/include/asm/processor.h | |||
@@ -149,8 +149,8 @@ extern void exit_thread(void); | |||
149 | 149 | ||
150 | unsigned long get_wchan(struct task_struct *p); | 150 | unsigned long get_wchan(struct task_struct *p); |
151 | 151 | ||
152 | #define KSTK_EIP(tsk) ((tsk)->thread.kernel_context->CurrPC) | 152 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ctx.CurrPC) |
153 | #define KSTK_ESP(tsk) ((tsk)->thread.kernel_context->AX[0].U0) | 153 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->ctx.AX[0].U0) |
154 | 154 | ||
155 | #define user_stack_pointer(regs) ((regs)->ctx.AX[0].U0) | 155 | #define user_stack_pointer(regs) ((regs)->ctx.AX[0].U0) |
156 | 156 | ||
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 0536bc021cc6..ef548510b951 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S | |||
@@ -348,8 +348,9 @@ C_ENTRY(_user_exception): | |||
348 | * The LP register should point to the location where the called function | 348 | * The LP register should point to the location where the called function |
349 | * should return. [note that MAKE_SYS_CALL uses label 1] */ | 349 | * should return. [note that MAKE_SYS_CALL uses label 1] */ |
350 | /* See if the system call number is valid */ | 350 | /* See if the system call number is valid */ |
351 | blti r12, 5f | ||
351 | addi r11, r12, -__NR_syscalls; | 352 | addi r11, r12, -__NR_syscalls; |
352 | bgei r11,5f; | 353 | bgei r11, 5f; |
353 | /* Figure out which function to use for this system call. */ | 354 | /* Figure out which function to use for this system call. */ |
354 | /* Note Microblaze barrel shift is optional, so don't rely on it */ | 355 | /* Note Microblaze barrel shift is optional, so don't rely on it */ |
355 | add r12, r12, r12; /* convert num -> ptr */ | 356 | add r12, r12, r12; /* convert num -> ptr */ |
@@ -375,7 +376,7 @@ C_ENTRY(_user_exception): | |||
375 | 376 | ||
376 | /* The syscall number is invalid, return an error. */ | 377 | /* The syscall number is invalid, return an error. */ |
377 | 5: | 378 | 5: |
378 | rtsd r15, 8; /* looks like a normal subroutine return */ | 379 | braid ret_from_trap |
379 | addi r3, r0, -ENOSYS; | 380 | addi r3, r0, -ENOSYS; |
380 | 381 | ||
381 | /* Entry point used to return from a syscall/trap */ | 382 | /* Entry point used to return from a syscall/trap */ |
@@ -411,7 +412,7 @@ C_ENTRY(ret_from_trap): | |||
411 | bri 1b | 412 | bri 1b |
412 | 413 | ||
413 | /* Maybe handle a signal */ | 414 | /* Maybe handle a signal */ |
414 | 5: | 415 | 5: |
415 | andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME; | 416 | andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME; |
416 | beqi r11, 4f; /* Signals to handle, handle them */ | 417 | beqi r11, 4f; /* Signals to handle, handle them */ |
417 | 418 | ||
diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h index cdac7b3eeaf7..80386470d3a4 100644 --- a/arch/mips/include/asm/asmmacro-32.h +++ b/arch/mips/include/asm/asmmacro-32.h | |||
@@ -16,38 +16,38 @@ | |||
16 | .set push | 16 | .set push |
17 | SET_HARDFLOAT | 17 | SET_HARDFLOAT |
18 | cfc1 \tmp, fcr31 | 18 | cfc1 \tmp, fcr31 |
19 | swc1 $f0, THREAD_FPR0_LS64(\thread) | 19 | swc1 $f0, THREAD_FPR0(\thread) |
20 | swc1 $f1, THREAD_FPR1_LS64(\thread) | 20 | swc1 $f1, THREAD_FPR1(\thread) |
21 | swc1 $f2, THREAD_FPR2_LS64(\thread) | 21 | swc1 $f2, THREAD_FPR2(\thread) |
22 | swc1 $f3, THREAD_FPR3_LS64(\thread) | 22 | swc1 $f3, THREAD_FPR3(\thread) |
23 | swc1 $f4, THREAD_FPR4_LS64(\thread) | 23 | swc1 $f4, THREAD_FPR4(\thread) |
24 | swc1 $f5, THREAD_FPR5_LS64(\thread) | 24 | swc1 $f5, THREAD_FPR5(\thread) |
25 | swc1 $f6, THREAD_FPR6_LS64(\thread) | 25 | swc1 $f6, THREAD_FPR6(\thread) |
26 | swc1 $f7, THREAD_FPR7_LS64(\thread) | 26 | swc1 $f7, THREAD_FPR7(\thread) |
27 | swc1 $f8, THREAD_FPR8_LS64(\thread) | 27 | swc1 $f8, THREAD_FPR8(\thread) |
28 | swc1 $f9, THREAD_FPR9_LS64(\thread) | 28 | swc1 $f9, THREAD_FPR9(\thread) |
29 | swc1 $f10, THREAD_FPR10_LS64(\thread) | 29 | swc1 $f10, THREAD_FPR10(\thread) |
30 | swc1 $f11, THREAD_FPR11_LS64(\thread) | 30 | swc1 $f11, THREAD_FPR11(\thread) |
31 | swc1 $f12, THREAD_FPR12_LS64(\thread) | 31 | swc1 $f12, THREAD_FPR12(\thread) |
32 | swc1 $f13, THREAD_FPR13_LS64(\thread) | 32 | swc1 $f13, THREAD_FPR13(\thread) |
33 | swc1 $f14, THREAD_FPR14_LS64(\thread) | 33 | swc1 $f14, THREAD_FPR14(\thread) |
34 | swc1 $f15, THREAD_FPR15_LS64(\thread) | 34 | swc1 $f15, THREAD_FPR15(\thread) |
35 | swc1 $f16, THREAD_FPR16_LS64(\thread) | 35 | swc1 $f16, THREAD_FPR16(\thread) |
36 | swc1 $f17, THREAD_FPR17_LS64(\thread) | 36 | swc1 $f17, THREAD_FPR17(\thread) |
37 | swc1 $f18, THREAD_FPR18_LS64(\thread) | 37 | swc1 $f18, THREAD_FPR18(\thread) |
38 | swc1 $f19, THREAD_FPR19_LS64(\thread) | 38 | swc1 $f19, THREAD_FPR19(\thread) |
39 | swc1 $f20, THREAD_FPR20_LS64(\thread) | 39 | swc1 $f20, THREAD_FPR20(\thread) |
40 | swc1 $f21, THREAD_FPR21_LS64(\thread) | 40 | swc1 $f21, THREAD_FPR21(\thread) |
41 | swc1 $f22, THREAD_FPR22_LS64(\thread) | 41 | swc1 $f22, THREAD_FPR22(\thread) |
42 | swc1 $f23, THREAD_FPR23_LS64(\thread) | 42 | swc1 $f23, THREAD_FPR23(\thread) |
43 | swc1 $f24, THREAD_FPR24_LS64(\thread) | 43 | swc1 $f24, THREAD_FPR24(\thread) |
44 | swc1 $f25, THREAD_FPR25_LS64(\thread) | 44 | swc1 $f25, THREAD_FPR25(\thread) |
45 | swc1 $f26, THREAD_FPR26_LS64(\thread) | 45 | swc1 $f26, THREAD_FPR26(\thread) |
46 | swc1 $f27, THREAD_FPR27_LS64(\thread) | 46 | swc1 $f27, THREAD_FPR27(\thread) |
47 | swc1 $f28, THREAD_FPR28_LS64(\thread) | 47 | swc1 $f28, THREAD_FPR28(\thread) |
48 | swc1 $f29, THREAD_FPR29_LS64(\thread) | 48 | swc1 $f29, THREAD_FPR29(\thread) |
49 | swc1 $f30, THREAD_FPR30_LS64(\thread) | 49 | swc1 $f30, THREAD_FPR30(\thread) |
50 | swc1 $f31, THREAD_FPR31_LS64(\thread) | 50 | swc1 $f31, THREAD_FPR31(\thread) |
51 | sw \tmp, THREAD_FCR31(\thread) | 51 | sw \tmp, THREAD_FCR31(\thread) |
52 | .set pop | 52 | .set pop |
53 | .endm | 53 | .endm |
@@ -56,38 +56,38 @@ | |||
56 | .set push | 56 | .set push |
57 | SET_HARDFLOAT | 57 | SET_HARDFLOAT |
58 | lw \tmp, THREAD_FCR31(\thread) | 58 | lw \tmp, THREAD_FCR31(\thread) |
59 | lwc1 $f0, THREAD_FPR0_LS64(\thread) | 59 | lwc1 $f0, THREAD_FPR0(\thread) |
60 | lwc1 $f1, THREAD_FPR1_LS64(\thread) | 60 | lwc1 $f1, THREAD_FPR1(\thread) |
61 | lwc1 $f2, THREAD_FPR2_LS64(\thread) | 61 | lwc1 $f2, THREAD_FPR2(\thread) |
62 | lwc1 $f3, THREAD_FPR3_LS64(\thread) | 62 | lwc1 $f3, THREAD_FPR3(\thread) |
63 | lwc1 $f4, THREAD_FPR4_LS64(\thread) | 63 | lwc1 $f4, THREAD_FPR4(\thread) |
64 | lwc1 $f5, THREAD_FPR5_LS64(\thread) | 64 | lwc1 $f5, THREAD_FPR5(\thread) |
65 | lwc1 $f6, THREAD_FPR6_LS64(\thread) | 65 | lwc1 $f6, THREAD_FPR6(\thread) |
66 | lwc1 $f7, THREAD_FPR7_LS64(\thread) | 66 | lwc1 $f7, THREAD_FPR7(\thread) |
67 | lwc1 $f8, THREAD_FPR8_LS64(\thread) | 67 | lwc1 $f8, THREAD_FPR8(\thread) |
68 | lwc1 $f9, THREAD_FPR9_LS64(\thread) | 68 | lwc1 $f9, THREAD_FPR9(\thread) |
69 | lwc1 $f10, THREAD_FPR10_LS64(\thread) | 69 | lwc1 $f10, THREAD_FPR10(\thread) |
70 | lwc1 $f11, THREAD_FPR11_LS64(\thread) | 70 | lwc1 $f11, THREAD_FPR11(\thread) |
71 | lwc1 $f12, THREAD_FPR12_LS64(\thread) | 71 | lwc1 $f12, THREAD_FPR12(\thread) |
72 | lwc1 $f13, THREAD_FPR13_LS64(\thread) | 72 | lwc1 $f13, THREAD_FPR13(\thread) |
73 | lwc1 $f14, THREAD_FPR14_LS64(\thread) | 73 | lwc1 $f14, THREAD_FPR14(\thread) |
74 | lwc1 $f15, THREAD_FPR15_LS64(\thread) | 74 | lwc1 $f15, THREAD_FPR15(\thread) |
75 | lwc1 $f16, THREAD_FPR16_LS64(\thread) | 75 | lwc1 $f16, THREAD_FPR16(\thread) |
76 | lwc1 $f17, THREAD_FPR17_LS64(\thread) | 76 | lwc1 $f17, THREAD_FPR17(\thread) |
77 | lwc1 $f18, THREAD_FPR18_LS64(\thread) | 77 | lwc1 $f18, THREAD_FPR18(\thread) |
78 | lwc1 $f19, THREAD_FPR19_LS64(\thread) | 78 | lwc1 $f19, THREAD_FPR19(\thread) |
79 | lwc1 $f20, THREAD_FPR20_LS64(\thread) | 79 | lwc1 $f20, THREAD_FPR20(\thread) |
80 | lwc1 $f21, THREAD_FPR21_LS64(\thread) | 80 | lwc1 $f21, THREAD_FPR21(\thread) |
81 | lwc1 $f22, THREAD_FPR22_LS64(\thread) | 81 | lwc1 $f22, THREAD_FPR22(\thread) |
82 | lwc1 $f23, THREAD_FPR23_LS64(\thread) | 82 | lwc1 $f23, THREAD_FPR23(\thread) |
83 | lwc1 $f24, THREAD_FPR24_LS64(\thread) | 83 | lwc1 $f24, THREAD_FPR24(\thread) |
84 | lwc1 $f25, THREAD_FPR25_LS64(\thread) | 84 | lwc1 $f25, THREAD_FPR25(\thread) |
85 | lwc1 $f26, THREAD_FPR26_LS64(\thread) | 85 | lwc1 $f26, THREAD_FPR26(\thread) |
86 | lwc1 $f27, THREAD_FPR27_LS64(\thread) | 86 | lwc1 $f27, THREAD_FPR27(\thread) |
87 | lwc1 $f28, THREAD_FPR28_LS64(\thread) | 87 | lwc1 $f28, THREAD_FPR28(\thread) |
88 | lwc1 $f29, THREAD_FPR29_LS64(\thread) | 88 | lwc1 $f29, THREAD_FPR29(\thread) |
89 | lwc1 $f30, THREAD_FPR30_LS64(\thread) | 89 | lwc1 $f30, THREAD_FPR30(\thread) |
90 | lwc1 $f31, THREAD_FPR31_LS64(\thread) | 90 | lwc1 $f31, THREAD_FPR31(\thread) |
91 | ctc1 \tmp, fcr31 | 91 | ctc1 \tmp, fcr31 |
92 | .set pop | 92 | .set pop |
93 | .endm | 93 | .endm |
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 0cae4595e985..6156ac8c4cfb 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h | |||
@@ -60,22 +60,22 @@ | |||
60 | .set push | 60 | .set push |
61 | SET_HARDFLOAT | 61 | SET_HARDFLOAT |
62 | cfc1 \tmp, fcr31 | 62 | cfc1 \tmp, fcr31 |
63 | sdc1 $f0, THREAD_FPR0_LS64(\thread) | 63 | sdc1 $f0, THREAD_FPR0(\thread) |
64 | sdc1 $f2, THREAD_FPR2_LS64(\thread) | 64 | sdc1 $f2, THREAD_FPR2(\thread) |
65 | sdc1 $f4, THREAD_FPR4_LS64(\thread) | 65 | sdc1 $f4, THREAD_FPR4(\thread) |
66 | sdc1 $f6, THREAD_FPR6_LS64(\thread) | 66 | sdc1 $f6, THREAD_FPR6(\thread) |
67 | sdc1 $f8, THREAD_FPR8_LS64(\thread) | 67 | sdc1 $f8, THREAD_FPR8(\thread) |
68 | sdc1 $f10, THREAD_FPR10_LS64(\thread) | 68 | sdc1 $f10, THREAD_FPR10(\thread) |
69 | sdc1 $f12, THREAD_FPR12_LS64(\thread) | 69 | sdc1 $f12, THREAD_FPR12(\thread) |
70 | sdc1 $f14, THREAD_FPR14_LS64(\thread) | 70 | sdc1 $f14, THREAD_FPR14(\thread) |
71 | sdc1 $f16, THREAD_FPR16_LS64(\thread) | 71 | sdc1 $f16, THREAD_FPR16(\thread) |
72 | sdc1 $f18, THREAD_FPR18_LS64(\thread) | 72 | sdc1 $f18, THREAD_FPR18(\thread) |
73 | sdc1 $f20, THREAD_FPR20_LS64(\thread) | 73 | sdc1 $f20, THREAD_FPR20(\thread) |
74 | sdc1 $f22, THREAD_FPR22_LS64(\thread) | 74 | sdc1 $f22, THREAD_FPR22(\thread) |
75 | sdc1 $f24, THREAD_FPR24_LS64(\thread) | 75 | sdc1 $f24, THREAD_FPR24(\thread) |
76 | sdc1 $f26, THREAD_FPR26_LS64(\thread) | 76 | sdc1 $f26, THREAD_FPR26(\thread) |
77 | sdc1 $f28, THREAD_FPR28_LS64(\thread) | 77 | sdc1 $f28, THREAD_FPR28(\thread) |
78 | sdc1 $f30, THREAD_FPR30_LS64(\thread) | 78 | sdc1 $f30, THREAD_FPR30(\thread) |
79 | sw \tmp, THREAD_FCR31(\thread) | 79 | sw \tmp, THREAD_FCR31(\thread) |
80 | .set pop | 80 | .set pop |
81 | .endm | 81 | .endm |
@@ -84,22 +84,22 @@ | |||
84 | .set push | 84 | .set push |
85 | .set mips64r2 | 85 | .set mips64r2 |
86 | SET_HARDFLOAT | 86 | SET_HARDFLOAT |
87 | sdc1 $f1, THREAD_FPR1_LS64(\thread) | 87 | sdc1 $f1, THREAD_FPR1(\thread) |
88 | sdc1 $f3, THREAD_FPR3_LS64(\thread) | 88 | sdc1 $f3, THREAD_FPR3(\thread) |
89 | sdc1 $f5, THREAD_FPR5_LS64(\thread) | 89 | sdc1 $f5, THREAD_FPR5(\thread) |
90 | sdc1 $f7, THREAD_FPR7_LS64(\thread) | 90 | sdc1 $f7, THREAD_FPR7(\thread) |
91 | sdc1 $f9, THREAD_FPR9_LS64(\thread) | 91 | sdc1 $f9, THREAD_FPR9(\thread) |
92 | sdc1 $f11, THREAD_FPR11_LS64(\thread) | 92 | sdc1 $f11, THREAD_FPR11(\thread) |
93 | sdc1 $f13, THREAD_FPR13_LS64(\thread) | 93 | sdc1 $f13, THREAD_FPR13(\thread) |
94 | sdc1 $f15, THREAD_FPR15_LS64(\thread) | 94 | sdc1 $f15, THREAD_FPR15(\thread) |
95 | sdc1 $f17, THREAD_FPR17_LS64(\thread) | 95 | sdc1 $f17, THREAD_FPR17(\thread) |
96 | sdc1 $f19, THREAD_FPR19_LS64(\thread) | 96 | sdc1 $f19, THREAD_FPR19(\thread) |
97 | sdc1 $f21, THREAD_FPR21_LS64(\thread) | 97 | sdc1 $f21, THREAD_FPR21(\thread) |
98 | sdc1 $f23, THREAD_FPR23_LS64(\thread) | 98 | sdc1 $f23, THREAD_FPR23(\thread) |
99 | sdc1 $f25, THREAD_FPR25_LS64(\thread) | 99 | sdc1 $f25, THREAD_FPR25(\thread) |
100 | sdc1 $f27, THREAD_FPR27_LS64(\thread) | 100 | sdc1 $f27, THREAD_FPR27(\thread) |
101 | sdc1 $f29, THREAD_FPR29_LS64(\thread) | 101 | sdc1 $f29, THREAD_FPR29(\thread) |
102 | sdc1 $f31, THREAD_FPR31_LS64(\thread) | 102 | sdc1 $f31, THREAD_FPR31(\thread) |
103 | .set pop | 103 | .set pop |
104 | .endm | 104 | .endm |
105 | 105 | ||
@@ -118,22 +118,22 @@ | |||
118 | .set push | 118 | .set push |
119 | SET_HARDFLOAT | 119 | SET_HARDFLOAT |
120 | lw \tmp, THREAD_FCR31(\thread) | 120 | lw \tmp, THREAD_FCR31(\thread) |
121 | ldc1 $f0, THREAD_FPR0_LS64(\thread) | 121 | ldc1 $f0, THREAD_FPR0(\thread) |
122 | ldc1 $f2, THREAD_FPR2_LS64(\thread) | 122 | ldc1 $f2, THREAD_FPR2(\thread) |
123 | ldc1 $f4, THREAD_FPR4_LS64(\thread) | 123 | ldc1 $f4, THREAD_FPR4(\thread) |
124 | ldc1 $f6, THREAD_FPR6_LS64(\thread) | 124 | ldc1 $f6, THREAD_FPR6(\thread) |
125 | ldc1 $f8, THREAD_FPR8_LS64(\thread) | 125 | ldc1 $f8, THREAD_FPR8(\thread) |
126 | ldc1 $f10, THREAD_FPR10_LS64(\thread) | 126 | ldc1 $f10, THREAD_FPR10(\thread) |
127 | ldc1 $f12, THREAD_FPR12_LS64(\thread) | 127 | ldc1 $f12, THREAD_FPR12(\thread) |
128 | ldc1 $f14, THREAD_FPR14_LS64(\thread) | 128 | ldc1 $f14, THREAD_FPR14(\thread) |
129 | ldc1 $f16, THREAD_FPR16_LS64(\thread) | 129 | ldc1 $f16, THREAD_FPR16(\thread) |
130 | ldc1 $f18, THREAD_FPR18_LS64(\thread) | 130 | ldc1 $f18, THREAD_FPR18(\thread) |
131 | ldc1 $f20, THREAD_FPR20_LS64(\thread) | 131 | ldc1 $f20, THREAD_FPR20(\thread) |
132 | ldc1 $f22, THREAD_FPR22_LS64(\thread) | 132 | ldc1 $f22, THREAD_FPR22(\thread) |
133 | ldc1 $f24, THREAD_FPR24_LS64(\thread) | 133 | ldc1 $f24, THREAD_FPR24(\thread) |
134 | ldc1 $f26, THREAD_FPR26_LS64(\thread) | 134 | ldc1 $f26, THREAD_FPR26(\thread) |
135 | ldc1 $f28, THREAD_FPR28_LS64(\thread) | 135 | ldc1 $f28, THREAD_FPR28(\thread) |
136 | ldc1 $f30, THREAD_FPR30_LS64(\thread) | 136 | ldc1 $f30, THREAD_FPR30(\thread) |
137 | ctc1 \tmp, fcr31 | 137 | ctc1 \tmp, fcr31 |
138 | .endm | 138 | .endm |
139 | 139 | ||
@@ -141,22 +141,22 @@ | |||
141 | .set push | 141 | .set push |
142 | .set mips64r2 | 142 | .set mips64r2 |
143 | SET_HARDFLOAT | 143 | SET_HARDFLOAT |
144 | ldc1 $f1, THREAD_FPR1_LS64(\thread) | 144 | ldc1 $f1, THREAD_FPR1(\thread) |
145 | ldc1 $f3, THREAD_FPR3_LS64(\thread) | 145 | ldc1 $f3, THREAD_FPR3(\thread) |
146 | ldc1 $f5, THREAD_FPR5_LS64(\thread) | 146 | ldc1 $f5, THREAD_FPR5(\thread) |
147 | ldc1 $f7, THREAD_FPR7_LS64(\thread) | 147 | ldc1 $f7, THREAD_FPR7(\thread) |
148 | ldc1 $f9, THREAD_FPR9_LS64(\thread) | 148 | ldc1 $f9, THREAD_FPR9(\thread) |
149 | ldc1 $f11, THREAD_FPR11_LS64(\thread) | 149 | ldc1 $f11, THREAD_FPR11(\thread) |
150 | ldc1 $f13, THREAD_FPR13_LS64(\thread) | 150 | ldc1 $f13, THREAD_FPR13(\thread) |
151 | ldc1 $f15, THREAD_FPR15_LS64(\thread) | 151 | ldc1 $f15, THREAD_FPR15(\thread) |
152 | ldc1 $f17, THREAD_FPR17_LS64(\thread) | 152 | ldc1 $f17, THREAD_FPR17(\thread) |
153 | ldc1 $f19, THREAD_FPR19_LS64(\thread) | 153 | ldc1 $f19, THREAD_FPR19(\thread) |
154 | ldc1 $f21, THREAD_FPR21_LS64(\thread) | 154 | ldc1 $f21, THREAD_FPR21(\thread) |
155 | ldc1 $f23, THREAD_FPR23_LS64(\thread) | 155 | ldc1 $f23, THREAD_FPR23(\thread) |
156 | ldc1 $f25, THREAD_FPR25_LS64(\thread) | 156 | ldc1 $f25, THREAD_FPR25(\thread) |
157 | ldc1 $f27, THREAD_FPR27_LS64(\thread) | 157 | ldc1 $f27, THREAD_FPR27(\thread) |
158 | ldc1 $f29, THREAD_FPR29_LS64(\thread) | 158 | ldc1 $f29, THREAD_FPR29(\thread) |
159 | ldc1 $f31, THREAD_FPR31_LS64(\thread) | 159 | ldc1 $f31, THREAD_FPR31(\thread) |
160 | .set pop | 160 | .set pop |
161 | .endm | 161 | .endm |
162 | 162 | ||
@@ -211,6 +211,22 @@ | |||
211 | .endm | 211 | .endm |
212 | 212 | ||
213 | #ifdef TOOLCHAIN_SUPPORTS_MSA | 213 | #ifdef TOOLCHAIN_SUPPORTS_MSA |
214 | .macro _cfcmsa rd, cs | ||
215 | .set push | ||
216 | .set mips32r2 | ||
217 | .set msa | ||
218 | cfcmsa \rd, $\cs | ||
219 | .set pop | ||
220 | .endm | ||
221 | |||
222 | .macro _ctcmsa cd, rs | ||
223 | .set push | ||
224 | .set mips32r2 | ||
225 | .set msa | ||
226 | ctcmsa $\cd, \rs | ||
227 | .set pop | ||
228 | .endm | ||
229 | |||
214 | .macro ld_d wd, off, base | 230 | .macro ld_d wd, off, base |
215 | .set push | 231 | .set push |
216 | .set mips32r2 | 232 | .set mips32r2 |
@@ -227,35 +243,35 @@ | |||
227 | .set pop | 243 | .set pop |
228 | .endm | 244 | .endm |
229 | 245 | ||
230 | .macro copy_u_w rd, ws, n | 246 | .macro copy_u_w ws, n |
231 | .set push | 247 | .set push |
232 | .set mips32r2 | 248 | .set mips32r2 |
233 | .set msa | 249 | .set msa |
234 | copy_u.w \rd, $w\ws[\n] | 250 | copy_u.w $1, $w\ws[\n] |
235 | .set pop | 251 | .set pop |
236 | .endm | 252 | .endm |
237 | 253 | ||
238 | .macro copy_u_d rd, ws, n | 254 | .macro copy_u_d ws, n |
239 | .set push | 255 | .set push |
240 | .set mips64r2 | 256 | .set mips64r2 |
241 | .set msa | 257 | .set msa |
242 | copy_u.d \rd, $w\ws[\n] | 258 | copy_u.d $1, $w\ws[\n] |
243 | .set pop | 259 | .set pop |
244 | .endm | 260 | .endm |
245 | 261 | ||
246 | .macro insert_w wd, n, rs | 262 | .macro insert_w wd, n |
247 | .set push | 263 | .set push |
248 | .set mips32r2 | 264 | .set mips32r2 |
249 | .set msa | 265 | .set msa |
250 | insert.w $w\wd[\n], \rs | 266 | insert.w $w\wd[\n], $1 |
251 | .set pop | 267 | .set pop |
252 | .endm | 268 | .endm |
253 | 269 | ||
254 | .macro insert_d wd, n, rs | 270 | .macro insert_d wd, n |
255 | .set push | 271 | .set push |
256 | .set mips64r2 | 272 | .set mips64r2 |
257 | .set msa | 273 | .set msa |
258 | insert.d $w\wd[\n], \rs | 274 | insert.d $w\wd[\n], $1 |
259 | .set pop | 275 | .set pop |
260 | .endm | 276 | .endm |
261 | #else | 277 | #else |
@@ -283,7 +299,7 @@ | |||
283 | /* | 299 | /* |
284 | * Temporary until all toolchains in use include MSA support. | 300 | * Temporary until all toolchains in use include MSA support. |
285 | */ | 301 | */ |
286 | .macro cfcmsa rd, cs | 302 | .macro _cfcmsa rd, cs |
287 | .set push | 303 | .set push |
288 | .set noat | 304 | .set noat |
289 | SET_HARDFLOAT | 305 | SET_HARDFLOAT |
@@ -293,7 +309,7 @@ | |||
293 | .set pop | 309 | .set pop |
294 | .endm | 310 | .endm |
295 | 311 | ||
296 | .macro ctcmsa cd, rs | 312 | .macro _ctcmsa cd, rs |
297 | .set push | 313 | .set push |
298 | .set noat | 314 | .set noat |
299 | SET_HARDFLOAT | 315 | SET_HARDFLOAT |
@@ -320,44 +336,36 @@ | |||
320 | .set pop | 336 | .set pop |
321 | .endm | 337 | .endm |
322 | 338 | ||
323 | .macro copy_u_w rd, ws, n | 339 | .macro copy_u_w ws, n |
324 | .set push | 340 | .set push |
325 | .set noat | 341 | .set noat |
326 | SET_HARDFLOAT | 342 | SET_HARDFLOAT |
327 | .insn | 343 | .insn |
328 | .word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11) | 344 | .word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11) |
329 | /* move triggers an assembler bug... */ | ||
330 | or \rd, $1, zero | ||
331 | .set pop | 345 | .set pop |
332 | .endm | 346 | .endm |
333 | 347 | ||
334 | .macro copy_u_d rd, ws, n | 348 | .macro copy_u_d ws, n |
335 | .set push | 349 | .set push |
336 | .set noat | 350 | .set noat |
337 | SET_HARDFLOAT | 351 | SET_HARDFLOAT |
338 | .insn | 352 | .insn |
339 | .word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11) | 353 | .word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11) |
340 | /* move triggers an assembler bug... */ | ||
341 | or \rd, $1, zero | ||
342 | .set pop | 354 | .set pop |
343 | .endm | 355 | .endm |
344 | 356 | ||
345 | .macro insert_w wd, n, rs | 357 | .macro insert_w wd, n |
346 | .set push | 358 | .set push |
347 | .set noat | 359 | .set noat |
348 | SET_HARDFLOAT | 360 | SET_HARDFLOAT |
349 | /* move triggers an assembler bug... */ | ||
350 | or $1, \rs, zero | ||
351 | .word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6) | 361 | .word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6) |
352 | .set pop | 362 | .set pop |
353 | .endm | 363 | .endm |
354 | 364 | ||
355 | .macro insert_d wd, n, rs | 365 | .macro insert_d wd, n |
356 | .set push | 366 | .set push |
357 | .set noat | 367 | .set noat |
358 | SET_HARDFLOAT | 368 | SET_HARDFLOAT |
359 | /* move triggers an assembler bug... */ | ||
360 | or $1, \rs, zero | ||
361 | .word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6) | 369 | .word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6) |
362 | .set pop | 370 | .set pop |
363 | .endm | 371 | .endm |
@@ -399,7 +407,7 @@ | |||
399 | .set push | 407 | .set push |
400 | .set noat | 408 | .set noat |
401 | SET_HARDFLOAT | 409 | SET_HARDFLOAT |
402 | cfcmsa $1, MSA_CSR | 410 | _cfcmsa $1, MSA_CSR |
403 | sw $1, THREAD_MSA_CSR(\thread) | 411 | sw $1, THREAD_MSA_CSR(\thread) |
404 | .set pop | 412 | .set pop |
405 | .endm | 413 | .endm |
@@ -409,7 +417,7 @@ | |||
409 | .set noat | 417 | .set noat |
410 | SET_HARDFLOAT | 418 | SET_HARDFLOAT |
411 | lw $1, THREAD_MSA_CSR(\thread) | 419 | lw $1, THREAD_MSA_CSR(\thread) |
412 | ctcmsa MSA_CSR, $1 | 420 | _ctcmsa MSA_CSR, $1 |
413 | .set pop | 421 | .set pop |
414 | ld_d 0, THREAD_FPR0, \thread | 422 | ld_d 0, THREAD_FPR0, \thread |
415 | ld_d 1, THREAD_FPR1, \thread | 423 | ld_d 1, THREAD_FPR1, \thread |
@@ -452,9 +460,6 @@ | |||
452 | insert_w \wd, 2 | 460 | insert_w \wd, 2 |
453 | insert_w \wd, 3 | 461 | insert_w \wd, 3 |
454 | #endif | 462 | #endif |
455 | .if 31-\wd | ||
456 | msa_init_upper (\wd+1) | ||
457 | .endif | ||
458 | .endm | 463 | .endm |
459 | 464 | ||
460 | .macro msa_init_all_upper | 465 | .macro msa_init_all_upper |
@@ -463,6 +468,37 @@ | |||
463 | SET_HARDFLOAT | 468 | SET_HARDFLOAT |
464 | not $1, zero | 469 | not $1, zero |
465 | msa_init_upper 0 | 470 | msa_init_upper 0 |
471 | msa_init_upper 1 | ||
472 | msa_init_upper 2 | ||
473 | msa_init_upper 3 | ||
474 | msa_init_upper 4 | ||
475 | msa_init_upper 5 | ||
476 | msa_init_upper 6 | ||
477 | msa_init_upper 7 | ||
478 | msa_init_upper 8 | ||
479 | msa_init_upper 9 | ||
480 | msa_init_upper 10 | ||
481 | msa_init_upper 11 | ||
482 | msa_init_upper 12 | ||
483 | msa_init_upper 13 | ||
484 | msa_init_upper 14 | ||
485 | msa_init_upper 15 | ||
486 | msa_init_upper 16 | ||
487 | msa_init_upper 17 | ||
488 | msa_init_upper 18 | ||
489 | msa_init_upper 19 | ||
490 | msa_init_upper 20 | ||
491 | msa_init_upper 21 | ||
492 | msa_init_upper 22 | ||
493 | msa_init_upper 23 | ||
494 | msa_init_upper 24 | ||
495 | msa_init_upper 25 | ||
496 | msa_init_upper 26 | ||
497 | msa_init_upper 27 | ||
498 | msa_init_upper 28 | ||
499 | msa_init_upper 29 | ||
500 | msa_init_upper 30 | ||
501 | msa_init_upper 31 | ||
466 | .set pop | 502 | .set pop |
467 | .endm | 503 | .endm |
468 | 504 | ||
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index dd083e999b08..b104ad9d655f 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h | |||
@@ -48,6 +48,12 @@ enum fpu_mode { | |||
48 | #define FPU_FR_MASK 0x1 | 48 | #define FPU_FR_MASK 0x1 |
49 | }; | 49 | }; |
50 | 50 | ||
51 | #define __disable_fpu() \ | ||
52 | do { \ | ||
53 | clear_c0_status(ST0_CU1); \ | ||
54 | disable_fpu_hazard(); \ | ||
55 | } while (0) | ||
56 | |||
51 | static inline int __enable_fpu(enum fpu_mode mode) | 57 | static inline int __enable_fpu(enum fpu_mode mode) |
52 | { | 58 | { |
53 | int fr; | 59 | int fr; |
@@ -86,7 +92,12 @@ fr_common: | |||
86 | enable_fpu_hazard(); | 92 | enable_fpu_hazard(); |
87 | 93 | ||
88 | /* check FR has the desired value */ | 94 | /* check FR has the desired value */ |
89 | return (!!(read_c0_status() & ST0_FR) == !!fr) ? 0 : SIGFPE; | 95 | if (!!(read_c0_status() & ST0_FR) == !!fr) |
96 | return 0; | ||
97 | |||
98 | /* unsupported FR value */ | ||
99 | __disable_fpu(); | ||
100 | return SIGFPE; | ||
90 | 101 | ||
91 | default: | 102 | default: |
92 | BUG(); | 103 | BUG(); |
@@ -95,12 +106,6 @@ fr_common: | |||
95 | return SIGFPE; | 106 | return SIGFPE; |
96 | } | 107 | } |
97 | 108 | ||
98 | #define __disable_fpu() \ | ||
99 | do { \ | ||
100 | clear_c0_status(ST0_CU1); \ | ||
101 | disable_fpu_hazard(); \ | ||
102 | } while (0) | ||
103 | |||
104 | #define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU) | 109 | #define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU) |
105 | 110 | ||
106 | static inline int __is_fpu_owner(void) | 111 | static inline int __is_fpu_owner(void) |
@@ -170,6 +175,7 @@ static inline void lose_fpu(int save) | |||
170 | } | 175 | } |
171 | disable_msa(); | 176 | disable_msa(); |
172 | clear_thread_flag(TIF_USEDMSA); | 177 | clear_thread_flag(TIF_USEDMSA); |
178 | __disable_fpu(); | ||
173 | } else if (is_fpu_owner()) { | 179 | } else if (is_fpu_owner()) { |
174 | if (save) | 180 | if (save) |
175 | _save_fp(current); | 181 | _save_fp(current); |
diff --git a/arch/mips/include/asm/kdebug.h b/arch/mips/include/asm/kdebug.h index 6a9af5fcb5d7..cba22ab7ad4d 100644 --- a/arch/mips/include/asm/kdebug.h +++ b/arch/mips/include/asm/kdebug.h | |||
@@ -10,7 +10,8 @@ enum die_val { | |||
10 | DIE_RI, | 10 | DIE_RI, |
11 | DIE_PAGE_FAULT, | 11 | DIE_PAGE_FAULT, |
12 | DIE_BREAK, | 12 | DIE_BREAK, |
13 | DIE_SSTEPBP | 13 | DIE_SSTEPBP, |
14 | DIE_MSAFP | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | #endif /* _ASM_MIPS_KDEBUG_H */ | 17 | #endif /* _ASM_MIPS_KDEBUG_H */ |
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index ac4fc716062b..4c25823563fe 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h | |||
@@ -21,10 +21,10 @@ | |||
21 | 21 | ||
22 | /* MIPS KVM register ids */ | 22 | /* MIPS KVM register ids */ |
23 | #define MIPS_CP0_32(_R, _S) \ | 23 | #define MIPS_CP0_32(_R, _S) \ |
24 | (KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x10000 | (8 * (_R) + (_S))) | 24 | (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) |
25 | 25 | ||
26 | #define MIPS_CP0_64(_R, _S) \ | 26 | #define MIPS_CP0_64(_R, _S) \ |
27 | (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x10000 | (8 * (_R) + (_S))) | 27 | (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S))) |
28 | 28 | ||
29 | #define KVM_REG_MIPS_CP0_INDEX MIPS_CP0_32(0, 0) | 29 | #define KVM_REG_MIPS_CP0_INDEX MIPS_CP0_32(0, 0) |
30 | #define KVM_REG_MIPS_CP0_ENTRYLO0 MIPS_CP0_64(2, 0) | 30 | #define KVM_REG_MIPS_CP0_ENTRYLO0 MIPS_CP0_64(2, 0) |
@@ -42,11 +42,14 @@ | |||
42 | #define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0) | 42 | #define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0) |
43 | #define KVM_REG_MIPS_CP0_CAUSE MIPS_CP0_32(13, 0) | 43 | #define KVM_REG_MIPS_CP0_CAUSE MIPS_CP0_32(13, 0) |
44 | #define KVM_REG_MIPS_CP0_EPC MIPS_CP0_64(14, 0) | 44 | #define KVM_REG_MIPS_CP0_EPC MIPS_CP0_64(14, 0) |
45 | #define KVM_REG_MIPS_CP0_PRID MIPS_CP0_32(15, 0) | ||
45 | #define KVM_REG_MIPS_CP0_EBASE MIPS_CP0_64(15, 1) | 46 | #define KVM_REG_MIPS_CP0_EBASE MIPS_CP0_64(15, 1) |
46 | #define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0) | 47 | #define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0) |
47 | #define KVM_REG_MIPS_CP0_CONFIG1 MIPS_CP0_32(16, 1) | 48 | #define KVM_REG_MIPS_CP0_CONFIG1 MIPS_CP0_32(16, 1) |
48 | #define KVM_REG_MIPS_CP0_CONFIG2 MIPS_CP0_32(16, 2) | 49 | #define KVM_REG_MIPS_CP0_CONFIG2 MIPS_CP0_32(16, 2) |
49 | #define KVM_REG_MIPS_CP0_CONFIG3 MIPS_CP0_32(16, 3) | 50 | #define KVM_REG_MIPS_CP0_CONFIG3 MIPS_CP0_32(16, 3) |
51 | #define KVM_REG_MIPS_CP0_CONFIG4 MIPS_CP0_32(16, 4) | ||
52 | #define KVM_REG_MIPS_CP0_CONFIG5 MIPS_CP0_32(16, 5) | ||
50 | #define KVM_REG_MIPS_CP0_CONFIG7 MIPS_CP0_32(16, 7) | 53 | #define KVM_REG_MIPS_CP0_CONFIG7 MIPS_CP0_32(16, 7) |
51 | #define KVM_REG_MIPS_CP0_XCONTEXT MIPS_CP0_64(20, 0) | 54 | #define KVM_REG_MIPS_CP0_XCONTEXT MIPS_CP0_64(20, 0) |
52 | #define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0) | 55 | #define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0) |
@@ -119,6 +122,10 @@ struct kvm_vcpu_stat { | |||
119 | u32 syscall_exits; | 122 | u32 syscall_exits; |
120 | u32 resvd_inst_exits; | 123 | u32 resvd_inst_exits; |
121 | u32 break_inst_exits; | 124 | u32 break_inst_exits; |
125 | u32 trap_inst_exits; | ||
126 | u32 msa_fpe_exits; | ||
127 | u32 fpe_exits; | ||
128 | u32 msa_disabled_exits; | ||
122 | u32 flush_dcache_exits; | 129 | u32 flush_dcache_exits; |
123 | u32 halt_successful_poll; | 130 | u32 halt_successful_poll; |
124 | u32 halt_wakeup; | 131 | u32 halt_wakeup; |
@@ -138,6 +145,10 @@ enum kvm_mips_exit_types { | |||
138 | SYSCALL_EXITS, | 145 | SYSCALL_EXITS, |
139 | RESVD_INST_EXITS, | 146 | RESVD_INST_EXITS, |
140 | BREAK_INST_EXITS, | 147 | BREAK_INST_EXITS, |
148 | TRAP_INST_EXITS, | ||
149 | MSA_FPE_EXITS, | ||
150 | FPE_EXITS, | ||
151 | MSA_DISABLED_EXITS, | ||
141 | FLUSH_DCACHE_EXITS, | 152 | FLUSH_DCACHE_EXITS, |
142 | MAX_KVM_MIPS_EXIT_TYPES | 153 | MAX_KVM_MIPS_EXIT_TYPES |
143 | }; | 154 | }; |
@@ -206,6 +217,8 @@ struct mips_coproc { | |||
206 | #define MIPS_CP0_CONFIG1_SEL 1 | 217 | #define MIPS_CP0_CONFIG1_SEL 1 |
207 | #define MIPS_CP0_CONFIG2_SEL 2 | 218 | #define MIPS_CP0_CONFIG2_SEL 2 |
208 | #define MIPS_CP0_CONFIG3_SEL 3 | 219 | #define MIPS_CP0_CONFIG3_SEL 3 |
220 | #define MIPS_CP0_CONFIG4_SEL 4 | ||
221 | #define MIPS_CP0_CONFIG5_SEL 5 | ||
209 | 222 | ||
210 | /* Config0 register bits */ | 223 | /* Config0 register bits */ |
211 | #define CP0C0_M 31 | 224 | #define CP0C0_M 31 |
@@ -262,31 +275,6 @@ struct mips_coproc { | |||
262 | #define CP0C3_SM 1 | 275 | #define CP0C3_SM 1 |
263 | #define CP0C3_TL 0 | 276 | #define CP0C3_TL 0 |
264 | 277 | ||
265 | /* Have config1, Cacheable, noncoherent, write-back, write allocate*/ | ||
266 | #define MIPS_CONFIG0 \ | ||
267 | ((1 << CP0C0_M) | (0x3 << CP0C0_K0)) | ||
268 | |||
269 | /* Have config2, no coprocessor2 attached, no MDMX support attached, | ||
270 | no performance counters, watch registers present, | ||
271 | no code compression, EJTAG present, no FPU, no watch registers */ | ||
272 | #define MIPS_CONFIG1 \ | ||
273 | ((1 << CP0C1_M) | \ | ||
274 | (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ | ||
275 | (0 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \ | ||
276 | (0 << CP0C1_FP)) | ||
277 | |||
278 | /* Have config3, no tertiary/secondary caches implemented */ | ||
279 | #define MIPS_CONFIG2 \ | ||
280 | ((1 << CP0C2_M)) | ||
281 | |||
282 | /* No config4, no DSP ASE, no large physaddr (PABITS), | ||
283 | no external interrupt controller, no vectored interrupts, | ||
284 | no 1kb pages, no SmartMIPS ASE, no trace logic */ | ||
285 | #define MIPS_CONFIG3 \ | ||
286 | ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ | ||
287 | (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ | ||
288 | (0 << CP0C3_SM) | (0 << CP0C3_TL)) | ||
289 | |||
290 | /* MMU types, the first four entries have the same layout as the | 278 | /* MMU types, the first four entries have the same layout as the |
291 | CP0C0_MT field. */ | 279 | CP0C0_MT field. */ |
292 | enum mips_mmu_types { | 280 | enum mips_mmu_types { |
@@ -321,7 +309,9 @@ enum mips_mmu_types { | |||
321 | */ | 309 | */ |
322 | #define T_TRAP 13 /* Trap instruction */ | 310 | #define T_TRAP 13 /* Trap instruction */ |
323 | #define T_VCEI 14 /* Virtual coherency exception */ | 311 | #define T_VCEI 14 /* Virtual coherency exception */ |
312 | #define T_MSAFPE 14 /* MSA floating point exception */ | ||
324 | #define T_FPE 15 /* Floating point exception */ | 313 | #define T_FPE 15 /* Floating point exception */ |
314 | #define T_MSADIS 21 /* MSA disabled exception */ | ||
325 | #define T_WATCH 23 /* Watch address reference */ | 315 | #define T_WATCH 23 /* Watch address reference */ |
326 | #define T_VCED 31 /* Virtual coherency data */ | 316 | #define T_VCED 31 /* Virtual coherency data */ |
327 | 317 | ||
@@ -374,6 +364,9 @@ struct kvm_mips_tlb { | |||
374 | long tlb_lo1; | 364 | long tlb_lo1; |
375 | }; | 365 | }; |
376 | 366 | ||
367 | #define KVM_MIPS_FPU_FPU 0x1 | ||
368 | #define KVM_MIPS_FPU_MSA 0x2 | ||
369 | |||
377 | #define KVM_MIPS_GUEST_TLB_SIZE 64 | 370 | #define KVM_MIPS_GUEST_TLB_SIZE 64 |
378 | struct kvm_vcpu_arch { | 371 | struct kvm_vcpu_arch { |
379 | void *host_ebase, *guest_ebase; | 372 | void *host_ebase, *guest_ebase; |
@@ -395,6 +388,8 @@ struct kvm_vcpu_arch { | |||
395 | 388 | ||
396 | /* FPU State */ | 389 | /* FPU State */ |
397 | struct mips_fpu_struct fpu; | 390 | struct mips_fpu_struct fpu; |
391 | /* Which FPU state is loaded (KVM_MIPS_FPU_*) */ | ||
392 | unsigned int fpu_inuse; | ||
398 | 393 | ||
399 | /* COP0 State */ | 394 | /* COP0 State */ |
400 | struct mips_coproc *cop0; | 395 | struct mips_coproc *cop0; |
@@ -441,6 +436,9 @@ struct kvm_vcpu_arch { | |||
441 | 436 | ||
442 | /* WAIT executed */ | 437 | /* WAIT executed */ |
443 | int wait; | 438 | int wait; |
439 | |||
440 | u8 fpu_enabled; | ||
441 | u8 msa_enabled; | ||
444 | }; | 442 | }; |
445 | 443 | ||
446 | 444 | ||
@@ -482,11 +480,15 @@ struct kvm_vcpu_arch { | |||
482 | #define kvm_read_c0_guest_config1(cop0) (cop0->reg[MIPS_CP0_CONFIG][1]) | 480 | #define kvm_read_c0_guest_config1(cop0) (cop0->reg[MIPS_CP0_CONFIG][1]) |
483 | #define kvm_read_c0_guest_config2(cop0) (cop0->reg[MIPS_CP0_CONFIG][2]) | 481 | #define kvm_read_c0_guest_config2(cop0) (cop0->reg[MIPS_CP0_CONFIG][2]) |
484 | #define kvm_read_c0_guest_config3(cop0) (cop0->reg[MIPS_CP0_CONFIG][3]) | 482 | #define kvm_read_c0_guest_config3(cop0) (cop0->reg[MIPS_CP0_CONFIG][3]) |
483 | #define kvm_read_c0_guest_config4(cop0) (cop0->reg[MIPS_CP0_CONFIG][4]) | ||
484 | #define kvm_read_c0_guest_config5(cop0) (cop0->reg[MIPS_CP0_CONFIG][5]) | ||
485 | #define kvm_read_c0_guest_config7(cop0) (cop0->reg[MIPS_CP0_CONFIG][7]) | 485 | #define kvm_read_c0_guest_config7(cop0) (cop0->reg[MIPS_CP0_CONFIG][7]) |
486 | #define kvm_write_c0_guest_config(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][0] = (val)) | 486 | #define kvm_write_c0_guest_config(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][0] = (val)) |
487 | #define kvm_write_c0_guest_config1(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][1] = (val)) | 487 | #define kvm_write_c0_guest_config1(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][1] = (val)) |
488 | #define kvm_write_c0_guest_config2(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][2] = (val)) | 488 | #define kvm_write_c0_guest_config2(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][2] = (val)) |
489 | #define kvm_write_c0_guest_config3(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][3] = (val)) | 489 | #define kvm_write_c0_guest_config3(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][3] = (val)) |
490 | #define kvm_write_c0_guest_config4(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][4] = (val)) | ||
491 | #define kvm_write_c0_guest_config5(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][5] = (val)) | ||
490 | #define kvm_write_c0_guest_config7(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][7] = (val)) | 492 | #define kvm_write_c0_guest_config7(cop0, val) (cop0->reg[MIPS_CP0_CONFIG][7] = (val)) |
491 | #define kvm_read_c0_guest_errorepc(cop0) (cop0->reg[MIPS_CP0_ERROR_PC][0]) | 493 | #define kvm_read_c0_guest_errorepc(cop0) (cop0->reg[MIPS_CP0_ERROR_PC][0]) |
492 | #define kvm_write_c0_guest_errorepc(cop0, val) (cop0->reg[MIPS_CP0_ERROR_PC][0] = (val)) | 494 | #define kvm_write_c0_guest_errorepc(cop0, val) (cop0->reg[MIPS_CP0_ERROR_PC][0] = (val)) |
@@ -567,6 +569,31 @@ static inline void _kvm_atomic_change_c0_guest_reg(unsigned long *reg, | |||
567 | kvm_set_c0_guest_ebase(cop0, ((val) & (change))); \ | 569 | kvm_set_c0_guest_ebase(cop0, ((val) & (change))); \ |
568 | } | 570 | } |
569 | 571 | ||
572 | /* Helpers */ | ||
573 | |||
574 | static inline bool kvm_mips_guest_can_have_fpu(struct kvm_vcpu_arch *vcpu) | ||
575 | { | ||
576 | return (!__builtin_constant_p(cpu_has_fpu) || cpu_has_fpu) && | ||
577 | vcpu->fpu_enabled; | ||
578 | } | ||
579 | |||
580 | static inline bool kvm_mips_guest_has_fpu(struct kvm_vcpu_arch *vcpu) | ||
581 | { | ||
582 | return kvm_mips_guest_can_have_fpu(vcpu) && | ||
583 | kvm_read_c0_guest_config1(vcpu->cop0) & MIPS_CONF1_FP; | ||
584 | } | ||
585 | |||
586 | static inline bool kvm_mips_guest_can_have_msa(struct kvm_vcpu_arch *vcpu) | ||
587 | { | ||
588 | return (!__builtin_constant_p(cpu_has_msa) || cpu_has_msa) && | ||
589 | vcpu->msa_enabled; | ||
590 | } | ||
591 | |||
592 | static inline bool kvm_mips_guest_has_msa(struct kvm_vcpu_arch *vcpu) | ||
593 | { | ||
594 | return kvm_mips_guest_can_have_msa(vcpu) && | ||
595 | kvm_read_c0_guest_config3(vcpu->cop0) & MIPS_CONF3_MSA; | ||
596 | } | ||
570 | 597 | ||
571 | struct kvm_mips_callbacks { | 598 | struct kvm_mips_callbacks { |
572 | int (*handle_cop_unusable)(struct kvm_vcpu *vcpu); | 599 | int (*handle_cop_unusable)(struct kvm_vcpu *vcpu); |
@@ -578,6 +605,10 @@ struct kvm_mips_callbacks { | |||
578 | int (*handle_syscall)(struct kvm_vcpu *vcpu); | 605 | int (*handle_syscall)(struct kvm_vcpu *vcpu); |
579 | int (*handle_res_inst)(struct kvm_vcpu *vcpu); | 606 | int (*handle_res_inst)(struct kvm_vcpu *vcpu); |
580 | int (*handle_break)(struct kvm_vcpu *vcpu); | 607 | int (*handle_break)(struct kvm_vcpu *vcpu); |
608 | int (*handle_trap)(struct kvm_vcpu *vcpu); | ||
609 | int (*handle_msa_fpe)(struct kvm_vcpu *vcpu); | ||
610 | int (*handle_fpe)(struct kvm_vcpu *vcpu); | ||
611 | int (*handle_msa_disabled)(struct kvm_vcpu *vcpu); | ||
581 | int (*vm_init)(struct kvm *kvm); | 612 | int (*vm_init)(struct kvm *kvm); |
582 | int (*vcpu_init)(struct kvm_vcpu *vcpu); | 613 | int (*vcpu_init)(struct kvm_vcpu *vcpu); |
583 | int (*vcpu_setup)(struct kvm_vcpu *vcpu); | 614 | int (*vcpu_setup)(struct kvm_vcpu *vcpu); |
@@ -596,6 +627,8 @@ struct kvm_mips_callbacks { | |||
596 | const struct kvm_one_reg *reg, s64 *v); | 627 | const struct kvm_one_reg *reg, s64 *v); |
597 | int (*set_one_reg)(struct kvm_vcpu *vcpu, | 628 | int (*set_one_reg)(struct kvm_vcpu *vcpu, |
598 | const struct kvm_one_reg *reg, s64 v); | 629 | const struct kvm_one_reg *reg, s64 v); |
630 | int (*vcpu_get_regs)(struct kvm_vcpu *vcpu); | ||
631 | int (*vcpu_set_regs)(struct kvm_vcpu *vcpu); | ||
599 | }; | 632 | }; |
600 | extern struct kvm_mips_callbacks *kvm_mips_callbacks; | 633 | extern struct kvm_mips_callbacks *kvm_mips_callbacks; |
601 | int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks); | 634 | int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks); |
@@ -606,6 +639,19 @@ int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu); | |||
606 | /* Trampoline ASM routine to start running in "Guest" context */ | 639 | /* Trampoline ASM routine to start running in "Guest" context */ |
607 | extern int __kvm_mips_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu); | 640 | extern int __kvm_mips_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu); |
608 | 641 | ||
642 | /* FPU/MSA context management */ | ||
643 | void __kvm_save_fpu(struct kvm_vcpu_arch *vcpu); | ||
644 | void __kvm_restore_fpu(struct kvm_vcpu_arch *vcpu); | ||
645 | void __kvm_restore_fcsr(struct kvm_vcpu_arch *vcpu); | ||
646 | void __kvm_save_msa(struct kvm_vcpu_arch *vcpu); | ||
647 | void __kvm_restore_msa(struct kvm_vcpu_arch *vcpu); | ||
648 | void __kvm_restore_msa_upper(struct kvm_vcpu_arch *vcpu); | ||
649 | void __kvm_restore_msacsr(struct kvm_vcpu_arch *vcpu); | ||
650 | void kvm_own_fpu(struct kvm_vcpu *vcpu); | ||
651 | void kvm_own_msa(struct kvm_vcpu *vcpu); | ||
652 | void kvm_drop_fpu(struct kvm_vcpu *vcpu); | ||
653 | void kvm_lose_fpu(struct kvm_vcpu *vcpu); | ||
654 | |||
609 | /* TLB handling */ | 655 | /* TLB handling */ |
610 | uint32_t kvm_get_kernel_asid(struct kvm_vcpu *vcpu); | 656 | uint32_t kvm_get_kernel_asid(struct kvm_vcpu *vcpu); |
611 | 657 | ||
@@ -711,6 +757,26 @@ extern enum emulation_result kvm_mips_emulate_bp_exc(unsigned long cause, | |||
711 | struct kvm_run *run, | 757 | struct kvm_run *run, |
712 | struct kvm_vcpu *vcpu); | 758 | struct kvm_vcpu *vcpu); |
713 | 759 | ||
760 | extern enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause, | ||
761 | uint32_t *opc, | ||
762 | struct kvm_run *run, | ||
763 | struct kvm_vcpu *vcpu); | ||
764 | |||
765 | extern enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause, | ||
766 | uint32_t *opc, | ||
767 | struct kvm_run *run, | ||
768 | struct kvm_vcpu *vcpu); | ||
769 | |||
770 | extern enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause, | ||
771 | uint32_t *opc, | ||
772 | struct kvm_run *run, | ||
773 | struct kvm_vcpu *vcpu); | ||
774 | |||
775 | extern enum emulation_result kvm_mips_emulate_msadis_exc(unsigned long cause, | ||
776 | uint32_t *opc, | ||
777 | struct kvm_run *run, | ||
778 | struct kvm_vcpu *vcpu); | ||
779 | |||
714 | extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, | 780 | extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, |
715 | struct kvm_run *run); | 781 | struct kvm_run *run); |
716 | 782 | ||
@@ -749,6 +815,11 @@ enum emulation_result kvm_mips_emulate_load(uint32_t inst, | |||
749 | struct kvm_run *run, | 815 | struct kvm_run *run, |
750 | struct kvm_vcpu *vcpu); | 816 | struct kvm_vcpu *vcpu); |
751 | 817 | ||
818 | unsigned int kvm_mips_config1_wrmask(struct kvm_vcpu *vcpu); | ||
819 | unsigned int kvm_mips_config3_wrmask(struct kvm_vcpu *vcpu); | ||
820 | unsigned int kvm_mips_config4_wrmask(struct kvm_vcpu *vcpu); | ||
821 | unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu); | ||
822 | |||
752 | /* Dynamic binary translation */ | 823 | /* Dynamic binary translation */ |
753 | extern int kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc, | 824 | extern int kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc, |
754 | struct kvm_vcpu *vcpu); | 825 | struct kvm_vcpu *vcpu); |
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index b5dcbee01fd7..9b3b48e21c22 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h | |||
@@ -105,7 +105,7 @@ union fpureg { | |||
105 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | 105 | #ifdef CONFIG_CPU_LITTLE_ENDIAN |
106 | # define FPR_IDX(width, idx) (idx) | 106 | # define FPR_IDX(width, idx) (idx) |
107 | #else | 107 | #else |
108 | # define FPR_IDX(width, idx) ((FPU_REG_WIDTH / (width)) - 1 - (idx)) | 108 | # define FPR_IDX(width, idx) ((idx) ^ ((64 / (width)) - 1)) |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | #define BUILD_FPR_ACCESS(width) \ | 111 | #define BUILD_FPR_ACCESS(width) \ |
diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h index 2c04b6d9ff85..6985eb59b085 100644 --- a/arch/mips/include/uapi/asm/kvm.h +++ b/arch/mips/include/uapi/asm/kvm.h | |||
@@ -36,77 +36,85 @@ struct kvm_regs { | |||
36 | 36 | ||
37 | /* | 37 | /* |
38 | * for KVM_GET_FPU and KVM_SET_FPU | 38 | * for KVM_GET_FPU and KVM_SET_FPU |
39 | * | ||
40 | * If Status[FR] is zero (32-bit FPU), the upper 32-bits of the FPRs | ||
41 | * are zero filled. | ||
42 | */ | 39 | */ |
43 | struct kvm_fpu { | 40 | struct kvm_fpu { |
44 | __u64 fpr[32]; | ||
45 | __u32 fir; | ||
46 | __u32 fccr; | ||
47 | __u32 fexr; | ||
48 | __u32 fenr; | ||
49 | __u32 fcsr; | ||
50 | __u32 pad; | ||
51 | }; | 41 | }; |
52 | 42 | ||
53 | 43 | ||
54 | /* | 44 | /* |
55 | * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access CP0 | 45 | * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various |
56 | * registers. The id field is broken down as follows: | 46 | * registers. The id field is broken down as follows: |
57 | * | 47 | * |
58 | * bits[2..0] - Register 'sel' index. | ||
59 | * bits[7..3] - Register 'rd' index. | ||
60 | * bits[15..8] - Must be zero. | ||
61 | * bits[31..16] - 1 -> CP0 registers. | ||
62 | * bits[51..32] - Must be zero. | ||
63 | * bits[63..52] - As per linux/kvm.h | 48 | * bits[63..52] - As per linux/kvm.h |
49 | * bits[51..32] - Must be zero. | ||
50 | * bits[31..16] - Register set. | ||
51 | * | ||
52 | * Register set = 0: GP registers from kvm_regs (see definitions below). | ||
53 | * | ||
54 | * Register set = 1: CP0 registers. | ||
55 | * bits[15..8] - Must be zero. | ||
56 | * bits[7..3] - Register 'rd' index. | ||
57 | * bits[2..0] - Register 'sel' index. | ||
58 | * | ||
59 | * Register set = 2: KVM specific registers (see definitions below). | ||
60 | * | ||
61 | * Register set = 3: FPU / MSA registers (see definitions below). | ||
64 | * | 62 | * |
65 | * Other sets registers may be added in the future. Each set would | 63 | * Other sets registers may be added in the future. Each set would |
66 | * have its own identifier in bits[31..16]. | 64 | * have its own identifier in bits[31..16]. |
67 | * | ||
68 | * The registers defined in struct kvm_regs are also accessible, the | ||
69 | * id values for these are below. | ||
70 | */ | 65 | */ |
71 | 66 | ||
72 | #define KVM_REG_MIPS_R0 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0) | 67 | #define KVM_REG_MIPS_GP (KVM_REG_MIPS | 0x0000000000000000ULL) |
73 | #define KVM_REG_MIPS_R1 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 1) | 68 | #define KVM_REG_MIPS_CP0 (KVM_REG_MIPS | 0x0000000000010000ULL) |
74 | #define KVM_REG_MIPS_R2 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 2) | 69 | #define KVM_REG_MIPS_KVM (KVM_REG_MIPS | 0x0000000000020000ULL) |
75 | #define KVM_REG_MIPS_R3 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 3) | 70 | #define KVM_REG_MIPS_FPU (KVM_REG_MIPS | 0x0000000000030000ULL) |
76 | #define KVM_REG_MIPS_R4 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 4) | 71 | |
77 | #define KVM_REG_MIPS_R5 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 5) | 72 | |
78 | #define KVM_REG_MIPS_R6 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 6) | 73 | /* |
79 | #define KVM_REG_MIPS_R7 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 7) | 74 | * KVM_REG_MIPS_GP - General purpose registers from kvm_regs. |
80 | #define KVM_REG_MIPS_R8 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 8) | 75 | */ |
81 | #define KVM_REG_MIPS_R9 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 9) | 76 | |
82 | #define KVM_REG_MIPS_R10 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 10) | 77 | #define KVM_REG_MIPS_R0 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 0) |
83 | #define KVM_REG_MIPS_R11 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 11) | 78 | #define KVM_REG_MIPS_R1 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 1) |
84 | #define KVM_REG_MIPS_R12 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 12) | 79 | #define KVM_REG_MIPS_R2 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 2) |
85 | #define KVM_REG_MIPS_R13 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 13) | 80 | #define KVM_REG_MIPS_R3 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 3) |
86 | #define KVM_REG_MIPS_R14 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 14) | 81 | #define KVM_REG_MIPS_R4 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 4) |
87 | #define KVM_REG_MIPS_R15 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 15) | 82 | #define KVM_REG_MIPS_R5 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 5) |
88 | #define KVM_REG_MIPS_R16 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 16) | 83 | #define KVM_REG_MIPS_R6 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 6) |
89 | #define KVM_REG_MIPS_R17 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 17) | 84 | #define KVM_REG_MIPS_R7 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 7) |
90 | #define KVM_REG_MIPS_R18 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 18) | 85 | #define KVM_REG_MIPS_R8 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 8) |
91 | #define KVM_REG_MIPS_R19 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 19) | 86 | #define KVM_REG_MIPS_R9 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 9) |
92 | #define KVM_REG_MIPS_R20 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 20) | 87 | #define KVM_REG_MIPS_R10 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 10) |
93 | #define KVM_REG_MIPS_R21 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 21) | 88 | #define KVM_REG_MIPS_R11 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 11) |
94 | #define KVM_REG_MIPS_R22 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 22) | 89 | #define KVM_REG_MIPS_R12 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 12) |
95 | #define KVM_REG_MIPS_R23 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 23) | 90 | #define KVM_REG_MIPS_R13 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 13) |
96 | #define KVM_REG_MIPS_R24 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 24) | 91 | #define KVM_REG_MIPS_R14 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 14) |
97 | #define KVM_REG_MIPS_R25 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 25) | 92 | #define KVM_REG_MIPS_R15 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 15) |
98 | #define KVM_REG_MIPS_R26 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 26) | 93 | #define KVM_REG_MIPS_R16 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 16) |
99 | #define KVM_REG_MIPS_R27 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 27) | 94 | #define KVM_REG_MIPS_R17 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 17) |
100 | #define KVM_REG_MIPS_R28 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 28) | 95 | #define KVM_REG_MIPS_R18 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 18) |
101 | #define KVM_REG_MIPS_R29 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 29) | 96 | #define KVM_REG_MIPS_R19 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 19) |
102 | #define KVM_REG_MIPS_R30 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 30) | 97 | #define KVM_REG_MIPS_R20 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 20) |
103 | #define KVM_REG_MIPS_R31 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 31) | 98 | #define KVM_REG_MIPS_R21 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 21) |
104 | 99 | #define KVM_REG_MIPS_R22 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 22) | |
105 | #define KVM_REG_MIPS_HI (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 32) | 100 | #define KVM_REG_MIPS_R23 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 23) |
106 | #define KVM_REG_MIPS_LO (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 33) | 101 | #define KVM_REG_MIPS_R24 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 24) |
107 | #define KVM_REG_MIPS_PC (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 34) | 102 | #define KVM_REG_MIPS_R25 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 25) |
108 | 103 | #define KVM_REG_MIPS_R26 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 26) | |
109 | /* KVM specific control registers */ | 104 | #define KVM_REG_MIPS_R27 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 27) |
105 | #define KVM_REG_MIPS_R28 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 28) | ||
106 | #define KVM_REG_MIPS_R29 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 29) | ||
107 | #define KVM_REG_MIPS_R30 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 30) | ||
108 | #define KVM_REG_MIPS_R31 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 31) | ||
109 | |||
110 | #define KVM_REG_MIPS_HI (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 32) | ||
111 | #define KVM_REG_MIPS_LO (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 33) | ||
112 | #define KVM_REG_MIPS_PC (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 34) | ||
113 | |||
114 | |||
115 | /* | ||
116 | * KVM_REG_MIPS_KVM - KVM specific control registers. | ||
117 | */ | ||
110 | 118 | ||
111 | /* | 119 | /* |
112 | * CP0_Count control | 120 | * CP0_Count control |
@@ -118,8 +126,7 @@ struct kvm_fpu { | |||
118 | * safely without losing time or guest timer interrupts. | 126 | * safely without losing time or guest timer interrupts. |
119 | * Other: Reserved, do not change. | 127 | * Other: Reserved, do not change. |
120 | */ | 128 | */ |
121 | #define KVM_REG_MIPS_COUNT_CTL (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \ | 129 | #define KVM_REG_MIPS_COUNT_CTL (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 0) |
122 | 0x20000 | 0) | ||
123 | #define KVM_REG_MIPS_COUNT_CTL_DC 0x00000001 | 130 | #define KVM_REG_MIPS_COUNT_CTL_DC 0x00000001 |
124 | 131 | ||
125 | /* | 132 | /* |
@@ -131,15 +138,46 @@ struct kvm_fpu { | |||
131 | * emulated. | 138 | * emulated. |
132 | * Modifications to times in the future are rejected. | 139 | * Modifications to times in the future are rejected. |
133 | */ | 140 | */ |
134 | #define KVM_REG_MIPS_COUNT_RESUME (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \ | 141 | #define KVM_REG_MIPS_COUNT_RESUME (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 1) |
135 | 0x20000 | 1) | ||
136 | /* | 142 | /* |
137 | * CP0_Count rate in Hz | 143 | * CP0_Count rate in Hz |
138 | * Specifies the rate of the CP0_Count timer in Hz. Modifications occur without | 144 | * Specifies the rate of the CP0_Count timer in Hz. Modifications occur without |
139 | * discontinuities in CP0_Count. | 145 | * discontinuities in CP0_Count. |
140 | */ | 146 | */ |
141 | #define KVM_REG_MIPS_COUNT_HZ (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \ | 147 | #define KVM_REG_MIPS_COUNT_HZ (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 2) |
142 | 0x20000 | 2) | 148 | |
149 | |||
150 | /* | ||
151 | * KVM_REG_MIPS_FPU - Floating Point and MIPS SIMD Architecture (MSA) registers. | ||
152 | * | ||
153 | * bits[15..8] - Register subset (see definitions below). | ||
154 | * bits[7..5] - Must be zero. | ||
155 | * bits[4..0] - Register number within register subset. | ||
156 | */ | ||
157 | |||
158 | #define KVM_REG_MIPS_FPR (KVM_REG_MIPS_FPU | 0x0000000000000000ULL) | ||
159 | #define KVM_REG_MIPS_FCR (KVM_REG_MIPS_FPU | 0x0000000000000100ULL) | ||
160 | #define KVM_REG_MIPS_MSACR (KVM_REG_MIPS_FPU | 0x0000000000000200ULL) | ||
161 | |||
162 | /* | ||
163 | * KVM_REG_MIPS_FPR - Floating point / Vector registers. | ||
164 | */ | ||
165 | #define KVM_REG_MIPS_FPR_32(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U32 | (n)) | ||
166 | #define KVM_REG_MIPS_FPR_64(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U64 | (n)) | ||
167 | #define KVM_REG_MIPS_VEC_128(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U128 | (n)) | ||
168 | |||
169 | /* | ||
170 | * KVM_REG_MIPS_FCR - Floating point control registers. | ||
171 | */ | ||
172 | #define KVM_REG_MIPS_FCR_IR (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 0) | ||
173 | #define KVM_REG_MIPS_FCR_CSR (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 31) | ||
174 | |||
175 | /* | ||
176 | * KVM_REG_MIPS_MSACR - MIPS SIMD Architecture (MSA) control registers. | ||
177 | */ | ||
178 | #define KVM_REG_MIPS_MSA_IR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 | 0) | ||
179 | #define KVM_REG_MIPS_MSA_CSR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 | 1) | ||
180 | |||
143 | 181 | ||
144 | /* | 182 | /* |
145 | * KVM MIPS specific structures and definitions | 183 | * KVM MIPS specific structures and definitions |
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 750d67ac41e9..e59fd7cfac9e 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -167,72 +167,6 @@ void output_thread_fpu_defines(void) | |||
167 | OFFSET(THREAD_FPR30, task_struct, thread.fpu.fpr[30]); | 167 | OFFSET(THREAD_FPR30, task_struct, thread.fpu.fpr[30]); |
168 | OFFSET(THREAD_FPR31, task_struct, thread.fpu.fpr[31]); | 168 | OFFSET(THREAD_FPR31, task_struct, thread.fpu.fpr[31]); |
169 | 169 | ||
170 | /* the least significant 64 bits of each FP register */ | ||
171 | OFFSET(THREAD_FPR0_LS64, task_struct, | ||
172 | thread.fpu.fpr[0].val64[FPR_IDX(64, 0)]); | ||
173 | OFFSET(THREAD_FPR1_LS64, task_struct, | ||
174 | thread.fpu.fpr[1].val64[FPR_IDX(64, 0)]); | ||
175 | OFFSET(THREAD_FPR2_LS64, task_struct, | ||
176 | thread.fpu.fpr[2].val64[FPR_IDX(64, 0)]); | ||
177 | OFFSET(THREAD_FPR3_LS64, task_struct, | ||
178 | thread.fpu.fpr[3].val64[FPR_IDX(64, 0)]); | ||
179 | OFFSET(THREAD_FPR4_LS64, task_struct, | ||
180 | thread.fpu.fpr[4].val64[FPR_IDX(64, 0)]); | ||
181 | OFFSET(THREAD_FPR5_LS64, task_struct, | ||
182 | thread.fpu.fpr[5].val64[FPR_IDX(64, 0)]); | ||
183 | OFFSET(THREAD_FPR6_LS64, task_struct, | ||
184 | thread.fpu.fpr[6].val64[FPR_IDX(64, 0)]); | ||
185 | OFFSET(THREAD_FPR7_LS64, task_struct, | ||
186 | thread.fpu.fpr[7].val64[FPR_IDX(64, 0)]); | ||
187 | OFFSET(THREAD_FPR8_LS64, task_struct, | ||
188 | thread.fpu.fpr[8].val64[FPR_IDX(64, 0)]); | ||
189 | OFFSET(THREAD_FPR9_LS64, task_struct, | ||
190 | thread.fpu.fpr[9].val64[FPR_IDX(64, 0)]); | ||
191 | OFFSET(THREAD_FPR10_LS64, task_struct, | ||
192 | thread.fpu.fpr[10].val64[FPR_IDX(64, 0)]); | ||
193 | OFFSET(THREAD_FPR11_LS64, task_struct, | ||
194 | thread.fpu.fpr[11].val64[FPR_IDX(64, 0)]); | ||
195 | OFFSET(THREAD_FPR12_LS64, task_struct, | ||
196 | thread.fpu.fpr[12].val64[FPR_IDX(64, 0)]); | ||
197 | OFFSET(THREAD_FPR13_LS64, task_struct, | ||
198 | thread.fpu.fpr[13].val64[FPR_IDX(64, 0)]); | ||
199 | OFFSET(THREAD_FPR14_LS64, task_struct, | ||
200 | thread.fpu.fpr[14].val64[FPR_IDX(64, 0)]); | ||
201 | OFFSET(THREAD_FPR15_LS64, task_struct, | ||
202 | thread.fpu.fpr[15].val64[FPR_IDX(64, 0)]); | ||
203 | OFFSET(THREAD_FPR16_LS64, task_struct, | ||
204 | thread.fpu.fpr[16].val64[FPR_IDX(64, 0)]); | ||
205 | OFFSET(THREAD_FPR17_LS64, task_struct, | ||
206 | thread.fpu.fpr[17].val64[FPR_IDX(64, 0)]); | ||
207 | OFFSET(THREAD_FPR18_LS64, task_struct, | ||
208 | thread.fpu.fpr[18].val64[FPR_IDX(64, 0)]); | ||
209 | OFFSET(THREAD_FPR19_LS64, task_struct, | ||
210 | thread.fpu.fpr[19].val64[FPR_IDX(64, 0)]); | ||
211 | OFFSET(THREAD_FPR20_LS64, task_struct, | ||
212 | thread.fpu.fpr[20].val64[FPR_IDX(64, 0)]); | ||
213 | OFFSET(THREAD_FPR21_LS64, task_struct, | ||
214 | thread.fpu.fpr[21].val64[FPR_IDX(64, 0)]); | ||
215 | OFFSET(THREAD_FPR22_LS64, task_struct, | ||
216 | thread.fpu.fpr[22].val64[FPR_IDX(64, 0)]); | ||
217 | OFFSET(THREAD_FPR23_LS64, task_struct, | ||
218 | thread.fpu.fpr[23].val64[FPR_IDX(64, 0)]); | ||
219 | OFFSET(THREAD_FPR24_LS64, task_struct, | ||
220 | thread.fpu.fpr[24].val64[FPR_IDX(64, 0)]); | ||
221 | OFFSET(THREAD_FPR25_LS64, task_struct, | ||
222 | thread.fpu.fpr[25].val64[FPR_IDX(64, 0)]); | ||
223 | OFFSET(THREAD_FPR26_LS64, task_struct, | ||
224 | thread.fpu.fpr[26].val64[FPR_IDX(64, 0)]); | ||
225 | OFFSET(THREAD_FPR27_LS64, task_struct, | ||
226 | thread.fpu.fpr[27].val64[FPR_IDX(64, 0)]); | ||
227 | OFFSET(THREAD_FPR28_LS64, task_struct, | ||
228 | thread.fpu.fpr[28].val64[FPR_IDX(64, 0)]); | ||
229 | OFFSET(THREAD_FPR29_LS64, task_struct, | ||
230 | thread.fpu.fpr[29].val64[FPR_IDX(64, 0)]); | ||
231 | OFFSET(THREAD_FPR30_LS64, task_struct, | ||
232 | thread.fpu.fpr[30].val64[FPR_IDX(64, 0)]); | ||
233 | OFFSET(THREAD_FPR31_LS64, task_struct, | ||
234 | thread.fpu.fpr[31].val64[FPR_IDX(64, 0)]); | ||
235 | |||
236 | OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31); | 170 | OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31); |
237 | OFFSET(THREAD_MSA_CSR, task_struct, thread.fpu.msacsr); | 171 | OFFSET(THREAD_MSA_CSR, task_struct, thread.fpu.msacsr); |
238 | BLANK(); | 172 | BLANK(); |
@@ -470,6 +404,45 @@ void output_kvm_defines(void) | |||
470 | OFFSET(VCPU_LO, kvm_vcpu_arch, lo); | 404 | OFFSET(VCPU_LO, kvm_vcpu_arch, lo); |
471 | OFFSET(VCPU_HI, kvm_vcpu_arch, hi); | 405 | OFFSET(VCPU_HI, kvm_vcpu_arch, hi); |
472 | OFFSET(VCPU_PC, kvm_vcpu_arch, pc); | 406 | OFFSET(VCPU_PC, kvm_vcpu_arch, pc); |
407 | BLANK(); | ||
408 | |||
409 | OFFSET(VCPU_FPR0, kvm_vcpu_arch, fpu.fpr[0]); | ||
410 | OFFSET(VCPU_FPR1, kvm_vcpu_arch, fpu.fpr[1]); | ||
411 | OFFSET(VCPU_FPR2, kvm_vcpu_arch, fpu.fpr[2]); | ||
412 | OFFSET(VCPU_FPR3, kvm_vcpu_arch, fpu.fpr[3]); | ||
413 | OFFSET(VCPU_FPR4, kvm_vcpu_arch, fpu.fpr[4]); | ||
414 | OFFSET(VCPU_FPR5, kvm_vcpu_arch, fpu.fpr[5]); | ||
415 | OFFSET(VCPU_FPR6, kvm_vcpu_arch, fpu.fpr[6]); | ||
416 | OFFSET(VCPU_FPR7, kvm_vcpu_arch, fpu.fpr[7]); | ||
417 | OFFSET(VCPU_FPR8, kvm_vcpu_arch, fpu.fpr[8]); | ||
418 | OFFSET(VCPU_FPR9, kvm_vcpu_arch, fpu.fpr[9]); | ||
419 | OFFSET(VCPU_FPR10, kvm_vcpu_arch, fpu.fpr[10]); | ||
420 | OFFSET(VCPU_FPR11, kvm_vcpu_arch, fpu.fpr[11]); | ||
421 | OFFSET(VCPU_FPR12, kvm_vcpu_arch, fpu.fpr[12]); | ||
422 | OFFSET(VCPU_FPR13, kvm_vcpu_arch, fpu.fpr[13]); | ||
423 | OFFSET(VCPU_FPR14, kvm_vcpu_arch, fpu.fpr[14]); | ||
424 | OFFSET(VCPU_FPR15, kvm_vcpu_arch, fpu.fpr[15]); | ||
425 | OFFSET(VCPU_FPR16, kvm_vcpu_arch, fpu.fpr[16]); | ||
426 | OFFSET(VCPU_FPR17, kvm_vcpu_arch, fpu.fpr[17]); | ||
427 | OFFSET(VCPU_FPR18, kvm_vcpu_arch, fpu.fpr[18]); | ||
428 | OFFSET(VCPU_FPR19, kvm_vcpu_arch, fpu.fpr[19]); | ||
429 | OFFSET(VCPU_FPR20, kvm_vcpu_arch, fpu.fpr[20]); | ||
430 | OFFSET(VCPU_FPR21, kvm_vcpu_arch, fpu.fpr[21]); | ||
431 | OFFSET(VCPU_FPR22, kvm_vcpu_arch, fpu.fpr[22]); | ||
432 | OFFSET(VCPU_FPR23, kvm_vcpu_arch, fpu.fpr[23]); | ||
433 | OFFSET(VCPU_FPR24, kvm_vcpu_arch, fpu.fpr[24]); | ||
434 | OFFSET(VCPU_FPR25, kvm_vcpu_arch, fpu.fpr[25]); | ||
435 | OFFSET(VCPU_FPR26, kvm_vcpu_arch, fpu.fpr[26]); | ||
436 | OFFSET(VCPU_FPR27, kvm_vcpu_arch, fpu.fpr[27]); | ||
437 | OFFSET(VCPU_FPR28, kvm_vcpu_arch, fpu.fpr[28]); | ||
438 | OFFSET(VCPU_FPR29, kvm_vcpu_arch, fpu.fpr[29]); | ||
439 | OFFSET(VCPU_FPR30, kvm_vcpu_arch, fpu.fpr[30]); | ||
440 | OFFSET(VCPU_FPR31, kvm_vcpu_arch, fpu.fpr[31]); | ||
441 | |||
442 | OFFSET(VCPU_FCR31, kvm_vcpu_arch, fpu.fcr31); | ||
443 | OFFSET(VCPU_MSA_CSR, kvm_vcpu_arch, fpu.msacsr); | ||
444 | BLANK(); | ||
445 | |||
473 | OFFSET(VCPU_COP0, kvm_vcpu_arch, cop0); | 446 | OFFSET(VCPU_COP0, kvm_vcpu_arch, cop0); |
474 | OFFSET(VCPU_GUEST_KERNEL_ASID, kvm_vcpu_arch, guest_kernel_asid); | 447 | OFFSET(VCPU_GUEST_KERNEL_ASID, kvm_vcpu_arch, guest_kernel_asid); |
475 | OFFSET(VCPU_GUEST_USER_ASID, kvm_vcpu_arch, guest_user_asid); | 448 | OFFSET(VCPU_GUEST_USER_ASID, kvm_vcpu_arch, guest_user_asid); |
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 2ebaabe3af15..af42e7003f12 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -360,12 +360,15 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
360 | .set mips1 | 360 | .set mips1 |
361 | SET_HARDFLOAT | 361 | SET_HARDFLOAT |
362 | cfc1 a1, fcr31 | 362 | cfc1 a1, fcr31 |
363 | li a2, ~(0x3f << 12) | ||
364 | and a2, a1 | ||
365 | ctc1 a2, fcr31 | ||
366 | .set pop | 363 | .set pop |
367 | TRACE_IRQS_ON | 364 | CLI |
368 | STI | 365 | TRACE_IRQS_OFF |
366 | .endm | ||
367 | |||
368 | .macro __build_clear_msa_fpe | ||
369 | _cfcmsa a1, MSA_CSR | ||
370 | CLI | ||
371 | TRACE_IRQS_OFF | ||
369 | .endm | 372 | .endm |
370 | 373 | ||
371 | .macro __build_clear_ade | 374 | .macro __build_clear_ade |
@@ -426,7 +429,7 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
426 | BUILD_HANDLER cpu cpu sti silent /* #11 */ | 429 | BUILD_HANDLER cpu cpu sti silent /* #11 */ |
427 | BUILD_HANDLER ov ov sti silent /* #12 */ | 430 | BUILD_HANDLER ov ov sti silent /* #12 */ |
428 | BUILD_HANDLER tr tr sti silent /* #13 */ | 431 | BUILD_HANDLER tr tr sti silent /* #13 */ |
429 | BUILD_HANDLER msa_fpe msa_fpe sti silent /* #14 */ | 432 | BUILD_HANDLER msa_fpe msa_fpe msa_fpe silent /* #14 */ |
430 | BUILD_HANDLER fpe fpe fpe silent /* #15 */ | 433 | BUILD_HANDLER fpe fpe fpe silent /* #15 */ |
431 | BUILD_HANDLER ftlb ftlb none silent /* #16 */ | 434 | BUILD_HANDLER ftlb ftlb none silent /* #16 */ |
432 | BUILD_HANDLER msa msa sti silent /* #21 */ | 435 | BUILD_HANDLER msa msa sti silent /* #21 */ |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 510452812594..7da6e324dd35 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -46,6 +46,26 @@ | |||
46 | #define CREATE_TRACE_POINTS | 46 | #define CREATE_TRACE_POINTS |
47 | #include <trace/events/syscalls.h> | 47 | #include <trace/events/syscalls.h> |
48 | 48 | ||
49 | static void init_fp_ctx(struct task_struct *target) | ||
50 | { | ||
51 | /* If FP has been used then the target already has context */ | ||
52 | if (tsk_used_math(target)) | ||
53 | return; | ||
54 | |||
55 | /* Begin with data registers set to all 1s... */ | ||
56 | memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr)); | ||
57 | |||
58 | /* ...and FCSR zeroed */ | ||
59 | target->thread.fpu.fcr31 = 0; | ||
60 | |||
61 | /* | ||
62 | * Record that the target has "used" math, such that the context | ||
63 | * just initialised, and any modifications made by the caller, | ||
64 | * aren't discarded. | ||
65 | */ | ||
66 | set_stopped_child_used_math(target); | ||
67 | } | ||
68 | |||
49 | /* | 69 | /* |
50 | * Called by kernel/ptrace.c when detaching.. | 70 | * Called by kernel/ptrace.c when detaching.. |
51 | * | 71 | * |
@@ -142,6 +162,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data) | |||
142 | if (!access_ok(VERIFY_READ, data, 33 * 8)) | 162 | if (!access_ok(VERIFY_READ, data, 33 * 8)) |
143 | return -EIO; | 163 | return -EIO; |
144 | 164 | ||
165 | init_fp_ctx(child); | ||
145 | fregs = get_fpu_regs(child); | 166 | fregs = get_fpu_regs(child); |
146 | 167 | ||
147 | for (i = 0; i < 32; i++) { | 168 | for (i = 0; i < 32; i++) { |
@@ -439,6 +460,8 @@ static int fpr_set(struct task_struct *target, | |||
439 | 460 | ||
440 | /* XXX fcr31 */ | 461 | /* XXX fcr31 */ |
441 | 462 | ||
463 | init_fp_ctx(target); | ||
464 | |||
442 | if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) | 465 | if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) |
443 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 466 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
444 | &target->thread.fpu, | 467 | &target->thread.fpu, |
@@ -660,12 +683,7 @@ long arch_ptrace(struct task_struct *child, long request, | |||
660 | case FPR_BASE ... FPR_BASE + 31: { | 683 | case FPR_BASE ... FPR_BASE + 31: { |
661 | union fpureg *fregs = get_fpu_regs(child); | 684 | union fpureg *fregs = get_fpu_regs(child); |
662 | 685 | ||
663 | if (!tsk_used_math(child)) { | 686 | init_fp_ctx(child); |
664 | /* FP not yet used */ | ||
665 | memset(&child->thread.fpu, ~0, | ||
666 | sizeof(child->thread.fpu)); | ||
667 | child->thread.fpu.fcr31 = 0; | ||
668 | } | ||
669 | #ifdef CONFIG_32BIT | 687 | #ifdef CONFIG_32BIT |
670 | if (test_thread_flag(TIF_32BIT_FPREGS)) { | 688 | if (test_thread_flag(TIF_32BIT_FPREGS)) { |
671 | /* | 689 | /* |
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 676c5030a953..1d88af26ba82 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S | |||
@@ -34,7 +34,6 @@ | |||
34 | .endm | 34 | .endm |
35 | 35 | ||
36 | .set noreorder | 36 | .set noreorder |
37 | .set MIPS_ISA_ARCH_LEVEL_RAW | ||
38 | 37 | ||
39 | LEAF(_save_fp_context) | 38 | LEAF(_save_fp_context) |
40 | .set push | 39 | .set push |
@@ -103,6 +102,7 @@ LEAF(_save_fp_context) | |||
103 | /* Save 32-bit process floating point context */ | 102 | /* Save 32-bit process floating point context */ |
104 | LEAF(_save_fp_context32) | 103 | LEAF(_save_fp_context32) |
105 | .set push | 104 | .set push |
105 | .set MIPS_ISA_ARCH_LEVEL_RAW | ||
106 | SET_HARDFLOAT | 106 | SET_HARDFLOAT |
107 | cfc1 t1, fcr31 | 107 | cfc1 t1, fcr31 |
108 | 108 | ||
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 33984c04b60b..5b4d711f878d 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -701,6 +701,13 @@ asmlinkage void do_ov(struct pt_regs *regs) | |||
701 | 701 | ||
702 | int process_fpemu_return(int sig, void __user *fault_addr) | 702 | int process_fpemu_return(int sig, void __user *fault_addr) |
703 | { | 703 | { |
704 | /* | ||
705 | * We can't allow the emulated instruction to leave any of the cause | ||
706 | * bits set in FCSR. If they were then the kernel would take an FP | ||
707 | * exception when restoring FP context. | ||
708 | */ | ||
709 | current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; | ||
710 | |||
704 | if (sig == SIGSEGV || sig == SIGBUS) { | 711 | if (sig == SIGSEGV || sig == SIGBUS) { |
705 | struct siginfo si = {0}; | 712 | struct siginfo si = {0}; |
706 | si.si_addr = fault_addr; | 713 | si.si_addr = fault_addr; |
@@ -781,6 +788,11 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
781 | if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), | 788 | if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), |
782 | SIGFPE) == NOTIFY_STOP) | 789 | SIGFPE) == NOTIFY_STOP) |
783 | goto out; | 790 | goto out; |
791 | |||
792 | /* Clear FCSR.Cause before enabling interrupts */ | ||
793 | write_32bit_cp1_register(CP1_STATUS, fcr31 & ~FPU_CSR_ALL_X); | ||
794 | local_irq_enable(); | ||
795 | |||
784 | die_if_kernel("FP exception in kernel code", regs); | 796 | die_if_kernel("FP exception in kernel code", regs); |
785 | 797 | ||
786 | if (fcr31 & FPU_CSR_UNI_X) { | 798 | if (fcr31 & FPU_CSR_UNI_X) { |
@@ -804,18 +816,12 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
804 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, | 816 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, |
805 | &fault_addr); | 817 | &fault_addr); |
806 | 818 | ||
807 | /* | 819 | /* If something went wrong, signal */ |
808 | * We can't allow the emulated instruction to leave any of | 820 | process_fpemu_return(sig, fault_addr); |
809 | * the cause bit set in $fcr31. | ||
810 | */ | ||
811 | current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; | ||
812 | 821 | ||
813 | /* Restore the hardware register state */ | 822 | /* Restore the hardware register state */ |
814 | own_fpu(1); /* Using the FPU again. */ | 823 | own_fpu(1); /* Using the FPU again. */ |
815 | 824 | ||
816 | /* If something went wrong, signal */ | ||
817 | process_fpemu_return(sig, fault_addr); | ||
818 | |||
819 | goto out; | 825 | goto out; |
820 | } else if (fcr31 & FPU_CSR_INV_X) | 826 | } else if (fcr31 & FPU_CSR_INV_X) |
821 | info.si_code = FPE_FLTINV; | 827 | info.si_code = FPE_FLTINV; |
@@ -1392,13 +1398,22 @@ out: | |||
1392 | exception_exit(prev_state); | 1398 | exception_exit(prev_state); |
1393 | } | 1399 | } |
1394 | 1400 | ||
1395 | asmlinkage void do_msa_fpe(struct pt_regs *regs) | 1401 | asmlinkage void do_msa_fpe(struct pt_regs *regs, unsigned int msacsr) |
1396 | { | 1402 | { |
1397 | enum ctx_state prev_state; | 1403 | enum ctx_state prev_state; |
1398 | 1404 | ||
1399 | prev_state = exception_enter(); | 1405 | prev_state = exception_enter(); |
1406 | if (notify_die(DIE_MSAFP, "MSA FP exception", regs, 0, | ||
1407 | regs_to_trapnr(regs), SIGFPE) == NOTIFY_STOP) | ||
1408 | goto out; | ||
1409 | |||
1410 | /* Clear MSACSR.Cause before enabling interrupts */ | ||
1411 | write_msa_csr(msacsr & ~MSA_CSR_CAUSEF); | ||
1412 | local_irq_enable(); | ||
1413 | |||
1400 | die_if_kernel("do_msa_fpe invoked from kernel context!", regs); | 1414 | die_if_kernel("do_msa_fpe invoked from kernel context!", regs); |
1401 | force_sig(SIGFPE, current); | 1415 | force_sig(SIGFPE, current); |
1416 | out: | ||
1402 | exception_exit(prev_state); | 1417 | exception_exit(prev_state); |
1403 | } | 1418 | } |
1404 | 1419 | ||
diff --git a/arch/mips/kvm/Makefile b/arch/mips/kvm/Makefile index 401fe027c261..637ebbebd549 100644 --- a/arch/mips/kvm/Makefile +++ b/arch/mips/kvm/Makefile | |||
@@ -1,13 +1,15 @@ | |||
1 | # Makefile for KVM support for MIPS | 1 | # Makefile for KVM support for MIPS |
2 | # | 2 | # |
3 | 3 | ||
4 | common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) | 4 | common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) |
5 | 5 | ||
6 | EXTRA_CFLAGS += -Ivirt/kvm -Iarch/mips/kvm | 6 | EXTRA_CFLAGS += -Ivirt/kvm -Iarch/mips/kvm |
7 | 7 | ||
8 | kvm-objs := $(common-objs) mips.o emulate.o locore.o \ | 8 | common-objs-$(CONFIG_CPU_HAS_MSA) += msa.o |
9 | |||
10 | kvm-objs := $(common-objs-y) mips.o emulate.o locore.o \ | ||
9 | interrupt.o stats.o commpage.o \ | 11 | interrupt.o stats.o commpage.o \ |
10 | dyntrans.o trap_emul.o | 12 | dyntrans.o trap_emul.o fpu.o |
11 | 13 | ||
12 | obj-$(CONFIG_KVM) += kvm.o | 14 | obj-$(CONFIG_KVM) += kvm.o |
13 | obj-y += callback.o tlb.o | 15 | obj-y += callback.o tlb.o |
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index fb3e8dfd1ff6..6230f376a44e 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c | |||
@@ -884,6 +884,84 @@ enum emulation_result kvm_mips_emul_tlbp(struct kvm_vcpu *vcpu) | |||
884 | return EMULATE_DONE; | 884 | return EMULATE_DONE; |
885 | } | 885 | } |
886 | 886 | ||
887 | /** | ||
888 | * kvm_mips_config1_wrmask() - Find mask of writable bits in guest Config1 | ||
889 | * @vcpu: Virtual CPU. | ||
890 | * | ||
891 | * Finds the mask of bits which are writable in the guest's Config1 CP0 | ||
892 | * register, by userland (currently read-only to the guest). | ||
893 | */ | ||
894 | unsigned int kvm_mips_config1_wrmask(struct kvm_vcpu *vcpu) | ||
895 | { | ||
896 | unsigned int mask = 0; | ||
897 | |||
898 | /* Permit FPU to be present if FPU is supported */ | ||
899 | if (kvm_mips_guest_can_have_fpu(&vcpu->arch)) | ||
900 | mask |= MIPS_CONF1_FP; | ||
901 | |||
902 | return mask; | ||
903 | } | ||
904 | |||
905 | /** | ||
906 | * kvm_mips_config3_wrmask() - Find mask of writable bits in guest Config3 | ||
907 | * @vcpu: Virtual CPU. | ||
908 | * | ||
909 | * Finds the mask of bits which are writable in the guest's Config3 CP0 | ||
910 | * register, by userland (currently read-only to the guest). | ||
911 | */ | ||
912 | unsigned int kvm_mips_config3_wrmask(struct kvm_vcpu *vcpu) | ||
913 | { | ||
914 | /* Config4 is optional */ | ||
915 | unsigned int mask = MIPS_CONF_M; | ||
916 | |||
917 | /* Permit MSA to be present if MSA is supported */ | ||
918 | if (kvm_mips_guest_can_have_msa(&vcpu->arch)) | ||
919 | mask |= MIPS_CONF3_MSA; | ||
920 | |||
921 | return mask; | ||
922 | } | ||
923 | |||
924 | /** | ||
925 | * kvm_mips_config4_wrmask() - Find mask of writable bits in guest Config4 | ||
926 | * @vcpu: Virtual CPU. | ||
927 | * | ||
928 | * Finds the mask of bits which are writable in the guest's Config4 CP0 | ||
929 | * register, by userland (currently read-only to the guest). | ||
930 | */ | ||
931 | unsigned int kvm_mips_config4_wrmask(struct kvm_vcpu *vcpu) | ||
932 | { | ||
933 | /* Config5 is optional */ | ||
934 | return MIPS_CONF_M; | ||
935 | } | ||
936 | |||
937 | /** | ||
938 | * kvm_mips_config5_wrmask() - Find mask of writable bits in guest Config5 | ||
939 | * @vcpu: Virtual CPU. | ||
940 | * | ||
941 | * Finds the mask of bits which are writable in the guest's Config5 CP0 | ||
942 | * register, by the guest itself. | ||
943 | */ | ||
944 | unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu) | ||
945 | { | ||
946 | unsigned int mask = 0; | ||
947 | |||
948 | /* Permit MSAEn changes if MSA supported and enabled */ | ||
949 | if (kvm_mips_guest_has_msa(&vcpu->arch)) | ||
950 | mask |= MIPS_CONF5_MSAEN; | ||
951 | |||
952 | /* | ||
953 | * Permit guest FPU mode changes if FPU is enabled and the relevant | ||
954 | * feature exists according to FIR register. | ||
955 | */ | ||
956 | if (kvm_mips_guest_has_fpu(&vcpu->arch)) { | ||
957 | if (cpu_has_fre) | ||
958 | mask |= MIPS_CONF5_FRE; | ||
959 | /* We don't support UFR or UFE */ | ||
960 | } | ||
961 | |||
962 | return mask; | ||
963 | } | ||
964 | |||
887 | enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, | 965 | enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, |
888 | uint32_t cause, struct kvm_run *run, | 966 | uint32_t cause, struct kvm_run *run, |
889 | struct kvm_vcpu *vcpu) | 967 | struct kvm_vcpu *vcpu) |
@@ -1021,18 +1099,114 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, | |||
1021 | kvm_mips_write_compare(vcpu, | 1099 | kvm_mips_write_compare(vcpu, |
1022 | vcpu->arch.gprs[rt]); | 1100 | vcpu->arch.gprs[rt]); |
1023 | } else if ((rd == MIPS_CP0_STATUS) && (sel == 0)) { | 1101 | } else if ((rd == MIPS_CP0_STATUS) && (sel == 0)) { |
1024 | kvm_write_c0_guest_status(cop0, | 1102 | unsigned int old_val, val, change; |
1025 | vcpu->arch.gprs[rt]); | 1103 | |
1104 | old_val = kvm_read_c0_guest_status(cop0); | ||
1105 | val = vcpu->arch.gprs[rt]; | ||
1106 | change = val ^ old_val; | ||
1107 | |||
1108 | /* Make sure that the NMI bit is never set */ | ||
1109 | val &= ~ST0_NMI; | ||
1110 | |||
1111 | /* | ||
1112 | * Don't allow CU1 or FR to be set unless FPU | ||
1113 | * capability enabled and exists in guest | ||
1114 | * configuration. | ||
1115 | */ | ||
1116 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
1117 | val &= ~(ST0_CU1 | ST0_FR); | ||
1118 | |||
1119 | /* | ||
1120 | * Also don't allow FR to be set if host doesn't | ||
1121 | * support it. | ||
1122 | */ | ||
1123 | if (!(current_cpu_data.fpu_id & MIPS_FPIR_F64)) | ||
1124 | val &= ~ST0_FR; | ||
1125 | |||
1126 | |||
1127 | /* Handle changes in FPU mode */ | ||
1128 | preempt_disable(); | ||
1129 | |||
1130 | /* | ||
1131 | * FPU and Vector register state is made | ||
1132 | * UNPREDICTABLE by a change of FR, so don't | ||
1133 | * even bother saving it. | ||
1134 | */ | ||
1135 | if (change & ST0_FR) | ||
1136 | kvm_drop_fpu(vcpu); | ||
1137 | |||
1138 | /* | ||
1139 | * If MSA state is already live, it is undefined | ||
1140 | * how it interacts with FR=0 FPU state, and we | ||
1141 | * don't want to hit reserved instruction | ||
1142 | * exceptions trying to save the MSA state later | ||
1143 | * when CU=1 && FR=1, so play it safe and save | ||
1144 | * it first. | ||
1145 | */ | ||
1146 | if (change & ST0_CU1 && !(val & ST0_FR) && | ||
1147 | vcpu->arch.fpu_inuse & KVM_MIPS_FPU_MSA) | ||
1148 | kvm_lose_fpu(vcpu); | ||
1149 | |||
1026 | /* | 1150 | /* |
1027 | * Make sure that CU1 and NMI bits are | 1151 | * Propagate CU1 (FPU enable) changes |
1028 | * never set | 1152 | * immediately if the FPU context is already |
1153 | * loaded. When disabling we leave the context | ||
1154 | * loaded so it can be quickly enabled again in | ||
1155 | * the near future. | ||
1029 | */ | 1156 | */ |
1030 | kvm_clear_c0_guest_status(cop0, | 1157 | if (change & ST0_CU1 && |
1031 | (ST0_CU1 | ST0_NMI)); | 1158 | vcpu->arch.fpu_inuse & KVM_MIPS_FPU_FPU) |
1159 | change_c0_status(ST0_CU1, val); | ||
1160 | |||
1161 | preempt_enable(); | ||
1162 | |||
1163 | kvm_write_c0_guest_status(cop0, val); | ||
1032 | 1164 | ||
1033 | #ifdef CONFIG_KVM_MIPS_DYN_TRANS | 1165 | #ifdef CONFIG_KVM_MIPS_DYN_TRANS |
1034 | kvm_mips_trans_mtc0(inst, opc, vcpu); | 1166 | /* |
1167 | * If FPU present, we need CU1/FR bits to take | ||
1168 | * effect fairly soon. | ||
1169 | */ | ||
1170 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
1171 | kvm_mips_trans_mtc0(inst, opc, vcpu); | ||
1035 | #endif | 1172 | #endif |
1173 | } else if ((rd == MIPS_CP0_CONFIG) && (sel == 5)) { | ||
1174 | unsigned int old_val, val, change, wrmask; | ||
1175 | |||
1176 | old_val = kvm_read_c0_guest_config5(cop0); | ||
1177 | val = vcpu->arch.gprs[rt]; | ||
1178 | |||
1179 | /* Only a few bits are writable in Config5 */ | ||
1180 | wrmask = kvm_mips_config5_wrmask(vcpu); | ||
1181 | change = (val ^ old_val) & wrmask; | ||
1182 | val = old_val ^ change; | ||
1183 | |||
1184 | |||
1185 | /* Handle changes in FPU/MSA modes */ | ||
1186 | preempt_disable(); | ||
1187 | |||
1188 | /* | ||
1189 | * Propagate FRE changes immediately if the FPU | ||
1190 | * context is already loaded. | ||
1191 | */ | ||
1192 | if (change & MIPS_CONF5_FRE && | ||
1193 | vcpu->arch.fpu_inuse & KVM_MIPS_FPU_FPU) | ||
1194 | change_c0_config5(MIPS_CONF5_FRE, val); | ||
1195 | |||
1196 | /* | ||
1197 | * Propagate MSAEn changes immediately if the | ||
1198 | * MSA context is already loaded. When disabling | ||
1199 | * we leave the context loaded so it can be | ||
1200 | * quickly enabled again in the near future. | ||
1201 | */ | ||
1202 | if (change & MIPS_CONF5_MSAEN && | ||
1203 | vcpu->arch.fpu_inuse & KVM_MIPS_FPU_MSA) | ||
1204 | change_c0_config5(MIPS_CONF5_MSAEN, | ||
1205 | val); | ||
1206 | |||
1207 | preempt_enable(); | ||
1208 | |||
1209 | kvm_write_c0_guest_config5(cop0, val); | ||
1036 | } else if ((rd == MIPS_CP0_CAUSE) && (sel == 0)) { | 1210 | } else if ((rd == MIPS_CP0_CAUSE) && (sel == 0)) { |
1037 | uint32_t old_cause, new_cause; | 1211 | uint32_t old_cause, new_cause; |
1038 | 1212 | ||
@@ -1970,6 +2144,146 @@ enum emulation_result kvm_mips_emulate_bp_exc(unsigned long cause, | |||
1970 | return er; | 2144 | return er; |
1971 | } | 2145 | } |
1972 | 2146 | ||
2147 | enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause, | ||
2148 | uint32_t *opc, | ||
2149 | struct kvm_run *run, | ||
2150 | struct kvm_vcpu *vcpu) | ||
2151 | { | ||
2152 | struct mips_coproc *cop0 = vcpu->arch.cop0; | ||
2153 | struct kvm_vcpu_arch *arch = &vcpu->arch; | ||
2154 | enum emulation_result er = EMULATE_DONE; | ||
2155 | |||
2156 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | ||
2157 | /* save old pc */ | ||
2158 | kvm_write_c0_guest_epc(cop0, arch->pc); | ||
2159 | kvm_set_c0_guest_status(cop0, ST0_EXL); | ||
2160 | |||
2161 | if (cause & CAUSEF_BD) | ||
2162 | kvm_set_c0_guest_cause(cop0, CAUSEF_BD); | ||
2163 | else | ||
2164 | kvm_clear_c0_guest_cause(cop0, CAUSEF_BD); | ||
2165 | |||
2166 | kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc); | ||
2167 | |||
2168 | kvm_change_c0_guest_cause(cop0, (0xff), | ||
2169 | (T_TRAP << CAUSEB_EXCCODE)); | ||
2170 | |||
2171 | /* Set PC to the exception entry point */ | ||
2172 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | ||
2173 | |||
2174 | } else { | ||
2175 | kvm_err("Trying to deliver TRAP when EXL is already set\n"); | ||
2176 | er = EMULATE_FAIL; | ||
2177 | } | ||
2178 | |||
2179 | return er; | ||
2180 | } | ||
2181 | |||
2182 | enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause, | ||
2183 | uint32_t *opc, | ||
2184 | struct kvm_run *run, | ||
2185 | struct kvm_vcpu *vcpu) | ||
2186 | { | ||
2187 | struct mips_coproc *cop0 = vcpu->arch.cop0; | ||
2188 | struct kvm_vcpu_arch *arch = &vcpu->arch; | ||
2189 | enum emulation_result er = EMULATE_DONE; | ||
2190 | |||
2191 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | ||
2192 | /* save old pc */ | ||
2193 | kvm_write_c0_guest_epc(cop0, arch->pc); | ||
2194 | kvm_set_c0_guest_status(cop0, ST0_EXL); | ||
2195 | |||
2196 | if (cause & CAUSEF_BD) | ||
2197 | kvm_set_c0_guest_cause(cop0, CAUSEF_BD); | ||
2198 | else | ||
2199 | kvm_clear_c0_guest_cause(cop0, CAUSEF_BD); | ||
2200 | |||
2201 | kvm_debug("Delivering MSAFPE @ pc %#lx\n", arch->pc); | ||
2202 | |||
2203 | kvm_change_c0_guest_cause(cop0, (0xff), | ||
2204 | (T_MSAFPE << CAUSEB_EXCCODE)); | ||
2205 | |||
2206 | /* Set PC to the exception entry point */ | ||
2207 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | ||
2208 | |||
2209 | } else { | ||
2210 | kvm_err("Trying to deliver MSAFPE when EXL is already set\n"); | ||
2211 | er = EMULATE_FAIL; | ||
2212 | } | ||
2213 | |||
2214 | return er; | ||
2215 | } | ||
2216 | |||
2217 | enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause, | ||
2218 | uint32_t *opc, | ||
2219 | struct kvm_run *run, | ||
2220 | struct kvm_vcpu *vcpu) | ||
2221 | { | ||
2222 | struct mips_coproc *cop0 = vcpu->arch.cop0; | ||
2223 | struct kvm_vcpu_arch *arch = &vcpu->arch; | ||
2224 | enum emulation_result er = EMULATE_DONE; | ||
2225 | |||
2226 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | ||
2227 | /* save old pc */ | ||
2228 | kvm_write_c0_guest_epc(cop0, arch->pc); | ||
2229 | kvm_set_c0_guest_status(cop0, ST0_EXL); | ||
2230 | |||
2231 | if (cause & CAUSEF_BD) | ||
2232 | kvm_set_c0_guest_cause(cop0, CAUSEF_BD); | ||
2233 | else | ||
2234 | kvm_clear_c0_guest_cause(cop0, CAUSEF_BD); | ||
2235 | |||
2236 | kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc); | ||
2237 | |||
2238 | kvm_change_c0_guest_cause(cop0, (0xff), | ||
2239 | (T_FPE << CAUSEB_EXCCODE)); | ||
2240 | |||
2241 | /* Set PC to the exception entry point */ | ||
2242 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | ||
2243 | |||
2244 | } else { | ||
2245 | kvm_err("Trying to deliver FPE when EXL is already set\n"); | ||
2246 | er = EMULATE_FAIL; | ||
2247 | } | ||
2248 | |||
2249 | return er; | ||
2250 | } | ||
2251 | |||
2252 | enum emulation_result kvm_mips_emulate_msadis_exc(unsigned long cause, | ||
2253 | uint32_t *opc, | ||
2254 | struct kvm_run *run, | ||
2255 | struct kvm_vcpu *vcpu) | ||
2256 | { | ||
2257 | struct mips_coproc *cop0 = vcpu->arch.cop0; | ||
2258 | struct kvm_vcpu_arch *arch = &vcpu->arch; | ||
2259 | enum emulation_result er = EMULATE_DONE; | ||
2260 | |||
2261 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | ||
2262 | /* save old pc */ | ||
2263 | kvm_write_c0_guest_epc(cop0, arch->pc); | ||
2264 | kvm_set_c0_guest_status(cop0, ST0_EXL); | ||
2265 | |||
2266 | if (cause & CAUSEF_BD) | ||
2267 | kvm_set_c0_guest_cause(cop0, CAUSEF_BD); | ||
2268 | else | ||
2269 | kvm_clear_c0_guest_cause(cop0, CAUSEF_BD); | ||
2270 | |||
2271 | kvm_debug("Delivering MSADIS @ pc %#lx\n", arch->pc); | ||
2272 | |||
2273 | kvm_change_c0_guest_cause(cop0, (0xff), | ||
2274 | (T_MSADIS << CAUSEB_EXCCODE)); | ||
2275 | |||
2276 | /* Set PC to the exception entry point */ | ||
2277 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | ||
2278 | |||
2279 | } else { | ||
2280 | kvm_err("Trying to deliver MSADIS when EXL is already set\n"); | ||
2281 | er = EMULATE_FAIL; | ||
2282 | } | ||
2283 | |||
2284 | return er; | ||
2285 | } | ||
2286 | |||
1973 | /* ll/sc, rdhwr, sync emulation */ | 2287 | /* ll/sc, rdhwr, sync emulation */ |
1974 | 2288 | ||
1975 | #define OPCODE 0xfc000000 | 2289 | #define OPCODE 0xfc000000 |
@@ -2176,6 +2490,10 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause, | |||
2176 | case T_SYSCALL: | 2490 | case T_SYSCALL: |
2177 | case T_BREAK: | 2491 | case T_BREAK: |
2178 | case T_RES_INST: | 2492 | case T_RES_INST: |
2493 | case T_TRAP: | ||
2494 | case T_MSAFPE: | ||
2495 | case T_FPE: | ||
2496 | case T_MSADIS: | ||
2179 | break; | 2497 | break; |
2180 | 2498 | ||
2181 | case T_COP_UNUSABLE: | 2499 | case T_COP_UNUSABLE: |
diff --git a/arch/mips/kvm/fpu.S b/arch/mips/kvm/fpu.S new file mode 100644 index 000000000000..531fbf5131c0 --- /dev/null +++ b/arch/mips/kvm/fpu.S | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * FPU context handling code for KVM. | ||
7 | * | ||
8 | * Copyright (C) 2015 Imagination Technologies Ltd. | ||
9 | */ | ||
10 | |||
11 | #include <asm/asm.h> | ||
12 | #include <asm/asm-offsets.h> | ||
13 | #include <asm/fpregdef.h> | ||
14 | #include <asm/mipsregs.h> | ||
15 | #include <asm/regdef.h> | ||
16 | |||
17 | .set noreorder | ||
18 | .set noat | ||
19 | |||
20 | LEAF(__kvm_save_fpu) | ||
21 | .set push | ||
22 | .set mips64r2 | ||
23 | SET_HARDFLOAT | ||
24 | mfc0 t0, CP0_STATUS | ||
25 | sll t0, t0, 5 # is Status.FR set? | ||
26 | bgez t0, 1f # no: skip odd doubles | ||
27 | nop | ||
28 | sdc1 $f1, VCPU_FPR1(a0) | ||
29 | sdc1 $f3, VCPU_FPR3(a0) | ||
30 | sdc1 $f5, VCPU_FPR5(a0) | ||
31 | sdc1 $f7, VCPU_FPR7(a0) | ||
32 | sdc1 $f9, VCPU_FPR9(a0) | ||
33 | sdc1 $f11, VCPU_FPR11(a0) | ||
34 | sdc1 $f13, VCPU_FPR13(a0) | ||
35 | sdc1 $f15, VCPU_FPR15(a0) | ||
36 | sdc1 $f17, VCPU_FPR17(a0) | ||
37 | sdc1 $f19, VCPU_FPR19(a0) | ||
38 | sdc1 $f21, VCPU_FPR21(a0) | ||
39 | sdc1 $f23, VCPU_FPR23(a0) | ||
40 | sdc1 $f25, VCPU_FPR25(a0) | ||
41 | sdc1 $f27, VCPU_FPR27(a0) | ||
42 | sdc1 $f29, VCPU_FPR29(a0) | ||
43 | sdc1 $f31, VCPU_FPR31(a0) | ||
44 | 1: sdc1 $f0, VCPU_FPR0(a0) | ||
45 | sdc1 $f2, VCPU_FPR2(a0) | ||
46 | sdc1 $f4, VCPU_FPR4(a0) | ||
47 | sdc1 $f6, VCPU_FPR6(a0) | ||
48 | sdc1 $f8, VCPU_FPR8(a0) | ||
49 | sdc1 $f10, VCPU_FPR10(a0) | ||
50 | sdc1 $f12, VCPU_FPR12(a0) | ||
51 | sdc1 $f14, VCPU_FPR14(a0) | ||
52 | sdc1 $f16, VCPU_FPR16(a0) | ||
53 | sdc1 $f18, VCPU_FPR18(a0) | ||
54 | sdc1 $f20, VCPU_FPR20(a0) | ||
55 | sdc1 $f22, VCPU_FPR22(a0) | ||
56 | sdc1 $f24, VCPU_FPR24(a0) | ||
57 | sdc1 $f26, VCPU_FPR26(a0) | ||
58 | sdc1 $f28, VCPU_FPR28(a0) | ||
59 | jr ra | ||
60 | sdc1 $f30, VCPU_FPR30(a0) | ||
61 | .set pop | ||
62 | END(__kvm_save_fpu) | ||
63 | |||
64 | LEAF(__kvm_restore_fpu) | ||
65 | .set push | ||
66 | .set mips64r2 | ||
67 | SET_HARDFLOAT | ||
68 | mfc0 t0, CP0_STATUS | ||
69 | sll t0, t0, 5 # is Status.FR set? | ||
70 | bgez t0, 1f # no: skip odd doubles | ||
71 | nop | ||
72 | ldc1 $f1, VCPU_FPR1(a0) | ||
73 | ldc1 $f3, VCPU_FPR3(a0) | ||
74 | ldc1 $f5, VCPU_FPR5(a0) | ||
75 | ldc1 $f7, VCPU_FPR7(a0) | ||
76 | ldc1 $f9, VCPU_FPR9(a0) | ||
77 | ldc1 $f11, VCPU_FPR11(a0) | ||
78 | ldc1 $f13, VCPU_FPR13(a0) | ||
79 | ldc1 $f15, VCPU_FPR15(a0) | ||
80 | ldc1 $f17, VCPU_FPR17(a0) | ||
81 | ldc1 $f19, VCPU_FPR19(a0) | ||
82 | ldc1 $f21, VCPU_FPR21(a0) | ||
83 | ldc1 $f23, VCPU_FPR23(a0) | ||
84 | ldc1 $f25, VCPU_FPR25(a0) | ||
85 | ldc1 $f27, VCPU_FPR27(a0) | ||
86 | ldc1 $f29, VCPU_FPR29(a0) | ||
87 | ldc1 $f31, VCPU_FPR31(a0) | ||
88 | 1: ldc1 $f0, VCPU_FPR0(a0) | ||
89 | ldc1 $f2, VCPU_FPR2(a0) | ||
90 | ldc1 $f4, VCPU_FPR4(a0) | ||
91 | ldc1 $f6, VCPU_FPR6(a0) | ||
92 | ldc1 $f8, VCPU_FPR8(a0) | ||
93 | ldc1 $f10, VCPU_FPR10(a0) | ||
94 | ldc1 $f12, VCPU_FPR12(a0) | ||
95 | ldc1 $f14, VCPU_FPR14(a0) | ||
96 | ldc1 $f16, VCPU_FPR16(a0) | ||
97 | ldc1 $f18, VCPU_FPR18(a0) | ||
98 | ldc1 $f20, VCPU_FPR20(a0) | ||
99 | ldc1 $f22, VCPU_FPR22(a0) | ||
100 | ldc1 $f24, VCPU_FPR24(a0) | ||
101 | ldc1 $f26, VCPU_FPR26(a0) | ||
102 | ldc1 $f28, VCPU_FPR28(a0) | ||
103 | jr ra | ||
104 | ldc1 $f30, VCPU_FPR30(a0) | ||
105 | .set pop | ||
106 | END(__kvm_restore_fpu) | ||
107 | |||
108 | LEAF(__kvm_restore_fcsr) | ||
109 | .set push | ||
110 | SET_HARDFLOAT | ||
111 | lw t0, VCPU_FCR31(a0) | ||
112 | /* | ||
113 | * The ctc1 must stay at this offset in __kvm_restore_fcsr. | ||
114 | * See kvm_mips_csr_die_notify() which handles t0 containing a value | ||
115 | * which triggers an FP Exception, which must be stepped over and | ||
116 | * ignored since the set cause bits must remain there for the guest. | ||
117 | */ | ||
118 | ctc1 t0, fcr31 | ||
119 | jr ra | ||
120 | nop | ||
121 | .set pop | ||
122 | END(__kvm_restore_fcsr) | ||
diff --git a/arch/mips/kvm/locore.S b/arch/mips/kvm/locore.S index 4a68b176d6e4..c567240386a0 100644 --- a/arch/mips/kvm/locore.S +++ b/arch/mips/kvm/locore.S | |||
@@ -36,6 +36,8 @@ | |||
36 | #define PT_HOST_USERLOCAL PT_EPC | 36 | #define PT_HOST_USERLOCAL PT_EPC |
37 | 37 | ||
38 | #define CP0_DDATA_LO $28,3 | 38 | #define CP0_DDATA_LO $28,3 |
39 | #define CP0_CONFIG3 $16,3 | ||
40 | #define CP0_CONFIG5 $16,5 | ||
39 | #define CP0_EBASE $15,1 | 41 | #define CP0_EBASE $15,1 |
40 | 42 | ||
41 | #define CP0_INTCTL $12,1 | 43 | #define CP0_INTCTL $12,1 |
@@ -353,6 +355,42 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) | |||
353 | LONG_L k0, VCPU_HOST_EBASE(k1) | 355 | LONG_L k0, VCPU_HOST_EBASE(k1) |
354 | mtc0 k0,CP0_EBASE | 356 | mtc0 k0,CP0_EBASE |
355 | 357 | ||
358 | /* | ||
359 | * If FPU is enabled, save FCR31 and clear it so that later ctc1's don't | ||
360 | * trigger FPE for pending exceptions. | ||
361 | */ | ||
362 | .set at | ||
363 | and v1, v0, ST0_CU1 | ||
364 | beqz v1, 1f | ||
365 | nop | ||
366 | .set push | ||
367 | SET_HARDFLOAT | ||
368 | cfc1 t0, fcr31 | ||
369 | sw t0, VCPU_FCR31(k1) | ||
370 | ctc1 zero,fcr31 | ||
371 | .set pop | ||
372 | .set noat | ||
373 | 1: | ||
374 | |||
375 | #ifdef CONFIG_CPU_HAS_MSA | ||
376 | /* | ||
377 | * If MSA is enabled, save MSACSR and clear it so that later | ||
378 | * instructions don't trigger MSAFPE for pending exceptions. | ||
379 | */ | ||
380 | mfc0 t0, CP0_CONFIG3 | ||
381 | ext t0, t0, 28, 1 /* MIPS_CONF3_MSAP */ | ||
382 | beqz t0, 1f | ||
383 | nop | ||
384 | mfc0 t0, CP0_CONFIG5 | ||
385 | ext t0, t0, 27, 1 /* MIPS_CONF5_MSAEN */ | ||
386 | beqz t0, 1f | ||
387 | nop | ||
388 | _cfcmsa t0, MSA_CSR | ||
389 | sw t0, VCPU_MSA_CSR(k1) | ||
390 | _ctcmsa MSA_CSR, zero | ||
391 | 1: | ||
392 | #endif | ||
393 | |||
356 | /* Now that the new EBASE has been loaded, unset BEV and KSU_USER */ | 394 | /* Now that the new EBASE has been loaded, unset BEV and KSU_USER */ |
357 | .set at | 395 | .set at |
358 | and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE) | 396 | and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE) |
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index c9eccf5df912..bb68e8d520e8 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/kdebug.h> | ||
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/vmalloc.h> | 16 | #include <linux/vmalloc.h> |
16 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
@@ -48,6 +49,10 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
48 | { "syscall", VCPU_STAT(syscall_exits), KVM_STAT_VCPU }, | 49 | { "syscall", VCPU_STAT(syscall_exits), KVM_STAT_VCPU }, |
49 | { "resvd_inst", VCPU_STAT(resvd_inst_exits), KVM_STAT_VCPU }, | 50 | { "resvd_inst", VCPU_STAT(resvd_inst_exits), KVM_STAT_VCPU }, |
50 | { "break_inst", VCPU_STAT(break_inst_exits), KVM_STAT_VCPU }, | 51 | { "break_inst", VCPU_STAT(break_inst_exits), KVM_STAT_VCPU }, |
52 | { "trap_inst", VCPU_STAT(trap_inst_exits), KVM_STAT_VCPU }, | ||
53 | { "msa_fpe", VCPU_STAT(msa_fpe_exits), KVM_STAT_VCPU }, | ||
54 | { "fpe", VCPU_STAT(fpe_exits), KVM_STAT_VCPU }, | ||
55 | { "msa_disabled", VCPU_STAT(msa_disabled_exits), KVM_STAT_VCPU }, | ||
51 | { "flush_dcache", VCPU_STAT(flush_dcache_exits), KVM_STAT_VCPU }, | 56 | { "flush_dcache", VCPU_STAT(flush_dcache_exits), KVM_STAT_VCPU }, |
52 | { "halt_successful_poll", VCPU_STAT(halt_successful_poll), KVM_STAT_VCPU }, | 57 | { "halt_successful_poll", VCPU_STAT(halt_successful_poll), KVM_STAT_VCPU }, |
53 | { "halt_wakeup", VCPU_STAT(halt_wakeup), KVM_STAT_VCPU }, | 58 | { "halt_wakeup", VCPU_STAT(halt_wakeup), KVM_STAT_VCPU }, |
@@ -504,10 +509,13 @@ static u64 kvm_mips_get_one_regs[] = { | |||
504 | KVM_REG_MIPS_CP0_STATUS, | 509 | KVM_REG_MIPS_CP0_STATUS, |
505 | KVM_REG_MIPS_CP0_CAUSE, | 510 | KVM_REG_MIPS_CP0_CAUSE, |
506 | KVM_REG_MIPS_CP0_EPC, | 511 | KVM_REG_MIPS_CP0_EPC, |
512 | KVM_REG_MIPS_CP0_PRID, | ||
507 | KVM_REG_MIPS_CP0_CONFIG, | 513 | KVM_REG_MIPS_CP0_CONFIG, |
508 | KVM_REG_MIPS_CP0_CONFIG1, | 514 | KVM_REG_MIPS_CP0_CONFIG1, |
509 | KVM_REG_MIPS_CP0_CONFIG2, | 515 | KVM_REG_MIPS_CP0_CONFIG2, |
510 | KVM_REG_MIPS_CP0_CONFIG3, | 516 | KVM_REG_MIPS_CP0_CONFIG3, |
517 | KVM_REG_MIPS_CP0_CONFIG4, | ||
518 | KVM_REG_MIPS_CP0_CONFIG5, | ||
511 | KVM_REG_MIPS_CP0_CONFIG7, | 519 | KVM_REG_MIPS_CP0_CONFIG7, |
512 | KVM_REG_MIPS_CP0_ERROREPC, | 520 | KVM_REG_MIPS_CP0_ERROREPC, |
513 | 521 | ||
@@ -520,10 +528,14 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, | |||
520 | const struct kvm_one_reg *reg) | 528 | const struct kvm_one_reg *reg) |
521 | { | 529 | { |
522 | struct mips_coproc *cop0 = vcpu->arch.cop0; | 530 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
531 | struct mips_fpu_struct *fpu = &vcpu->arch.fpu; | ||
523 | int ret; | 532 | int ret; |
524 | s64 v; | 533 | s64 v; |
534 | s64 vs[2]; | ||
535 | unsigned int idx; | ||
525 | 536 | ||
526 | switch (reg->id) { | 537 | switch (reg->id) { |
538 | /* General purpose registers */ | ||
527 | case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31: | 539 | case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31: |
528 | v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0]; | 540 | v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0]; |
529 | break; | 541 | break; |
@@ -537,6 +549,67 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, | |||
537 | v = (long)vcpu->arch.pc; | 549 | v = (long)vcpu->arch.pc; |
538 | break; | 550 | break; |
539 | 551 | ||
552 | /* Floating point registers */ | ||
553 | case KVM_REG_MIPS_FPR_32(0) ... KVM_REG_MIPS_FPR_32(31): | ||
554 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
555 | return -EINVAL; | ||
556 | idx = reg->id - KVM_REG_MIPS_FPR_32(0); | ||
557 | /* Odd singles in top of even double when FR=0 */ | ||
558 | if (kvm_read_c0_guest_status(cop0) & ST0_FR) | ||
559 | v = get_fpr32(&fpu->fpr[idx], 0); | ||
560 | else | ||
561 | v = get_fpr32(&fpu->fpr[idx & ~1], idx & 1); | ||
562 | break; | ||
563 | case KVM_REG_MIPS_FPR_64(0) ... KVM_REG_MIPS_FPR_64(31): | ||
564 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
565 | return -EINVAL; | ||
566 | idx = reg->id - KVM_REG_MIPS_FPR_64(0); | ||
567 | /* Can't access odd doubles in FR=0 mode */ | ||
568 | if (idx & 1 && !(kvm_read_c0_guest_status(cop0) & ST0_FR)) | ||
569 | return -EINVAL; | ||
570 | v = get_fpr64(&fpu->fpr[idx], 0); | ||
571 | break; | ||
572 | case KVM_REG_MIPS_FCR_IR: | ||
573 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
574 | return -EINVAL; | ||
575 | v = boot_cpu_data.fpu_id; | ||
576 | break; | ||
577 | case KVM_REG_MIPS_FCR_CSR: | ||
578 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
579 | return -EINVAL; | ||
580 | v = fpu->fcr31; | ||
581 | break; | ||
582 | |||
583 | /* MIPS SIMD Architecture (MSA) registers */ | ||
584 | case KVM_REG_MIPS_VEC_128(0) ... KVM_REG_MIPS_VEC_128(31): | ||
585 | if (!kvm_mips_guest_has_msa(&vcpu->arch)) | ||
586 | return -EINVAL; | ||
587 | /* Can't access MSA registers in FR=0 mode */ | ||
588 | if (!(kvm_read_c0_guest_status(cop0) & ST0_FR)) | ||
589 | return -EINVAL; | ||
590 | idx = reg->id - KVM_REG_MIPS_VEC_128(0); | ||
591 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
592 | /* least significant byte first */ | ||
593 | vs[0] = get_fpr64(&fpu->fpr[idx], 0); | ||
594 | vs[1] = get_fpr64(&fpu->fpr[idx], 1); | ||
595 | #else | ||
596 | /* most significant byte first */ | ||
597 | vs[0] = get_fpr64(&fpu->fpr[idx], 1); | ||
598 | vs[1] = get_fpr64(&fpu->fpr[idx], 0); | ||
599 | #endif | ||
600 | break; | ||
601 | case KVM_REG_MIPS_MSA_IR: | ||
602 | if (!kvm_mips_guest_has_msa(&vcpu->arch)) | ||
603 | return -EINVAL; | ||
604 | v = boot_cpu_data.msa_id; | ||
605 | break; | ||
606 | case KVM_REG_MIPS_MSA_CSR: | ||
607 | if (!kvm_mips_guest_has_msa(&vcpu->arch)) | ||
608 | return -EINVAL; | ||
609 | v = fpu->msacsr; | ||
610 | break; | ||
611 | |||
612 | /* Co-processor 0 registers */ | ||
540 | case KVM_REG_MIPS_CP0_INDEX: | 613 | case KVM_REG_MIPS_CP0_INDEX: |
541 | v = (long)kvm_read_c0_guest_index(cop0); | 614 | v = (long)kvm_read_c0_guest_index(cop0); |
542 | break; | 615 | break; |
@@ -573,8 +646,8 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, | |||
573 | case KVM_REG_MIPS_CP0_EPC: | 646 | case KVM_REG_MIPS_CP0_EPC: |
574 | v = (long)kvm_read_c0_guest_epc(cop0); | 647 | v = (long)kvm_read_c0_guest_epc(cop0); |
575 | break; | 648 | break; |
576 | case KVM_REG_MIPS_CP0_ERROREPC: | 649 | case KVM_REG_MIPS_CP0_PRID: |
577 | v = (long)kvm_read_c0_guest_errorepc(cop0); | 650 | v = (long)kvm_read_c0_guest_prid(cop0); |
578 | break; | 651 | break; |
579 | case KVM_REG_MIPS_CP0_CONFIG: | 652 | case KVM_REG_MIPS_CP0_CONFIG: |
580 | v = (long)kvm_read_c0_guest_config(cop0); | 653 | v = (long)kvm_read_c0_guest_config(cop0); |
@@ -588,9 +661,18 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, | |||
588 | case KVM_REG_MIPS_CP0_CONFIG3: | 661 | case KVM_REG_MIPS_CP0_CONFIG3: |
589 | v = (long)kvm_read_c0_guest_config3(cop0); | 662 | v = (long)kvm_read_c0_guest_config3(cop0); |
590 | break; | 663 | break; |
664 | case KVM_REG_MIPS_CP0_CONFIG4: | ||
665 | v = (long)kvm_read_c0_guest_config4(cop0); | ||
666 | break; | ||
667 | case KVM_REG_MIPS_CP0_CONFIG5: | ||
668 | v = (long)kvm_read_c0_guest_config5(cop0); | ||
669 | break; | ||
591 | case KVM_REG_MIPS_CP0_CONFIG7: | 670 | case KVM_REG_MIPS_CP0_CONFIG7: |
592 | v = (long)kvm_read_c0_guest_config7(cop0); | 671 | v = (long)kvm_read_c0_guest_config7(cop0); |
593 | break; | 672 | break; |
673 | case KVM_REG_MIPS_CP0_ERROREPC: | ||
674 | v = (long)kvm_read_c0_guest_errorepc(cop0); | ||
675 | break; | ||
594 | /* registers to be handled specially */ | 676 | /* registers to be handled specially */ |
595 | case KVM_REG_MIPS_CP0_COUNT: | 677 | case KVM_REG_MIPS_CP0_COUNT: |
596 | case KVM_REG_MIPS_COUNT_CTL: | 678 | case KVM_REG_MIPS_COUNT_CTL: |
@@ -612,6 +694,10 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, | |||
612 | u32 v32 = (u32)v; | 694 | u32 v32 = (u32)v; |
613 | 695 | ||
614 | return put_user(v32, uaddr32); | 696 | return put_user(v32, uaddr32); |
697 | } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) { | ||
698 | void __user *uaddr = (void __user *)(long)reg->addr; | ||
699 | |||
700 | return copy_to_user(uaddr, vs, 16); | ||
615 | } else { | 701 | } else { |
616 | return -EINVAL; | 702 | return -EINVAL; |
617 | } | 703 | } |
@@ -621,7 +707,10 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, | |||
621 | const struct kvm_one_reg *reg) | 707 | const struct kvm_one_reg *reg) |
622 | { | 708 | { |
623 | struct mips_coproc *cop0 = vcpu->arch.cop0; | 709 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
624 | u64 v; | 710 | struct mips_fpu_struct *fpu = &vcpu->arch.fpu; |
711 | s64 v; | ||
712 | s64 vs[2]; | ||
713 | unsigned int idx; | ||
625 | 714 | ||
626 | if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) { | 715 | if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) { |
627 | u64 __user *uaddr64 = (u64 __user *)(long)reg->addr; | 716 | u64 __user *uaddr64 = (u64 __user *)(long)reg->addr; |
@@ -635,11 +724,16 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, | |||
635 | if (get_user(v32, uaddr32) != 0) | 724 | if (get_user(v32, uaddr32) != 0) |
636 | return -EFAULT; | 725 | return -EFAULT; |
637 | v = (s64)v32; | 726 | v = (s64)v32; |
727 | } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) { | ||
728 | void __user *uaddr = (void __user *)(long)reg->addr; | ||
729 | |||
730 | return copy_from_user(vs, uaddr, 16); | ||
638 | } else { | 731 | } else { |
639 | return -EINVAL; | 732 | return -EINVAL; |
640 | } | 733 | } |
641 | 734 | ||
642 | switch (reg->id) { | 735 | switch (reg->id) { |
736 | /* General purpose registers */ | ||
643 | case KVM_REG_MIPS_R0: | 737 | case KVM_REG_MIPS_R0: |
644 | /* Silently ignore requests to set $0 */ | 738 | /* Silently ignore requests to set $0 */ |
645 | break; | 739 | break; |
@@ -656,6 +750,64 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, | |||
656 | vcpu->arch.pc = v; | 750 | vcpu->arch.pc = v; |
657 | break; | 751 | break; |
658 | 752 | ||
753 | /* Floating point registers */ | ||
754 | case KVM_REG_MIPS_FPR_32(0) ... KVM_REG_MIPS_FPR_32(31): | ||
755 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
756 | return -EINVAL; | ||
757 | idx = reg->id - KVM_REG_MIPS_FPR_32(0); | ||
758 | /* Odd singles in top of even double when FR=0 */ | ||
759 | if (kvm_read_c0_guest_status(cop0) & ST0_FR) | ||
760 | set_fpr32(&fpu->fpr[idx], 0, v); | ||
761 | else | ||
762 | set_fpr32(&fpu->fpr[idx & ~1], idx & 1, v); | ||
763 | break; | ||
764 | case KVM_REG_MIPS_FPR_64(0) ... KVM_REG_MIPS_FPR_64(31): | ||
765 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
766 | return -EINVAL; | ||
767 | idx = reg->id - KVM_REG_MIPS_FPR_64(0); | ||
768 | /* Can't access odd doubles in FR=0 mode */ | ||
769 | if (idx & 1 && !(kvm_read_c0_guest_status(cop0) & ST0_FR)) | ||
770 | return -EINVAL; | ||
771 | set_fpr64(&fpu->fpr[idx], 0, v); | ||
772 | break; | ||
773 | case KVM_REG_MIPS_FCR_IR: | ||
774 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
775 | return -EINVAL; | ||
776 | /* Read-only */ | ||
777 | break; | ||
778 | case KVM_REG_MIPS_FCR_CSR: | ||
779 | if (!kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
780 | return -EINVAL; | ||
781 | fpu->fcr31 = v; | ||
782 | break; | ||
783 | |||
784 | /* MIPS SIMD Architecture (MSA) registers */ | ||
785 | case KVM_REG_MIPS_VEC_128(0) ... KVM_REG_MIPS_VEC_128(31): | ||
786 | if (!kvm_mips_guest_has_msa(&vcpu->arch)) | ||
787 | return -EINVAL; | ||
788 | idx = reg->id - KVM_REG_MIPS_VEC_128(0); | ||
789 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
790 | /* least significant byte first */ | ||
791 | set_fpr64(&fpu->fpr[idx], 0, vs[0]); | ||
792 | set_fpr64(&fpu->fpr[idx], 1, vs[1]); | ||
793 | #else | ||
794 | /* most significant byte first */ | ||
795 | set_fpr64(&fpu->fpr[idx], 1, vs[0]); | ||
796 | set_fpr64(&fpu->fpr[idx], 0, vs[1]); | ||
797 | #endif | ||
798 | break; | ||
799 | case KVM_REG_MIPS_MSA_IR: | ||
800 | if (!kvm_mips_guest_has_msa(&vcpu->arch)) | ||
801 | return -EINVAL; | ||
802 | /* Read-only */ | ||
803 | break; | ||
804 | case KVM_REG_MIPS_MSA_CSR: | ||
805 | if (!kvm_mips_guest_has_msa(&vcpu->arch)) | ||
806 | return -EINVAL; | ||
807 | fpu->msacsr = v; | ||
808 | break; | ||
809 | |||
810 | /* Co-processor 0 registers */ | ||
659 | case KVM_REG_MIPS_CP0_INDEX: | 811 | case KVM_REG_MIPS_CP0_INDEX: |
660 | kvm_write_c0_guest_index(cop0, v); | 812 | kvm_write_c0_guest_index(cop0, v); |
661 | break; | 813 | break; |
@@ -686,6 +838,9 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, | |||
686 | case KVM_REG_MIPS_CP0_EPC: | 838 | case KVM_REG_MIPS_CP0_EPC: |
687 | kvm_write_c0_guest_epc(cop0, v); | 839 | kvm_write_c0_guest_epc(cop0, v); |
688 | break; | 840 | break; |
841 | case KVM_REG_MIPS_CP0_PRID: | ||
842 | kvm_write_c0_guest_prid(cop0, v); | ||
843 | break; | ||
689 | case KVM_REG_MIPS_CP0_ERROREPC: | 844 | case KVM_REG_MIPS_CP0_ERROREPC: |
690 | kvm_write_c0_guest_errorepc(cop0, v); | 845 | kvm_write_c0_guest_errorepc(cop0, v); |
691 | break; | 846 | break; |
@@ -693,6 +848,12 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, | |||
693 | case KVM_REG_MIPS_CP0_COUNT: | 848 | case KVM_REG_MIPS_CP0_COUNT: |
694 | case KVM_REG_MIPS_CP0_COMPARE: | 849 | case KVM_REG_MIPS_CP0_COMPARE: |
695 | case KVM_REG_MIPS_CP0_CAUSE: | 850 | case KVM_REG_MIPS_CP0_CAUSE: |
851 | case KVM_REG_MIPS_CP0_CONFIG: | ||
852 | case KVM_REG_MIPS_CP0_CONFIG1: | ||
853 | case KVM_REG_MIPS_CP0_CONFIG2: | ||
854 | case KVM_REG_MIPS_CP0_CONFIG3: | ||
855 | case KVM_REG_MIPS_CP0_CONFIG4: | ||
856 | case KVM_REG_MIPS_CP0_CONFIG5: | ||
696 | case KVM_REG_MIPS_COUNT_CTL: | 857 | case KVM_REG_MIPS_COUNT_CTL: |
697 | case KVM_REG_MIPS_COUNT_RESUME: | 858 | case KVM_REG_MIPS_COUNT_RESUME: |
698 | case KVM_REG_MIPS_COUNT_HZ: | 859 | case KVM_REG_MIPS_COUNT_HZ: |
@@ -703,6 +864,33 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, | |||
703 | return 0; | 864 | return 0; |
704 | } | 865 | } |
705 | 866 | ||
867 | static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, | ||
868 | struct kvm_enable_cap *cap) | ||
869 | { | ||
870 | int r = 0; | ||
871 | |||
872 | if (!kvm_vm_ioctl_check_extension(vcpu->kvm, cap->cap)) | ||
873 | return -EINVAL; | ||
874 | if (cap->flags) | ||
875 | return -EINVAL; | ||
876 | if (cap->args[0]) | ||
877 | return -EINVAL; | ||
878 | |||
879 | switch (cap->cap) { | ||
880 | case KVM_CAP_MIPS_FPU: | ||
881 | vcpu->arch.fpu_enabled = true; | ||
882 | break; | ||
883 | case KVM_CAP_MIPS_MSA: | ||
884 | vcpu->arch.msa_enabled = true; | ||
885 | break; | ||
886 | default: | ||
887 | r = -EINVAL; | ||
888 | break; | ||
889 | } | ||
890 | |||
891 | return r; | ||
892 | } | ||
893 | |||
706 | long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, | 894 | long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, |
707 | unsigned long arg) | 895 | unsigned long arg) |
708 | { | 896 | { |
@@ -760,6 +948,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, | |||
760 | r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); | 948 | r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); |
761 | break; | 949 | break; |
762 | } | 950 | } |
951 | case KVM_ENABLE_CAP: { | ||
952 | struct kvm_enable_cap cap; | ||
953 | |||
954 | r = -EFAULT; | ||
955 | if (copy_from_user(&cap, argp, sizeof(cap))) | ||
956 | goto out; | ||
957 | r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); | ||
958 | break; | ||
959 | } | ||
763 | default: | 960 | default: |
764 | r = -ENOIOCTLCMD; | 961 | r = -ENOIOCTLCMD; |
765 | } | 962 | } |
@@ -868,11 +1065,30 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
868 | 1065 | ||
869 | switch (ext) { | 1066 | switch (ext) { |
870 | case KVM_CAP_ONE_REG: | 1067 | case KVM_CAP_ONE_REG: |
1068 | case KVM_CAP_ENABLE_CAP: | ||
871 | r = 1; | 1069 | r = 1; |
872 | break; | 1070 | break; |
873 | case KVM_CAP_COALESCED_MMIO: | 1071 | case KVM_CAP_COALESCED_MMIO: |
874 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; | 1072 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; |
875 | break; | 1073 | break; |
1074 | case KVM_CAP_MIPS_FPU: | ||
1075 | r = !!cpu_has_fpu; | ||
1076 | break; | ||
1077 | case KVM_CAP_MIPS_MSA: | ||
1078 | /* | ||
1079 | * We don't support MSA vector partitioning yet: | ||
1080 | * 1) It would require explicit support which can't be tested | ||
1081 | * yet due to lack of support in current hardware. | ||
1082 | * 2) It extends the state that would need to be saved/restored | ||
1083 | * by e.g. QEMU for migration. | ||
1084 | * | ||
1085 | * When vector partitioning hardware becomes available, support | ||
1086 | * could be added by requiring a flag when enabling | ||
1087 | * KVM_CAP_MIPS_MSA capability to indicate that userland knows | ||
1088 | * to save/restore the appropriate extra state. | ||
1089 | */ | ||
1090 | r = cpu_has_msa && !(boot_cpu_data.msa_id & MSA_IR_WRPF); | ||
1091 | break; | ||
876 | default: | 1092 | default: |
877 | r = 0; | 1093 | r = 0; |
878 | break; | 1094 | break; |
@@ -1119,6 +1335,30 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1119 | ret = kvm_mips_callbacks->handle_break(vcpu); | 1335 | ret = kvm_mips_callbacks->handle_break(vcpu); |
1120 | break; | 1336 | break; |
1121 | 1337 | ||
1338 | case T_TRAP: | ||
1339 | ++vcpu->stat.trap_inst_exits; | ||
1340 | trace_kvm_exit(vcpu, TRAP_INST_EXITS); | ||
1341 | ret = kvm_mips_callbacks->handle_trap(vcpu); | ||
1342 | break; | ||
1343 | |||
1344 | case T_MSAFPE: | ||
1345 | ++vcpu->stat.msa_fpe_exits; | ||
1346 | trace_kvm_exit(vcpu, MSA_FPE_EXITS); | ||
1347 | ret = kvm_mips_callbacks->handle_msa_fpe(vcpu); | ||
1348 | break; | ||
1349 | |||
1350 | case T_FPE: | ||
1351 | ++vcpu->stat.fpe_exits; | ||
1352 | trace_kvm_exit(vcpu, FPE_EXITS); | ||
1353 | ret = kvm_mips_callbacks->handle_fpe(vcpu); | ||
1354 | break; | ||
1355 | |||
1356 | case T_MSADIS: | ||
1357 | ++vcpu->stat.msa_disabled_exits; | ||
1358 | trace_kvm_exit(vcpu, MSA_DISABLED_EXITS); | ||
1359 | ret = kvm_mips_callbacks->handle_msa_disabled(vcpu); | ||
1360 | break; | ||
1361 | |||
1122 | default: | 1362 | default: |
1123 | kvm_err("Exception Code: %d, not yet handled, @ PC: %p, inst: 0x%08x BadVaddr: %#lx Status: %#lx\n", | 1363 | kvm_err("Exception Code: %d, not yet handled, @ PC: %p, inst: 0x%08x BadVaddr: %#lx Status: %#lx\n", |
1124 | exccode, opc, kvm_get_inst(opc, vcpu), badvaddr, | 1364 | exccode, opc, kvm_get_inst(opc, vcpu), badvaddr, |
@@ -1146,12 +1386,233 @@ skip_emul: | |||
1146 | } | 1386 | } |
1147 | } | 1387 | } |
1148 | 1388 | ||
1389 | if (ret == RESUME_GUEST) { | ||
1390 | /* | ||
1391 | * If FPU / MSA are enabled (i.e. the guest's FPU / MSA context | ||
1392 | * is live), restore FCR31 / MSACSR. | ||
1393 | * | ||
1394 | * This should be before returning to the guest exception | ||
1395 | * vector, as it may well cause an [MSA] FP exception if there | ||
1396 | * are pending exception bits unmasked. (see | ||
1397 | * kvm_mips_csr_die_notifier() for how that is handled). | ||
1398 | */ | ||
1399 | if (kvm_mips_guest_has_fpu(&vcpu->arch) && | ||
1400 | read_c0_status() & ST0_CU1) | ||
1401 | __kvm_restore_fcsr(&vcpu->arch); | ||
1402 | |||
1403 | if (kvm_mips_guest_has_msa(&vcpu->arch) && | ||
1404 | read_c0_config5() & MIPS_CONF5_MSAEN) | ||
1405 | __kvm_restore_msacsr(&vcpu->arch); | ||
1406 | } | ||
1407 | |||
1149 | /* Disable HTW before returning to guest or host */ | 1408 | /* Disable HTW before returning to guest or host */ |
1150 | htw_stop(); | 1409 | htw_stop(); |
1151 | 1410 | ||
1152 | return ret; | 1411 | return ret; |
1153 | } | 1412 | } |
1154 | 1413 | ||
1414 | /* Enable FPU for guest and restore context */ | ||
1415 | void kvm_own_fpu(struct kvm_vcpu *vcpu) | ||
1416 | { | ||
1417 | struct mips_coproc *cop0 = vcpu->arch.cop0; | ||
1418 | unsigned int sr, cfg5; | ||
1419 | |||
1420 | preempt_disable(); | ||
1421 | |||
1422 | sr = kvm_read_c0_guest_status(cop0); | ||
1423 | |||
1424 | /* | ||
1425 | * If MSA state is already live, it is undefined how it interacts with | ||
1426 | * FR=0 FPU state, and we don't want to hit reserved instruction | ||
1427 | * exceptions trying to save the MSA state later when CU=1 && FR=1, so | ||
1428 | * play it safe and save it first. | ||
1429 | * | ||
1430 | * In theory we shouldn't ever hit this case since kvm_lose_fpu() should | ||
1431 | * get called when guest CU1 is set, however we can't trust the guest | ||
1432 | * not to clobber the status register directly via the commpage. | ||
1433 | */ | ||
1434 | if (cpu_has_msa && sr & ST0_CU1 && !(sr & ST0_FR) && | ||
1435 | vcpu->arch.fpu_inuse & KVM_MIPS_FPU_MSA) | ||
1436 | kvm_lose_fpu(vcpu); | ||
1437 | |||
1438 | /* | ||
1439 | * Enable FPU for guest | ||
1440 | * We set FR and FRE according to guest context | ||
1441 | */ | ||
1442 | change_c0_status(ST0_CU1 | ST0_FR, sr); | ||
1443 | if (cpu_has_fre) { | ||
1444 | cfg5 = kvm_read_c0_guest_config5(cop0); | ||
1445 | change_c0_config5(MIPS_CONF5_FRE, cfg5); | ||
1446 | } | ||
1447 | enable_fpu_hazard(); | ||
1448 | |||
1449 | /* If guest FPU state not active, restore it now */ | ||
1450 | if (!(vcpu->arch.fpu_inuse & KVM_MIPS_FPU_FPU)) { | ||
1451 | __kvm_restore_fpu(&vcpu->arch); | ||
1452 | vcpu->arch.fpu_inuse |= KVM_MIPS_FPU_FPU; | ||
1453 | } | ||
1454 | |||
1455 | preempt_enable(); | ||
1456 | } | ||
1457 | |||
1458 | #ifdef CONFIG_CPU_HAS_MSA | ||
1459 | /* Enable MSA for guest and restore context */ | ||
1460 | void kvm_own_msa(struct kvm_vcpu *vcpu) | ||
1461 | { | ||
1462 | struct mips_coproc *cop0 = vcpu->arch.cop0; | ||
1463 | unsigned int sr, cfg5; | ||
1464 | |||
1465 | preempt_disable(); | ||
1466 | |||
1467 | /* | ||
1468 | * Enable FPU if enabled in guest, since we're restoring FPU context | ||
1469 | * anyway. We set FR and FRE according to guest context. | ||
1470 | */ | ||
1471 | if (kvm_mips_guest_has_fpu(&vcpu->arch)) { | ||
1472 | sr = kvm_read_c0_guest_status(cop0); | ||
1473 | |||
1474 | /* | ||
1475 | * If FR=0 FPU state is already live, it is undefined how it | ||
1476 | * interacts with MSA state, so play it safe and save it first. | ||
1477 | */ | ||
1478 | if (!(sr & ST0_FR) && | ||
1479 | (vcpu->arch.fpu_inuse & (KVM_MIPS_FPU_FPU | | ||
1480 | KVM_MIPS_FPU_MSA)) == KVM_MIPS_FPU_FPU) | ||
1481 | kvm_lose_fpu(vcpu); | ||
1482 | |||
1483 | change_c0_status(ST0_CU1 | ST0_FR, sr); | ||
1484 | if (sr & ST0_CU1 && cpu_has_fre) { | ||
1485 | cfg5 = kvm_read_c0_guest_config5(cop0); | ||
1486 | change_c0_config5(MIPS_CONF5_FRE, cfg5); | ||
1487 | } | ||
1488 | } | ||
1489 | |||
1490 | /* Enable MSA for guest */ | ||
1491 | set_c0_config5(MIPS_CONF5_MSAEN); | ||
1492 | enable_fpu_hazard(); | ||
1493 | |||
1494 | switch (vcpu->arch.fpu_inuse & (KVM_MIPS_FPU_FPU | KVM_MIPS_FPU_MSA)) { | ||
1495 | case KVM_MIPS_FPU_FPU: | ||
1496 | /* | ||
1497 | * Guest FPU state already loaded, only restore upper MSA state | ||
1498 | */ | ||
1499 | __kvm_restore_msa_upper(&vcpu->arch); | ||
1500 | vcpu->arch.fpu_inuse |= KVM_MIPS_FPU_MSA; | ||
1501 | break; | ||
1502 | case 0: | ||
1503 | /* Neither FPU or MSA already active, restore full MSA state */ | ||
1504 | __kvm_restore_msa(&vcpu->arch); | ||
1505 | vcpu->arch.fpu_inuse |= KVM_MIPS_FPU_MSA; | ||
1506 | if (kvm_mips_guest_has_fpu(&vcpu->arch)) | ||
1507 | vcpu->arch.fpu_inuse |= KVM_MIPS_FPU_FPU; | ||
1508 | break; | ||
1509 | default: | ||
1510 | break; | ||
1511 | } | ||
1512 | |||
1513 | preempt_enable(); | ||
1514 | } | ||
1515 | #endif | ||
1516 | |||
1517 | /* Drop FPU & MSA without saving it */ | ||
1518 | void kvm_drop_fpu(struct kvm_vcpu *vcpu) | ||
1519 | { | ||
1520 | preempt_disable(); | ||
1521 | if (cpu_has_msa && vcpu->arch.fpu_inuse & KVM_MIPS_FPU_MSA) { | ||
1522 | disable_msa(); | ||
1523 | vcpu->arch.fpu_inuse &= ~KVM_MIPS_FPU_MSA; | ||
1524 | } | ||
1525 | if (vcpu->arch.fpu_inuse & KVM_MIPS_FPU_FPU) { | ||
1526 | clear_c0_status(ST0_CU1 | ST0_FR); | ||
1527 | vcpu->arch.fpu_inuse &= ~KVM_MIPS_FPU_FPU; | ||
1528 | } | ||
1529 | preempt_enable(); | ||
1530 | } | ||
1531 | |||
1532 | /* Save and disable FPU & MSA */ | ||
1533 | void kvm_lose_fpu(struct kvm_vcpu *vcpu) | ||
1534 | { | ||
1535 | /* | ||
1536 | * FPU & MSA get disabled in root context (hardware) when it is disabled | ||
1537 | * in guest context (software), but the register state in the hardware | ||
1538 | * may still be in use. This is why we explicitly re-enable the hardware | ||
1539 | * before saving. | ||
1540 | */ | ||
1541 | |||
1542 | preempt_disable(); | ||
1543 | if (cpu_has_msa && vcpu->arch.fpu_inuse & KVM_MIPS_FPU_MSA) { | ||
1544 | set_c0_config5(MIPS_CONF5_MSAEN); | ||
1545 | enable_fpu_hazard(); | ||
1546 | |||
1547 | __kvm_save_msa(&vcpu->arch); | ||
1548 | |||
1549 | /* Disable MSA & FPU */ | ||
1550 | disable_msa(); | ||
1551 | if (vcpu->arch.fpu_inuse & KVM_MIPS_FPU_FPU) | ||
1552 | clear_c0_status(ST0_CU1 | ST0_FR); | ||
1553 | vcpu->arch.fpu_inuse &= ~(KVM_MIPS_FPU_FPU | KVM_MIPS_FPU_MSA); | ||
1554 | } else if (vcpu->arch.fpu_inuse & KVM_MIPS_FPU_FPU) { | ||
1555 | set_c0_status(ST0_CU1); | ||
1556 | enable_fpu_hazard(); | ||
1557 | |||
1558 | __kvm_save_fpu(&vcpu->arch); | ||
1559 | vcpu->arch.fpu_inuse &= ~KVM_MIPS_FPU_FPU; | ||
1560 | |||
1561 | /* Disable FPU */ | ||
1562 | clear_c0_status(ST0_CU1 | ST0_FR); | ||
1563 | } | ||
1564 | preempt_enable(); | ||
1565 | } | ||
1566 | |||
1567 | /* | ||
1568 | * Step over a specific ctc1 to FCSR and a specific ctcmsa to MSACSR which are | ||
1569 | * used to restore guest FCSR/MSACSR state and may trigger a "harmless" FP/MSAFP | ||
1570 | * exception if cause bits are set in the value being written. | ||
1571 | */ | ||
1572 | static int kvm_mips_csr_die_notify(struct notifier_block *self, | ||
1573 | unsigned long cmd, void *ptr) | ||
1574 | { | ||
1575 | struct die_args *args = (struct die_args *)ptr; | ||
1576 | struct pt_regs *regs = args->regs; | ||
1577 | unsigned long pc; | ||
1578 | |||
1579 | /* Only interested in FPE and MSAFPE */ | ||
1580 | if (cmd != DIE_FP && cmd != DIE_MSAFP) | ||
1581 | return NOTIFY_DONE; | ||
1582 | |||
1583 | /* Return immediately if guest context isn't active */ | ||
1584 | if (!(current->flags & PF_VCPU)) | ||
1585 | return NOTIFY_DONE; | ||
1586 | |||
1587 | /* Should never get here from user mode */ | ||
1588 | BUG_ON(user_mode(regs)); | ||
1589 | |||
1590 | pc = instruction_pointer(regs); | ||
1591 | switch (cmd) { | ||
1592 | case DIE_FP: | ||
1593 | /* match 2nd instruction in __kvm_restore_fcsr */ | ||
1594 | if (pc != (unsigned long)&__kvm_restore_fcsr + 4) | ||
1595 | return NOTIFY_DONE; | ||
1596 | break; | ||
1597 | case DIE_MSAFP: | ||
1598 | /* match 2nd/3rd instruction in __kvm_restore_msacsr */ | ||
1599 | if (!cpu_has_msa || | ||
1600 | pc < (unsigned long)&__kvm_restore_msacsr + 4 || | ||
1601 | pc > (unsigned long)&__kvm_restore_msacsr + 8) | ||
1602 | return NOTIFY_DONE; | ||
1603 | break; | ||
1604 | } | ||
1605 | |||
1606 | /* Move PC forward a little and continue executing */ | ||
1607 | instruction_pointer(regs) += 4; | ||
1608 | |||
1609 | return NOTIFY_STOP; | ||
1610 | } | ||
1611 | |||
1612 | static struct notifier_block kvm_mips_csr_die_notifier = { | ||
1613 | .notifier_call = kvm_mips_csr_die_notify, | ||
1614 | }; | ||
1615 | |||
1155 | int __init kvm_mips_init(void) | 1616 | int __init kvm_mips_init(void) |
1156 | { | 1617 | { |
1157 | int ret; | 1618 | int ret; |
@@ -1161,6 +1622,8 @@ int __init kvm_mips_init(void) | |||
1161 | if (ret) | 1622 | if (ret) |
1162 | return ret; | 1623 | return ret; |
1163 | 1624 | ||
1625 | register_die_notifier(&kvm_mips_csr_die_notifier); | ||
1626 | |||
1164 | /* | 1627 | /* |
1165 | * On MIPS, kernel modules are executed from "mapped space", which | 1628 | * On MIPS, kernel modules are executed from "mapped space", which |
1166 | * requires TLBs. The TLB handling code is statically linked with | 1629 | * requires TLBs. The TLB handling code is statically linked with |
@@ -1173,7 +1636,6 @@ int __init kvm_mips_init(void) | |||
1173 | kvm_mips_release_pfn_clean = kvm_release_pfn_clean; | 1636 | kvm_mips_release_pfn_clean = kvm_release_pfn_clean; |
1174 | kvm_mips_is_error_pfn = is_error_pfn; | 1637 | kvm_mips_is_error_pfn = is_error_pfn; |
1175 | 1638 | ||
1176 | pr_info("KVM/MIPS Initialized\n"); | ||
1177 | return 0; | 1639 | return 0; |
1178 | } | 1640 | } |
1179 | 1641 | ||
@@ -1185,7 +1647,7 @@ void __exit kvm_mips_exit(void) | |||
1185 | kvm_mips_release_pfn_clean = NULL; | 1647 | kvm_mips_release_pfn_clean = NULL; |
1186 | kvm_mips_is_error_pfn = NULL; | 1648 | kvm_mips_is_error_pfn = NULL; |
1187 | 1649 | ||
1188 | pr_info("KVM/MIPS unloaded\n"); | 1650 | unregister_die_notifier(&kvm_mips_csr_die_notifier); |
1189 | } | 1651 | } |
1190 | 1652 | ||
1191 | module_init(kvm_mips_init); | 1653 | module_init(kvm_mips_init); |
diff --git a/arch/mips/kvm/msa.S b/arch/mips/kvm/msa.S new file mode 100644 index 000000000000..d02f0c6cc2cc --- /dev/null +++ b/arch/mips/kvm/msa.S | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * MIPS SIMD Architecture (MSA) context handling code for KVM. | ||
7 | * | ||
8 | * Copyright (C) 2015 Imagination Technologies Ltd. | ||
9 | */ | ||
10 | |||
11 | #include <asm/asm.h> | ||
12 | #include <asm/asm-offsets.h> | ||
13 | #include <asm/asmmacro.h> | ||
14 | #include <asm/regdef.h> | ||
15 | |||
16 | .set noreorder | ||
17 | .set noat | ||
18 | |||
19 | LEAF(__kvm_save_msa) | ||
20 | st_d 0, VCPU_FPR0, a0 | ||
21 | st_d 1, VCPU_FPR1, a0 | ||
22 | st_d 2, VCPU_FPR2, a0 | ||
23 | st_d 3, VCPU_FPR3, a0 | ||
24 | st_d 4, VCPU_FPR4, a0 | ||
25 | st_d 5, VCPU_FPR5, a0 | ||
26 | st_d 6, VCPU_FPR6, a0 | ||
27 | st_d 7, VCPU_FPR7, a0 | ||
28 | st_d 8, VCPU_FPR8, a0 | ||
29 | st_d 9, VCPU_FPR9, a0 | ||
30 | st_d 10, VCPU_FPR10, a0 | ||
31 | st_d 11, VCPU_FPR11, a0 | ||
32 | st_d 12, VCPU_FPR12, a0 | ||
33 | st_d 13, VCPU_FPR13, a0 | ||
34 | st_d 14, VCPU_FPR14, a0 | ||
35 | st_d 15, VCPU_FPR15, a0 | ||
36 | st_d 16, VCPU_FPR16, a0 | ||
37 | st_d 17, VCPU_FPR17, a0 | ||
38 | st_d 18, VCPU_FPR18, a0 | ||
39 | st_d 19, VCPU_FPR19, a0 | ||
40 | st_d 20, VCPU_FPR20, a0 | ||
41 | st_d 21, VCPU_FPR21, a0 | ||
42 | st_d 22, VCPU_FPR22, a0 | ||
43 | st_d 23, VCPU_FPR23, a0 | ||
44 | st_d 24, VCPU_FPR24, a0 | ||
45 | st_d 25, VCPU_FPR25, a0 | ||
46 | st_d 26, VCPU_FPR26, a0 | ||
47 | st_d 27, VCPU_FPR27, a0 | ||
48 | st_d 28, VCPU_FPR28, a0 | ||
49 | st_d 29, VCPU_FPR29, a0 | ||
50 | st_d 30, VCPU_FPR30, a0 | ||
51 | st_d 31, VCPU_FPR31, a0 | ||
52 | jr ra | ||
53 | nop | ||
54 | END(__kvm_save_msa) | ||
55 | |||
56 | LEAF(__kvm_restore_msa) | ||
57 | ld_d 0, VCPU_FPR0, a0 | ||
58 | ld_d 1, VCPU_FPR1, a0 | ||
59 | ld_d 2, VCPU_FPR2, a0 | ||
60 | ld_d 3, VCPU_FPR3, a0 | ||
61 | ld_d 4, VCPU_FPR4, a0 | ||
62 | ld_d 5, VCPU_FPR5, a0 | ||
63 | ld_d 6, VCPU_FPR6, a0 | ||
64 | ld_d 7, VCPU_FPR7, a0 | ||
65 | ld_d 8, VCPU_FPR8, a0 | ||
66 | ld_d 9, VCPU_FPR9, a0 | ||
67 | ld_d 10, VCPU_FPR10, a0 | ||
68 | ld_d 11, VCPU_FPR11, a0 | ||
69 | ld_d 12, VCPU_FPR12, a0 | ||
70 | ld_d 13, VCPU_FPR13, a0 | ||
71 | ld_d 14, VCPU_FPR14, a0 | ||
72 | ld_d 15, VCPU_FPR15, a0 | ||
73 | ld_d 16, VCPU_FPR16, a0 | ||
74 | ld_d 17, VCPU_FPR17, a0 | ||
75 | ld_d 18, VCPU_FPR18, a0 | ||
76 | ld_d 19, VCPU_FPR19, a0 | ||
77 | ld_d 20, VCPU_FPR20, a0 | ||
78 | ld_d 21, VCPU_FPR21, a0 | ||
79 | ld_d 22, VCPU_FPR22, a0 | ||
80 | ld_d 23, VCPU_FPR23, a0 | ||
81 | ld_d 24, VCPU_FPR24, a0 | ||
82 | ld_d 25, VCPU_FPR25, a0 | ||
83 | ld_d 26, VCPU_FPR26, a0 | ||
84 | ld_d 27, VCPU_FPR27, a0 | ||
85 | ld_d 28, VCPU_FPR28, a0 | ||
86 | ld_d 29, VCPU_FPR29, a0 | ||
87 | ld_d 30, VCPU_FPR30, a0 | ||
88 | ld_d 31, VCPU_FPR31, a0 | ||
89 | jr ra | ||
90 | nop | ||
91 | END(__kvm_restore_msa) | ||
92 | |||
93 | .macro kvm_restore_msa_upper wr, off, base | ||
94 | .set push | ||
95 | .set noat | ||
96 | #ifdef CONFIG_64BIT | ||
97 | ld $1, \off(\base) | ||
98 | insert_d \wr, 1 | ||
99 | #elif defined(CONFIG_CPU_LITTLE_ENDIAN) | ||
100 | lw $1, \off(\base) | ||
101 | insert_w \wr, 2 | ||
102 | lw $1, (\off+4)(\base) | ||
103 | insert_w \wr, 3 | ||
104 | #else /* CONFIG_CPU_BIG_ENDIAN */ | ||
105 | lw $1, (\off+4)(\base) | ||
106 | insert_w \wr, 2 | ||
107 | lw $1, \off(\base) | ||
108 | insert_w \wr, 3 | ||
109 | #endif | ||
110 | .set pop | ||
111 | .endm | ||
112 | |||
113 | LEAF(__kvm_restore_msa_upper) | ||
114 | kvm_restore_msa_upper 0, VCPU_FPR0 +8, a0 | ||
115 | kvm_restore_msa_upper 1, VCPU_FPR1 +8, a0 | ||
116 | kvm_restore_msa_upper 2, VCPU_FPR2 +8, a0 | ||
117 | kvm_restore_msa_upper 3, VCPU_FPR3 +8, a0 | ||
118 | kvm_restore_msa_upper 4, VCPU_FPR4 +8, a0 | ||
119 | kvm_restore_msa_upper 5, VCPU_FPR5 +8, a0 | ||
120 | kvm_restore_msa_upper 6, VCPU_FPR6 +8, a0 | ||
121 | kvm_restore_msa_upper 7, VCPU_FPR7 +8, a0 | ||
122 | kvm_restore_msa_upper 8, VCPU_FPR8 +8, a0 | ||
123 | kvm_restore_msa_upper 9, VCPU_FPR9 +8, a0 | ||
124 | kvm_restore_msa_upper 10, VCPU_FPR10+8, a0 | ||
125 | kvm_restore_msa_upper 11, VCPU_FPR11+8, a0 | ||
126 | kvm_restore_msa_upper 12, VCPU_FPR12+8, a0 | ||
127 | kvm_restore_msa_upper 13, VCPU_FPR13+8, a0 | ||
128 | kvm_restore_msa_upper 14, VCPU_FPR14+8, a0 | ||
129 | kvm_restore_msa_upper 15, VCPU_FPR15+8, a0 | ||
130 | kvm_restore_msa_upper 16, VCPU_FPR16+8, a0 | ||
131 | kvm_restore_msa_upper 17, VCPU_FPR17+8, a0 | ||
132 | kvm_restore_msa_upper 18, VCPU_FPR18+8, a0 | ||
133 | kvm_restore_msa_upper 19, VCPU_FPR19+8, a0 | ||
134 | kvm_restore_msa_upper 20, VCPU_FPR20+8, a0 | ||
135 | kvm_restore_msa_upper 21, VCPU_FPR21+8, a0 | ||
136 | kvm_restore_msa_upper 22, VCPU_FPR22+8, a0 | ||
137 | kvm_restore_msa_upper 23, VCPU_FPR23+8, a0 | ||
138 | kvm_restore_msa_upper 24, VCPU_FPR24+8, a0 | ||
139 | kvm_restore_msa_upper 25, VCPU_FPR25+8, a0 | ||
140 | kvm_restore_msa_upper 26, VCPU_FPR26+8, a0 | ||
141 | kvm_restore_msa_upper 27, VCPU_FPR27+8, a0 | ||
142 | kvm_restore_msa_upper 28, VCPU_FPR28+8, a0 | ||
143 | kvm_restore_msa_upper 29, VCPU_FPR29+8, a0 | ||
144 | kvm_restore_msa_upper 30, VCPU_FPR30+8, a0 | ||
145 | kvm_restore_msa_upper 31, VCPU_FPR31+8, a0 | ||
146 | jr ra | ||
147 | nop | ||
148 | END(__kvm_restore_msa_upper) | ||
149 | |||
150 | LEAF(__kvm_restore_msacsr) | ||
151 | lw t0, VCPU_MSA_CSR(a0) | ||
152 | /* | ||
153 | * The ctcmsa must stay at this offset in __kvm_restore_msacsr. | ||
154 | * See kvm_mips_csr_die_notify() which handles t0 containing a value | ||
155 | * which triggers an MSA FP Exception, which must be stepped over and | ||
156 | * ignored since the set cause bits must remain there for the guest. | ||
157 | */ | ||
158 | _ctcmsa MSA_CSR, t0 | ||
159 | jr ra | ||
160 | nop | ||
161 | END(__kvm_restore_msacsr) | ||
diff --git a/arch/mips/kvm/stats.c b/arch/mips/kvm/stats.c index a74d6024c5ad..888bb67070ac 100644 --- a/arch/mips/kvm/stats.c +++ b/arch/mips/kvm/stats.c | |||
@@ -25,6 +25,10 @@ char *kvm_mips_exit_types_str[MAX_KVM_MIPS_EXIT_TYPES] = { | |||
25 | "System Call", | 25 | "System Call", |
26 | "Reserved Inst", | 26 | "Reserved Inst", |
27 | "Break Inst", | 27 | "Break Inst", |
28 | "Trap Inst", | ||
29 | "MSA FPE", | ||
30 | "FPE", | ||
31 | "MSA Disabled", | ||
28 | "D-Cache Flushes", | 32 | "D-Cache Flushes", |
29 | }; | 33 | }; |
30 | 34 | ||
diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c index bbcd82242059..aed0ac2a4972 100644 --- a/arch/mips/kvm/tlb.c +++ b/arch/mips/kvm/tlb.c | |||
@@ -216,6 +216,7 @@ int kvm_mips_host_tlb_write(struct kvm_vcpu *vcpu, unsigned long entryhi, | |||
216 | if (idx > current_cpu_data.tlbsize) { | 216 | if (idx > current_cpu_data.tlbsize) { |
217 | kvm_err("%s: Invalid Index: %d\n", __func__, idx); | 217 | kvm_err("%s: Invalid Index: %d\n", __func__, idx); |
218 | kvm_mips_dump_host_tlbs(); | 218 | kvm_mips_dump_host_tlbs(); |
219 | local_irq_restore(flags); | ||
219 | return -1; | 220 | return -1; |
220 | } | 221 | } |
221 | 222 | ||
@@ -732,6 +733,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
732 | } | 733 | } |
733 | } | 734 | } |
734 | 735 | ||
736 | /* restore guest state to registers */ | ||
737 | kvm_mips_callbacks->vcpu_set_regs(vcpu); | ||
738 | |||
735 | local_irq_restore(flags); | 739 | local_irq_restore(flags); |
736 | 740 | ||
737 | } | 741 | } |
@@ -750,6 +754,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
750 | vcpu->arch.preempt_entryhi = read_c0_entryhi(); | 754 | vcpu->arch.preempt_entryhi = read_c0_entryhi(); |
751 | vcpu->arch.last_sched_cpu = cpu; | 755 | vcpu->arch.last_sched_cpu = cpu; |
752 | 756 | ||
757 | /* save guest state in registers */ | ||
758 | kvm_mips_callbacks->vcpu_get_regs(vcpu); | ||
759 | |||
753 | if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) & | 760 | if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) & |
754 | ASID_VERSION_MASK)) { | 761 | ASID_VERSION_MASK)) { |
755 | kvm_debug("%s: Dropping MMU Context: %#lx\n", __func__, | 762 | kvm_debug("%s: Dropping MMU Context: %#lx\n", __func__, |
diff --git a/arch/mips/kvm/trace.h b/arch/mips/kvm/trace.h index c1388d40663b..bd6437f67dc0 100644 --- a/arch/mips/kvm/trace.h +++ b/arch/mips/kvm/trace.h | |||
@@ -24,18 +24,18 @@ TRACE_EVENT(kvm_exit, | |||
24 | TP_PROTO(struct kvm_vcpu *vcpu, unsigned int reason), | 24 | TP_PROTO(struct kvm_vcpu *vcpu, unsigned int reason), |
25 | TP_ARGS(vcpu, reason), | 25 | TP_ARGS(vcpu, reason), |
26 | TP_STRUCT__entry( | 26 | TP_STRUCT__entry( |
27 | __field(struct kvm_vcpu *, vcpu) | 27 | __field(unsigned long, pc) |
28 | __field(unsigned int, reason) | 28 | __field(unsigned int, reason) |
29 | ), | 29 | ), |
30 | 30 | ||
31 | TP_fast_assign( | 31 | TP_fast_assign( |
32 | __entry->vcpu = vcpu; | 32 | __entry->pc = vcpu->arch.pc; |
33 | __entry->reason = reason; | 33 | __entry->reason = reason; |
34 | ), | 34 | ), |
35 | 35 | ||
36 | TP_printk("[%s]PC: 0x%08lx", | 36 | TP_printk("[%s]PC: 0x%08lx", |
37 | kvm_mips_exit_types_str[__entry->reason], | 37 | kvm_mips_exit_types_str[__entry->reason], |
38 | __entry->vcpu->arch.pc) | 38 | __entry->pc) |
39 | ); | 39 | ); |
40 | 40 | ||
41 | #endif /* _TRACE_KVM_H */ | 41 | #endif /* _TRACE_KVM_H */ |
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index fd7257b70e65..d836ed5b0bc7 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c | |||
@@ -39,16 +39,30 @@ static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva) | |||
39 | 39 | ||
40 | static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu) | 40 | static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu) |
41 | { | 41 | { |
42 | struct mips_coproc *cop0 = vcpu->arch.cop0; | ||
42 | struct kvm_run *run = vcpu->run; | 43 | struct kvm_run *run = vcpu->run; |
43 | uint32_t __user *opc = (uint32_t __user *) vcpu->arch.pc; | 44 | uint32_t __user *opc = (uint32_t __user *) vcpu->arch.pc; |
44 | unsigned long cause = vcpu->arch.host_cp0_cause; | 45 | unsigned long cause = vcpu->arch.host_cp0_cause; |
45 | enum emulation_result er = EMULATE_DONE; | 46 | enum emulation_result er = EMULATE_DONE; |
46 | int ret = RESUME_GUEST; | 47 | int ret = RESUME_GUEST; |
47 | 48 | ||
48 | if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 1) | 49 | if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 1) { |
49 | er = kvm_mips_emulate_fpu_exc(cause, opc, run, vcpu); | 50 | /* FPU Unusable */ |
50 | else | 51 | if (!kvm_mips_guest_has_fpu(&vcpu->arch) || |
52 | (kvm_read_c0_guest_status(cop0) & ST0_CU1) == 0) { | ||
53 | /* | ||
54 | * Unusable/no FPU in guest: | ||
55 | * deliver guest COP1 Unusable Exception | ||
56 | */ | ||
57 | er = kvm_mips_emulate_fpu_exc(cause, opc, run, vcpu); | ||
58 | } else { | ||
59 | /* Restore FPU state */ | ||
60 | kvm_own_fpu(vcpu); | ||
61 | er = EMULATE_DONE; | ||
62 | } | ||
63 | } else { | ||
51 | er = kvm_mips_emulate_inst(cause, opc, run, vcpu); | 64 | er = kvm_mips_emulate_inst(cause, opc, run, vcpu); |
65 | } | ||
52 | 66 | ||
53 | switch (er) { | 67 | switch (er) { |
54 | case EMULATE_DONE: | 68 | case EMULATE_DONE: |
@@ -330,6 +344,107 @@ static int kvm_trap_emul_handle_break(struct kvm_vcpu *vcpu) | |||
330 | return ret; | 344 | return ret; |
331 | } | 345 | } |
332 | 346 | ||
347 | static int kvm_trap_emul_handle_trap(struct kvm_vcpu *vcpu) | ||
348 | { | ||
349 | struct kvm_run *run = vcpu->run; | ||
350 | uint32_t __user *opc = (uint32_t __user *)vcpu->arch.pc; | ||
351 | unsigned long cause = vcpu->arch.host_cp0_cause; | ||
352 | enum emulation_result er = EMULATE_DONE; | ||
353 | int ret = RESUME_GUEST; | ||
354 | |||
355 | er = kvm_mips_emulate_trap_exc(cause, opc, run, vcpu); | ||
356 | if (er == EMULATE_DONE) { | ||
357 | ret = RESUME_GUEST; | ||
358 | } else { | ||
359 | run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||
360 | ret = RESUME_HOST; | ||
361 | } | ||
362 | return ret; | ||
363 | } | ||
364 | |||
365 | static int kvm_trap_emul_handle_msa_fpe(struct kvm_vcpu *vcpu) | ||
366 | { | ||
367 | struct kvm_run *run = vcpu->run; | ||
368 | uint32_t __user *opc = (uint32_t __user *)vcpu->arch.pc; | ||
369 | unsigned long cause = vcpu->arch.host_cp0_cause; | ||
370 | enum emulation_result er = EMULATE_DONE; | ||
371 | int ret = RESUME_GUEST; | ||
372 | |||
373 | er = kvm_mips_emulate_msafpe_exc(cause, opc, run, vcpu); | ||
374 | if (er == EMULATE_DONE) { | ||
375 | ret = RESUME_GUEST; | ||
376 | } else { | ||
377 | run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||
378 | ret = RESUME_HOST; | ||
379 | } | ||
380 | return ret; | ||
381 | } | ||
382 | |||
383 | static int kvm_trap_emul_handle_fpe(struct kvm_vcpu *vcpu) | ||
384 | { | ||
385 | struct kvm_run *run = vcpu->run; | ||
386 | uint32_t __user *opc = (uint32_t __user *)vcpu->arch.pc; | ||
387 | unsigned long cause = vcpu->arch.host_cp0_cause; | ||
388 | enum emulation_result er = EMULATE_DONE; | ||
389 | int ret = RESUME_GUEST; | ||
390 | |||
391 | er = kvm_mips_emulate_fpe_exc(cause, opc, run, vcpu); | ||
392 | if (er == EMULATE_DONE) { | ||
393 | ret = RESUME_GUEST; | ||
394 | } else { | ||
395 | run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||
396 | ret = RESUME_HOST; | ||
397 | } | ||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * kvm_trap_emul_handle_msa_disabled() - Guest used MSA while disabled in root. | ||
403 | * @vcpu: Virtual CPU context. | ||
404 | * | ||
405 | * Handle when the guest attempts to use MSA when it is disabled. | ||
406 | */ | ||
407 | static int kvm_trap_emul_handle_msa_disabled(struct kvm_vcpu *vcpu) | ||
408 | { | ||
409 | struct mips_coproc *cop0 = vcpu->arch.cop0; | ||
410 | struct kvm_run *run = vcpu->run; | ||
411 | uint32_t __user *opc = (uint32_t __user *) vcpu->arch.pc; | ||
412 | unsigned long cause = vcpu->arch.host_cp0_cause; | ||
413 | enum emulation_result er = EMULATE_DONE; | ||
414 | int ret = RESUME_GUEST; | ||
415 | |||
416 | if (!kvm_mips_guest_has_msa(&vcpu->arch) || | ||
417 | (kvm_read_c0_guest_status(cop0) & (ST0_CU1 | ST0_FR)) == ST0_CU1) { | ||
418 | /* | ||
419 | * No MSA in guest, or FPU enabled and not in FR=1 mode, | ||
420 | * guest reserved instruction exception | ||
421 | */ | ||
422 | er = kvm_mips_emulate_ri_exc(cause, opc, run, vcpu); | ||
423 | } else if (!(kvm_read_c0_guest_config5(cop0) & MIPS_CONF5_MSAEN)) { | ||
424 | /* MSA disabled by guest, guest MSA disabled exception */ | ||
425 | er = kvm_mips_emulate_msadis_exc(cause, opc, run, vcpu); | ||
426 | } else { | ||
427 | /* Restore MSA/FPU state */ | ||
428 | kvm_own_msa(vcpu); | ||
429 | er = EMULATE_DONE; | ||
430 | } | ||
431 | |||
432 | switch (er) { | ||
433 | case EMULATE_DONE: | ||
434 | ret = RESUME_GUEST; | ||
435 | break; | ||
436 | |||
437 | case EMULATE_FAIL: | ||
438 | run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||
439 | ret = RESUME_HOST; | ||
440 | break; | ||
441 | |||
442 | default: | ||
443 | BUG(); | ||
444 | } | ||
445 | return ret; | ||
446 | } | ||
447 | |||
333 | static int kvm_trap_emul_vm_init(struct kvm *kvm) | 448 | static int kvm_trap_emul_vm_init(struct kvm *kvm) |
334 | { | 449 | { |
335 | return 0; | 450 | return 0; |
@@ -351,8 +466,9 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu) | |||
351 | * guest will come up as expected, for now we simulate a MIPS 24kc | 466 | * guest will come up as expected, for now we simulate a MIPS 24kc |
352 | */ | 467 | */ |
353 | kvm_write_c0_guest_prid(cop0, 0x00019300); | 468 | kvm_write_c0_guest_prid(cop0, 0x00019300); |
354 | kvm_write_c0_guest_config(cop0, | 469 | /* Have config1, Cacheable, noncoherent, write-back, write allocate */ |
355 | MIPS_CONFIG0 | (0x1 << CP0C0_AR) | | 470 | kvm_write_c0_guest_config(cop0, MIPS_CONF_M | (0x3 << CP0C0_K0) | |
471 | (0x1 << CP0C0_AR) | | ||
356 | (MMU_TYPE_R4000 << CP0C0_MT)); | 472 | (MMU_TYPE_R4000 << CP0C0_MT)); |
357 | 473 | ||
358 | /* Read the cache characteristics from the host Config1 Register */ | 474 | /* Read the cache characteristics from the host Config1 Register */ |
@@ -368,10 +484,18 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu) | |||
368 | (1 << CP0C1_WR) | (1 << CP0C1_CA)); | 484 | (1 << CP0C1_WR) | (1 << CP0C1_CA)); |
369 | kvm_write_c0_guest_config1(cop0, config1); | 485 | kvm_write_c0_guest_config1(cop0, config1); |
370 | 486 | ||
371 | kvm_write_c0_guest_config2(cop0, MIPS_CONFIG2); | 487 | /* Have config3, no tertiary/secondary caches implemented */ |
372 | /* MIPS_CONFIG2 | (read_c0_config2() & 0xfff) */ | 488 | kvm_write_c0_guest_config2(cop0, MIPS_CONF_M); |
373 | kvm_write_c0_guest_config3(cop0, MIPS_CONFIG3 | (0 << CP0C3_VInt) | | 489 | /* MIPS_CONF_M | (read_c0_config2() & 0xfff) */ |
374 | (1 << CP0C3_ULRI)); | 490 | |
491 | /* Have config4, UserLocal */ | ||
492 | kvm_write_c0_guest_config3(cop0, MIPS_CONF_M | MIPS_CONF3_ULRI); | ||
493 | |||
494 | /* Have config5 */ | ||
495 | kvm_write_c0_guest_config4(cop0, MIPS_CONF_M); | ||
496 | |||
497 | /* No config6 */ | ||
498 | kvm_write_c0_guest_config5(cop0, 0); | ||
375 | 499 | ||
376 | /* Set Wait IE/IXMT Ignore in Config7, IAR, AR */ | 500 | /* Set Wait IE/IXMT Ignore in Config7, IAR, AR */ |
377 | kvm_write_c0_guest_config7(cop0, (MIPS_CONF7_WII) | (1 << 10)); | 501 | kvm_write_c0_guest_config7(cop0, (MIPS_CONF7_WII) | (1 << 10)); |
@@ -416,6 +540,7 @@ static int kvm_trap_emul_set_one_reg(struct kvm_vcpu *vcpu, | |||
416 | { | 540 | { |
417 | struct mips_coproc *cop0 = vcpu->arch.cop0; | 541 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
418 | int ret = 0; | 542 | int ret = 0; |
543 | unsigned int cur, change; | ||
419 | 544 | ||
420 | switch (reg->id) { | 545 | switch (reg->id) { |
421 | case KVM_REG_MIPS_CP0_COUNT: | 546 | case KVM_REG_MIPS_CP0_COUNT: |
@@ -444,6 +569,44 @@ static int kvm_trap_emul_set_one_reg(struct kvm_vcpu *vcpu, | |||
444 | kvm_write_c0_guest_cause(cop0, v); | 569 | kvm_write_c0_guest_cause(cop0, v); |
445 | } | 570 | } |
446 | break; | 571 | break; |
572 | case KVM_REG_MIPS_CP0_CONFIG: | ||
573 | /* read-only for now */ | ||
574 | break; | ||
575 | case KVM_REG_MIPS_CP0_CONFIG1: | ||
576 | cur = kvm_read_c0_guest_config1(cop0); | ||
577 | change = (cur ^ v) & kvm_mips_config1_wrmask(vcpu); | ||
578 | if (change) { | ||
579 | v = cur ^ change; | ||
580 | kvm_write_c0_guest_config1(cop0, v); | ||
581 | } | ||
582 | break; | ||
583 | case KVM_REG_MIPS_CP0_CONFIG2: | ||
584 | /* read-only for now */ | ||
585 | break; | ||
586 | case KVM_REG_MIPS_CP0_CONFIG3: | ||
587 | cur = kvm_read_c0_guest_config3(cop0); | ||
588 | change = (cur ^ v) & kvm_mips_config3_wrmask(vcpu); | ||
589 | if (change) { | ||
590 | v = cur ^ change; | ||
591 | kvm_write_c0_guest_config3(cop0, v); | ||
592 | } | ||
593 | break; | ||
594 | case KVM_REG_MIPS_CP0_CONFIG4: | ||
595 | cur = kvm_read_c0_guest_config4(cop0); | ||
596 | change = (cur ^ v) & kvm_mips_config4_wrmask(vcpu); | ||
597 | if (change) { | ||
598 | v = cur ^ change; | ||
599 | kvm_write_c0_guest_config4(cop0, v); | ||
600 | } | ||
601 | break; | ||
602 | case KVM_REG_MIPS_CP0_CONFIG5: | ||
603 | cur = kvm_read_c0_guest_config5(cop0); | ||
604 | change = (cur ^ v) & kvm_mips_config5_wrmask(vcpu); | ||
605 | if (change) { | ||
606 | v = cur ^ change; | ||
607 | kvm_write_c0_guest_config5(cop0, v); | ||
608 | } | ||
609 | break; | ||
447 | case KVM_REG_MIPS_COUNT_CTL: | 610 | case KVM_REG_MIPS_COUNT_CTL: |
448 | ret = kvm_mips_set_count_ctl(vcpu, v); | 611 | ret = kvm_mips_set_count_ctl(vcpu, v); |
449 | break; | 612 | break; |
@@ -459,6 +622,18 @@ static int kvm_trap_emul_set_one_reg(struct kvm_vcpu *vcpu, | |||
459 | return ret; | 622 | return ret; |
460 | } | 623 | } |
461 | 624 | ||
625 | static int kvm_trap_emul_vcpu_get_regs(struct kvm_vcpu *vcpu) | ||
626 | { | ||
627 | kvm_lose_fpu(vcpu); | ||
628 | |||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | static int kvm_trap_emul_vcpu_set_regs(struct kvm_vcpu *vcpu) | ||
633 | { | ||
634 | return 0; | ||
635 | } | ||
636 | |||
462 | static struct kvm_mips_callbacks kvm_trap_emul_callbacks = { | 637 | static struct kvm_mips_callbacks kvm_trap_emul_callbacks = { |
463 | /* exit handlers */ | 638 | /* exit handlers */ |
464 | .handle_cop_unusable = kvm_trap_emul_handle_cop_unusable, | 639 | .handle_cop_unusable = kvm_trap_emul_handle_cop_unusable, |
@@ -470,6 +645,10 @@ static struct kvm_mips_callbacks kvm_trap_emul_callbacks = { | |||
470 | .handle_syscall = kvm_trap_emul_handle_syscall, | 645 | .handle_syscall = kvm_trap_emul_handle_syscall, |
471 | .handle_res_inst = kvm_trap_emul_handle_res_inst, | 646 | .handle_res_inst = kvm_trap_emul_handle_res_inst, |
472 | .handle_break = kvm_trap_emul_handle_break, | 647 | .handle_break = kvm_trap_emul_handle_break, |
648 | .handle_trap = kvm_trap_emul_handle_trap, | ||
649 | .handle_msa_fpe = kvm_trap_emul_handle_msa_fpe, | ||
650 | .handle_fpe = kvm_trap_emul_handle_fpe, | ||
651 | .handle_msa_disabled = kvm_trap_emul_handle_msa_disabled, | ||
473 | 652 | ||
474 | .vm_init = kvm_trap_emul_vm_init, | 653 | .vm_init = kvm_trap_emul_vm_init, |
475 | .vcpu_init = kvm_trap_emul_vcpu_init, | 654 | .vcpu_init = kvm_trap_emul_vcpu_init, |
@@ -483,6 +662,8 @@ static struct kvm_mips_callbacks kvm_trap_emul_callbacks = { | |||
483 | .irq_clear = kvm_mips_irq_clear_cb, | 662 | .irq_clear = kvm_mips_irq_clear_cb, |
484 | .get_one_reg = kvm_trap_emul_get_one_reg, | 663 | .get_one_reg = kvm_trap_emul_get_one_reg, |
485 | .set_one_reg = kvm_trap_emul_set_one_reg, | 664 | .set_one_reg = kvm_trap_emul_set_one_reg, |
665 | .vcpu_get_regs = kvm_trap_emul_vcpu_get_regs, | ||
666 | .vcpu_set_regs = kvm_trap_emul_vcpu_set_regs, | ||
486 | }; | 667 | }; |
487 | 668 | ||
488 | int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks) | 669 | int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks) |
diff --git a/arch/mn10300/include/asm/pgtable.h b/arch/mn10300/include/asm/pgtable.h index afab728ab65e..96d3f9deb59c 100644 --- a/arch/mn10300/include/asm/pgtable.h +++ b/arch/mn10300/include/asm/pgtable.h | |||
@@ -56,7 +56,9 @@ extern void paging_init(void); | |||
56 | #define PGDIR_SHIFT 22 | 56 | #define PGDIR_SHIFT 22 |
57 | #define PTRS_PER_PGD 1024 | 57 | #define PTRS_PER_PGD 1024 |
58 | #define PTRS_PER_PUD 1 /* we don't really have any PUD physically */ | 58 | #define PTRS_PER_PUD 1 /* we don't really have any PUD physically */ |
59 | #define __PAGETABLE_PUD_FOLDED | ||
59 | #define PTRS_PER_PMD 1 /* we don't really have any PMD physically */ | 60 | #define PTRS_PER_PMD 1 /* we don't really have any PMD physically */ |
61 | #define __PAGETABLE_PMD_FOLDED | ||
60 | #define PTRS_PER_PTE 1024 | 62 | #define PTRS_PER_PTE 1024 |
61 | 63 | ||
62 | #define PGD_SIZE PAGE_SIZE | 64 | #define PGD_SIZE PAGE_SIZE |
diff --git a/arch/nios2/include/asm/ptrace.h b/arch/nios2/include/asm/ptrace.h index 20fb1cf2dab6..642462144872 100644 --- a/arch/nios2/include/asm/ptrace.h +++ b/arch/nios2/include/asm/ptrace.h | |||
@@ -15,7 +15,54 @@ | |||
15 | 15 | ||
16 | #include <uapi/asm/ptrace.h> | 16 | #include <uapi/asm/ptrace.h> |
17 | 17 | ||
18 | /* This struct defines the way the registers are stored on the | ||
19 | stack during a system call. */ | ||
20 | |||
18 | #ifndef __ASSEMBLY__ | 21 | #ifndef __ASSEMBLY__ |
22 | struct pt_regs { | ||
23 | unsigned long r8; /* r8-r15 Caller-saved GP registers */ | ||
24 | unsigned long r9; | ||
25 | unsigned long r10; | ||
26 | unsigned long r11; | ||
27 | unsigned long r12; | ||
28 | unsigned long r13; | ||
29 | unsigned long r14; | ||
30 | unsigned long r15; | ||
31 | unsigned long r1; /* Assembler temporary */ | ||
32 | unsigned long r2; /* Retval LS 32bits */ | ||
33 | unsigned long r3; /* Retval MS 32bits */ | ||
34 | unsigned long r4; /* r4-r7 Register arguments */ | ||
35 | unsigned long r5; | ||
36 | unsigned long r6; | ||
37 | unsigned long r7; | ||
38 | unsigned long orig_r2; /* Copy of r2 ?? */ | ||
39 | unsigned long ra; /* Return address */ | ||
40 | unsigned long fp; /* Frame pointer */ | ||
41 | unsigned long sp; /* Stack pointer */ | ||
42 | unsigned long gp; /* Global pointer */ | ||
43 | unsigned long estatus; | ||
44 | unsigned long ea; /* Exception return address (pc) */ | ||
45 | unsigned long orig_r7; | ||
46 | }; | ||
47 | |||
48 | /* | ||
49 | * This is the extended stack used by signal handlers and the context | ||
50 | * switcher: it's pushed after the normal "struct pt_regs". | ||
51 | */ | ||
52 | struct switch_stack { | ||
53 | unsigned long r16; /* r16-r23 Callee-saved GP registers */ | ||
54 | unsigned long r17; | ||
55 | unsigned long r18; | ||
56 | unsigned long r19; | ||
57 | unsigned long r20; | ||
58 | unsigned long r21; | ||
59 | unsigned long r22; | ||
60 | unsigned long r23; | ||
61 | unsigned long fp; | ||
62 | unsigned long gp; | ||
63 | unsigned long ra; | ||
64 | }; | ||
65 | |||
19 | #define user_mode(regs) (((regs)->estatus & ESTATUS_EU)) | 66 | #define user_mode(regs) (((regs)->estatus & ESTATUS_EU)) |
20 | 67 | ||
21 | #define instruction_pointer(regs) ((regs)->ra) | 68 | #define instruction_pointer(regs) ((regs)->ra) |
diff --git a/arch/nios2/include/asm/thread_info.h b/arch/nios2/include/asm/thread_info.h index 1f266575beb5..a16e55cbd8ad 100644 --- a/arch/nios2/include/asm/thread_info.h +++ b/arch/nios2/include/asm/thread_info.h | |||
@@ -47,7 +47,6 @@ struct thread_info { | |||
47 | 0-0x7FFFFFFF for user-thead | 47 | 0-0x7FFFFFFF for user-thead |
48 | 0-0xFFFFFFFF for kernel-thread | 48 | 0-0xFFFFFFFF for kernel-thread |
49 | */ | 49 | */ |
50 | struct restart_block restart_block; | ||
51 | struct pt_regs *regs; | 50 | struct pt_regs *regs; |
52 | }; | 51 | }; |
53 | 52 | ||
@@ -64,9 +63,6 @@ struct thread_info { | |||
64 | .cpu = 0, \ | 63 | .cpu = 0, \ |
65 | .preempt_count = INIT_PREEMPT_COUNT, \ | 64 | .preempt_count = INIT_PREEMPT_COUNT, \ |
66 | .addr_limit = KERNEL_DS, \ | 65 | .addr_limit = KERNEL_DS, \ |
67 | .restart_block = { \ | ||
68 | .fn = do_no_restart_syscall, \ | ||
69 | }, \ | ||
70 | } | 66 | } |
71 | 67 | ||
72 | #define init_thread_info (init_thread_union.thread_info) | 68 | #define init_thread_info (init_thread_union.thread_info) |
diff --git a/arch/nios2/include/asm/ucontext.h b/arch/nios2/include/asm/ucontext.h deleted file mode 100644 index 2c87614b0f6e..000000000000 --- a/arch/nios2/include/asm/ucontext.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch> | ||
3 | * Copyright (C) 2004 Microtronix Datacom Ltd | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #ifndef _ASM_NIOS2_UCONTEXT_H | ||
11 | #define _ASM_NIOS2_UCONTEXT_H | ||
12 | |||
13 | typedef int greg_t; | ||
14 | #define NGREG 32 | ||
15 | typedef greg_t gregset_t[NGREG]; | ||
16 | |||
17 | struct mcontext { | ||
18 | int version; | ||
19 | gregset_t gregs; | ||
20 | }; | ||
21 | |||
22 | #define MCONTEXT_VERSION 2 | ||
23 | |||
24 | struct ucontext { | ||
25 | unsigned long uc_flags; | ||
26 | struct ucontext *uc_link; | ||
27 | stack_t uc_stack; | ||
28 | struct mcontext uc_mcontext; | ||
29 | sigset_t uc_sigmask; /* mask last for extensibility */ | ||
30 | }; | ||
31 | |||
32 | #endif | ||
diff --git a/arch/nios2/include/uapi/asm/Kbuild b/arch/nios2/include/uapi/asm/Kbuild index 4f07ca3f8d10..e0bb972a50d7 100644 --- a/arch/nios2/include/uapi/asm/Kbuild +++ b/arch/nios2/include/uapi/asm/Kbuild | |||
@@ -1,4 +1,5 @@ | |||
1 | include include/uapi/asm-generic/Kbuild.asm | 1 | include include/uapi/asm-generic/Kbuild.asm |
2 | 2 | ||
3 | header-y += elf.h | 3 | header-y += elf.h |
4 | header-y += ucontext.h | 4 | |
5 | generic-y += ucontext.h | ||
diff --git a/arch/nios2/include/uapi/asm/elf.h b/arch/nios2/include/uapi/asm/elf.h index a5b91ae5cf56..6f06d3b2949e 100644 --- a/arch/nios2/include/uapi/asm/elf.h +++ b/arch/nios2/include/uapi/asm/elf.h | |||
@@ -50,9 +50,7 @@ | |||
50 | 50 | ||
51 | typedef unsigned long elf_greg_t; | 51 | typedef unsigned long elf_greg_t; |
52 | 52 | ||
53 | #define ELF_NGREG \ | 53 | #define ELF_NGREG 49 |
54 | ((sizeof(struct pt_regs) + sizeof(struct switch_stack)) / \ | ||
55 | sizeof(elf_greg_t)) | ||
56 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | 54 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; |
57 | 55 | ||
58 | typedef unsigned long elf_fpregset_t; | 56 | typedef unsigned long elf_fpregset_t; |
diff --git a/arch/nios2/include/uapi/asm/ptrace.h b/arch/nios2/include/uapi/asm/ptrace.h index e83a7c9d1c36..eff00e67c0a2 100644 --- a/arch/nios2/include/uapi/asm/ptrace.h +++ b/arch/nios2/include/uapi/asm/ptrace.h | |||
@@ -60,60 +60,21 @@ | |||
60 | #define PTR_IPENDING 37 | 60 | #define PTR_IPENDING 37 |
61 | #define PTR_CPUID 38 | 61 | #define PTR_CPUID 38 |
62 | #define PTR_CTL6 39 | 62 | #define PTR_CTL6 39 |
63 | #define PTR_CTL7 40 | 63 | #define PTR_EXCEPTION 40 |
64 | #define PTR_PTEADDR 41 | 64 | #define PTR_PTEADDR 41 |
65 | #define PTR_TLBACC 42 | 65 | #define PTR_TLBACC 42 |
66 | #define PTR_TLBMISC 43 | 66 | #define PTR_TLBMISC 43 |
67 | #define PTR_ECCINJ 44 | ||
68 | #define PTR_BADADDR 45 | ||
69 | #define PTR_CONFIG 46 | ||
70 | #define PTR_MPUBASE 47 | ||
71 | #define PTR_MPUACC 48 | ||
67 | 72 | ||
68 | #define NUM_PTRACE_REG (PTR_TLBMISC + 1) | 73 | #define NUM_PTRACE_REG (PTR_MPUACC + 1) |
69 | 74 | ||
70 | /* this struct defines the way the registers are stored on the | 75 | /* User structures for general purpose registers. */ |
71 | stack during a system call. | 76 | struct user_pt_regs { |
72 | 77 | __u32 regs[49]; | |
73 | There is a fake_regs in setup.c that has to match pt_regs.*/ | ||
74 | |||
75 | struct pt_regs { | ||
76 | unsigned long r8; /* r8-r15 Caller-saved GP registers */ | ||
77 | unsigned long r9; | ||
78 | unsigned long r10; | ||
79 | unsigned long r11; | ||
80 | unsigned long r12; | ||
81 | unsigned long r13; | ||
82 | unsigned long r14; | ||
83 | unsigned long r15; | ||
84 | unsigned long r1; /* Assembler temporary */ | ||
85 | unsigned long r2; /* Retval LS 32bits */ | ||
86 | unsigned long r3; /* Retval MS 32bits */ | ||
87 | unsigned long r4; /* r4-r7 Register arguments */ | ||
88 | unsigned long r5; | ||
89 | unsigned long r6; | ||
90 | unsigned long r7; | ||
91 | unsigned long orig_r2; /* Copy of r2 ?? */ | ||
92 | unsigned long ra; /* Return address */ | ||
93 | unsigned long fp; /* Frame pointer */ | ||
94 | unsigned long sp; /* Stack pointer */ | ||
95 | unsigned long gp; /* Global pointer */ | ||
96 | unsigned long estatus; | ||
97 | unsigned long ea; /* Exception return address (pc) */ | ||
98 | unsigned long orig_r7; | ||
99 | }; | ||
100 | |||
101 | /* | ||
102 | * This is the extended stack used by signal handlers and the context | ||
103 | * switcher: it's pushed after the normal "struct pt_regs". | ||
104 | */ | ||
105 | struct switch_stack { | ||
106 | unsigned long r16; /* r16-r23 Callee-saved GP registers */ | ||
107 | unsigned long r17; | ||
108 | unsigned long r18; | ||
109 | unsigned long r19; | ||
110 | unsigned long r20; | ||
111 | unsigned long r21; | ||
112 | unsigned long r22; | ||
113 | unsigned long r23; | ||
114 | unsigned long fp; | ||
115 | unsigned long gp; | ||
116 | unsigned long ra; | ||
117 | }; | 78 | }; |
118 | 79 | ||
119 | #endif /* __ASSEMBLY__ */ | 80 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/nios2/include/uapi/asm/sigcontext.h b/arch/nios2/include/uapi/asm/sigcontext.h index 7b8bb41867d4..b67944a50927 100644 --- a/arch/nios2/include/uapi/asm/sigcontext.h +++ b/arch/nios2/include/uapi/asm/sigcontext.h | |||
@@ -15,14 +15,16 @@ | |||
15 | * details. | 15 | * details. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #ifndef _ASM_NIOS2_SIGCONTEXT_H | 18 | #ifndef _UAPI__ASM_SIGCONTEXT_H |
19 | #define _ASM_NIOS2_SIGCONTEXT_H | 19 | #define _UAPI__ASM_SIGCONTEXT_H |
20 | 20 | ||
21 | #include <asm/ptrace.h> | 21 | #include <linux/types.h> |
22 | |||
23 | #define MCONTEXT_VERSION 2 | ||
22 | 24 | ||
23 | struct sigcontext { | 25 | struct sigcontext { |
24 | struct pt_regs regs; | 26 | int version; |
25 | unsigned long sc_mask; /* old sigmask */ | 27 | unsigned long gregs[32]; |
26 | }; | 28 | }; |
27 | 29 | ||
28 | #endif | 30 | #endif |
diff --git a/arch/nios2/kernel/entry.S b/arch/nios2/kernel/entry.S index 7729bd3f2e79..27b006c52e12 100644 --- a/arch/nios2/kernel/entry.S +++ b/arch/nios2/kernel/entry.S | |||
@@ -161,7 +161,7 @@ ENTRY(inthandler) | |||
161 | *********************************************************************** | 161 | *********************************************************************** |
162 | */ | 162 | */ |
163 | ENTRY(handle_trap) | 163 | ENTRY(handle_trap) |
164 | ldw r24, -4(ea) /* instruction that caused the exception */ | 164 | ldwio r24, -4(ea) /* instruction that caused the exception */ |
165 | srli r24, r24, 4 | 165 | srli r24, r24, 4 |
166 | andi r24, r24, 0x7c | 166 | andi r24, r24, 0x7c |
167 | movia r9,trap_table | 167 | movia r9,trap_table |
diff --git a/arch/nios2/kernel/signal.c b/arch/nios2/kernel/signal.c index 2d0ea25be171..20662b0f6c9e 100644 --- a/arch/nios2/kernel/signal.c +++ b/arch/nios2/kernel/signal.c | |||
@@ -39,11 +39,11 @@ static inline int rt_restore_ucontext(struct pt_regs *regs, | |||
39 | struct ucontext *uc, int *pr2) | 39 | struct ucontext *uc, int *pr2) |
40 | { | 40 | { |
41 | int temp; | 41 | int temp; |
42 | greg_t *gregs = uc->uc_mcontext.gregs; | 42 | unsigned long *gregs = uc->uc_mcontext.gregs; |
43 | int err; | 43 | int err; |
44 | 44 | ||
45 | /* Always make any pending restarted system calls return -EINTR */ | 45 | /* Always make any pending restarted system calls return -EINTR */ |
46 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 46 | current->restart_block.fn = do_no_restart_syscall; |
47 | 47 | ||
48 | err = __get_user(temp, &uc->uc_mcontext.version); | 48 | err = __get_user(temp, &uc->uc_mcontext.version); |
49 | if (temp != MCONTEXT_VERSION) | 49 | if (temp != MCONTEXT_VERSION) |
@@ -127,7 +127,7 @@ badframe: | |||
127 | static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) | 127 | static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) |
128 | { | 128 | { |
129 | struct switch_stack *sw = (struct switch_stack *)regs - 1; | 129 | struct switch_stack *sw = (struct switch_stack *)regs - 1; |
130 | greg_t *gregs = uc->uc_mcontext.gregs; | 130 | unsigned long *gregs = uc->uc_mcontext.gregs; |
131 | int err = 0; | 131 | int err = 0; |
132 | 132 | ||
133 | err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); | 133 | err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); |
diff --git a/arch/nios2/mm/cacheflush.c b/arch/nios2/mm/cacheflush.c index 2ae482b42669..796642932e2e 100644 --- a/arch/nios2/mm/cacheflush.c +++ b/arch/nios2/mm/cacheflush.c | |||
@@ -23,9 +23,6 @@ static void __flush_dcache(unsigned long start, unsigned long end) | |||
23 | end += (cpuinfo.dcache_line_size - 1); | 23 | end += (cpuinfo.dcache_line_size - 1); |
24 | end &= ~(cpuinfo.dcache_line_size - 1); | 24 | end &= ~(cpuinfo.dcache_line_size - 1); |
25 | 25 | ||
26 | if (end > start + cpuinfo.dcache_size) | ||
27 | end = start + cpuinfo.dcache_size; | ||
28 | |||
29 | for (addr = start; addr < end; addr += cpuinfo.dcache_line_size) { | 26 | for (addr = start; addr < end; addr += cpuinfo.dcache_line_size) { |
30 | __asm__ __volatile__ (" flushda 0(%0)\n" | 27 | __asm__ __volatile__ (" flushda 0(%0)\n" |
31 | : /* Outputs */ | 28 | : /* Outputs */ |
diff --git a/arch/nios2/mm/fault.c b/arch/nios2/mm/fault.c index 0d231adfe576..0c9b6afe69e9 100644 --- a/arch/nios2/mm/fault.c +++ b/arch/nios2/mm/fault.c | |||
@@ -126,7 +126,6 @@ good_area: | |||
126 | break; | 126 | break; |
127 | } | 127 | } |
128 | 128 | ||
129 | survive: | ||
130 | /* | 129 | /* |
131 | * If for any reason at all we couldn't handle the fault, | 130 | * If for any reason at all we couldn't handle the fault, |
132 | * make sure we exit gracefully rather than endlessly redo | 131 | * make sure we exit gracefully rather than endlessly redo |
@@ -220,11 +219,6 @@ no_context: | |||
220 | */ | 219 | */ |
221 | out_of_memory: | 220 | out_of_memory: |
222 | up_read(&mm->mmap_sem); | 221 | up_read(&mm->mmap_sem); |
223 | if (is_global_init(tsk)) { | ||
224 | yield(); | ||
225 | down_read(&mm->mmap_sem); | ||
226 | goto survive; | ||
227 | } | ||
228 | if (!user_mode(regs)) | 222 | if (!user_mode(regs)) |
229 | goto no_context; | 223 | goto no_context; |
230 | pagefault_out_of_memory(); | 224 | pagefault_out_of_memory(); |
diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h index f213f5b4c423..d17437238a2c 100644 --- a/arch/parisc/include/asm/pgalloc.h +++ b/arch/parisc/include/asm/pgalloc.h | |||
@@ -26,7 +26,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) | |||
26 | 26 | ||
27 | if (likely(pgd != NULL)) { | 27 | if (likely(pgd != NULL)) { |
28 | memset(pgd, 0, PAGE_SIZE<<PGD_ALLOC_ORDER); | 28 | memset(pgd, 0, PAGE_SIZE<<PGD_ALLOC_ORDER); |
29 | #ifdef CONFIG_64BIT | 29 | #if PT_NLEVELS == 3 |
30 | actual_pgd += PTRS_PER_PGD; | 30 | actual_pgd += PTRS_PER_PGD; |
31 | /* Populate first pmd with allocated memory. We mark it | 31 | /* Populate first pmd with allocated memory. We mark it |
32 | * with PxD_FLAG_ATTACHED as a signal to the system that this | 32 | * with PxD_FLAG_ATTACHED as a signal to the system that this |
@@ -45,7 +45,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) | |||
45 | 45 | ||
46 | static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) | 46 | static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) |
47 | { | 47 | { |
48 | #ifdef CONFIG_64BIT | 48 | #if PT_NLEVELS == 3 |
49 | pgd -= PTRS_PER_PGD; | 49 | pgd -= PTRS_PER_PGD; |
50 | #endif | 50 | #endif |
51 | free_pages((unsigned long)pgd, PGD_ALLOC_ORDER); | 51 | free_pages((unsigned long)pgd, PGD_ALLOC_ORDER); |
@@ -72,12 +72,15 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |||
72 | 72 | ||
73 | static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | 73 | static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) |
74 | { | 74 | { |
75 | #ifdef CONFIG_64BIT | ||
76 | if(pmd_flag(*pmd) & PxD_FLAG_ATTACHED) | 75 | if(pmd_flag(*pmd) & PxD_FLAG_ATTACHED) |
77 | /* This is the permanent pmd attached to the pgd; | 76 | /* |
78 | * cannot free it */ | 77 | * This is the permanent pmd attached to the pgd; |
78 | * cannot free it. | ||
79 | * Increment the counter to compensate for the decrement | ||
80 | * done by generic mm code. | ||
81 | */ | ||
82 | mm_inc_nr_pmds(mm); | ||
79 | return; | 83 | return; |
80 | #endif | ||
81 | free_pages((unsigned long)pmd, PMD_ORDER); | 84 | free_pages((unsigned long)pmd, PMD_ORDER); |
82 | } | 85 | } |
83 | 86 | ||
@@ -99,7 +102,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |||
99 | static inline void | 102 | static inline void |
100 | pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) | 103 | pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) |
101 | { | 104 | { |
102 | #ifdef CONFIG_64BIT | 105 | #if PT_NLEVELS == 3 |
103 | /* preserve the gateway marker if this is the beginning of | 106 | /* preserve the gateway marker if this is the beginning of |
104 | * the permanent pmd */ | 107 | * the permanent pmd */ |
105 | if(pmd_flag(*pmd) & PxD_FLAG_ATTACHED) | 108 | if(pmd_flag(*pmd) & PxD_FLAG_ATTACHED) |
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index 8c966b2270aa..15207b9362bf 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h | |||
@@ -96,6 +96,7 @@ extern void purge_tlb_entries(struct mm_struct *, unsigned long); | |||
96 | #if PT_NLEVELS == 3 | 96 | #if PT_NLEVELS == 3 |
97 | #define BITS_PER_PMD (PAGE_SHIFT + PMD_ORDER - BITS_PER_PMD_ENTRY) | 97 | #define BITS_PER_PMD (PAGE_SHIFT + PMD_ORDER - BITS_PER_PMD_ENTRY) |
98 | #else | 98 | #else |
99 | #define __PAGETABLE_PMD_FOLDED | ||
99 | #define BITS_PER_PMD 0 | 100 | #define BITS_PER_PMD 0 |
100 | #endif | 101 | #endif |
101 | #define PTRS_PER_PMD (1UL << BITS_PER_PMD) | 102 | #define PTRS_PER_PMD (1UL << BITS_PER_PMD) |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 5a8997d63899..8eefb12d1d33 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
@@ -55,8 +55,8 @@ | |||
55 | #define ENTRY_COMP(_name_) .word sys_##_name_ | 55 | #define ENTRY_COMP(_name_) .word sys_##_name_ |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | ENTRY_SAME(restart_syscall) /* 0 */ | 58 | 90: ENTRY_SAME(restart_syscall) /* 0 */ |
59 | ENTRY_SAME(exit) | 59 | 91: ENTRY_SAME(exit) |
60 | ENTRY_SAME(fork_wrapper) | 60 | ENTRY_SAME(fork_wrapper) |
61 | ENTRY_SAME(read) | 61 | ENTRY_SAME(read) |
62 | ENTRY_SAME(write) | 62 | ENTRY_SAME(write) |
@@ -439,7 +439,10 @@ | |||
439 | ENTRY_SAME(bpf) | 439 | ENTRY_SAME(bpf) |
440 | ENTRY_COMP(execveat) | 440 | ENTRY_COMP(execveat) |
441 | 441 | ||
442 | /* Nothing yet */ | 442 | |
443 | .ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b)) | ||
444 | .error "size of syscall table does not fit value of __NR_Linux_syscalls" | ||
445 | .endif | ||
443 | 446 | ||
444 | #undef ENTRY_SAME | 447 | #undef ENTRY_SAME |
445 | #undef ENTRY_DIFF | 448 | #undef ENTRY_DIFF |
diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index 2bf8e9307be9..4c8ad592ae33 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h | |||
@@ -55,7 +55,7 @@ static inline cpumask_t cpu_thread_mask_to_cores(const struct cpumask *threads) | |||
55 | 55 | ||
56 | static inline int cpu_nr_cores(void) | 56 | static inline int cpu_nr_cores(void) |
57 | { | 57 | { |
58 | return NR_CPUS >> threads_shift; | 58 | return nr_cpu_ids >> threads_shift; |
59 | } | 59 | } |
60 | 60 | ||
61 | static inline cpumask_t cpu_online_cores_map(void) | 61 | static inline cpumask_t cpu_online_cores_map(void) |
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 9cfa3706a1b8..f1ea5972f6ec 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h | |||
@@ -113,6 +113,7 @@ extern void iommu_register_group(struct iommu_table *tbl, | |||
113 | int pci_domain_number, unsigned long pe_num); | 113 | int pci_domain_number, unsigned long pe_num); |
114 | extern int iommu_add_device(struct device *dev); | 114 | extern int iommu_add_device(struct device *dev); |
115 | extern void iommu_del_device(struct device *dev); | 115 | extern void iommu_del_device(struct device *dev); |
116 | extern int __init tce_iommu_bus_notifier_init(void); | ||
116 | #else | 117 | #else |
117 | static inline void iommu_register_group(struct iommu_table *tbl, | 118 | static inline void iommu_register_group(struct iommu_table *tbl, |
118 | int pci_domain_number, | 119 | int pci_domain_number, |
@@ -128,6 +129,11 @@ static inline int iommu_add_device(struct device *dev) | |||
128 | static inline void iommu_del_device(struct device *dev) | 129 | static inline void iommu_del_device(struct device *dev) |
129 | { | 130 | { |
130 | } | 131 | } |
132 | |||
133 | static inline int __init tce_iommu_bus_notifier_init(void) | ||
134 | { | ||
135 | return 0; | ||
136 | } | ||
131 | #endif /* !CONFIG_IOMMU_API */ | 137 | #endif /* !CONFIG_IOMMU_API */ |
132 | 138 | ||
133 | static inline void set_iommu_table_base_and_group(struct device *dev, | 139 | static inline void set_iommu_table_base_and_group(struct device *dev, |
diff --git a/arch/powerpc/include/asm/irq_work.h b/arch/powerpc/include/asm/irq_work.h new file mode 100644 index 000000000000..744fd54de374 --- /dev/null +++ b/arch/powerpc/include/asm/irq_work.h | |||
@@ -0,0 +1,9 @@ | |||
1 | #ifndef _ASM_POWERPC_IRQ_WORK_H | ||
2 | #define _ASM_POWERPC_IRQ_WORK_H | ||
3 | |||
4 | static inline bool arch_irq_work_has_interrupt(void) | ||
5 | { | ||
6 | return true; | ||
7 | } | ||
8 | |||
9 | #endif /* _ASM_POWERPC_IRQ_WORK_H */ | ||
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 03cd858a401c..4cbe23af400a 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h | |||
@@ -153,6 +153,7 @@ | |||
153 | #define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff | 153 | #define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff |
154 | #define PPC_INST_MFTMR 0x7c0002dc | 154 | #define PPC_INST_MFTMR 0x7c0002dc |
155 | #define PPC_INST_MSGSND 0x7c00019c | 155 | #define PPC_INST_MSGSND 0x7c00019c |
156 | #define PPC_INST_MSGCLR 0x7c0001dc | ||
156 | #define PPC_INST_MSGSNDP 0x7c00011c | 157 | #define PPC_INST_MSGSNDP 0x7c00011c |
157 | #define PPC_INST_MTTMR 0x7c0003dc | 158 | #define PPC_INST_MTTMR 0x7c0003dc |
158 | #define PPC_INST_NOP 0x60000000 | 159 | #define PPC_INST_NOP 0x60000000 |
@@ -309,6 +310,8 @@ | |||
309 | ___PPC_RB(b) | __PPC_EH(eh)) | 310 | ___PPC_RB(b) | __PPC_EH(eh)) |
310 | #define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \ | 311 | #define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \ |
311 | ___PPC_RB(b)) | 312 | ___PPC_RB(b)) |
313 | #define PPC_MSGCLR(b) stringify_in_c(.long PPC_INST_MSGCLR | \ | ||
314 | ___PPC_RB(b)) | ||
312 | #define PPC_MSGSNDP(b) stringify_in_c(.long PPC_INST_MSGSNDP | \ | 315 | #define PPC_MSGSNDP(b) stringify_in_c(.long PPC_INST_MSGSNDP | \ |
313 | ___PPC_RB(b)) | 316 | ___PPC_RB(b)) |
314 | #define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \ | 317 | #define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \ |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 1c874fb533bb..af56b5c6c81a 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -608,13 +608,16 @@ | |||
608 | #define SRR1_ISI_N_OR_G 0x10000000 /* ISI: Access is no-exec or G */ | 608 | #define SRR1_ISI_N_OR_G 0x10000000 /* ISI: Access is no-exec or G */ |
609 | #define SRR1_ISI_PROT 0x08000000 /* ISI: Other protection fault */ | 609 | #define SRR1_ISI_PROT 0x08000000 /* ISI: Other protection fault */ |
610 | #define SRR1_WAKEMASK 0x00380000 /* reason for wakeup */ | 610 | #define SRR1_WAKEMASK 0x00380000 /* reason for wakeup */ |
611 | #define SRR1_WAKEMASK_P8 0x003c0000 /* reason for wakeup on POWER8 */ | ||
611 | #define SRR1_WAKESYSERR 0x00300000 /* System error */ | 612 | #define SRR1_WAKESYSERR 0x00300000 /* System error */ |
612 | #define SRR1_WAKEEE 0x00200000 /* External interrupt */ | 613 | #define SRR1_WAKEEE 0x00200000 /* External interrupt */ |
613 | #define SRR1_WAKEMT 0x00280000 /* mtctrl */ | 614 | #define SRR1_WAKEMT 0x00280000 /* mtctrl */ |
614 | #define SRR1_WAKEHMI 0x00280000 /* Hypervisor maintenance */ | 615 | #define SRR1_WAKEHMI 0x00280000 /* Hypervisor maintenance */ |
615 | #define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */ | 616 | #define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */ |
617 | #define SRR1_WAKEDBELL 0x00140000 /* Privileged doorbell on P8 */ | ||
616 | #define SRR1_WAKETHERM 0x00100000 /* Thermal management interrupt */ | 618 | #define SRR1_WAKETHERM 0x00100000 /* Thermal management interrupt */ |
617 | #define SRR1_WAKERESET 0x00100000 /* System reset */ | 619 | #define SRR1_WAKERESET 0x00100000 /* System reset */ |
620 | #define SRR1_WAKEHDBELL 0x000c0000 /* Hypervisor doorbell on P8 */ | ||
618 | #define SRR1_WAKESTATE 0x00030000 /* Powersave exit mask [46:47] */ | 621 | #define SRR1_WAKESTATE 0x00030000 /* Powersave exit mask [46:47] */ |
619 | #define SRR1_WS_DEEPEST 0x00030000 /* Some resources not maintained, | 622 | #define SRR1_WS_DEEPEST 0x00030000 /* Some resources not maintained, |
620 | * may not be recoverable */ | 623 | * may not be recoverable */ |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index f337666768a7..f83046878336 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -437,6 +437,26 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
437 | .machine_check_early = __machine_check_early_realmode_p8, | 437 | .machine_check_early = __machine_check_early_realmode_p8, |
438 | .platform = "power8", | 438 | .platform = "power8", |
439 | }, | 439 | }, |
440 | { /* Power8NVL */ | ||
441 | .pvr_mask = 0xffff0000, | ||
442 | .pvr_value = 0x004c0000, | ||
443 | .cpu_name = "POWER8NVL (raw)", | ||
444 | .cpu_features = CPU_FTRS_POWER8, | ||
445 | .cpu_user_features = COMMON_USER_POWER8, | ||
446 | .cpu_user_features2 = COMMON_USER2_POWER8, | ||
447 | .mmu_features = MMU_FTRS_POWER8, | ||
448 | .icache_bsize = 128, | ||
449 | .dcache_bsize = 128, | ||
450 | .num_pmcs = 6, | ||
451 | .pmc_type = PPC_PMC_IBM, | ||
452 | .oprofile_cpu_type = "ppc64/power8", | ||
453 | .oprofile_type = PPC_OPROFILE_INVALID, | ||
454 | .cpu_setup = __setup_cpu_power8, | ||
455 | .cpu_restore = __restore_cpu_power8, | ||
456 | .flush_tlb = __flush_tlb_power8, | ||
457 | .machine_check_early = __machine_check_early_realmode_p8, | ||
458 | .platform = "power8", | ||
459 | }, | ||
440 | { /* Power8 DD1: Does not support doorbell IPIs */ | 460 | { /* Power8 DD1: Does not support doorbell IPIs */ |
441 | .pvr_mask = 0xffffff00, | 461 | .pvr_mask = 0xffffff00, |
442 | .pvr_value = 0x004d0100, | 462 | .pvr_value = 0x004d0100, |
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c index f4217819cc31..2128f3a96c32 100644 --- a/arch/powerpc/kernel/dbell.c +++ b/arch/powerpc/kernel/dbell.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <asm/dbell.h> | 18 | #include <asm/dbell.h> |
19 | #include <asm/irq_regs.h> | 19 | #include <asm/irq_regs.h> |
20 | #include <asm/kvm_ppc.h> | ||
20 | 21 | ||
21 | #ifdef CONFIG_SMP | 22 | #ifdef CONFIG_SMP |
22 | void doorbell_setup_this_cpu(void) | 23 | void doorbell_setup_this_cpu(void) |
@@ -41,6 +42,7 @@ void doorbell_exception(struct pt_regs *regs) | |||
41 | 42 | ||
42 | may_hard_irq_enable(); | 43 | may_hard_irq_enable(); |
43 | 44 | ||
45 | kvmppc_set_host_ipi(smp_processor_id(), 0); | ||
44 | __this_cpu_inc(irq_stat.doorbell_irqs); | 46 | __this_cpu_inc(irq_stat.doorbell_irqs); |
45 | 47 | ||
46 | smp_ipi_demux(); | 48 | smp_ipi_demux(); |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index c2df8150bd7a..9519e6bdc6d7 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -1408,7 +1408,7 @@ machine_check_handle_early: | |||
1408 | bne 9f /* continue in V mode if we are. */ | 1408 | bne 9f /* continue in V mode if we are. */ |
1409 | 1409 | ||
1410 | 5: | 1410 | 5: |
1411 | #ifdef CONFIG_KVM_BOOK3S_64_HV | 1411 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER |
1412 | /* | 1412 | /* |
1413 | * We are coming from kernel context. Check if we are coming from | 1413 | * We are coming from kernel context. Check if we are coming from |
1414 | * guest. if yes, then we can continue. We will fall through | 1414 | * guest. if yes, then we can continue. We will fall through |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 5d3968c4d799..b054f33ab1fb 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -1175,4 +1175,30 @@ void iommu_del_device(struct device *dev) | |||
1175 | } | 1175 | } |
1176 | EXPORT_SYMBOL_GPL(iommu_del_device); | 1176 | EXPORT_SYMBOL_GPL(iommu_del_device); |
1177 | 1177 | ||
1178 | static int tce_iommu_bus_notifier(struct notifier_block *nb, | ||
1179 | unsigned long action, void *data) | ||
1180 | { | ||
1181 | struct device *dev = data; | ||
1182 | |||
1183 | switch (action) { | ||
1184 | case BUS_NOTIFY_ADD_DEVICE: | ||
1185 | return iommu_add_device(dev); | ||
1186 | case BUS_NOTIFY_DEL_DEVICE: | ||
1187 | if (dev->iommu_group) | ||
1188 | iommu_del_device(dev); | ||
1189 | return 0; | ||
1190 | default: | ||
1191 | return 0; | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | static struct notifier_block tce_iommu_bus_nb = { | ||
1196 | .notifier_call = tce_iommu_bus_notifier, | ||
1197 | }; | ||
1198 | |||
1199 | int __init tce_iommu_bus_notifier_init(void) | ||
1200 | { | ||
1201 | bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb); | ||
1202 | return 0; | ||
1203 | } | ||
1178 | #endif /* CONFIG_IOMMU_API */ | 1204 | #endif /* CONFIG_IOMMU_API */ |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 6e19afa35a15..ec9ec2058d2d 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -541,8 +541,8 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
541 | if (smp_ops->give_timebase) | 541 | if (smp_ops->give_timebase) |
542 | smp_ops->give_timebase(); | 542 | smp_ops->give_timebase(); |
543 | 543 | ||
544 | /* Wait until cpu puts itself in the online map */ | 544 | /* Wait until cpu puts itself in the online & active maps */ |
545 | while (!cpu_online(cpu)) | 545 | while (!cpu_online(cpu) || !cpu_active(cpu)) |
546 | cpu_relax(); | 546 | cpu_relax(); |
547 | 547 | ||
548 | return 0; | 548 | return 0; |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index de4018a1bc4b..de747563d29d 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -636,7 +636,7 @@ static int kvmppc_get_yield_count(struct kvm_vcpu *vcpu) | |||
636 | spin_lock(&vcpu->arch.vpa_update_lock); | 636 | spin_lock(&vcpu->arch.vpa_update_lock); |
637 | lppaca = (struct lppaca *)vcpu->arch.vpa.pinned_addr; | 637 | lppaca = (struct lppaca *)vcpu->arch.vpa.pinned_addr; |
638 | if (lppaca) | 638 | if (lppaca) |
639 | yield_count = lppaca->yield_count; | 639 | yield_count = be32_to_cpu(lppaca->yield_count); |
640 | spin_unlock(&vcpu->arch.vpa_update_lock); | 640 | spin_unlock(&vcpu->arch.vpa_update_lock); |
641 | return yield_count; | 641 | return yield_count; |
642 | } | 642 | } |
@@ -942,20 +942,20 @@ static int kvm_arch_vcpu_ioctl_set_sregs_hv(struct kvm_vcpu *vcpu, | |||
942 | static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr, | 942 | static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr, |
943 | bool preserve_top32) | 943 | bool preserve_top32) |
944 | { | 944 | { |
945 | struct kvm *kvm = vcpu->kvm; | ||
945 | struct kvmppc_vcore *vc = vcpu->arch.vcore; | 946 | struct kvmppc_vcore *vc = vcpu->arch.vcore; |
946 | u64 mask; | 947 | u64 mask; |
947 | 948 | ||
949 | mutex_lock(&kvm->lock); | ||
948 | spin_lock(&vc->lock); | 950 | spin_lock(&vc->lock); |
949 | /* | 951 | /* |
950 | * If ILE (interrupt little-endian) has changed, update the | 952 | * If ILE (interrupt little-endian) has changed, update the |
951 | * MSR_LE bit in the intr_msr for each vcpu in this vcore. | 953 | * MSR_LE bit in the intr_msr for each vcpu in this vcore. |
952 | */ | 954 | */ |
953 | if ((new_lpcr & LPCR_ILE) != (vc->lpcr & LPCR_ILE)) { | 955 | if ((new_lpcr & LPCR_ILE) != (vc->lpcr & LPCR_ILE)) { |
954 | struct kvm *kvm = vcpu->kvm; | ||
955 | struct kvm_vcpu *vcpu; | 956 | struct kvm_vcpu *vcpu; |
956 | int i; | 957 | int i; |
957 | 958 | ||
958 | mutex_lock(&kvm->lock); | ||
959 | kvm_for_each_vcpu(i, vcpu, kvm) { | 959 | kvm_for_each_vcpu(i, vcpu, kvm) { |
960 | if (vcpu->arch.vcore != vc) | 960 | if (vcpu->arch.vcore != vc) |
961 | continue; | 961 | continue; |
@@ -964,7 +964,6 @@ static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr, | |||
964 | else | 964 | else |
965 | vcpu->arch.intr_msr &= ~MSR_LE; | 965 | vcpu->arch.intr_msr &= ~MSR_LE; |
966 | } | 966 | } |
967 | mutex_unlock(&kvm->lock); | ||
968 | } | 967 | } |
969 | 968 | ||
970 | /* | 969 | /* |
@@ -981,6 +980,7 @@ static void kvmppc_set_lpcr(struct kvm_vcpu *vcpu, u64 new_lpcr, | |||
981 | mask &= 0xFFFFFFFF; | 980 | mask &= 0xFFFFFFFF; |
982 | vc->lpcr = (vc->lpcr & ~mask) | (new_lpcr & mask); | 981 | vc->lpcr = (vc->lpcr & ~mask) | (new_lpcr & mask); |
983 | spin_unlock(&vc->lock); | 982 | spin_unlock(&vc->lock); |
983 | mutex_unlock(&kvm->lock); | ||
984 | } | 984 | } |
985 | 985 | ||
986 | static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, | 986 | static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index bb94e6f20c81..6cbf1630cb70 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -1005,6 +1005,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | |||
1005 | /* Save HEIR (HV emulation assist reg) in emul_inst | 1005 | /* Save HEIR (HV emulation assist reg) in emul_inst |
1006 | if this is an HEI (HV emulation interrupt, e40) */ | 1006 | if this is an HEI (HV emulation interrupt, e40) */ |
1007 | li r3,KVM_INST_FETCH_FAILED | 1007 | li r3,KVM_INST_FETCH_FAILED |
1008 | stw r3,VCPU_LAST_INST(r9) | ||
1008 | cmpwi r12,BOOK3S_INTERRUPT_H_EMUL_ASSIST | 1009 | cmpwi r12,BOOK3S_INTERRUPT_H_EMUL_ASSIST |
1009 | bne 11f | 1010 | bne 11f |
1010 | mfspr r3,SPRN_HEIR | 1011 | mfspr r3,SPRN_HEIR |
diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 39b3a8f816f2..6249cdc834d1 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <asm/kvm_para.h> | 34 | #include <asm/kvm_para.h> |
35 | #include <asm/kvm_host.h> | 35 | #include <asm/kvm_host.h> |
36 | #include <asm/kvm_ppc.h> | 36 | #include <asm/kvm_ppc.h> |
37 | #include "iodev.h" | 37 | #include <kvm/iodev.h> |
38 | 38 | ||
39 | #define MAX_CPU 32 | 39 | #define MAX_CPU 32 |
40 | #define MAX_SRC 256 | 40 | #define MAX_SRC 256 |
@@ -289,11 +289,6 @@ static inline void IRQ_resetbit(struct irq_queue *q, int n_IRQ) | |||
289 | clear_bit(n_IRQ, q->queue); | 289 | clear_bit(n_IRQ, q->queue); |
290 | } | 290 | } |
291 | 291 | ||
292 | static inline int IRQ_testbit(struct irq_queue *q, int n_IRQ) | ||
293 | { | ||
294 | return test_bit(n_IRQ, q->queue); | ||
295 | } | ||
296 | |||
297 | static void IRQ_check(struct openpic *opp, struct irq_queue *q) | 292 | static void IRQ_check(struct openpic *opp, struct irq_queue *q) |
298 | { | 293 | { |
299 | int irq = -1; | 294 | int irq = -1; |
@@ -1374,8 +1369,9 @@ static int kvm_mpic_write_internal(struct openpic *opp, gpa_t addr, u32 val) | |||
1374 | return -ENXIO; | 1369 | return -ENXIO; |
1375 | } | 1370 | } |
1376 | 1371 | ||
1377 | static int kvm_mpic_read(struct kvm_io_device *this, gpa_t addr, | 1372 | static int kvm_mpic_read(struct kvm_vcpu *vcpu, |
1378 | int len, void *ptr) | 1373 | struct kvm_io_device *this, |
1374 | gpa_t addr, int len, void *ptr) | ||
1379 | { | 1375 | { |
1380 | struct openpic *opp = container_of(this, struct openpic, mmio); | 1376 | struct openpic *opp = container_of(this, struct openpic, mmio); |
1381 | int ret; | 1377 | int ret; |
@@ -1415,8 +1411,9 @@ static int kvm_mpic_read(struct kvm_io_device *this, gpa_t addr, | |||
1415 | return ret; | 1411 | return ret; |
1416 | } | 1412 | } |
1417 | 1413 | ||
1418 | static int kvm_mpic_write(struct kvm_io_device *this, gpa_t addr, | 1414 | static int kvm_mpic_write(struct kvm_vcpu *vcpu, |
1419 | int len, const void *ptr) | 1415 | struct kvm_io_device *this, |
1416 | gpa_t addr, int len, const void *ptr) | ||
1420 | { | 1417 | { |
1421 | struct openpic *opp = container_of(this, struct openpic, mmio); | 1418 | struct openpic *opp = container_of(this, struct openpic, mmio); |
1422 | int ret; | 1419 | int ret; |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 27c0face86f4..24bfe401373e 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -807,7 +807,7 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
807 | 807 | ||
808 | idx = srcu_read_lock(&vcpu->kvm->srcu); | 808 | idx = srcu_read_lock(&vcpu->kvm->srcu); |
809 | 809 | ||
810 | ret = kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, | 810 | ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, run->mmio.phys_addr, |
811 | bytes, &run->mmio.data); | 811 | bytes, &run->mmio.data); |
812 | 812 | ||
813 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | 813 | srcu_read_unlock(&vcpu->kvm->srcu, idx); |
@@ -880,7 +880,7 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
880 | 880 | ||
881 | idx = srcu_read_lock(&vcpu->kvm->srcu); | 881 | idx = srcu_read_lock(&vcpu->kvm->srcu); |
882 | 882 | ||
883 | ret = kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, run->mmio.phys_addr, | 883 | ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, run->mmio.phys_addr, |
884 | bytes, &run->mmio.data); | 884 | bytes, &run->mmio.data); |
885 | 885 | ||
886 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | 886 | srcu_read_unlock(&vcpu->kvm->srcu, idx); |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index e69142f4af08..54323d6b5166 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -836,30 +836,4 @@ void __init pnv_pci_init(void) | |||
836 | #endif | 836 | #endif |
837 | } | 837 | } |
838 | 838 | ||
839 | static int tce_iommu_bus_notifier(struct notifier_block *nb, | ||
840 | unsigned long action, void *data) | ||
841 | { | ||
842 | struct device *dev = data; | ||
843 | |||
844 | switch (action) { | ||
845 | case BUS_NOTIFY_ADD_DEVICE: | ||
846 | return iommu_add_device(dev); | ||
847 | case BUS_NOTIFY_DEL_DEVICE: | ||
848 | if (dev->iommu_group) | ||
849 | iommu_del_device(dev); | ||
850 | return 0; | ||
851 | default: | ||
852 | return 0; | ||
853 | } | ||
854 | } | ||
855 | |||
856 | static struct notifier_block tce_iommu_bus_nb = { | ||
857 | .notifier_call = tce_iommu_bus_notifier, | ||
858 | }; | ||
859 | |||
860 | static int __init tce_iommu_bus_notifier_init(void) | ||
861 | { | ||
862 | bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb); | ||
863 | return 0; | ||
864 | } | ||
865 | machine_subsys_initcall_sync(powernv, tce_iommu_bus_notifier_init); | 839 | machine_subsys_initcall_sync(powernv, tce_iommu_bus_notifier_init); |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index fc34025ef822..38a45088f633 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <asm/runlatch.h> | 33 | #include <asm/runlatch.h> |
34 | #include <asm/code-patching.h> | 34 | #include <asm/code-patching.h> |
35 | #include <asm/dbell.h> | 35 | #include <asm/dbell.h> |
36 | #include <asm/kvm_ppc.h> | ||
37 | #include <asm/ppc-opcode.h> | ||
36 | 38 | ||
37 | #include "powernv.h" | 39 | #include "powernv.h" |
38 | 40 | ||
@@ -149,7 +151,7 @@ static int pnv_smp_cpu_disable(void) | |||
149 | static void pnv_smp_cpu_kill_self(void) | 151 | static void pnv_smp_cpu_kill_self(void) |
150 | { | 152 | { |
151 | unsigned int cpu; | 153 | unsigned int cpu; |
152 | unsigned long srr1; | 154 | unsigned long srr1, wmask; |
153 | u32 idle_states; | 155 | u32 idle_states; |
154 | 156 | ||
155 | /* Standard hot unplug procedure */ | 157 | /* Standard hot unplug procedure */ |
@@ -161,6 +163,10 @@ static void pnv_smp_cpu_kill_self(void) | |||
161 | generic_set_cpu_dead(cpu); | 163 | generic_set_cpu_dead(cpu); |
162 | smp_wmb(); | 164 | smp_wmb(); |
163 | 165 | ||
166 | wmask = SRR1_WAKEMASK; | ||
167 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
168 | wmask = SRR1_WAKEMASK_P8; | ||
169 | |||
164 | idle_states = pnv_get_supported_cpuidle_states(); | 170 | idle_states = pnv_get_supported_cpuidle_states(); |
165 | /* We don't want to take decrementer interrupts while we are offline, | 171 | /* We don't want to take decrementer interrupts while we are offline, |
166 | * so clear LPCR:PECE1. We keep PECE2 enabled. | 172 | * so clear LPCR:PECE1. We keep PECE2 enabled. |
@@ -191,10 +197,14 @@ static void pnv_smp_cpu_kill_self(void) | |||
191 | * having finished executing in a KVM guest, then srr1 | 197 | * having finished executing in a KVM guest, then srr1 |
192 | * contains 0. | 198 | * contains 0. |
193 | */ | 199 | */ |
194 | if ((srr1 & SRR1_WAKEMASK) == SRR1_WAKEEE) { | 200 | if ((srr1 & wmask) == SRR1_WAKEEE) { |
195 | icp_native_flush_interrupt(); | 201 | icp_native_flush_interrupt(); |
196 | local_paca->irq_happened &= PACA_IRQ_HARD_DIS; | 202 | local_paca->irq_happened &= PACA_IRQ_HARD_DIS; |
197 | smp_mb(); | 203 | smp_mb(); |
204 | } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) { | ||
205 | unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER); | ||
206 | asm volatile(PPC_MSGCLR(%0) : : "r" (msg)); | ||
207 | kvmppc_set_host_ipi(cpu, 0); | ||
198 | } | 208 | } |
199 | 209 | ||
200 | if (cpu_core_split_required()) | 210 | if (cpu_core_split_required()) |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 1d3d52dc3ff3..7803a19adb31 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -1340,3 +1340,5 @@ static int __init disable_multitce(char *str) | |||
1340 | } | 1340 | } |
1341 | 1341 | ||
1342 | __setup("multitce=", disable_multitce); | 1342 | __setup("multitce=", disable_multitce); |
1343 | |||
1344 | machine_subsys_initcall_sync(pseries, tce_iommu_bus_notifier_init); | ||
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 90cf3dcbd9f2..8f35d525cede 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c | |||
@@ -25,10 +25,10 @@ | |||
25 | static struct kobject *mobility_kobj; | 25 | static struct kobject *mobility_kobj; |
26 | 26 | ||
27 | struct update_props_workarea { | 27 | struct update_props_workarea { |
28 | u32 phandle; | 28 | __be32 phandle; |
29 | u32 state; | 29 | __be32 state; |
30 | u64 reserved; | 30 | __be64 reserved; |
31 | u32 nprops; | 31 | __be32 nprops; |
32 | } __packed; | 32 | } __packed; |
33 | 33 | ||
34 | #define NODE_ACTION_MASK 0xff000000 | 34 | #define NODE_ACTION_MASK 0xff000000 |
@@ -54,11 +54,11 @@ static int mobility_rtas_call(int token, char *buf, s32 scope) | |||
54 | return rc; | 54 | return rc; |
55 | } | 55 | } |
56 | 56 | ||
57 | static int delete_dt_node(u32 phandle) | 57 | static int delete_dt_node(__be32 phandle) |
58 | { | 58 | { |
59 | struct device_node *dn; | 59 | struct device_node *dn; |
60 | 60 | ||
61 | dn = of_find_node_by_phandle(phandle); | 61 | dn = of_find_node_by_phandle(be32_to_cpu(phandle)); |
62 | if (!dn) | 62 | if (!dn) |
63 | return -ENOENT; | 63 | return -ENOENT; |
64 | 64 | ||
@@ -127,7 +127,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop, | |||
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | static int update_dt_node(u32 phandle, s32 scope) | 130 | static int update_dt_node(__be32 phandle, s32 scope) |
131 | { | 131 | { |
132 | struct update_props_workarea *upwa; | 132 | struct update_props_workarea *upwa; |
133 | struct device_node *dn; | 133 | struct device_node *dn; |
@@ -136,6 +136,7 @@ static int update_dt_node(u32 phandle, s32 scope) | |||
136 | char *prop_data; | 136 | char *prop_data; |
137 | char *rtas_buf; | 137 | char *rtas_buf; |
138 | int update_properties_token; | 138 | int update_properties_token; |
139 | u32 nprops; | ||
139 | u32 vd; | 140 | u32 vd; |
140 | 141 | ||
141 | update_properties_token = rtas_token("ibm,update-properties"); | 142 | update_properties_token = rtas_token("ibm,update-properties"); |
@@ -146,7 +147,7 @@ static int update_dt_node(u32 phandle, s32 scope) | |||
146 | if (!rtas_buf) | 147 | if (!rtas_buf) |
147 | return -ENOMEM; | 148 | return -ENOMEM; |
148 | 149 | ||
149 | dn = of_find_node_by_phandle(phandle); | 150 | dn = of_find_node_by_phandle(be32_to_cpu(phandle)); |
150 | if (!dn) { | 151 | if (!dn) { |
151 | kfree(rtas_buf); | 152 | kfree(rtas_buf); |
152 | return -ENOENT; | 153 | return -ENOENT; |
@@ -162,6 +163,7 @@ static int update_dt_node(u32 phandle, s32 scope) | |||
162 | break; | 163 | break; |
163 | 164 | ||
164 | prop_data = rtas_buf + sizeof(*upwa); | 165 | prop_data = rtas_buf + sizeof(*upwa); |
166 | nprops = be32_to_cpu(upwa->nprops); | ||
165 | 167 | ||
166 | /* On the first call to ibm,update-properties for a node the | 168 | /* On the first call to ibm,update-properties for a node the |
167 | * the first property value descriptor contains an empty | 169 | * the first property value descriptor contains an empty |
@@ -170,17 +172,17 @@ static int update_dt_node(u32 phandle, s32 scope) | |||
170 | */ | 172 | */ |
171 | if (*prop_data == 0) { | 173 | if (*prop_data == 0) { |
172 | prop_data++; | 174 | prop_data++; |
173 | vd = *(u32 *)prop_data; | 175 | vd = be32_to_cpu(*(__be32 *)prop_data); |
174 | prop_data += vd + sizeof(vd); | 176 | prop_data += vd + sizeof(vd); |
175 | upwa->nprops--; | 177 | nprops--; |
176 | } | 178 | } |
177 | 179 | ||
178 | for (i = 0; i < upwa->nprops; i++) { | 180 | for (i = 0; i < nprops; i++) { |
179 | char *prop_name; | 181 | char *prop_name; |
180 | 182 | ||
181 | prop_name = prop_data; | 183 | prop_name = prop_data; |
182 | prop_data += strlen(prop_name) + 1; | 184 | prop_data += strlen(prop_name) + 1; |
183 | vd = *(u32 *)prop_data; | 185 | vd = be32_to_cpu(*(__be32 *)prop_data); |
184 | prop_data += sizeof(vd); | 186 | prop_data += sizeof(vd); |
185 | 187 | ||
186 | switch (vd) { | 188 | switch (vd) { |
@@ -212,13 +214,13 @@ static int update_dt_node(u32 phandle, s32 scope) | |||
212 | return 0; | 214 | return 0; |
213 | } | 215 | } |
214 | 216 | ||
215 | static int add_dt_node(u32 parent_phandle, u32 drc_index) | 217 | static int add_dt_node(__be32 parent_phandle, __be32 drc_index) |
216 | { | 218 | { |
217 | struct device_node *dn; | 219 | struct device_node *dn; |
218 | struct device_node *parent_dn; | 220 | struct device_node *parent_dn; |
219 | int rc; | 221 | int rc; |
220 | 222 | ||
221 | parent_dn = of_find_node_by_phandle(parent_phandle); | 223 | parent_dn = of_find_node_by_phandle(be32_to_cpu(parent_phandle)); |
222 | if (!parent_dn) | 224 | if (!parent_dn) |
223 | return -ENOENT; | 225 | return -ENOENT; |
224 | 226 | ||
@@ -237,7 +239,7 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index) | |||
237 | int pseries_devicetree_update(s32 scope) | 239 | int pseries_devicetree_update(s32 scope) |
238 | { | 240 | { |
239 | char *rtas_buf; | 241 | char *rtas_buf; |
240 | u32 *data; | 242 | __be32 *data; |
241 | int update_nodes_token; | 243 | int update_nodes_token; |
242 | int rc; | 244 | int rc; |
243 | 245 | ||
@@ -254,17 +256,17 @@ int pseries_devicetree_update(s32 scope) | |||
254 | if (rc && rc != 1) | 256 | if (rc && rc != 1) |
255 | break; | 257 | break; |
256 | 258 | ||
257 | data = (u32 *)rtas_buf + 4; | 259 | data = (__be32 *)rtas_buf + 4; |
258 | while (*data & NODE_ACTION_MASK) { | 260 | while (be32_to_cpu(*data) & NODE_ACTION_MASK) { |
259 | int i; | 261 | int i; |
260 | u32 action = *data & NODE_ACTION_MASK; | 262 | u32 action = be32_to_cpu(*data) & NODE_ACTION_MASK; |
261 | int node_count = *data & NODE_COUNT_MASK; | 263 | u32 node_count = be32_to_cpu(*data) & NODE_COUNT_MASK; |
262 | 264 | ||
263 | data++; | 265 | data++; |
264 | 266 | ||
265 | for (i = 0; i < node_count; i++) { | 267 | for (i = 0; i < node_count; i++) { |
266 | u32 phandle = *data++; | 268 | __be32 phandle = *data++; |
267 | u32 drc_index; | 269 | __be32 drc_index; |
268 | 270 | ||
269 | switch (action) { | 271 | switch (action) { |
270 | case DELETE_DT_NODE: | 272 | case DELETE_DT_NODE: |
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index c9df40b5c0ac..c9c875d9ed31 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
@@ -211,7 +211,7 @@ do { \ | |||
211 | 211 | ||
212 | extern unsigned long mmap_rnd_mask; | 212 | extern unsigned long mmap_rnd_mask; |
213 | 213 | ||
214 | #define STACK_RND_MASK (mmap_rnd_mask) | 214 | #define STACK_RND_MASK (test_thread_flag(TIF_31BIT) ? 0x7ff : mmap_rnd_mask) |
215 | 215 | ||
216 | #define ARCH_DLINFO \ | 216 | #define ARCH_DLINFO \ |
217 | do { \ | 217 | do { \ |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index d84559e31f32..d01fc588b5c3 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -172,7 +172,9 @@ struct kvm_s390_sie_block { | |||
172 | __u32 fac; /* 0x01a0 */ | 172 | __u32 fac; /* 0x01a0 */ |
173 | __u8 reserved1a4[20]; /* 0x01a4 */ | 173 | __u8 reserved1a4[20]; /* 0x01a4 */ |
174 | __u64 cbrlo; /* 0x01b8 */ | 174 | __u64 cbrlo; /* 0x01b8 */ |
175 | __u8 reserved1c0[30]; /* 0x01c0 */ | 175 | __u8 reserved1c0[8]; /* 0x01c0 */ |
176 | __u32 ecd; /* 0x01c8 */ | ||
177 | __u8 reserved1cc[18]; /* 0x01cc */ | ||
176 | __u64 pp; /* 0x01de */ | 178 | __u64 pp; /* 0x01de */ |
177 | __u8 reserved1e6[2]; /* 0x01e6 */ | 179 | __u8 reserved1e6[2]; /* 0x01e6 */ |
178 | __u64 itdba; /* 0x01e8 */ | 180 | __u64 itdba; /* 0x01e8 */ |
@@ -183,11 +185,17 @@ struct kvm_s390_itdb { | |||
183 | __u8 data[256]; | 185 | __u8 data[256]; |
184 | } __packed; | 186 | } __packed; |
185 | 187 | ||
188 | struct kvm_s390_vregs { | ||
189 | __vector128 vrs[32]; | ||
190 | __u8 reserved200[512]; /* for future vector expansion */ | ||
191 | } __packed; | ||
192 | |||
186 | struct sie_page { | 193 | struct sie_page { |
187 | struct kvm_s390_sie_block sie_block; | 194 | struct kvm_s390_sie_block sie_block; |
188 | __u8 reserved200[1024]; /* 0x0200 */ | 195 | __u8 reserved200[1024]; /* 0x0200 */ |
189 | struct kvm_s390_itdb itdb; /* 0x0600 */ | 196 | struct kvm_s390_itdb itdb; /* 0x0600 */ |
190 | __u8 reserved700[2304]; /* 0x0700 */ | 197 | __u8 reserved700[1280]; /* 0x0700 */ |
198 | struct kvm_s390_vregs vregs; /* 0x0c00 */ | ||
191 | } __packed; | 199 | } __packed; |
192 | 200 | ||
193 | struct kvm_vcpu_stat { | 201 | struct kvm_vcpu_stat { |
@@ -238,6 +246,7 @@ struct kvm_vcpu_stat { | |||
238 | u32 instruction_sigp_stop; | 246 | u32 instruction_sigp_stop; |
239 | u32 instruction_sigp_stop_store_status; | 247 | u32 instruction_sigp_stop_store_status; |
240 | u32 instruction_sigp_store_status; | 248 | u32 instruction_sigp_store_status; |
249 | u32 instruction_sigp_store_adtl_status; | ||
241 | u32 instruction_sigp_arch; | 250 | u32 instruction_sigp_arch; |
242 | u32 instruction_sigp_prefix; | 251 | u32 instruction_sigp_prefix; |
243 | u32 instruction_sigp_restart; | 252 | u32 instruction_sigp_restart; |
@@ -270,6 +279,7 @@ struct kvm_vcpu_stat { | |||
270 | #define PGM_SPECIAL_OPERATION 0x13 | 279 | #define PGM_SPECIAL_OPERATION 0x13 |
271 | #define PGM_OPERAND 0x15 | 280 | #define PGM_OPERAND 0x15 |
272 | #define PGM_TRACE_TABEL 0x16 | 281 | #define PGM_TRACE_TABEL 0x16 |
282 | #define PGM_VECTOR_PROCESSING 0x1b | ||
273 | #define PGM_SPACE_SWITCH 0x1c | 283 | #define PGM_SPACE_SWITCH 0x1c |
274 | #define PGM_HFP_SQUARE_ROOT 0x1d | 284 | #define PGM_HFP_SQUARE_ROOT 0x1d |
275 | #define PGM_PC_TRANSLATION_SPEC 0x1f | 285 | #define PGM_PC_TRANSLATION_SPEC 0x1f |
@@ -334,6 +344,11 @@ enum irq_types { | |||
334 | IRQ_PEND_COUNT | 344 | IRQ_PEND_COUNT |
335 | }; | 345 | }; |
336 | 346 | ||
347 | /* We have 2M for virtio device descriptor pages. Smallest amount of | ||
348 | * memory per page is 24 bytes (1 queue), so (2048*1024) / 24 = 87381 | ||
349 | */ | ||
350 | #define KVM_S390_MAX_VIRTIO_IRQS 87381 | ||
351 | |||
337 | /* | 352 | /* |
338 | * Repressible (non-floating) machine check interrupts | 353 | * Repressible (non-floating) machine check interrupts |
339 | * subclass bits in MCIC | 354 | * subclass bits in MCIC |
@@ -411,13 +426,32 @@ struct kvm_s390_local_interrupt { | |||
411 | unsigned long pending_irqs; | 426 | unsigned long pending_irqs; |
412 | }; | 427 | }; |
413 | 428 | ||
429 | #define FIRQ_LIST_IO_ISC_0 0 | ||
430 | #define FIRQ_LIST_IO_ISC_1 1 | ||
431 | #define FIRQ_LIST_IO_ISC_2 2 | ||
432 | #define FIRQ_LIST_IO_ISC_3 3 | ||
433 | #define FIRQ_LIST_IO_ISC_4 4 | ||
434 | #define FIRQ_LIST_IO_ISC_5 5 | ||
435 | #define FIRQ_LIST_IO_ISC_6 6 | ||
436 | #define FIRQ_LIST_IO_ISC_7 7 | ||
437 | #define FIRQ_LIST_PFAULT 8 | ||
438 | #define FIRQ_LIST_VIRTIO 9 | ||
439 | #define FIRQ_LIST_COUNT 10 | ||
440 | #define FIRQ_CNTR_IO 0 | ||
441 | #define FIRQ_CNTR_SERVICE 1 | ||
442 | #define FIRQ_CNTR_VIRTIO 2 | ||
443 | #define FIRQ_CNTR_PFAULT 3 | ||
444 | #define FIRQ_MAX_COUNT 4 | ||
445 | |||
414 | struct kvm_s390_float_interrupt { | 446 | struct kvm_s390_float_interrupt { |
447 | unsigned long pending_irqs; | ||
415 | spinlock_t lock; | 448 | spinlock_t lock; |
416 | struct list_head list; | 449 | struct list_head lists[FIRQ_LIST_COUNT]; |
417 | atomic_t active; | 450 | int counters[FIRQ_MAX_COUNT]; |
451 | struct kvm_s390_mchk_info mchk; | ||
452 | struct kvm_s390_ext_info srv_signal; | ||
418 | int next_rr_cpu; | 453 | int next_rr_cpu; |
419 | unsigned long idle_mask[BITS_TO_LONGS(KVM_MAX_VCPUS)]; | 454 | unsigned long idle_mask[BITS_TO_LONGS(KVM_MAX_VCPUS)]; |
420 | unsigned int irq_count; | ||
421 | }; | 455 | }; |
422 | 456 | ||
423 | struct kvm_hw_wp_info_arch { | 457 | struct kvm_hw_wp_info_arch { |
@@ -465,6 +499,7 @@ struct kvm_vcpu_arch { | |||
465 | s390_fp_regs host_fpregs; | 499 | s390_fp_regs host_fpregs; |
466 | unsigned int host_acrs[NUM_ACRS]; | 500 | unsigned int host_acrs[NUM_ACRS]; |
467 | s390_fp_regs guest_fpregs; | 501 | s390_fp_regs guest_fpregs; |
502 | struct kvm_s390_vregs *host_vregs; | ||
468 | struct kvm_s390_local_interrupt local_int; | 503 | struct kvm_s390_local_interrupt local_int; |
469 | struct hrtimer ckc_timer; | 504 | struct hrtimer ckc_timer; |
470 | struct kvm_s390_pgm_info pgm; | 505 | struct kvm_s390_pgm_info pgm; |
@@ -515,15 +550,15 @@ struct s390_io_adapter { | |||
515 | #define S390_ARCH_FAC_MASK_SIZE_U64 \ | 550 | #define S390_ARCH_FAC_MASK_SIZE_U64 \ |
516 | (S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64)) | 551 | (S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64)) |
517 | 552 | ||
518 | struct s390_model_fac { | 553 | struct kvm_s390_fac { |
519 | /* facilities used in SIE context */ | 554 | /* facility list requested by guest */ |
520 | __u64 sie[S390_ARCH_FAC_LIST_SIZE_U64]; | 555 | __u64 list[S390_ARCH_FAC_LIST_SIZE_U64]; |
521 | /* subset enabled by kvm */ | 556 | /* facility mask supported by kvm & hosting machine */ |
522 | __u64 kvm[S390_ARCH_FAC_LIST_SIZE_U64]; | 557 | __u64 mask[S390_ARCH_FAC_LIST_SIZE_U64]; |
523 | }; | 558 | }; |
524 | 559 | ||
525 | struct kvm_s390_cpu_model { | 560 | struct kvm_s390_cpu_model { |
526 | struct s390_model_fac *fac; | 561 | struct kvm_s390_fac *fac; |
527 | struct cpuid cpu_id; | 562 | struct cpuid cpu_id; |
528 | unsigned short ibc; | 563 | unsigned short ibc; |
529 | }; | 564 | }; |
@@ -553,6 +588,7 @@ struct kvm_arch{ | |||
553 | int use_cmma; | 588 | int use_cmma; |
554 | int user_cpu_state_ctrl; | 589 | int user_cpu_state_ctrl; |
555 | int user_sigp; | 590 | int user_sigp; |
591 | int user_stsi; | ||
556 | struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; | 592 | struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; |
557 | wait_queue_head_t ipte_wq; | 593 | wait_queue_head_t ipte_wq; |
558 | int ipte_lock_count; | 594 | int ipte_lock_count; |
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index f49b71954654..8fb3802f8fad 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h | |||
@@ -62,6 +62,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
62 | { | 62 | { |
63 | int cpu = smp_processor_id(); | 63 | int cpu = smp_processor_id(); |
64 | 64 | ||
65 | S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd); | ||
65 | if (prev == next) | 66 | if (prev == next) |
66 | return; | 67 | return; |
67 | if (MACHINE_HAS_TLB_LC) | 68 | if (MACHINE_HAS_TLB_LC) |
@@ -73,7 +74,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
73 | atomic_dec(&prev->context.attach_count); | 74 | atomic_dec(&prev->context.attach_count); |
74 | if (MACHINE_HAS_TLB_LC) | 75 | if (MACHINE_HAS_TLB_LC) |
75 | cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask); | 76 | cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask); |
76 | S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd); | ||
77 | } | 77 | } |
78 | 78 | ||
79 | #define finish_arch_post_lock_switch finish_arch_post_lock_switch | 79 | #define finish_arch_post_lock_switch finish_arch_post_lock_switch |
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 7b2ac6e44166..53eacbd4f09b 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h | |||
@@ -37,16 +37,7 @@ static inline void storage_key_init_range(unsigned long start, unsigned long end | |||
37 | #endif | 37 | #endif |
38 | } | 38 | } |
39 | 39 | ||
40 | static inline void clear_page(void *page) | 40 | #define clear_page(page) memset((page), 0, PAGE_SIZE) |
41 | { | ||
42 | register unsigned long reg1 asm ("1") = 0; | ||
43 | register void *reg2 asm ("2") = page; | ||
44 | register unsigned long reg3 asm ("3") = 4096; | ||
45 | asm volatile( | ||
46 | " mvcl 2,0" | ||
47 | : "+d" (reg2), "+d" (reg3) : "d" (reg1) | ||
48 | : "memory", "cc"); | ||
49 | } | ||
50 | 41 | ||
51 | /* | 42 | /* |
52 | * copy_page uses the mvcl instruction with 0xb0 padding byte in order to | 43 | * copy_page uses the mvcl instruction with 0xb0 padding byte in order to |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index fbb5ee3ae57c..e08ec38f8c6e 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -91,7 +91,9 @@ extern unsigned long zero_page_mask; | |||
91 | */ | 91 | */ |
92 | #define PTRS_PER_PTE 256 | 92 | #define PTRS_PER_PTE 256 |
93 | #ifndef CONFIG_64BIT | 93 | #ifndef CONFIG_64BIT |
94 | #define __PAGETABLE_PUD_FOLDED | ||
94 | #define PTRS_PER_PMD 1 | 95 | #define PTRS_PER_PMD 1 |
96 | #define __PAGETABLE_PMD_FOLDED | ||
95 | #define PTRS_PER_PUD 1 | 97 | #define PTRS_PER_PUD 1 |
96 | #else /* CONFIG_64BIT */ | 98 | #else /* CONFIG_64BIT */ |
97 | #define PTRS_PER_PMD 2048 | 99 | #define PTRS_PER_PMD 2048 |
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 9c77e60b9a26..ef1a5fcc6c66 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h | |||
@@ -150,6 +150,7 @@ struct kvm_guest_debug_arch { | |||
150 | #define KVM_SYNC_CRS (1UL << 3) | 150 | #define KVM_SYNC_CRS (1UL << 3) |
151 | #define KVM_SYNC_ARCH0 (1UL << 4) | 151 | #define KVM_SYNC_ARCH0 (1UL << 4) |
152 | #define KVM_SYNC_PFAULT (1UL << 5) | 152 | #define KVM_SYNC_PFAULT (1UL << 5) |
153 | #define KVM_SYNC_VRS (1UL << 6) | ||
153 | /* definition of registers in kvm_run */ | 154 | /* definition of registers in kvm_run */ |
154 | struct kvm_sync_regs { | 155 | struct kvm_sync_regs { |
155 | __u64 prefix; /* prefix register */ | 156 | __u64 prefix; /* prefix register */ |
@@ -164,6 +165,9 @@ struct kvm_sync_regs { | |||
164 | __u64 pft; /* pfault token [PFAULT] */ | 165 | __u64 pft; /* pfault token [PFAULT] */ |
165 | __u64 pfs; /* pfault select [PFAULT] */ | 166 | __u64 pfs; /* pfault select [PFAULT] */ |
166 | __u64 pfc; /* pfault compare [PFAULT] */ | 167 | __u64 pfc; /* pfault compare [PFAULT] */ |
168 | __u64 vrs[32][2]; /* vector registers */ | ||
169 | __u8 reserved[512]; /* for future vector expansion */ | ||
170 | __u32 fpc; /* only valid with vector registers */ | ||
167 | }; | 171 | }; |
168 | 172 | ||
169 | #define KVM_REG_S390_TODPR (KVM_REG_S390 | KVM_REG_SIZE_U32 | 0x1) | 173 | #define KVM_REG_S390_TODPR (KVM_REG_S390 | KVM_REG_SIZE_U32 | 0x1) |
diff --git a/arch/s390/include/uapi/asm/sie.h b/arch/s390/include/uapi/asm/sie.h index d4096fdfc6ab..ee69c0854c88 100644 --- a/arch/s390/include/uapi/asm/sie.h +++ b/arch/s390/include/uapi/asm/sie.h | |||
@@ -230,7 +230,7 @@ | |||
230 | * and returns a key, which can be used to find a mnemonic name | 230 | * and returns a key, which can be used to find a mnemonic name |
231 | * of the instruction in the icpt_insn_codes table. | 231 | * of the instruction in the icpt_insn_codes table. |
232 | */ | 232 | */ |
233 | #define icpt_insn_decoder(insn) \ | 233 | #define icpt_insn_decoder(insn) ( \ |
234 | INSN_DECODE_IPA0(0x01, insn, 48, 0xff) \ | 234 | INSN_DECODE_IPA0(0x01, insn, 48, 0xff) \ |
235 | INSN_DECODE_IPA0(0xaa, insn, 48, 0x0f) \ | 235 | INSN_DECODE_IPA0(0xaa, insn, 48, 0x0f) \ |
236 | INSN_DECODE_IPA0(0xb2, insn, 48, 0xff) \ | 236 | INSN_DECODE_IPA0(0xb2, insn, 48, 0xff) \ |
@@ -239,6 +239,6 @@ | |||
239 | INSN_DECODE_IPA0(0xe5, insn, 48, 0xff) \ | 239 | INSN_DECODE_IPA0(0xe5, insn, 48, 0xff) \ |
240 | INSN_DECODE_IPA0(0xeb, insn, 16, 0xff) \ | 240 | INSN_DECODE_IPA0(0xeb, insn, 16, 0xff) \ |
241 | INSN_DECODE_IPA0(0xc8, insn, 48, 0x0f) \ | 241 | INSN_DECODE_IPA0(0xc8, insn, 48, 0x0f) \ |
242 | INSN_DECODE(insn) | 242 | INSN_DECODE(insn)) |
243 | 243 | ||
244 | #endif /* _UAPI_ASM_S390_SIE_H */ | 244 | #endif /* _UAPI_ASM_S390_SIE_H */ |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index e07e91605353..8dc4db10d160 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
@@ -171,6 +171,7 @@ int main(void) | |||
171 | #else /* CONFIG_32BIT */ | 171 | #else /* CONFIG_32BIT */ |
172 | DEFINE(__LC_DATA_EXC_CODE, offsetof(struct _lowcore, data_exc_code)); | 172 | DEFINE(__LC_DATA_EXC_CODE, offsetof(struct _lowcore, data_exc_code)); |
173 | DEFINE(__LC_MCCK_FAIL_STOR_ADDR, offsetof(struct _lowcore, failing_storage_address)); | 173 | DEFINE(__LC_MCCK_FAIL_STOR_ADDR, offsetof(struct _lowcore, failing_storage_address)); |
174 | DEFINE(__LC_VX_SAVE_AREA_ADDR, offsetof(struct _lowcore, vector_save_area_addr)); | ||
174 | DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2)); | 175 | DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2)); |
175 | DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area)); | 176 | DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area)); |
176 | DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste)); | 177 | DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste)); |
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 82c19899574f..6c79f1b44fe7 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c | |||
@@ -57,6 +57,44 @@ | |||
57 | 57 | ||
58 | unsigned long ftrace_plt; | 58 | unsigned long ftrace_plt; |
59 | 59 | ||
60 | static inline void ftrace_generate_orig_insn(struct ftrace_insn *insn) | ||
61 | { | ||
62 | #ifdef CC_USING_HOTPATCH | ||
63 | /* brcl 0,0 */ | ||
64 | insn->opc = 0xc004; | ||
65 | insn->disp = 0; | ||
66 | #else | ||
67 | /* stg r14,8(r15) */ | ||
68 | insn->opc = 0xe3e0; | ||
69 | insn->disp = 0xf0080024; | ||
70 | #endif | ||
71 | } | ||
72 | |||
73 | static inline int is_kprobe_on_ftrace(struct ftrace_insn *insn) | ||
74 | { | ||
75 | #ifdef CONFIG_KPROBES | ||
76 | if (insn->opc == BREAKPOINT_INSTRUCTION) | ||
77 | return 1; | ||
78 | #endif | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static inline void ftrace_generate_kprobe_nop_insn(struct ftrace_insn *insn) | ||
83 | { | ||
84 | #ifdef CONFIG_KPROBES | ||
85 | insn->opc = BREAKPOINT_INSTRUCTION; | ||
86 | insn->disp = KPROBE_ON_FTRACE_NOP; | ||
87 | #endif | ||
88 | } | ||
89 | |||
90 | static inline void ftrace_generate_kprobe_call_insn(struct ftrace_insn *insn) | ||
91 | { | ||
92 | #ifdef CONFIG_KPROBES | ||
93 | insn->opc = BREAKPOINT_INSTRUCTION; | ||
94 | insn->disp = KPROBE_ON_FTRACE_CALL; | ||
95 | #endif | ||
96 | } | ||
97 | |||
60 | int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, | 98 | int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, |
61 | unsigned long addr) | 99 | unsigned long addr) |
62 | { | 100 | { |
@@ -72,16 +110,9 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, | |||
72 | return -EFAULT; | 110 | return -EFAULT; |
73 | if (addr == MCOUNT_ADDR) { | 111 | if (addr == MCOUNT_ADDR) { |
74 | /* Initial code replacement */ | 112 | /* Initial code replacement */ |
75 | #ifdef CC_USING_HOTPATCH | 113 | ftrace_generate_orig_insn(&orig); |
76 | /* We expect to see brcl 0,0 */ | ||
77 | ftrace_generate_nop_insn(&orig); | ||
78 | #else | ||
79 | /* We expect to see stg r14,8(r15) */ | ||
80 | orig.opc = 0xe3e0; | ||
81 | orig.disp = 0xf0080024; | ||
82 | #endif | ||
83 | ftrace_generate_nop_insn(&new); | 114 | ftrace_generate_nop_insn(&new); |
84 | } else if (old.opc == BREAKPOINT_INSTRUCTION) { | 115 | } else if (is_kprobe_on_ftrace(&old)) { |
85 | /* | 116 | /* |
86 | * If we find a breakpoint instruction, a kprobe has been | 117 | * If we find a breakpoint instruction, a kprobe has been |
87 | * placed at the beginning of the function. We write the | 118 | * placed at the beginning of the function. We write the |
@@ -89,9 +120,8 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, | |||
89 | * bytes of the original instruction so that the kprobes | 120 | * bytes of the original instruction so that the kprobes |
90 | * handler can execute a nop, if it reaches this breakpoint. | 121 | * handler can execute a nop, if it reaches this breakpoint. |
91 | */ | 122 | */ |
92 | new.opc = orig.opc = BREAKPOINT_INSTRUCTION; | 123 | ftrace_generate_kprobe_call_insn(&orig); |
93 | orig.disp = KPROBE_ON_FTRACE_CALL; | 124 | ftrace_generate_kprobe_nop_insn(&new); |
94 | new.disp = KPROBE_ON_FTRACE_NOP; | ||
95 | } else { | 125 | } else { |
96 | /* Replace ftrace call with a nop. */ | 126 | /* Replace ftrace call with a nop. */ |
97 | ftrace_generate_call_insn(&orig, rec->ip); | 127 | ftrace_generate_call_insn(&orig, rec->ip); |
@@ -111,7 +141,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
111 | 141 | ||
112 | if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) | 142 | if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) |
113 | return -EFAULT; | 143 | return -EFAULT; |
114 | if (old.opc == BREAKPOINT_INSTRUCTION) { | 144 | if (is_kprobe_on_ftrace(&old)) { |
115 | /* | 145 | /* |
116 | * If we find a breakpoint instruction, a kprobe has been | 146 | * If we find a breakpoint instruction, a kprobe has been |
117 | * placed at the beginning of the function. We write the | 147 | * placed at the beginning of the function. We write the |
@@ -119,9 +149,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
119 | * bytes of the original instruction so that the kprobes | 149 | * bytes of the original instruction so that the kprobes |
120 | * handler can execute a brasl if it reaches this breakpoint. | 150 | * handler can execute a brasl if it reaches this breakpoint. |
121 | */ | 151 | */ |
122 | new.opc = orig.opc = BREAKPOINT_INSTRUCTION; | 152 | ftrace_generate_kprobe_nop_insn(&orig); |
123 | orig.disp = KPROBE_ON_FTRACE_NOP; | 153 | ftrace_generate_kprobe_call_insn(&new); |
124 | new.disp = KPROBE_ON_FTRACE_CALL; | ||
125 | } else { | 154 | } else { |
126 | /* Replace nop with an ftrace call. */ | 155 | /* Replace nop with an ftrace call. */ |
127 | ftrace_generate_nop_insn(&orig); | 156 | ftrace_generate_nop_insn(&orig); |
diff --git a/arch/s390/kernel/jump_label.c b/arch/s390/kernel/jump_label.c index cb2d51e779df..830066f936c8 100644 --- a/arch/s390/kernel/jump_label.c +++ b/arch/s390/kernel/jump_label.c | |||
@@ -36,16 +36,20 @@ static void jump_label_make_branch(struct jump_entry *entry, struct insn *insn) | |||
36 | insn->offset = (entry->target - entry->code) >> 1; | 36 | insn->offset = (entry->target - entry->code) >> 1; |
37 | } | 37 | } |
38 | 38 | ||
39 | static void jump_label_bug(struct jump_entry *entry, struct insn *insn) | 39 | static void jump_label_bug(struct jump_entry *entry, struct insn *expected, |
40 | struct insn *new) | ||
40 | { | 41 | { |
41 | unsigned char *ipc = (unsigned char *)entry->code; | 42 | unsigned char *ipc = (unsigned char *)entry->code; |
42 | unsigned char *ipe = (unsigned char *)insn; | 43 | unsigned char *ipe = (unsigned char *)expected; |
44 | unsigned char *ipn = (unsigned char *)new; | ||
43 | 45 | ||
44 | pr_emerg("Jump label code mismatch at %pS [%p]\n", ipc, ipc); | 46 | pr_emerg("Jump label code mismatch at %pS [%p]\n", ipc, ipc); |
45 | pr_emerg("Found: %02x %02x %02x %02x %02x %02x\n", | 47 | pr_emerg("Found: %02x %02x %02x %02x %02x %02x\n", |
46 | ipc[0], ipc[1], ipc[2], ipc[3], ipc[4], ipc[5]); | 48 | ipc[0], ipc[1], ipc[2], ipc[3], ipc[4], ipc[5]); |
47 | pr_emerg("Expected: %02x %02x %02x %02x %02x %02x\n", | 49 | pr_emerg("Expected: %02x %02x %02x %02x %02x %02x\n", |
48 | ipe[0], ipe[1], ipe[2], ipe[3], ipe[4], ipe[5]); | 50 | ipe[0], ipe[1], ipe[2], ipe[3], ipe[4], ipe[5]); |
51 | pr_emerg("New: %02x %02x %02x %02x %02x %02x\n", | ||
52 | ipn[0], ipn[1], ipn[2], ipn[3], ipn[4], ipn[5]); | ||
49 | panic("Corrupted kernel text"); | 53 | panic("Corrupted kernel text"); |
50 | } | 54 | } |
51 | 55 | ||
@@ -69,10 +73,10 @@ static void __jump_label_transform(struct jump_entry *entry, | |||
69 | } | 73 | } |
70 | if (init) { | 74 | if (init) { |
71 | if (memcmp((void *)entry->code, &orignop, sizeof(orignop))) | 75 | if (memcmp((void *)entry->code, &orignop, sizeof(orignop))) |
72 | jump_label_bug(entry, &old); | 76 | jump_label_bug(entry, &orignop, &new); |
73 | } else { | 77 | } else { |
74 | if (memcmp((void *)entry->code, &old, sizeof(old))) | 78 | if (memcmp((void *)entry->code, &old, sizeof(old))) |
75 | jump_label_bug(entry, &old); | 79 | jump_label_bug(entry, &old, &new); |
76 | } | 80 | } |
77 | probe_kernel_write((void *)entry->code, &new, sizeof(new)); | 81 | probe_kernel_write((void *)entry->code, &new, sizeof(new)); |
78 | } | 82 | } |
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 36154a2f1814..2ca95862e336 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c | |||
@@ -436,6 +436,7 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
436 | const Elf_Shdr *sechdrs, | 436 | const Elf_Shdr *sechdrs, |
437 | struct module *me) | 437 | struct module *me) |
438 | { | 438 | { |
439 | jump_label_apply_nops(me); | ||
439 | vfree(me->arch.syminfo); | 440 | vfree(me->arch.syminfo); |
440 | me->arch.syminfo = NULL; | 441 | me->arch.syminfo = NULL; |
441 | return 0; | 442 | return 0; |
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index c3f8d157cb0d..e6a1578fc000 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c | |||
@@ -1415,7 +1415,7 @@ CPUMF_EVENT_ATTR(SF, SF_CYCLES_BASIC_DIAG, PERF_EVENT_CPUM_SF_DIAG); | |||
1415 | 1415 | ||
1416 | static struct attribute *cpumsf_pmu_events_attr[] = { | 1416 | static struct attribute *cpumsf_pmu_events_attr[] = { |
1417 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC), | 1417 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC), |
1418 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG), | 1418 | NULL, |
1419 | NULL, | 1419 | NULL, |
1420 | }; | 1420 | }; |
1421 | 1421 | ||
@@ -1606,8 +1606,11 @@ static int __init init_cpum_sampling_pmu(void) | |||
1606 | return -EINVAL; | 1606 | return -EINVAL; |
1607 | } | 1607 | } |
1608 | 1608 | ||
1609 | if (si.ad) | 1609 | if (si.ad) { |
1610 | sfb_set_limits(CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB); | 1610 | sfb_set_limits(CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB); |
1611 | cpumsf_pmu_events_attr[1] = | ||
1612 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG); | ||
1613 | } | ||
1611 | 1614 | ||
1612 | sfdbg = debug_register(KMSG_COMPONENT, 2, 1, 80); | 1615 | sfdbg = debug_register(KMSG_COMPONENT, 2, 1, 80); |
1613 | if (!sfdbg) | 1616 | if (!sfdbg) |
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 26108232fcaa..dc488e13b7e3 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | static DEFINE_PER_CPU(struct cpuid, cpu_id); | 19 | static DEFINE_PER_CPU(struct cpuid, cpu_id); |
20 | 20 | ||
21 | void cpu_relax(void) | 21 | void notrace cpu_relax(void) |
22 | { | 22 | { |
23 | if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) | 23 | if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) |
24 | asm volatile("diag 0,0,0x44"); | 24 | asm volatile("diag 0,0,0x44"); |
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index 6b09fdffbd2f..ca6294645dd3 100644 --- a/arch/s390/kernel/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S | |||
@@ -177,6 +177,17 @@ restart_entry: | |||
177 | lhi %r1,1 | 177 | lhi %r1,1 |
178 | sigp %r1,%r0,SIGP_SET_ARCHITECTURE | 178 | sigp %r1,%r0,SIGP_SET_ARCHITECTURE |
179 | sam64 | 179 | sam64 |
180 | #ifdef CONFIG_SMP | ||
181 | larl %r1,smp_cpu_mt_shift | ||
182 | icm %r1,15,0(%r1) | ||
183 | jz smt_done | ||
184 | llgfr %r1,%r1 | ||
185 | smt_loop: | ||
186 | sigp %r1,%r0,SIGP_SET_MULTI_THREADING | ||
187 | brc 8,smt_done /* accepted */ | ||
188 | brc 2,smt_loop /* busy, try again */ | ||
189 | smt_done: | ||
190 | #endif | ||
180 | larl %r1,.Lnew_pgm_check_psw | 191 | larl %r1,.Lnew_pgm_check_psw |
181 | lpswe 0(%r1) | 192 | lpswe 0(%r1) |
182 | pgm_check_entry: | 193 | pgm_check_entry: |
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 9254afff250c..fc7ec95848c3 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c | |||
@@ -77,7 +77,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu) | |||
77 | 77 | ||
78 | if (vcpu->run->s.regs.gprs[rx] & 7) | 78 | if (vcpu->run->s.regs.gprs[rx] & 7) |
79 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 79 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
80 | rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm)); | 80 | rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm)); |
81 | if (rc) | 81 | if (rc) |
82 | return kvm_s390_inject_prog_cond(vcpu, rc); | 82 | return kvm_s390_inject_prog_cond(vcpu, rc); |
83 | if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258) | 83 | if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258) |
@@ -213,7 +213,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) | |||
213 | * - gpr 3 contains the virtqueue index (passed as datamatch) | 213 | * - gpr 3 contains the virtqueue index (passed as datamatch) |
214 | * - gpr 4 contains the index on the bus (optionally) | 214 | * - gpr 4 contains the index on the bus (optionally) |
215 | */ | 215 | */ |
216 | ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS, | 216 | ret = kvm_io_bus_write_cookie(vcpu, KVM_VIRTIO_CCW_NOTIFY_BUS, |
217 | vcpu->run->s.regs.gprs[2] & 0xffffffff, | 217 | vcpu->run->s.regs.gprs[2] & 0xffffffff, |
218 | 8, &vcpu->run->s.regs.gprs[3], | 218 | 8, &vcpu->run->s.regs.gprs[3], |
219 | vcpu->run->s.regs.gprs[4]); | 219 | vcpu->run->s.regs.gprs[4]); |
@@ -230,7 +230,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) | |||
230 | 230 | ||
231 | int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) | 231 | int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) |
232 | { | 232 | { |
233 | int code = kvm_s390_get_base_disp_rs(vcpu) & 0xffff; | 233 | int code = kvm_s390_get_base_disp_rs(vcpu, NULL) & 0xffff; |
234 | 234 | ||
235 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 235 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
236 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 236 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 267523cac6de..a7559f7207df 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <asm/pgtable.h> | 10 | #include <asm/pgtable.h> |
11 | #include "kvm-s390.h" | 11 | #include "kvm-s390.h" |
12 | #include "gaccess.h" | 12 | #include "gaccess.h" |
13 | #include <asm/switch_to.h> | ||
13 | 14 | ||
14 | union asce { | 15 | union asce { |
15 | unsigned long val; | 16 | unsigned long val; |
@@ -207,6 +208,54 @@ union raddress { | |||
207 | unsigned long pfra : 52; /* Page-Frame Real Address */ | 208 | unsigned long pfra : 52; /* Page-Frame Real Address */ |
208 | }; | 209 | }; |
209 | 210 | ||
211 | union alet { | ||
212 | u32 val; | ||
213 | struct { | ||
214 | u32 reserved : 7; | ||
215 | u32 p : 1; | ||
216 | u32 alesn : 8; | ||
217 | u32 alen : 16; | ||
218 | }; | ||
219 | }; | ||
220 | |||
221 | union ald { | ||
222 | u32 val; | ||
223 | struct { | ||
224 | u32 : 1; | ||
225 | u32 alo : 24; | ||
226 | u32 all : 7; | ||
227 | }; | ||
228 | }; | ||
229 | |||
230 | struct ale { | ||
231 | unsigned long i : 1; /* ALEN-Invalid Bit */ | ||
232 | unsigned long : 5; | ||
233 | unsigned long fo : 1; /* Fetch-Only Bit */ | ||
234 | unsigned long p : 1; /* Private Bit */ | ||
235 | unsigned long alesn : 8; /* Access-List-Entry Sequence Number */ | ||
236 | unsigned long aleax : 16; /* Access-List-Entry Authorization Index */ | ||
237 | unsigned long : 32; | ||
238 | unsigned long : 1; | ||
239 | unsigned long asteo : 25; /* ASN-Second-Table-Entry Origin */ | ||
240 | unsigned long : 6; | ||
241 | unsigned long astesn : 32; /* ASTE Sequence Number */ | ||
242 | } __packed; | ||
243 | |||
244 | struct aste { | ||
245 | unsigned long i : 1; /* ASX-Invalid Bit */ | ||
246 | unsigned long ato : 29; /* Authority-Table Origin */ | ||
247 | unsigned long : 1; | ||
248 | unsigned long b : 1; /* Base-Space Bit */ | ||
249 | unsigned long ax : 16; /* Authorization Index */ | ||
250 | unsigned long atl : 12; /* Authority-Table Length */ | ||
251 | unsigned long : 2; | ||
252 | unsigned long ca : 1; /* Controlled-ASN Bit */ | ||
253 | unsigned long ra : 1; /* Reusable-ASN Bit */ | ||
254 | unsigned long asce : 64; /* Address-Space-Control Element */ | ||
255 | unsigned long ald : 32; | ||
256 | unsigned long astesn : 32; | ||
257 | /* .. more fields there */ | ||
258 | } __packed; | ||
210 | 259 | ||
211 | int ipte_lock_held(struct kvm_vcpu *vcpu) | 260 | int ipte_lock_held(struct kvm_vcpu *vcpu) |
212 | { | 261 | { |
@@ -307,15 +356,157 @@ void ipte_unlock(struct kvm_vcpu *vcpu) | |||
307 | ipte_unlock_simple(vcpu); | 356 | ipte_unlock_simple(vcpu); |
308 | } | 357 | } |
309 | 358 | ||
310 | static unsigned long get_vcpu_asce(struct kvm_vcpu *vcpu) | 359 | static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, ar_t ar, |
360 | int write) | ||
361 | { | ||
362 | union alet alet; | ||
363 | struct ale ale; | ||
364 | struct aste aste; | ||
365 | unsigned long ald_addr, authority_table_addr; | ||
366 | union ald ald; | ||
367 | int eax, rc; | ||
368 | u8 authority_table; | ||
369 | |||
370 | if (ar >= NUM_ACRS) | ||
371 | return -EINVAL; | ||
372 | |||
373 | save_access_regs(vcpu->run->s.regs.acrs); | ||
374 | alet.val = vcpu->run->s.regs.acrs[ar]; | ||
375 | |||
376 | if (ar == 0 || alet.val == 0) { | ||
377 | asce->val = vcpu->arch.sie_block->gcr[1]; | ||
378 | return 0; | ||
379 | } else if (alet.val == 1) { | ||
380 | asce->val = vcpu->arch.sie_block->gcr[7]; | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | if (alet.reserved) | ||
385 | return PGM_ALET_SPECIFICATION; | ||
386 | |||
387 | if (alet.p) | ||
388 | ald_addr = vcpu->arch.sie_block->gcr[5]; | ||
389 | else | ||
390 | ald_addr = vcpu->arch.sie_block->gcr[2]; | ||
391 | ald_addr &= 0x7fffffc0; | ||
392 | |||
393 | rc = read_guest_real(vcpu, ald_addr + 16, &ald.val, sizeof(union ald)); | ||
394 | if (rc) | ||
395 | return rc; | ||
396 | |||
397 | if (alet.alen / 8 > ald.all) | ||
398 | return PGM_ALEN_TRANSLATION; | ||
399 | |||
400 | if (0x7fffffff - ald.alo * 128 < alet.alen * 16) | ||
401 | return PGM_ADDRESSING; | ||
402 | |||
403 | rc = read_guest_real(vcpu, ald.alo * 128 + alet.alen * 16, &ale, | ||
404 | sizeof(struct ale)); | ||
405 | if (rc) | ||
406 | return rc; | ||
407 | |||
408 | if (ale.i == 1) | ||
409 | return PGM_ALEN_TRANSLATION; | ||
410 | if (ale.alesn != alet.alesn) | ||
411 | return PGM_ALE_SEQUENCE; | ||
412 | |||
413 | rc = read_guest_real(vcpu, ale.asteo * 64, &aste, sizeof(struct aste)); | ||
414 | if (rc) | ||
415 | return rc; | ||
416 | |||
417 | if (aste.i) | ||
418 | return PGM_ASTE_VALIDITY; | ||
419 | if (aste.astesn != ale.astesn) | ||
420 | return PGM_ASTE_SEQUENCE; | ||
421 | |||
422 | if (ale.p == 1) { | ||
423 | eax = (vcpu->arch.sie_block->gcr[8] >> 16) & 0xffff; | ||
424 | if (ale.aleax != eax) { | ||
425 | if (eax / 16 > aste.atl) | ||
426 | return PGM_EXTENDED_AUTHORITY; | ||
427 | |||
428 | authority_table_addr = aste.ato * 4 + eax / 4; | ||
429 | |||
430 | rc = read_guest_real(vcpu, authority_table_addr, | ||
431 | &authority_table, | ||
432 | sizeof(u8)); | ||
433 | if (rc) | ||
434 | return rc; | ||
435 | |||
436 | if ((authority_table & (0x40 >> ((eax & 3) * 2))) == 0) | ||
437 | return PGM_EXTENDED_AUTHORITY; | ||
438 | } | ||
439 | } | ||
440 | |||
441 | if (ale.fo == 1 && write) | ||
442 | return PGM_PROTECTION; | ||
443 | |||
444 | asce->val = aste.asce; | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | struct trans_exc_code_bits { | ||
449 | unsigned long addr : 52; /* Translation-exception Address */ | ||
450 | unsigned long fsi : 2; /* Access Exception Fetch/Store Indication */ | ||
451 | unsigned long : 6; | ||
452 | unsigned long b60 : 1; | ||
453 | unsigned long b61 : 1; | ||
454 | unsigned long as : 2; /* ASCE Identifier */ | ||
455 | }; | ||
456 | |||
457 | enum { | ||
458 | FSI_UNKNOWN = 0, /* Unknown wether fetch or store */ | ||
459 | FSI_STORE = 1, /* Exception was due to store operation */ | ||
460 | FSI_FETCH = 2 /* Exception was due to fetch operation */ | ||
461 | }; | ||
462 | |||
463 | static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce, | ||
464 | ar_t ar, int write) | ||
311 | { | 465 | { |
466 | int rc; | ||
467 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | ||
468 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; | ||
469 | struct trans_exc_code_bits *tec_bits; | ||
470 | |||
471 | memset(pgm, 0, sizeof(*pgm)); | ||
472 | tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code; | ||
473 | tec_bits->fsi = write ? FSI_STORE : FSI_FETCH; | ||
474 | tec_bits->as = psw_bits(*psw).as; | ||
475 | |||
476 | if (!psw_bits(*psw).t) { | ||
477 | asce->val = 0; | ||
478 | asce->r = 1; | ||
479 | return 0; | ||
480 | } | ||
481 | |||
312 | switch (psw_bits(vcpu->arch.sie_block->gpsw).as) { | 482 | switch (psw_bits(vcpu->arch.sie_block->gpsw).as) { |
313 | case PSW_AS_PRIMARY: | 483 | case PSW_AS_PRIMARY: |
314 | return vcpu->arch.sie_block->gcr[1]; | 484 | asce->val = vcpu->arch.sie_block->gcr[1]; |
485 | return 0; | ||
315 | case PSW_AS_SECONDARY: | 486 | case PSW_AS_SECONDARY: |
316 | return vcpu->arch.sie_block->gcr[7]; | 487 | asce->val = vcpu->arch.sie_block->gcr[7]; |
488 | return 0; | ||
317 | case PSW_AS_HOME: | 489 | case PSW_AS_HOME: |
318 | return vcpu->arch.sie_block->gcr[13]; | 490 | asce->val = vcpu->arch.sie_block->gcr[13]; |
491 | return 0; | ||
492 | case PSW_AS_ACCREG: | ||
493 | rc = ar_translation(vcpu, asce, ar, write); | ||
494 | switch (rc) { | ||
495 | case PGM_ALEN_TRANSLATION: | ||
496 | case PGM_ALE_SEQUENCE: | ||
497 | case PGM_ASTE_VALIDITY: | ||
498 | case PGM_ASTE_SEQUENCE: | ||
499 | case PGM_EXTENDED_AUTHORITY: | ||
500 | vcpu->arch.pgm.exc_access_id = ar; | ||
501 | break; | ||
502 | case PGM_PROTECTION: | ||
503 | tec_bits->b60 = 1; | ||
504 | tec_bits->b61 = 1; | ||
505 | break; | ||
506 | } | ||
507 | if (rc > 0) | ||
508 | pgm->code = rc; | ||
509 | return rc; | ||
319 | } | 510 | } |
320 | return 0; | 511 | return 0; |
321 | } | 512 | } |
@@ -330,10 +521,11 @@ static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val) | |||
330 | * @vcpu: virtual cpu | 521 | * @vcpu: virtual cpu |
331 | * @gva: guest virtual address | 522 | * @gva: guest virtual address |
332 | * @gpa: points to where guest physical (absolute) address should be stored | 523 | * @gpa: points to where guest physical (absolute) address should be stored |
524 | * @asce: effective asce | ||
333 | * @write: indicates if access is a write access | 525 | * @write: indicates if access is a write access |
334 | * | 526 | * |
335 | * Translate a guest virtual address into a guest absolute address by means | 527 | * Translate a guest virtual address into a guest absolute address by means |
336 | * of dynamic address translation as specified by the architecuture. | 528 | * of dynamic address translation as specified by the architecture. |
337 | * If the resulting absolute address is not available in the configuration | 529 | * If the resulting absolute address is not available in the configuration |
338 | * an addressing exception is indicated and @gpa will not be changed. | 530 | * an addressing exception is indicated and @gpa will not be changed. |
339 | * | 531 | * |
@@ -345,7 +537,8 @@ static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val) | |||
345 | * by the architecture | 537 | * by the architecture |
346 | */ | 538 | */ |
347 | static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, | 539 | static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, |
348 | unsigned long *gpa, int write) | 540 | unsigned long *gpa, const union asce asce, |
541 | int write) | ||
349 | { | 542 | { |
350 | union vaddress vaddr = {.addr = gva}; | 543 | union vaddress vaddr = {.addr = gva}; |
351 | union raddress raddr = {.addr = gva}; | 544 | union raddress raddr = {.addr = gva}; |
@@ -354,12 +547,10 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, | |||
354 | union ctlreg0 ctlreg0; | 547 | union ctlreg0 ctlreg0; |
355 | unsigned long ptr; | 548 | unsigned long ptr; |
356 | int edat1, edat2; | 549 | int edat1, edat2; |
357 | union asce asce; | ||
358 | 550 | ||
359 | ctlreg0.val = vcpu->arch.sie_block->gcr[0]; | 551 | ctlreg0.val = vcpu->arch.sie_block->gcr[0]; |
360 | edat1 = ctlreg0.edat && test_kvm_facility(vcpu->kvm, 8); | 552 | edat1 = ctlreg0.edat && test_kvm_facility(vcpu->kvm, 8); |
361 | edat2 = edat1 && test_kvm_facility(vcpu->kvm, 78); | 553 | edat2 = edat1 && test_kvm_facility(vcpu->kvm, 78); |
362 | asce.val = get_vcpu_asce(vcpu); | ||
363 | if (asce.r) | 554 | if (asce.r) |
364 | goto real_address; | 555 | goto real_address; |
365 | ptr = asce.origin * 4096; | 556 | ptr = asce.origin * 4096; |
@@ -506,48 +697,30 @@ static inline int is_low_address(unsigned long ga) | |||
506 | return (ga & ~0x11fful) == 0; | 697 | return (ga & ~0x11fful) == 0; |
507 | } | 698 | } |
508 | 699 | ||
509 | static int low_address_protection_enabled(struct kvm_vcpu *vcpu) | 700 | static int low_address_protection_enabled(struct kvm_vcpu *vcpu, |
701 | const union asce asce) | ||
510 | { | 702 | { |
511 | union ctlreg0 ctlreg0 = {.val = vcpu->arch.sie_block->gcr[0]}; | 703 | union ctlreg0 ctlreg0 = {.val = vcpu->arch.sie_block->gcr[0]}; |
512 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | 704 | psw_t *psw = &vcpu->arch.sie_block->gpsw; |
513 | union asce asce; | ||
514 | 705 | ||
515 | if (!ctlreg0.lap) | 706 | if (!ctlreg0.lap) |
516 | return 0; | 707 | return 0; |
517 | asce.val = get_vcpu_asce(vcpu); | ||
518 | if (psw_bits(*psw).t && asce.p) | 708 | if (psw_bits(*psw).t && asce.p) |
519 | return 0; | 709 | return 0; |
520 | return 1; | 710 | return 1; |
521 | } | 711 | } |
522 | 712 | ||
523 | struct trans_exc_code_bits { | ||
524 | unsigned long addr : 52; /* Translation-exception Address */ | ||
525 | unsigned long fsi : 2; /* Access Exception Fetch/Store Indication */ | ||
526 | unsigned long : 7; | ||
527 | unsigned long b61 : 1; | ||
528 | unsigned long as : 2; /* ASCE Identifier */ | ||
529 | }; | ||
530 | |||
531 | enum { | ||
532 | FSI_UNKNOWN = 0, /* Unknown wether fetch or store */ | ||
533 | FSI_STORE = 1, /* Exception was due to store operation */ | ||
534 | FSI_FETCH = 2 /* Exception was due to fetch operation */ | ||
535 | }; | ||
536 | |||
537 | static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, | 713 | static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, |
538 | unsigned long *pages, unsigned long nr_pages, | 714 | unsigned long *pages, unsigned long nr_pages, |
539 | int write) | 715 | const union asce asce, int write) |
540 | { | 716 | { |
541 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; | 717 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; |
542 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | 718 | psw_t *psw = &vcpu->arch.sie_block->gpsw; |
543 | struct trans_exc_code_bits *tec_bits; | 719 | struct trans_exc_code_bits *tec_bits; |
544 | int lap_enabled, rc; | 720 | int lap_enabled, rc; |
545 | 721 | ||
546 | memset(pgm, 0, sizeof(*pgm)); | ||
547 | tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code; | 722 | tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code; |
548 | tec_bits->fsi = write ? FSI_STORE : FSI_FETCH; | 723 | lap_enabled = low_address_protection_enabled(vcpu, asce); |
549 | tec_bits->as = psw_bits(*psw).as; | ||
550 | lap_enabled = low_address_protection_enabled(vcpu); | ||
551 | while (nr_pages) { | 724 | while (nr_pages) { |
552 | ga = kvm_s390_logical_to_effective(vcpu, ga); | 725 | ga = kvm_s390_logical_to_effective(vcpu, ga); |
553 | tec_bits->addr = ga >> PAGE_SHIFT; | 726 | tec_bits->addr = ga >> PAGE_SHIFT; |
@@ -557,7 +730,7 @@ static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, | |||
557 | } | 730 | } |
558 | ga &= PAGE_MASK; | 731 | ga &= PAGE_MASK; |
559 | if (psw_bits(*psw).t) { | 732 | if (psw_bits(*psw).t) { |
560 | rc = guest_translate(vcpu, ga, pages, write); | 733 | rc = guest_translate(vcpu, ga, pages, asce, write); |
561 | if (rc < 0) | 734 | if (rc < 0) |
562 | return rc; | 735 | return rc; |
563 | if (rc == PGM_PROTECTION) | 736 | if (rc == PGM_PROTECTION) |
@@ -578,7 +751,7 @@ static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, | |||
578 | return 0; | 751 | return 0; |
579 | } | 752 | } |
580 | 753 | ||
581 | int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data, | 754 | int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
582 | unsigned long len, int write) | 755 | unsigned long len, int write) |
583 | { | 756 | { |
584 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | 757 | psw_t *psw = &vcpu->arch.sie_block->gpsw; |
@@ -591,20 +764,19 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data, | |||
591 | 764 | ||
592 | if (!len) | 765 | if (!len) |
593 | return 0; | 766 | return 0; |
594 | /* Access register mode is not supported yet. */ | 767 | rc = get_vcpu_asce(vcpu, &asce, ar, write); |
595 | if (psw_bits(*psw).t && psw_bits(*psw).as == PSW_AS_ACCREG) | 768 | if (rc) |
596 | return -EOPNOTSUPP; | 769 | return rc; |
597 | nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1; | 770 | nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1; |
598 | pages = pages_array; | 771 | pages = pages_array; |
599 | if (nr_pages > ARRAY_SIZE(pages_array)) | 772 | if (nr_pages > ARRAY_SIZE(pages_array)) |
600 | pages = vmalloc(nr_pages * sizeof(unsigned long)); | 773 | pages = vmalloc(nr_pages * sizeof(unsigned long)); |
601 | if (!pages) | 774 | if (!pages) |
602 | return -ENOMEM; | 775 | return -ENOMEM; |
603 | asce.val = get_vcpu_asce(vcpu); | ||
604 | need_ipte_lock = psw_bits(*psw).t && !asce.r; | 776 | need_ipte_lock = psw_bits(*psw).t && !asce.r; |
605 | if (need_ipte_lock) | 777 | if (need_ipte_lock) |
606 | ipte_lock(vcpu); | 778 | ipte_lock(vcpu); |
607 | rc = guest_page_range(vcpu, ga, pages, nr_pages, write); | 779 | rc = guest_page_range(vcpu, ga, pages, nr_pages, asce, write); |
608 | for (idx = 0; idx < nr_pages && !rc; idx++) { | 780 | for (idx = 0; idx < nr_pages && !rc; idx++) { |
609 | gpa = *(pages + idx) + (ga & ~PAGE_MASK); | 781 | gpa = *(pages + idx) + (ga & ~PAGE_MASK); |
610 | _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); | 782 | _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); |
@@ -652,7 +824,7 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | |||
652 | * Note: The IPTE lock is not taken during this function, so the caller | 824 | * Note: The IPTE lock is not taken during this function, so the caller |
653 | * has to take care of this. | 825 | * has to take care of this. |
654 | */ | 826 | */ |
655 | int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, | 827 | int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, |
656 | unsigned long *gpa, int write) | 828 | unsigned long *gpa, int write) |
657 | { | 829 | { |
658 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; | 830 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; |
@@ -661,26 +833,21 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, | |||
661 | union asce asce; | 833 | union asce asce; |
662 | int rc; | 834 | int rc; |
663 | 835 | ||
664 | /* Access register mode is not supported yet. */ | ||
665 | if (psw_bits(*psw).t && psw_bits(*psw).as == PSW_AS_ACCREG) | ||
666 | return -EOPNOTSUPP; | ||
667 | |||
668 | gva = kvm_s390_logical_to_effective(vcpu, gva); | 836 | gva = kvm_s390_logical_to_effective(vcpu, gva); |
669 | memset(pgm, 0, sizeof(*pgm)); | ||
670 | tec = (struct trans_exc_code_bits *)&pgm->trans_exc_code; | 837 | tec = (struct trans_exc_code_bits *)&pgm->trans_exc_code; |
671 | tec->as = psw_bits(*psw).as; | 838 | rc = get_vcpu_asce(vcpu, &asce, ar, write); |
672 | tec->fsi = write ? FSI_STORE : FSI_FETCH; | ||
673 | tec->addr = gva >> PAGE_SHIFT; | 839 | tec->addr = gva >> PAGE_SHIFT; |
674 | if (is_low_address(gva) && low_address_protection_enabled(vcpu)) { | 840 | if (rc) |
841 | return rc; | ||
842 | if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) { | ||
675 | if (write) { | 843 | if (write) { |
676 | rc = pgm->code = PGM_PROTECTION; | 844 | rc = pgm->code = PGM_PROTECTION; |
677 | return rc; | 845 | return rc; |
678 | } | 846 | } |
679 | } | 847 | } |
680 | 848 | ||
681 | asce.val = get_vcpu_asce(vcpu); | ||
682 | if (psw_bits(*psw).t && !asce.r) { /* Use DAT? */ | 849 | if (psw_bits(*psw).t && !asce.r) { /* Use DAT? */ |
683 | rc = guest_translate(vcpu, gva, gpa, write); | 850 | rc = guest_translate(vcpu, gva, gpa, asce, write); |
684 | if (rc > 0) { | 851 | if (rc > 0) { |
685 | if (rc == PGM_PROTECTION) | 852 | if (rc == PGM_PROTECTION) |
686 | tec->b61 = 1; | 853 | tec->b61 = 1; |
@@ -697,28 +864,51 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, | |||
697 | } | 864 | } |
698 | 865 | ||
699 | /** | 866 | /** |
700 | * kvm_s390_check_low_addr_protection - check for low-address protection | 867 | * check_gva_range - test a range of guest virtual addresses for accessibility |
701 | * @ga: Guest address | 868 | */ |
869 | int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, | ||
870 | unsigned long length, int is_write) | ||
871 | { | ||
872 | unsigned long gpa; | ||
873 | unsigned long currlen; | ||
874 | int rc = 0; | ||
875 | |||
876 | ipte_lock(vcpu); | ||
877 | while (length > 0 && !rc) { | ||
878 | currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE)); | ||
879 | rc = guest_translate_address(vcpu, gva, ar, &gpa, is_write); | ||
880 | gva += currlen; | ||
881 | length -= currlen; | ||
882 | } | ||
883 | ipte_unlock(vcpu); | ||
884 | |||
885 | return rc; | ||
886 | } | ||
887 | |||
888 | /** | ||
889 | * kvm_s390_check_low_addr_prot_real - check for low-address protection | ||
890 | * @gra: Guest real address | ||
702 | * | 891 | * |
703 | * Checks whether an address is subject to low-address protection and set | 892 | * Checks whether an address is subject to low-address protection and set |
704 | * up vcpu->arch.pgm accordingly if necessary. | 893 | * up vcpu->arch.pgm accordingly if necessary. |
705 | * | 894 | * |
706 | * Return: 0 if no protection exception, or PGM_PROTECTION if protected. | 895 | * Return: 0 if no protection exception, or PGM_PROTECTION if protected. |
707 | */ | 896 | */ |
708 | int kvm_s390_check_low_addr_protection(struct kvm_vcpu *vcpu, unsigned long ga) | 897 | int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra) |
709 | { | 898 | { |
710 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; | 899 | struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm; |
711 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | 900 | psw_t *psw = &vcpu->arch.sie_block->gpsw; |
712 | struct trans_exc_code_bits *tec_bits; | 901 | struct trans_exc_code_bits *tec_bits; |
902 | union ctlreg0 ctlreg0 = {.val = vcpu->arch.sie_block->gcr[0]}; | ||
713 | 903 | ||
714 | if (!is_low_address(ga) || !low_address_protection_enabled(vcpu)) | 904 | if (!ctlreg0.lap || !is_low_address(gra)) |
715 | return 0; | 905 | return 0; |
716 | 906 | ||
717 | memset(pgm, 0, sizeof(*pgm)); | 907 | memset(pgm, 0, sizeof(*pgm)); |
718 | tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code; | 908 | tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code; |
719 | tec_bits->fsi = FSI_STORE; | 909 | tec_bits->fsi = FSI_STORE; |
720 | tec_bits->as = psw_bits(*psw).as; | 910 | tec_bits->as = psw_bits(*psw).as; |
721 | tec_bits->addr = ga >> PAGE_SHIFT; | 911 | tec_bits->addr = gra >> PAGE_SHIFT; |
722 | pgm->code = PGM_PROTECTION; | 912 | pgm->code = PGM_PROTECTION; |
723 | 913 | ||
724 | return pgm->code; | 914 | return pgm->code; |
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index 0149cf15058a..ef03726cc661 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h | |||
@@ -156,9 +156,11 @@ int read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data, | |||
156 | } | 156 | } |
157 | 157 | ||
158 | int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, | 158 | int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, |
159 | unsigned long *gpa, int write); | 159 | ar_t ar, unsigned long *gpa, int write); |
160 | int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar, | ||
161 | unsigned long length, int is_write); | ||
160 | 162 | ||
161 | int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data, | 163 | int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
162 | unsigned long len, int write); | 164 | unsigned long len, int write); |
163 | 165 | ||
164 | int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | 166 | int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, |
@@ -168,6 +170,7 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | |||
168 | * write_guest - copy data from kernel space to guest space | 170 | * write_guest - copy data from kernel space to guest space |
169 | * @vcpu: virtual cpu | 171 | * @vcpu: virtual cpu |
170 | * @ga: guest address | 172 | * @ga: guest address |
173 | * @ar: access register | ||
171 | * @data: source address in kernel space | 174 | * @data: source address in kernel space |
172 | * @len: number of bytes to copy | 175 | * @len: number of bytes to copy |
173 | * | 176 | * |
@@ -176,8 +179,7 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | |||
176 | * If DAT is off data will be copied to guest real or absolute memory. | 179 | * If DAT is off data will be copied to guest real or absolute memory. |
177 | * If DAT is on data will be copied to the address space as specified by | 180 | * If DAT is on data will be copied to the address space as specified by |
178 | * the address space bits of the PSW: | 181 | * the address space bits of the PSW: |
179 | * Primary, secondory or home space (access register mode is currently not | 182 | * Primary, secondary, home space or access register mode. |
180 | * implemented). | ||
181 | * The addressing mode of the PSW is also inspected, so that address wrap | 183 | * The addressing mode of the PSW is also inspected, so that address wrap |
182 | * around is taken into account for 24-, 31- and 64-bit addressing mode, | 184 | * around is taken into account for 24-, 31- and 64-bit addressing mode, |
183 | * if the to be copied data crosses page boundaries in guest address space. | 185 | * if the to be copied data crosses page boundaries in guest address space. |
@@ -210,16 +212,17 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, | |||
210 | * if data has been changed in guest space in case of an exception. | 212 | * if data has been changed in guest space in case of an exception. |
211 | */ | 213 | */ |
212 | static inline __must_check | 214 | static inline __must_check |
213 | int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data, | 215 | int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
214 | unsigned long len) | 216 | unsigned long len) |
215 | { | 217 | { |
216 | return access_guest(vcpu, ga, data, len, 1); | 218 | return access_guest(vcpu, ga, ar, data, len, 1); |
217 | } | 219 | } |
218 | 220 | ||
219 | /** | 221 | /** |
220 | * read_guest - copy data from guest space to kernel space | 222 | * read_guest - copy data from guest space to kernel space |
221 | * @vcpu: virtual cpu | 223 | * @vcpu: virtual cpu |
222 | * @ga: guest address | 224 | * @ga: guest address |
225 | * @ar: access register | ||
223 | * @data: destination address in kernel space | 226 | * @data: destination address in kernel space |
224 | * @len: number of bytes to copy | 227 | * @len: number of bytes to copy |
225 | * | 228 | * |
@@ -229,10 +232,10 @@ int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data, | |||
229 | * data will be copied from guest space to kernel space. | 232 | * data will be copied from guest space to kernel space. |
230 | */ | 233 | */ |
231 | static inline __must_check | 234 | static inline __must_check |
232 | int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data, | 235 | int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data, |
233 | unsigned long len) | 236 | unsigned long len) |
234 | { | 237 | { |
235 | return access_guest(vcpu, ga, data, len, 0); | 238 | return access_guest(vcpu, ga, ar, data, len, 0); |
236 | } | 239 | } |
237 | 240 | ||
238 | /** | 241 | /** |
@@ -330,6 +333,6 @@ int read_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data, | |||
330 | void ipte_lock(struct kvm_vcpu *vcpu); | 333 | void ipte_lock(struct kvm_vcpu *vcpu); |
331 | void ipte_unlock(struct kvm_vcpu *vcpu); | 334 | void ipte_unlock(struct kvm_vcpu *vcpu); |
332 | int ipte_lock_held(struct kvm_vcpu *vcpu); | 335 | int ipte_lock_held(struct kvm_vcpu *vcpu); |
333 | int kvm_s390_check_low_addr_protection(struct kvm_vcpu *vcpu, unsigned long ga); | 336 | int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra); |
334 | 337 | ||
335 | #endif /* __KVM_S390_GACCESS_H */ | 338 | #endif /* __KVM_S390_GACCESS_H */ |
diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c index 3e8d4092ce30..e97b3455d7e6 100644 --- a/arch/s390/kvm/guestdbg.c +++ b/arch/s390/kvm/guestdbg.c | |||
@@ -191,8 +191,8 @@ static int __import_wp_info(struct kvm_vcpu *vcpu, | |||
191 | if (!wp_info->old_data) | 191 | if (!wp_info->old_data) |
192 | return -ENOMEM; | 192 | return -ENOMEM; |
193 | /* try to backup the original value */ | 193 | /* try to backup the original value */ |
194 | ret = read_guest(vcpu, wp_info->phys_addr, wp_info->old_data, | 194 | ret = read_guest_abs(vcpu, wp_info->phys_addr, wp_info->old_data, |
195 | wp_info->len); | 195 | wp_info->len); |
196 | if (ret) { | 196 | if (ret) { |
197 | kfree(wp_info->old_data); | 197 | kfree(wp_info->old_data); |
198 | wp_info->old_data = NULL; | 198 | wp_info->old_data = NULL; |
@@ -362,8 +362,8 @@ static struct kvm_hw_wp_info_arch *any_wp_changed(struct kvm_vcpu *vcpu) | |||
362 | continue; | 362 | continue; |
363 | 363 | ||
364 | /* refetch the wp data and compare it to the old value */ | 364 | /* refetch the wp data and compare it to the old value */ |
365 | if (!read_guest(vcpu, wp_info->phys_addr, temp, | 365 | if (!read_guest_abs(vcpu, wp_info->phys_addr, temp, |
366 | wp_info->len)) { | 366 | wp_info->len)) { |
367 | if (memcmp(temp, wp_info->old_data, wp_info->len)) { | 367 | if (memcmp(temp, wp_info->old_data, wp_info->len)) { |
368 | kfree(temp); | 368 | kfree(temp); |
369 | return wp_info; | 369 | return wp_info; |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index bebd2157edd0..9e3779e3e496 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -165,6 +165,7 @@ static void __extract_prog_irq(struct kvm_vcpu *vcpu, | |||
165 | pgm_info->mon_class_nr = vcpu->arch.sie_block->mcn; | 165 | pgm_info->mon_class_nr = vcpu->arch.sie_block->mcn; |
166 | pgm_info->mon_code = vcpu->arch.sie_block->tecmc; | 166 | pgm_info->mon_code = vcpu->arch.sie_block->tecmc; |
167 | break; | 167 | break; |
168 | case PGM_VECTOR_PROCESSING: | ||
168 | case PGM_DATA: | 169 | case PGM_DATA: |
169 | pgm_info->data_exc_code = vcpu->arch.sie_block->dxc; | 170 | pgm_info->data_exc_code = vcpu->arch.sie_block->dxc; |
170 | break; | 171 | break; |
@@ -319,7 +320,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu) | |||
319 | 320 | ||
320 | /* Make sure that the source is paged-in */ | 321 | /* Make sure that the source is paged-in */ |
321 | rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg2], | 322 | rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg2], |
322 | &srcaddr, 0); | 323 | reg2, &srcaddr, 0); |
323 | if (rc) | 324 | if (rc) |
324 | return kvm_s390_inject_prog_cond(vcpu, rc); | 325 | return kvm_s390_inject_prog_cond(vcpu, rc); |
325 | rc = kvm_arch_fault_in_page(vcpu, srcaddr, 0); | 326 | rc = kvm_arch_fault_in_page(vcpu, srcaddr, 0); |
@@ -328,7 +329,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu) | |||
328 | 329 | ||
329 | /* Make sure that the destination is paged-in */ | 330 | /* Make sure that the destination is paged-in */ |
330 | rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg1], | 331 | rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg1], |
331 | &dstaddr, 1); | 332 | reg1, &dstaddr, 1); |
332 | if (rc) | 333 | if (rc) |
333 | return kvm_s390_inject_prog_cond(vcpu, rc); | 334 | return kvm_s390_inject_prog_cond(vcpu, rc); |
334 | rc = kvm_arch_fault_in_page(vcpu, dstaddr, 1); | 335 | rc = kvm_arch_fault_in_page(vcpu, dstaddr, 1); |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 073b5f387d1d..9de47265ef73 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * handling kvm guest interrupts | 2 | * handling kvm guest interrupts |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2008,2014 | 4 | * Copyright IBM Corp. 2008, 2015 |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License (version 2 only) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
@@ -17,9 +17,12 @@ | |||
17 | #include <linux/signal.h> | 17 | #include <linux/signal.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/bitmap.h> | 19 | #include <linux/bitmap.h> |
20 | #include <linux/vmalloc.h> | ||
20 | #include <asm/asm-offsets.h> | 21 | #include <asm/asm-offsets.h> |
22 | #include <asm/dis.h> | ||
21 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
22 | #include <asm/sclp.h> | 24 | #include <asm/sclp.h> |
25 | #include <asm/isc.h> | ||
23 | #include "kvm-s390.h" | 26 | #include "kvm-s390.h" |
24 | #include "gaccess.h" | 27 | #include "gaccess.h" |
25 | #include "trace-s390.h" | 28 | #include "trace-s390.h" |
@@ -32,11 +35,6 @@ | |||
32 | #define PFAULT_DONE 0x0680 | 35 | #define PFAULT_DONE 0x0680 |
33 | #define VIRTIO_PARAM 0x0d00 | 36 | #define VIRTIO_PARAM 0x0d00 |
34 | 37 | ||
35 | static int is_ioint(u64 type) | ||
36 | { | ||
37 | return ((type & 0xfffe0000u) != 0xfffe0000u); | ||
38 | } | ||
39 | |||
40 | int psw_extint_disabled(struct kvm_vcpu *vcpu) | 38 | int psw_extint_disabled(struct kvm_vcpu *vcpu) |
41 | { | 39 | { |
42 | return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_EXT); | 40 | return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_EXT); |
@@ -72,70 +70,45 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu) | |||
72 | return 1; | 70 | return 1; |
73 | } | 71 | } |
74 | 72 | ||
75 | static u64 int_word_to_isc_bits(u32 int_word) | 73 | static int ckc_irq_pending(struct kvm_vcpu *vcpu) |
74 | { | ||
75 | if (!(vcpu->arch.sie_block->ckc < | ||
76 | get_tod_clock_fast() + vcpu->arch.sie_block->epoch)) | ||
77 | return 0; | ||
78 | return ckc_interrupts_enabled(vcpu); | ||
79 | } | ||
80 | |||
81 | static int cpu_timer_interrupts_enabled(struct kvm_vcpu *vcpu) | ||
82 | { | ||
83 | return !psw_extint_disabled(vcpu) && | ||
84 | (vcpu->arch.sie_block->gcr[0] & 0x400ul); | ||
85 | } | ||
86 | |||
87 | static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu) | ||
88 | { | ||
89 | return (vcpu->arch.sie_block->cputm >> 63) && | ||
90 | cpu_timer_interrupts_enabled(vcpu); | ||
91 | } | ||
92 | |||
93 | static inline int is_ioirq(unsigned long irq_type) | ||
76 | { | 94 | { |
77 | u8 isc = (int_word & 0x38000000) >> 27; | 95 | return ((irq_type >= IRQ_PEND_IO_ISC_0) && |
96 | (irq_type <= IRQ_PEND_IO_ISC_7)); | ||
97 | } | ||
78 | 98 | ||
99 | static uint64_t isc_to_isc_bits(int isc) | ||
100 | { | ||
79 | return (0x80 >> isc) << 24; | 101 | return (0x80 >> isc) << 24; |
80 | } | 102 | } |
81 | 103 | ||
82 | static int __must_check __interrupt_is_deliverable(struct kvm_vcpu *vcpu, | 104 | static inline u8 int_word_to_isc(u32 int_word) |
83 | struct kvm_s390_interrupt_info *inti) | ||
84 | { | 105 | { |
85 | switch (inti->type) { | 106 | return (int_word & 0x38000000) >> 27; |
86 | case KVM_S390_INT_EXTERNAL_CALL: | 107 | } |
87 | if (psw_extint_disabled(vcpu)) | 108 | |
88 | return 0; | 109 | static inline unsigned long pending_floating_irqs(struct kvm_vcpu *vcpu) |
89 | if (vcpu->arch.sie_block->gcr[0] & 0x2000ul) | 110 | { |
90 | return 1; | 111 | return vcpu->kvm->arch.float_int.pending_irqs; |
91 | return 0; | ||
92 | case KVM_S390_INT_EMERGENCY: | ||
93 | if (psw_extint_disabled(vcpu)) | ||
94 | return 0; | ||
95 | if (vcpu->arch.sie_block->gcr[0] & 0x4000ul) | ||
96 | return 1; | ||
97 | return 0; | ||
98 | case KVM_S390_INT_CLOCK_COMP: | ||
99 | return ckc_interrupts_enabled(vcpu); | ||
100 | case KVM_S390_INT_CPU_TIMER: | ||
101 | if (psw_extint_disabled(vcpu)) | ||
102 | return 0; | ||
103 | if (vcpu->arch.sie_block->gcr[0] & 0x400ul) | ||
104 | return 1; | ||
105 | return 0; | ||
106 | case KVM_S390_INT_SERVICE: | ||
107 | case KVM_S390_INT_PFAULT_INIT: | ||
108 | case KVM_S390_INT_PFAULT_DONE: | ||
109 | case KVM_S390_INT_VIRTIO: | ||
110 | if (psw_extint_disabled(vcpu)) | ||
111 | return 0; | ||
112 | if (vcpu->arch.sie_block->gcr[0] & 0x200ul) | ||
113 | return 1; | ||
114 | return 0; | ||
115 | case KVM_S390_PROGRAM_INT: | ||
116 | case KVM_S390_SIGP_STOP: | ||
117 | case KVM_S390_SIGP_SET_PREFIX: | ||
118 | case KVM_S390_RESTART: | ||
119 | return 1; | ||
120 | case KVM_S390_MCHK: | ||
121 | if (psw_mchk_disabled(vcpu)) | ||
122 | return 0; | ||
123 | if (vcpu->arch.sie_block->gcr[14] & inti->mchk.cr14) | ||
124 | return 1; | ||
125 | return 0; | ||
126 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | ||
127 | if (psw_ioint_disabled(vcpu)) | ||
128 | return 0; | ||
129 | if (vcpu->arch.sie_block->gcr[6] & | ||
130 | int_word_to_isc_bits(inti->io.io_int_word)) | ||
131 | return 1; | ||
132 | return 0; | ||
133 | default: | ||
134 | printk(KERN_WARNING "illegal interrupt type %llx\n", | ||
135 | inti->type); | ||
136 | BUG(); | ||
137 | } | ||
138 | return 0; | ||
139 | } | 112 | } |
140 | 113 | ||
141 | static inline unsigned long pending_local_irqs(struct kvm_vcpu *vcpu) | 114 | static inline unsigned long pending_local_irqs(struct kvm_vcpu *vcpu) |
@@ -143,12 +116,31 @@ static inline unsigned long pending_local_irqs(struct kvm_vcpu *vcpu) | |||
143 | return vcpu->arch.local_int.pending_irqs; | 116 | return vcpu->arch.local_int.pending_irqs; |
144 | } | 117 | } |
145 | 118 | ||
146 | static unsigned long deliverable_local_irqs(struct kvm_vcpu *vcpu) | 119 | static unsigned long disable_iscs(struct kvm_vcpu *vcpu, |
120 | unsigned long active_mask) | ||
121 | { | ||
122 | int i; | ||
123 | |||
124 | for (i = 0; i <= MAX_ISC; i++) | ||
125 | if (!(vcpu->arch.sie_block->gcr[6] & isc_to_isc_bits(i))) | ||
126 | active_mask &= ~(1UL << (IRQ_PEND_IO_ISC_0 + i)); | ||
127 | |||
128 | return active_mask; | ||
129 | } | ||
130 | |||
131 | static unsigned long deliverable_irqs(struct kvm_vcpu *vcpu) | ||
147 | { | 132 | { |
148 | unsigned long active_mask = pending_local_irqs(vcpu); | 133 | unsigned long active_mask; |
134 | |||
135 | active_mask = pending_local_irqs(vcpu); | ||
136 | active_mask |= pending_floating_irqs(vcpu); | ||
149 | 137 | ||
150 | if (psw_extint_disabled(vcpu)) | 138 | if (psw_extint_disabled(vcpu)) |
151 | active_mask &= ~IRQ_PEND_EXT_MASK; | 139 | active_mask &= ~IRQ_PEND_EXT_MASK; |
140 | if (psw_ioint_disabled(vcpu)) | ||
141 | active_mask &= ~IRQ_PEND_IO_MASK; | ||
142 | else | ||
143 | active_mask = disable_iscs(vcpu, active_mask); | ||
152 | if (!(vcpu->arch.sie_block->gcr[0] & 0x2000ul)) | 144 | if (!(vcpu->arch.sie_block->gcr[0] & 0x2000ul)) |
153 | __clear_bit(IRQ_PEND_EXT_EXTERNAL, &active_mask); | 145 | __clear_bit(IRQ_PEND_EXT_EXTERNAL, &active_mask); |
154 | if (!(vcpu->arch.sie_block->gcr[0] & 0x4000ul)) | 146 | if (!(vcpu->arch.sie_block->gcr[0] & 0x4000ul)) |
@@ -157,8 +149,13 @@ static unsigned long deliverable_local_irqs(struct kvm_vcpu *vcpu) | |||
157 | __clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &active_mask); | 149 | __clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &active_mask); |
158 | if (!(vcpu->arch.sie_block->gcr[0] & 0x400ul)) | 150 | if (!(vcpu->arch.sie_block->gcr[0] & 0x400ul)) |
159 | __clear_bit(IRQ_PEND_EXT_CPU_TIMER, &active_mask); | 151 | __clear_bit(IRQ_PEND_EXT_CPU_TIMER, &active_mask); |
152 | if (!(vcpu->arch.sie_block->gcr[0] & 0x200ul)) | ||
153 | __clear_bit(IRQ_PEND_EXT_SERVICE, &active_mask); | ||
160 | if (psw_mchk_disabled(vcpu)) | 154 | if (psw_mchk_disabled(vcpu)) |
161 | active_mask &= ~IRQ_PEND_MCHK_MASK; | 155 | active_mask &= ~IRQ_PEND_MCHK_MASK; |
156 | if (!(vcpu->arch.sie_block->gcr[14] & | ||
157 | vcpu->kvm->arch.float_int.mchk.cr14)) | ||
158 | __clear_bit(IRQ_PEND_MCHK_REP, &active_mask); | ||
162 | 159 | ||
163 | /* | 160 | /* |
164 | * STOP irqs will never be actively delivered. They are triggered via | 161 | * STOP irqs will never be actively delivered. They are triggered via |
@@ -200,6 +197,16 @@ static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag) | |||
200 | atomic_set_mask(flag, &vcpu->arch.sie_block->cpuflags); | 197 | atomic_set_mask(flag, &vcpu->arch.sie_block->cpuflags); |
201 | } | 198 | } |
202 | 199 | ||
200 | static void set_intercept_indicators_io(struct kvm_vcpu *vcpu) | ||
201 | { | ||
202 | if (!(pending_floating_irqs(vcpu) & IRQ_PEND_IO_MASK)) | ||
203 | return; | ||
204 | else if (psw_ioint_disabled(vcpu)) | ||
205 | __set_cpuflag(vcpu, CPUSTAT_IO_INT); | ||
206 | else | ||
207 | vcpu->arch.sie_block->lctl |= LCTL_CR6; | ||
208 | } | ||
209 | |||
203 | static void set_intercept_indicators_ext(struct kvm_vcpu *vcpu) | 210 | static void set_intercept_indicators_ext(struct kvm_vcpu *vcpu) |
204 | { | 211 | { |
205 | if (!(pending_local_irqs(vcpu) & IRQ_PEND_EXT_MASK)) | 212 | if (!(pending_local_irqs(vcpu) & IRQ_PEND_EXT_MASK)) |
@@ -226,47 +233,17 @@ static void set_intercept_indicators_stop(struct kvm_vcpu *vcpu) | |||
226 | __set_cpuflag(vcpu, CPUSTAT_STOP_INT); | 233 | __set_cpuflag(vcpu, CPUSTAT_STOP_INT); |
227 | } | 234 | } |
228 | 235 | ||
229 | /* Set interception request for non-deliverable local interrupts */ | 236 | /* Set interception request for non-deliverable interrupts */ |
230 | static void set_intercept_indicators_local(struct kvm_vcpu *vcpu) | 237 | static void set_intercept_indicators(struct kvm_vcpu *vcpu) |
231 | { | 238 | { |
239 | set_intercept_indicators_io(vcpu); | ||
232 | set_intercept_indicators_ext(vcpu); | 240 | set_intercept_indicators_ext(vcpu); |
233 | set_intercept_indicators_mchk(vcpu); | 241 | set_intercept_indicators_mchk(vcpu); |
234 | set_intercept_indicators_stop(vcpu); | 242 | set_intercept_indicators_stop(vcpu); |
235 | } | 243 | } |
236 | 244 | ||
237 | static void __set_intercept_indicator(struct kvm_vcpu *vcpu, | ||
238 | struct kvm_s390_interrupt_info *inti) | ||
239 | { | ||
240 | switch (inti->type) { | ||
241 | case KVM_S390_INT_SERVICE: | ||
242 | case KVM_S390_INT_PFAULT_DONE: | ||
243 | case KVM_S390_INT_VIRTIO: | ||
244 | if (psw_extint_disabled(vcpu)) | ||
245 | __set_cpuflag(vcpu, CPUSTAT_EXT_INT); | ||
246 | else | ||
247 | vcpu->arch.sie_block->lctl |= LCTL_CR0; | ||
248 | break; | ||
249 | case KVM_S390_MCHK: | ||
250 | if (psw_mchk_disabled(vcpu)) | ||
251 | vcpu->arch.sie_block->ictl |= ICTL_LPSW; | ||
252 | else | ||
253 | vcpu->arch.sie_block->lctl |= LCTL_CR14; | ||
254 | break; | ||
255 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | ||
256 | if (psw_ioint_disabled(vcpu)) | ||
257 | __set_cpuflag(vcpu, CPUSTAT_IO_INT); | ||
258 | else | ||
259 | vcpu->arch.sie_block->lctl |= LCTL_CR6; | ||
260 | break; | ||
261 | default: | ||
262 | BUG(); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | static u16 get_ilc(struct kvm_vcpu *vcpu) | 245 | static u16 get_ilc(struct kvm_vcpu *vcpu) |
267 | { | 246 | { |
268 | const unsigned short table[] = { 2, 4, 4, 6 }; | ||
269 | |||
270 | switch (vcpu->arch.sie_block->icptcode) { | 247 | switch (vcpu->arch.sie_block->icptcode) { |
271 | case ICPT_INST: | 248 | case ICPT_INST: |
272 | case ICPT_INSTPROGI: | 249 | case ICPT_INSTPROGI: |
@@ -274,7 +251,7 @@ static u16 get_ilc(struct kvm_vcpu *vcpu) | |||
274 | case ICPT_PARTEXEC: | 251 | case ICPT_PARTEXEC: |
275 | case ICPT_IOINST: | 252 | case ICPT_IOINST: |
276 | /* last instruction only stored for these icptcodes */ | 253 | /* last instruction only stored for these icptcodes */ |
277 | return table[vcpu->arch.sie_block->ipa >> 14]; | 254 | return insn_length(vcpu->arch.sie_block->ipa >> 8); |
278 | case ICPT_PROGI: | 255 | case ICPT_PROGI: |
279 | return vcpu->arch.sie_block->pgmilc; | 256 | return vcpu->arch.sie_block->pgmilc; |
280 | default: | 257 | default: |
@@ -350,38 +327,72 @@ static int __must_check __deliver_pfault_init(struct kvm_vcpu *vcpu) | |||
350 | 327 | ||
351 | static int __must_check __deliver_machine_check(struct kvm_vcpu *vcpu) | 328 | static int __must_check __deliver_machine_check(struct kvm_vcpu *vcpu) |
352 | { | 329 | { |
330 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | ||
353 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 331 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
354 | struct kvm_s390_mchk_info mchk; | 332 | struct kvm_s390_mchk_info mchk = {}; |
355 | int rc; | 333 | unsigned long adtl_status_addr; |
334 | int deliver = 0; | ||
335 | int rc = 0; | ||
356 | 336 | ||
337 | spin_lock(&fi->lock); | ||
357 | spin_lock(&li->lock); | 338 | spin_lock(&li->lock); |
358 | mchk = li->irq.mchk; | 339 | if (test_bit(IRQ_PEND_MCHK_EX, &li->pending_irqs) || |
340 | test_bit(IRQ_PEND_MCHK_REP, &li->pending_irqs)) { | ||
341 | /* | ||
342 | * If there was an exigent machine check pending, then any | ||
343 | * repressible machine checks that might have been pending | ||
344 | * are indicated along with it, so always clear bits for | ||
345 | * repressible and exigent interrupts | ||
346 | */ | ||
347 | mchk = li->irq.mchk; | ||
348 | clear_bit(IRQ_PEND_MCHK_EX, &li->pending_irqs); | ||
349 | clear_bit(IRQ_PEND_MCHK_REP, &li->pending_irqs); | ||
350 | memset(&li->irq.mchk, 0, sizeof(mchk)); | ||
351 | deliver = 1; | ||
352 | } | ||
359 | /* | 353 | /* |
360 | * If there was an exigent machine check pending, then any repressible | 354 | * We indicate floating repressible conditions along with |
361 | * machine checks that might have been pending are indicated along | 355 | * other pending conditions. Channel Report Pending and Channel |
362 | * with it, so always clear both bits | 356 | * Subsystem damage are the only two and and are indicated by |
357 | * bits in mcic and masked in cr14. | ||
363 | */ | 358 | */ |
364 | clear_bit(IRQ_PEND_MCHK_EX, &li->pending_irqs); | 359 | if (test_and_clear_bit(IRQ_PEND_MCHK_REP, &fi->pending_irqs)) { |
365 | clear_bit(IRQ_PEND_MCHK_REP, &li->pending_irqs); | 360 | mchk.mcic |= fi->mchk.mcic; |
366 | memset(&li->irq.mchk, 0, sizeof(mchk)); | 361 | mchk.cr14 |= fi->mchk.cr14; |
362 | memset(&fi->mchk, 0, sizeof(mchk)); | ||
363 | deliver = 1; | ||
364 | } | ||
367 | spin_unlock(&li->lock); | 365 | spin_unlock(&li->lock); |
366 | spin_unlock(&fi->lock); | ||
368 | 367 | ||
369 | VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx", | 368 | if (deliver) { |
370 | mchk.mcic); | 369 | VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx", |
371 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_MCHK, | 370 | mchk.mcic); |
372 | mchk.cr14, mchk.mcic); | 371 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, |
373 | 372 | KVM_S390_MCHK, | |
374 | rc = kvm_s390_vcpu_store_status(vcpu, KVM_S390_STORE_STATUS_PREFIXED); | 373 | mchk.cr14, mchk.mcic); |
375 | rc |= put_guest_lc(vcpu, mchk.mcic, | 374 | |
376 | (u64 __user *) __LC_MCCK_CODE); | 375 | rc = kvm_s390_vcpu_store_status(vcpu, |
377 | rc |= put_guest_lc(vcpu, mchk.failing_storage_address, | 376 | KVM_S390_STORE_STATUS_PREFIXED); |
378 | (u64 __user *) __LC_MCCK_FAIL_STOR_ADDR); | 377 | rc |= read_guest_lc(vcpu, __LC_VX_SAVE_AREA_ADDR, |
379 | rc |= write_guest_lc(vcpu, __LC_PSW_SAVE_AREA, | 378 | &adtl_status_addr, |
380 | &mchk.fixed_logout, sizeof(mchk.fixed_logout)); | 379 | sizeof(unsigned long)); |
381 | rc |= write_guest_lc(vcpu, __LC_MCK_OLD_PSW, | 380 | rc |= kvm_s390_vcpu_store_adtl_status(vcpu, |
382 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 381 | adtl_status_addr); |
383 | rc |= read_guest_lc(vcpu, __LC_MCK_NEW_PSW, | 382 | rc |= put_guest_lc(vcpu, mchk.mcic, |
384 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 383 | (u64 __user *) __LC_MCCK_CODE); |
384 | rc |= put_guest_lc(vcpu, mchk.failing_storage_address, | ||
385 | (u64 __user *) __LC_MCCK_FAIL_STOR_ADDR); | ||
386 | rc |= write_guest_lc(vcpu, __LC_PSW_SAVE_AREA, | ||
387 | &mchk.fixed_logout, | ||
388 | sizeof(mchk.fixed_logout)); | ||
389 | rc |= write_guest_lc(vcpu, __LC_MCK_OLD_PSW, | ||
390 | &vcpu->arch.sie_block->gpsw, | ||
391 | sizeof(psw_t)); | ||
392 | rc |= read_guest_lc(vcpu, __LC_MCK_NEW_PSW, | ||
393 | &vcpu->arch.sie_block->gpsw, | ||
394 | sizeof(psw_t)); | ||
395 | } | ||
385 | return rc ? -EFAULT : 0; | 396 | return rc ? -EFAULT : 0; |
386 | } | 397 | } |
387 | 398 | ||
@@ -484,7 +495,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) | |||
484 | { | 495 | { |
485 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 496 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
486 | struct kvm_s390_pgm_info pgm_info; | 497 | struct kvm_s390_pgm_info pgm_info; |
487 | int rc = 0; | 498 | int rc = 0, nullifying = false; |
488 | u16 ilc = get_ilc(vcpu); | 499 | u16 ilc = get_ilc(vcpu); |
489 | 500 | ||
490 | spin_lock(&li->lock); | 501 | spin_lock(&li->lock); |
@@ -509,6 +520,8 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) | |||
509 | case PGM_LX_TRANSLATION: | 520 | case PGM_LX_TRANSLATION: |
510 | case PGM_PRIMARY_AUTHORITY: | 521 | case PGM_PRIMARY_AUTHORITY: |
511 | case PGM_SECONDARY_AUTHORITY: | 522 | case PGM_SECONDARY_AUTHORITY: |
523 | nullifying = true; | ||
524 | /* fall through */ | ||
512 | case PGM_SPACE_SWITCH: | 525 | case PGM_SPACE_SWITCH: |
513 | rc = put_guest_lc(vcpu, pgm_info.trans_exc_code, | 526 | rc = put_guest_lc(vcpu, pgm_info.trans_exc_code, |
514 | (u64 *)__LC_TRANS_EXC_CODE); | 527 | (u64 *)__LC_TRANS_EXC_CODE); |
@@ -521,6 +534,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) | |||
521 | case PGM_EXTENDED_AUTHORITY: | 534 | case PGM_EXTENDED_AUTHORITY: |
522 | rc = put_guest_lc(vcpu, pgm_info.exc_access_id, | 535 | rc = put_guest_lc(vcpu, pgm_info.exc_access_id, |
523 | (u8 *)__LC_EXC_ACCESS_ID); | 536 | (u8 *)__LC_EXC_ACCESS_ID); |
537 | nullifying = true; | ||
524 | break; | 538 | break; |
525 | case PGM_ASCE_TYPE: | 539 | case PGM_ASCE_TYPE: |
526 | case PGM_PAGE_TRANSLATION: | 540 | case PGM_PAGE_TRANSLATION: |
@@ -534,6 +548,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) | |||
534 | (u8 *)__LC_EXC_ACCESS_ID); | 548 | (u8 *)__LC_EXC_ACCESS_ID); |
535 | rc |= put_guest_lc(vcpu, pgm_info.op_access_id, | 549 | rc |= put_guest_lc(vcpu, pgm_info.op_access_id, |
536 | (u8 *)__LC_OP_ACCESS_ID); | 550 | (u8 *)__LC_OP_ACCESS_ID); |
551 | nullifying = true; | ||
537 | break; | 552 | break; |
538 | case PGM_MONITOR: | 553 | case PGM_MONITOR: |
539 | rc = put_guest_lc(vcpu, pgm_info.mon_class_nr, | 554 | rc = put_guest_lc(vcpu, pgm_info.mon_class_nr, |
@@ -541,6 +556,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) | |||
541 | rc |= put_guest_lc(vcpu, pgm_info.mon_code, | 556 | rc |= put_guest_lc(vcpu, pgm_info.mon_code, |
542 | (u64 *)__LC_MON_CODE); | 557 | (u64 *)__LC_MON_CODE); |
543 | break; | 558 | break; |
559 | case PGM_VECTOR_PROCESSING: | ||
544 | case PGM_DATA: | 560 | case PGM_DATA: |
545 | rc = put_guest_lc(vcpu, pgm_info.data_exc_code, | 561 | rc = put_guest_lc(vcpu, pgm_info.data_exc_code, |
546 | (u32 *)__LC_DATA_EXC_CODE); | 562 | (u32 *)__LC_DATA_EXC_CODE); |
@@ -551,6 +567,15 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) | |||
551 | rc |= put_guest_lc(vcpu, pgm_info.exc_access_id, | 567 | rc |= put_guest_lc(vcpu, pgm_info.exc_access_id, |
552 | (u8 *)__LC_EXC_ACCESS_ID); | 568 | (u8 *)__LC_EXC_ACCESS_ID); |
553 | break; | 569 | break; |
570 | case PGM_STACK_FULL: | ||
571 | case PGM_STACK_EMPTY: | ||
572 | case PGM_STACK_SPECIFICATION: | ||
573 | case PGM_STACK_TYPE: | ||
574 | case PGM_STACK_OPERATION: | ||
575 | case PGM_TRACE_TABEL: | ||
576 | case PGM_CRYPTO_OPERATION: | ||
577 | nullifying = true; | ||
578 | break; | ||
554 | } | 579 | } |
555 | 580 | ||
556 | if (pgm_info.code & PGM_PER) { | 581 | if (pgm_info.code & PGM_PER) { |
@@ -564,7 +589,12 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) | |||
564 | (u8 *) __LC_PER_ACCESS_ID); | 589 | (u8 *) __LC_PER_ACCESS_ID); |
565 | } | 590 | } |
566 | 591 | ||
592 | if (nullifying && vcpu->arch.sie_block->icptcode == ICPT_INST) | ||
593 | kvm_s390_rewind_psw(vcpu, ilc); | ||
594 | |||
567 | rc |= put_guest_lc(vcpu, ilc, (u16 *) __LC_PGM_ILC); | 595 | rc |= put_guest_lc(vcpu, ilc, (u16 *) __LC_PGM_ILC); |
596 | rc |= put_guest_lc(vcpu, vcpu->arch.sie_block->gbea, | ||
597 | (u64 *) __LC_LAST_BREAK); | ||
568 | rc |= put_guest_lc(vcpu, pgm_info.code, | 598 | rc |= put_guest_lc(vcpu, pgm_info.code, |
569 | (u16 *)__LC_PGM_INT_CODE); | 599 | (u16 *)__LC_PGM_INT_CODE); |
570 | rc |= write_guest_lc(vcpu, __LC_PGM_OLD_PSW, | 600 | rc |= write_guest_lc(vcpu, __LC_PGM_OLD_PSW, |
@@ -574,16 +604,27 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) | |||
574 | return rc ? -EFAULT : 0; | 604 | return rc ? -EFAULT : 0; |
575 | } | 605 | } |
576 | 606 | ||
577 | static int __must_check __deliver_service(struct kvm_vcpu *vcpu, | 607 | static int __must_check __deliver_service(struct kvm_vcpu *vcpu) |
578 | struct kvm_s390_interrupt_info *inti) | ||
579 | { | 608 | { |
580 | int rc; | 609 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; |
610 | struct kvm_s390_ext_info ext; | ||
611 | int rc = 0; | ||
612 | |||
613 | spin_lock(&fi->lock); | ||
614 | if (!(test_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs))) { | ||
615 | spin_unlock(&fi->lock); | ||
616 | return 0; | ||
617 | } | ||
618 | ext = fi->srv_signal; | ||
619 | memset(&fi->srv_signal, 0, sizeof(ext)); | ||
620 | clear_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs); | ||
621 | spin_unlock(&fi->lock); | ||
581 | 622 | ||
582 | VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x", | 623 | VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x", |
583 | inti->ext.ext_params); | 624 | ext.ext_params); |
584 | vcpu->stat.deliver_service_signal++; | 625 | vcpu->stat.deliver_service_signal++; |
585 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | 626 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_SERVICE, |
586 | inti->ext.ext_params, 0); | 627 | ext.ext_params, 0); |
587 | 628 | ||
588 | rc = put_guest_lc(vcpu, EXT_IRQ_SERVICE_SIG, (u16 *)__LC_EXT_INT_CODE); | 629 | rc = put_guest_lc(vcpu, EXT_IRQ_SERVICE_SIG, (u16 *)__LC_EXT_INT_CODE); |
589 | rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); | 630 | rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); |
@@ -591,106 +632,146 @@ static int __must_check __deliver_service(struct kvm_vcpu *vcpu, | |||
591 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 632 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); |
592 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | 633 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, |
593 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 634 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); |
594 | rc |= put_guest_lc(vcpu, inti->ext.ext_params, | 635 | rc |= put_guest_lc(vcpu, ext.ext_params, |
595 | (u32 *)__LC_EXT_PARAMS); | 636 | (u32 *)__LC_EXT_PARAMS); |
637 | |||
596 | return rc ? -EFAULT : 0; | 638 | return rc ? -EFAULT : 0; |
597 | } | 639 | } |
598 | 640 | ||
599 | static int __must_check __deliver_pfault_done(struct kvm_vcpu *vcpu, | 641 | static int __must_check __deliver_pfault_done(struct kvm_vcpu *vcpu) |
600 | struct kvm_s390_interrupt_info *inti) | ||
601 | { | 642 | { |
602 | int rc; | 643 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; |
644 | struct kvm_s390_interrupt_info *inti; | ||
645 | int rc = 0; | ||
603 | 646 | ||
604 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, | 647 | spin_lock(&fi->lock); |
605 | KVM_S390_INT_PFAULT_DONE, 0, | 648 | inti = list_first_entry_or_null(&fi->lists[FIRQ_LIST_PFAULT], |
606 | inti->ext.ext_params2); | 649 | struct kvm_s390_interrupt_info, |
650 | list); | ||
651 | if (inti) { | ||
652 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, | ||
653 | KVM_S390_INT_PFAULT_DONE, 0, | ||
654 | inti->ext.ext_params2); | ||
655 | list_del(&inti->list); | ||
656 | fi->counters[FIRQ_CNTR_PFAULT] -= 1; | ||
657 | } | ||
658 | if (list_empty(&fi->lists[FIRQ_LIST_PFAULT])) | ||
659 | clear_bit(IRQ_PEND_PFAULT_DONE, &fi->pending_irqs); | ||
660 | spin_unlock(&fi->lock); | ||
607 | 661 | ||
608 | rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, (u16 *)__LC_EXT_INT_CODE); | 662 | if (inti) { |
609 | rc |= put_guest_lc(vcpu, PFAULT_DONE, (u16 *)__LC_EXT_CPU_ADDR); | 663 | rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, |
610 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | 664 | (u16 *)__LC_EXT_INT_CODE); |
611 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 665 | rc |= put_guest_lc(vcpu, PFAULT_DONE, |
612 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | 666 | (u16 *)__LC_EXT_CPU_ADDR); |
613 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 667 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, |
614 | rc |= put_guest_lc(vcpu, inti->ext.ext_params2, | 668 | &vcpu->arch.sie_block->gpsw, |
615 | (u64 *)__LC_EXT_PARAMS2); | 669 | sizeof(psw_t)); |
670 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | ||
671 | &vcpu->arch.sie_block->gpsw, | ||
672 | sizeof(psw_t)); | ||
673 | rc |= put_guest_lc(vcpu, inti->ext.ext_params2, | ||
674 | (u64 *)__LC_EXT_PARAMS2); | ||
675 | kfree(inti); | ||
676 | } | ||
616 | return rc ? -EFAULT : 0; | 677 | return rc ? -EFAULT : 0; |
617 | } | 678 | } |
618 | 679 | ||
619 | static int __must_check __deliver_virtio(struct kvm_vcpu *vcpu, | 680 | static int __must_check __deliver_virtio(struct kvm_vcpu *vcpu) |
620 | struct kvm_s390_interrupt_info *inti) | ||
621 | { | 681 | { |
622 | int rc; | 682 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; |
683 | struct kvm_s390_interrupt_info *inti; | ||
684 | int rc = 0; | ||
623 | 685 | ||
624 | VCPU_EVENT(vcpu, 4, "interrupt: virtio parm:%x,parm64:%llx", | 686 | spin_lock(&fi->lock); |
625 | inti->ext.ext_params, inti->ext.ext_params2); | 687 | inti = list_first_entry_or_null(&fi->lists[FIRQ_LIST_VIRTIO], |
626 | vcpu->stat.deliver_virtio_interrupt++; | 688 | struct kvm_s390_interrupt_info, |
627 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | 689 | list); |
628 | inti->ext.ext_params, | 690 | if (inti) { |
629 | inti->ext.ext_params2); | 691 | VCPU_EVENT(vcpu, 4, |
692 | "interrupt: virtio parm:%x,parm64:%llx", | ||
693 | inti->ext.ext_params, inti->ext.ext_params2); | ||
694 | vcpu->stat.deliver_virtio_interrupt++; | ||
695 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, | ||
696 | inti->type, | ||
697 | inti->ext.ext_params, | ||
698 | inti->ext.ext_params2); | ||
699 | list_del(&inti->list); | ||
700 | fi->counters[FIRQ_CNTR_VIRTIO] -= 1; | ||
701 | } | ||
702 | if (list_empty(&fi->lists[FIRQ_LIST_VIRTIO])) | ||
703 | clear_bit(IRQ_PEND_VIRTIO, &fi->pending_irqs); | ||
704 | spin_unlock(&fi->lock); | ||
630 | 705 | ||
631 | rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, (u16 *)__LC_EXT_INT_CODE); | 706 | if (inti) { |
632 | rc |= put_guest_lc(vcpu, VIRTIO_PARAM, (u16 *)__LC_EXT_CPU_ADDR); | 707 | rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, |
633 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, | 708 | (u16 *)__LC_EXT_INT_CODE); |
634 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 709 | rc |= put_guest_lc(vcpu, VIRTIO_PARAM, |
635 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, | 710 | (u16 *)__LC_EXT_CPU_ADDR); |
636 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 711 | rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, |
637 | rc |= put_guest_lc(vcpu, inti->ext.ext_params, | 712 | &vcpu->arch.sie_block->gpsw, |
638 | (u32 *)__LC_EXT_PARAMS); | 713 | sizeof(psw_t)); |
639 | rc |= put_guest_lc(vcpu, inti->ext.ext_params2, | 714 | rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, |
640 | (u64 *)__LC_EXT_PARAMS2); | 715 | &vcpu->arch.sie_block->gpsw, |
716 | sizeof(psw_t)); | ||
717 | rc |= put_guest_lc(vcpu, inti->ext.ext_params, | ||
718 | (u32 *)__LC_EXT_PARAMS); | ||
719 | rc |= put_guest_lc(vcpu, inti->ext.ext_params2, | ||
720 | (u64 *)__LC_EXT_PARAMS2); | ||
721 | kfree(inti); | ||
722 | } | ||
641 | return rc ? -EFAULT : 0; | 723 | return rc ? -EFAULT : 0; |
642 | } | 724 | } |
643 | 725 | ||
644 | static int __must_check __deliver_io(struct kvm_vcpu *vcpu, | 726 | static int __must_check __deliver_io(struct kvm_vcpu *vcpu, |
645 | struct kvm_s390_interrupt_info *inti) | 727 | unsigned long irq_type) |
646 | { | 728 | { |
647 | int rc; | 729 | struct list_head *isc_list; |
730 | struct kvm_s390_float_interrupt *fi; | ||
731 | struct kvm_s390_interrupt_info *inti = NULL; | ||
732 | int rc = 0; | ||
648 | 733 | ||
649 | VCPU_EVENT(vcpu, 4, "interrupt: I/O %llx", inti->type); | 734 | fi = &vcpu->kvm->arch.float_int; |
650 | vcpu->stat.deliver_io_int++; | ||
651 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, | ||
652 | ((__u32)inti->io.subchannel_id << 16) | | ||
653 | inti->io.subchannel_nr, | ||
654 | ((__u64)inti->io.io_int_parm << 32) | | ||
655 | inti->io.io_int_word); | ||
656 | |||
657 | rc = put_guest_lc(vcpu, inti->io.subchannel_id, | ||
658 | (u16 *)__LC_SUBCHANNEL_ID); | ||
659 | rc |= put_guest_lc(vcpu, inti->io.subchannel_nr, | ||
660 | (u16 *)__LC_SUBCHANNEL_NR); | ||
661 | rc |= put_guest_lc(vcpu, inti->io.io_int_parm, | ||
662 | (u32 *)__LC_IO_INT_PARM); | ||
663 | rc |= put_guest_lc(vcpu, inti->io.io_int_word, | ||
664 | (u32 *)__LC_IO_INT_WORD); | ||
665 | rc |= write_guest_lc(vcpu, __LC_IO_OLD_PSW, | ||
666 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
667 | rc |= read_guest_lc(vcpu, __LC_IO_NEW_PSW, | ||
668 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
669 | return rc ? -EFAULT : 0; | ||
670 | } | ||
671 | 735 | ||
672 | static int __must_check __deliver_mchk_floating(struct kvm_vcpu *vcpu, | 736 | spin_lock(&fi->lock); |
673 | struct kvm_s390_interrupt_info *inti) | 737 | isc_list = &fi->lists[irq_type - IRQ_PEND_IO_ISC_0]; |
674 | { | 738 | inti = list_first_entry_or_null(isc_list, |
675 | struct kvm_s390_mchk_info *mchk = &inti->mchk; | 739 | struct kvm_s390_interrupt_info, |
676 | int rc; | 740 | list); |
741 | if (inti) { | ||
742 | VCPU_EVENT(vcpu, 4, "interrupt: I/O %llx", inti->type); | ||
743 | vcpu->stat.deliver_io_int++; | ||
744 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, | ||
745 | inti->type, | ||
746 | ((__u32)inti->io.subchannel_id << 16) | | ||
747 | inti->io.subchannel_nr, | ||
748 | ((__u64)inti->io.io_int_parm << 32) | | ||
749 | inti->io.io_int_word); | ||
750 | list_del(&inti->list); | ||
751 | fi->counters[FIRQ_CNTR_IO] -= 1; | ||
752 | } | ||
753 | if (list_empty(isc_list)) | ||
754 | clear_bit(irq_type, &fi->pending_irqs); | ||
755 | spin_unlock(&fi->lock); | ||
756 | |||
757 | if (inti) { | ||
758 | rc = put_guest_lc(vcpu, inti->io.subchannel_id, | ||
759 | (u16 *)__LC_SUBCHANNEL_ID); | ||
760 | rc |= put_guest_lc(vcpu, inti->io.subchannel_nr, | ||
761 | (u16 *)__LC_SUBCHANNEL_NR); | ||
762 | rc |= put_guest_lc(vcpu, inti->io.io_int_parm, | ||
763 | (u32 *)__LC_IO_INT_PARM); | ||
764 | rc |= put_guest_lc(vcpu, inti->io.io_int_word, | ||
765 | (u32 *)__LC_IO_INT_WORD); | ||
766 | rc |= write_guest_lc(vcpu, __LC_IO_OLD_PSW, | ||
767 | &vcpu->arch.sie_block->gpsw, | ||
768 | sizeof(psw_t)); | ||
769 | rc |= read_guest_lc(vcpu, __LC_IO_NEW_PSW, | ||
770 | &vcpu->arch.sie_block->gpsw, | ||
771 | sizeof(psw_t)); | ||
772 | kfree(inti); | ||
773 | } | ||
677 | 774 | ||
678 | VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx", | ||
679 | mchk->mcic); | ||
680 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_MCHK, | ||
681 | mchk->cr14, mchk->mcic); | ||
682 | |||
683 | rc = kvm_s390_vcpu_store_status(vcpu, KVM_S390_STORE_STATUS_PREFIXED); | ||
684 | rc |= put_guest_lc(vcpu, mchk->mcic, | ||
685 | (u64 __user *) __LC_MCCK_CODE); | ||
686 | rc |= put_guest_lc(vcpu, mchk->failing_storage_address, | ||
687 | (u64 __user *) __LC_MCCK_FAIL_STOR_ADDR); | ||
688 | rc |= write_guest_lc(vcpu, __LC_PSW_SAVE_AREA, | ||
689 | &mchk->fixed_logout, sizeof(mchk->fixed_logout)); | ||
690 | rc |= write_guest_lc(vcpu, __LC_MCK_OLD_PSW, | ||
691 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
692 | rc |= read_guest_lc(vcpu, __LC_MCK_NEW_PSW, | ||
693 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | ||
694 | return rc ? -EFAULT : 0; | 775 | return rc ? -EFAULT : 0; |
695 | } | 776 | } |
696 | 777 | ||
@@ -698,6 +779,7 @@ typedef int (*deliver_irq_t)(struct kvm_vcpu *vcpu); | |||
698 | 779 | ||
699 | static const deliver_irq_t deliver_irq_funcs[] = { | 780 | static const deliver_irq_t deliver_irq_funcs[] = { |
700 | [IRQ_PEND_MCHK_EX] = __deliver_machine_check, | 781 | [IRQ_PEND_MCHK_EX] = __deliver_machine_check, |
782 | [IRQ_PEND_MCHK_REP] = __deliver_machine_check, | ||
701 | [IRQ_PEND_PROG] = __deliver_prog, | 783 | [IRQ_PEND_PROG] = __deliver_prog, |
702 | [IRQ_PEND_EXT_EMERGENCY] = __deliver_emergency_signal, | 784 | [IRQ_PEND_EXT_EMERGENCY] = __deliver_emergency_signal, |
703 | [IRQ_PEND_EXT_EXTERNAL] = __deliver_external_call, | 785 | [IRQ_PEND_EXT_EXTERNAL] = __deliver_external_call, |
@@ -706,36 +788,11 @@ static const deliver_irq_t deliver_irq_funcs[] = { | |||
706 | [IRQ_PEND_RESTART] = __deliver_restart, | 788 | [IRQ_PEND_RESTART] = __deliver_restart, |
707 | [IRQ_PEND_SET_PREFIX] = __deliver_set_prefix, | 789 | [IRQ_PEND_SET_PREFIX] = __deliver_set_prefix, |
708 | [IRQ_PEND_PFAULT_INIT] = __deliver_pfault_init, | 790 | [IRQ_PEND_PFAULT_INIT] = __deliver_pfault_init, |
791 | [IRQ_PEND_EXT_SERVICE] = __deliver_service, | ||
792 | [IRQ_PEND_PFAULT_DONE] = __deliver_pfault_done, | ||
793 | [IRQ_PEND_VIRTIO] = __deliver_virtio, | ||
709 | }; | 794 | }; |
710 | 795 | ||
711 | static int __must_check __deliver_floating_interrupt(struct kvm_vcpu *vcpu, | ||
712 | struct kvm_s390_interrupt_info *inti) | ||
713 | { | ||
714 | int rc; | ||
715 | |||
716 | switch (inti->type) { | ||
717 | case KVM_S390_INT_SERVICE: | ||
718 | rc = __deliver_service(vcpu, inti); | ||
719 | break; | ||
720 | case KVM_S390_INT_PFAULT_DONE: | ||
721 | rc = __deliver_pfault_done(vcpu, inti); | ||
722 | break; | ||
723 | case KVM_S390_INT_VIRTIO: | ||
724 | rc = __deliver_virtio(vcpu, inti); | ||
725 | break; | ||
726 | case KVM_S390_MCHK: | ||
727 | rc = __deliver_mchk_floating(vcpu, inti); | ||
728 | break; | ||
729 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | ||
730 | rc = __deliver_io(vcpu, inti); | ||
731 | break; | ||
732 | default: | ||
733 | BUG(); | ||
734 | } | ||
735 | |||
736 | return rc; | ||
737 | } | ||
738 | |||
739 | /* Check whether an external call is pending (deliverable or not) */ | 796 | /* Check whether an external call is pending (deliverable or not) */ |
740 | int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu) | 797 | int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu) |
741 | { | 798 | { |
@@ -751,21 +808,9 @@ int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu) | |||
751 | 808 | ||
752 | int kvm_s390_vcpu_has_irq(struct kvm_vcpu *vcpu, int exclude_stop) | 809 | int kvm_s390_vcpu_has_irq(struct kvm_vcpu *vcpu, int exclude_stop) |
753 | { | 810 | { |
754 | struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; | ||
755 | struct kvm_s390_interrupt_info *inti; | ||
756 | int rc; | 811 | int rc; |
757 | 812 | ||
758 | rc = !!deliverable_local_irqs(vcpu); | 813 | rc = !!deliverable_irqs(vcpu); |
759 | |||
760 | if ((!rc) && atomic_read(&fi->active)) { | ||
761 | spin_lock(&fi->lock); | ||
762 | list_for_each_entry(inti, &fi->list, list) | ||
763 | if (__interrupt_is_deliverable(vcpu, inti)) { | ||
764 | rc = 1; | ||
765 | break; | ||
766 | } | ||
767 | spin_unlock(&fi->lock); | ||
768 | } | ||
769 | 814 | ||
770 | if (!rc && kvm_cpu_has_pending_timer(vcpu)) | 815 | if (!rc && kvm_cpu_has_pending_timer(vcpu)) |
771 | rc = 1; | 816 | rc = 1; |
@@ -784,12 +829,7 @@ int kvm_s390_vcpu_has_irq(struct kvm_vcpu *vcpu, int exclude_stop) | |||
784 | 829 | ||
785 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) | 830 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) |
786 | { | 831 | { |
787 | if (!(vcpu->arch.sie_block->ckc < | 832 | return ckc_irq_pending(vcpu) || cpu_timer_irq_pending(vcpu); |
788 | get_tod_clock_fast() + vcpu->arch.sie_block->epoch)) | ||
789 | return 0; | ||
790 | if (!ckc_interrupts_enabled(vcpu)) | ||
791 | return 0; | ||
792 | return 1; | ||
793 | } | 833 | } |
794 | 834 | ||
795 | int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) | 835 | int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) |
@@ -884,60 +924,45 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu) | |||
884 | int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) | 924 | int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) |
885 | { | 925 | { |
886 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 926 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
887 | struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; | ||
888 | struct kvm_s390_interrupt_info *n, *inti = NULL; | ||
889 | deliver_irq_t func; | 927 | deliver_irq_t func; |
890 | int deliver; | ||
891 | int rc = 0; | 928 | int rc = 0; |
892 | unsigned long irq_type; | 929 | unsigned long irq_type; |
893 | unsigned long deliverable_irqs; | 930 | unsigned long irqs; |
894 | 931 | ||
895 | __reset_intercept_indicators(vcpu); | 932 | __reset_intercept_indicators(vcpu); |
896 | 933 | ||
897 | /* pending ckc conditions might have been invalidated */ | 934 | /* pending ckc conditions might have been invalidated */ |
898 | clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); | 935 | clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); |
899 | if (kvm_cpu_has_pending_timer(vcpu)) | 936 | if (ckc_irq_pending(vcpu)) |
900 | set_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); | 937 | set_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); |
901 | 938 | ||
939 | /* pending cpu timer conditions might have been invalidated */ | ||
940 | clear_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs); | ||
941 | if (cpu_timer_irq_pending(vcpu)) | ||
942 | set_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs); | ||
943 | |||
902 | do { | 944 | do { |
903 | deliverable_irqs = deliverable_local_irqs(vcpu); | 945 | irqs = deliverable_irqs(vcpu); |
904 | /* bits are in the order of interrupt priority */ | 946 | /* bits are in the order of interrupt priority */ |
905 | irq_type = find_first_bit(&deliverable_irqs, IRQ_PEND_COUNT); | 947 | irq_type = find_first_bit(&irqs, IRQ_PEND_COUNT); |
906 | if (irq_type == IRQ_PEND_COUNT) | 948 | if (irq_type == IRQ_PEND_COUNT) |
907 | break; | 949 | break; |
908 | func = deliver_irq_funcs[irq_type]; | 950 | if (is_ioirq(irq_type)) { |
909 | if (!func) { | 951 | rc = __deliver_io(vcpu, irq_type); |
910 | WARN_ON_ONCE(func == NULL); | 952 | } else { |
911 | clear_bit(irq_type, &li->pending_irqs); | 953 | func = deliver_irq_funcs[irq_type]; |
912 | continue; | 954 | if (!func) { |
955 | WARN_ON_ONCE(func == NULL); | ||
956 | clear_bit(irq_type, &li->pending_irqs); | ||
957 | continue; | ||
958 | } | ||
959 | rc = func(vcpu); | ||
913 | } | 960 | } |
914 | rc = func(vcpu); | 961 | if (rc) |
915 | } while (!rc && irq_type != IRQ_PEND_COUNT); | 962 | break; |
963 | } while (!rc); | ||
916 | 964 | ||
917 | set_intercept_indicators_local(vcpu); | 965 | set_intercept_indicators(vcpu); |
918 | |||
919 | if (!rc && atomic_read(&fi->active)) { | ||
920 | do { | ||
921 | deliver = 0; | ||
922 | spin_lock(&fi->lock); | ||
923 | list_for_each_entry_safe(inti, n, &fi->list, list) { | ||
924 | if (__interrupt_is_deliverable(vcpu, inti)) { | ||
925 | list_del(&inti->list); | ||
926 | fi->irq_count--; | ||
927 | deliver = 1; | ||
928 | break; | ||
929 | } | ||
930 | __set_intercept_indicator(vcpu, inti); | ||
931 | } | ||
932 | if (list_empty(&fi->list)) | ||
933 | atomic_set(&fi->active, 0); | ||
934 | spin_unlock(&fi->lock); | ||
935 | if (deliver) { | ||
936 | rc = __deliver_floating_interrupt(vcpu, inti); | ||
937 | kfree(inti); | ||
938 | } | ||
939 | } while (!rc && deliver); | ||
940 | } | ||
941 | 966 | ||
942 | return rc; | 967 | return rc; |
943 | } | 968 | } |
@@ -1172,80 +1197,182 @@ static int __inject_cpu_timer(struct kvm_vcpu *vcpu) | |||
1172 | return 0; | 1197 | return 0; |
1173 | } | 1198 | } |
1174 | 1199 | ||
1200 | static struct kvm_s390_interrupt_info *get_io_int(struct kvm *kvm, | ||
1201 | int isc, u32 schid) | ||
1202 | { | ||
1203 | struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; | ||
1204 | struct list_head *isc_list = &fi->lists[FIRQ_LIST_IO_ISC_0 + isc]; | ||
1205 | struct kvm_s390_interrupt_info *iter; | ||
1206 | u16 id = (schid & 0xffff0000U) >> 16; | ||
1207 | u16 nr = schid & 0x0000ffffU; | ||
1175 | 1208 | ||
1209 | spin_lock(&fi->lock); | ||
1210 | list_for_each_entry(iter, isc_list, list) { | ||
1211 | if (schid && (id != iter->io.subchannel_id || | ||
1212 | nr != iter->io.subchannel_nr)) | ||
1213 | continue; | ||
1214 | /* found an appropriate entry */ | ||
1215 | list_del_init(&iter->list); | ||
1216 | fi->counters[FIRQ_CNTR_IO] -= 1; | ||
1217 | if (list_empty(isc_list)) | ||
1218 | clear_bit(IRQ_PEND_IO_ISC_0 + isc, &fi->pending_irqs); | ||
1219 | spin_unlock(&fi->lock); | ||
1220 | return iter; | ||
1221 | } | ||
1222 | spin_unlock(&fi->lock); | ||
1223 | return NULL; | ||
1224 | } | ||
1225 | |||
1226 | /* | ||
1227 | * Dequeue and return an I/O interrupt matching any of the interruption | ||
1228 | * subclasses as designated by the isc mask in cr6 and the schid (if != 0). | ||
1229 | */ | ||
1176 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, | 1230 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, |
1177 | u64 cr6, u64 schid) | 1231 | u64 isc_mask, u32 schid) |
1232 | { | ||
1233 | struct kvm_s390_interrupt_info *inti = NULL; | ||
1234 | int isc; | ||
1235 | |||
1236 | for (isc = 0; isc <= MAX_ISC && !inti; isc++) { | ||
1237 | if (isc_mask & isc_to_isc_bits(isc)) | ||
1238 | inti = get_io_int(kvm, isc, schid); | ||
1239 | } | ||
1240 | return inti; | ||
1241 | } | ||
1242 | |||
1243 | #define SCCB_MASK 0xFFFFFFF8 | ||
1244 | #define SCCB_EVENT_PENDING 0x3 | ||
1245 | |||
1246 | static int __inject_service(struct kvm *kvm, | ||
1247 | struct kvm_s390_interrupt_info *inti) | ||
1248 | { | ||
1249 | struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; | ||
1250 | |||
1251 | spin_lock(&fi->lock); | ||
1252 | fi->srv_signal.ext_params |= inti->ext.ext_params & SCCB_EVENT_PENDING; | ||
1253 | /* | ||
1254 | * Early versions of the QEMU s390 bios will inject several | ||
1255 | * service interrupts after another without handling a | ||
1256 | * condition code indicating busy. | ||
1257 | * We will silently ignore those superfluous sccb values. | ||
1258 | * A future version of QEMU will take care of serialization | ||
1259 | * of servc requests | ||
1260 | */ | ||
1261 | if (fi->srv_signal.ext_params & SCCB_MASK) | ||
1262 | goto out; | ||
1263 | fi->srv_signal.ext_params |= inti->ext.ext_params & SCCB_MASK; | ||
1264 | set_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs); | ||
1265 | out: | ||
1266 | spin_unlock(&fi->lock); | ||
1267 | kfree(inti); | ||
1268 | return 0; | ||
1269 | } | ||
1270 | |||
1271 | static int __inject_virtio(struct kvm *kvm, | ||
1272 | struct kvm_s390_interrupt_info *inti) | ||
1273 | { | ||
1274 | struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; | ||
1275 | |||
1276 | spin_lock(&fi->lock); | ||
1277 | if (fi->counters[FIRQ_CNTR_VIRTIO] >= KVM_S390_MAX_VIRTIO_IRQS) { | ||
1278 | spin_unlock(&fi->lock); | ||
1279 | return -EBUSY; | ||
1280 | } | ||
1281 | fi->counters[FIRQ_CNTR_VIRTIO] += 1; | ||
1282 | list_add_tail(&inti->list, &fi->lists[FIRQ_LIST_VIRTIO]); | ||
1283 | set_bit(IRQ_PEND_VIRTIO, &fi->pending_irqs); | ||
1284 | spin_unlock(&fi->lock); | ||
1285 | return 0; | ||
1286 | } | ||
1287 | |||
1288 | static int __inject_pfault_done(struct kvm *kvm, | ||
1289 | struct kvm_s390_interrupt_info *inti) | ||
1290 | { | ||
1291 | struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; | ||
1292 | |||
1293 | spin_lock(&fi->lock); | ||
1294 | if (fi->counters[FIRQ_CNTR_PFAULT] >= | ||
1295 | (ASYNC_PF_PER_VCPU * KVM_MAX_VCPUS)) { | ||
1296 | spin_unlock(&fi->lock); | ||
1297 | return -EBUSY; | ||
1298 | } | ||
1299 | fi->counters[FIRQ_CNTR_PFAULT] += 1; | ||
1300 | list_add_tail(&inti->list, &fi->lists[FIRQ_LIST_PFAULT]); | ||
1301 | set_bit(IRQ_PEND_PFAULT_DONE, &fi->pending_irqs); | ||
1302 | spin_unlock(&fi->lock); | ||
1303 | return 0; | ||
1304 | } | ||
1305 | |||
1306 | #define CR_PENDING_SUBCLASS 28 | ||
1307 | static int __inject_float_mchk(struct kvm *kvm, | ||
1308 | struct kvm_s390_interrupt_info *inti) | ||
1309 | { | ||
1310 | struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; | ||
1311 | |||
1312 | spin_lock(&fi->lock); | ||
1313 | fi->mchk.cr14 |= inti->mchk.cr14 & (1UL << CR_PENDING_SUBCLASS); | ||
1314 | fi->mchk.mcic |= inti->mchk.mcic; | ||
1315 | set_bit(IRQ_PEND_MCHK_REP, &fi->pending_irqs); | ||
1316 | spin_unlock(&fi->lock); | ||
1317 | kfree(inti); | ||
1318 | return 0; | ||
1319 | } | ||
1320 | |||
1321 | static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | ||
1178 | { | 1322 | { |
1179 | struct kvm_s390_float_interrupt *fi; | 1323 | struct kvm_s390_float_interrupt *fi; |
1180 | struct kvm_s390_interrupt_info *inti, *iter; | 1324 | struct list_head *list; |
1325 | int isc; | ||
1181 | 1326 | ||
1182 | if ((!schid && !cr6) || (schid && cr6)) | ||
1183 | return NULL; | ||
1184 | fi = &kvm->arch.float_int; | 1327 | fi = &kvm->arch.float_int; |
1185 | spin_lock(&fi->lock); | 1328 | spin_lock(&fi->lock); |
1186 | inti = NULL; | 1329 | if (fi->counters[FIRQ_CNTR_IO] >= KVM_S390_MAX_FLOAT_IRQS) { |
1187 | list_for_each_entry(iter, &fi->list, list) { | 1330 | spin_unlock(&fi->lock); |
1188 | if (!is_ioint(iter->type)) | 1331 | return -EBUSY; |
1189 | continue; | ||
1190 | if (cr6 && | ||
1191 | ((cr6 & int_word_to_isc_bits(iter->io.io_int_word)) == 0)) | ||
1192 | continue; | ||
1193 | if (schid) { | ||
1194 | if (((schid & 0x00000000ffff0000) >> 16) != | ||
1195 | iter->io.subchannel_id) | ||
1196 | continue; | ||
1197 | if ((schid & 0x000000000000ffff) != | ||
1198 | iter->io.subchannel_nr) | ||
1199 | continue; | ||
1200 | } | ||
1201 | inti = iter; | ||
1202 | break; | ||
1203 | } | ||
1204 | if (inti) { | ||
1205 | list_del_init(&inti->list); | ||
1206 | fi->irq_count--; | ||
1207 | } | 1332 | } |
1208 | if (list_empty(&fi->list)) | 1333 | fi->counters[FIRQ_CNTR_IO] += 1; |
1209 | atomic_set(&fi->active, 0); | 1334 | |
1335 | isc = int_word_to_isc(inti->io.io_int_word); | ||
1336 | list = &fi->lists[FIRQ_LIST_IO_ISC_0 + isc]; | ||
1337 | list_add_tail(&inti->list, list); | ||
1338 | set_bit(IRQ_PEND_IO_ISC_0 + isc, &fi->pending_irqs); | ||
1210 | spin_unlock(&fi->lock); | 1339 | spin_unlock(&fi->lock); |
1211 | return inti; | 1340 | return 0; |
1212 | } | 1341 | } |
1213 | 1342 | ||
1214 | static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | 1343 | static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) |
1215 | { | 1344 | { |
1216 | struct kvm_s390_local_interrupt *li; | 1345 | struct kvm_s390_local_interrupt *li; |
1217 | struct kvm_s390_float_interrupt *fi; | 1346 | struct kvm_s390_float_interrupt *fi; |
1218 | struct kvm_s390_interrupt_info *iter; | ||
1219 | struct kvm_vcpu *dst_vcpu = NULL; | 1347 | struct kvm_vcpu *dst_vcpu = NULL; |
1220 | int sigcpu; | 1348 | int sigcpu; |
1221 | int rc = 0; | 1349 | u64 type = READ_ONCE(inti->type); |
1350 | int rc; | ||
1222 | 1351 | ||
1223 | fi = &kvm->arch.float_int; | 1352 | fi = &kvm->arch.float_int; |
1224 | spin_lock(&fi->lock); | 1353 | |
1225 | if (fi->irq_count >= KVM_S390_MAX_FLOAT_IRQS) { | 1354 | switch (type) { |
1355 | case KVM_S390_MCHK: | ||
1356 | rc = __inject_float_mchk(kvm, inti); | ||
1357 | break; | ||
1358 | case KVM_S390_INT_VIRTIO: | ||
1359 | rc = __inject_virtio(kvm, inti); | ||
1360 | break; | ||
1361 | case KVM_S390_INT_SERVICE: | ||
1362 | rc = __inject_service(kvm, inti); | ||
1363 | break; | ||
1364 | case KVM_S390_INT_PFAULT_DONE: | ||
1365 | rc = __inject_pfault_done(kvm, inti); | ||
1366 | break; | ||
1367 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | ||
1368 | rc = __inject_io(kvm, inti); | ||
1369 | break; | ||
1370 | default: | ||
1226 | rc = -EINVAL; | 1371 | rc = -EINVAL; |
1227 | goto unlock_fi; | ||
1228 | } | 1372 | } |
1229 | fi->irq_count++; | 1373 | if (rc) |
1230 | if (!is_ioint(inti->type)) { | 1374 | return rc; |
1231 | list_add_tail(&inti->list, &fi->list); | ||
1232 | } else { | ||
1233 | u64 isc_bits = int_word_to_isc_bits(inti->io.io_int_word); | ||
1234 | 1375 | ||
1235 | /* Keep I/O interrupts sorted in isc order. */ | ||
1236 | list_for_each_entry(iter, &fi->list, list) { | ||
1237 | if (!is_ioint(iter->type)) | ||
1238 | continue; | ||
1239 | if (int_word_to_isc_bits(iter->io.io_int_word) | ||
1240 | <= isc_bits) | ||
1241 | continue; | ||
1242 | break; | ||
1243 | } | ||
1244 | list_add_tail(&inti->list, &iter->list); | ||
1245 | } | ||
1246 | atomic_set(&fi->active, 1); | ||
1247 | if (atomic_read(&kvm->online_vcpus) == 0) | ||
1248 | goto unlock_fi; | ||
1249 | sigcpu = find_first_bit(fi->idle_mask, KVM_MAX_VCPUS); | 1376 | sigcpu = find_first_bit(fi->idle_mask, KVM_MAX_VCPUS); |
1250 | if (sigcpu == KVM_MAX_VCPUS) { | 1377 | if (sigcpu == KVM_MAX_VCPUS) { |
1251 | do { | 1378 | do { |
@@ -1257,7 +1384,7 @@ static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | |||
1257 | dst_vcpu = kvm_get_vcpu(kvm, sigcpu); | 1384 | dst_vcpu = kvm_get_vcpu(kvm, sigcpu); |
1258 | li = &dst_vcpu->arch.local_int; | 1385 | li = &dst_vcpu->arch.local_int; |
1259 | spin_lock(&li->lock); | 1386 | spin_lock(&li->lock); |
1260 | switch (inti->type) { | 1387 | switch (type) { |
1261 | case KVM_S390_MCHK: | 1388 | case KVM_S390_MCHK: |
1262 | atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); | 1389 | atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); |
1263 | break; | 1390 | break; |
@@ -1270,9 +1397,8 @@ static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | |||
1270 | } | 1397 | } |
1271 | spin_unlock(&li->lock); | 1398 | spin_unlock(&li->lock); |
1272 | kvm_s390_vcpu_wakeup(kvm_get_vcpu(kvm, sigcpu)); | 1399 | kvm_s390_vcpu_wakeup(kvm_get_vcpu(kvm, sigcpu)); |
1273 | unlock_fi: | 1400 | return 0; |
1274 | spin_unlock(&fi->lock); | 1401 | |
1275 | return rc; | ||
1276 | } | 1402 | } |
1277 | 1403 | ||
1278 | int kvm_s390_inject_vm(struct kvm *kvm, | 1404 | int kvm_s390_inject_vm(struct kvm *kvm, |
@@ -1332,10 +1458,10 @@ int kvm_s390_inject_vm(struct kvm *kvm, | |||
1332 | return rc; | 1458 | return rc; |
1333 | } | 1459 | } |
1334 | 1460 | ||
1335 | void kvm_s390_reinject_io_int(struct kvm *kvm, | 1461 | int kvm_s390_reinject_io_int(struct kvm *kvm, |
1336 | struct kvm_s390_interrupt_info *inti) | 1462 | struct kvm_s390_interrupt_info *inti) |
1337 | { | 1463 | { |
1338 | __inject_vm(kvm, inti); | 1464 | return __inject_vm(kvm, inti); |
1339 | } | 1465 | } |
1340 | 1466 | ||
1341 | int s390int_to_s390irq(struct kvm_s390_interrupt *s390int, | 1467 | int s390int_to_s390irq(struct kvm_s390_interrupt *s390int, |
@@ -1388,12 +1514,10 @@ void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu) | |||
1388 | spin_unlock(&li->lock); | 1514 | spin_unlock(&li->lock); |
1389 | } | 1515 | } |
1390 | 1516 | ||
1391 | int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | 1517 | static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) |
1392 | { | 1518 | { |
1393 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
1394 | int rc; | 1519 | int rc; |
1395 | 1520 | ||
1396 | spin_lock(&li->lock); | ||
1397 | switch (irq->type) { | 1521 | switch (irq->type) { |
1398 | case KVM_S390_PROGRAM_INT: | 1522 | case KVM_S390_PROGRAM_INT: |
1399 | VCPU_EVENT(vcpu, 3, "inject: program check %d (from user)", | 1523 | VCPU_EVENT(vcpu, 3, "inject: program check %d (from user)", |
@@ -1433,83 +1557,130 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | |||
1433 | default: | 1557 | default: |
1434 | rc = -EINVAL; | 1558 | rc = -EINVAL; |
1435 | } | 1559 | } |
1560 | |||
1561 | return rc; | ||
1562 | } | ||
1563 | |||
1564 | int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | ||
1565 | { | ||
1566 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
1567 | int rc; | ||
1568 | |||
1569 | spin_lock(&li->lock); | ||
1570 | rc = do_inject_vcpu(vcpu, irq); | ||
1436 | spin_unlock(&li->lock); | 1571 | spin_unlock(&li->lock); |
1437 | if (!rc) | 1572 | if (!rc) |
1438 | kvm_s390_vcpu_wakeup(vcpu); | 1573 | kvm_s390_vcpu_wakeup(vcpu); |
1439 | return rc; | 1574 | return rc; |
1440 | } | 1575 | } |
1441 | 1576 | ||
1442 | void kvm_s390_clear_float_irqs(struct kvm *kvm) | 1577 | static inline void clear_irq_list(struct list_head *_list) |
1443 | { | 1578 | { |
1444 | struct kvm_s390_float_interrupt *fi; | 1579 | struct kvm_s390_interrupt_info *inti, *n; |
1445 | struct kvm_s390_interrupt_info *n, *inti = NULL; | ||
1446 | 1580 | ||
1447 | fi = &kvm->arch.float_int; | 1581 | list_for_each_entry_safe(inti, n, _list, list) { |
1448 | spin_lock(&fi->lock); | ||
1449 | list_for_each_entry_safe(inti, n, &fi->list, list) { | ||
1450 | list_del(&inti->list); | 1582 | list_del(&inti->list); |
1451 | kfree(inti); | 1583 | kfree(inti); |
1452 | } | 1584 | } |
1453 | fi->irq_count = 0; | ||
1454 | atomic_set(&fi->active, 0); | ||
1455 | spin_unlock(&fi->lock); | ||
1456 | } | 1585 | } |
1457 | 1586 | ||
1458 | static inline int copy_irq_to_user(struct kvm_s390_interrupt_info *inti, | 1587 | static void inti_to_irq(struct kvm_s390_interrupt_info *inti, |
1459 | u8 *addr) | 1588 | struct kvm_s390_irq *irq) |
1460 | { | 1589 | { |
1461 | struct kvm_s390_irq __user *uptr = (struct kvm_s390_irq __user *) addr; | 1590 | irq->type = inti->type; |
1462 | struct kvm_s390_irq irq = {0}; | ||
1463 | |||
1464 | irq.type = inti->type; | ||
1465 | switch (inti->type) { | 1591 | switch (inti->type) { |
1466 | case KVM_S390_INT_PFAULT_INIT: | 1592 | case KVM_S390_INT_PFAULT_INIT: |
1467 | case KVM_S390_INT_PFAULT_DONE: | 1593 | case KVM_S390_INT_PFAULT_DONE: |
1468 | case KVM_S390_INT_VIRTIO: | 1594 | case KVM_S390_INT_VIRTIO: |
1469 | case KVM_S390_INT_SERVICE: | 1595 | irq->u.ext = inti->ext; |
1470 | irq.u.ext = inti->ext; | ||
1471 | break; | 1596 | break; |
1472 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | 1597 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: |
1473 | irq.u.io = inti->io; | 1598 | irq->u.io = inti->io; |
1474 | break; | 1599 | break; |
1475 | case KVM_S390_MCHK: | ||
1476 | irq.u.mchk = inti->mchk; | ||
1477 | break; | ||
1478 | default: | ||
1479 | return -EINVAL; | ||
1480 | } | 1600 | } |
1601 | } | ||
1481 | 1602 | ||
1482 | if (copy_to_user(uptr, &irq, sizeof(irq))) | 1603 | void kvm_s390_clear_float_irqs(struct kvm *kvm) |
1483 | return -EFAULT; | 1604 | { |
1605 | struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; | ||
1606 | int i; | ||
1484 | 1607 | ||
1485 | return 0; | 1608 | spin_lock(&fi->lock); |
1486 | } | 1609 | for (i = 0; i < FIRQ_LIST_COUNT; i++) |
1610 | clear_irq_list(&fi->lists[i]); | ||
1611 | for (i = 0; i < FIRQ_MAX_COUNT; i++) | ||
1612 | fi->counters[i] = 0; | ||
1613 | spin_unlock(&fi->lock); | ||
1614 | }; | ||
1487 | 1615 | ||
1488 | static int get_all_floating_irqs(struct kvm *kvm, __u8 *buf, __u64 len) | 1616 | static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len) |
1489 | { | 1617 | { |
1490 | struct kvm_s390_interrupt_info *inti; | 1618 | struct kvm_s390_interrupt_info *inti; |
1491 | struct kvm_s390_float_interrupt *fi; | 1619 | struct kvm_s390_float_interrupt *fi; |
1620 | struct kvm_s390_irq *buf; | ||
1621 | struct kvm_s390_irq *irq; | ||
1622 | int max_irqs; | ||
1492 | int ret = 0; | 1623 | int ret = 0; |
1493 | int n = 0; | 1624 | int n = 0; |
1625 | int i; | ||
1626 | |||
1627 | if (len > KVM_S390_FLIC_MAX_BUFFER || len == 0) | ||
1628 | return -EINVAL; | ||
1629 | |||
1630 | /* | ||
1631 | * We are already using -ENOMEM to signal | ||
1632 | * userspace it may retry with a bigger buffer, | ||
1633 | * so we need to use something else for this case | ||
1634 | */ | ||
1635 | buf = vzalloc(len); | ||
1636 | if (!buf) | ||
1637 | return -ENOBUFS; | ||
1638 | |||
1639 | max_irqs = len / sizeof(struct kvm_s390_irq); | ||
1494 | 1640 | ||
1495 | fi = &kvm->arch.float_int; | 1641 | fi = &kvm->arch.float_int; |
1496 | spin_lock(&fi->lock); | 1642 | spin_lock(&fi->lock); |
1497 | 1643 | for (i = 0; i < FIRQ_LIST_COUNT; i++) { | |
1498 | list_for_each_entry(inti, &fi->list, list) { | 1644 | list_for_each_entry(inti, &fi->lists[i], list) { |
1499 | if (len < sizeof(struct kvm_s390_irq)) { | 1645 | if (n == max_irqs) { |
1646 | /* signal userspace to try again */ | ||
1647 | ret = -ENOMEM; | ||
1648 | goto out; | ||
1649 | } | ||
1650 | inti_to_irq(inti, &buf[n]); | ||
1651 | n++; | ||
1652 | } | ||
1653 | } | ||
1654 | if (test_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs)) { | ||
1655 | if (n == max_irqs) { | ||
1500 | /* signal userspace to try again */ | 1656 | /* signal userspace to try again */ |
1501 | ret = -ENOMEM; | 1657 | ret = -ENOMEM; |
1502 | break; | 1658 | goto out; |
1503 | } | 1659 | } |
1504 | ret = copy_irq_to_user(inti, buf); | 1660 | irq = (struct kvm_s390_irq *) &buf[n]; |
1505 | if (ret) | 1661 | irq->type = KVM_S390_INT_SERVICE; |
1506 | break; | 1662 | irq->u.ext = fi->srv_signal; |
1507 | buf += sizeof(struct kvm_s390_irq); | ||
1508 | len -= sizeof(struct kvm_s390_irq); | ||
1509 | n++; | 1663 | n++; |
1510 | } | 1664 | } |
1665 | if (test_bit(IRQ_PEND_MCHK_REP, &fi->pending_irqs)) { | ||
1666 | if (n == max_irqs) { | ||
1667 | /* signal userspace to try again */ | ||
1668 | ret = -ENOMEM; | ||
1669 | goto out; | ||
1670 | } | ||
1671 | irq = (struct kvm_s390_irq *) &buf[n]; | ||
1672 | irq->type = KVM_S390_MCHK; | ||
1673 | irq->u.mchk = fi->mchk; | ||
1674 | n++; | ||
1675 | } | ||
1511 | 1676 | ||
1677 | out: | ||
1512 | spin_unlock(&fi->lock); | 1678 | spin_unlock(&fi->lock); |
1679 | if (!ret && n > 0) { | ||
1680 | if (copy_to_user(usrbuf, buf, sizeof(struct kvm_s390_irq) * n)) | ||
1681 | ret = -EFAULT; | ||
1682 | } | ||
1683 | vfree(buf); | ||
1513 | 1684 | ||
1514 | return ret < 0 ? ret : n; | 1685 | return ret < 0 ? ret : n; |
1515 | } | 1686 | } |
@@ -1520,7 +1691,7 @@ static int flic_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | |||
1520 | 1691 | ||
1521 | switch (attr->group) { | 1692 | switch (attr->group) { |
1522 | case KVM_DEV_FLIC_GET_ALL_IRQS: | 1693 | case KVM_DEV_FLIC_GET_ALL_IRQS: |
1523 | r = get_all_floating_irqs(dev->kvm, (u8 *) attr->addr, | 1694 | r = get_all_floating_irqs(dev->kvm, (u8 __user *) attr->addr, |
1524 | attr->attr); | 1695 | attr->attr); |
1525 | break; | 1696 | break; |
1526 | default: | 1697 | default: |
@@ -1952,3 +2123,143 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, | |||
1952 | { | 2123 | { |
1953 | return -EINVAL; | 2124 | return -EINVAL; |
1954 | } | 2125 | } |
2126 | |||
2127 | int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *irqstate, int len) | ||
2128 | { | ||
2129 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
2130 | struct kvm_s390_irq *buf; | ||
2131 | int r = 0; | ||
2132 | int n; | ||
2133 | |||
2134 | buf = vmalloc(len); | ||
2135 | if (!buf) | ||
2136 | return -ENOMEM; | ||
2137 | |||
2138 | if (copy_from_user((void *) buf, irqstate, len)) { | ||
2139 | r = -EFAULT; | ||
2140 | goto out_free; | ||
2141 | } | ||
2142 | |||
2143 | /* | ||
2144 | * Don't allow setting the interrupt state | ||
2145 | * when there are already interrupts pending | ||
2146 | */ | ||
2147 | spin_lock(&li->lock); | ||
2148 | if (li->pending_irqs) { | ||
2149 | r = -EBUSY; | ||
2150 | goto out_unlock; | ||
2151 | } | ||
2152 | |||
2153 | for (n = 0; n < len / sizeof(*buf); n++) { | ||
2154 | r = do_inject_vcpu(vcpu, &buf[n]); | ||
2155 | if (r) | ||
2156 | break; | ||
2157 | } | ||
2158 | |||
2159 | out_unlock: | ||
2160 | spin_unlock(&li->lock); | ||
2161 | out_free: | ||
2162 | vfree(buf); | ||
2163 | |||
2164 | return r; | ||
2165 | } | ||
2166 | |||
2167 | static void store_local_irq(struct kvm_s390_local_interrupt *li, | ||
2168 | struct kvm_s390_irq *irq, | ||
2169 | unsigned long irq_type) | ||
2170 | { | ||
2171 | switch (irq_type) { | ||
2172 | case IRQ_PEND_MCHK_EX: | ||
2173 | case IRQ_PEND_MCHK_REP: | ||
2174 | irq->type = KVM_S390_MCHK; | ||
2175 | irq->u.mchk = li->irq.mchk; | ||
2176 | break; | ||
2177 | case IRQ_PEND_PROG: | ||
2178 | irq->type = KVM_S390_PROGRAM_INT; | ||
2179 | irq->u.pgm = li->irq.pgm; | ||
2180 | break; | ||
2181 | case IRQ_PEND_PFAULT_INIT: | ||
2182 | irq->type = KVM_S390_INT_PFAULT_INIT; | ||
2183 | irq->u.ext = li->irq.ext; | ||
2184 | break; | ||
2185 | case IRQ_PEND_EXT_EXTERNAL: | ||
2186 | irq->type = KVM_S390_INT_EXTERNAL_CALL; | ||
2187 | irq->u.extcall = li->irq.extcall; | ||
2188 | break; | ||
2189 | case IRQ_PEND_EXT_CLOCK_COMP: | ||
2190 | irq->type = KVM_S390_INT_CLOCK_COMP; | ||
2191 | break; | ||
2192 | case IRQ_PEND_EXT_CPU_TIMER: | ||
2193 | irq->type = KVM_S390_INT_CPU_TIMER; | ||
2194 | break; | ||
2195 | case IRQ_PEND_SIGP_STOP: | ||
2196 | irq->type = KVM_S390_SIGP_STOP; | ||
2197 | irq->u.stop = li->irq.stop; | ||
2198 | break; | ||
2199 | case IRQ_PEND_RESTART: | ||
2200 | irq->type = KVM_S390_RESTART; | ||
2201 | break; | ||
2202 | case IRQ_PEND_SET_PREFIX: | ||
2203 | irq->type = KVM_S390_SIGP_SET_PREFIX; | ||
2204 | irq->u.prefix = li->irq.prefix; | ||
2205 | break; | ||
2206 | } | ||
2207 | } | ||
2208 | |||
2209 | int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu, __u8 __user *buf, int len) | ||
2210 | { | ||
2211 | uint8_t sigp_ctrl = vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sigp_ctrl; | ||
2212 | unsigned long sigp_emerg_pending[BITS_TO_LONGS(KVM_MAX_VCPUS)]; | ||
2213 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
2214 | unsigned long pending_irqs; | ||
2215 | struct kvm_s390_irq irq; | ||
2216 | unsigned long irq_type; | ||
2217 | int cpuaddr; | ||
2218 | int n = 0; | ||
2219 | |||
2220 | spin_lock(&li->lock); | ||
2221 | pending_irqs = li->pending_irqs; | ||
2222 | memcpy(&sigp_emerg_pending, &li->sigp_emerg_pending, | ||
2223 | sizeof(sigp_emerg_pending)); | ||
2224 | spin_unlock(&li->lock); | ||
2225 | |||
2226 | for_each_set_bit(irq_type, &pending_irqs, IRQ_PEND_COUNT) { | ||
2227 | memset(&irq, 0, sizeof(irq)); | ||
2228 | if (irq_type == IRQ_PEND_EXT_EMERGENCY) | ||
2229 | continue; | ||
2230 | if (n + sizeof(irq) > len) | ||
2231 | return -ENOBUFS; | ||
2232 | store_local_irq(&vcpu->arch.local_int, &irq, irq_type); | ||
2233 | if (copy_to_user(&buf[n], &irq, sizeof(irq))) | ||
2234 | return -EFAULT; | ||
2235 | n += sizeof(irq); | ||
2236 | } | ||
2237 | |||
2238 | if (test_bit(IRQ_PEND_EXT_EMERGENCY, &pending_irqs)) { | ||
2239 | for_each_set_bit(cpuaddr, sigp_emerg_pending, KVM_MAX_VCPUS) { | ||
2240 | memset(&irq, 0, sizeof(irq)); | ||
2241 | if (n + sizeof(irq) > len) | ||
2242 | return -ENOBUFS; | ||
2243 | irq.type = KVM_S390_INT_EMERGENCY; | ||
2244 | irq.u.emerg.code = cpuaddr; | ||
2245 | if (copy_to_user(&buf[n], &irq, sizeof(irq))) | ||
2246 | return -EFAULT; | ||
2247 | n += sizeof(irq); | ||
2248 | } | ||
2249 | } | ||
2250 | |||
2251 | if ((sigp_ctrl & SIGP_CTRL_C) && | ||
2252 | (atomic_read(&vcpu->arch.sie_block->cpuflags) & | ||
2253 | CPUSTAT_ECALL_PEND)) { | ||
2254 | if (n + sizeof(irq) > len) | ||
2255 | return -ENOBUFS; | ||
2256 | memset(&irq, 0, sizeof(irq)); | ||
2257 | irq.type = KVM_S390_INT_EXTERNAL_CALL; | ||
2258 | irq.u.extcall.code = sigp_ctrl & SIGP_CTRL_SCN_MASK; | ||
2259 | if (copy_to_user(&buf[n], &irq, sizeof(irq))) | ||
2260 | return -EFAULT; | ||
2261 | n += sizeof(irq); | ||
2262 | } | ||
2263 | |||
2264 | return n; | ||
2265 | } | ||
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 0c3623927563..afa2bd750ffc 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -25,11 +25,13 @@ | |||
25 | #include <linux/random.h> | 25 | #include <linux/random.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
28 | #include <linux/vmalloc.h> | ||
28 | #include <asm/asm-offsets.h> | 29 | #include <asm/asm-offsets.h> |
29 | #include <asm/lowcore.h> | 30 | #include <asm/lowcore.h> |
30 | #include <asm/pgtable.h> | 31 | #include <asm/pgtable.h> |
31 | #include <asm/nmi.h> | 32 | #include <asm/nmi.h> |
32 | #include <asm/switch_to.h> | 33 | #include <asm/switch_to.h> |
34 | #include <asm/isc.h> | ||
33 | #include <asm/sclp.h> | 35 | #include <asm/sclp.h> |
34 | #include "kvm-s390.h" | 36 | #include "kvm-s390.h" |
35 | #include "gaccess.h" | 37 | #include "gaccess.h" |
@@ -38,6 +40,11 @@ | |||
38 | #include "trace.h" | 40 | #include "trace.h" |
39 | #include "trace-s390.h" | 41 | #include "trace-s390.h" |
40 | 42 | ||
43 | #define MEM_OP_MAX_SIZE 65536 /* Maximum transfer size for KVM_S390_MEM_OP */ | ||
44 | #define LOCAL_IRQS 32 | ||
45 | #define VCPU_IRQS_MAX_BUF (sizeof(struct kvm_s390_irq) * \ | ||
46 | (KVM_MAX_VCPUS + LOCAL_IRQS)) | ||
47 | |||
41 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU | 48 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU |
42 | 49 | ||
43 | struct kvm_stats_debugfs_item debugfs_entries[] = { | 50 | struct kvm_stats_debugfs_item debugfs_entries[] = { |
@@ -87,6 +94,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
87 | { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) }, | 94 | { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) }, |
88 | { "instruction_sigp_stop_store_status", VCPU_STAT(instruction_sigp_stop_store_status) }, | 95 | { "instruction_sigp_stop_store_status", VCPU_STAT(instruction_sigp_stop_store_status) }, |
89 | { "instruction_sigp_store_status", VCPU_STAT(instruction_sigp_store_status) }, | 96 | { "instruction_sigp_store_status", VCPU_STAT(instruction_sigp_store_status) }, |
97 | { "instruction_sigp_store_adtl_status", VCPU_STAT(instruction_sigp_store_adtl_status) }, | ||
90 | { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) }, | 98 | { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) }, |
91 | { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) }, | 99 | { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) }, |
92 | { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) }, | 100 | { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) }, |
@@ -101,8 +109,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
101 | 109 | ||
102 | /* upper facilities limit for kvm */ | 110 | /* upper facilities limit for kvm */ |
103 | unsigned long kvm_s390_fac_list_mask[] = { | 111 | unsigned long kvm_s390_fac_list_mask[] = { |
104 | 0xff82fffbf4fc2000UL, | 112 | 0xffe6fffbfcfdfc40UL, |
105 | 0x005c000000000000UL, | 113 | 0x205c800000000000UL, |
106 | }; | 114 | }; |
107 | 115 | ||
108 | unsigned long kvm_s390_fac_list_mask_size(void) | 116 | unsigned long kvm_s390_fac_list_mask_size(void) |
@@ -165,16 +173,22 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
165 | case KVM_CAP_ONE_REG: | 173 | case KVM_CAP_ONE_REG: |
166 | case KVM_CAP_ENABLE_CAP: | 174 | case KVM_CAP_ENABLE_CAP: |
167 | case KVM_CAP_S390_CSS_SUPPORT: | 175 | case KVM_CAP_S390_CSS_SUPPORT: |
168 | case KVM_CAP_IRQFD: | ||
169 | case KVM_CAP_IOEVENTFD: | 176 | case KVM_CAP_IOEVENTFD: |
170 | case KVM_CAP_DEVICE_CTRL: | 177 | case KVM_CAP_DEVICE_CTRL: |
171 | case KVM_CAP_ENABLE_CAP_VM: | 178 | case KVM_CAP_ENABLE_CAP_VM: |
172 | case KVM_CAP_S390_IRQCHIP: | 179 | case KVM_CAP_S390_IRQCHIP: |
173 | case KVM_CAP_VM_ATTRIBUTES: | 180 | case KVM_CAP_VM_ATTRIBUTES: |
174 | case KVM_CAP_MP_STATE: | 181 | case KVM_CAP_MP_STATE: |
182 | case KVM_CAP_S390_INJECT_IRQ: | ||
175 | case KVM_CAP_S390_USER_SIGP: | 183 | case KVM_CAP_S390_USER_SIGP: |
184 | case KVM_CAP_S390_USER_STSI: | ||
185 | case KVM_CAP_S390_SKEYS: | ||
186 | case KVM_CAP_S390_IRQ_STATE: | ||
176 | r = 1; | 187 | r = 1; |
177 | break; | 188 | break; |
189 | case KVM_CAP_S390_MEM_OP: | ||
190 | r = MEM_OP_MAX_SIZE; | ||
191 | break; | ||
178 | case KVM_CAP_NR_VCPUS: | 192 | case KVM_CAP_NR_VCPUS: |
179 | case KVM_CAP_MAX_VCPUS: | 193 | case KVM_CAP_MAX_VCPUS: |
180 | r = KVM_MAX_VCPUS; | 194 | r = KVM_MAX_VCPUS; |
@@ -185,6 +199,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
185 | case KVM_CAP_S390_COW: | 199 | case KVM_CAP_S390_COW: |
186 | r = MACHINE_HAS_ESOP; | 200 | r = MACHINE_HAS_ESOP; |
187 | break; | 201 | break; |
202 | case KVM_CAP_S390_VECTOR_REGISTERS: | ||
203 | r = MACHINE_HAS_VX; | ||
204 | break; | ||
188 | default: | 205 | default: |
189 | r = 0; | 206 | r = 0; |
190 | } | 207 | } |
@@ -265,6 +282,18 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) | |||
265 | kvm->arch.user_sigp = 1; | 282 | kvm->arch.user_sigp = 1; |
266 | r = 0; | 283 | r = 0; |
267 | break; | 284 | break; |
285 | case KVM_CAP_S390_VECTOR_REGISTERS: | ||
286 | if (MACHINE_HAS_VX) { | ||
287 | set_kvm_facility(kvm->arch.model.fac->mask, 129); | ||
288 | set_kvm_facility(kvm->arch.model.fac->list, 129); | ||
289 | r = 0; | ||
290 | } else | ||
291 | r = -EINVAL; | ||
292 | break; | ||
293 | case KVM_CAP_S390_USER_STSI: | ||
294 | kvm->arch.user_stsi = 1; | ||
295 | r = 0; | ||
296 | break; | ||
268 | default: | 297 | default: |
269 | r = -EINVAL; | 298 | r = -EINVAL; |
270 | break; | 299 | break; |
@@ -522,7 +551,7 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) | |||
522 | memcpy(&kvm->arch.model.cpu_id, &proc->cpuid, | 551 | memcpy(&kvm->arch.model.cpu_id, &proc->cpuid, |
523 | sizeof(struct cpuid)); | 552 | sizeof(struct cpuid)); |
524 | kvm->arch.model.ibc = proc->ibc; | 553 | kvm->arch.model.ibc = proc->ibc; |
525 | memcpy(kvm->arch.model.fac->kvm, proc->fac_list, | 554 | memcpy(kvm->arch.model.fac->list, proc->fac_list, |
526 | S390_ARCH_FAC_LIST_SIZE_BYTE); | 555 | S390_ARCH_FAC_LIST_SIZE_BYTE); |
527 | } else | 556 | } else |
528 | ret = -EFAULT; | 557 | ret = -EFAULT; |
@@ -556,7 +585,7 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr) | |||
556 | } | 585 | } |
557 | memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid)); | 586 | memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid)); |
558 | proc->ibc = kvm->arch.model.ibc; | 587 | proc->ibc = kvm->arch.model.ibc; |
559 | memcpy(&proc->fac_list, kvm->arch.model.fac->kvm, S390_ARCH_FAC_LIST_SIZE_BYTE); | 588 | memcpy(&proc->fac_list, kvm->arch.model.fac->list, S390_ARCH_FAC_LIST_SIZE_BYTE); |
560 | if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc))) | 589 | if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc))) |
561 | ret = -EFAULT; | 590 | ret = -EFAULT; |
562 | kfree(proc); | 591 | kfree(proc); |
@@ -576,10 +605,10 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr) | |||
576 | } | 605 | } |
577 | get_cpu_id((struct cpuid *) &mach->cpuid); | 606 | get_cpu_id((struct cpuid *) &mach->cpuid); |
578 | mach->ibc = sclp_get_ibc(); | 607 | mach->ibc = sclp_get_ibc(); |
579 | memcpy(&mach->fac_mask, kvm_s390_fac_list_mask, | 608 | memcpy(&mach->fac_mask, kvm->arch.model.fac->mask, |
580 | kvm_s390_fac_list_mask_size() * sizeof(u64)); | 609 | S390_ARCH_FAC_LIST_SIZE_BYTE); |
581 | memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list, | 610 | memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list, |
582 | S390_ARCH_FAC_LIST_SIZE_U64); | 611 | S390_ARCH_FAC_LIST_SIZE_BYTE); |
583 | if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach))) | 612 | if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach))) |
584 | ret = -EFAULT; | 613 | ret = -EFAULT; |
585 | kfree(mach); | 614 | kfree(mach); |
@@ -709,6 +738,108 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr) | |||
709 | return ret; | 738 | return ret; |
710 | } | 739 | } |
711 | 740 | ||
741 | static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args) | ||
742 | { | ||
743 | uint8_t *keys; | ||
744 | uint64_t hva; | ||
745 | unsigned long curkey; | ||
746 | int i, r = 0; | ||
747 | |||
748 | if (args->flags != 0) | ||
749 | return -EINVAL; | ||
750 | |||
751 | /* Is this guest using storage keys? */ | ||
752 | if (!mm_use_skey(current->mm)) | ||
753 | return KVM_S390_GET_SKEYS_NONE; | ||
754 | |||
755 | /* Enforce sane limit on memory allocation */ | ||
756 | if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX) | ||
757 | return -EINVAL; | ||
758 | |||
759 | keys = kmalloc_array(args->count, sizeof(uint8_t), | ||
760 | GFP_KERNEL | __GFP_NOWARN); | ||
761 | if (!keys) | ||
762 | keys = vmalloc(sizeof(uint8_t) * args->count); | ||
763 | if (!keys) | ||
764 | return -ENOMEM; | ||
765 | |||
766 | for (i = 0; i < args->count; i++) { | ||
767 | hva = gfn_to_hva(kvm, args->start_gfn + i); | ||
768 | if (kvm_is_error_hva(hva)) { | ||
769 | r = -EFAULT; | ||
770 | goto out; | ||
771 | } | ||
772 | |||
773 | curkey = get_guest_storage_key(current->mm, hva); | ||
774 | if (IS_ERR_VALUE(curkey)) { | ||
775 | r = curkey; | ||
776 | goto out; | ||
777 | } | ||
778 | keys[i] = curkey; | ||
779 | } | ||
780 | |||
781 | r = copy_to_user((uint8_t __user *)args->skeydata_addr, keys, | ||
782 | sizeof(uint8_t) * args->count); | ||
783 | if (r) | ||
784 | r = -EFAULT; | ||
785 | out: | ||
786 | kvfree(keys); | ||
787 | return r; | ||
788 | } | ||
789 | |||
790 | static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args) | ||
791 | { | ||
792 | uint8_t *keys; | ||
793 | uint64_t hva; | ||
794 | int i, r = 0; | ||
795 | |||
796 | if (args->flags != 0) | ||
797 | return -EINVAL; | ||
798 | |||
799 | /* Enforce sane limit on memory allocation */ | ||
800 | if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX) | ||
801 | return -EINVAL; | ||
802 | |||
803 | keys = kmalloc_array(args->count, sizeof(uint8_t), | ||
804 | GFP_KERNEL | __GFP_NOWARN); | ||
805 | if (!keys) | ||
806 | keys = vmalloc(sizeof(uint8_t) * args->count); | ||
807 | if (!keys) | ||
808 | return -ENOMEM; | ||
809 | |||
810 | r = copy_from_user(keys, (uint8_t __user *)args->skeydata_addr, | ||
811 | sizeof(uint8_t) * args->count); | ||
812 | if (r) { | ||
813 | r = -EFAULT; | ||
814 | goto out; | ||
815 | } | ||
816 | |||
817 | /* Enable storage key handling for the guest */ | ||
818 | s390_enable_skey(); | ||
819 | |||
820 | for (i = 0; i < args->count; i++) { | ||
821 | hva = gfn_to_hva(kvm, args->start_gfn + i); | ||
822 | if (kvm_is_error_hva(hva)) { | ||
823 | r = -EFAULT; | ||
824 | goto out; | ||
825 | } | ||
826 | |||
827 | /* Lowest order bit is reserved */ | ||
828 | if (keys[i] & 0x01) { | ||
829 | r = -EINVAL; | ||
830 | goto out; | ||
831 | } | ||
832 | |||
833 | r = set_guest_storage_key(current->mm, hva, | ||
834 | (unsigned long)keys[i], 0); | ||
835 | if (r) | ||
836 | goto out; | ||
837 | } | ||
838 | out: | ||
839 | kvfree(keys); | ||
840 | return r; | ||
841 | } | ||
842 | |||
712 | long kvm_arch_vm_ioctl(struct file *filp, | 843 | long kvm_arch_vm_ioctl(struct file *filp, |
713 | unsigned int ioctl, unsigned long arg) | 844 | unsigned int ioctl, unsigned long arg) |
714 | { | 845 | { |
@@ -768,6 +899,26 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
768 | r = kvm_s390_vm_has_attr(kvm, &attr); | 899 | r = kvm_s390_vm_has_attr(kvm, &attr); |
769 | break; | 900 | break; |
770 | } | 901 | } |
902 | case KVM_S390_GET_SKEYS: { | ||
903 | struct kvm_s390_skeys args; | ||
904 | |||
905 | r = -EFAULT; | ||
906 | if (copy_from_user(&args, argp, | ||
907 | sizeof(struct kvm_s390_skeys))) | ||
908 | break; | ||
909 | r = kvm_s390_get_skeys(kvm, &args); | ||
910 | break; | ||
911 | } | ||
912 | case KVM_S390_SET_SKEYS: { | ||
913 | struct kvm_s390_skeys args; | ||
914 | |||
915 | r = -EFAULT; | ||
916 | if (copy_from_user(&args, argp, | ||
917 | sizeof(struct kvm_s390_skeys))) | ||
918 | break; | ||
919 | r = kvm_s390_set_skeys(kvm, &args); | ||
920 | break; | ||
921 | } | ||
771 | default: | 922 | default: |
772 | r = -ENOTTY; | 923 | r = -ENOTTY; |
773 | } | 924 | } |
@@ -778,15 +929,18 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
778 | static int kvm_s390_query_ap_config(u8 *config) | 929 | static int kvm_s390_query_ap_config(u8 *config) |
779 | { | 930 | { |
780 | u32 fcn_code = 0x04000000UL; | 931 | u32 fcn_code = 0x04000000UL; |
781 | u32 cc; | 932 | u32 cc = 0; |
782 | 933 | ||
934 | memset(config, 0, 128); | ||
783 | asm volatile( | 935 | asm volatile( |
784 | "lgr 0,%1\n" | 936 | "lgr 0,%1\n" |
785 | "lgr 2,%2\n" | 937 | "lgr 2,%2\n" |
786 | ".long 0xb2af0000\n" /* PQAP(QCI) */ | 938 | ".long 0xb2af0000\n" /* PQAP(QCI) */ |
787 | "ipm %0\n" | 939 | "0: ipm %0\n" |
788 | "srl %0,28\n" | 940 | "srl %0,28\n" |
789 | : "=r" (cc) | 941 | "1:\n" |
942 | EX_TABLE(0b, 1b) | ||
943 | : "+r" (cc) | ||
790 | : "r" (fcn_code), "r" (config) | 944 | : "r" (fcn_code), "r" (config) |
791 | : "cc", "0", "2", "memory" | 945 | : "cc", "0", "2", "memory" |
792 | ); | 946 | ); |
@@ -839,9 +993,13 @@ static int kvm_s390_crypto_init(struct kvm *kvm) | |||
839 | 993 | ||
840 | kvm_s390_set_crycb_format(kvm); | 994 | kvm_s390_set_crycb_format(kvm); |
841 | 995 | ||
842 | /* Disable AES/DEA protected key functions by default */ | 996 | /* Enable AES/DEA protected key functions by default */ |
843 | kvm->arch.crypto.aes_kw = 0; | 997 | kvm->arch.crypto.aes_kw = 1; |
844 | kvm->arch.crypto.dea_kw = 0; | 998 | kvm->arch.crypto.dea_kw = 1; |
999 | get_random_bytes(kvm->arch.crypto.crycb->aes_wrapping_key_mask, | ||
1000 | sizeof(kvm->arch.crypto.crycb->aes_wrapping_key_mask)); | ||
1001 | get_random_bytes(kvm->arch.crypto.crycb->dea_wrapping_key_mask, | ||
1002 | sizeof(kvm->arch.crypto.crycb->dea_wrapping_key_mask)); | ||
845 | 1003 | ||
846 | return 0; | 1004 | return 0; |
847 | } | 1005 | } |
@@ -881,53 +1039,43 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
881 | 1039 | ||
882 | kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long)); | 1040 | kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long)); |
883 | if (!kvm->arch.dbf) | 1041 | if (!kvm->arch.dbf) |
884 | goto out_nodbf; | 1042 | goto out_err; |
885 | 1043 | ||
886 | /* | 1044 | /* |
887 | * The architectural maximum amount of facilities is 16 kbit. To store | 1045 | * The architectural maximum amount of facilities is 16 kbit. To store |
888 | * this amount, 2 kbyte of memory is required. Thus we need a full | 1046 | * this amount, 2 kbyte of memory is required. Thus we need a full |
889 | * page to hold the active copy (arch.model.fac->sie) and the current | 1047 | * page to hold the guest facility list (arch.model.fac->list) and the |
890 | * facilities set (arch.model.fac->kvm). Its address size has to be | 1048 | * facility mask (arch.model.fac->mask). Its address size has to be |
891 | * 31 bits and word aligned. | 1049 | * 31 bits and word aligned. |
892 | */ | 1050 | */ |
893 | kvm->arch.model.fac = | 1051 | kvm->arch.model.fac = |
894 | (struct s390_model_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | 1052 | (struct kvm_s390_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
895 | if (!kvm->arch.model.fac) | 1053 | if (!kvm->arch.model.fac) |
896 | goto out_nofac; | 1054 | goto out_err; |
897 | |||
898 | memcpy(kvm->arch.model.fac->kvm, S390_lowcore.stfle_fac_list, | ||
899 | S390_ARCH_FAC_LIST_SIZE_U64); | ||
900 | |||
901 | /* | ||
902 | * If this KVM host runs *not* in a LPAR, relax the facility bits | ||
903 | * of the kvm facility mask by all missing facilities. This will allow | ||
904 | * to determine the right CPU model by means of the remaining facilities. | ||
905 | * Live guest migration must prohibit the migration of KVMs running in | ||
906 | * a LPAR to non LPAR hosts. | ||
907 | */ | ||
908 | if (!MACHINE_IS_LPAR) | ||
909 | for (i = 0; i < kvm_s390_fac_list_mask_size(); i++) | ||
910 | kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->kvm[i]; | ||
911 | 1055 | ||
912 | /* | 1056 | /* Populate the facility mask initially. */ |
913 | * Apply the kvm facility mask to limit the kvm supported/tolerated | 1057 | memcpy(kvm->arch.model.fac->mask, S390_lowcore.stfle_fac_list, |
914 | * facility list. | 1058 | S390_ARCH_FAC_LIST_SIZE_BYTE); |
915 | */ | ||
916 | for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { | 1059 | for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { |
917 | if (i < kvm_s390_fac_list_mask_size()) | 1060 | if (i < kvm_s390_fac_list_mask_size()) |
918 | kvm->arch.model.fac->kvm[i] &= kvm_s390_fac_list_mask[i]; | 1061 | kvm->arch.model.fac->mask[i] &= kvm_s390_fac_list_mask[i]; |
919 | else | 1062 | else |
920 | kvm->arch.model.fac->kvm[i] = 0UL; | 1063 | kvm->arch.model.fac->mask[i] = 0UL; |
921 | } | 1064 | } |
922 | 1065 | ||
1066 | /* Populate the facility list initially. */ | ||
1067 | memcpy(kvm->arch.model.fac->list, kvm->arch.model.fac->mask, | ||
1068 | S390_ARCH_FAC_LIST_SIZE_BYTE); | ||
1069 | |||
923 | kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id); | 1070 | kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id); |
924 | kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff; | 1071 | kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff; |
925 | 1072 | ||
926 | if (kvm_s390_crypto_init(kvm) < 0) | 1073 | if (kvm_s390_crypto_init(kvm) < 0) |
927 | goto out_crypto; | 1074 | goto out_err; |
928 | 1075 | ||
929 | spin_lock_init(&kvm->arch.float_int.lock); | 1076 | spin_lock_init(&kvm->arch.float_int.lock); |
930 | INIT_LIST_HEAD(&kvm->arch.float_int.list); | 1077 | for (i = 0; i < FIRQ_LIST_COUNT; i++) |
1078 | INIT_LIST_HEAD(&kvm->arch.float_int.lists[i]); | ||
931 | init_waitqueue_head(&kvm->arch.ipte_wq); | 1079 | init_waitqueue_head(&kvm->arch.ipte_wq); |
932 | mutex_init(&kvm->arch.ipte_mutex); | 1080 | mutex_init(&kvm->arch.ipte_mutex); |
933 | 1081 | ||
@@ -939,7 +1087,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
939 | } else { | 1087 | } else { |
940 | kvm->arch.gmap = gmap_alloc(current->mm, (1UL << 44) - 1); | 1088 | kvm->arch.gmap = gmap_alloc(current->mm, (1UL << 44) - 1); |
941 | if (!kvm->arch.gmap) | 1089 | if (!kvm->arch.gmap) |
942 | goto out_nogmap; | 1090 | goto out_err; |
943 | kvm->arch.gmap->private = kvm; | 1091 | kvm->arch.gmap->private = kvm; |
944 | kvm->arch.gmap->pfault_enabled = 0; | 1092 | kvm->arch.gmap->pfault_enabled = 0; |
945 | } | 1093 | } |
@@ -951,15 +1099,11 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
951 | spin_lock_init(&kvm->arch.start_stop_lock); | 1099 | spin_lock_init(&kvm->arch.start_stop_lock); |
952 | 1100 | ||
953 | return 0; | 1101 | return 0; |
954 | out_nogmap: | 1102 | out_err: |
955 | kfree(kvm->arch.crypto.crycb); | 1103 | kfree(kvm->arch.crypto.crycb); |
956 | out_crypto: | ||
957 | free_page((unsigned long)kvm->arch.model.fac); | 1104 | free_page((unsigned long)kvm->arch.model.fac); |
958 | out_nofac: | ||
959 | debug_unregister(kvm->arch.dbf); | 1105 | debug_unregister(kvm->arch.dbf); |
960 | out_nodbf: | ||
961 | free_page((unsigned long)(kvm->arch.sca)); | 1106 | free_page((unsigned long)(kvm->arch.sca)); |
962 | out_err: | ||
963 | return rc; | 1107 | return rc; |
964 | } | 1108 | } |
965 | 1109 | ||
@@ -1039,6 +1183,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
1039 | KVM_SYNC_CRS | | 1183 | KVM_SYNC_CRS | |
1040 | KVM_SYNC_ARCH0 | | 1184 | KVM_SYNC_ARCH0 | |
1041 | KVM_SYNC_PFAULT; | 1185 | KVM_SYNC_PFAULT; |
1186 | if (test_kvm_facility(vcpu->kvm, 129)) | ||
1187 | vcpu->run->kvm_valid_regs |= KVM_SYNC_VRS; | ||
1042 | 1188 | ||
1043 | if (kvm_is_ucontrol(vcpu->kvm)) | 1189 | if (kvm_is_ucontrol(vcpu->kvm)) |
1044 | return __kvm_ucontrol_vcpu_init(vcpu); | 1190 | return __kvm_ucontrol_vcpu_init(vcpu); |
@@ -1049,10 +1195,18 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
1049 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 1195 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
1050 | { | 1196 | { |
1051 | save_fp_ctl(&vcpu->arch.host_fpregs.fpc); | 1197 | save_fp_ctl(&vcpu->arch.host_fpregs.fpc); |
1052 | save_fp_regs(vcpu->arch.host_fpregs.fprs); | 1198 | if (test_kvm_facility(vcpu->kvm, 129)) |
1199 | save_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs); | ||
1200 | else | ||
1201 | save_fp_regs(vcpu->arch.host_fpregs.fprs); | ||
1053 | save_access_regs(vcpu->arch.host_acrs); | 1202 | save_access_regs(vcpu->arch.host_acrs); |
1054 | restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc); | 1203 | if (test_kvm_facility(vcpu->kvm, 129)) { |
1055 | restore_fp_regs(vcpu->arch.guest_fpregs.fprs); | 1204 | restore_fp_ctl(&vcpu->run->s.regs.fpc); |
1205 | restore_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); | ||
1206 | } else { | ||
1207 | restore_fp_ctl(&vcpu->arch.guest_fpregs.fpc); | ||
1208 | restore_fp_regs(vcpu->arch.guest_fpregs.fprs); | ||
1209 | } | ||
1056 | restore_access_regs(vcpu->run->s.regs.acrs); | 1210 | restore_access_regs(vcpu->run->s.regs.acrs); |
1057 | gmap_enable(vcpu->arch.gmap); | 1211 | gmap_enable(vcpu->arch.gmap); |
1058 | atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); | 1212 | atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); |
@@ -1062,11 +1216,19 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
1062 | { | 1216 | { |
1063 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); | 1217 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); |
1064 | gmap_disable(vcpu->arch.gmap); | 1218 | gmap_disable(vcpu->arch.gmap); |
1065 | save_fp_ctl(&vcpu->arch.guest_fpregs.fpc); | 1219 | if (test_kvm_facility(vcpu->kvm, 129)) { |
1066 | save_fp_regs(vcpu->arch.guest_fpregs.fprs); | 1220 | save_fp_ctl(&vcpu->run->s.regs.fpc); |
1221 | save_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); | ||
1222 | } else { | ||
1223 | save_fp_ctl(&vcpu->arch.guest_fpregs.fpc); | ||
1224 | save_fp_regs(vcpu->arch.guest_fpregs.fprs); | ||
1225 | } | ||
1067 | save_access_regs(vcpu->run->s.regs.acrs); | 1226 | save_access_regs(vcpu->run->s.regs.acrs); |
1068 | restore_fp_ctl(&vcpu->arch.host_fpregs.fpc); | 1227 | restore_fp_ctl(&vcpu->arch.host_fpregs.fpc); |
1069 | restore_fp_regs(vcpu->arch.host_fpregs.fprs); | 1228 | if (test_kvm_facility(vcpu->kvm, 129)) |
1229 | restore_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs); | ||
1230 | else | ||
1231 | restore_fp_regs(vcpu->arch.host_fpregs.fprs); | ||
1070 | restore_access_regs(vcpu->arch.host_acrs); | 1232 | restore_access_regs(vcpu->arch.host_acrs); |
1071 | } | 1233 | } |
1072 | 1234 | ||
@@ -1134,6 +1296,15 @@ int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu) | |||
1134 | return 0; | 1296 | return 0; |
1135 | } | 1297 | } |
1136 | 1298 | ||
1299 | static void kvm_s390_vcpu_setup_model(struct kvm_vcpu *vcpu) | ||
1300 | { | ||
1301 | struct kvm_s390_cpu_model *model = &vcpu->kvm->arch.model; | ||
1302 | |||
1303 | vcpu->arch.cpu_id = model->cpu_id; | ||
1304 | vcpu->arch.sie_block->ibc = model->ibc; | ||
1305 | vcpu->arch.sie_block->fac = (int) (long) model->fac->list; | ||
1306 | } | ||
1307 | |||
1137 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | 1308 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) |
1138 | { | 1309 | { |
1139 | int rc = 0; | 1310 | int rc = 0; |
@@ -1142,6 +1313,8 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1142 | CPUSTAT_SM | | 1313 | CPUSTAT_SM | |
1143 | CPUSTAT_STOPPED | | 1314 | CPUSTAT_STOPPED | |
1144 | CPUSTAT_GED); | 1315 | CPUSTAT_GED); |
1316 | kvm_s390_vcpu_setup_model(vcpu); | ||
1317 | |||
1145 | vcpu->arch.sie_block->ecb = 6; | 1318 | vcpu->arch.sie_block->ecb = 6; |
1146 | if (test_kvm_facility(vcpu->kvm, 50) && test_kvm_facility(vcpu->kvm, 73)) | 1319 | if (test_kvm_facility(vcpu->kvm, 50) && test_kvm_facility(vcpu->kvm, 73)) |
1147 | vcpu->arch.sie_block->ecb |= 0x10; | 1320 | vcpu->arch.sie_block->ecb |= 0x10; |
@@ -1152,8 +1325,11 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1152 | vcpu->arch.sie_block->eca |= 1; | 1325 | vcpu->arch.sie_block->eca |= 1; |
1153 | if (sclp_has_sigpif()) | 1326 | if (sclp_has_sigpif()) |
1154 | vcpu->arch.sie_block->eca |= 0x10000000U; | 1327 | vcpu->arch.sie_block->eca |= 0x10000000U; |
1155 | vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE | | 1328 | if (test_kvm_facility(vcpu->kvm, 129)) { |
1156 | ICTL_TPROT; | 1329 | vcpu->arch.sie_block->eca |= 0x00020000; |
1330 | vcpu->arch.sie_block->ecd |= 0x20000000; | ||
1331 | } | ||
1332 | vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE; | ||
1157 | 1333 | ||
1158 | if (kvm_s390_cmma_enabled(vcpu->kvm)) { | 1334 | if (kvm_s390_cmma_enabled(vcpu->kvm)) { |
1159 | rc = kvm_s390_vcpu_setup_cmma(vcpu); | 1335 | rc = kvm_s390_vcpu_setup_cmma(vcpu); |
@@ -1163,13 +1339,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1163 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 1339 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
1164 | vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup; | 1340 | vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup; |
1165 | 1341 | ||
1166 | mutex_lock(&vcpu->kvm->lock); | ||
1167 | vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id; | ||
1168 | memcpy(vcpu->kvm->arch.model.fac->sie, vcpu->kvm->arch.model.fac->kvm, | ||
1169 | S390_ARCH_FAC_LIST_SIZE_BYTE); | ||
1170 | vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc; | ||
1171 | mutex_unlock(&vcpu->kvm->lock); | ||
1172 | |||
1173 | kvm_s390_vcpu_crypto_setup(vcpu); | 1342 | kvm_s390_vcpu_crypto_setup(vcpu); |
1174 | 1343 | ||
1175 | return rc; | 1344 | return rc; |
@@ -1197,6 +1366,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
1197 | 1366 | ||
1198 | vcpu->arch.sie_block = &sie_page->sie_block; | 1367 | vcpu->arch.sie_block = &sie_page->sie_block; |
1199 | vcpu->arch.sie_block->itdba = (unsigned long) &sie_page->itdb; | 1368 | vcpu->arch.sie_block->itdba = (unsigned long) &sie_page->itdb; |
1369 | vcpu->arch.host_vregs = &sie_page->vregs; | ||
1200 | 1370 | ||
1201 | vcpu->arch.sie_block->icpua = id; | 1371 | vcpu->arch.sie_block->icpua = id; |
1202 | if (!kvm_is_ucontrol(kvm)) { | 1372 | if (!kvm_is_ucontrol(kvm)) { |
@@ -1212,7 +1382,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
1212 | vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; | 1382 | vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; |
1213 | set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); | 1383 | set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); |
1214 | } | 1384 | } |
1215 | vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->sie; | ||
1216 | 1385 | ||
1217 | spin_lock_init(&vcpu->arch.local_int.lock); | 1386 | spin_lock_init(&vcpu->arch.local_int.lock); |
1218 | vcpu->arch.local_int.float_int = &kvm->arch.float_int; | 1387 | vcpu->arch.local_int.float_int = &kvm->arch.float_int; |
@@ -1732,6 +1901,31 @@ static int vcpu_pre_run(struct kvm_vcpu *vcpu) | |||
1732 | return 0; | 1901 | return 0; |
1733 | } | 1902 | } |
1734 | 1903 | ||
1904 | static int vcpu_post_run_fault_in_sie(struct kvm_vcpu *vcpu) | ||
1905 | { | ||
1906 | psw_t *psw = &vcpu->arch.sie_block->gpsw; | ||
1907 | u8 opcode; | ||
1908 | int rc; | ||
1909 | |||
1910 | VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); | ||
1911 | trace_kvm_s390_sie_fault(vcpu); | ||
1912 | |||
1913 | /* | ||
1914 | * We want to inject an addressing exception, which is defined as a | ||
1915 | * suppressing or terminating exception. However, since we came here | ||
1916 | * by a DAT access exception, the PSW still points to the faulting | ||
1917 | * instruction since DAT exceptions are nullifying. So we've got | ||
1918 | * to look up the current opcode to get the length of the instruction | ||
1919 | * to be able to forward the PSW. | ||
1920 | */ | ||
1921 | rc = read_guest(vcpu, psw->addr, 0, &opcode, 1); | ||
1922 | if (rc) | ||
1923 | return kvm_s390_inject_prog_cond(vcpu, rc); | ||
1924 | psw->addr = __rewind_psw(*psw, -insn_length(opcode)); | ||
1925 | |||
1926 | return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); | ||
1927 | } | ||
1928 | |||
1735 | static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) | 1929 | static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) |
1736 | { | 1930 | { |
1737 | int rc = -1; | 1931 | int rc = -1; |
@@ -1763,11 +1957,8 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) | |||
1763 | } | 1957 | } |
1764 | } | 1958 | } |
1765 | 1959 | ||
1766 | if (rc == -1) { | 1960 | if (rc == -1) |
1767 | VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); | 1961 | rc = vcpu_post_run_fault_in_sie(vcpu); |
1768 | trace_kvm_s390_sie_fault(vcpu); | ||
1769 | rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); | ||
1770 | } | ||
1771 | 1962 | ||
1772 | memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); | 1963 | memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); |
1773 | 1964 | ||
@@ -1983,6 +2174,35 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) | |||
1983 | return kvm_s390_store_status_unloaded(vcpu, addr); | 2174 | return kvm_s390_store_status_unloaded(vcpu, addr); |
1984 | } | 2175 | } |
1985 | 2176 | ||
2177 | /* | ||
2178 | * store additional status at address | ||
2179 | */ | ||
2180 | int kvm_s390_store_adtl_status_unloaded(struct kvm_vcpu *vcpu, | ||
2181 | unsigned long gpa) | ||
2182 | { | ||
2183 | /* Only bits 0-53 are used for address formation */ | ||
2184 | if (!(gpa & ~0x3ff)) | ||
2185 | return 0; | ||
2186 | |||
2187 | return write_guest_abs(vcpu, gpa & ~0x3ff, | ||
2188 | (void *)&vcpu->run->s.regs.vrs, 512); | ||
2189 | } | ||
2190 | |||
2191 | int kvm_s390_vcpu_store_adtl_status(struct kvm_vcpu *vcpu, unsigned long addr) | ||
2192 | { | ||
2193 | if (!test_kvm_facility(vcpu->kvm, 129)) | ||
2194 | return 0; | ||
2195 | |||
2196 | /* | ||
2197 | * The guest VXRS are in the host VXRs due to the lazy | ||
2198 | * copying in vcpu load/put. Let's update our copies before we save | ||
2199 | * it into the save area. | ||
2200 | */ | ||
2201 | save_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); | ||
2202 | |||
2203 | return kvm_s390_store_adtl_status_unloaded(vcpu, addr); | ||
2204 | } | ||
2205 | |||
1986 | static void __disable_ibs_on_vcpu(struct kvm_vcpu *vcpu) | 2206 | static void __disable_ibs_on_vcpu(struct kvm_vcpu *vcpu) |
1987 | { | 2207 | { |
1988 | kvm_check_request(KVM_REQ_ENABLE_IBS, vcpu); | 2208 | kvm_check_request(KVM_REQ_ENABLE_IBS, vcpu); |
@@ -2107,6 +2327,65 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, | |||
2107 | return r; | 2327 | return r; |
2108 | } | 2328 | } |
2109 | 2329 | ||
2330 | static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu, | ||
2331 | struct kvm_s390_mem_op *mop) | ||
2332 | { | ||
2333 | void __user *uaddr = (void __user *)mop->buf; | ||
2334 | void *tmpbuf = NULL; | ||
2335 | int r, srcu_idx; | ||
2336 | const u64 supported_flags = KVM_S390_MEMOP_F_INJECT_EXCEPTION | ||
2337 | | KVM_S390_MEMOP_F_CHECK_ONLY; | ||
2338 | |||
2339 | if (mop->flags & ~supported_flags) | ||
2340 | return -EINVAL; | ||
2341 | |||
2342 | if (mop->size > MEM_OP_MAX_SIZE) | ||
2343 | return -E2BIG; | ||
2344 | |||
2345 | if (!(mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY)) { | ||
2346 | tmpbuf = vmalloc(mop->size); | ||
2347 | if (!tmpbuf) | ||
2348 | return -ENOMEM; | ||
2349 | } | ||
2350 | |||
2351 | srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
2352 | |||
2353 | switch (mop->op) { | ||
2354 | case KVM_S390_MEMOP_LOGICAL_READ: | ||
2355 | if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { | ||
2356 | r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, false); | ||
2357 | break; | ||
2358 | } | ||
2359 | r = read_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size); | ||
2360 | if (r == 0) { | ||
2361 | if (copy_to_user(uaddr, tmpbuf, mop->size)) | ||
2362 | r = -EFAULT; | ||
2363 | } | ||
2364 | break; | ||
2365 | case KVM_S390_MEMOP_LOGICAL_WRITE: | ||
2366 | if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { | ||
2367 | r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, true); | ||
2368 | break; | ||
2369 | } | ||
2370 | if (copy_from_user(tmpbuf, uaddr, mop->size)) { | ||
2371 | r = -EFAULT; | ||
2372 | break; | ||
2373 | } | ||
2374 | r = write_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size); | ||
2375 | break; | ||
2376 | default: | ||
2377 | r = -EINVAL; | ||
2378 | } | ||
2379 | |||
2380 | srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx); | ||
2381 | |||
2382 | if (r > 0 && (mop->flags & KVM_S390_MEMOP_F_INJECT_EXCEPTION) != 0) | ||
2383 | kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); | ||
2384 | |||
2385 | vfree(tmpbuf); | ||
2386 | return r; | ||
2387 | } | ||
2388 | |||
2110 | long kvm_arch_vcpu_ioctl(struct file *filp, | 2389 | long kvm_arch_vcpu_ioctl(struct file *filp, |
2111 | unsigned int ioctl, unsigned long arg) | 2390 | unsigned int ioctl, unsigned long arg) |
2112 | { | 2391 | { |
@@ -2116,6 +2395,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
2116 | long r; | 2395 | long r; |
2117 | 2396 | ||
2118 | switch (ioctl) { | 2397 | switch (ioctl) { |
2398 | case KVM_S390_IRQ: { | ||
2399 | struct kvm_s390_irq s390irq; | ||
2400 | |||
2401 | r = -EFAULT; | ||
2402 | if (copy_from_user(&s390irq, argp, sizeof(s390irq))) | ||
2403 | break; | ||
2404 | r = kvm_s390_inject_vcpu(vcpu, &s390irq); | ||
2405 | break; | ||
2406 | } | ||
2119 | case KVM_S390_INTERRUPT: { | 2407 | case KVM_S390_INTERRUPT: { |
2120 | struct kvm_s390_interrupt s390int; | 2408 | struct kvm_s390_interrupt s390int; |
2121 | struct kvm_s390_irq s390irq; | 2409 | struct kvm_s390_irq s390irq; |
@@ -2206,6 +2494,47 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
2206 | r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); | 2494 | r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); |
2207 | break; | 2495 | break; |
2208 | } | 2496 | } |
2497 | case KVM_S390_MEM_OP: { | ||
2498 | struct kvm_s390_mem_op mem_op; | ||
2499 | |||
2500 | if (copy_from_user(&mem_op, argp, sizeof(mem_op)) == 0) | ||
2501 | r = kvm_s390_guest_mem_op(vcpu, &mem_op); | ||
2502 | else | ||
2503 | r = -EFAULT; | ||
2504 | break; | ||
2505 | } | ||
2506 | case KVM_S390_SET_IRQ_STATE: { | ||
2507 | struct kvm_s390_irq_state irq_state; | ||
2508 | |||
2509 | r = -EFAULT; | ||
2510 | if (copy_from_user(&irq_state, argp, sizeof(irq_state))) | ||
2511 | break; | ||
2512 | if (irq_state.len > VCPU_IRQS_MAX_BUF || | ||
2513 | irq_state.len == 0 || | ||
2514 | irq_state.len % sizeof(struct kvm_s390_irq) > 0) { | ||
2515 | r = -EINVAL; | ||
2516 | break; | ||
2517 | } | ||
2518 | r = kvm_s390_set_irq_state(vcpu, | ||
2519 | (void __user *) irq_state.buf, | ||
2520 | irq_state.len); | ||
2521 | break; | ||
2522 | } | ||
2523 | case KVM_S390_GET_IRQ_STATE: { | ||
2524 | struct kvm_s390_irq_state irq_state; | ||
2525 | |||
2526 | r = -EFAULT; | ||
2527 | if (copy_from_user(&irq_state, argp, sizeof(irq_state))) | ||
2528 | break; | ||
2529 | if (irq_state.len == 0) { | ||
2530 | r = -EINVAL; | ||
2531 | break; | ||
2532 | } | ||
2533 | r = kvm_s390_get_irq_state(vcpu, | ||
2534 | (__u8 __user *) irq_state.buf, | ||
2535 | irq_state.len); | ||
2536 | break; | ||
2537 | } | ||
2209 | default: | 2538 | default: |
2210 | r = -ENOTTY; | 2539 | r = -ENOTTY; |
2211 | } | 2540 | } |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 985c2114d7ef..ca108b90ae56 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
@@ -70,16 +70,22 @@ static inline void kvm_s390_set_prefix(struct kvm_vcpu *vcpu, u32 prefix) | |||
70 | kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu); | 70 | kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu); |
71 | } | 71 | } |
72 | 72 | ||
73 | static inline u64 kvm_s390_get_base_disp_s(struct kvm_vcpu *vcpu) | 73 | typedef u8 __bitwise ar_t; |
74 | |||
75 | static inline u64 kvm_s390_get_base_disp_s(struct kvm_vcpu *vcpu, ar_t *ar) | ||
74 | { | 76 | { |
75 | u32 base2 = vcpu->arch.sie_block->ipb >> 28; | 77 | u32 base2 = vcpu->arch.sie_block->ipb >> 28; |
76 | u32 disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16); | 78 | u32 disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16); |
77 | 79 | ||
80 | if (ar) | ||
81 | *ar = base2; | ||
82 | |||
78 | return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2; | 83 | return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2; |
79 | } | 84 | } |
80 | 85 | ||
81 | static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu, | 86 | static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu, |
82 | u64 *address1, u64 *address2) | 87 | u64 *address1, u64 *address2, |
88 | ar_t *ar_b1, ar_t *ar_b2) | ||
83 | { | 89 | { |
84 | u32 base1 = (vcpu->arch.sie_block->ipb & 0xf0000000) >> 28; | 90 | u32 base1 = (vcpu->arch.sie_block->ipb & 0xf0000000) >> 28; |
85 | u32 disp1 = (vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16; | 91 | u32 disp1 = (vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16; |
@@ -88,6 +94,11 @@ static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu, | |||
88 | 94 | ||
89 | *address1 = (base1 ? vcpu->run->s.regs.gprs[base1] : 0) + disp1; | 95 | *address1 = (base1 ? vcpu->run->s.regs.gprs[base1] : 0) + disp1; |
90 | *address2 = (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2; | 96 | *address2 = (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2; |
97 | |||
98 | if (ar_b1) | ||
99 | *ar_b1 = base1; | ||
100 | if (ar_b2) | ||
101 | *ar_b2 = base2; | ||
91 | } | 102 | } |
92 | 103 | ||
93 | static inline void kvm_s390_get_regs_rre(struct kvm_vcpu *vcpu, int *r1, int *r2) | 104 | static inline void kvm_s390_get_regs_rre(struct kvm_vcpu *vcpu, int *r1, int *r2) |
@@ -98,7 +109,7 @@ static inline void kvm_s390_get_regs_rre(struct kvm_vcpu *vcpu, int *r1, int *r2 | |||
98 | *r2 = (vcpu->arch.sie_block->ipb & 0x000f0000) >> 16; | 109 | *r2 = (vcpu->arch.sie_block->ipb & 0x000f0000) >> 16; |
99 | } | 110 | } |
100 | 111 | ||
101 | static inline u64 kvm_s390_get_base_disp_rsy(struct kvm_vcpu *vcpu) | 112 | static inline u64 kvm_s390_get_base_disp_rsy(struct kvm_vcpu *vcpu, ar_t *ar) |
102 | { | 113 | { |
103 | u32 base2 = vcpu->arch.sie_block->ipb >> 28; | 114 | u32 base2 = vcpu->arch.sie_block->ipb >> 28; |
104 | u32 disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16) + | 115 | u32 disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16) + |
@@ -107,14 +118,20 @@ static inline u64 kvm_s390_get_base_disp_rsy(struct kvm_vcpu *vcpu) | |||
107 | if (disp2 & 0x80000) | 118 | if (disp2 & 0x80000) |
108 | disp2+=0xfff00000; | 119 | disp2+=0xfff00000; |
109 | 120 | ||
121 | if (ar) | ||
122 | *ar = base2; | ||
123 | |||
110 | return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + (long)(int)disp2; | 124 | return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + (long)(int)disp2; |
111 | } | 125 | } |
112 | 126 | ||
113 | static inline u64 kvm_s390_get_base_disp_rs(struct kvm_vcpu *vcpu) | 127 | static inline u64 kvm_s390_get_base_disp_rs(struct kvm_vcpu *vcpu, ar_t *ar) |
114 | { | 128 | { |
115 | u32 base2 = vcpu->arch.sie_block->ipb >> 28; | 129 | u32 base2 = vcpu->arch.sie_block->ipb >> 28; |
116 | u32 disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16); | 130 | u32 disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16); |
117 | 131 | ||
132 | if (ar) | ||
133 | *ar = base2; | ||
134 | |||
118 | return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2; | 135 | return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2; |
119 | } | 136 | } |
120 | 137 | ||
@@ -125,10 +142,22 @@ static inline void kvm_s390_set_psw_cc(struct kvm_vcpu *vcpu, unsigned long cc) | |||
125 | vcpu->arch.sie_block->gpsw.mask |= cc << 44; | 142 | vcpu->arch.sie_block->gpsw.mask |= cc << 44; |
126 | } | 143 | } |
127 | 144 | ||
128 | /* test availability of facility in a kvm intance */ | 145 | /* test availability of facility in a kvm instance */ |
129 | static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr) | 146 | static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr) |
130 | { | 147 | { |
131 | return __test_facility(nr, kvm->arch.model.fac->kvm); | 148 | return __test_facility(nr, kvm->arch.model.fac->mask) && |
149 | __test_facility(nr, kvm->arch.model.fac->list); | ||
150 | } | ||
151 | |||
152 | static inline int set_kvm_facility(u64 *fac_list, unsigned long nr) | ||
153 | { | ||
154 | unsigned char *ptr; | ||
155 | |||
156 | if (nr >= MAX_FACILITY_BIT) | ||
157 | return -EINVAL; | ||
158 | ptr = (unsigned char *) fac_list + (nr >> 3); | ||
159 | *ptr |= (0x80UL >> (nr & 7)); | ||
160 | return 0; | ||
132 | } | 161 | } |
133 | 162 | ||
134 | /* are cpu states controlled by user space */ | 163 | /* are cpu states controlled by user space */ |
@@ -149,9 +178,9 @@ int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, | |||
149 | struct kvm_s390_irq *irq); | 178 | struct kvm_s390_irq *irq); |
150 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); | 179 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); |
151 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, | 180 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, |
152 | u64 cr6, u64 schid); | 181 | u64 isc_mask, u32 schid); |
153 | void kvm_s390_reinject_io_int(struct kvm *kvm, | 182 | int kvm_s390_reinject_io_int(struct kvm *kvm, |
154 | struct kvm_s390_interrupt_info *inti); | 183 | struct kvm_s390_interrupt_info *inti); |
155 | int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked); | 184 | int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked); |
156 | 185 | ||
157 | /* implemented in intercept.c */ | 186 | /* implemented in intercept.c */ |
@@ -176,7 +205,10 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu); | |||
176 | /* implemented in kvm-s390.c */ | 205 | /* implemented in kvm-s390.c */ |
177 | long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); | 206 | long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); |
178 | int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); | 207 | int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); |
208 | int kvm_s390_store_adtl_status_unloaded(struct kvm_vcpu *vcpu, | ||
209 | unsigned long addr); | ||
179 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr); | 210 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr); |
211 | int kvm_s390_vcpu_store_adtl_status(struct kvm_vcpu *vcpu, unsigned long addr); | ||
180 | void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); | 212 | void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); |
181 | void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu); | 213 | void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu); |
182 | void s390_vcpu_block(struct kvm_vcpu *vcpu); | 214 | void s390_vcpu_block(struct kvm_vcpu *vcpu); |
@@ -240,6 +272,10 @@ int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu); | |||
240 | extern struct kvm_device_ops kvm_flic_ops; | 272 | extern struct kvm_device_ops kvm_flic_ops; |
241 | int kvm_s390_is_stop_irq_pending(struct kvm_vcpu *vcpu); | 273 | int kvm_s390_is_stop_irq_pending(struct kvm_vcpu *vcpu); |
242 | void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu); | 274 | void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu); |
275 | int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, | ||
276 | void __user *buf, int len); | ||
277 | int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu, | ||
278 | __u8 __user *buf, int len); | ||
243 | 279 | ||
244 | /* implemented in guestdbg.c */ | 280 | /* implemented in guestdbg.c */ |
245 | void kvm_s390_backup_guest_per_regs(struct kvm_vcpu *vcpu); | 281 | void kvm_s390_backup_guest_per_regs(struct kvm_vcpu *vcpu); |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index bdd9b5b17e03..d22d8ee1ff9d 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -36,15 +36,16 @@ static int handle_set_clock(struct kvm_vcpu *vcpu) | |||
36 | struct kvm_vcpu *cpup; | 36 | struct kvm_vcpu *cpup; |
37 | s64 hostclk, val; | 37 | s64 hostclk, val; |
38 | int i, rc; | 38 | int i, rc; |
39 | ar_t ar; | ||
39 | u64 op2; | 40 | u64 op2; |
40 | 41 | ||
41 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 42 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
42 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 43 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
43 | 44 | ||
44 | op2 = kvm_s390_get_base_disp_s(vcpu); | 45 | op2 = kvm_s390_get_base_disp_s(vcpu, &ar); |
45 | if (op2 & 7) /* Operand must be on a doubleword boundary */ | 46 | if (op2 & 7) /* Operand must be on a doubleword boundary */ |
46 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 47 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
47 | rc = read_guest(vcpu, op2, &val, sizeof(val)); | 48 | rc = read_guest(vcpu, op2, ar, &val, sizeof(val)); |
48 | if (rc) | 49 | if (rc) |
49 | return kvm_s390_inject_prog_cond(vcpu, rc); | 50 | return kvm_s390_inject_prog_cond(vcpu, rc); |
50 | 51 | ||
@@ -68,20 +69,21 @@ static int handle_set_prefix(struct kvm_vcpu *vcpu) | |||
68 | u64 operand2; | 69 | u64 operand2; |
69 | u32 address; | 70 | u32 address; |
70 | int rc; | 71 | int rc; |
72 | ar_t ar; | ||
71 | 73 | ||
72 | vcpu->stat.instruction_spx++; | 74 | vcpu->stat.instruction_spx++; |
73 | 75 | ||
74 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 76 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
75 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 77 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
76 | 78 | ||
77 | operand2 = kvm_s390_get_base_disp_s(vcpu); | 79 | operand2 = kvm_s390_get_base_disp_s(vcpu, &ar); |
78 | 80 | ||
79 | /* must be word boundary */ | 81 | /* must be word boundary */ |
80 | if (operand2 & 3) | 82 | if (operand2 & 3) |
81 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 83 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
82 | 84 | ||
83 | /* get the value */ | 85 | /* get the value */ |
84 | rc = read_guest(vcpu, operand2, &address, sizeof(address)); | 86 | rc = read_guest(vcpu, operand2, ar, &address, sizeof(address)); |
85 | if (rc) | 87 | if (rc) |
86 | return kvm_s390_inject_prog_cond(vcpu, rc); | 88 | return kvm_s390_inject_prog_cond(vcpu, rc); |
87 | 89 | ||
@@ -107,13 +109,14 @@ static int handle_store_prefix(struct kvm_vcpu *vcpu) | |||
107 | u64 operand2; | 109 | u64 operand2; |
108 | u32 address; | 110 | u32 address; |
109 | int rc; | 111 | int rc; |
112 | ar_t ar; | ||
110 | 113 | ||
111 | vcpu->stat.instruction_stpx++; | 114 | vcpu->stat.instruction_stpx++; |
112 | 115 | ||
113 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 116 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
114 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 117 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
115 | 118 | ||
116 | operand2 = kvm_s390_get_base_disp_s(vcpu); | 119 | operand2 = kvm_s390_get_base_disp_s(vcpu, &ar); |
117 | 120 | ||
118 | /* must be word boundary */ | 121 | /* must be word boundary */ |
119 | if (operand2 & 3) | 122 | if (operand2 & 3) |
@@ -122,7 +125,7 @@ static int handle_store_prefix(struct kvm_vcpu *vcpu) | |||
122 | address = kvm_s390_get_prefix(vcpu); | 125 | address = kvm_s390_get_prefix(vcpu); |
123 | 126 | ||
124 | /* get the value */ | 127 | /* get the value */ |
125 | rc = write_guest(vcpu, operand2, &address, sizeof(address)); | 128 | rc = write_guest(vcpu, operand2, ar, &address, sizeof(address)); |
126 | if (rc) | 129 | if (rc) |
127 | return kvm_s390_inject_prog_cond(vcpu, rc); | 130 | return kvm_s390_inject_prog_cond(vcpu, rc); |
128 | 131 | ||
@@ -136,18 +139,19 @@ static int handle_store_cpu_address(struct kvm_vcpu *vcpu) | |||
136 | u16 vcpu_id = vcpu->vcpu_id; | 139 | u16 vcpu_id = vcpu->vcpu_id; |
137 | u64 ga; | 140 | u64 ga; |
138 | int rc; | 141 | int rc; |
142 | ar_t ar; | ||
139 | 143 | ||
140 | vcpu->stat.instruction_stap++; | 144 | vcpu->stat.instruction_stap++; |
141 | 145 | ||
142 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 146 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
143 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 147 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
144 | 148 | ||
145 | ga = kvm_s390_get_base_disp_s(vcpu); | 149 | ga = kvm_s390_get_base_disp_s(vcpu, &ar); |
146 | 150 | ||
147 | if (ga & 1) | 151 | if (ga & 1) |
148 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 152 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
149 | 153 | ||
150 | rc = write_guest(vcpu, ga, &vcpu_id, sizeof(vcpu_id)); | 154 | rc = write_guest(vcpu, ga, ar, &vcpu_id, sizeof(vcpu_id)); |
151 | if (rc) | 155 | if (rc) |
152 | return kvm_s390_inject_prog_cond(vcpu, rc); | 156 | return kvm_s390_inject_prog_cond(vcpu, rc); |
153 | 157 | ||
@@ -207,7 +211,7 @@ static int handle_test_block(struct kvm_vcpu *vcpu) | |||
207 | kvm_s390_get_regs_rre(vcpu, NULL, ®2); | 211 | kvm_s390_get_regs_rre(vcpu, NULL, ®2); |
208 | addr = vcpu->run->s.regs.gprs[reg2] & PAGE_MASK; | 212 | addr = vcpu->run->s.regs.gprs[reg2] & PAGE_MASK; |
209 | addr = kvm_s390_logical_to_effective(vcpu, addr); | 213 | addr = kvm_s390_logical_to_effective(vcpu, addr); |
210 | if (kvm_s390_check_low_addr_protection(vcpu, addr)) | 214 | if (kvm_s390_check_low_addr_prot_real(vcpu, addr)) |
211 | return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); | 215 | return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); |
212 | addr = kvm_s390_real_to_abs(vcpu, addr); | 216 | addr = kvm_s390_real_to_abs(vcpu, addr); |
213 | 217 | ||
@@ -229,18 +233,20 @@ static int handle_tpi(struct kvm_vcpu *vcpu) | |||
229 | struct kvm_s390_interrupt_info *inti; | 233 | struct kvm_s390_interrupt_info *inti; |
230 | unsigned long len; | 234 | unsigned long len; |
231 | u32 tpi_data[3]; | 235 | u32 tpi_data[3]; |
232 | int cc, rc; | 236 | int rc; |
233 | u64 addr; | 237 | u64 addr; |
238 | ar_t ar; | ||
234 | 239 | ||
235 | rc = 0; | 240 | addr = kvm_s390_get_base_disp_s(vcpu, &ar); |
236 | addr = kvm_s390_get_base_disp_s(vcpu); | ||
237 | if (addr & 3) | 241 | if (addr & 3) |
238 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 242 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
239 | cc = 0; | 243 | |
240 | inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->arch.sie_block->gcr[6], 0); | 244 | inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->arch.sie_block->gcr[6], 0); |
241 | if (!inti) | 245 | if (!inti) { |
242 | goto no_interrupt; | 246 | kvm_s390_set_psw_cc(vcpu, 0); |
243 | cc = 1; | 247 | return 0; |
248 | } | ||
249 | |||
244 | tpi_data[0] = inti->io.subchannel_id << 16 | inti->io.subchannel_nr; | 250 | tpi_data[0] = inti->io.subchannel_id << 16 | inti->io.subchannel_nr; |
245 | tpi_data[1] = inti->io.io_int_parm; | 251 | tpi_data[1] = inti->io.io_int_parm; |
246 | tpi_data[2] = inti->io.io_int_word; | 252 | tpi_data[2] = inti->io.io_int_word; |
@@ -250,40 +256,51 @@ static int handle_tpi(struct kvm_vcpu *vcpu) | |||
250 | * provided area. | 256 | * provided area. |
251 | */ | 257 | */ |
252 | len = sizeof(tpi_data) - 4; | 258 | len = sizeof(tpi_data) - 4; |
253 | rc = write_guest(vcpu, addr, &tpi_data, len); | 259 | rc = write_guest(vcpu, addr, ar, &tpi_data, len); |
254 | if (rc) | 260 | if (rc) { |
255 | return kvm_s390_inject_prog_cond(vcpu, rc); | 261 | rc = kvm_s390_inject_prog_cond(vcpu, rc); |
262 | goto reinject_interrupt; | ||
263 | } | ||
256 | } else { | 264 | } else { |
257 | /* | 265 | /* |
258 | * Store the three-word I/O interruption code into | 266 | * Store the three-word I/O interruption code into |
259 | * the appropriate lowcore area. | 267 | * the appropriate lowcore area. |
260 | */ | 268 | */ |
261 | len = sizeof(tpi_data); | 269 | len = sizeof(tpi_data); |
262 | if (write_guest_lc(vcpu, __LC_SUBCHANNEL_ID, &tpi_data, len)) | 270 | if (write_guest_lc(vcpu, __LC_SUBCHANNEL_ID, &tpi_data, len)) { |
271 | /* failed writes to the low core are not recoverable */ | ||
263 | rc = -EFAULT; | 272 | rc = -EFAULT; |
273 | goto reinject_interrupt; | ||
274 | } | ||
264 | } | 275 | } |
276 | |||
277 | /* irq was successfully handed to the guest */ | ||
278 | kfree(inti); | ||
279 | kvm_s390_set_psw_cc(vcpu, 1); | ||
280 | return 0; | ||
281 | reinject_interrupt: | ||
265 | /* | 282 | /* |
266 | * If we encounter a problem storing the interruption code, the | 283 | * If we encounter a problem storing the interruption code, the |
267 | * instruction is suppressed from the guest's view: reinject the | 284 | * instruction is suppressed from the guest's view: reinject the |
268 | * interrupt. | 285 | * interrupt. |
269 | */ | 286 | */ |
270 | if (!rc) | 287 | if (kvm_s390_reinject_io_int(vcpu->kvm, inti)) { |
271 | kfree(inti); | 288 | kfree(inti); |
272 | else | 289 | rc = -EFAULT; |
273 | kvm_s390_reinject_io_int(vcpu->kvm, inti); | 290 | } |
274 | no_interrupt: | 291 | /* don't set the cc, a pgm irq was injected or we drop to user space */ |
275 | /* Set condition code and we're done. */ | ||
276 | if (!rc) | ||
277 | kvm_s390_set_psw_cc(vcpu, cc); | ||
278 | return rc ? -EFAULT : 0; | 292 | return rc ? -EFAULT : 0; |
279 | } | 293 | } |
280 | 294 | ||
281 | static int handle_tsch(struct kvm_vcpu *vcpu) | 295 | static int handle_tsch(struct kvm_vcpu *vcpu) |
282 | { | 296 | { |
283 | struct kvm_s390_interrupt_info *inti; | 297 | struct kvm_s390_interrupt_info *inti = NULL; |
298 | const u64 isc_mask = 0xffUL << 24; /* all iscs set */ | ||
284 | 299 | ||
285 | inti = kvm_s390_get_io_int(vcpu->kvm, 0, | 300 | /* a valid schid has at least one bit set */ |
286 | vcpu->run->s.regs.gprs[1]); | 301 | if (vcpu->run->s.regs.gprs[1]) |
302 | inti = kvm_s390_get_io_int(vcpu->kvm, isc_mask, | ||
303 | vcpu->run->s.regs.gprs[1]); | ||
287 | 304 | ||
288 | /* | 305 | /* |
289 | * Prepare exit to userspace. | 306 | * Prepare exit to userspace. |
@@ -348,7 +365,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) | |||
348 | * We need to shift the lower 32 facility bits (bit 0-31) from a u64 | 365 | * We need to shift the lower 32 facility bits (bit 0-31) from a u64 |
349 | * into a u32 memory representation. They will remain bits 0-31. | 366 | * into a u32 memory representation. They will remain bits 0-31. |
350 | */ | 367 | */ |
351 | fac = *vcpu->kvm->arch.model.fac->sie >> 32; | 368 | fac = *vcpu->kvm->arch.model.fac->list >> 32; |
352 | rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), | 369 | rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), |
353 | &fac, sizeof(fac)); | 370 | &fac, sizeof(fac)); |
354 | if (rc) | 371 | if (rc) |
@@ -386,15 +403,16 @@ int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu) | |||
386 | psw_compat_t new_psw; | 403 | psw_compat_t new_psw; |
387 | u64 addr; | 404 | u64 addr; |
388 | int rc; | 405 | int rc; |
406 | ar_t ar; | ||
389 | 407 | ||
390 | if (gpsw->mask & PSW_MASK_PSTATE) | 408 | if (gpsw->mask & PSW_MASK_PSTATE) |
391 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 409 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
392 | 410 | ||
393 | addr = kvm_s390_get_base_disp_s(vcpu); | 411 | addr = kvm_s390_get_base_disp_s(vcpu, &ar); |
394 | if (addr & 7) | 412 | if (addr & 7) |
395 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 413 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
396 | 414 | ||
397 | rc = read_guest(vcpu, addr, &new_psw, sizeof(new_psw)); | 415 | rc = read_guest(vcpu, addr, ar, &new_psw, sizeof(new_psw)); |
398 | if (rc) | 416 | if (rc) |
399 | return kvm_s390_inject_prog_cond(vcpu, rc); | 417 | return kvm_s390_inject_prog_cond(vcpu, rc); |
400 | if (!(new_psw.mask & PSW32_MASK_BASE)) | 418 | if (!(new_psw.mask & PSW32_MASK_BASE)) |
@@ -412,14 +430,15 @@ static int handle_lpswe(struct kvm_vcpu *vcpu) | |||
412 | psw_t new_psw; | 430 | psw_t new_psw; |
413 | u64 addr; | 431 | u64 addr; |
414 | int rc; | 432 | int rc; |
433 | ar_t ar; | ||
415 | 434 | ||
416 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 435 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
417 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 436 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
418 | 437 | ||
419 | addr = kvm_s390_get_base_disp_s(vcpu); | 438 | addr = kvm_s390_get_base_disp_s(vcpu, &ar); |
420 | if (addr & 7) | 439 | if (addr & 7) |
421 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 440 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
422 | rc = read_guest(vcpu, addr, &new_psw, sizeof(new_psw)); | 441 | rc = read_guest(vcpu, addr, ar, &new_psw, sizeof(new_psw)); |
423 | if (rc) | 442 | if (rc) |
424 | return kvm_s390_inject_prog_cond(vcpu, rc); | 443 | return kvm_s390_inject_prog_cond(vcpu, rc); |
425 | vcpu->arch.sie_block->gpsw = new_psw; | 444 | vcpu->arch.sie_block->gpsw = new_psw; |
@@ -433,18 +452,19 @@ static int handle_stidp(struct kvm_vcpu *vcpu) | |||
433 | u64 stidp_data = vcpu->arch.stidp_data; | 452 | u64 stidp_data = vcpu->arch.stidp_data; |
434 | u64 operand2; | 453 | u64 operand2; |
435 | int rc; | 454 | int rc; |
455 | ar_t ar; | ||
436 | 456 | ||
437 | vcpu->stat.instruction_stidp++; | 457 | vcpu->stat.instruction_stidp++; |
438 | 458 | ||
439 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 459 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
440 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 460 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
441 | 461 | ||
442 | operand2 = kvm_s390_get_base_disp_s(vcpu); | 462 | operand2 = kvm_s390_get_base_disp_s(vcpu, &ar); |
443 | 463 | ||
444 | if (operand2 & 7) | 464 | if (operand2 & 7) |
445 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 465 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
446 | 466 | ||
447 | rc = write_guest(vcpu, operand2, &stidp_data, sizeof(stidp_data)); | 467 | rc = write_guest(vcpu, operand2, ar, &stidp_data, sizeof(stidp_data)); |
448 | if (rc) | 468 | if (rc) |
449 | return kvm_s390_inject_prog_cond(vcpu, rc); | 469 | return kvm_s390_inject_prog_cond(vcpu, rc); |
450 | 470 | ||
@@ -467,6 +487,7 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem) | |||
467 | for (n = mem->count - 1; n > 0 ; n--) | 487 | for (n = mem->count - 1; n > 0 ; n--) |
468 | memcpy(&mem->vm[n], &mem->vm[n - 1], sizeof(mem->vm[0])); | 488 | memcpy(&mem->vm[n], &mem->vm[n - 1], sizeof(mem->vm[0])); |
469 | 489 | ||
490 | memset(&mem->vm[0], 0, sizeof(mem->vm[0])); | ||
470 | mem->vm[0].cpus_total = cpus; | 491 | mem->vm[0].cpus_total = cpus; |
471 | mem->vm[0].cpus_configured = cpus; | 492 | mem->vm[0].cpus_configured = cpus; |
472 | mem->vm[0].cpus_standby = 0; | 493 | mem->vm[0].cpus_standby = 0; |
@@ -478,6 +499,17 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem) | |||
478 | ASCEBC(mem->vm[0].cpi, 16); | 499 | ASCEBC(mem->vm[0].cpi, 16); |
479 | } | 500 | } |
480 | 501 | ||
502 | static void insert_stsi_usr_data(struct kvm_vcpu *vcpu, u64 addr, ar_t ar, | ||
503 | u8 fc, u8 sel1, u16 sel2) | ||
504 | { | ||
505 | vcpu->run->exit_reason = KVM_EXIT_S390_STSI; | ||
506 | vcpu->run->s390_stsi.addr = addr; | ||
507 | vcpu->run->s390_stsi.ar = ar; | ||
508 | vcpu->run->s390_stsi.fc = fc; | ||
509 | vcpu->run->s390_stsi.sel1 = sel1; | ||
510 | vcpu->run->s390_stsi.sel2 = sel2; | ||
511 | } | ||
512 | |||
481 | static int handle_stsi(struct kvm_vcpu *vcpu) | 513 | static int handle_stsi(struct kvm_vcpu *vcpu) |
482 | { | 514 | { |
483 | int fc = (vcpu->run->s.regs.gprs[0] & 0xf0000000) >> 28; | 515 | int fc = (vcpu->run->s.regs.gprs[0] & 0xf0000000) >> 28; |
@@ -486,6 +518,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu) | |||
486 | unsigned long mem = 0; | 518 | unsigned long mem = 0; |
487 | u64 operand2; | 519 | u64 operand2; |
488 | int rc = 0; | 520 | int rc = 0; |
521 | ar_t ar; | ||
489 | 522 | ||
490 | vcpu->stat.instruction_stsi++; | 523 | vcpu->stat.instruction_stsi++; |
491 | VCPU_EVENT(vcpu, 4, "stsi: fc: %x sel1: %x sel2: %x", fc, sel1, sel2); | 524 | VCPU_EVENT(vcpu, 4, "stsi: fc: %x sel1: %x sel2: %x", fc, sel1, sel2); |
@@ -508,7 +541,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu) | |||
508 | return 0; | 541 | return 0; |
509 | } | 542 | } |
510 | 543 | ||
511 | operand2 = kvm_s390_get_base_disp_s(vcpu); | 544 | operand2 = kvm_s390_get_base_disp_s(vcpu, &ar); |
512 | 545 | ||
513 | if (operand2 & 0xfff) | 546 | if (operand2 & 0xfff) |
514 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 547 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
@@ -532,16 +565,20 @@ static int handle_stsi(struct kvm_vcpu *vcpu) | |||
532 | break; | 565 | break; |
533 | } | 566 | } |
534 | 567 | ||
535 | rc = write_guest(vcpu, operand2, (void *)mem, PAGE_SIZE); | 568 | rc = write_guest(vcpu, operand2, ar, (void *)mem, PAGE_SIZE); |
536 | if (rc) { | 569 | if (rc) { |
537 | rc = kvm_s390_inject_prog_cond(vcpu, rc); | 570 | rc = kvm_s390_inject_prog_cond(vcpu, rc); |
538 | goto out; | 571 | goto out; |
539 | } | 572 | } |
573 | if (vcpu->kvm->arch.user_stsi) { | ||
574 | insert_stsi_usr_data(vcpu, operand2, ar, fc, sel1, sel2); | ||
575 | rc = -EREMOTE; | ||
576 | } | ||
540 | trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2); | 577 | trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2); |
541 | free_page(mem); | 578 | free_page(mem); |
542 | kvm_s390_set_psw_cc(vcpu, 0); | 579 | kvm_s390_set_psw_cc(vcpu, 0); |
543 | vcpu->run->s.regs.gprs[0] = 0; | 580 | vcpu->run->s.regs.gprs[0] = 0; |
544 | return 0; | 581 | return rc; |
545 | out_no_data: | 582 | out_no_data: |
546 | kvm_s390_set_psw_cc(vcpu, 3); | 583 | kvm_s390_set_psw_cc(vcpu, 3); |
547 | out: | 584 | out: |
@@ -670,7 +707,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) | |||
670 | } | 707 | } |
671 | 708 | ||
672 | if (vcpu->run->s.regs.gprs[reg1] & PFMF_CF) { | 709 | if (vcpu->run->s.regs.gprs[reg1] & PFMF_CF) { |
673 | if (kvm_s390_check_low_addr_protection(vcpu, start)) | 710 | if (kvm_s390_check_low_addr_prot_real(vcpu, start)) |
674 | return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); | 711 | return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); |
675 | } | 712 | } |
676 | 713 | ||
@@ -776,13 +813,14 @@ int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu) | |||
776 | int reg, rc, nr_regs; | 813 | int reg, rc, nr_regs; |
777 | u32 ctl_array[16]; | 814 | u32 ctl_array[16]; |
778 | u64 ga; | 815 | u64 ga; |
816 | ar_t ar; | ||
779 | 817 | ||
780 | vcpu->stat.instruction_lctl++; | 818 | vcpu->stat.instruction_lctl++; |
781 | 819 | ||
782 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 820 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
783 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 821 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
784 | 822 | ||
785 | ga = kvm_s390_get_base_disp_rs(vcpu); | 823 | ga = kvm_s390_get_base_disp_rs(vcpu, &ar); |
786 | 824 | ||
787 | if (ga & 3) | 825 | if (ga & 3) |
788 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 826 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
@@ -791,7 +829,7 @@ int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu) | |||
791 | trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, ga); | 829 | trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, ga); |
792 | 830 | ||
793 | nr_regs = ((reg3 - reg1) & 0xf) + 1; | 831 | nr_regs = ((reg3 - reg1) & 0xf) + 1; |
794 | rc = read_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u32)); | 832 | rc = read_guest(vcpu, ga, ar, ctl_array, nr_regs * sizeof(u32)); |
795 | if (rc) | 833 | if (rc) |
796 | return kvm_s390_inject_prog_cond(vcpu, rc); | 834 | return kvm_s390_inject_prog_cond(vcpu, rc); |
797 | reg = reg1; | 835 | reg = reg1; |
@@ -814,13 +852,14 @@ int kvm_s390_handle_stctl(struct kvm_vcpu *vcpu) | |||
814 | int reg, rc, nr_regs; | 852 | int reg, rc, nr_regs; |
815 | u32 ctl_array[16]; | 853 | u32 ctl_array[16]; |
816 | u64 ga; | 854 | u64 ga; |
855 | ar_t ar; | ||
817 | 856 | ||
818 | vcpu->stat.instruction_stctl++; | 857 | vcpu->stat.instruction_stctl++; |
819 | 858 | ||
820 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 859 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
821 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 860 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
822 | 861 | ||
823 | ga = kvm_s390_get_base_disp_rs(vcpu); | 862 | ga = kvm_s390_get_base_disp_rs(vcpu, &ar); |
824 | 863 | ||
825 | if (ga & 3) | 864 | if (ga & 3) |
826 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 865 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
@@ -836,7 +875,7 @@ int kvm_s390_handle_stctl(struct kvm_vcpu *vcpu) | |||
836 | break; | 875 | break; |
837 | reg = (reg + 1) % 16; | 876 | reg = (reg + 1) % 16; |
838 | } while (1); | 877 | } while (1); |
839 | rc = write_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u32)); | 878 | rc = write_guest(vcpu, ga, ar, ctl_array, nr_regs * sizeof(u32)); |
840 | return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0; | 879 | return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0; |
841 | } | 880 | } |
842 | 881 | ||
@@ -847,13 +886,14 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) | |||
847 | int reg, rc, nr_regs; | 886 | int reg, rc, nr_regs; |
848 | u64 ctl_array[16]; | 887 | u64 ctl_array[16]; |
849 | u64 ga; | 888 | u64 ga; |
889 | ar_t ar; | ||
850 | 890 | ||
851 | vcpu->stat.instruction_lctlg++; | 891 | vcpu->stat.instruction_lctlg++; |
852 | 892 | ||
853 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 893 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
854 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 894 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
855 | 895 | ||
856 | ga = kvm_s390_get_base_disp_rsy(vcpu); | 896 | ga = kvm_s390_get_base_disp_rsy(vcpu, &ar); |
857 | 897 | ||
858 | if (ga & 7) | 898 | if (ga & 7) |
859 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 899 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
@@ -862,7 +902,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) | |||
862 | trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, ga); | 902 | trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, ga); |
863 | 903 | ||
864 | nr_regs = ((reg3 - reg1) & 0xf) + 1; | 904 | nr_regs = ((reg3 - reg1) & 0xf) + 1; |
865 | rc = read_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u64)); | 905 | rc = read_guest(vcpu, ga, ar, ctl_array, nr_regs * sizeof(u64)); |
866 | if (rc) | 906 | if (rc) |
867 | return kvm_s390_inject_prog_cond(vcpu, rc); | 907 | return kvm_s390_inject_prog_cond(vcpu, rc); |
868 | reg = reg1; | 908 | reg = reg1; |
@@ -884,13 +924,14 @@ static int handle_stctg(struct kvm_vcpu *vcpu) | |||
884 | int reg, rc, nr_regs; | 924 | int reg, rc, nr_regs; |
885 | u64 ctl_array[16]; | 925 | u64 ctl_array[16]; |
886 | u64 ga; | 926 | u64 ga; |
927 | ar_t ar; | ||
887 | 928 | ||
888 | vcpu->stat.instruction_stctg++; | 929 | vcpu->stat.instruction_stctg++; |
889 | 930 | ||
890 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 931 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
891 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 932 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
892 | 933 | ||
893 | ga = kvm_s390_get_base_disp_rsy(vcpu); | 934 | ga = kvm_s390_get_base_disp_rsy(vcpu, &ar); |
894 | 935 | ||
895 | if (ga & 7) | 936 | if (ga & 7) |
896 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 937 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
@@ -906,7 +947,7 @@ static int handle_stctg(struct kvm_vcpu *vcpu) | |||
906 | break; | 947 | break; |
907 | reg = (reg + 1) % 16; | 948 | reg = (reg + 1) % 16; |
908 | } while (1); | 949 | } while (1); |
909 | rc = write_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u64)); | 950 | rc = write_guest(vcpu, ga, ar, ctl_array, nr_regs * sizeof(u64)); |
910 | return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0; | 951 | return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0; |
911 | } | 952 | } |
912 | 953 | ||
@@ -931,13 +972,14 @@ static int handle_tprot(struct kvm_vcpu *vcpu) | |||
931 | unsigned long hva, gpa; | 972 | unsigned long hva, gpa; |
932 | int ret = 0, cc = 0; | 973 | int ret = 0, cc = 0; |
933 | bool writable; | 974 | bool writable; |
975 | ar_t ar; | ||
934 | 976 | ||
935 | vcpu->stat.instruction_tprot++; | 977 | vcpu->stat.instruction_tprot++; |
936 | 978 | ||
937 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 979 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
938 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 980 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
939 | 981 | ||
940 | kvm_s390_get_base_disp_sse(vcpu, &address1, &address2); | 982 | kvm_s390_get_base_disp_sse(vcpu, &address1, &address2, &ar, NULL); |
941 | 983 | ||
942 | /* we only handle the Linux memory detection case: | 984 | /* we only handle the Linux memory detection case: |
943 | * access key == 0 | 985 | * access key == 0 |
@@ -946,11 +988,11 @@ static int handle_tprot(struct kvm_vcpu *vcpu) | |||
946 | return -EOPNOTSUPP; | 988 | return -EOPNOTSUPP; |
947 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT) | 989 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT) |
948 | ipte_lock(vcpu); | 990 | ipte_lock(vcpu); |
949 | ret = guest_translate_address(vcpu, address1, &gpa, 1); | 991 | ret = guest_translate_address(vcpu, address1, ar, &gpa, 1); |
950 | if (ret == PGM_PROTECTION) { | 992 | if (ret == PGM_PROTECTION) { |
951 | /* Write protected? Try again with read-only... */ | 993 | /* Write protected? Try again with read-only... */ |
952 | cc = 1; | 994 | cc = 1; |
953 | ret = guest_translate_address(vcpu, address1, &gpa, 0); | 995 | ret = guest_translate_address(vcpu, address1, ar, &gpa, 0); |
954 | } | 996 | } |
955 | if (ret) { | 997 | if (ret) { |
956 | if (ret == PGM_ADDRESSING || ret == PGM_TRANSLATION_SPEC) { | 998 | if (ret == PGM_ADDRESSING || ret == PGM_TRANSLATION_SPEC) { |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 23b1e86b2122..72e58bd2bee7 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
@@ -393,6 +393,9 @@ static int handle_sigp_order_in_user_space(struct kvm_vcpu *vcpu, u8 order_code) | |||
393 | case SIGP_STORE_STATUS_AT_ADDRESS: | 393 | case SIGP_STORE_STATUS_AT_ADDRESS: |
394 | vcpu->stat.instruction_sigp_store_status++; | 394 | vcpu->stat.instruction_sigp_store_status++; |
395 | break; | 395 | break; |
396 | case SIGP_STORE_ADDITIONAL_STATUS: | ||
397 | vcpu->stat.instruction_sigp_store_adtl_status++; | ||
398 | break; | ||
396 | case SIGP_SET_PREFIX: | 399 | case SIGP_SET_PREFIX: |
397 | vcpu->stat.instruction_sigp_prefix++; | 400 | vcpu->stat.instruction_sigp_prefix++; |
398 | break; | 401 | break; |
@@ -431,7 +434,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | |||
431 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 434 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
432 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 435 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
433 | 436 | ||
434 | order_code = kvm_s390_get_base_disp_rs(vcpu); | 437 | order_code = kvm_s390_get_base_disp_rs(vcpu, NULL); |
435 | if (handle_sigp_order_in_user_space(vcpu, order_code)) | 438 | if (handle_sigp_order_in_user_space(vcpu, order_code)) |
436 | return -EOPNOTSUPP; | 439 | return -EOPNOTSUPP; |
437 | 440 | ||
@@ -473,7 +476,7 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu) | |||
473 | int r3 = vcpu->arch.sie_block->ipa & 0x000f; | 476 | int r3 = vcpu->arch.sie_block->ipa & 0x000f; |
474 | u16 cpu_addr = vcpu->run->s.regs.gprs[r3]; | 477 | u16 cpu_addr = vcpu->run->s.regs.gprs[r3]; |
475 | struct kvm_vcpu *dest_vcpu; | 478 | struct kvm_vcpu *dest_vcpu; |
476 | u8 order_code = kvm_s390_get_base_disp_rs(vcpu); | 479 | u8 order_code = kvm_s390_get_base_disp_rs(vcpu, NULL); |
477 | 480 | ||
478 | trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); | 481 | trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); |
479 | 482 | ||
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 753a56731951..f0b85443e060 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -287,7 +287,7 @@ void __iomem *pci_iomap_range(struct pci_dev *pdev, | |||
287 | addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48); | 287 | addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48); |
288 | return (void __iomem *) addr + offset; | 288 | return (void __iomem *) addr + offset; |
289 | } | 289 | } |
290 | EXPORT_SYMBOL_GPL(pci_iomap_range); | 290 | EXPORT_SYMBOL(pci_iomap_range); |
291 | 291 | ||
292 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | 292 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) |
293 | { | 293 | { |
@@ -309,7 +309,7 @@ void pci_iounmap(struct pci_dev *pdev, void __iomem *addr) | |||
309 | } | 309 | } |
310 | spin_unlock(&zpci_iomap_lock); | 310 | spin_unlock(&zpci_iomap_lock); |
311 | } | 311 | } |
312 | EXPORT_SYMBOL_GPL(pci_iounmap); | 312 | EXPORT_SYMBOL(pci_iounmap); |
313 | 313 | ||
314 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, | 314 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, |
315 | int size, u32 *val) | 315 | int size, u32 *val) |
@@ -483,9 +483,8 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev) | |||
483 | airq_iv_free_bit(zpci_aisb_iv, zdev->aisb); | 483 | airq_iv_free_bit(zpci_aisb_iv, zdev->aisb); |
484 | } | 484 | } |
485 | 485 | ||
486 | static void zpci_map_resources(struct zpci_dev *zdev) | 486 | static void zpci_map_resources(struct pci_dev *pdev) |
487 | { | 487 | { |
488 | struct pci_dev *pdev = zdev->pdev; | ||
489 | resource_size_t len; | 488 | resource_size_t len; |
490 | int i; | 489 | int i; |
491 | 490 | ||
@@ -499,9 +498,8 @@ static void zpci_map_resources(struct zpci_dev *zdev) | |||
499 | } | 498 | } |
500 | } | 499 | } |
501 | 500 | ||
502 | static void zpci_unmap_resources(struct zpci_dev *zdev) | 501 | static void zpci_unmap_resources(struct pci_dev *pdev) |
503 | { | 502 | { |
504 | struct pci_dev *pdev = zdev->pdev; | ||
505 | resource_size_t len; | 503 | resource_size_t len; |
506 | int i; | 504 | int i; |
507 | 505 | ||
@@ -651,7 +649,7 @@ int pcibios_add_device(struct pci_dev *pdev) | |||
651 | 649 | ||
652 | zdev->pdev = pdev; | 650 | zdev->pdev = pdev; |
653 | pdev->dev.groups = zpci_attr_groups; | 651 | pdev->dev.groups = zpci_attr_groups; |
654 | zpci_map_resources(zdev); | 652 | zpci_map_resources(pdev); |
655 | 653 | ||
656 | for (i = 0; i < PCI_BAR_COUNT; i++) { | 654 | for (i = 0; i < PCI_BAR_COUNT; i++) { |
657 | res = &pdev->resource[i]; | 655 | res = &pdev->resource[i]; |
@@ -663,6 +661,11 @@ int pcibios_add_device(struct pci_dev *pdev) | |||
663 | return 0; | 661 | return 0; |
664 | } | 662 | } |
665 | 663 | ||
664 | void pcibios_release_device(struct pci_dev *pdev) | ||
665 | { | ||
666 | zpci_unmap_resources(pdev); | ||
667 | } | ||
668 | |||
666 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | 669 | int pcibios_enable_device(struct pci_dev *pdev, int mask) |
667 | { | 670 | { |
668 | struct zpci_dev *zdev = get_zdev(pdev); | 671 | struct zpci_dev *zdev = get_zdev(pdev); |
@@ -670,7 +673,6 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask) | |||
670 | zdev->pdev = pdev; | 673 | zdev->pdev = pdev; |
671 | zpci_debug_init_device(zdev); | 674 | zpci_debug_init_device(zdev); |
672 | zpci_fmb_enable_device(zdev); | 675 | zpci_fmb_enable_device(zdev); |
673 | zpci_map_resources(zdev); | ||
674 | 676 | ||
675 | return pci_enable_resources(pdev, mask); | 677 | return pci_enable_resources(pdev, mask); |
676 | } | 678 | } |
@@ -679,7 +681,6 @@ void pcibios_disable_device(struct pci_dev *pdev) | |||
679 | { | 681 | { |
680 | struct zpci_dev *zdev = get_zdev(pdev); | 682 | struct zpci_dev *zdev = get_zdev(pdev); |
681 | 683 | ||
682 | zpci_unmap_resources(zdev); | ||
683 | zpci_fmb_disable_device(zdev); | 684 | zpci_fmb_disable_device(zdev); |
684 | zpci_debug_exit_device(zdev); | 685 | zpci_debug_exit_device(zdev); |
685 | zdev->pdev = NULL; | 686 | zdev->pdev = NULL; |
@@ -688,7 +689,8 @@ void pcibios_disable_device(struct pci_dev *pdev) | |||
688 | #ifdef CONFIG_HIBERNATE_CALLBACKS | 689 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
689 | static int zpci_restore(struct device *dev) | 690 | static int zpci_restore(struct device *dev) |
690 | { | 691 | { |
691 | struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); | 692 | struct pci_dev *pdev = to_pci_dev(dev); |
693 | struct zpci_dev *zdev = get_zdev(pdev); | ||
692 | int ret = 0; | 694 | int ret = 0; |
693 | 695 | ||
694 | if (zdev->state != ZPCI_FN_STATE_ONLINE) | 696 | if (zdev->state != ZPCI_FN_STATE_ONLINE) |
@@ -698,7 +700,7 @@ static int zpci_restore(struct device *dev) | |||
698 | if (ret) | 700 | if (ret) |
699 | goto out; | 701 | goto out; |
700 | 702 | ||
701 | zpci_map_resources(zdev); | 703 | zpci_map_resources(pdev); |
702 | zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET, | 704 | zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET, |
703 | zdev->start_dma + zdev->iommu_size - 1, | 705 | zdev->start_dma + zdev->iommu_size - 1, |
704 | (u64) zdev->dma_table); | 706 | (u64) zdev->dma_table); |
@@ -709,12 +711,14 @@ out: | |||
709 | 711 | ||
710 | static int zpci_freeze(struct device *dev) | 712 | static int zpci_freeze(struct device *dev) |
711 | { | 713 | { |
712 | struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); | 714 | struct pci_dev *pdev = to_pci_dev(dev); |
715 | struct zpci_dev *zdev = get_zdev(pdev); | ||
713 | 716 | ||
714 | if (zdev->state != ZPCI_FN_STATE_ONLINE) | 717 | if (zdev->state != ZPCI_FN_STATE_ONLINE) |
715 | return 0; | 718 | return 0; |
716 | 719 | ||
717 | zpci_unregister_ioat(zdev, 0); | 720 | zpci_unregister_ioat(zdev, 0); |
721 | zpci_unmap_resources(pdev); | ||
718 | return clp_disable_fh(zdev); | 722 | return clp_disable_fh(zdev); |
719 | } | 723 | } |
720 | 724 | ||
diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c index 8aa271b3d1ad..b1bb2b72302c 100644 --- a/arch/s390/pci/pci_mmio.c +++ b/arch/s390/pci/pci_mmio.c | |||
@@ -64,8 +64,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr, | |||
64 | if (copy_from_user(buf, user_buffer, length)) | 64 | if (copy_from_user(buf, user_buffer, length)) |
65 | goto out; | 65 | goto out; |
66 | 66 | ||
67 | memcpy_toio(io_addr, buf, length); | 67 | ret = zpci_memcpy_toio(io_addr, buf, length); |
68 | ret = 0; | ||
69 | out: | 68 | out: |
70 | if (buf != local_buf) | 69 | if (buf != local_buf) |
71 | kfree(buf); | 70 | kfree(buf); |
@@ -98,16 +97,16 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr, | |||
98 | goto out; | 97 | goto out; |
99 | io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); | 98 | io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); |
100 | 99 | ||
101 | ret = -EFAULT; | 100 | if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) { |
102 | if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) | 101 | ret = -EFAULT; |
103 | goto out; | 102 | goto out; |
104 | 103 | } | |
105 | memcpy_fromio(buf, io_addr, length); | 104 | ret = zpci_memcpy_fromio(buf, io_addr, length); |
106 | 105 | if (ret) | |
107 | if (copy_to_user(user_buffer, buf, length)) | ||
108 | goto out; | 106 | goto out; |
107 | if (copy_to_user(user_buffer, buf, length)) | ||
108 | ret = -EFAULT; | ||
109 | 109 | ||
110 | ret = 0; | ||
111 | out: | 110 | out: |
112 | if (buf != local_buf) | 111 | if (buf != local_buf) |
113 | kfree(buf); | 112 | kfree(buf); |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 96ac69c5eba0..efb00ec75805 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -86,6 +86,9 @@ config ARCH_DEFCONFIG | |||
86 | default "arch/sparc/configs/sparc32_defconfig" if SPARC32 | 86 | default "arch/sparc/configs/sparc32_defconfig" if SPARC32 |
87 | default "arch/sparc/configs/sparc64_defconfig" if SPARC64 | 87 | default "arch/sparc/configs/sparc64_defconfig" if SPARC64 |
88 | 88 | ||
89 | config ARCH_PROC_KCORE_TEXT | ||
90 | def_bool y | ||
91 | |||
89 | config IOMMU_HELPER | 92 | config IOMMU_HELPER |
90 | bool | 93 | bool |
91 | default y if SPARC64 | 94 | default y if SPARC64 |
diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h index 4f6725ff4c33..f5b6537306f0 100644 --- a/arch/sparc/include/asm/hypervisor.h +++ b/arch/sparc/include/asm/hypervisor.h | |||
@@ -2957,6 +2957,17 @@ unsigned long sun4v_t5_set_perfreg(unsigned long reg_num, | |||
2957 | unsigned long reg_val); | 2957 | unsigned long reg_val); |
2958 | #endif | 2958 | #endif |
2959 | 2959 | ||
2960 | |||
2961 | #define HV_FAST_M7_GET_PERFREG 0x43 | ||
2962 | #define HV_FAST_M7_SET_PERFREG 0x44 | ||
2963 | |||
2964 | #ifndef __ASSEMBLY__ | ||
2965 | unsigned long sun4v_m7_get_perfreg(unsigned long reg_num, | ||
2966 | unsigned long *reg_val); | ||
2967 | unsigned long sun4v_m7_set_perfreg(unsigned long reg_num, | ||
2968 | unsigned long reg_val); | ||
2969 | #endif | ||
2970 | |||
2960 | /* Function numbers for HV_CORE_TRAP. */ | 2971 | /* Function numbers for HV_CORE_TRAP. */ |
2961 | #define HV_CORE_SET_VER 0x00 | 2972 | #define HV_CORE_SET_VER 0x00 |
2962 | #define HV_CORE_PUTCHAR 0x01 | 2973 | #define HV_CORE_PUTCHAR 0x01 |
@@ -2981,6 +2992,7 @@ unsigned long sun4v_t5_set_perfreg(unsigned long reg_num, | |||
2981 | #define HV_GRP_SDIO 0x0108 | 2992 | #define HV_GRP_SDIO 0x0108 |
2982 | #define HV_GRP_SDIO_ERR 0x0109 | 2993 | #define HV_GRP_SDIO_ERR 0x0109 |
2983 | #define HV_GRP_REBOOT_DATA 0x0110 | 2994 | #define HV_GRP_REBOOT_DATA 0x0110 |
2995 | #define HV_GRP_M7_PERF 0x0114 | ||
2984 | #define HV_GRP_NIAG_PERF 0x0200 | 2996 | #define HV_GRP_NIAG_PERF 0x0200 |
2985 | #define HV_GRP_FIRE_PERF 0x0201 | 2997 | #define HV_GRP_FIRE_PERF 0x0201 |
2986 | #define HV_GRP_N2_CPU 0x0202 | 2998 | #define HV_GRP_N2_CPU 0x0202 |
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h index 9b672be70dda..50d4840d9aeb 100644 --- a/arch/sparc/include/asm/io_64.h +++ b/arch/sparc/include/asm/io_64.h | |||
@@ -407,16 +407,16 @@ static inline void iounmap(volatile void __iomem *addr) | |||
407 | { | 407 | { |
408 | } | 408 | } |
409 | 409 | ||
410 | #define ioread8(X) readb(X) | 410 | #define ioread8 readb |
411 | #define ioread16(X) readw(X) | 411 | #define ioread16 readw |
412 | #define ioread16be(X) __raw_readw(X) | 412 | #define ioread16be __raw_readw |
413 | #define ioread32(X) readl(X) | 413 | #define ioread32 readl |
414 | #define ioread32be(X) __raw_readl(X) | 414 | #define ioread32be __raw_readl |
415 | #define iowrite8(val,X) writeb(val,X) | 415 | #define iowrite8 writeb |
416 | #define iowrite16(val,X) writew(val,X) | 416 | #define iowrite16 writew |
417 | #define iowrite16be(val,X) __raw_writew(val,X) | 417 | #define iowrite16be __raw_writew |
418 | #define iowrite32(val,X) writel(val,X) | 418 | #define iowrite32 writel |
419 | #define iowrite32be(val,X) __raw_writel(val,X) | 419 | #define iowrite32be __raw_writel |
420 | 420 | ||
421 | /* Create a virtual mapping cookie for an IO port range */ | 421 | /* Create a virtual mapping cookie for an IO port range */ |
422 | void __iomem *ioport_map(unsigned long port, unsigned int nr); | 422 | void __iomem *ioport_map(unsigned long port, unsigned int nr); |
diff --git a/arch/sparc/include/asm/starfire.h b/arch/sparc/include/asm/starfire.h index c100dc27a0a9..176fa0ad19f1 100644 --- a/arch/sparc/include/asm/starfire.h +++ b/arch/sparc/include/asm/starfire.h | |||
@@ -12,7 +12,6 @@ | |||
12 | extern int this_is_starfire; | 12 | extern int this_is_starfire; |
13 | 13 | ||
14 | void check_if_starfire(void); | 14 | void check_if_starfire(void); |
15 | int starfire_hard_smp_processor_id(void); | ||
16 | void starfire_hookup(int); | 15 | void starfire_hookup(int); |
17 | unsigned int starfire_translate(unsigned long imap, unsigned int upaid); | 16 | unsigned int starfire_translate(unsigned long imap, unsigned int upaid); |
18 | 17 | ||
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 88d322b67fac..07cc49e541f4 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h | |||
@@ -98,11 +98,7 @@ void sun4v_do_mna(struct pt_regs *regs, | |||
98 | void do_privop(struct pt_regs *regs); | 98 | void do_privop(struct pt_regs *regs); |
99 | void do_privact(struct pt_regs *regs); | 99 | void do_privact(struct pt_regs *regs); |
100 | void do_cee(struct pt_regs *regs); | 100 | void do_cee(struct pt_regs *regs); |
101 | void do_cee_tl1(struct pt_regs *regs); | ||
102 | void do_dae_tl1(struct pt_regs *regs); | ||
103 | void do_iae_tl1(struct pt_regs *regs); | ||
104 | void do_div0_tl1(struct pt_regs *regs); | 101 | void do_div0_tl1(struct pt_regs *regs); |
105 | void do_fpdis_tl1(struct pt_regs *regs); | ||
106 | void do_fpieee_tl1(struct pt_regs *regs); | 102 | void do_fpieee_tl1(struct pt_regs *regs); |
107 | void do_fpother_tl1(struct pt_regs *regs); | 103 | void do_fpother_tl1(struct pt_regs *regs); |
108 | void do_ill_tl1(struct pt_regs *regs); | 104 | void do_ill_tl1(struct pt_regs *regs); |
diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c index 5c55145bfbf0..662500fa555f 100644 --- a/arch/sparc/kernel/hvapi.c +++ b/arch/sparc/kernel/hvapi.c | |||
@@ -48,6 +48,7 @@ static struct api_info api_table[] = { | |||
48 | { .group = HV_GRP_VT_CPU, }, | 48 | { .group = HV_GRP_VT_CPU, }, |
49 | { .group = HV_GRP_T5_CPU, }, | 49 | { .group = HV_GRP_T5_CPU, }, |
50 | { .group = HV_GRP_DIAG, .flags = FLAG_PRE_API }, | 50 | { .group = HV_GRP_DIAG, .flags = FLAG_PRE_API }, |
51 | { .group = HV_GRP_M7_PERF, }, | ||
51 | }; | 52 | }; |
52 | 53 | ||
53 | static DEFINE_SPINLOCK(hvapi_lock); | 54 | static DEFINE_SPINLOCK(hvapi_lock); |
diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S index caedf8320416..afbaba52d2f1 100644 --- a/arch/sparc/kernel/hvcalls.S +++ b/arch/sparc/kernel/hvcalls.S | |||
@@ -837,3 +837,19 @@ ENTRY(sun4v_t5_set_perfreg) | |||
837 | retl | 837 | retl |
838 | nop | 838 | nop |
839 | ENDPROC(sun4v_t5_set_perfreg) | 839 | ENDPROC(sun4v_t5_set_perfreg) |
840 | |||
841 | ENTRY(sun4v_m7_get_perfreg) | ||
842 | mov %o1, %o4 | ||
843 | mov HV_FAST_M7_GET_PERFREG, %o5 | ||
844 | ta HV_FAST_TRAP | ||
845 | stx %o1, [%o4] | ||
846 | retl | ||
847 | nop | ||
848 | ENDPROC(sun4v_m7_get_perfreg) | ||
849 | |||
850 | ENTRY(sun4v_m7_set_perfreg) | ||
851 | mov HV_FAST_M7_SET_PERFREG, %o5 | ||
852 | ta HV_FAST_TRAP | ||
853 | retl | ||
854 | nop | ||
855 | ENDPROC(sun4v_m7_set_perfreg) | ||
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 9ce5afe167ff..b36365f49478 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -639,10 +639,7 @@ static void pci_claim_bus_resources(struct pci_bus *bus) | |||
639 | (unsigned long long)r->end, | 639 | (unsigned long long)r->end, |
640 | (unsigned int)r->flags); | 640 | (unsigned int)r->flags); |
641 | 641 | ||
642 | if (pci_claim_resource(dev, i) == 0) | 642 | pci_claim_resource(dev, i); |
643 | continue; | ||
644 | |||
645 | pci_claim_bridge_resource(dev, i); | ||
646 | } | 643 | } |
647 | } | 644 | } |
648 | 645 | ||
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index 7e967c8018c8..eb978c77c76a 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c | |||
@@ -217,6 +217,31 @@ static const struct pcr_ops n5_pcr_ops = { | |||
217 | .pcr_nmi_disable = PCR_N4_PICNPT, | 217 | .pcr_nmi_disable = PCR_N4_PICNPT, |
218 | }; | 218 | }; |
219 | 219 | ||
220 | static u64 m7_pcr_read(unsigned long reg_num) | ||
221 | { | ||
222 | unsigned long val; | ||
223 | |||
224 | (void) sun4v_m7_get_perfreg(reg_num, &val); | ||
225 | |||
226 | return val; | ||
227 | } | ||
228 | |||
229 | static void m7_pcr_write(unsigned long reg_num, u64 val) | ||
230 | { | ||
231 | (void) sun4v_m7_set_perfreg(reg_num, val); | ||
232 | } | ||
233 | |||
234 | static const struct pcr_ops m7_pcr_ops = { | ||
235 | .read_pcr = m7_pcr_read, | ||
236 | .write_pcr = m7_pcr_write, | ||
237 | .read_pic = n4_pic_read, | ||
238 | .write_pic = n4_pic_write, | ||
239 | .nmi_picl_value = n4_picl_value, | ||
240 | .pcr_nmi_enable = (PCR_N4_PICNPT | PCR_N4_STRACE | | ||
241 | PCR_N4_UTRACE | PCR_N4_TOE | | ||
242 | (26 << PCR_N4_SL_SHIFT)), | ||
243 | .pcr_nmi_disable = PCR_N4_PICNPT, | ||
244 | }; | ||
220 | 245 | ||
221 | static unsigned long perf_hsvc_group; | 246 | static unsigned long perf_hsvc_group; |
222 | static unsigned long perf_hsvc_major; | 247 | static unsigned long perf_hsvc_major; |
@@ -248,6 +273,10 @@ static int __init register_perf_hsvc(void) | |||
248 | perf_hsvc_group = HV_GRP_T5_CPU; | 273 | perf_hsvc_group = HV_GRP_T5_CPU; |
249 | break; | 274 | break; |
250 | 275 | ||
276 | case SUN4V_CHIP_SPARC_M7: | ||
277 | perf_hsvc_group = HV_GRP_M7_PERF; | ||
278 | break; | ||
279 | |||
251 | default: | 280 | default: |
252 | return -ENODEV; | 281 | return -ENODEV; |
253 | } | 282 | } |
@@ -293,6 +322,10 @@ static int __init setup_sun4v_pcr_ops(void) | |||
293 | pcr_ops = &n5_pcr_ops; | 322 | pcr_ops = &n5_pcr_ops; |
294 | break; | 323 | break; |
295 | 324 | ||
325 | case SUN4V_CHIP_SPARC_M7: | ||
326 | pcr_ops = &m7_pcr_ops; | ||
327 | break; | ||
328 | |||
296 | default: | 329 | default: |
297 | ret = -ENODEV; | 330 | ret = -ENODEV; |
298 | break; | 331 | break; |
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 46a5e4508752..86eebfa3b158 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
@@ -792,6 +792,42 @@ static const struct sparc_pmu niagara4_pmu = { | |||
792 | .num_pic_regs = 4, | 792 | .num_pic_regs = 4, |
793 | }; | 793 | }; |
794 | 794 | ||
795 | static void sparc_m7_write_pmc(int idx, u64 val) | ||
796 | { | ||
797 | u64 pcr; | ||
798 | |||
799 | pcr = pcr_ops->read_pcr(idx); | ||
800 | /* ensure ov and ntc are reset */ | ||
801 | pcr &= ~(PCR_N4_OV | PCR_N4_NTC); | ||
802 | |||
803 | pcr_ops->write_pic(idx, val & 0xffffffff); | ||
804 | |||
805 | pcr_ops->write_pcr(idx, pcr); | ||
806 | } | ||
807 | |||
808 | static const struct sparc_pmu sparc_m7_pmu = { | ||
809 | .event_map = niagara4_event_map, | ||
810 | .cache_map = &niagara4_cache_map, | ||
811 | .max_events = ARRAY_SIZE(niagara4_perfmon_event_map), | ||
812 | .read_pmc = sparc_vt_read_pmc, | ||
813 | .write_pmc = sparc_m7_write_pmc, | ||
814 | .upper_shift = 5, | ||
815 | .lower_shift = 5, | ||
816 | .event_mask = 0x7ff, | ||
817 | .user_bit = PCR_N4_UTRACE, | ||
818 | .priv_bit = PCR_N4_STRACE, | ||
819 | |||
820 | /* We explicitly don't support hypervisor tracing. */ | ||
821 | .hv_bit = 0, | ||
822 | |||
823 | .irq_bit = PCR_N4_TOE, | ||
824 | .upper_nop = 0, | ||
825 | .lower_nop = 0, | ||
826 | .flags = 0, | ||
827 | .max_hw_events = 4, | ||
828 | .num_pcrs = 4, | ||
829 | .num_pic_regs = 4, | ||
830 | }; | ||
795 | static const struct sparc_pmu *sparc_pmu __read_mostly; | 831 | static const struct sparc_pmu *sparc_pmu __read_mostly; |
796 | 832 | ||
797 | static u64 event_encoding(u64 event_id, int idx) | 833 | static u64 event_encoding(u64 event_id, int idx) |
@@ -960,6 +996,8 @@ out: | |||
960 | cpuc->pcr[0] |= cpuc->event[0]->hw.config_base; | 996 | cpuc->pcr[0] |= cpuc->event[0]->hw.config_base; |
961 | } | 997 | } |
962 | 998 | ||
999 | static void sparc_pmu_start(struct perf_event *event, int flags); | ||
1000 | |||
963 | /* On this PMU each PIC has it's own PCR control register. */ | 1001 | /* On this PMU each PIC has it's own PCR control register. */ |
964 | static void calculate_multiple_pcrs(struct cpu_hw_events *cpuc) | 1002 | static void calculate_multiple_pcrs(struct cpu_hw_events *cpuc) |
965 | { | 1003 | { |
@@ -972,20 +1010,13 @@ static void calculate_multiple_pcrs(struct cpu_hw_events *cpuc) | |||
972 | struct perf_event *cp = cpuc->event[i]; | 1010 | struct perf_event *cp = cpuc->event[i]; |
973 | struct hw_perf_event *hwc = &cp->hw; | 1011 | struct hw_perf_event *hwc = &cp->hw; |
974 | int idx = hwc->idx; | 1012 | int idx = hwc->idx; |
975 | u64 enc; | ||
976 | 1013 | ||
977 | if (cpuc->current_idx[i] != PIC_NO_INDEX) | 1014 | if (cpuc->current_idx[i] != PIC_NO_INDEX) |
978 | continue; | 1015 | continue; |
979 | 1016 | ||
980 | sparc_perf_event_set_period(cp, hwc, idx); | ||
981 | cpuc->current_idx[i] = idx; | 1017 | cpuc->current_idx[i] = idx; |
982 | 1018 | ||
983 | enc = perf_event_get_enc(cpuc->events[i]); | 1019 | sparc_pmu_start(cp, PERF_EF_RELOAD); |
984 | cpuc->pcr[idx] &= ~mask_for_index(idx); | ||
985 | if (hwc->state & PERF_HES_STOPPED) | ||
986 | cpuc->pcr[idx] |= nop_for_index(idx); | ||
987 | else | ||
988 | cpuc->pcr[idx] |= event_encoding(enc, idx); | ||
989 | } | 1020 | } |
990 | out: | 1021 | out: |
991 | for (i = 0; i < cpuc->n_events; i++) { | 1022 | for (i = 0; i < cpuc->n_events; i++) { |
@@ -1101,7 +1132,6 @@ static void sparc_pmu_del(struct perf_event *event, int _flags) | |||
1101 | int i; | 1132 | int i; |
1102 | 1133 | ||
1103 | local_irq_save(flags); | 1134 | local_irq_save(flags); |
1104 | perf_pmu_disable(event->pmu); | ||
1105 | 1135 | ||
1106 | for (i = 0; i < cpuc->n_events; i++) { | 1136 | for (i = 0; i < cpuc->n_events; i++) { |
1107 | if (event == cpuc->event[i]) { | 1137 | if (event == cpuc->event[i]) { |
@@ -1127,7 +1157,6 @@ static void sparc_pmu_del(struct perf_event *event, int _flags) | |||
1127 | } | 1157 | } |
1128 | } | 1158 | } |
1129 | 1159 | ||
1130 | perf_pmu_enable(event->pmu); | ||
1131 | local_irq_restore(flags); | 1160 | local_irq_restore(flags); |
1132 | } | 1161 | } |
1133 | 1162 | ||
@@ -1361,7 +1390,6 @@ static int sparc_pmu_add(struct perf_event *event, int ef_flags) | |||
1361 | unsigned long flags; | 1390 | unsigned long flags; |
1362 | 1391 | ||
1363 | local_irq_save(flags); | 1392 | local_irq_save(flags); |
1364 | perf_pmu_disable(event->pmu); | ||
1365 | 1393 | ||
1366 | n0 = cpuc->n_events; | 1394 | n0 = cpuc->n_events; |
1367 | if (n0 >= sparc_pmu->max_hw_events) | 1395 | if (n0 >= sparc_pmu->max_hw_events) |
@@ -1394,7 +1422,6 @@ nocheck: | |||
1394 | 1422 | ||
1395 | ret = 0; | 1423 | ret = 0; |
1396 | out: | 1424 | out: |
1397 | perf_pmu_enable(event->pmu); | ||
1398 | local_irq_restore(flags); | 1425 | local_irq_restore(flags); |
1399 | return ret; | 1426 | return ret; |
1400 | } | 1427 | } |
@@ -1667,6 +1694,10 @@ static bool __init supported_pmu(void) | |||
1667 | sparc_pmu = &niagara4_pmu; | 1694 | sparc_pmu = &niagara4_pmu; |
1668 | return true; | 1695 | return true; |
1669 | } | 1696 | } |
1697 | if (!strcmp(sparc_pmu_type, "sparc-m7")) { | ||
1698 | sparc_pmu = &sparc_m7_pmu; | ||
1699 | return true; | ||
1700 | } | ||
1670 | return false; | 1701 | return false; |
1671 | } | 1702 | } |
1672 | 1703 | ||
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 0be7bf978cb1..46a59643bb1c 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -287,6 +287,8 @@ void arch_trigger_all_cpu_backtrace(bool include_self) | |||
287 | printk(" TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n", | 287 | printk(" TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n", |
288 | gp->tpc, gp->o7, gp->i7, gp->rpc); | 288 | gp->tpc, gp->o7, gp->i7, gp->rpc); |
289 | } | 289 | } |
290 | |||
291 | touch_nmi_watchdog(); | ||
290 | } | 292 | } |
291 | 293 | ||
292 | memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot)); | 294 | memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot)); |
@@ -362,6 +364,8 @@ static void pmu_snapshot_all_cpus(void) | |||
362 | (cpu == this_cpu ? '*' : ' '), cpu, | 364 | (cpu == this_cpu ? '*' : ' '), cpu, |
363 | pp->pcr[0], pp->pcr[1], pp->pcr[2], pp->pcr[3], | 365 | pp->pcr[0], pp->pcr[1], pp->pcr[2], pp->pcr[3], |
364 | pp->pic[0], pp->pic[1], pp->pic[2], pp->pic[3]); | 366 | pp->pic[0], pp->pic[1], pp->pic[2], pp->pic[3]); |
367 | |||
368 | touch_nmi_watchdog(); | ||
365 | } | 369 | } |
366 | 370 | ||
367 | memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot)); | 371 | memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot)); |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index da6f1a7fc4db..61139d9924ca 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -1406,11 +1406,32 @@ void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) | |||
1406 | scheduler_ipi(); | 1406 | scheduler_ipi(); |
1407 | } | 1407 | } |
1408 | 1408 | ||
1409 | /* This is a nop because we capture all other cpus | 1409 | static void stop_this_cpu(void *dummy) |
1410 | * anyways when making the PROM active. | 1410 | { |
1411 | */ | 1411 | prom_stopself(); |
1412 | } | ||
1413 | |||
1412 | void smp_send_stop(void) | 1414 | void smp_send_stop(void) |
1413 | { | 1415 | { |
1416 | int cpu; | ||
1417 | |||
1418 | if (tlb_type == hypervisor) { | ||
1419 | for_each_online_cpu(cpu) { | ||
1420 | if (cpu == smp_processor_id()) | ||
1421 | continue; | ||
1422 | #ifdef CONFIG_SUN_LDOMS | ||
1423 | if (ldom_domaining_enabled) { | ||
1424 | unsigned long hv_err; | ||
1425 | hv_err = sun4v_cpu_stop(cpu); | ||
1426 | if (hv_err) | ||
1427 | printk(KERN_ERR "sun4v_cpu_stop() " | ||
1428 | "failed err=%lu\n", hv_err); | ||
1429 | } else | ||
1430 | #endif | ||
1431 | prom_stopcpu_cpuid(cpu); | ||
1432 | } | ||
1433 | } else | ||
1434 | smp_call_function(stop_this_cpu, NULL, 0); | ||
1414 | } | 1435 | } |
1415 | 1436 | ||
1416 | /** | 1437 | /** |
diff --git a/arch/sparc/kernel/starfire.c b/arch/sparc/kernel/starfire.c index 82281a566bb8..167fdfd9c837 100644 --- a/arch/sparc/kernel/starfire.c +++ b/arch/sparc/kernel/starfire.c | |||
@@ -28,11 +28,6 @@ void check_if_starfire(void) | |||
28 | this_is_starfire = 1; | 28 | this_is_starfire = 1; |
29 | } | 29 | } |
30 | 30 | ||
31 | int starfire_hard_smp_processor_id(void) | ||
32 | { | ||
33 | return upa_readl(0x1fff40000d0UL); | ||
34 | } | ||
35 | |||
36 | /* | 31 | /* |
37 | * Each Starfire board has 32 registers which perform translation | 32 | * Each Starfire board has 32 registers which perform translation |
38 | * and delivery of traditional interrupt packets into the extended | 33 | * and delivery of traditional interrupt packets into the extended |
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index c85403d0496c..30e7ddb27a3a 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
@@ -333,7 +333,7 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second | |||
333 | long err; | 333 | long err; |
334 | 334 | ||
335 | /* No need for backward compatibility. We can start fresh... */ | 335 | /* No need for backward compatibility. We can start fresh... */ |
336 | if (call <= SEMCTL) { | 336 | if (call <= SEMTIMEDOP) { |
337 | switch (call) { | 337 | switch (call) { |
338 | case SEMOP: | 338 | case SEMOP: |
339 | err = sys_semtimedop(first, ptr, | 339 | err = sys_semtimedop(first, ptr, |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index a27651e866e7..0e699745d643 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -2427,6 +2427,8 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs) | |||
2427 | } | 2427 | } |
2428 | user_instruction_dump ((unsigned int __user *) regs->tpc); | 2428 | user_instruction_dump ((unsigned int __user *) regs->tpc); |
2429 | } | 2429 | } |
2430 | if (panic_on_oops) | ||
2431 | panic("Fatal exception"); | ||
2430 | if (regs->tstate & TSTATE_PRIV) | 2432 | if (regs->tstate & TSTATE_PRIV) |
2431 | do_exit(SIGKILL); | 2433 | do_exit(SIGKILL); |
2432 | do_exit(SIGSEGV); | 2434 | do_exit(SIGSEGV); |
@@ -2564,27 +2566,6 @@ void do_cee(struct pt_regs *regs) | |||
2564 | die_if_kernel("TL0: Cache Error Exception", regs); | 2566 | die_if_kernel("TL0: Cache Error Exception", regs); |
2565 | } | 2567 | } |
2566 | 2568 | ||
2567 | void do_cee_tl1(struct pt_regs *regs) | ||
2568 | { | ||
2569 | exception_enter(); | ||
2570 | dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | ||
2571 | die_if_kernel("TL1: Cache Error Exception", regs); | ||
2572 | } | ||
2573 | |||
2574 | void do_dae_tl1(struct pt_regs *regs) | ||
2575 | { | ||
2576 | exception_enter(); | ||
2577 | dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | ||
2578 | die_if_kernel("TL1: Data Access Exception", regs); | ||
2579 | } | ||
2580 | |||
2581 | void do_iae_tl1(struct pt_regs *regs) | ||
2582 | { | ||
2583 | exception_enter(); | ||
2584 | dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | ||
2585 | die_if_kernel("TL1: Instruction Access Exception", regs); | ||
2586 | } | ||
2587 | |||
2588 | void do_div0_tl1(struct pt_regs *regs) | 2569 | void do_div0_tl1(struct pt_regs *regs) |
2589 | { | 2570 | { |
2590 | exception_enter(); | 2571 | exception_enter(); |
@@ -2592,13 +2573,6 @@ void do_div0_tl1(struct pt_regs *regs) | |||
2592 | die_if_kernel("TL1: DIV0 Exception", regs); | 2573 | die_if_kernel("TL1: DIV0 Exception", regs); |
2593 | } | 2574 | } |
2594 | 2575 | ||
2595 | void do_fpdis_tl1(struct pt_regs *regs) | ||
2596 | { | ||
2597 | exception_enter(); | ||
2598 | dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | ||
2599 | die_if_kernel("TL1: FPU Disabled", regs); | ||
2600 | } | ||
2601 | |||
2602 | void do_fpieee_tl1(struct pt_regs *regs) | 2576 | void do_fpieee_tl1(struct pt_regs *regs) |
2603 | { | 2577 | { |
2604 | exception_enter(); | 2578 | exception_enter(); |
diff --git a/arch/sparc/lib/memmove.S b/arch/sparc/lib/memmove.S index b7f6334e159f..857ad4f8905f 100644 --- a/arch/sparc/lib/memmove.S +++ b/arch/sparc/lib/memmove.S | |||
@@ -8,9 +8,11 @@ | |||
8 | 8 | ||
9 | .text | 9 | .text |
10 | ENTRY(memmove) /* o0=dst o1=src o2=len */ | 10 | ENTRY(memmove) /* o0=dst o1=src o2=len */ |
11 | mov %o0, %g1 | 11 | brz,pn %o2, 99f |
12 | mov %o0, %g1 | ||
13 | |||
12 | cmp %o0, %o1 | 14 | cmp %o0, %o1 |
13 | bleu,pt %xcc, memcpy | 15 | bleu,pt %xcc, 2f |
14 | add %o1, %o2, %g7 | 16 | add %o1, %o2, %g7 |
15 | cmp %g7, %o0 | 17 | cmp %g7, %o0 |
16 | bleu,pt %xcc, memcpy | 18 | bleu,pt %xcc, memcpy |
@@ -24,7 +26,34 @@ ENTRY(memmove) /* o0=dst o1=src o2=len */ | |||
24 | stb %g7, [%o0] | 26 | stb %g7, [%o0] |
25 | bne,pt %icc, 1b | 27 | bne,pt %icc, 1b |
26 | sub %o0, 1, %o0 | 28 | sub %o0, 1, %o0 |
27 | 29 | 99: | |
28 | retl | 30 | retl |
29 | mov %g1, %o0 | 31 | mov %g1, %o0 |
32 | |||
33 | /* We can't just call memcpy for these memmove cases. On some | ||
34 | * chips the memcpy uses cache initializing stores and when dst | ||
35 | * and src are close enough, those can clobber the source data | ||
36 | * before we've loaded it in. | ||
37 | */ | ||
38 | 2: or %o0, %o1, %g7 | ||
39 | or %o2, %g7, %g7 | ||
40 | andcc %g7, 0x7, %g0 | ||
41 | bne,pn %xcc, 4f | ||
42 | nop | ||
43 | |||
44 | 3: ldx [%o1], %g7 | ||
45 | add %o1, 8, %o1 | ||
46 | subcc %o2, 8, %o2 | ||
47 | add %o0, 8, %o0 | ||
48 | bne,pt %icc, 3b | ||
49 | stx %g7, [%o0 - 0x8] | ||
50 | ba,a,pt %xcc, 99b | ||
51 | |||
52 | 4: ldub [%o1], %g7 | ||
53 | add %o1, 1, %o1 | ||
54 | subcc %o2, 1, %o2 | ||
55 | add %o0, 1, %o0 | ||
56 | bne,pt %icc, 4b | ||
57 | stb %g7, [%o0 - 0x1] | ||
58 | ba,a,pt %xcc, 99b | ||
30 | ENDPROC(memmove) | 59 | ENDPROC(memmove) |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 3ea267c53320..4ca0d6ba5ec8 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -2820,7 +2820,7 @@ static int __init report_memory(void) | |||
2820 | 2820 | ||
2821 | return 0; | 2821 | return 0; |
2822 | } | 2822 | } |
2823 | device_initcall(report_memory); | 2823 | arch_initcall(report_memory); |
2824 | 2824 | ||
2825 | #ifdef CONFIG_SMP | 2825 | #ifdef CONFIG_SMP |
2826 | #define do_flush_tlb_kernel_range smp_flush_tlb_kernel_range | 2826 | #define do_flush_tlb_kernel_range smp_flush_tlb_kernel_range |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c2fb8a87dccb..b7d31ca55187 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -499,6 +499,7 @@ config X86_INTEL_QUARK | |||
499 | depends on X86_IO_APIC | 499 | depends on X86_IO_APIC |
500 | select IOSF_MBI | 500 | select IOSF_MBI |
501 | select INTEL_IMR | 501 | select INTEL_IMR |
502 | select COMMON_CLK | ||
502 | ---help--- | 503 | ---help--- |
503 | Select to include support for Quark X1000 SoC. | 504 | Select to include support for Quark X1000 SoC. |
504 | Say Y here if you have a Quark based system such as the Arduino | 505 | Say Y here if you have a Quark based system such as the Arduino |
diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c index 7083c16cccba..bb1376381985 100644 --- a/arch/x86/boot/compressed/aslr.c +++ b/arch/x86/boot/compressed/aslr.c | |||
@@ -14,13 +14,6 @@ | |||
14 | static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" | 14 | static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" |
15 | LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION; | 15 | LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION; |
16 | 16 | ||
17 | struct kaslr_setup_data { | ||
18 | __u64 next; | ||
19 | __u32 type; | ||
20 | __u32 len; | ||
21 | __u8 data[1]; | ||
22 | } kaslr_setup_data; | ||
23 | |||
24 | #define I8254_PORT_CONTROL 0x43 | 17 | #define I8254_PORT_CONTROL 0x43 |
25 | #define I8254_PORT_COUNTER0 0x40 | 18 | #define I8254_PORT_COUNTER0 0x40 |
26 | #define I8254_CMD_READBACK 0xC0 | 19 | #define I8254_CMD_READBACK 0xC0 |
@@ -302,29 +295,7 @@ static unsigned long find_random_addr(unsigned long minimum, | |||
302 | return slots_fetch_random(); | 295 | return slots_fetch_random(); |
303 | } | 296 | } |
304 | 297 | ||
305 | static void add_kaslr_setup_data(struct boot_params *params, __u8 enabled) | 298 | unsigned char *choose_kernel_location(unsigned char *input, |
306 | { | ||
307 | struct setup_data *data; | ||
308 | |||
309 | kaslr_setup_data.type = SETUP_KASLR; | ||
310 | kaslr_setup_data.len = 1; | ||
311 | kaslr_setup_data.next = 0; | ||
312 | kaslr_setup_data.data[0] = enabled; | ||
313 | |||
314 | data = (struct setup_data *)(unsigned long)params->hdr.setup_data; | ||
315 | |||
316 | while (data && data->next) | ||
317 | data = (struct setup_data *)(unsigned long)data->next; | ||
318 | |||
319 | if (data) | ||
320 | data->next = (unsigned long)&kaslr_setup_data; | ||
321 | else | ||
322 | params->hdr.setup_data = (unsigned long)&kaslr_setup_data; | ||
323 | |||
324 | } | ||
325 | |||
326 | unsigned char *choose_kernel_location(struct boot_params *params, | ||
327 | unsigned char *input, | ||
328 | unsigned long input_size, | 299 | unsigned long input_size, |
329 | unsigned char *output, | 300 | unsigned char *output, |
330 | unsigned long output_size) | 301 | unsigned long output_size) |
@@ -335,17 +306,14 @@ unsigned char *choose_kernel_location(struct boot_params *params, | |||
335 | #ifdef CONFIG_HIBERNATION | 306 | #ifdef CONFIG_HIBERNATION |
336 | if (!cmdline_find_option_bool("kaslr")) { | 307 | if (!cmdline_find_option_bool("kaslr")) { |
337 | debug_putstr("KASLR disabled by default...\n"); | 308 | debug_putstr("KASLR disabled by default...\n"); |
338 | add_kaslr_setup_data(params, 0); | ||
339 | goto out; | 309 | goto out; |
340 | } | 310 | } |
341 | #else | 311 | #else |
342 | if (cmdline_find_option_bool("nokaslr")) { | 312 | if (cmdline_find_option_bool("nokaslr")) { |
343 | debug_putstr("KASLR disabled by cmdline...\n"); | 313 | debug_putstr("KASLR disabled by cmdline...\n"); |
344 | add_kaslr_setup_data(params, 0); | ||
345 | goto out; | 314 | goto out; |
346 | } | 315 | } |
347 | #endif | 316 | #endif |
348 | add_kaslr_setup_data(params, 1); | ||
349 | 317 | ||
350 | /* Record the various known unsafe memory ranges. */ | 318 | /* Record the various known unsafe memory ranges. */ |
351 | mem_avoid_init((unsigned long)input, input_size, | 319 | mem_avoid_init((unsigned long)input, input_size, |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 5903089c818f..a950864a64da 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -401,8 +401,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, | |||
401 | * the entire decompressed kernel plus relocation table, or the | 401 | * the entire decompressed kernel plus relocation table, or the |
402 | * entire decompressed kernel plus .bss and .brk sections. | 402 | * entire decompressed kernel plus .bss and .brk sections. |
403 | */ | 403 | */ |
404 | output = choose_kernel_location(real_mode, input_data, input_len, | 404 | output = choose_kernel_location(input_data, input_len, output, |
405 | output, | ||
406 | output_len > run_size ? output_len | 405 | output_len > run_size ? output_len |
407 | : run_size); | 406 | : run_size); |
408 | 407 | ||
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index ee3576b2666b..04477d68403f 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h | |||
@@ -57,8 +57,7 @@ int cmdline_find_option_bool(const char *option); | |||
57 | 57 | ||
58 | #if CONFIG_RANDOMIZE_BASE | 58 | #if CONFIG_RANDOMIZE_BASE |
59 | /* aslr.c */ | 59 | /* aslr.c */ |
60 | unsigned char *choose_kernel_location(struct boot_params *params, | 60 | unsigned char *choose_kernel_location(unsigned char *input, |
61 | unsigned char *input, | ||
62 | unsigned long input_size, | 61 | unsigned long input_size, |
63 | unsigned char *output, | 62 | unsigned char *output, |
64 | unsigned long output_size); | 63 | unsigned long output_size); |
@@ -66,8 +65,7 @@ unsigned char *choose_kernel_location(struct boot_params *params, | |||
66 | bool has_cpuflag(int flag); | 65 | bool has_cpuflag(int flag); |
67 | #else | 66 | #else |
68 | static inline | 67 | static inline |
69 | unsigned char *choose_kernel_location(struct boot_params *params, | 68 | unsigned char *choose_kernel_location(unsigned char *input, |
70 | unsigned char *input, | ||
71 | unsigned long input_size, | 69 | unsigned long input_size, |
72 | unsigned char *output, | 70 | unsigned char *output, |
73 | unsigned long output_size) | 71 | unsigned long output_size) |
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 947c6bf52c33..54f60ab41c63 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c | |||
@@ -1155,7 +1155,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req) | |||
1155 | src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC); | 1155 | src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC); |
1156 | if (!src) | 1156 | if (!src) |
1157 | return -ENOMEM; | 1157 | return -ENOMEM; |
1158 | assoc = (src + req->cryptlen + auth_tag_len); | 1158 | assoc = (src + req->cryptlen); |
1159 | scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); | 1159 | scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); |
1160 | scatterwalk_map_and_copy(assoc, req->assoc, 0, | 1160 | scatterwalk_map_and_copy(assoc, req->assoc, 0, |
1161 | req->assoclen, 0); | 1161 | req->assoclen, 0); |
@@ -1180,7 +1180,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req) | |||
1180 | scatterwalk_done(&src_sg_walk, 0, 0); | 1180 | scatterwalk_done(&src_sg_walk, 0, 0); |
1181 | scatterwalk_done(&assoc_sg_walk, 0, 0); | 1181 | scatterwalk_done(&assoc_sg_walk, 0, 0); |
1182 | } else { | 1182 | } else { |
1183 | scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1); | 1183 | scatterwalk_map_and_copy(dst, req->dst, 0, tempCipherLen, 1); |
1184 | kfree(src); | 1184 | kfree(src); |
1185 | } | 1185 | } |
1186 | return retval; | 1186 | return retval; |
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 25bce45c6fc4..3738b138b843 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -2,6 +2,8 @@ | |||
2 | #define _ASM_X86_EFI_H | 2 | #define _ASM_X86_EFI_H |
3 | 3 | ||
4 | #include <asm/i387.h> | 4 | #include <asm/i387.h> |
5 | #include <asm/pgtable.h> | ||
6 | |||
5 | /* | 7 | /* |
6 | * We map the EFI regions needed for runtime services non-contiguously, | 8 | * We map the EFI regions needed for runtime services non-contiguously, |
7 | * with preserved alignment on virtual addresses starting from -4G down | 9 | * with preserved alignment on virtual addresses starting from -4G down |
@@ -89,8 +91,8 @@ extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size, | |||
89 | extern struct efi_scratch efi_scratch; | 91 | extern struct efi_scratch efi_scratch; |
90 | extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable); | 92 | extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable); |
91 | extern int __init efi_memblock_x86_reserve_range(void); | 93 | extern int __init efi_memblock_x86_reserve_range(void); |
92 | extern void __init efi_call_phys_prolog(void); | 94 | extern pgd_t * __init efi_call_phys_prolog(void); |
93 | extern void __init efi_call_phys_epilog(void); | 95 | extern void __init efi_call_phys_epilog(pgd_t *save_pgd); |
94 | extern void __init efi_unmap_memmap(void); | 96 | extern void __init efi_unmap_memmap(void); |
95 | extern void __init efi_memory_uc(u64 addr, unsigned long size); | 97 | extern void __init efi_memory_uc(u64 addr, unsigned long size); |
96 | extern void __init efi_map_region(efi_memory_desc_t *md); | 98 | extern void __init efi_map_region(efi_memory_desc_t *md); |
diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h index 0dbc08282291..72ba21a8b5fc 100644 --- a/arch/x86/include/asm/fpu-internal.h +++ b/arch/x86/include/asm/fpu-internal.h | |||
@@ -370,7 +370,7 @@ static inline void drop_fpu(struct task_struct *tsk) | |||
370 | preempt_disable(); | 370 | preempt_disable(); |
371 | tsk->thread.fpu_counter = 0; | 371 | tsk->thread.fpu_counter = 0; |
372 | __drop_fpu(tsk); | 372 | __drop_fpu(tsk); |
373 | clear_used_math(); | 373 | clear_stopped_child_used_math(tsk); |
374 | preempt_enable(); | 374 | preempt_enable(); |
375 | } | 375 | } |
376 | 376 | ||
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index a236e39cc385..dea2e7e962e3 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -81,11 +81,6 @@ static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level) | |||
81 | (base_gfn >> KVM_HPAGE_GFN_SHIFT(level)); | 81 | (base_gfn >> KVM_HPAGE_GFN_SHIFT(level)); |
82 | } | 82 | } |
83 | 83 | ||
84 | #define SELECTOR_TI_MASK (1 << 2) | ||
85 | #define SELECTOR_RPL_MASK 0x03 | ||
86 | |||
87 | #define IOPL_SHIFT 12 | ||
88 | |||
89 | #define KVM_PERMILLE_MMU_PAGES 20 | 84 | #define KVM_PERMILLE_MMU_PAGES 20 |
90 | #define KVM_MIN_ALLOC_MMU_PAGES 64 | 85 | #define KVM_MIN_ALLOC_MMU_PAGES 64 |
91 | #define KVM_MMU_HASH_SHIFT 10 | 86 | #define KVM_MMU_HASH_SHIFT 10 |
@@ -345,6 +340,7 @@ struct kvm_pmu { | |||
345 | enum { | 340 | enum { |
346 | KVM_DEBUGREG_BP_ENABLED = 1, | 341 | KVM_DEBUGREG_BP_ENABLED = 1, |
347 | KVM_DEBUGREG_WONT_EXIT = 2, | 342 | KVM_DEBUGREG_WONT_EXIT = 2, |
343 | KVM_DEBUGREG_RELOAD = 4, | ||
348 | }; | 344 | }; |
349 | 345 | ||
350 | struct kvm_vcpu_arch { | 346 | struct kvm_vcpu_arch { |
@@ -431,6 +427,9 @@ struct kvm_vcpu_arch { | |||
431 | 427 | ||
432 | int cpuid_nent; | 428 | int cpuid_nent; |
433 | struct kvm_cpuid_entry2 cpuid_entries[KVM_MAX_CPUID_ENTRIES]; | 429 | struct kvm_cpuid_entry2 cpuid_entries[KVM_MAX_CPUID_ENTRIES]; |
430 | |||
431 | int maxphyaddr; | ||
432 | |||
434 | /* emulate context */ | 433 | /* emulate context */ |
435 | 434 | ||
436 | struct x86_emulate_ctxt emulate_ctxt; | 435 | struct x86_emulate_ctxt emulate_ctxt; |
@@ -550,11 +549,20 @@ struct kvm_arch_memory_slot { | |||
550 | struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1]; | 549 | struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1]; |
551 | }; | 550 | }; |
552 | 551 | ||
552 | /* | ||
553 | * We use as the mode the number of bits allocated in the LDR for the | ||
554 | * logical processor ID. It happens that these are all powers of two. | ||
555 | * This makes it is very easy to detect cases where the APICs are | ||
556 | * configured for multiple modes; in that case, we cannot use the map and | ||
557 | * hence cannot use kvm_irq_delivery_to_apic_fast either. | ||
558 | */ | ||
559 | #define KVM_APIC_MODE_XAPIC_CLUSTER 4 | ||
560 | #define KVM_APIC_MODE_XAPIC_FLAT 8 | ||
561 | #define KVM_APIC_MODE_X2APIC 16 | ||
562 | |||
553 | struct kvm_apic_map { | 563 | struct kvm_apic_map { |
554 | struct rcu_head rcu; | 564 | struct rcu_head rcu; |
555 | u8 ldr_bits; | 565 | u8 mode; |
556 | /* fields bellow are used to decode ldr values in different modes */ | ||
557 | u32 cid_shift, cid_mask, lid_mask, broadcast; | ||
558 | struct kvm_lapic *phys_map[256]; | 566 | struct kvm_lapic *phys_map[256]; |
559 | /* first index is cluster id second is cpu id in a cluster */ | 567 | /* first index is cluster id second is cpu id in a cluster */ |
560 | struct kvm_lapic *logical_map[16][16]; | 568 | struct kvm_lapic *logical_map[16][16]; |
@@ -859,6 +867,8 @@ void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, | |||
859 | void kvm_mmu_reset_context(struct kvm_vcpu *vcpu); | 867 | void kvm_mmu_reset_context(struct kvm_vcpu *vcpu); |
860 | void kvm_mmu_slot_remove_write_access(struct kvm *kvm, | 868 | void kvm_mmu_slot_remove_write_access(struct kvm *kvm, |
861 | struct kvm_memory_slot *memslot); | 869 | struct kvm_memory_slot *memslot); |
870 | void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, | ||
871 | struct kvm_memory_slot *memslot); | ||
862 | void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm, | 872 | void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm, |
863 | struct kvm_memory_slot *memslot); | 873 | struct kvm_memory_slot *memslot); |
864 | void kvm_mmu_slot_largepage_remove_write_access(struct kvm *kvm, | 874 | void kvm_mmu_slot_largepage_remove_write_access(struct kvm *kvm, |
@@ -933,6 +943,7 @@ struct x86_emulate_ctxt; | |||
933 | int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); | 943 | int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); |
934 | void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); | 944 | void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); |
935 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); | 945 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); |
946 | int kvm_vcpu_halt(struct kvm_vcpu *vcpu); | ||
936 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); | 947 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); |
937 | 948 | ||
938 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); | 949 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); |
@@ -1128,7 +1139,6 @@ int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) | |||
1128 | int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); | 1139 | int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); |
1129 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | 1140 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); |
1130 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 1141 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
1131 | int cpuid_maxphyaddr(struct kvm_vcpu *vcpu); | ||
1132 | int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v); | 1142 | int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v); |
1133 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); | 1143 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); |
1134 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); | 1144 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); |
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index e62cf897f781..c1adf33fdd0d 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h | |||
@@ -115,7 +115,7 @@ static inline void kvm_spinlock_init(void) | |||
115 | 115 | ||
116 | static inline bool kvm_para_available(void) | 116 | static inline bool kvm_para_available(void) |
117 | { | 117 | { |
118 | return 0; | 118 | return false; |
119 | } | 119 | } |
120 | 120 | ||
121 | static inline unsigned int kvm_arch_para_features(void) | 121 | static inline unsigned int kvm_arch_para_features(void) |
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 95e11f79f123..f97fbe3abb67 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h | |||
@@ -51,8 +51,6 @@ extern int devmem_is_allowed(unsigned long pagenr); | |||
51 | extern unsigned long max_low_pfn_mapped; | 51 | extern unsigned long max_low_pfn_mapped; |
52 | extern unsigned long max_pfn_mapped; | 52 | extern unsigned long max_pfn_mapped; |
53 | 53 | ||
54 | extern bool kaslr_enabled; | ||
55 | |||
56 | static inline phys_addr_t get_max_mapped(void) | 54 | static inline phys_addr_t get_max_mapped(void) |
57 | { | 55 | { |
58 | return (phys_addr_t)max_pfn_mapped << PAGE_SHIFT; | 56 | return (phys_addr_t)max_pfn_mapped << PAGE_SHIFT; |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index fa1195dae425..164e3f8d3c3d 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -93,6 +93,8 @@ extern raw_spinlock_t pci_config_lock; | |||
93 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); | 93 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); |
94 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); | 94 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); |
95 | 95 | ||
96 | extern bool mp_should_keep_irq(struct device *dev); | ||
97 | |||
96 | struct pci_raw_ops { | 98 | struct pci_raw_ops { |
97 | int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, | 99 | int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, |
98 | int reg, int len, u32 *val); | 100 | int reg, int len, u32 *val); |
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index d6b078e9fa28..25b1cc07d496 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h | |||
@@ -95,6 +95,7 @@ unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src, | |||
95 | 95 | ||
96 | struct pvclock_vsyscall_time_info { | 96 | struct pvclock_vsyscall_time_info { |
97 | struct pvclock_vcpu_time_info pvti; | 97 | struct pvclock_vcpu_time_info pvti; |
98 | u32 migrate_count; | ||
98 | } __attribute__((__aligned__(SMP_CACHE_BYTES))); | 99 | } __attribute__((__aligned__(SMP_CACHE_BYTES))); |
99 | 100 | ||
100 | #define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info) | 101 | #define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info) |
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 12a26b979bf1..f2f9b39b274a 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h | |||
@@ -231,6 +231,6 @@ __copy_from_user_inatomic_nocache(void *dst, const void __user *src, | |||
231 | } | 231 | } |
232 | 232 | ||
233 | unsigned long | 233 | unsigned long |
234 | copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest); | 234 | copy_user_handle_tail(char *to, char *from, unsigned len); |
235 | 235 | ||
236 | #endif /* _ASM_X86_UACCESS_64_H */ | 236 | #endif /* _ASM_X86_UACCESS_64_H */ |
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 5fa9770035dc..c9a6d68b8d62 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h | |||
@@ -82,18 +82,15 @@ static inline int xsave_state_booting(struct xsave_struct *fx, u64 mask) | |||
82 | if (boot_cpu_has(X86_FEATURE_XSAVES)) | 82 | if (boot_cpu_has(X86_FEATURE_XSAVES)) |
83 | asm volatile("1:"XSAVES"\n\t" | 83 | asm volatile("1:"XSAVES"\n\t" |
84 | "2:\n\t" | 84 | "2:\n\t" |
85 | : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) | 85 | xstate_fault |
86 | : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) | ||
86 | : "memory"); | 87 | : "memory"); |
87 | else | 88 | else |
88 | asm volatile("1:"XSAVE"\n\t" | 89 | asm volatile("1:"XSAVE"\n\t" |
89 | "2:\n\t" | 90 | "2:\n\t" |
90 | : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) | 91 | xstate_fault |
92 | : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) | ||
91 | : "memory"); | 93 | : "memory"); |
92 | |||
93 | asm volatile(xstate_fault | ||
94 | : "0" (0) | ||
95 | : "memory"); | ||
96 | |||
97 | return err; | 94 | return err; |
98 | } | 95 | } |
99 | 96 | ||
@@ -112,18 +109,15 @@ static inline int xrstor_state_booting(struct xsave_struct *fx, u64 mask) | |||
112 | if (boot_cpu_has(X86_FEATURE_XSAVES)) | 109 | if (boot_cpu_has(X86_FEATURE_XSAVES)) |
113 | asm volatile("1:"XRSTORS"\n\t" | 110 | asm volatile("1:"XRSTORS"\n\t" |
114 | "2:\n\t" | 111 | "2:\n\t" |
115 | : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) | 112 | xstate_fault |
113 | : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) | ||
116 | : "memory"); | 114 | : "memory"); |
117 | else | 115 | else |
118 | asm volatile("1:"XRSTOR"\n\t" | 116 | asm volatile("1:"XRSTOR"\n\t" |
119 | "2:\n\t" | 117 | "2:\n\t" |
120 | : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) | 118 | xstate_fault |
119 | : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) | ||
121 | : "memory"); | 120 | : "memory"); |
122 | |||
123 | asm volatile(xstate_fault | ||
124 | : "0" (0) | ||
125 | : "memory"); | ||
126 | |||
127 | return err; | 121 | return err; |
128 | } | 122 | } |
129 | 123 | ||
@@ -149,9 +143,9 @@ static inline int xsave_state(struct xsave_struct *fx, u64 mask) | |||
149 | */ | 143 | */ |
150 | alternative_input_2( | 144 | alternative_input_2( |
151 | "1:"XSAVE, | 145 | "1:"XSAVE, |
152 | "1:"XSAVEOPT, | 146 | XSAVEOPT, |
153 | X86_FEATURE_XSAVEOPT, | 147 | X86_FEATURE_XSAVEOPT, |
154 | "1:"XSAVES, | 148 | XSAVES, |
155 | X86_FEATURE_XSAVES, | 149 | X86_FEATURE_XSAVES, |
156 | [fx] "D" (fx), "a" (lmask), "d" (hmask) : | 150 | [fx] "D" (fx), "a" (lmask), "d" (hmask) : |
157 | "memory"); | 151 | "memory"); |
@@ -178,7 +172,7 @@ static inline int xrstor_state(struct xsave_struct *fx, u64 mask) | |||
178 | */ | 172 | */ |
179 | alternative_input( | 173 | alternative_input( |
180 | "1: " XRSTOR, | 174 | "1: " XRSTOR, |
181 | "1: " XRSTORS, | 175 | XRSTORS, |
182 | X86_FEATURE_XSAVES, | 176 | X86_FEATURE_XSAVES, |
183 | "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) | 177 | "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) |
184 | : "memory"); | 178 | : "memory"); |
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index 44e6dd7e36a2..225b0988043a 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h | |||
@@ -7,7 +7,6 @@ | |||
7 | #define SETUP_DTB 2 | 7 | #define SETUP_DTB 2 |
8 | #define SETUP_PCI 3 | 8 | #define SETUP_PCI 3 |
9 | #define SETUP_EFI 4 | 9 | #define SETUP_EFI 4 |
10 | #define SETUP_KASLR 5 | ||
11 | 10 | ||
12 | /* ram_size flags */ | 11 | /* ram_size flags */ |
13 | #define RAMDISK_IMAGE_START_MASK 0x07FF | 12 | #define RAMDISK_IMAGE_START_MASK 0x07FF |
diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h index c5f1a1deb91a..1fe92181ee9e 100644 --- a/arch/x86/include/uapi/asm/vmx.h +++ b/arch/x86/include/uapi/asm/vmx.h | |||
@@ -67,6 +67,7 @@ | |||
67 | #define EXIT_REASON_EPT_VIOLATION 48 | 67 | #define EXIT_REASON_EPT_VIOLATION 48 |
68 | #define EXIT_REASON_EPT_MISCONFIG 49 | 68 | #define EXIT_REASON_EPT_MISCONFIG 49 |
69 | #define EXIT_REASON_INVEPT 50 | 69 | #define EXIT_REASON_INVEPT 50 |
70 | #define EXIT_REASON_RDTSCP 51 | ||
70 | #define EXIT_REASON_PREEMPTION_TIMER 52 | 71 | #define EXIT_REASON_PREEMPTION_TIMER 52 |
71 | #define EXIT_REASON_INVVPID 53 | 72 | #define EXIT_REASON_INVVPID 53 |
72 | #define EXIT_REASON_WBINVD 54 | 73 | #define EXIT_REASON_WBINVD 54 |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 3d525c6124f6..803b684676ff 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -1338,6 +1338,26 @@ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) | |||
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | /* | 1340 | /* |
1341 | * ACPI offers an alternative platform interface model that removes | ||
1342 | * ACPI hardware requirements for platforms that do not implement | ||
1343 | * the PC Architecture. | ||
1344 | * | ||
1345 | * We initialize the Hardware-reduced ACPI model here: | ||
1346 | */ | ||
1347 | static void __init acpi_reduced_hw_init(void) | ||
1348 | { | ||
1349 | if (acpi_gbl_reduced_hardware) { | ||
1350 | /* | ||
1351 | * Override x86_init functions and bypass legacy pic | ||
1352 | * in Hardware-reduced ACPI mode | ||
1353 | */ | ||
1354 | x86_init.timers.timer_init = x86_init_noop; | ||
1355 | x86_init.irqs.pre_vector_init = x86_init_noop; | ||
1356 | legacy_pic = &null_legacy_pic; | ||
1357 | } | ||
1358 | } | ||
1359 | |||
1360 | /* | ||
1341 | * If your system is blacklisted here, but you find that acpi=force | 1361 | * If your system is blacklisted here, but you find that acpi=force |
1342 | * works for you, please contact linux-acpi@vger.kernel.org | 1362 | * works for you, please contact linux-acpi@vger.kernel.org |
1343 | */ | 1363 | */ |
@@ -1536,6 +1556,11 @@ int __init early_acpi_boot_init(void) | |||
1536 | */ | 1556 | */ |
1537 | early_acpi_process_madt(); | 1557 | early_acpi_process_madt(); |
1538 | 1558 | ||
1559 | /* | ||
1560 | * Hardware-reduced ACPI mode initialization: | ||
1561 | */ | ||
1562 | acpi_reduced_hw_init(); | ||
1563 | |||
1539 | return 0; | 1564 | return 0; |
1540 | } | 1565 | } |
1541 | 1566 | ||
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index c2fd21fed002..017149cded07 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c | |||
@@ -37,10 +37,12 @@ static const struct apic apic_numachip; | |||
37 | static unsigned int get_apic_id(unsigned long x) | 37 | static unsigned int get_apic_id(unsigned long x) |
38 | { | 38 | { |
39 | unsigned long value; | 39 | unsigned long value; |
40 | unsigned int id; | 40 | unsigned int id = (x >> 24) & 0xff; |
41 | 41 | ||
42 | rdmsrl(MSR_FAM10H_NODE_ID, value); | 42 | if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { |
43 | id = ((x >> 24) & 0xffU) | ((value << 2) & 0xff00U); | 43 | rdmsrl(MSR_FAM10H_NODE_ID, value); |
44 | id |= (value << 2) & 0xff00; | ||
45 | } | ||
44 | 46 | ||
45 | return id; | 47 | return id; |
46 | } | 48 | } |
@@ -155,10 +157,18 @@ static int __init numachip_probe(void) | |||
155 | 157 | ||
156 | static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) | 158 | static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) |
157 | { | 159 | { |
158 | if (c->phys_proc_id != node) { | 160 | u64 val; |
159 | c->phys_proc_id = node; | 161 | u32 nodes = 1; |
160 | per_cpu(cpu_llc_id, smp_processor_id()) = node; | 162 | |
163 | this_cpu_write(cpu_llc_id, node); | ||
164 | |||
165 | /* Account for nodes per socket in multi-core-module processors */ | ||
166 | if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { | ||
167 | rdmsrl(MSR_FAM10H_NODE_ID, val); | ||
168 | nodes = ((val >> 3) & 7) + 1; | ||
161 | } | 169 | } |
170 | |||
171 | c->phys_proc_id = node / nodes; | ||
162 | } | 172 | } |
163 | 173 | ||
164 | static int __init numachip_system_init(void) | 174 | static int __init numachip_system_init(void) |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index b5c8ff5e9dfc..2346c95c6ab1 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1396,6 +1396,12 @@ void cpu_init(void) | |||
1396 | 1396 | ||
1397 | wait_for_master_cpu(cpu); | 1397 | wait_for_master_cpu(cpu); |
1398 | 1398 | ||
1399 | /* | ||
1400 | * Initialize the CR4 shadow before doing anything that could | ||
1401 | * try to read it. | ||
1402 | */ | ||
1403 | cr4_init_shadow(); | ||
1404 | |||
1399 | show_ucode_info_early(); | 1405 | show_ucode_info_early(); |
1400 | 1406 | ||
1401 | printk(KERN_INFO "Initializing CPU#%d\n", cpu); | 1407 | printk(KERN_INFO "Initializing CPU#%d\n", cpu); |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 94d7dcb12145..50163fa9034f 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -565,8 +565,8 @@ static const struct _tlb_table intel_tlb_table[] = { | |||
565 | { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" }, | 565 | { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" }, |
566 | { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" }, | 566 | { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" }, |
567 | { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" }, | 567 | { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" }, |
568 | { 0xb5, TLB_INST_4K, 64, " TLB_INST 4 KByte pages, 8-way set ssociative" }, | 568 | { 0xb5, TLB_INST_4K, 64, " TLB_INST 4 KByte pages, 8-way set associative" }, |
569 | { 0xb6, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 8-way set ssociative" }, | 569 | { 0xb6, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 8-way set associative" }, |
570 | { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" }, | 570 | { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" }, |
571 | { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" }, | 571 | { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" }, |
572 | { 0xc1, STLB_4K_2M, 1024, " STLB 4 KByte and 2 MByte pages, 8-way associative" }, | 572 | { 0xc1, STLB_4K_2M, 1024, " STLB 4 KByte and 2 MByte pages, 8-way associative" }, |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 498b6d967138..258990688a5e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -212,11 +212,11 @@ static struct event_constraint intel_hsw_event_constraints[] = { | |||
212 | INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */ | 212 | INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */ |
213 | INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ | 213 | INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ |
214 | /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */ | 214 | /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */ |
215 | INTEL_EVENT_CONSTRAINT(0x08a3, 0x4), | 215 | INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4), |
216 | /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */ | 216 | /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */ |
217 | INTEL_EVENT_CONSTRAINT(0x0ca3, 0x4), | 217 | INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4), |
218 | /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */ | 218 | /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */ |
219 | INTEL_EVENT_CONSTRAINT(0x04a3, 0xf), | 219 | INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), |
220 | EVENT_CONSTRAINT_END | 220 | EVENT_CONSTRAINT_END |
221 | }; | 221 | }; |
222 | 222 | ||
@@ -1649,11 +1649,11 @@ intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event | |||
1649 | if (c) | 1649 | if (c) |
1650 | return c; | 1650 | return c; |
1651 | 1651 | ||
1652 | c = intel_pebs_constraints(event); | 1652 | c = intel_shared_regs_constraints(cpuc, event); |
1653 | if (c) | 1653 | if (c) |
1654 | return c; | 1654 | return c; |
1655 | 1655 | ||
1656 | c = intel_shared_regs_constraints(cpuc, event); | 1656 | c = intel_pebs_constraints(event); |
1657 | if (c) | 1657 | if (c) |
1658 | return c; | 1658 | return c; |
1659 | 1659 | ||
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 000d4199b03e..31e2d5bf3e38 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -982,6 +982,9 @@ ENTRY(xen_hypervisor_callback) | |||
982 | ENTRY(xen_do_upcall) | 982 | ENTRY(xen_do_upcall) |
983 | 1: mov %esp, %eax | 983 | 1: mov %esp, %eax |
984 | call xen_evtchn_do_upcall | 984 | call xen_evtchn_do_upcall |
985 | #ifndef CONFIG_PREEMPT | ||
986 | call xen_maybe_preempt_hcall | ||
987 | #endif | ||
985 | jmp ret_from_intr | 988 | jmp ret_from_intr |
986 | CFI_ENDPROC | 989 | CFI_ENDPROC |
987 | ENDPROC(xen_hypervisor_callback) | 990 | ENDPROC(xen_hypervisor_callback) |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index db13655c3a2a..f0095a76c182 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -269,11 +269,14 @@ ENTRY(ret_from_fork) | |||
269 | testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? | 269 | testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? |
270 | jz 1f | 270 | jz 1f |
271 | 271 | ||
272 | testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET | 272 | /* |
273 | jnz int_ret_from_sys_call | 273 | * By the time we get here, we have no idea whether our pt_regs, |
274 | 274 | * ti flags, and ti status came from the 64-bit SYSCALL fast path, | |
275 | RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET | 275 | * the slow path, or one of the ia32entry paths. |
276 | jmp ret_from_sys_call # go to the SYSRET fastpath | 276 | * Use int_ret_from_sys_call to return, since it can safely handle |
277 | * all of the above. | ||
278 | */ | ||
279 | jmp int_ret_from_sys_call | ||
277 | 280 | ||
278 | 1: | 281 | 1: |
279 | subq $REST_SKIP, %rsp # leave space for volatiles | 282 | subq $REST_SKIP, %rsp # leave space for volatiles |
@@ -361,12 +364,21 @@ system_call_fastpath: | |||
361 | * Has incomplete stack frame and undefined top of stack. | 364 | * Has incomplete stack frame and undefined top of stack. |
362 | */ | 365 | */ |
363 | ret_from_sys_call: | 366 | ret_from_sys_call: |
364 | testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) | ||
365 | jnz int_ret_from_sys_call_fixup /* Go the the slow path */ | ||
366 | |||
367 | LOCKDEP_SYS_EXIT | 367 | LOCKDEP_SYS_EXIT |
368 | DISABLE_INTERRUPTS(CLBR_NONE) | 368 | DISABLE_INTERRUPTS(CLBR_NONE) |
369 | TRACE_IRQS_OFF | 369 | TRACE_IRQS_OFF |
370 | |||
371 | /* | ||
372 | * We must check ti flags with interrupts (or at least preemption) | ||
373 | * off because we must *never* return to userspace without | ||
374 | * processing exit work that is enqueued if we're preempted here. | ||
375 | * In particular, returning to userspace with any of the one-shot | ||
376 | * flags (TIF_NOTIFY_RESUME, TIF_USER_RETURN_NOTIFY, etc) set is | ||
377 | * very bad. | ||
378 | */ | ||
379 | testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) | ||
380 | jnz int_ret_from_sys_call_fixup /* Go the the slow path */ | ||
381 | |||
370 | CFI_REMEMBER_STATE | 382 | CFI_REMEMBER_STATE |
371 | /* | 383 | /* |
372 | * sysretq will re-enable interrupts: | 384 | * sysretq will re-enable interrupts: |
@@ -383,7 +395,7 @@ ret_from_sys_call: | |||
383 | 395 | ||
384 | int_ret_from_sys_call_fixup: | 396 | int_ret_from_sys_call_fixup: |
385 | FIXUP_TOP_OF_STACK %r11, -ARGOFFSET | 397 | FIXUP_TOP_OF_STACK %r11, -ARGOFFSET |
386 | jmp int_ret_from_sys_call | 398 | jmp int_ret_from_sys_call_irqs_off |
387 | 399 | ||
388 | /* Do syscall tracing */ | 400 | /* Do syscall tracing */ |
389 | tracesys: | 401 | tracesys: |
@@ -429,6 +441,7 @@ tracesys_phase2: | |||
429 | GLOBAL(int_ret_from_sys_call) | 441 | GLOBAL(int_ret_from_sys_call) |
430 | DISABLE_INTERRUPTS(CLBR_NONE) | 442 | DISABLE_INTERRUPTS(CLBR_NONE) |
431 | TRACE_IRQS_OFF | 443 | TRACE_IRQS_OFF |
444 | int_ret_from_sys_call_irqs_off: | ||
432 | movl $_TIF_ALLWORK_MASK,%edi | 445 | movl $_TIF_ALLWORK_MASK,%edi |
433 | /* edi: mask to check */ | 446 | /* edi: mask to check */ |
434 | GLOBAL(int_with_check) | 447 | GLOBAL(int_with_check) |
@@ -786,7 +799,21 @@ retint_swapgs: /* return to user-space */ | |||
786 | cmpq %r11,(EFLAGS-ARGOFFSET)(%rsp) /* R11 == RFLAGS */ | 799 | cmpq %r11,(EFLAGS-ARGOFFSET)(%rsp) /* R11 == RFLAGS */ |
787 | jne opportunistic_sysret_failed | 800 | jne opportunistic_sysret_failed |
788 | 801 | ||
789 | testq $X86_EFLAGS_RF,%r11 /* sysret can't restore RF */ | 802 | /* |
803 | * SYSRET can't restore RF. SYSRET can restore TF, but unlike IRET, | ||
804 | * restoring TF results in a trap from userspace immediately after | ||
805 | * SYSRET. This would cause an infinite loop whenever #DB happens | ||
806 | * with register state that satisfies the opportunistic SYSRET | ||
807 | * conditions. For example, single-stepping this user code: | ||
808 | * | ||
809 | * movq $stuck_here,%rcx | ||
810 | * pushfq | ||
811 | * popq %r11 | ||
812 | * stuck_here: | ||
813 | * | ||
814 | * would never get past 'stuck_here'. | ||
815 | */ | ||
816 | testq $(X86_EFLAGS_RF|X86_EFLAGS_TF), %r11 | ||
790 | jnz opportunistic_sysret_failed | 817 | jnz opportunistic_sysret_failed |
791 | 818 | ||
792 | /* nothing to check for RSP */ | 819 | /* nothing to check for RSP */ |
@@ -1208,6 +1235,9 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) | |||
1208 | popq %rsp | 1235 | popq %rsp |
1209 | CFI_DEF_CFA_REGISTER rsp | 1236 | CFI_DEF_CFA_REGISTER rsp |
1210 | decl PER_CPU_VAR(irq_count) | 1237 | decl PER_CPU_VAR(irq_count) |
1238 | #ifndef CONFIG_PREEMPT | ||
1239 | call xen_maybe_preempt_hcall | ||
1240 | #endif | ||
1211 | jmp error_exit | 1241 | jmp error_exit |
1212 | CFI_ENDPROC | 1242 | CFI_ENDPROC |
1213 | END(xen_do_hypervisor_callback) | 1243 | END(xen_do_hypervisor_callback) |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 7ec1d5f8d283..25ecd56cefa8 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -72,7 +72,7 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = | |||
72 | { "bx", 8, offsetof(struct pt_regs, bx) }, | 72 | { "bx", 8, offsetof(struct pt_regs, bx) }, |
73 | { "cx", 8, offsetof(struct pt_regs, cx) }, | 73 | { "cx", 8, offsetof(struct pt_regs, cx) }, |
74 | { "dx", 8, offsetof(struct pt_regs, dx) }, | 74 | { "dx", 8, offsetof(struct pt_regs, dx) }, |
75 | { "si", 8, offsetof(struct pt_regs, dx) }, | 75 | { "si", 8, offsetof(struct pt_regs, si) }, |
76 | { "di", 8, offsetof(struct pt_regs, di) }, | 76 | { "di", 8, offsetof(struct pt_regs, di) }, |
77 | { "bp", 8, offsetof(struct pt_regs, bp) }, | 77 | { "bp", 8, offsetof(struct pt_regs, bp) }, |
78 | { "sp", 8, offsetof(struct pt_regs, sp) }, | 78 | { "sp", 8, offsetof(struct pt_regs, sp) }, |
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 6a1146ea4d4d..4e3d5a9621fe 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
@@ -223,27 +223,48 @@ static unsigned long | |||
223 | __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) | 223 | __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) |
224 | { | 224 | { |
225 | struct kprobe *kp; | 225 | struct kprobe *kp; |
226 | unsigned long faddr; | ||
226 | 227 | ||
227 | kp = get_kprobe((void *)addr); | 228 | kp = get_kprobe((void *)addr); |
228 | /* There is no probe, return original address */ | 229 | faddr = ftrace_location(addr); |
229 | if (!kp) | 230 | /* |
231 | * Addresses inside the ftrace location are refused by | ||
232 | * arch_check_ftrace_location(). Something went terribly wrong | ||
233 | * if such an address is checked here. | ||
234 | */ | ||
235 | if (WARN_ON(faddr && faddr != addr)) | ||
236 | return 0UL; | ||
237 | /* | ||
238 | * Use the current code if it is not modified by Kprobe | ||
239 | * and it cannot be modified by ftrace. | ||
240 | */ | ||
241 | if (!kp && !faddr) | ||
230 | return addr; | 242 | return addr; |
231 | 243 | ||
232 | /* | 244 | /* |
233 | * Basically, kp->ainsn.insn has an original instruction. | 245 | * Basically, kp->ainsn.insn has an original instruction. |
234 | * However, RIP-relative instruction can not do single-stepping | 246 | * However, RIP-relative instruction can not do single-stepping |
235 | * at different place, __copy_instruction() tweaks the displacement of | 247 | * at different place, __copy_instruction() tweaks the displacement of |
236 | * that instruction. In that case, we can't recover the instruction | 248 | * that instruction. In that case, we can't recover the instruction |
237 | * from the kp->ainsn.insn. | 249 | * from the kp->ainsn.insn. |
238 | * | 250 | * |
239 | * On the other hand, kp->opcode has a copy of the first byte of | 251 | * On the other hand, in case on normal Kprobe, kp->opcode has a copy |
240 | * the probed instruction, which is overwritten by int3. And | 252 | * of the first byte of the probed instruction, which is overwritten |
241 | * the instruction at kp->addr is not modified by kprobes except | 253 | * by int3. And the instruction at kp->addr is not modified by kprobes |
242 | * for the first byte, we can recover the original instruction | 254 | * except for the first byte, we can recover the original instruction |
243 | * from it and kp->opcode. | 255 | * from it and kp->opcode. |
256 | * | ||
257 | * In case of Kprobes using ftrace, we do not have a copy of | ||
258 | * the original instruction. In fact, the ftrace location might | ||
259 | * be modified at anytime and even could be in an inconsistent state. | ||
260 | * Fortunately, we know that the original code is the ideal 5-byte | ||
261 | * long NOP. | ||
244 | */ | 262 | */ |
245 | memcpy(buf, kp->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | 263 | memcpy(buf, (void *)addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); |
246 | buf[0] = kp->opcode; | 264 | if (faddr) |
265 | memcpy(buf, ideal_nops[NOP_ATOMIC5], 5); | ||
266 | else | ||
267 | buf[0] = kp->opcode; | ||
247 | return (unsigned long)buf; | 268 | return (unsigned long)buf; |
248 | } | 269 | } |
249 | 270 | ||
@@ -251,6 +272,7 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) | |||
251 | * Recover the probed instruction at addr for further analysis. | 272 | * Recover the probed instruction at addr for further analysis. |
252 | * Caller must lock kprobes by kprobe_mutex, or disable preemption | 273 | * Caller must lock kprobes by kprobe_mutex, or disable preemption |
253 | * for preventing to release referencing kprobes. | 274 | * for preventing to release referencing kprobes. |
275 | * Returns zero if the instruction can not get recovered. | ||
254 | */ | 276 | */ |
255 | unsigned long recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr) | 277 | unsigned long recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr) |
256 | { | 278 | { |
@@ -285,6 +307,8 @@ static int can_probe(unsigned long paddr) | |||
285 | * normally used, we just go through if there is no kprobe. | 307 | * normally used, we just go through if there is no kprobe. |
286 | */ | 308 | */ |
287 | __addr = recover_probed_instruction(buf, addr); | 309 | __addr = recover_probed_instruction(buf, addr); |
310 | if (!__addr) | ||
311 | return 0; | ||
288 | kernel_insn_init(&insn, (void *)__addr, MAX_INSN_SIZE); | 312 | kernel_insn_init(&insn, (void *)__addr, MAX_INSN_SIZE); |
289 | insn_get_length(&insn); | 313 | insn_get_length(&insn); |
290 | 314 | ||
@@ -333,6 +357,8 @@ int __copy_instruction(u8 *dest, u8 *src) | |||
333 | unsigned long recovered_insn = | 357 | unsigned long recovered_insn = |
334 | recover_probed_instruction(buf, (unsigned long)src); | 358 | recover_probed_instruction(buf, (unsigned long)src); |
335 | 359 | ||
360 | if (!recovered_insn) | ||
361 | return 0; | ||
336 | kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); | 362 | kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); |
337 | insn_get_length(&insn); | 363 | insn_get_length(&insn); |
338 | /* Another subsystem puts a breakpoint, failed to recover */ | 364 | /* Another subsystem puts a breakpoint, failed to recover */ |
diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index 0dd8d089c315..7b3b9d15c47a 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c | |||
@@ -259,6 +259,8 @@ static int can_optimize(unsigned long paddr) | |||
259 | */ | 259 | */ |
260 | return 0; | 260 | return 0; |
261 | recovered_insn = recover_probed_instruction(buf, addr); | 261 | recovered_insn = recover_probed_instruction(buf, addr); |
262 | if (!recovered_insn) | ||
263 | return 0; | ||
262 | kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); | 264 | kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); |
263 | insn_get_length(&insn); | 265 | insn_get_length(&insn); |
264 | /* Another subsystem puts a breakpoint */ | 266 | /* Another subsystem puts a breakpoint */ |
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 9bbb9b35c144..d1ac80b72c72 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
@@ -47,13 +47,21 @@ do { \ | |||
47 | 47 | ||
48 | #ifdef CONFIG_RANDOMIZE_BASE | 48 | #ifdef CONFIG_RANDOMIZE_BASE |
49 | static unsigned long module_load_offset; | 49 | static unsigned long module_load_offset; |
50 | static int randomize_modules = 1; | ||
50 | 51 | ||
51 | /* Mutex protects the module_load_offset. */ | 52 | /* Mutex protects the module_load_offset. */ |
52 | static DEFINE_MUTEX(module_kaslr_mutex); | 53 | static DEFINE_MUTEX(module_kaslr_mutex); |
53 | 54 | ||
55 | static int __init parse_nokaslr(char *p) | ||
56 | { | ||
57 | randomize_modules = 0; | ||
58 | return 0; | ||
59 | } | ||
60 | early_param("nokaslr", parse_nokaslr); | ||
61 | |||
54 | static unsigned long int get_module_load_offset(void) | 62 | static unsigned long int get_module_load_offset(void) |
55 | { | 63 | { |
56 | if (kaslr_enabled) { | 64 | if (randomize_modules) { |
57 | mutex_lock(&module_kaslr_mutex); | 65 | mutex_lock(&module_kaslr_mutex); |
58 | /* | 66 | /* |
59 | * Calculate the module_load_offset the first time this | 67 | * Calculate the module_load_offset the first time this |
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 2f355d229a58..e5ecd20e72dd 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c | |||
@@ -141,7 +141,46 @@ void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock, | |||
141 | set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); | 141 | set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); |
142 | } | 142 | } |
143 | 143 | ||
144 | static struct pvclock_vsyscall_time_info *pvclock_vdso_info; | ||
145 | |||
146 | static struct pvclock_vsyscall_time_info * | ||
147 | pvclock_get_vsyscall_user_time_info(int cpu) | ||
148 | { | ||
149 | if (!pvclock_vdso_info) { | ||
150 | BUG(); | ||
151 | return NULL; | ||
152 | } | ||
153 | |||
154 | return &pvclock_vdso_info[cpu]; | ||
155 | } | ||
156 | |||
157 | struct pvclock_vcpu_time_info *pvclock_get_vsyscall_time_info(int cpu) | ||
158 | { | ||
159 | return &pvclock_get_vsyscall_user_time_info(cpu)->pvti; | ||
160 | } | ||
161 | |||
144 | #ifdef CONFIG_X86_64 | 162 | #ifdef CONFIG_X86_64 |
163 | static int pvclock_task_migrate(struct notifier_block *nb, unsigned long l, | ||
164 | void *v) | ||
165 | { | ||
166 | struct task_migration_notifier *mn = v; | ||
167 | struct pvclock_vsyscall_time_info *pvti; | ||
168 | |||
169 | pvti = pvclock_get_vsyscall_user_time_info(mn->from_cpu); | ||
170 | |||
171 | /* this is NULL when pvclock vsyscall is not initialized */ | ||
172 | if (unlikely(pvti == NULL)) | ||
173 | return NOTIFY_DONE; | ||
174 | |||
175 | pvti->migrate_count++; | ||
176 | |||
177 | return NOTIFY_DONE; | ||
178 | } | ||
179 | |||
180 | static struct notifier_block pvclock_migrate = { | ||
181 | .notifier_call = pvclock_task_migrate, | ||
182 | }; | ||
183 | |||
145 | /* | 184 | /* |
146 | * Initialize the generic pvclock vsyscall state. This will allocate | 185 | * Initialize the generic pvclock vsyscall state. This will allocate |
147 | * a/some page(s) for the per-vcpu pvclock information, set up a | 186 | * a/some page(s) for the per-vcpu pvclock information, set up a |
@@ -155,12 +194,17 @@ int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i, | |||
155 | 194 | ||
156 | WARN_ON (size != PVCLOCK_VSYSCALL_NR_PAGES*PAGE_SIZE); | 195 | WARN_ON (size != PVCLOCK_VSYSCALL_NR_PAGES*PAGE_SIZE); |
157 | 196 | ||
197 | pvclock_vdso_info = i; | ||
198 | |||
158 | for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) { | 199 | for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) { |
159 | __set_fixmap(PVCLOCK_FIXMAP_BEGIN + idx, | 200 | __set_fixmap(PVCLOCK_FIXMAP_BEGIN + idx, |
160 | __pa(i) + (idx*PAGE_SIZE), | 201 | __pa(i) + (idx*PAGE_SIZE), |
161 | PAGE_KERNEL_VVAR); | 202 | PAGE_KERNEL_VVAR); |
162 | } | 203 | } |
163 | 204 | ||
205 | |||
206 | register_task_migration_notifier(&pvclock_migrate); | ||
207 | |||
164 | return 0; | 208 | return 0; |
165 | } | 209 | } |
166 | #endif | 210 | #endif |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index bae6c609888e..86db4bcd7ce5 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -183,6 +183,16 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
183 | }, | 183 | }, |
184 | }, | 184 | }, |
185 | 185 | ||
186 | /* ASRock */ | ||
187 | { /* Handle problems with rebooting on ASRock Q1900DC-ITX */ | ||
188 | .callback = set_pci_reboot, | ||
189 | .ident = "ASRock Q1900DC-ITX", | ||
190 | .matches = { | ||
191 | DMI_MATCH(DMI_BOARD_VENDOR, "ASRock"), | ||
192 | DMI_MATCH(DMI_BOARD_NAME, "Q1900DC-ITX"), | ||
193 | }, | ||
194 | }, | ||
195 | |||
186 | /* ASUS */ | 196 | /* ASUS */ |
187 | { /* Handle problems with rebooting on ASUS P4S800 */ | 197 | { /* Handle problems with rebooting on ASUS P4S800 */ |
188 | .callback = set_bios_reboot, | 198 | .callback = set_bios_reboot, |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 98dc9317286e..0a2421cca01f 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -122,8 +122,6 @@ | |||
122 | unsigned long max_low_pfn_mapped; | 122 | unsigned long max_low_pfn_mapped; |
123 | unsigned long max_pfn_mapped; | 123 | unsigned long max_pfn_mapped; |
124 | 124 | ||
125 | bool __read_mostly kaslr_enabled = false; | ||
126 | |||
127 | #ifdef CONFIG_DMI | 125 | #ifdef CONFIG_DMI |
128 | RESERVE_BRK(dmi_alloc, 65536); | 126 | RESERVE_BRK(dmi_alloc, 65536); |
129 | #endif | 127 | #endif |
@@ -427,11 +425,6 @@ static void __init reserve_initrd(void) | |||
427 | } | 425 | } |
428 | #endif /* CONFIG_BLK_DEV_INITRD */ | 426 | #endif /* CONFIG_BLK_DEV_INITRD */ |
429 | 427 | ||
430 | static void __init parse_kaslr_setup(u64 pa_data, u32 data_len) | ||
431 | { | ||
432 | kaslr_enabled = (bool)(pa_data + sizeof(struct setup_data)); | ||
433 | } | ||
434 | |||
435 | static void __init parse_setup_data(void) | 428 | static void __init parse_setup_data(void) |
436 | { | 429 | { |
437 | struct setup_data *data; | 430 | struct setup_data *data; |
@@ -457,9 +450,6 @@ static void __init parse_setup_data(void) | |||
457 | case SETUP_EFI: | 450 | case SETUP_EFI: |
458 | parse_efi_setup(pa_data, data_len); | 451 | parse_efi_setup(pa_data, data_len); |
459 | break; | 452 | break; |
460 | case SETUP_KASLR: | ||
461 | parse_kaslr_setup(pa_data, data_len); | ||
462 | break; | ||
463 | default: | 453 | default: |
464 | break; | 454 | break; |
465 | } | 455 | } |
@@ -842,14 +832,10 @@ static void __init trim_low_memory_range(void) | |||
842 | static int | 832 | static int |
843 | dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) | 833 | dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) |
844 | { | 834 | { |
845 | if (kaslr_enabled) | 835 | pr_emerg("Kernel Offset: 0x%lx from 0x%lx " |
846 | pr_emerg("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n", | 836 | "(relocation range: 0x%lx-0x%lx)\n", |
847 | (unsigned long)&_text - __START_KERNEL, | 837 | (unsigned long)&_text - __START_KERNEL, __START_KERNEL, |
848 | __START_KERNEL, | 838 | __START_KERNEL_map, MODULES_VADDR-1); |
849 | __START_KERNEL_map, | ||
850 | MODULES_VADDR-1); | ||
851 | else | ||
852 | pr_emerg("Kernel Offset: disabled\n"); | ||
853 | 839 | ||
854 | return 0; | 840 | return 0; |
855 | } | 841 | } |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 9d2073e2ecc9..4ff5d162ff9f 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -384,7 +384,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) | |||
384 | goto exit; | 384 | goto exit; |
385 | conditional_sti(regs); | 385 | conditional_sti(regs); |
386 | 386 | ||
387 | if (!user_mode(regs)) | 387 | if (!user_mode_vm(regs)) |
388 | die("bounds", regs, error_code); | 388 | die("bounds", regs, error_code); |
389 | 389 | ||
390 | if (!cpu_feature_enabled(X86_FEATURE_MPX)) { | 390 | if (!cpu_feature_enabled(X86_FEATURE_MPX)) { |
@@ -637,7 +637,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) | |||
637 | * then it's very likely the result of an icebp/int01 trap. | 637 | * then it's very likely the result of an icebp/int01 trap. |
638 | * User wants a sigtrap for that. | 638 | * User wants a sigtrap for that. |
639 | */ | 639 | */ |
640 | if (!dr6 && user_mode(regs)) | 640 | if (!dr6 && user_mode_vm(regs)) |
641 | user_icebp = 1; | 641 | user_icebp = 1; |
642 | 642 | ||
643 | /* Catch kmemcheck conditions first of all! */ | 643 | /* Catch kmemcheck conditions first of all! */ |
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 34f66e58a896..cdc6cf903078 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c | |||
@@ -379,7 +379,7 @@ int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size) | |||
379 | * thread's fpu state, reconstruct fxstate from the fsave | 379 | * thread's fpu state, reconstruct fxstate from the fsave |
380 | * header. Sanitize the copied state etc. | 380 | * header. Sanitize the copied state etc. |
381 | */ | 381 | */ |
382 | struct xsave_struct *xsave = &tsk->thread.fpu.state->xsave; | 382 | struct fpu *fpu = &tsk->thread.fpu; |
383 | struct user_i387_ia32_struct env; | 383 | struct user_i387_ia32_struct env; |
384 | int err = 0; | 384 | int err = 0; |
385 | 385 | ||
@@ -393,14 +393,15 @@ int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size) | |||
393 | */ | 393 | */ |
394 | drop_fpu(tsk); | 394 | drop_fpu(tsk); |
395 | 395 | ||
396 | if (__copy_from_user(xsave, buf_fx, state_size) || | 396 | if (__copy_from_user(&fpu->state->xsave, buf_fx, state_size) || |
397 | __copy_from_user(&env, buf, sizeof(env))) { | 397 | __copy_from_user(&env, buf, sizeof(env))) { |
398 | fpu_finit(fpu); | ||
398 | err = -1; | 399 | err = -1; |
399 | } else { | 400 | } else { |
400 | sanitize_restored_xstate(tsk, &env, xstate_bv, fx_only); | 401 | sanitize_restored_xstate(tsk, &env, xstate_bv, fx_only); |
401 | set_used_math(); | ||
402 | } | 402 | } |
403 | 403 | ||
404 | set_used_math(); | ||
404 | if (use_eager_fpu()) { | 405 | if (use_eager_fpu()) { |
405 | preempt_disable(); | 406 | preempt_disable(); |
406 | math_state_restore(); | 407 | math_state_restore(); |
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 08f790dfadc9..16e8f962eaad 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | ccflags-y += -Ivirt/kvm -Iarch/x86/kvm | 2 | ccflags-y += -Iarch/x86/kvm |
3 | 3 | ||
4 | CFLAGS_x86.o := -I. | 4 | CFLAGS_x86.o := -I. |
5 | CFLAGS_svm.o := -I. | 5 | CFLAGS_svm.o := -I. |
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 8a80737ee6e6..59b69f6a2844 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
@@ -104,6 +104,9 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) | |||
104 | ((best->eax & 0xff00) >> 8) != 0) | 104 | ((best->eax & 0xff00) >> 8) != 0) |
105 | return -EINVAL; | 105 | return -EINVAL; |
106 | 106 | ||
107 | /* Update physical-address width */ | ||
108 | vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); | ||
109 | |||
107 | kvm_pmu_cpuid_update(vcpu); | 110 | kvm_pmu_cpuid_update(vcpu); |
108 | return 0; | 111 | return 0; |
109 | } | 112 | } |
@@ -135,6 +138,21 @@ static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu) | |||
135 | } | 138 | } |
136 | } | 139 | } |
137 | 140 | ||
141 | int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu) | ||
142 | { | ||
143 | struct kvm_cpuid_entry2 *best; | ||
144 | |||
145 | best = kvm_find_cpuid_entry(vcpu, 0x80000000, 0); | ||
146 | if (!best || best->eax < 0x80000008) | ||
147 | goto not_found; | ||
148 | best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); | ||
149 | if (best) | ||
150 | return best->eax & 0xff; | ||
151 | not_found: | ||
152 | return 36; | ||
153 | } | ||
154 | EXPORT_SYMBOL_GPL(cpuid_query_maxphyaddr); | ||
155 | |||
138 | /* when an old userspace process fills a new kernel module */ | 156 | /* when an old userspace process fills a new kernel module */ |
139 | int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, | 157 | int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, |
140 | struct kvm_cpuid *cpuid, | 158 | struct kvm_cpuid *cpuid, |
@@ -757,21 +775,6 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, | |||
757 | } | 775 | } |
758 | EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry); | 776 | EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry); |
759 | 777 | ||
760 | int cpuid_maxphyaddr(struct kvm_vcpu *vcpu) | ||
761 | { | ||
762 | struct kvm_cpuid_entry2 *best; | ||
763 | |||
764 | best = kvm_find_cpuid_entry(vcpu, 0x80000000, 0); | ||
765 | if (!best || best->eax < 0x80000008) | ||
766 | goto not_found; | ||
767 | best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); | ||
768 | if (best) | ||
769 | return best->eax & 0xff; | ||
770 | not_found: | ||
771 | return 36; | ||
772 | } | ||
773 | EXPORT_SYMBOL_GPL(cpuid_maxphyaddr); | ||
774 | |||
775 | /* | 778 | /* |
776 | * If no match is found, check whether we exceed the vCPU's limit | 779 | * If no match is found, check whether we exceed the vCPU's limit |
777 | * and return the content of the highest valid _standard_ leaf instead. | 780 | * and return the content of the highest valid _standard_ leaf instead. |
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index 4452eedfaedd..c3b1ad9fca81 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h | |||
@@ -20,13 +20,19 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, | |||
20 | struct kvm_cpuid_entry2 __user *entries); | 20 | struct kvm_cpuid_entry2 __user *entries); |
21 | void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); | 21 | void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); |
22 | 22 | ||
23 | int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu); | ||
24 | |||
25 | static inline int cpuid_maxphyaddr(struct kvm_vcpu *vcpu) | ||
26 | { | ||
27 | return vcpu->arch.maxphyaddr; | ||
28 | } | ||
23 | 29 | ||
24 | static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) | 30 | static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) |
25 | { | 31 | { |
26 | struct kvm_cpuid_entry2 *best; | 32 | struct kvm_cpuid_entry2 *best; |
27 | 33 | ||
28 | if (!static_cpu_has(X86_FEATURE_XSAVE)) | 34 | if (!static_cpu_has(X86_FEATURE_XSAVE)) |
29 | return 0; | 35 | return false; |
30 | 36 | ||
31 | best = kvm_find_cpuid_entry(vcpu, 1, 0); | 37 | best = kvm_find_cpuid_entry(vcpu, 1, 0); |
32 | return best && (best->ecx & bit(X86_FEATURE_XSAVE)); | 38 | return best && (best->ecx & bit(X86_FEATURE_XSAVE)); |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e0b794a84c35..630bcb0d7a04 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -248,27 +248,7 @@ struct mode_dual { | |||
248 | struct opcode mode64; | 248 | struct opcode mode64; |
249 | }; | 249 | }; |
250 | 250 | ||
251 | /* EFLAGS bit definitions. */ | ||
252 | #define EFLG_ID (1<<21) | ||
253 | #define EFLG_VIP (1<<20) | ||
254 | #define EFLG_VIF (1<<19) | ||
255 | #define EFLG_AC (1<<18) | ||
256 | #define EFLG_VM (1<<17) | ||
257 | #define EFLG_RF (1<<16) | ||
258 | #define EFLG_IOPL (3<<12) | ||
259 | #define EFLG_NT (1<<14) | ||
260 | #define EFLG_OF (1<<11) | ||
261 | #define EFLG_DF (1<<10) | ||
262 | #define EFLG_IF (1<<9) | ||
263 | #define EFLG_TF (1<<8) | ||
264 | #define EFLG_SF (1<<7) | ||
265 | #define EFLG_ZF (1<<6) | ||
266 | #define EFLG_AF (1<<4) | ||
267 | #define EFLG_PF (1<<2) | ||
268 | #define EFLG_CF (1<<0) | ||
269 | |||
270 | #define EFLG_RESERVED_ZEROS_MASK 0xffc0802a | 251 | #define EFLG_RESERVED_ZEROS_MASK 0xffc0802a |
271 | #define EFLG_RESERVED_ONE_MASK 2 | ||
272 | 252 | ||
273 | enum x86_transfer_type { | 253 | enum x86_transfer_type { |
274 | X86_TRANSFER_NONE, | 254 | X86_TRANSFER_NONE, |
@@ -317,7 +297,8 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) | |||
317 | * These EFLAGS bits are restored from saved value during emulation, and | 297 | * These EFLAGS bits are restored from saved value during emulation, and |
318 | * any changes are written back to the saved value after emulation. | 298 | * any changes are written back to the saved value after emulation. |
319 | */ | 299 | */ |
320 | #define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF) | 300 | #define EFLAGS_MASK (X86_EFLAGS_OF|X86_EFLAGS_SF|X86_EFLAGS_ZF|X86_EFLAGS_AF|\ |
301 | X86_EFLAGS_PF|X86_EFLAGS_CF) | ||
321 | 302 | ||
322 | #ifdef CONFIG_X86_64 | 303 | #ifdef CONFIG_X86_64 |
323 | #define ON64(x) x | 304 | #define ON64(x) x |
@@ -478,6 +459,25 @@ static void assign_masked(ulong *dest, ulong src, ulong mask) | |||
478 | *dest = (*dest & ~mask) | (src & mask); | 459 | *dest = (*dest & ~mask) | (src & mask); |
479 | } | 460 | } |
480 | 461 | ||
462 | static void assign_register(unsigned long *reg, u64 val, int bytes) | ||
463 | { | ||
464 | /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ | ||
465 | switch (bytes) { | ||
466 | case 1: | ||
467 | *(u8 *)reg = (u8)val; | ||
468 | break; | ||
469 | case 2: | ||
470 | *(u16 *)reg = (u16)val; | ||
471 | break; | ||
472 | case 4: | ||
473 | *reg = (u32)val; | ||
474 | break; /* 64b: zero-extend */ | ||
475 | case 8: | ||
476 | *reg = val; | ||
477 | break; | ||
478 | } | ||
479 | } | ||
480 | |||
481 | static inline unsigned long ad_mask(struct x86_emulate_ctxt *ctxt) | 481 | static inline unsigned long ad_mask(struct x86_emulate_ctxt *ctxt) |
482 | { | 482 | { |
483 | return (1UL << (ctxt->ad_bytes << 3)) - 1; | 483 | return (1UL << (ctxt->ad_bytes << 3)) - 1; |
@@ -943,6 +943,22 @@ FASTOP2(xadd); | |||
943 | 943 | ||
944 | FASTOP2R(cmp, cmp_r); | 944 | FASTOP2R(cmp, cmp_r); |
945 | 945 | ||
946 | static int em_bsf_c(struct x86_emulate_ctxt *ctxt) | ||
947 | { | ||
948 | /* If src is zero, do not writeback, but update flags */ | ||
949 | if (ctxt->src.val == 0) | ||
950 | ctxt->dst.type = OP_NONE; | ||
951 | return fastop(ctxt, em_bsf); | ||
952 | } | ||
953 | |||
954 | static int em_bsr_c(struct x86_emulate_ctxt *ctxt) | ||
955 | { | ||
956 | /* If src is zero, do not writeback, but update flags */ | ||
957 | if (ctxt->src.val == 0) | ||
958 | ctxt->dst.type = OP_NONE; | ||
959 | return fastop(ctxt, em_bsr); | ||
960 | } | ||
961 | |||
946 | static u8 test_cc(unsigned int condition, unsigned long flags) | 962 | static u8 test_cc(unsigned int condition, unsigned long flags) |
947 | { | 963 | { |
948 | u8 rc; | 964 | u8 rc; |
@@ -1399,7 +1415,7 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt, | |||
1399 | unsigned int in_page, n; | 1415 | unsigned int in_page, n; |
1400 | unsigned int count = ctxt->rep_prefix ? | 1416 | unsigned int count = ctxt->rep_prefix ? |
1401 | address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) : 1; | 1417 | address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) : 1; |
1402 | in_page = (ctxt->eflags & EFLG_DF) ? | 1418 | in_page = (ctxt->eflags & X86_EFLAGS_DF) ? |
1403 | offset_in_page(reg_read(ctxt, VCPU_REGS_RDI)) : | 1419 | offset_in_page(reg_read(ctxt, VCPU_REGS_RDI)) : |
1404 | PAGE_SIZE - offset_in_page(reg_read(ctxt, VCPU_REGS_RDI)); | 1420 | PAGE_SIZE - offset_in_page(reg_read(ctxt, VCPU_REGS_RDI)); |
1405 | n = min3(in_page, (unsigned int)sizeof(rc->data) / size, count); | 1421 | n = min3(in_page, (unsigned int)sizeof(rc->data) / size, count); |
@@ -1412,7 +1428,7 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt, | |||
1412 | } | 1428 | } |
1413 | 1429 | ||
1414 | if (ctxt->rep_prefix && (ctxt->d & String) && | 1430 | if (ctxt->rep_prefix && (ctxt->d & String) && |
1415 | !(ctxt->eflags & EFLG_DF)) { | 1431 | !(ctxt->eflags & X86_EFLAGS_DF)) { |
1416 | ctxt->dst.data = rc->data + rc->pos; | 1432 | ctxt->dst.data = rc->data + rc->pos; |
1417 | ctxt->dst.type = OP_MEM_STR; | 1433 | ctxt->dst.type = OP_MEM_STR; |
1418 | ctxt->dst.count = (rc->end - rc->pos) / size; | 1434 | ctxt->dst.count = (rc->end - rc->pos) / size; |
@@ -1691,21 +1707,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
1691 | 1707 | ||
1692 | static void write_register_operand(struct operand *op) | 1708 | static void write_register_operand(struct operand *op) |
1693 | { | 1709 | { |
1694 | /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ | 1710 | return assign_register(op->addr.reg, op->val, op->bytes); |
1695 | switch (op->bytes) { | ||
1696 | case 1: | ||
1697 | *(u8 *)op->addr.reg = (u8)op->val; | ||
1698 | break; | ||
1699 | case 2: | ||
1700 | *(u16 *)op->addr.reg = (u16)op->val; | ||
1701 | break; | ||
1702 | case 4: | ||
1703 | *op->addr.reg = (u32)op->val; | ||
1704 | break; /* 64b: zero-extend */ | ||
1705 | case 8: | ||
1706 | *op->addr.reg = op->val; | ||
1707 | break; | ||
1708 | } | ||
1709 | } | 1711 | } |
1710 | 1712 | ||
1711 | static int writeback(struct x86_emulate_ctxt *ctxt, struct operand *op) | 1713 | static int writeback(struct x86_emulate_ctxt *ctxt, struct operand *op) |
@@ -1792,32 +1794,34 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt, | |||
1792 | { | 1794 | { |
1793 | int rc; | 1795 | int rc; |
1794 | unsigned long val, change_mask; | 1796 | unsigned long val, change_mask; |
1795 | int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | 1797 | int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> X86_EFLAGS_IOPL_BIT; |
1796 | int cpl = ctxt->ops->cpl(ctxt); | 1798 | int cpl = ctxt->ops->cpl(ctxt); |
1797 | 1799 | ||
1798 | rc = emulate_pop(ctxt, &val, len); | 1800 | rc = emulate_pop(ctxt, &val, len); |
1799 | if (rc != X86EMUL_CONTINUE) | 1801 | if (rc != X86EMUL_CONTINUE) |
1800 | return rc; | 1802 | return rc; |
1801 | 1803 | ||
1802 | change_mask = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF | EFLG_OF | 1804 | change_mask = X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | |
1803 | | EFLG_TF | EFLG_DF | EFLG_NT | EFLG_AC | EFLG_ID; | 1805 | X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF | |
1806 | X86_EFLAGS_TF | X86_EFLAGS_DF | X86_EFLAGS_NT | | ||
1807 | X86_EFLAGS_AC | X86_EFLAGS_ID; | ||
1804 | 1808 | ||
1805 | switch(ctxt->mode) { | 1809 | switch(ctxt->mode) { |
1806 | case X86EMUL_MODE_PROT64: | 1810 | case X86EMUL_MODE_PROT64: |
1807 | case X86EMUL_MODE_PROT32: | 1811 | case X86EMUL_MODE_PROT32: |
1808 | case X86EMUL_MODE_PROT16: | 1812 | case X86EMUL_MODE_PROT16: |
1809 | if (cpl == 0) | 1813 | if (cpl == 0) |
1810 | change_mask |= EFLG_IOPL; | 1814 | change_mask |= X86_EFLAGS_IOPL; |
1811 | if (cpl <= iopl) | 1815 | if (cpl <= iopl) |
1812 | change_mask |= EFLG_IF; | 1816 | change_mask |= X86_EFLAGS_IF; |
1813 | break; | 1817 | break; |
1814 | case X86EMUL_MODE_VM86: | 1818 | case X86EMUL_MODE_VM86: |
1815 | if (iopl < 3) | 1819 | if (iopl < 3) |
1816 | return emulate_gp(ctxt, 0); | 1820 | return emulate_gp(ctxt, 0); |
1817 | change_mask |= EFLG_IF; | 1821 | change_mask |= X86_EFLAGS_IF; |
1818 | break; | 1822 | break; |
1819 | default: /* real mode */ | 1823 | default: /* real mode */ |
1820 | change_mask |= (EFLG_IOPL | EFLG_IF); | 1824 | change_mask |= (X86_EFLAGS_IOPL | X86_EFLAGS_IF); |
1821 | break; | 1825 | break; |
1822 | } | 1826 | } |
1823 | 1827 | ||
@@ -1918,7 +1922,7 @@ static int em_pusha(struct x86_emulate_ctxt *ctxt) | |||
1918 | 1922 | ||
1919 | static int em_pushf(struct x86_emulate_ctxt *ctxt) | 1923 | static int em_pushf(struct x86_emulate_ctxt *ctxt) |
1920 | { | 1924 | { |
1921 | ctxt->src.val = (unsigned long)ctxt->eflags & ~EFLG_VM; | 1925 | ctxt->src.val = (unsigned long)ctxt->eflags & ~X86_EFLAGS_VM; |
1922 | return em_push(ctxt); | 1926 | return em_push(ctxt); |
1923 | } | 1927 | } |
1924 | 1928 | ||
@@ -1926,6 +1930,7 @@ static int em_popa(struct x86_emulate_ctxt *ctxt) | |||
1926 | { | 1930 | { |
1927 | int rc = X86EMUL_CONTINUE; | 1931 | int rc = X86EMUL_CONTINUE; |
1928 | int reg = VCPU_REGS_RDI; | 1932 | int reg = VCPU_REGS_RDI; |
1933 | u32 val; | ||
1929 | 1934 | ||
1930 | while (reg >= VCPU_REGS_RAX) { | 1935 | while (reg >= VCPU_REGS_RAX) { |
1931 | if (reg == VCPU_REGS_RSP) { | 1936 | if (reg == VCPU_REGS_RSP) { |
@@ -1933,9 +1938,10 @@ static int em_popa(struct x86_emulate_ctxt *ctxt) | |||
1933 | --reg; | 1938 | --reg; |
1934 | } | 1939 | } |
1935 | 1940 | ||
1936 | rc = emulate_pop(ctxt, reg_rmw(ctxt, reg), ctxt->op_bytes); | 1941 | rc = emulate_pop(ctxt, &val, ctxt->op_bytes); |
1937 | if (rc != X86EMUL_CONTINUE) | 1942 | if (rc != X86EMUL_CONTINUE) |
1938 | break; | 1943 | break; |
1944 | assign_register(reg_rmw(ctxt, reg), val, ctxt->op_bytes); | ||
1939 | --reg; | 1945 | --reg; |
1940 | } | 1946 | } |
1941 | return rc; | 1947 | return rc; |
@@ -1956,7 +1962,7 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq) | |||
1956 | if (rc != X86EMUL_CONTINUE) | 1962 | if (rc != X86EMUL_CONTINUE) |
1957 | return rc; | 1963 | return rc; |
1958 | 1964 | ||
1959 | ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC); | 1965 | ctxt->eflags &= ~(X86_EFLAGS_IF | X86_EFLAGS_TF | X86_EFLAGS_AC); |
1960 | 1966 | ||
1961 | ctxt->src.val = get_segment_selector(ctxt, VCPU_SREG_CS); | 1967 | ctxt->src.val = get_segment_selector(ctxt, VCPU_SREG_CS); |
1962 | rc = em_push(ctxt); | 1968 | rc = em_push(ctxt); |
@@ -2022,10 +2028,14 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt) | |||
2022 | unsigned long temp_eip = 0; | 2028 | unsigned long temp_eip = 0; |
2023 | unsigned long temp_eflags = 0; | 2029 | unsigned long temp_eflags = 0; |
2024 | unsigned long cs = 0; | 2030 | unsigned long cs = 0; |
2025 | unsigned long mask = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF | EFLG_TF | | 2031 | unsigned long mask = X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | |
2026 | EFLG_IF | EFLG_DF | EFLG_OF | EFLG_IOPL | EFLG_NT | EFLG_RF | | 2032 | X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_TF | |
2027 | EFLG_AC | EFLG_ID | (1 << 1); /* Last one is the reserved bit */ | 2033 | X86_EFLAGS_IF | X86_EFLAGS_DF | X86_EFLAGS_OF | |
2028 | unsigned long vm86_mask = EFLG_VM | EFLG_VIF | EFLG_VIP; | 2034 | X86_EFLAGS_IOPL | X86_EFLAGS_NT | X86_EFLAGS_RF | |
2035 | X86_EFLAGS_AC | X86_EFLAGS_ID | | ||
2036 | X86_EFLAGS_FIXED; | ||
2037 | unsigned long vm86_mask = X86_EFLAGS_VM | X86_EFLAGS_VIF | | ||
2038 | X86_EFLAGS_VIP; | ||
2029 | 2039 | ||
2030 | /* TODO: Add stack limit check */ | 2040 | /* TODO: Add stack limit check */ |
2031 | 2041 | ||
@@ -2054,7 +2064,6 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt) | |||
2054 | 2064 | ||
2055 | ctxt->_eip = temp_eip; | 2065 | ctxt->_eip = temp_eip; |
2056 | 2066 | ||
2057 | |||
2058 | if (ctxt->op_bytes == 4) | 2067 | if (ctxt->op_bytes == 4) |
2059 | ctxt->eflags = ((temp_eflags & mask) | (ctxt->eflags & vm86_mask)); | 2068 | ctxt->eflags = ((temp_eflags & mask) | (ctxt->eflags & vm86_mask)); |
2060 | else if (ctxt->op_bytes == 2) { | 2069 | else if (ctxt->op_bytes == 2) { |
@@ -2063,7 +2072,7 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt) | |||
2063 | } | 2072 | } |
2064 | 2073 | ||
2065 | ctxt->eflags &= ~EFLG_RESERVED_ZEROS_MASK; /* Clear reserved zeros */ | 2074 | ctxt->eflags &= ~EFLG_RESERVED_ZEROS_MASK; /* Clear reserved zeros */ |
2066 | ctxt->eflags |= EFLG_RESERVED_ONE_MASK; | 2075 | ctxt->eflags |= X86_EFLAGS_FIXED; |
2067 | ctxt->ops->set_nmi_mask(ctxt, false); | 2076 | ctxt->ops->set_nmi_mask(ctxt, false); |
2068 | 2077 | ||
2069 | return rc; | 2078 | return rc; |
@@ -2145,12 +2154,12 @@ static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt) | |||
2145 | ((u32) (old >> 32) != (u32) reg_read(ctxt, VCPU_REGS_RDX))) { | 2154 | ((u32) (old >> 32) != (u32) reg_read(ctxt, VCPU_REGS_RDX))) { |
2146 | *reg_write(ctxt, VCPU_REGS_RAX) = (u32) (old >> 0); | 2155 | *reg_write(ctxt, VCPU_REGS_RAX) = (u32) (old >> 0); |
2147 | *reg_write(ctxt, VCPU_REGS_RDX) = (u32) (old >> 32); | 2156 | *reg_write(ctxt, VCPU_REGS_RDX) = (u32) (old >> 32); |
2148 | ctxt->eflags &= ~EFLG_ZF; | 2157 | ctxt->eflags &= ~X86_EFLAGS_ZF; |
2149 | } else { | 2158 | } else { |
2150 | ctxt->dst.val64 = ((u64)reg_read(ctxt, VCPU_REGS_RCX) << 32) | | 2159 | ctxt->dst.val64 = ((u64)reg_read(ctxt, VCPU_REGS_RCX) << 32) | |
2151 | (u32) reg_read(ctxt, VCPU_REGS_RBX); | 2160 | (u32) reg_read(ctxt, VCPU_REGS_RBX); |
2152 | 2161 | ||
2153 | ctxt->eflags |= EFLG_ZF; | 2162 | ctxt->eflags |= X86_EFLAGS_ZF; |
2154 | } | 2163 | } |
2155 | return X86EMUL_CONTINUE; | 2164 | return X86EMUL_CONTINUE; |
2156 | } | 2165 | } |
@@ -2222,7 +2231,7 @@ static int em_cmpxchg(struct x86_emulate_ctxt *ctxt) | |||
2222 | ctxt->src.val = ctxt->dst.orig_val; | 2231 | ctxt->src.val = ctxt->dst.orig_val; |
2223 | fastop(ctxt, em_cmp); | 2232 | fastop(ctxt, em_cmp); |
2224 | 2233 | ||
2225 | if (ctxt->eflags & EFLG_ZF) { | 2234 | if (ctxt->eflags & X86_EFLAGS_ZF) { |
2226 | /* Success: write back to memory; no update of EAX */ | 2235 | /* Success: write back to memory; no update of EAX */ |
2227 | ctxt->src.type = OP_NONE; | 2236 | ctxt->src.type = OP_NONE; |
2228 | ctxt->dst.val = ctxt->src.orig_val; | 2237 | ctxt->dst.val = ctxt->src.orig_val; |
@@ -2381,14 +2390,14 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt) | |||
2381 | 2390 | ||
2382 | ops->get_msr(ctxt, MSR_SYSCALL_MASK, &msr_data); | 2391 | ops->get_msr(ctxt, MSR_SYSCALL_MASK, &msr_data); |
2383 | ctxt->eflags &= ~msr_data; | 2392 | ctxt->eflags &= ~msr_data; |
2384 | ctxt->eflags |= EFLG_RESERVED_ONE_MASK; | 2393 | ctxt->eflags |= X86_EFLAGS_FIXED; |
2385 | #endif | 2394 | #endif |
2386 | } else { | 2395 | } else { |
2387 | /* legacy mode */ | 2396 | /* legacy mode */ |
2388 | ops->get_msr(ctxt, MSR_STAR, &msr_data); | 2397 | ops->get_msr(ctxt, MSR_STAR, &msr_data); |
2389 | ctxt->_eip = (u32)msr_data; | 2398 | ctxt->_eip = (u32)msr_data; |
2390 | 2399 | ||
2391 | ctxt->eflags &= ~(EFLG_VM | EFLG_IF); | 2400 | ctxt->eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_IF); |
2392 | } | 2401 | } |
2393 | 2402 | ||
2394 | return X86EMUL_CONTINUE; | 2403 | return X86EMUL_CONTINUE; |
@@ -2425,8 +2434,8 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) | |||
2425 | if ((msr_data & 0xfffc) == 0x0) | 2434 | if ((msr_data & 0xfffc) == 0x0) |
2426 | return emulate_gp(ctxt, 0); | 2435 | return emulate_gp(ctxt, 0); |
2427 | 2436 | ||
2428 | ctxt->eflags &= ~(EFLG_VM | EFLG_IF); | 2437 | ctxt->eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_IF); |
2429 | cs_sel = (u16)msr_data & ~SELECTOR_RPL_MASK; | 2438 | cs_sel = (u16)msr_data & ~SEGMENT_RPL_MASK; |
2430 | ss_sel = cs_sel + 8; | 2439 | ss_sel = cs_sel + 8; |
2431 | if (efer & EFER_LMA) { | 2440 | if (efer & EFER_LMA) { |
2432 | cs.d = 0; | 2441 | cs.d = 0; |
@@ -2493,8 +2502,8 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt) | |||
2493 | return emulate_gp(ctxt, 0); | 2502 | return emulate_gp(ctxt, 0); |
2494 | break; | 2503 | break; |
2495 | } | 2504 | } |
2496 | cs_sel |= SELECTOR_RPL_MASK; | 2505 | cs_sel |= SEGMENT_RPL_MASK; |
2497 | ss_sel |= SELECTOR_RPL_MASK; | 2506 | ss_sel |= SEGMENT_RPL_MASK; |
2498 | 2507 | ||
2499 | ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS); | 2508 | ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS); |
2500 | ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS); | 2509 | ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS); |
@@ -2512,7 +2521,7 @@ static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) | |||
2512 | return false; | 2521 | return false; |
2513 | if (ctxt->mode == X86EMUL_MODE_VM86) | 2522 | if (ctxt->mode == X86EMUL_MODE_VM86) |
2514 | return true; | 2523 | return true; |
2515 | iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | 2524 | iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> X86_EFLAGS_IOPL_BIT; |
2516 | return ctxt->ops->cpl(ctxt) > iopl; | 2525 | return ctxt->ops->cpl(ctxt) > iopl; |
2517 | } | 2526 | } |
2518 | 2527 | ||
@@ -2782,10 +2791,8 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt, | |||
2782 | return ret; | 2791 | return ret; |
2783 | ret = __load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS, cpl, | 2792 | ret = __load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS, cpl, |
2784 | X86_TRANSFER_TASK_SWITCH, NULL); | 2793 | X86_TRANSFER_TASK_SWITCH, NULL); |
2785 | if (ret != X86EMUL_CONTINUE) | ||
2786 | return ret; | ||
2787 | 2794 | ||
2788 | return X86EMUL_CONTINUE; | 2795 | return ret; |
2789 | } | 2796 | } |
2790 | 2797 | ||
2791 | static int task_switch_32(struct x86_emulate_ctxt *ctxt, | 2798 | static int task_switch_32(struct x86_emulate_ctxt *ctxt, |
@@ -2954,7 +2961,7 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt, | |||
2954 | static void string_addr_inc(struct x86_emulate_ctxt *ctxt, int reg, | 2961 | static void string_addr_inc(struct x86_emulate_ctxt *ctxt, int reg, |
2955 | struct operand *op) | 2962 | struct operand *op) |
2956 | { | 2963 | { |
2957 | int df = (ctxt->eflags & EFLG_DF) ? -op->count : op->count; | 2964 | int df = (ctxt->eflags & X86_EFLAGS_DF) ? -op->count : op->count; |
2958 | 2965 | ||
2959 | register_address_increment(ctxt, reg, df * op->bytes); | 2966 | register_address_increment(ctxt, reg, df * op->bytes); |
2960 | op->addr.mem.ea = register_address(ctxt, reg); | 2967 | op->addr.mem.ea = register_address(ctxt, reg); |
@@ -3323,7 +3330,7 @@ static int em_clts(struct x86_emulate_ctxt *ctxt) | |||
3323 | return X86EMUL_CONTINUE; | 3330 | return X86EMUL_CONTINUE; |
3324 | } | 3331 | } |
3325 | 3332 | ||
3326 | static int em_vmcall(struct x86_emulate_ctxt *ctxt) | 3333 | static int em_hypercall(struct x86_emulate_ctxt *ctxt) |
3327 | { | 3334 | { |
3328 | int rc = ctxt->ops->fix_hypercall(ctxt); | 3335 | int rc = ctxt->ops->fix_hypercall(ctxt); |
3329 | 3336 | ||
@@ -3395,17 +3402,6 @@ static int em_lgdt(struct x86_emulate_ctxt *ctxt) | |||
3395 | return em_lgdt_lidt(ctxt, true); | 3402 | return em_lgdt_lidt(ctxt, true); |
3396 | } | 3403 | } |
3397 | 3404 | ||
3398 | static int em_vmmcall(struct x86_emulate_ctxt *ctxt) | ||
3399 | { | ||
3400 | int rc; | ||
3401 | |||
3402 | rc = ctxt->ops->fix_hypercall(ctxt); | ||
3403 | |||
3404 | /* Disable writeback. */ | ||
3405 | ctxt->dst.type = OP_NONE; | ||
3406 | return rc; | ||
3407 | } | ||
3408 | |||
3409 | static int em_lidt(struct x86_emulate_ctxt *ctxt) | 3405 | static int em_lidt(struct x86_emulate_ctxt *ctxt) |
3410 | { | 3406 | { |
3411 | return em_lgdt_lidt(ctxt, false); | 3407 | return em_lgdt_lidt(ctxt, false); |
@@ -3504,7 +3500,8 @@ static int em_sahf(struct x86_emulate_ctxt *ctxt) | |||
3504 | { | 3500 | { |
3505 | u32 flags; | 3501 | u32 flags; |
3506 | 3502 | ||
3507 | flags = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF; | 3503 | flags = X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | X86_EFLAGS_ZF | |
3504 | X86_EFLAGS_SF; | ||
3508 | flags &= *reg_rmw(ctxt, VCPU_REGS_RAX) >> 8; | 3505 | flags &= *reg_rmw(ctxt, VCPU_REGS_RAX) >> 8; |
3509 | 3506 | ||
3510 | ctxt->eflags &= ~0xffUL; | 3507 | ctxt->eflags &= ~0xffUL; |
@@ -3769,7 +3766,7 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt) | |||
3769 | 3766 | ||
3770 | static const struct opcode group7_rm0[] = { | 3767 | static const struct opcode group7_rm0[] = { |
3771 | N, | 3768 | N, |
3772 | I(SrcNone | Priv | EmulateOnUD, em_vmcall), | 3769 | I(SrcNone | Priv | EmulateOnUD, em_hypercall), |
3773 | N, N, N, N, N, N, | 3770 | N, N, N, N, N, N, |
3774 | }; | 3771 | }; |
3775 | 3772 | ||
@@ -3781,7 +3778,7 @@ static const struct opcode group7_rm1[] = { | |||
3781 | 3778 | ||
3782 | static const struct opcode group7_rm3[] = { | 3779 | static const struct opcode group7_rm3[] = { |
3783 | DIP(SrcNone | Prot | Priv, vmrun, check_svme_pa), | 3780 | DIP(SrcNone | Prot | Priv, vmrun, check_svme_pa), |
3784 | II(SrcNone | Prot | EmulateOnUD, em_vmmcall, vmmcall), | 3781 | II(SrcNone | Prot | EmulateOnUD, em_hypercall, vmmcall), |
3785 | DIP(SrcNone | Prot | Priv, vmload, check_svme_pa), | 3782 | DIP(SrcNone | Prot | Priv, vmload, check_svme_pa), |
3786 | DIP(SrcNone | Prot | Priv, vmsave, check_svme_pa), | 3783 | DIP(SrcNone | Prot | Priv, vmsave, check_svme_pa), |
3787 | DIP(SrcNone | Prot | Priv, stgi, check_svme), | 3784 | DIP(SrcNone | Prot | Priv, stgi, check_svme), |
@@ -4192,7 +4189,8 @@ static const struct opcode twobyte_table[256] = { | |||
4192 | N, N, | 4189 | N, N, |
4193 | G(BitOp, group8), | 4190 | G(BitOp, group8), |
4194 | F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc), | 4191 | F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc), |
4195 | F(DstReg | SrcMem | ModRM, em_bsf), F(DstReg | SrcMem | ModRM, em_bsr), | 4192 | I(DstReg | SrcMem | ModRM, em_bsf_c), |
4193 | I(DstReg | SrcMem | ModRM, em_bsr_c), | ||
4196 | D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), | 4194 | D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), |
4197 | /* 0xC0 - 0xC7 */ | 4195 | /* 0xC0 - 0xC7 */ |
4198 | F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd), | 4196 | F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd), |
@@ -4759,9 +4757,9 @@ static bool string_insn_completed(struct x86_emulate_ctxt *ctxt) | |||
4759 | if (((ctxt->b == 0xa6) || (ctxt->b == 0xa7) || | 4757 | if (((ctxt->b == 0xa6) || (ctxt->b == 0xa7) || |
4760 | (ctxt->b == 0xae) || (ctxt->b == 0xaf)) | 4758 | (ctxt->b == 0xae) || (ctxt->b == 0xaf)) |
4761 | && (((ctxt->rep_prefix == REPE_PREFIX) && | 4759 | && (((ctxt->rep_prefix == REPE_PREFIX) && |
4762 | ((ctxt->eflags & EFLG_ZF) == 0)) | 4760 | ((ctxt->eflags & X86_EFLAGS_ZF) == 0)) |
4763 | || ((ctxt->rep_prefix == REPNE_PREFIX) && | 4761 | || ((ctxt->rep_prefix == REPNE_PREFIX) && |
4764 | ((ctxt->eflags & EFLG_ZF) == EFLG_ZF)))) | 4762 | ((ctxt->eflags & X86_EFLAGS_ZF) == X86_EFLAGS_ZF)))) |
4765 | return true; | 4763 | return true; |
4766 | 4764 | ||
4767 | return false; | 4765 | return false; |
@@ -4913,7 +4911,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
4913 | /* All REP prefixes have the same first termination condition */ | 4911 | /* All REP prefixes have the same first termination condition */ |
4914 | if (address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) == 0) { | 4912 | if (address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) == 0) { |
4915 | ctxt->eip = ctxt->_eip; | 4913 | ctxt->eip = ctxt->_eip; |
4916 | ctxt->eflags &= ~EFLG_RF; | 4914 | ctxt->eflags &= ~X86_EFLAGS_RF; |
4917 | goto done; | 4915 | goto done; |
4918 | } | 4916 | } |
4919 | } | 4917 | } |
@@ -4950,7 +4948,8 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
4950 | goto done; | 4948 | goto done; |
4951 | } | 4949 | } |
4952 | } | 4950 | } |
4953 | ctxt->dst.orig_val = ctxt->dst.val; | 4951 | /* Copy full 64-bit value for CMPXCHG8B. */ |
4952 | ctxt->dst.orig_val64 = ctxt->dst.val64; | ||
4954 | 4953 | ||
4955 | special_insn: | 4954 | special_insn: |
4956 | 4955 | ||
@@ -4962,9 +4961,9 @@ special_insn: | |||
4962 | } | 4961 | } |
4963 | 4962 | ||
4964 | if (ctxt->rep_prefix && (ctxt->d & String)) | 4963 | if (ctxt->rep_prefix && (ctxt->d & String)) |
4965 | ctxt->eflags |= EFLG_RF; | 4964 | ctxt->eflags |= X86_EFLAGS_RF; |
4966 | else | 4965 | else |
4967 | ctxt->eflags &= ~EFLG_RF; | 4966 | ctxt->eflags &= ~X86_EFLAGS_RF; |
4968 | 4967 | ||
4969 | if (ctxt->execute) { | 4968 | if (ctxt->execute) { |
4970 | if (ctxt->d & Fastop) { | 4969 | if (ctxt->d & Fastop) { |
@@ -5013,7 +5012,7 @@ special_insn: | |||
5013 | rc = emulate_int(ctxt, ctxt->src.val); | 5012 | rc = emulate_int(ctxt, ctxt->src.val); |
5014 | break; | 5013 | break; |
5015 | case 0xce: /* into */ | 5014 | case 0xce: /* into */ |
5016 | if (ctxt->eflags & EFLG_OF) | 5015 | if (ctxt->eflags & X86_EFLAGS_OF) |
5017 | rc = emulate_int(ctxt, 4); | 5016 | rc = emulate_int(ctxt, 4); |
5018 | break; | 5017 | break; |
5019 | case 0xe9: /* jmp rel */ | 5018 | case 0xe9: /* jmp rel */ |
@@ -5026,19 +5025,19 @@ special_insn: | |||
5026 | break; | 5025 | break; |
5027 | case 0xf5: /* cmc */ | 5026 | case 0xf5: /* cmc */ |
5028 | /* complement carry flag from eflags reg */ | 5027 | /* complement carry flag from eflags reg */ |
5029 | ctxt->eflags ^= EFLG_CF; | 5028 | ctxt->eflags ^= X86_EFLAGS_CF; |
5030 | break; | 5029 | break; |
5031 | case 0xf8: /* clc */ | 5030 | case 0xf8: /* clc */ |
5032 | ctxt->eflags &= ~EFLG_CF; | 5031 | ctxt->eflags &= ~X86_EFLAGS_CF; |
5033 | break; | 5032 | break; |
5034 | case 0xf9: /* stc */ | 5033 | case 0xf9: /* stc */ |
5035 | ctxt->eflags |= EFLG_CF; | 5034 | ctxt->eflags |= X86_EFLAGS_CF; |
5036 | break; | 5035 | break; |
5037 | case 0xfc: /* cld */ | 5036 | case 0xfc: /* cld */ |
5038 | ctxt->eflags &= ~EFLG_DF; | 5037 | ctxt->eflags &= ~X86_EFLAGS_DF; |
5039 | break; | 5038 | break; |
5040 | case 0xfd: /* std */ | 5039 | case 0xfd: /* std */ |
5041 | ctxt->eflags |= EFLG_DF; | 5040 | ctxt->eflags |= X86_EFLAGS_DF; |
5042 | break; | 5041 | break; |
5043 | default: | 5042 | default: |
5044 | goto cannot_emulate; | 5043 | goto cannot_emulate; |
@@ -5099,7 +5098,7 @@ writeback: | |||
5099 | } | 5098 | } |
5100 | goto done; /* skip rip writeback */ | 5099 | goto done; /* skip rip writeback */ |
5101 | } | 5100 | } |
5102 | ctxt->eflags &= ~EFLG_RF; | 5101 | ctxt->eflags &= ~X86_EFLAGS_RF; |
5103 | } | 5102 | } |
5104 | 5103 | ||
5105 | ctxt->eip = ctxt->_eip; | 5104 | ctxt->eip = ctxt->_eip; |
@@ -5136,8 +5135,7 @@ twobyte_insn: | |||
5136 | case 0x40 ... 0x4f: /* cmov */ | 5135 | case 0x40 ... 0x4f: /* cmov */ |
5137 | if (test_cc(ctxt->b, ctxt->eflags)) | 5136 | if (test_cc(ctxt->b, ctxt->eflags)) |
5138 | ctxt->dst.val = ctxt->src.val; | 5137 | ctxt->dst.val = ctxt->src.val; |
5139 | else if (ctxt->mode != X86EMUL_MODE_PROT64 || | 5138 | else if (ctxt->op_bytes != 4) |
5140 | ctxt->op_bytes != 4) | ||
5141 | ctxt->dst.type = OP_NONE; /* no writeback */ | 5139 | ctxt->dst.type = OP_NONE; /* no writeback */ |
5142 | break; | 5140 | break; |
5143 | case 0x80 ... 0x8f: /* jnz rel, etc*/ | 5141 | case 0x80 ... 0x8f: /* jnz rel, etc*/ |
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 298781d4cfb4..4dce6f8b6129 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c | |||
@@ -443,7 +443,8 @@ static inline int pit_in_range(gpa_t addr) | |||
443 | (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH)); | 443 | (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH)); |
444 | } | 444 | } |
445 | 445 | ||
446 | static int pit_ioport_write(struct kvm_io_device *this, | 446 | static int pit_ioport_write(struct kvm_vcpu *vcpu, |
447 | struct kvm_io_device *this, | ||
447 | gpa_t addr, int len, const void *data) | 448 | gpa_t addr, int len, const void *data) |
448 | { | 449 | { |
449 | struct kvm_pit *pit = dev_to_pit(this); | 450 | struct kvm_pit *pit = dev_to_pit(this); |
@@ -519,7 +520,8 @@ static int pit_ioport_write(struct kvm_io_device *this, | |||
519 | return 0; | 520 | return 0; |
520 | } | 521 | } |
521 | 522 | ||
522 | static int pit_ioport_read(struct kvm_io_device *this, | 523 | static int pit_ioport_read(struct kvm_vcpu *vcpu, |
524 | struct kvm_io_device *this, | ||
523 | gpa_t addr, int len, void *data) | 525 | gpa_t addr, int len, void *data) |
524 | { | 526 | { |
525 | struct kvm_pit *pit = dev_to_pit(this); | 527 | struct kvm_pit *pit = dev_to_pit(this); |
@@ -589,7 +591,8 @@ static int pit_ioport_read(struct kvm_io_device *this, | |||
589 | return 0; | 591 | return 0; |
590 | } | 592 | } |
591 | 593 | ||
592 | static int speaker_ioport_write(struct kvm_io_device *this, | 594 | static int speaker_ioport_write(struct kvm_vcpu *vcpu, |
595 | struct kvm_io_device *this, | ||
593 | gpa_t addr, int len, const void *data) | 596 | gpa_t addr, int len, const void *data) |
594 | { | 597 | { |
595 | struct kvm_pit *pit = speaker_to_pit(this); | 598 | struct kvm_pit *pit = speaker_to_pit(this); |
@@ -606,8 +609,9 @@ static int speaker_ioport_write(struct kvm_io_device *this, | |||
606 | return 0; | 609 | return 0; |
607 | } | 610 | } |
608 | 611 | ||
609 | static int speaker_ioport_read(struct kvm_io_device *this, | 612 | static int speaker_ioport_read(struct kvm_vcpu *vcpu, |
610 | gpa_t addr, int len, void *data) | 613 | struct kvm_io_device *this, |
614 | gpa_t addr, int len, void *data) | ||
611 | { | 615 | { |
612 | struct kvm_pit *pit = speaker_to_pit(this); | 616 | struct kvm_pit *pit = speaker_to_pit(this); |
613 | struct kvm_kpit_state *pit_state = &pit->pit_state; | 617 | struct kvm_kpit_state *pit_state = &pit->pit_state; |
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h index dd1b16b611b0..c84990b42b5b 100644 --- a/arch/x86/kvm/i8254.h +++ b/arch/x86/kvm/i8254.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/kthread.h> | 4 | #include <linux/kthread.h> |
5 | 5 | ||
6 | #include "iodev.h" | 6 | #include <kvm/iodev.h> |
7 | 7 | ||
8 | struct kvm_kpit_channel_state { | 8 | struct kvm_kpit_channel_state { |
9 | u32 count; /* can be 65536 */ | 9 | u32 count; /* can be 65536 */ |
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index cc31f7c06d3d..fef922ff2635 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
@@ -507,6 +507,7 @@ static int picdev_read(struct kvm_pic *s, | |||
507 | return -EOPNOTSUPP; | 507 | return -EOPNOTSUPP; |
508 | 508 | ||
509 | if (len != 1) { | 509 | if (len != 1) { |
510 | memset(val, 0, len); | ||
510 | pr_pic_unimpl("non byte read\n"); | 511 | pr_pic_unimpl("non byte read\n"); |
511 | return 0; | 512 | return 0; |
512 | } | 513 | } |
@@ -528,42 +529,42 @@ static int picdev_read(struct kvm_pic *s, | |||
528 | return 0; | 529 | return 0; |
529 | } | 530 | } |
530 | 531 | ||
531 | static int picdev_master_write(struct kvm_io_device *dev, | 532 | static int picdev_master_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, |
532 | gpa_t addr, int len, const void *val) | 533 | gpa_t addr, int len, const void *val) |
533 | { | 534 | { |
534 | return picdev_write(container_of(dev, struct kvm_pic, dev_master), | 535 | return picdev_write(container_of(dev, struct kvm_pic, dev_master), |
535 | addr, len, val); | 536 | addr, len, val); |
536 | } | 537 | } |
537 | 538 | ||
538 | static int picdev_master_read(struct kvm_io_device *dev, | 539 | static int picdev_master_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, |
539 | gpa_t addr, int len, void *val) | 540 | gpa_t addr, int len, void *val) |
540 | { | 541 | { |
541 | return picdev_read(container_of(dev, struct kvm_pic, dev_master), | 542 | return picdev_read(container_of(dev, struct kvm_pic, dev_master), |
542 | addr, len, val); | 543 | addr, len, val); |
543 | } | 544 | } |
544 | 545 | ||
545 | static int picdev_slave_write(struct kvm_io_device *dev, | 546 | static int picdev_slave_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, |
546 | gpa_t addr, int len, const void *val) | 547 | gpa_t addr, int len, const void *val) |
547 | { | 548 | { |
548 | return picdev_write(container_of(dev, struct kvm_pic, dev_slave), | 549 | return picdev_write(container_of(dev, struct kvm_pic, dev_slave), |
549 | addr, len, val); | 550 | addr, len, val); |
550 | } | 551 | } |
551 | 552 | ||
552 | static int picdev_slave_read(struct kvm_io_device *dev, | 553 | static int picdev_slave_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, |
553 | gpa_t addr, int len, void *val) | 554 | gpa_t addr, int len, void *val) |
554 | { | 555 | { |
555 | return picdev_read(container_of(dev, struct kvm_pic, dev_slave), | 556 | return picdev_read(container_of(dev, struct kvm_pic, dev_slave), |
556 | addr, len, val); | 557 | addr, len, val); |
557 | } | 558 | } |
558 | 559 | ||
559 | static int picdev_eclr_write(struct kvm_io_device *dev, | 560 | static int picdev_eclr_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, |
560 | gpa_t addr, int len, const void *val) | 561 | gpa_t addr, int len, const void *val) |
561 | { | 562 | { |
562 | return picdev_write(container_of(dev, struct kvm_pic, dev_eclr), | 563 | return picdev_write(container_of(dev, struct kvm_pic, dev_eclr), |
563 | addr, len, val); | 564 | addr, len, val); |
564 | } | 565 | } |
565 | 566 | ||
566 | static int picdev_eclr_read(struct kvm_io_device *dev, | 567 | static int picdev_eclr_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, |
567 | gpa_t addr, int len, void *val) | 568 | gpa_t addr, int len, void *val) |
568 | { | 569 | { |
569 | return picdev_read(container_of(dev, struct kvm_pic, dev_eclr), | 570 | return picdev_read(container_of(dev, struct kvm_pic, dev_eclr), |
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index b1947e0f3e10..28146f03c514 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c | |||
@@ -206,6 +206,8 @@ static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq, | |||
206 | 206 | ||
207 | old_irr = ioapic->irr; | 207 | old_irr = ioapic->irr; |
208 | ioapic->irr |= mask; | 208 | ioapic->irr |= mask; |
209 | if (edge) | ||
210 | ioapic->irr_delivered &= ~mask; | ||
209 | if ((edge && old_irr == ioapic->irr) || | 211 | if ((edge && old_irr == ioapic->irr) || |
210 | (!edge && entry.fields.remote_irr)) { | 212 | (!edge && entry.fields.remote_irr)) { |
211 | ret = 0; | 213 | ret = 0; |
@@ -349,7 +351,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status) | |||
349 | irqe.shorthand = 0; | 351 | irqe.shorthand = 0; |
350 | 352 | ||
351 | if (irqe.trig_mode == IOAPIC_EDGE_TRIG) | 353 | if (irqe.trig_mode == IOAPIC_EDGE_TRIG) |
352 | ioapic->irr &= ~(1 << irq); | 354 | ioapic->irr_delivered |= 1 << irq; |
353 | 355 | ||
354 | if (irq == RTC_GSI && line_status) { | 356 | if (irq == RTC_GSI && line_status) { |
355 | /* | 357 | /* |
@@ -422,6 +424,7 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, | |||
422 | struct kvm_ioapic *ioapic, int vector, int trigger_mode) | 424 | struct kvm_ioapic *ioapic, int vector, int trigger_mode) |
423 | { | 425 | { |
424 | int i; | 426 | int i; |
427 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
425 | 428 | ||
426 | for (i = 0; i < IOAPIC_NUM_PINS; i++) { | 429 | for (i = 0; i < IOAPIC_NUM_PINS; i++) { |
427 | union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i]; | 430 | union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i]; |
@@ -443,7 +446,8 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, | |||
443 | kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, i); | 446 | kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, i); |
444 | spin_lock(&ioapic->lock); | 447 | spin_lock(&ioapic->lock); |
445 | 448 | ||
446 | if (trigger_mode != IOAPIC_LEVEL_TRIG) | 449 | if (trigger_mode != IOAPIC_LEVEL_TRIG || |
450 | kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) | ||
447 | continue; | 451 | continue; |
448 | 452 | ||
449 | ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); | 453 | ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); |
@@ -471,13 +475,6 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, | |||
471 | } | 475 | } |
472 | } | 476 | } |
473 | 477 | ||
474 | bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector) | ||
475 | { | ||
476 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; | ||
477 | smp_rmb(); | ||
478 | return test_bit(vector, ioapic->handled_vectors); | ||
479 | } | ||
480 | |||
481 | void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, int trigger_mode) | 478 | void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, int trigger_mode) |
482 | { | 479 | { |
483 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; | 480 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; |
@@ -498,8 +495,8 @@ static inline int ioapic_in_range(struct kvm_ioapic *ioapic, gpa_t addr) | |||
498 | (addr < ioapic->base_address + IOAPIC_MEM_LENGTH))); | 495 | (addr < ioapic->base_address + IOAPIC_MEM_LENGTH))); |
499 | } | 496 | } |
500 | 497 | ||
501 | static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, | 498 | static int ioapic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this, |
502 | void *val) | 499 | gpa_t addr, int len, void *val) |
503 | { | 500 | { |
504 | struct kvm_ioapic *ioapic = to_ioapic(this); | 501 | struct kvm_ioapic *ioapic = to_ioapic(this); |
505 | u32 result; | 502 | u32 result; |
@@ -541,8 +538,8 @@ static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, | |||
541 | return 0; | 538 | return 0; |
542 | } | 539 | } |
543 | 540 | ||
544 | static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, | 541 | static int ioapic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this, |
545 | const void *val) | 542 | gpa_t addr, int len, const void *val) |
546 | { | 543 | { |
547 | struct kvm_ioapic *ioapic = to_ioapic(this); | 544 | struct kvm_ioapic *ioapic = to_ioapic(this); |
548 | u32 data; | 545 | u32 data; |
@@ -597,6 +594,7 @@ static void kvm_ioapic_reset(struct kvm_ioapic *ioapic) | |||
597 | ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; | 594 | ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; |
598 | ioapic->ioregsel = 0; | 595 | ioapic->ioregsel = 0; |
599 | ioapic->irr = 0; | 596 | ioapic->irr = 0; |
597 | ioapic->irr_delivered = 0; | ||
600 | ioapic->id = 0; | 598 | ioapic->id = 0; |
601 | memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS); | 599 | memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS); |
602 | rtc_irq_eoi_tracking_reset(ioapic); | 600 | rtc_irq_eoi_tracking_reset(ioapic); |
@@ -654,6 +652,7 @@ int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) | |||
654 | 652 | ||
655 | spin_lock(&ioapic->lock); | 653 | spin_lock(&ioapic->lock); |
656 | memcpy(state, ioapic, sizeof(struct kvm_ioapic_state)); | 654 | memcpy(state, ioapic, sizeof(struct kvm_ioapic_state)); |
655 | state->irr &= ~ioapic->irr_delivered; | ||
657 | spin_unlock(&ioapic->lock); | 656 | spin_unlock(&ioapic->lock); |
658 | return 0; | 657 | return 0; |
659 | } | 658 | } |
@@ -667,6 +666,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) | |||
667 | spin_lock(&ioapic->lock); | 666 | spin_lock(&ioapic->lock); |
668 | memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); | 667 | memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); |
669 | ioapic->irr = 0; | 668 | ioapic->irr = 0; |
669 | ioapic->irr_delivered = 0; | ||
670 | update_handled_vectors(ioapic); | 670 | update_handled_vectors(ioapic); |
671 | kvm_vcpu_request_scan_ioapic(kvm); | 671 | kvm_vcpu_request_scan_ioapic(kvm); |
672 | kvm_ioapic_inject_all(ioapic, state->irr); | 672 | kvm_ioapic_inject_all(ioapic, state->irr); |
diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h index c2e36d934af4..ca0b0b4e6256 100644 --- a/arch/x86/kvm/ioapic.h +++ b/arch/x86/kvm/ioapic.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/kvm_host.h> | 4 | #include <linux/kvm_host.h> |
5 | 5 | ||
6 | #include "iodev.h" | 6 | #include <kvm/iodev.h> |
7 | 7 | ||
8 | struct kvm; | 8 | struct kvm; |
9 | struct kvm_vcpu; | 9 | struct kvm_vcpu; |
@@ -77,6 +77,7 @@ struct kvm_ioapic { | |||
77 | struct rtc_status rtc_status; | 77 | struct rtc_status rtc_status; |
78 | struct delayed_work eoi_inject; | 78 | struct delayed_work eoi_inject; |
79 | u32 irq_eoi[IOAPIC_NUM_PINS]; | 79 | u32 irq_eoi[IOAPIC_NUM_PINS]; |
80 | u32 irr_delivered; | ||
80 | }; | 81 | }; |
81 | 82 | ||
82 | #ifdef DEBUG | 83 | #ifdef DEBUG |
@@ -97,13 +98,19 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm) | |||
97 | return kvm->arch.vioapic; | 98 | return kvm->arch.vioapic; |
98 | } | 99 | } |
99 | 100 | ||
101 | static inline bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector) | ||
102 | { | ||
103 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; | ||
104 | smp_rmb(); | ||
105 | return test_bit(vector, ioapic->handled_vectors); | ||
106 | } | ||
107 | |||
100 | void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu); | 108 | void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu); |
101 | bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | 109 | bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
102 | int short_hand, unsigned int dest, int dest_mode); | 110 | int short_hand, unsigned int dest, int dest_mode); |
103 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); | 111 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); |
104 | void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, | 112 | void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, |
105 | int trigger_mode); | 113 | int trigger_mode); |
106 | bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector); | ||
107 | int kvm_ioapic_init(struct kvm *kvm); | 114 | int kvm_ioapic_init(struct kvm *kvm); |
108 | void kvm_ioapic_destroy(struct kvm *kvm); | 115 | void kvm_ioapic_destroy(struct kvm *kvm); |
109 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, | 116 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, |
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index 2d03568e9498..ad68c73008c5 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/kvm_host.h> | 27 | #include <linux/kvm_host.h> |
28 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
29 | 29 | ||
30 | #include "iodev.h" | 30 | #include <kvm/iodev.h> |
31 | #include "ioapic.h" | 31 | #include "ioapic.h" |
32 | #include "lapic.h" | 32 | #include "lapic.h" |
33 | 33 | ||
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index e55b5fc344eb..d67206a7b99a 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -133,6 +133,28 @@ static inline int kvm_apic_id(struct kvm_lapic *apic) | |||
133 | return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; | 133 | return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; |
134 | } | 134 | } |
135 | 135 | ||
136 | /* The logical map is definitely wrong if we have multiple | ||
137 | * modes at the same time. (Physical map is always right.) | ||
138 | */ | ||
139 | static inline bool kvm_apic_logical_map_valid(struct kvm_apic_map *map) | ||
140 | { | ||
141 | return !(map->mode & (map->mode - 1)); | ||
142 | } | ||
143 | |||
144 | static inline void | ||
145 | apic_logical_id(struct kvm_apic_map *map, u32 dest_id, u16 *cid, u16 *lid) | ||
146 | { | ||
147 | unsigned lid_bits; | ||
148 | |||
149 | BUILD_BUG_ON(KVM_APIC_MODE_XAPIC_CLUSTER != 4); | ||
150 | BUILD_BUG_ON(KVM_APIC_MODE_XAPIC_FLAT != 8); | ||
151 | BUILD_BUG_ON(KVM_APIC_MODE_X2APIC != 16); | ||
152 | lid_bits = map->mode; | ||
153 | |||
154 | *cid = dest_id >> lid_bits; | ||
155 | *lid = dest_id & ((1 << lid_bits) - 1); | ||
156 | } | ||
157 | |||
136 | static void recalculate_apic_map(struct kvm *kvm) | 158 | static void recalculate_apic_map(struct kvm *kvm) |
137 | { | 159 | { |
138 | struct kvm_apic_map *new, *old = NULL; | 160 | struct kvm_apic_map *new, *old = NULL; |
@@ -146,48 +168,6 @@ static void recalculate_apic_map(struct kvm *kvm) | |||
146 | if (!new) | 168 | if (!new) |
147 | goto out; | 169 | goto out; |
148 | 170 | ||
149 | new->ldr_bits = 8; | ||
150 | /* flat mode is default */ | ||
151 | new->cid_shift = 8; | ||
152 | new->cid_mask = 0; | ||
153 | new->lid_mask = 0xff; | ||
154 | new->broadcast = APIC_BROADCAST; | ||
155 | |||
156 | kvm_for_each_vcpu(i, vcpu, kvm) { | ||
157 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
158 | |||
159 | if (!kvm_apic_present(vcpu)) | ||
160 | continue; | ||
161 | |||
162 | if (apic_x2apic_mode(apic)) { | ||
163 | new->ldr_bits = 32; | ||
164 | new->cid_shift = 16; | ||
165 | new->cid_mask = new->lid_mask = 0xffff; | ||
166 | new->broadcast = X2APIC_BROADCAST; | ||
167 | } else if (kvm_apic_get_reg(apic, APIC_LDR)) { | ||
168 | if (kvm_apic_get_reg(apic, APIC_DFR) == | ||
169 | APIC_DFR_CLUSTER) { | ||
170 | new->cid_shift = 4; | ||
171 | new->cid_mask = 0xf; | ||
172 | new->lid_mask = 0xf; | ||
173 | } else { | ||
174 | new->cid_shift = 8; | ||
175 | new->cid_mask = 0; | ||
176 | new->lid_mask = 0xff; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * All APICs have to be configured in the same mode by an OS. | ||
182 | * We take advatage of this while building logical id loockup | ||
183 | * table. After reset APICs are in software disabled mode, so if | ||
184 | * we find apic with different setting we assume this is the mode | ||
185 | * OS wants all apics to be in; build lookup table accordingly. | ||
186 | */ | ||
187 | if (kvm_apic_sw_enabled(apic)) | ||
188 | break; | ||
189 | } | ||
190 | |||
191 | kvm_for_each_vcpu(i, vcpu, kvm) { | 171 | kvm_for_each_vcpu(i, vcpu, kvm) { |
192 | struct kvm_lapic *apic = vcpu->arch.apic; | 172 | struct kvm_lapic *apic = vcpu->arch.apic; |
193 | u16 cid, lid; | 173 | u16 cid, lid; |
@@ -198,11 +178,25 @@ static void recalculate_apic_map(struct kvm *kvm) | |||
198 | 178 | ||
199 | aid = kvm_apic_id(apic); | 179 | aid = kvm_apic_id(apic); |
200 | ldr = kvm_apic_get_reg(apic, APIC_LDR); | 180 | ldr = kvm_apic_get_reg(apic, APIC_LDR); |
201 | cid = apic_cluster_id(new, ldr); | ||
202 | lid = apic_logical_id(new, ldr); | ||
203 | 181 | ||
204 | if (aid < ARRAY_SIZE(new->phys_map)) | 182 | if (aid < ARRAY_SIZE(new->phys_map)) |
205 | new->phys_map[aid] = apic; | 183 | new->phys_map[aid] = apic; |
184 | |||
185 | if (apic_x2apic_mode(apic)) { | ||
186 | new->mode |= KVM_APIC_MODE_X2APIC; | ||
187 | } else if (ldr) { | ||
188 | ldr = GET_APIC_LOGICAL_ID(ldr); | ||
189 | if (kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_FLAT) | ||
190 | new->mode |= KVM_APIC_MODE_XAPIC_FLAT; | ||
191 | else | ||
192 | new->mode |= KVM_APIC_MODE_XAPIC_CLUSTER; | ||
193 | } | ||
194 | |||
195 | if (!kvm_apic_logical_map_valid(new)) | ||
196 | continue; | ||
197 | |||
198 | apic_logical_id(new, ldr, &cid, &lid); | ||
199 | |||
206 | if (lid && cid < ARRAY_SIZE(new->logical_map)) | 200 | if (lid && cid < ARRAY_SIZE(new->logical_map)) |
207 | new->logical_map[cid][ffs(lid) - 1] = apic; | 201 | new->logical_map[cid][ffs(lid) - 1] = apic; |
208 | } | 202 | } |
@@ -588,15 +582,23 @@ static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr) | |||
588 | apic_update_ppr(apic); | 582 | apic_update_ppr(apic); |
589 | } | 583 | } |
590 | 584 | ||
591 | static bool kvm_apic_broadcast(struct kvm_lapic *apic, u32 dest) | 585 | static bool kvm_apic_broadcast(struct kvm_lapic *apic, u32 mda) |
592 | { | 586 | { |
593 | return dest == (apic_x2apic_mode(apic) ? | 587 | if (apic_x2apic_mode(apic)) |
594 | X2APIC_BROADCAST : APIC_BROADCAST); | 588 | return mda == X2APIC_BROADCAST; |
589 | |||
590 | return GET_APIC_DEST_FIELD(mda) == APIC_BROADCAST; | ||
595 | } | 591 | } |
596 | 592 | ||
597 | static bool kvm_apic_match_physical_addr(struct kvm_lapic *apic, u32 dest) | 593 | static bool kvm_apic_match_physical_addr(struct kvm_lapic *apic, u32 mda) |
598 | { | 594 | { |
599 | return kvm_apic_id(apic) == dest || kvm_apic_broadcast(apic, dest); | 595 | if (kvm_apic_broadcast(apic, mda)) |
596 | return true; | ||
597 | |||
598 | if (apic_x2apic_mode(apic)) | ||
599 | return mda == kvm_apic_id(apic); | ||
600 | |||
601 | return mda == SET_APIC_DEST_FIELD(kvm_apic_id(apic)); | ||
600 | } | 602 | } |
601 | 603 | ||
602 | static bool kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda) | 604 | static bool kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda) |
@@ -613,6 +615,7 @@ static bool kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda) | |||
613 | && (logical_id & mda & 0xffff) != 0; | 615 | && (logical_id & mda & 0xffff) != 0; |
614 | 616 | ||
615 | logical_id = GET_APIC_LOGICAL_ID(logical_id); | 617 | logical_id = GET_APIC_LOGICAL_ID(logical_id); |
618 | mda = GET_APIC_DEST_FIELD(mda); | ||
616 | 619 | ||
617 | switch (kvm_apic_get_reg(apic, APIC_DFR)) { | 620 | switch (kvm_apic_get_reg(apic, APIC_DFR)) { |
618 | case APIC_DFR_FLAT: | 621 | case APIC_DFR_FLAT: |
@@ -627,10 +630,27 @@ static bool kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda) | |||
627 | } | 630 | } |
628 | } | 631 | } |
629 | 632 | ||
633 | /* KVM APIC implementation has two quirks | ||
634 | * - dest always begins at 0 while xAPIC MDA has offset 24, | ||
635 | * - IOxAPIC messages have to be delivered (directly) to x2APIC. | ||
636 | */ | ||
637 | static u32 kvm_apic_mda(unsigned int dest_id, struct kvm_lapic *source, | ||
638 | struct kvm_lapic *target) | ||
639 | { | ||
640 | bool ipi = source != NULL; | ||
641 | bool x2apic_mda = apic_x2apic_mode(ipi ? source : target); | ||
642 | |||
643 | if (!ipi && dest_id == APIC_BROADCAST && x2apic_mda) | ||
644 | return X2APIC_BROADCAST; | ||
645 | |||
646 | return x2apic_mda ? dest_id : SET_APIC_DEST_FIELD(dest_id); | ||
647 | } | ||
648 | |||
630 | bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | 649 | bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
631 | int short_hand, unsigned int dest, int dest_mode) | 650 | int short_hand, unsigned int dest, int dest_mode) |
632 | { | 651 | { |
633 | struct kvm_lapic *target = vcpu->arch.apic; | 652 | struct kvm_lapic *target = vcpu->arch.apic; |
653 | u32 mda = kvm_apic_mda(dest, source, target); | ||
634 | 654 | ||
635 | apic_debug("target %p, source %p, dest 0x%x, " | 655 | apic_debug("target %p, source %p, dest 0x%x, " |
636 | "dest_mode 0x%x, short_hand 0x%x\n", | 656 | "dest_mode 0x%x, short_hand 0x%x\n", |
@@ -640,9 +660,9 @@ bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, | |||
640 | switch (short_hand) { | 660 | switch (short_hand) { |
641 | case APIC_DEST_NOSHORT: | 661 | case APIC_DEST_NOSHORT: |
642 | if (dest_mode == APIC_DEST_PHYSICAL) | 662 | if (dest_mode == APIC_DEST_PHYSICAL) |
643 | return kvm_apic_match_physical_addr(target, dest); | 663 | return kvm_apic_match_physical_addr(target, mda); |
644 | else | 664 | else |
645 | return kvm_apic_match_logical_addr(target, dest); | 665 | return kvm_apic_match_logical_addr(target, mda); |
646 | case APIC_DEST_SELF: | 666 | case APIC_DEST_SELF: |
647 | return target == source; | 667 | return target == source; |
648 | case APIC_DEST_ALLINC: | 668 | case APIC_DEST_ALLINC: |
@@ -664,6 +684,7 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, | |||
664 | struct kvm_lapic **dst; | 684 | struct kvm_lapic **dst; |
665 | int i; | 685 | int i; |
666 | bool ret = false; | 686 | bool ret = false; |
687 | bool x2apic_ipi = src && apic_x2apic_mode(src); | ||
667 | 688 | ||
668 | *r = -1; | 689 | *r = -1; |
669 | 690 | ||
@@ -675,15 +696,15 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, | |||
675 | if (irq->shorthand) | 696 | if (irq->shorthand) |
676 | return false; | 697 | return false; |
677 | 698 | ||
699 | if (irq->dest_id == (x2apic_ipi ? X2APIC_BROADCAST : APIC_BROADCAST)) | ||
700 | return false; | ||
701 | |||
678 | rcu_read_lock(); | 702 | rcu_read_lock(); |
679 | map = rcu_dereference(kvm->arch.apic_map); | 703 | map = rcu_dereference(kvm->arch.apic_map); |
680 | 704 | ||
681 | if (!map) | 705 | if (!map) |
682 | goto out; | 706 | goto out; |
683 | 707 | ||
684 | if (irq->dest_id == map->broadcast) | ||
685 | goto out; | ||
686 | |||
687 | ret = true; | 708 | ret = true; |
688 | 709 | ||
689 | if (irq->dest_mode == APIC_DEST_PHYSICAL) { | 710 | if (irq->dest_mode == APIC_DEST_PHYSICAL) { |
@@ -692,16 +713,20 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, | |||
692 | 713 | ||
693 | dst = &map->phys_map[irq->dest_id]; | 714 | dst = &map->phys_map[irq->dest_id]; |
694 | } else { | 715 | } else { |
695 | u32 mda = irq->dest_id << (32 - map->ldr_bits); | 716 | u16 cid; |
696 | u16 cid = apic_cluster_id(map, mda); | 717 | |
718 | if (!kvm_apic_logical_map_valid(map)) { | ||
719 | ret = false; | ||
720 | goto out; | ||
721 | } | ||
722 | |||
723 | apic_logical_id(map, irq->dest_id, &cid, (u16 *)&bitmap); | ||
697 | 724 | ||
698 | if (cid >= ARRAY_SIZE(map->logical_map)) | 725 | if (cid >= ARRAY_SIZE(map->logical_map)) |
699 | goto out; | 726 | goto out; |
700 | 727 | ||
701 | dst = map->logical_map[cid]; | 728 | dst = map->logical_map[cid]; |
702 | 729 | ||
703 | bitmap = apic_logical_id(map, mda); | ||
704 | |||
705 | if (irq->delivery_mode == APIC_DM_LOWEST) { | 730 | if (irq->delivery_mode == APIC_DM_LOWEST) { |
706 | int l = -1; | 731 | int l = -1; |
707 | for_each_set_bit(i, &bitmap, 16) { | 732 | for_each_set_bit(i, &bitmap, 16) { |
@@ -833,8 +858,7 @@ int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2) | |||
833 | 858 | ||
834 | static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector) | 859 | static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector) |
835 | { | 860 | { |
836 | if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) && | 861 | if (kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) { |
837 | kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) { | ||
838 | int trigger_mode; | 862 | int trigger_mode; |
839 | if (apic_test_vector(vector, apic->regs + APIC_TMR)) | 863 | if (apic_test_vector(vector, apic->regs + APIC_TMR)) |
840 | trigger_mode = IOAPIC_LEVEL_TRIG; | 864 | trigger_mode = IOAPIC_LEVEL_TRIG; |
@@ -1038,7 +1062,7 @@ static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr) | |||
1038 | addr < apic->base_address + LAPIC_MMIO_LENGTH; | 1062 | addr < apic->base_address + LAPIC_MMIO_LENGTH; |
1039 | } | 1063 | } |
1040 | 1064 | ||
1041 | static int apic_mmio_read(struct kvm_io_device *this, | 1065 | static int apic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this, |
1042 | gpa_t address, int len, void *data) | 1066 | gpa_t address, int len, void *data) |
1043 | { | 1067 | { |
1044 | struct kvm_lapic *apic = to_lapic(this); | 1068 | struct kvm_lapic *apic = to_lapic(this); |
@@ -1358,7 +1382,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) | |||
1358 | return ret; | 1382 | return ret; |
1359 | } | 1383 | } |
1360 | 1384 | ||
1361 | static int apic_mmio_write(struct kvm_io_device *this, | 1385 | static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this, |
1362 | gpa_t address, int len, const void *data) | 1386 | gpa_t address, int len, const void *data) |
1363 | { | 1387 | { |
1364 | struct kvm_lapic *apic = to_lapic(this); | 1388 | struct kvm_lapic *apic = to_lapic(this); |
@@ -1498,8 +1522,6 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | |||
1498 | return; | 1522 | return; |
1499 | } | 1523 | } |
1500 | 1524 | ||
1501 | if (!kvm_vcpu_is_bsp(apic->vcpu)) | ||
1502 | value &= ~MSR_IA32_APICBASE_BSP; | ||
1503 | vcpu->arch.apic_base = value; | 1525 | vcpu->arch.apic_base = value; |
1504 | 1526 | ||
1505 | /* update jump label if enable bit changes */ | 1527 | /* update jump label if enable bit changes */ |
@@ -1572,7 +1594,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
1572 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); | 1594 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); |
1573 | } | 1595 | } |
1574 | apic->irr_pending = kvm_apic_vid_enabled(vcpu->kvm); | 1596 | apic->irr_pending = kvm_apic_vid_enabled(vcpu->kvm); |
1575 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm); | 1597 | apic->isr_count = kvm_x86_ops->hwapic_isr_update ? 1 : 0; |
1576 | apic->highest_isr_cache = -1; | 1598 | apic->highest_isr_cache = -1; |
1577 | update_divide_count(apic); | 1599 | update_divide_count(apic); |
1578 | atomic_set(&apic->lapic_timer.pending, 0); | 1600 | atomic_set(&apic->lapic_timer.pending, 0); |
@@ -1782,7 +1804,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu, | |||
1782 | update_divide_count(apic); | 1804 | update_divide_count(apic); |
1783 | start_apic_timer(apic); | 1805 | start_apic_timer(apic); |
1784 | apic->irr_pending = true; | 1806 | apic->irr_pending = true; |
1785 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm) ? | 1807 | apic->isr_count = kvm_x86_ops->hwapic_isr_update ? |
1786 | 1 : count_vectors(apic->regs + APIC_ISR); | 1808 | 1 : count_vectors(apic->regs + APIC_ISR); |
1787 | apic->highest_isr_cache = -1; | 1809 | apic->highest_isr_cache = -1; |
1788 | if (kvm_x86_ops->hwapic_irr_update) | 1810 | if (kvm_x86_ops->hwapic_irr_update) |
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 0bc6c656625b..9d28383fc1e7 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef __KVM_X86_LAPIC_H | 1 | #ifndef __KVM_X86_LAPIC_H |
2 | #define __KVM_X86_LAPIC_H | 2 | #define __KVM_X86_LAPIC_H |
3 | 3 | ||
4 | #include "iodev.h" | 4 | #include <kvm/iodev.h> |
5 | 5 | ||
6 | #include <linux/kvm_host.h> | 6 | #include <linux/kvm_host.h> |
7 | 7 | ||
@@ -148,21 +148,6 @@ static inline bool kvm_apic_vid_enabled(struct kvm *kvm) | |||
148 | return kvm_x86_ops->vm_has_apicv(kvm); | 148 | return kvm_x86_ops->vm_has_apicv(kvm); |
149 | } | 149 | } |
150 | 150 | ||
151 | static inline u16 apic_cluster_id(struct kvm_apic_map *map, u32 ldr) | ||
152 | { | ||
153 | u16 cid; | ||
154 | ldr >>= 32 - map->ldr_bits; | ||
155 | cid = (ldr >> map->cid_shift) & map->cid_mask; | ||
156 | |||
157 | return cid; | ||
158 | } | ||
159 | |||
160 | static inline u16 apic_logical_id(struct kvm_apic_map *map, u32 ldr) | ||
161 | { | ||
162 | ldr >>= (32 - map->ldr_bits); | ||
163 | return ldr & map->lid_mask; | ||
164 | } | ||
165 | |||
166 | static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu) | 151 | static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu) |
167 | { | 152 | { |
168 | return vcpu->arch.apic->pending_events; | 153 | return vcpu->arch.apic->pending_events; |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index cee759299a35..146f295ee322 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -4465,6 +4465,79 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, | |||
4465 | kvm_flush_remote_tlbs(kvm); | 4465 | kvm_flush_remote_tlbs(kvm); |
4466 | } | 4466 | } |
4467 | 4467 | ||
4468 | static bool kvm_mmu_zap_collapsible_spte(struct kvm *kvm, | ||
4469 | unsigned long *rmapp) | ||
4470 | { | ||
4471 | u64 *sptep; | ||
4472 | struct rmap_iterator iter; | ||
4473 | int need_tlb_flush = 0; | ||
4474 | pfn_t pfn; | ||
4475 | struct kvm_mmu_page *sp; | ||
4476 | |||
4477 | for (sptep = rmap_get_first(*rmapp, &iter); sptep;) { | ||
4478 | BUG_ON(!(*sptep & PT_PRESENT_MASK)); | ||
4479 | |||
4480 | sp = page_header(__pa(sptep)); | ||
4481 | pfn = spte_to_pfn(*sptep); | ||
4482 | |||
4483 | /* | ||
4484 | * Only EPT supported for now; otherwise, one would need to | ||
4485 | * find out efficiently whether the guest page tables are | ||
4486 | * also using huge pages. | ||
4487 | */ | ||
4488 | if (sp->role.direct && | ||
4489 | !kvm_is_reserved_pfn(pfn) && | ||
4490 | PageTransCompound(pfn_to_page(pfn))) { | ||
4491 | drop_spte(kvm, sptep); | ||
4492 | sptep = rmap_get_first(*rmapp, &iter); | ||
4493 | need_tlb_flush = 1; | ||
4494 | } else | ||
4495 | sptep = rmap_get_next(&iter); | ||
4496 | } | ||
4497 | |||
4498 | return need_tlb_flush; | ||
4499 | } | ||
4500 | |||
4501 | void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, | ||
4502 | struct kvm_memory_slot *memslot) | ||
4503 | { | ||
4504 | bool flush = false; | ||
4505 | unsigned long *rmapp; | ||
4506 | unsigned long last_index, index; | ||
4507 | gfn_t gfn_start, gfn_end; | ||
4508 | |||
4509 | spin_lock(&kvm->mmu_lock); | ||
4510 | |||
4511 | gfn_start = memslot->base_gfn; | ||
4512 | gfn_end = memslot->base_gfn + memslot->npages - 1; | ||
4513 | |||
4514 | if (gfn_start >= gfn_end) | ||
4515 | goto out; | ||
4516 | |||
4517 | rmapp = memslot->arch.rmap[0]; | ||
4518 | last_index = gfn_to_index(gfn_end, memslot->base_gfn, | ||
4519 | PT_PAGE_TABLE_LEVEL); | ||
4520 | |||
4521 | for (index = 0; index <= last_index; ++index, ++rmapp) { | ||
4522 | if (*rmapp) | ||
4523 | flush |= kvm_mmu_zap_collapsible_spte(kvm, rmapp); | ||
4524 | |||
4525 | if (need_resched() || spin_needbreak(&kvm->mmu_lock)) { | ||
4526 | if (flush) { | ||
4527 | kvm_flush_remote_tlbs(kvm); | ||
4528 | flush = false; | ||
4529 | } | ||
4530 | cond_resched_lock(&kvm->mmu_lock); | ||
4531 | } | ||
4532 | } | ||
4533 | |||
4534 | if (flush) | ||
4535 | kvm_flush_remote_tlbs(kvm); | ||
4536 | |||
4537 | out: | ||
4538 | spin_unlock(&kvm->mmu_lock); | ||
4539 | } | ||
4540 | |||
4468 | void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm, | 4541 | void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm, |
4469 | struct kvm_memory_slot *memslot) | 4542 | struct kvm_memory_slot *memslot) |
4470 | { | 4543 | { |
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 8e6b7d869d2f..29fbf9dfdc54 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c | |||
@@ -38,7 +38,7 @@ static struct kvm_arch_event_perf_mapping { | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | /* mapping between fixed pmc index and arch_events array */ | 40 | /* mapping between fixed pmc index and arch_events array */ |
41 | int fixed_pmc_events[] = {1, 0, 7}; | 41 | static int fixed_pmc_events[] = {1, 0, 7}; |
42 | 42 | ||
43 | static bool pmc_is_gp(struct kvm_pmc *pmc) | 43 | static bool pmc_is_gp(struct kvm_pmc *pmc) |
44 | { | 44 | { |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index d319e0c24758..ce741b8650f6 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1261,7 +1261,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
1261 | 1261 | ||
1262 | svm->vcpu.arch.apic_base = APIC_DEFAULT_PHYS_BASE | | 1262 | svm->vcpu.arch.apic_base = APIC_DEFAULT_PHYS_BASE | |
1263 | MSR_IA32_APICBASE_ENABLE; | 1263 | MSR_IA32_APICBASE_ENABLE; |
1264 | if (kvm_vcpu_is_bsp(&svm->vcpu)) | 1264 | if (kvm_vcpu_is_reset_bsp(&svm->vcpu)) |
1265 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; | 1265 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; |
1266 | 1266 | ||
1267 | svm_init_osvw(&svm->vcpu); | 1267 | svm_init_osvw(&svm->vcpu); |
@@ -1929,14 +1929,12 @@ static int nop_on_interception(struct vcpu_svm *svm) | |||
1929 | static int halt_interception(struct vcpu_svm *svm) | 1929 | static int halt_interception(struct vcpu_svm *svm) |
1930 | { | 1930 | { |
1931 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 1; | 1931 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 1; |
1932 | skip_emulated_instruction(&svm->vcpu); | ||
1933 | return kvm_emulate_halt(&svm->vcpu); | 1932 | return kvm_emulate_halt(&svm->vcpu); |
1934 | } | 1933 | } |
1935 | 1934 | ||
1936 | static int vmmcall_interception(struct vcpu_svm *svm) | 1935 | static int vmmcall_interception(struct vcpu_svm *svm) |
1937 | { | 1936 | { |
1938 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 1937 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
1939 | skip_emulated_instruction(&svm->vcpu); | ||
1940 | kvm_emulate_hypercall(&svm->vcpu); | 1938 | kvm_emulate_hypercall(&svm->vcpu); |
1941 | return 1; | 1939 | return 1; |
1942 | } | 1940 | } |
@@ -2757,11 +2755,11 @@ static int invlpga_interception(struct vcpu_svm *svm) | |||
2757 | { | 2755 | { |
2758 | struct kvm_vcpu *vcpu = &svm->vcpu; | 2756 | struct kvm_vcpu *vcpu = &svm->vcpu; |
2759 | 2757 | ||
2760 | trace_kvm_invlpga(svm->vmcb->save.rip, vcpu->arch.regs[VCPU_REGS_RCX], | 2758 | trace_kvm_invlpga(svm->vmcb->save.rip, kvm_register_read(&svm->vcpu, VCPU_REGS_RCX), |
2761 | vcpu->arch.regs[VCPU_REGS_RAX]); | 2759 | kvm_register_read(&svm->vcpu, VCPU_REGS_RAX)); |
2762 | 2760 | ||
2763 | /* Let's treat INVLPGA the same as INVLPG (can be optimized!) */ | 2761 | /* Let's treat INVLPGA the same as INVLPG (can be optimized!) */ |
2764 | kvm_mmu_invlpg(vcpu, vcpu->arch.regs[VCPU_REGS_RAX]); | 2762 | kvm_mmu_invlpg(vcpu, kvm_register_read(&svm->vcpu, VCPU_REGS_RAX)); |
2765 | 2763 | ||
2766 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 2764 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
2767 | skip_emulated_instruction(&svm->vcpu); | 2765 | skip_emulated_instruction(&svm->vcpu); |
@@ -2770,12 +2768,18 @@ static int invlpga_interception(struct vcpu_svm *svm) | |||
2770 | 2768 | ||
2771 | static int skinit_interception(struct vcpu_svm *svm) | 2769 | static int skinit_interception(struct vcpu_svm *svm) |
2772 | { | 2770 | { |
2773 | trace_kvm_skinit(svm->vmcb->save.rip, svm->vcpu.arch.regs[VCPU_REGS_RAX]); | 2771 | trace_kvm_skinit(svm->vmcb->save.rip, kvm_register_read(&svm->vcpu, VCPU_REGS_RAX)); |
2774 | 2772 | ||
2775 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); | 2773 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); |
2776 | return 1; | 2774 | return 1; |
2777 | } | 2775 | } |
2778 | 2776 | ||
2777 | static int wbinvd_interception(struct vcpu_svm *svm) | ||
2778 | { | ||
2779 | kvm_emulate_wbinvd(&svm->vcpu); | ||
2780 | return 1; | ||
2781 | } | ||
2782 | |||
2779 | static int xsetbv_interception(struct vcpu_svm *svm) | 2783 | static int xsetbv_interception(struct vcpu_svm *svm) |
2780 | { | 2784 | { |
2781 | u64 new_bv = kvm_read_edx_eax(&svm->vcpu); | 2785 | u64 new_bv = kvm_read_edx_eax(&svm->vcpu); |
@@ -2902,7 +2906,8 @@ static int rdpmc_interception(struct vcpu_svm *svm) | |||
2902 | return 1; | 2906 | return 1; |
2903 | } | 2907 | } |
2904 | 2908 | ||
2905 | bool check_selective_cr0_intercepted(struct vcpu_svm *svm, unsigned long val) | 2909 | static bool check_selective_cr0_intercepted(struct vcpu_svm *svm, |
2910 | unsigned long val) | ||
2906 | { | 2911 | { |
2907 | unsigned long cr0 = svm->vcpu.arch.cr0; | 2912 | unsigned long cr0 = svm->vcpu.arch.cr0; |
2908 | bool ret = false; | 2913 | bool ret = false; |
@@ -2940,7 +2945,10 @@ static int cr_interception(struct vcpu_svm *svm) | |||
2940 | return emulate_on_interception(svm); | 2945 | return emulate_on_interception(svm); |
2941 | 2946 | ||
2942 | reg = svm->vmcb->control.exit_info_1 & SVM_EXITINFO_REG_MASK; | 2947 | reg = svm->vmcb->control.exit_info_1 & SVM_EXITINFO_REG_MASK; |
2943 | cr = svm->vmcb->control.exit_code - SVM_EXIT_READ_CR0; | 2948 | if (svm->vmcb->control.exit_code == SVM_EXIT_CR0_SEL_WRITE) |
2949 | cr = SVM_EXIT_WRITE_CR0 - SVM_EXIT_READ_CR0; | ||
2950 | else | ||
2951 | cr = svm->vmcb->control.exit_code - SVM_EXIT_READ_CR0; | ||
2944 | 2952 | ||
2945 | err = 0; | 2953 | err = 0; |
2946 | if (cr >= 16) { /* mov to cr */ | 2954 | if (cr >= 16) { /* mov to cr */ |
@@ -3133,7 +3141,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | |||
3133 | 3141 | ||
3134 | static int rdmsr_interception(struct vcpu_svm *svm) | 3142 | static int rdmsr_interception(struct vcpu_svm *svm) |
3135 | { | 3143 | { |
3136 | u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; | 3144 | u32 ecx = kvm_register_read(&svm->vcpu, VCPU_REGS_RCX); |
3137 | u64 data; | 3145 | u64 data; |
3138 | 3146 | ||
3139 | if (svm_get_msr(&svm->vcpu, ecx, &data)) { | 3147 | if (svm_get_msr(&svm->vcpu, ecx, &data)) { |
@@ -3142,8 +3150,8 @@ static int rdmsr_interception(struct vcpu_svm *svm) | |||
3142 | } else { | 3150 | } else { |
3143 | trace_kvm_msr_read(ecx, data); | 3151 | trace_kvm_msr_read(ecx, data); |
3144 | 3152 | ||
3145 | svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; | 3153 | kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, data & 0xffffffff); |
3146 | svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32; | 3154 | kvm_register_write(&svm->vcpu, VCPU_REGS_RDX, data >> 32); |
3147 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; | 3155 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; |
3148 | skip_emulated_instruction(&svm->vcpu); | 3156 | skip_emulated_instruction(&svm->vcpu); |
3149 | } | 3157 | } |
@@ -3246,9 +3254,8 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) | |||
3246 | static int wrmsr_interception(struct vcpu_svm *svm) | 3254 | static int wrmsr_interception(struct vcpu_svm *svm) |
3247 | { | 3255 | { |
3248 | struct msr_data msr; | 3256 | struct msr_data msr; |
3249 | u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; | 3257 | u32 ecx = kvm_register_read(&svm->vcpu, VCPU_REGS_RCX); |
3250 | u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) | 3258 | u64 data = kvm_read_edx_eax(&svm->vcpu); |
3251 | | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); | ||
3252 | 3259 | ||
3253 | msr.data = data; | 3260 | msr.data = data; |
3254 | msr.index = ecx; | 3261 | msr.index = ecx; |
@@ -3325,7 +3332,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { | |||
3325 | [SVM_EXIT_READ_CR3] = cr_interception, | 3332 | [SVM_EXIT_READ_CR3] = cr_interception, |
3326 | [SVM_EXIT_READ_CR4] = cr_interception, | 3333 | [SVM_EXIT_READ_CR4] = cr_interception, |
3327 | [SVM_EXIT_READ_CR8] = cr_interception, | 3334 | [SVM_EXIT_READ_CR8] = cr_interception, |
3328 | [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, | 3335 | [SVM_EXIT_CR0_SEL_WRITE] = cr_interception, |
3329 | [SVM_EXIT_WRITE_CR0] = cr_interception, | 3336 | [SVM_EXIT_WRITE_CR0] = cr_interception, |
3330 | [SVM_EXIT_WRITE_CR3] = cr_interception, | 3337 | [SVM_EXIT_WRITE_CR3] = cr_interception, |
3331 | [SVM_EXIT_WRITE_CR4] = cr_interception, | 3338 | [SVM_EXIT_WRITE_CR4] = cr_interception, |
@@ -3376,7 +3383,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { | |||
3376 | [SVM_EXIT_STGI] = stgi_interception, | 3383 | [SVM_EXIT_STGI] = stgi_interception, |
3377 | [SVM_EXIT_CLGI] = clgi_interception, | 3384 | [SVM_EXIT_CLGI] = clgi_interception, |
3378 | [SVM_EXIT_SKINIT] = skinit_interception, | 3385 | [SVM_EXIT_SKINIT] = skinit_interception, |
3379 | [SVM_EXIT_WBINVD] = emulate_on_interception, | 3386 | [SVM_EXIT_WBINVD] = wbinvd_interception, |
3380 | [SVM_EXIT_MONITOR] = monitor_interception, | 3387 | [SVM_EXIT_MONITOR] = monitor_interception, |
3381 | [SVM_EXIT_MWAIT] = mwait_interception, | 3388 | [SVM_EXIT_MWAIT] = mwait_interception, |
3382 | [SVM_EXIT_XSETBV] = xsetbv_interception, | 3389 | [SVM_EXIT_XSETBV] = xsetbv_interception, |
@@ -3555,7 +3562,7 @@ static int handle_exit(struct kvm_vcpu *vcpu) | |||
3555 | 3562 | ||
3556 | if (exit_code >= ARRAY_SIZE(svm_exit_handlers) | 3563 | if (exit_code >= ARRAY_SIZE(svm_exit_handlers) |
3557 | || !svm_exit_handlers[exit_code]) { | 3564 | || !svm_exit_handlers[exit_code]) { |
3558 | WARN_ONCE(1, "vmx: unexpected exit reason 0x%x\n", exit_code); | 3565 | WARN_ONCE(1, "svm: unexpected exit reason 0x%x\n", exit_code); |
3559 | kvm_queue_exception(vcpu, UD_VECTOR); | 3566 | kvm_queue_exception(vcpu, UD_VECTOR); |
3560 | return 1; | 3567 | return 1; |
3561 | } | 3568 | } |
@@ -3649,11 +3656,6 @@ static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) | |||
3649 | return; | 3656 | return; |
3650 | } | 3657 | } |
3651 | 3658 | ||
3652 | static void svm_hwapic_isr_update(struct kvm *kvm, int isr) | ||
3653 | { | ||
3654 | return; | ||
3655 | } | ||
3656 | |||
3657 | static void svm_sync_pir_to_irr(struct kvm_vcpu *vcpu) | 3659 | static void svm_sync_pir_to_irr(struct kvm_vcpu *vcpu) |
3658 | { | 3660 | { |
3659 | return; | 3661 | return; |
@@ -4403,7 +4405,6 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
4403 | .set_virtual_x2apic_mode = svm_set_virtual_x2apic_mode, | 4405 | .set_virtual_x2apic_mode = svm_set_virtual_x2apic_mode, |
4404 | .vm_has_apicv = svm_vm_has_apicv, | 4406 | .vm_has_apicv = svm_vm_has_apicv, |
4405 | .load_eoi_exitmap = svm_load_eoi_exitmap, | 4407 | .load_eoi_exitmap = svm_load_eoi_exitmap, |
4406 | .hwapic_isr_update = svm_hwapic_isr_update, | ||
4407 | .sync_pir_to_irr = svm_sync_pir_to_irr, | 4408 | .sync_pir_to_irr = svm_sync_pir_to_irr, |
4408 | 4409 | ||
4409 | .set_tss_addr = svm_set_tss_addr, | 4410 | .set_tss_addr = svm_set_tss_addr, |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 14c1a18d206a..f5e8dce8046c 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -2168,7 +2168,10 @@ static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu) | |||
2168 | { | 2168 | { |
2169 | unsigned long *msr_bitmap; | 2169 | unsigned long *msr_bitmap; |
2170 | 2170 | ||
2171 | if (irqchip_in_kernel(vcpu->kvm) && apic_x2apic_mode(vcpu->arch.apic)) { | 2171 | if (is_guest_mode(vcpu)) |
2172 | msr_bitmap = vmx_msr_bitmap_nested; | ||
2173 | else if (irqchip_in_kernel(vcpu->kvm) && | ||
2174 | apic_x2apic_mode(vcpu->arch.apic)) { | ||
2172 | if (is_long_mode(vcpu)) | 2175 | if (is_long_mode(vcpu)) |
2173 | msr_bitmap = vmx_msr_bitmap_longmode_x2apic; | 2176 | msr_bitmap = vmx_msr_bitmap_longmode_x2apic; |
2174 | else | 2177 | else |
@@ -2467,6 +2470,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) | |||
2467 | vmx->nested.nested_vmx_secondary_ctls_low = 0; | 2470 | vmx->nested.nested_vmx_secondary_ctls_low = 0; |
2468 | vmx->nested.nested_vmx_secondary_ctls_high &= | 2471 | vmx->nested.nested_vmx_secondary_ctls_high &= |
2469 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | | 2472 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
2473 | SECONDARY_EXEC_RDTSCP | | ||
2470 | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | | 2474 | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | |
2471 | SECONDARY_EXEC_APIC_REGISTER_VIRT | | 2475 | SECONDARY_EXEC_APIC_REGISTER_VIRT | |
2472 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | | 2476 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | |
@@ -2476,8 +2480,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) | |||
2476 | if (enable_ept) { | 2480 | if (enable_ept) { |
2477 | /* nested EPT: emulate EPT also to L1 */ | 2481 | /* nested EPT: emulate EPT also to L1 */ |
2478 | vmx->nested.nested_vmx_secondary_ctls_high |= | 2482 | vmx->nested.nested_vmx_secondary_ctls_high |= |
2479 | SECONDARY_EXEC_ENABLE_EPT | | 2483 | SECONDARY_EXEC_ENABLE_EPT; |
2480 | SECONDARY_EXEC_UNRESTRICTED_GUEST; | ||
2481 | vmx->nested.nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | | 2484 | vmx->nested.nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | |
2482 | VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT | | 2485 | VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT | |
2483 | VMX_EPT_INVEPT_BIT; | 2486 | VMX_EPT_INVEPT_BIT; |
@@ -2491,6 +2494,10 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) | |||
2491 | } else | 2494 | } else |
2492 | vmx->nested.nested_vmx_ept_caps = 0; | 2495 | vmx->nested.nested_vmx_ept_caps = 0; |
2493 | 2496 | ||
2497 | if (enable_unrestricted_guest) | ||
2498 | vmx->nested.nested_vmx_secondary_ctls_high |= | ||
2499 | SECONDARY_EXEC_UNRESTRICTED_GUEST; | ||
2500 | |||
2494 | /* miscellaneous data */ | 2501 | /* miscellaneous data */ |
2495 | rdmsr(MSR_IA32_VMX_MISC, | 2502 | rdmsr(MSR_IA32_VMX_MISC, |
2496 | vmx->nested.nested_vmx_misc_low, | 2503 | vmx->nested.nested_vmx_misc_low, |
@@ -3262,8 +3269,8 @@ static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg, | |||
3262 | * default value. | 3269 | * default value. |
3263 | */ | 3270 | */ |
3264 | if (seg == VCPU_SREG_CS || seg == VCPU_SREG_SS) | 3271 | if (seg == VCPU_SREG_CS || seg == VCPU_SREG_SS) |
3265 | save->selector &= ~SELECTOR_RPL_MASK; | 3272 | save->selector &= ~SEGMENT_RPL_MASK; |
3266 | save->dpl = save->selector & SELECTOR_RPL_MASK; | 3273 | save->dpl = save->selector & SEGMENT_RPL_MASK; |
3267 | save->s = 1; | 3274 | save->s = 1; |
3268 | } | 3275 | } |
3269 | vmx_set_segment(vcpu, save, seg); | 3276 | vmx_set_segment(vcpu, save, seg); |
@@ -3836,7 +3843,7 @@ static bool code_segment_valid(struct kvm_vcpu *vcpu) | |||
3836 | unsigned int cs_rpl; | 3843 | unsigned int cs_rpl; |
3837 | 3844 | ||
3838 | vmx_get_segment(vcpu, &cs, VCPU_SREG_CS); | 3845 | vmx_get_segment(vcpu, &cs, VCPU_SREG_CS); |
3839 | cs_rpl = cs.selector & SELECTOR_RPL_MASK; | 3846 | cs_rpl = cs.selector & SEGMENT_RPL_MASK; |
3840 | 3847 | ||
3841 | if (cs.unusable) | 3848 | if (cs.unusable) |
3842 | return false; | 3849 | return false; |
@@ -3864,7 +3871,7 @@ static bool stack_segment_valid(struct kvm_vcpu *vcpu) | |||
3864 | unsigned int ss_rpl; | 3871 | unsigned int ss_rpl; |
3865 | 3872 | ||
3866 | vmx_get_segment(vcpu, &ss, VCPU_SREG_SS); | 3873 | vmx_get_segment(vcpu, &ss, VCPU_SREG_SS); |
3867 | ss_rpl = ss.selector & SELECTOR_RPL_MASK; | 3874 | ss_rpl = ss.selector & SEGMENT_RPL_MASK; |
3868 | 3875 | ||
3869 | if (ss.unusable) | 3876 | if (ss.unusable) |
3870 | return true; | 3877 | return true; |
@@ -3886,7 +3893,7 @@ static bool data_segment_valid(struct kvm_vcpu *vcpu, int seg) | |||
3886 | unsigned int rpl; | 3893 | unsigned int rpl; |
3887 | 3894 | ||
3888 | vmx_get_segment(vcpu, &var, seg); | 3895 | vmx_get_segment(vcpu, &var, seg); |
3889 | rpl = var.selector & SELECTOR_RPL_MASK; | 3896 | rpl = var.selector & SEGMENT_RPL_MASK; |
3890 | 3897 | ||
3891 | if (var.unusable) | 3898 | if (var.unusable) |
3892 | return true; | 3899 | return true; |
@@ -3913,7 +3920,7 @@ static bool tr_valid(struct kvm_vcpu *vcpu) | |||
3913 | 3920 | ||
3914 | if (tr.unusable) | 3921 | if (tr.unusable) |
3915 | return false; | 3922 | return false; |
3916 | if (tr.selector & SELECTOR_TI_MASK) /* TI = 1 */ | 3923 | if (tr.selector & SEGMENT_TI_MASK) /* TI = 1 */ |
3917 | return false; | 3924 | return false; |
3918 | if (tr.type != 3 && tr.type != 11) /* TODO: Check if guest is in IA32e mode */ | 3925 | if (tr.type != 3 && tr.type != 11) /* TODO: Check if guest is in IA32e mode */ |
3919 | return false; | 3926 | return false; |
@@ -3931,7 +3938,7 @@ static bool ldtr_valid(struct kvm_vcpu *vcpu) | |||
3931 | 3938 | ||
3932 | if (ldtr.unusable) | 3939 | if (ldtr.unusable) |
3933 | return true; | 3940 | return true; |
3934 | if (ldtr.selector & SELECTOR_TI_MASK) /* TI = 1 */ | 3941 | if (ldtr.selector & SEGMENT_TI_MASK) /* TI = 1 */ |
3935 | return false; | 3942 | return false; |
3936 | if (ldtr.type != 2) | 3943 | if (ldtr.type != 2) |
3937 | return false; | 3944 | return false; |
@@ -3948,8 +3955,8 @@ static bool cs_ss_rpl_check(struct kvm_vcpu *vcpu) | |||
3948 | vmx_get_segment(vcpu, &cs, VCPU_SREG_CS); | 3955 | vmx_get_segment(vcpu, &cs, VCPU_SREG_CS); |
3949 | vmx_get_segment(vcpu, &ss, VCPU_SREG_SS); | 3956 | vmx_get_segment(vcpu, &ss, VCPU_SREG_SS); |
3950 | 3957 | ||
3951 | return ((cs.selector & SELECTOR_RPL_MASK) == | 3958 | return ((cs.selector & SEGMENT_RPL_MASK) == |
3952 | (ss.selector & SELECTOR_RPL_MASK)); | 3959 | (ss.selector & SEGMENT_RPL_MASK)); |
3953 | } | 3960 | } |
3954 | 3961 | ||
3955 | /* | 3962 | /* |
@@ -4367,6 +4374,18 @@ static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) | |||
4367 | return 0; | 4374 | return 0; |
4368 | } | 4375 | } |
4369 | 4376 | ||
4377 | static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu) | ||
4378 | { | ||
4379 | #ifdef CONFIG_SMP | ||
4380 | if (vcpu->mode == IN_GUEST_MODE) { | ||
4381 | apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), | ||
4382 | POSTED_INTR_VECTOR); | ||
4383 | return true; | ||
4384 | } | ||
4385 | #endif | ||
4386 | return false; | ||
4387 | } | ||
4388 | |||
4370 | static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, | 4389 | static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, |
4371 | int vector) | 4390 | int vector) |
4372 | { | 4391 | { |
@@ -4375,9 +4394,7 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, | |||
4375 | if (is_guest_mode(vcpu) && | 4394 | if (is_guest_mode(vcpu) && |
4376 | vector == vmx->nested.posted_intr_nv) { | 4395 | vector == vmx->nested.posted_intr_nv) { |
4377 | /* the PIR and ON have been set by L1. */ | 4396 | /* the PIR and ON have been set by L1. */ |
4378 | if (vcpu->mode == IN_GUEST_MODE) | 4397 | kvm_vcpu_trigger_posted_interrupt(vcpu); |
4379 | apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), | ||
4380 | POSTED_INTR_VECTOR); | ||
4381 | /* | 4398 | /* |
4382 | * If a posted intr is not recognized by hardware, | 4399 | * If a posted intr is not recognized by hardware, |
4383 | * we will accomplish it in the next vmentry. | 4400 | * we will accomplish it in the next vmentry. |
@@ -4409,12 +4426,7 @@ static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector) | |||
4409 | 4426 | ||
4410 | r = pi_test_and_set_on(&vmx->pi_desc); | 4427 | r = pi_test_and_set_on(&vmx->pi_desc); |
4411 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 4428 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
4412 | #ifdef CONFIG_SMP | 4429 | if (r || !kvm_vcpu_trigger_posted_interrupt(vcpu)) |
4413 | if (!r && (vcpu->mode == IN_GUEST_MODE)) | ||
4414 | apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), | ||
4415 | POSTED_INTR_VECTOR); | ||
4416 | else | ||
4417 | #endif | ||
4418 | kvm_vcpu_kick(vcpu); | 4430 | kvm_vcpu_kick(vcpu); |
4419 | } | 4431 | } |
4420 | 4432 | ||
@@ -4700,7 +4712,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu) | |||
4700 | vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val(); | 4712 | vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val(); |
4701 | kvm_set_cr8(&vmx->vcpu, 0); | 4713 | kvm_set_cr8(&vmx->vcpu, 0); |
4702 | apic_base_msr.data = APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE; | 4714 | apic_base_msr.data = APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE; |
4703 | if (kvm_vcpu_is_bsp(&vmx->vcpu)) | 4715 | if (kvm_vcpu_is_reset_bsp(&vmx->vcpu)) |
4704 | apic_base_msr.data |= MSR_IA32_APICBASE_BSP; | 4716 | apic_base_msr.data |= MSR_IA32_APICBASE_BSP; |
4705 | apic_base_msr.host_initiated = true; | 4717 | apic_base_msr.host_initiated = true; |
4706 | kvm_set_apic_base(&vmx->vcpu, &apic_base_msr); | 4718 | kvm_set_apic_base(&vmx->vcpu, &apic_base_msr); |
@@ -4995,7 +5007,7 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, | |||
4995 | if (emulate_instruction(vcpu, 0) == EMULATE_DONE) { | 5007 | if (emulate_instruction(vcpu, 0) == EMULATE_DONE) { |
4996 | if (vcpu->arch.halt_request) { | 5008 | if (vcpu->arch.halt_request) { |
4997 | vcpu->arch.halt_request = 0; | 5009 | vcpu->arch.halt_request = 0; |
4998 | return kvm_emulate_halt(vcpu); | 5010 | return kvm_vcpu_halt(vcpu); |
4999 | } | 5011 | } |
5000 | return 1; | 5012 | return 1; |
5001 | } | 5013 | } |
@@ -5060,6 +5072,10 @@ static int handle_exception(struct kvm_vcpu *vcpu) | |||
5060 | } | 5072 | } |
5061 | 5073 | ||
5062 | if (is_invalid_opcode(intr_info)) { | 5074 | if (is_invalid_opcode(intr_info)) { |
5075 | if (is_guest_mode(vcpu)) { | ||
5076 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
5077 | return 1; | ||
5078 | } | ||
5063 | er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD); | 5079 | er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD); |
5064 | if (er != EMULATE_DONE) | 5080 | if (er != EMULATE_DONE) |
5065 | kvm_queue_exception(vcpu, UD_VECTOR); | 5081 | kvm_queue_exception(vcpu, UD_VECTOR); |
@@ -5079,9 +5095,10 @@ static int handle_exception(struct kvm_vcpu *vcpu) | |||
5079 | !(is_page_fault(intr_info) && !(error_code & PFERR_RSVD_MASK))) { | 5095 | !(is_page_fault(intr_info) && !(error_code & PFERR_RSVD_MASK))) { |
5080 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | 5096 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; |
5081 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_SIMUL_EX; | 5097 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_SIMUL_EX; |
5082 | vcpu->run->internal.ndata = 2; | 5098 | vcpu->run->internal.ndata = 3; |
5083 | vcpu->run->internal.data[0] = vect_info; | 5099 | vcpu->run->internal.data[0] = vect_info; |
5084 | vcpu->run->internal.data[1] = intr_info; | 5100 | vcpu->run->internal.data[1] = intr_info; |
5101 | vcpu->run->internal.data[2] = error_code; | ||
5085 | return 0; | 5102 | return 0; |
5086 | } | 5103 | } |
5087 | 5104 | ||
@@ -5522,13 +5539,11 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu) | |||
5522 | 5539 | ||
5523 | static int handle_halt(struct kvm_vcpu *vcpu) | 5540 | static int handle_halt(struct kvm_vcpu *vcpu) |
5524 | { | 5541 | { |
5525 | skip_emulated_instruction(vcpu); | ||
5526 | return kvm_emulate_halt(vcpu); | 5542 | return kvm_emulate_halt(vcpu); |
5527 | } | 5543 | } |
5528 | 5544 | ||
5529 | static int handle_vmcall(struct kvm_vcpu *vcpu) | 5545 | static int handle_vmcall(struct kvm_vcpu *vcpu) |
5530 | { | 5546 | { |
5531 | skip_emulated_instruction(vcpu); | ||
5532 | kvm_emulate_hypercall(vcpu); | 5547 | kvm_emulate_hypercall(vcpu); |
5533 | return 1; | 5548 | return 1; |
5534 | } | 5549 | } |
@@ -5559,7 +5574,6 @@ static int handle_rdpmc(struct kvm_vcpu *vcpu) | |||
5559 | 5574 | ||
5560 | static int handle_wbinvd(struct kvm_vcpu *vcpu) | 5575 | static int handle_wbinvd(struct kvm_vcpu *vcpu) |
5561 | { | 5576 | { |
5562 | skip_emulated_instruction(vcpu); | ||
5563 | kvm_emulate_wbinvd(vcpu); | 5577 | kvm_emulate_wbinvd(vcpu); |
5564 | return 1; | 5578 | return 1; |
5565 | } | 5579 | } |
@@ -5817,7 +5831,7 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu) | |||
5817 | gpa_t gpa; | 5831 | gpa_t gpa; |
5818 | 5832 | ||
5819 | gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); | 5833 | gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); |
5820 | if (!kvm_io_bus_write(vcpu->kvm, KVM_FAST_MMIO_BUS, gpa, 0, NULL)) { | 5834 | if (!kvm_io_bus_write(vcpu, KVM_FAST_MMIO_BUS, gpa, 0, NULL)) { |
5821 | skip_emulated_instruction(vcpu); | 5835 | skip_emulated_instruction(vcpu); |
5822 | return 1; | 5836 | return 1; |
5823 | } | 5837 | } |
@@ -5898,7 +5912,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) | |||
5898 | 5912 | ||
5899 | if (vcpu->arch.halt_request) { | 5913 | if (vcpu->arch.halt_request) { |
5900 | vcpu->arch.halt_request = 0; | 5914 | vcpu->arch.halt_request = 0; |
5901 | ret = kvm_emulate_halt(vcpu); | 5915 | ret = kvm_vcpu_halt(vcpu); |
5902 | goto out; | 5916 | goto out; |
5903 | } | 5917 | } |
5904 | 5918 | ||
@@ -7307,21 +7321,21 @@ static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, | |||
7307 | else if (port < 0x10000) | 7321 | else if (port < 0x10000) |
7308 | bitmap = vmcs12->io_bitmap_b; | 7322 | bitmap = vmcs12->io_bitmap_b; |
7309 | else | 7323 | else |
7310 | return 1; | 7324 | return true; |
7311 | bitmap += (port & 0x7fff) / 8; | 7325 | bitmap += (port & 0x7fff) / 8; |
7312 | 7326 | ||
7313 | if (last_bitmap != bitmap) | 7327 | if (last_bitmap != bitmap) |
7314 | if (kvm_read_guest(vcpu->kvm, bitmap, &b, 1)) | 7328 | if (kvm_read_guest(vcpu->kvm, bitmap, &b, 1)) |
7315 | return 1; | 7329 | return true; |
7316 | if (b & (1 << (port & 7))) | 7330 | if (b & (1 << (port & 7))) |
7317 | return 1; | 7331 | return true; |
7318 | 7332 | ||
7319 | port++; | 7333 | port++; |
7320 | size--; | 7334 | size--; |
7321 | last_bitmap = bitmap; | 7335 | last_bitmap = bitmap; |
7322 | } | 7336 | } |
7323 | 7337 | ||
7324 | return 0; | 7338 | return false; |
7325 | } | 7339 | } |
7326 | 7340 | ||
7327 | /* | 7341 | /* |
@@ -7337,7 +7351,7 @@ static bool nested_vmx_exit_handled_msr(struct kvm_vcpu *vcpu, | |||
7337 | gpa_t bitmap; | 7351 | gpa_t bitmap; |
7338 | 7352 | ||
7339 | if (!nested_cpu_has(vmcs12, CPU_BASED_USE_MSR_BITMAPS)) | 7353 | if (!nested_cpu_has(vmcs12, CPU_BASED_USE_MSR_BITMAPS)) |
7340 | return 1; | 7354 | return true; |
7341 | 7355 | ||
7342 | /* | 7356 | /* |
7343 | * The MSR_BITMAP page is divided into four 1024-byte bitmaps, | 7357 | * The MSR_BITMAP page is divided into four 1024-byte bitmaps, |
@@ -7356,10 +7370,10 @@ static bool nested_vmx_exit_handled_msr(struct kvm_vcpu *vcpu, | |||
7356 | if (msr_index < 1024*8) { | 7370 | if (msr_index < 1024*8) { |
7357 | unsigned char b; | 7371 | unsigned char b; |
7358 | if (kvm_read_guest(vcpu->kvm, bitmap + msr_index/8, &b, 1)) | 7372 | if (kvm_read_guest(vcpu->kvm, bitmap + msr_index/8, &b, 1)) |
7359 | return 1; | 7373 | return true; |
7360 | return 1 & (b >> (msr_index & 7)); | 7374 | return 1 & (b >> (msr_index & 7)); |
7361 | } else | 7375 | } else |
7362 | return 1; /* let L1 handle the wrong parameter */ | 7376 | return true; /* let L1 handle the wrong parameter */ |
7363 | } | 7377 | } |
7364 | 7378 | ||
7365 | /* | 7379 | /* |
@@ -7381,7 +7395,7 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu, | |||
7381 | case 0: | 7395 | case 0: |
7382 | if (vmcs12->cr0_guest_host_mask & | 7396 | if (vmcs12->cr0_guest_host_mask & |
7383 | (val ^ vmcs12->cr0_read_shadow)) | 7397 | (val ^ vmcs12->cr0_read_shadow)) |
7384 | return 1; | 7398 | return true; |
7385 | break; | 7399 | break; |
7386 | case 3: | 7400 | case 3: |
7387 | if ((vmcs12->cr3_target_count >= 1 && | 7401 | if ((vmcs12->cr3_target_count >= 1 && |
@@ -7392,37 +7406,37 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu, | |||
7392 | vmcs12->cr3_target_value2 == val) || | 7406 | vmcs12->cr3_target_value2 == val) || |
7393 | (vmcs12->cr3_target_count >= 4 && | 7407 | (vmcs12->cr3_target_count >= 4 && |
7394 | vmcs12->cr3_target_value3 == val)) | 7408 | vmcs12->cr3_target_value3 == val)) |
7395 | return 0; | 7409 | return false; |
7396 | if (nested_cpu_has(vmcs12, CPU_BASED_CR3_LOAD_EXITING)) | 7410 | if (nested_cpu_has(vmcs12, CPU_BASED_CR3_LOAD_EXITING)) |
7397 | return 1; | 7411 | return true; |
7398 | break; | 7412 | break; |
7399 | case 4: | 7413 | case 4: |
7400 | if (vmcs12->cr4_guest_host_mask & | 7414 | if (vmcs12->cr4_guest_host_mask & |
7401 | (vmcs12->cr4_read_shadow ^ val)) | 7415 | (vmcs12->cr4_read_shadow ^ val)) |
7402 | return 1; | 7416 | return true; |
7403 | break; | 7417 | break; |
7404 | case 8: | 7418 | case 8: |
7405 | if (nested_cpu_has(vmcs12, CPU_BASED_CR8_LOAD_EXITING)) | 7419 | if (nested_cpu_has(vmcs12, CPU_BASED_CR8_LOAD_EXITING)) |
7406 | return 1; | 7420 | return true; |
7407 | break; | 7421 | break; |
7408 | } | 7422 | } |
7409 | break; | 7423 | break; |
7410 | case 2: /* clts */ | 7424 | case 2: /* clts */ |
7411 | if ((vmcs12->cr0_guest_host_mask & X86_CR0_TS) && | 7425 | if ((vmcs12->cr0_guest_host_mask & X86_CR0_TS) && |
7412 | (vmcs12->cr0_read_shadow & X86_CR0_TS)) | 7426 | (vmcs12->cr0_read_shadow & X86_CR0_TS)) |
7413 | return 1; | 7427 | return true; |
7414 | break; | 7428 | break; |
7415 | case 1: /* mov from cr */ | 7429 | case 1: /* mov from cr */ |
7416 | switch (cr) { | 7430 | switch (cr) { |
7417 | case 3: | 7431 | case 3: |
7418 | if (vmcs12->cpu_based_vm_exec_control & | 7432 | if (vmcs12->cpu_based_vm_exec_control & |
7419 | CPU_BASED_CR3_STORE_EXITING) | 7433 | CPU_BASED_CR3_STORE_EXITING) |
7420 | return 1; | 7434 | return true; |
7421 | break; | 7435 | break; |
7422 | case 8: | 7436 | case 8: |
7423 | if (vmcs12->cpu_based_vm_exec_control & | 7437 | if (vmcs12->cpu_based_vm_exec_control & |
7424 | CPU_BASED_CR8_STORE_EXITING) | 7438 | CPU_BASED_CR8_STORE_EXITING) |
7425 | return 1; | 7439 | return true; |
7426 | break; | 7440 | break; |
7427 | } | 7441 | } |
7428 | break; | 7442 | break; |
@@ -7433,14 +7447,14 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu, | |||
7433 | */ | 7447 | */ |
7434 | if (vmcs12->cr0_guest_host_mask & 0xe & | 7448 | if (vmcs12->cr0_guest_host_mask & 0xe & |
7435 | (val ^ vmcs12->cr0_read_shadow)) | 7449 | (val ^ vmcs12->cr0_read_shadow)) |
7436 | return 1; | 7450 | return true; |
7437 | if ((vmcs12->cr0_guest_host_mask & 0x1) && | 7451 | if ((vmcs12->cr0_guest_host_mask & 0x1) && |
7438 | !(vmcs12->cr0_read_shadow & 0x1) && | 7452 | !(vmcs12->cr0_read_shadow & 0x1) && |
7439 | (val & 0x1)) | 7453 | (val & 0x1)) |
7440 | return 1; | 7454 | return true; |
7441 | break; | 7455 | break; |
7442 | } | 7456 | } |
7443 | return 0; | 7457 | return false; |
7444 | } | 7458 | } |
7445 | 7459 | ||
7446 | /* | 7460 | /* |
@@ -7463,48 +7477,48 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7463 | KVM_ISA_VMX); | 7477 | KVM_ISA_VMX); |
7464 | 7478 | ||
7465 | if (vmx->nested.nested_run_pending) | 7479 | if (vmx->nested.nested_run_pending) |
7466 | return 0; | 7480 | return false; |
7467 | 7481 | ||
7468 | if (unlikely(vmx->fail)) { | 7482 | if (unlikely(vmx->fail)) { |
7469 | pr_info_ratelimited("%s failed vm entry %x\n", __func__, | 7483 | pr_info_ratelimited("%s failed vm entry %x\n", __func__, |
7470 | vmcs_read32(VM_INSTRUCTION_ERROR)); | 7484 | vmcs_read32(VM_INSTRUCTION_ERROR)); |
7471 | return 1; | 7485 | return true; |
7472 | } | 7486 | } |
7473 | 7487 | ||
7474 | switch (exit_reason) { | 7488 | switch (exit_reason) { |
7475 | case EXIT_REASON_EXCEPTION_NMI: | 7489 | case EXIT_REASON_EXCEPTION_NMI: |
7476 | if (!is_exception(intr_info)) | 7490 | if (!is_exception(intr_info)) |
7477 | return 0; | 7491 | return false; |
7478 | else if (is_page_fault(intr_info)) | 7492 | else if (is_page_fault(intr_info)) |
7479 | return enable_ept; | 7493 | return enable_ept; |
7480 | else if (is_no_device(intr_info) && | 7494 | else if (is_no_device(intr_info) && |
7481 | !(vmcs12->guest_cr0 & X86_CR0_TS)) | 7495 | !(vmcs12->guest_cr0 & X86_CR0_TS)) |
7482 | return 0; | 7496 | return false; |
7483 | return vmcs12->exception_bitmap & | 7497 | return vmcs12->exception_bitmap & |
7484 | (1u << (intr_info & INTR_INFO_VECTOR_MASK)); | 7498 | (1u << (intr_info & INTR_INFO_VECTOR_MASK)); |
7485 | case EXIT_REASON_EXTERNAL_INTERRUPT: | 7499 | case EXIT_REASON_EXTERNAL_INTERRUPT: |
7486 | return 0; | 7500 | return false; |
7487 | case EXIT_REASON_TRIPLE_FAULT: | 7501 | case EXIT_REASON_TRIPLE_FAULT: |
7488 | return 1; | 7502 | return true; |
7489 | case EXIT_REASON_PENDING_INTERRUPT: | 7503 | case EXIT_REASON_PENDING_INTERRUPT: |
7490 | return nested_cpu_has(vmcs12, CPU_BASED_VIRTUAL_INTR_PENDING); | 7504 | return nested_cpu_has(vmcs12, CPU_BASED_VIRTUAL_INTR_PENDING); |
7491 | case EXIT_REASON_NMI_WINDOW: | 7505 | case EXIT_REASON_NMI_WINDOW: |
7492 | return nested_cpu_has(vmcs12, CPU_BASED_VIRTUAL_NMI_PENDING); | 7506 | return nested_cpu_has(vmcs12, CPU_BASED_VIRTUAL_NMI_PENDING); |
7493 | case EXIT_REASON_TASK_SWITCH: | 7507 | case EXIT_REASON_TASK_SWITCH: |
7494 | return 1; | 7508 | return true; |
7495 | case EXIT_REASON_CPUID: | 7509 | case EXIT_REASON_CPUID: |
7496 | if (kvm_register_read(vcpu, VCPU_REGS_RAX) == 0xa) | 7510 | if (kvm_register_read(vcpu, VCPU_REGS_RAX) == 0xa) |
7497 | return 0; | 7511 | return false; |
7498 | return 1; | 7512 | return true; |
7499 | case EXIT_REASON_HLT: | 7513 | case EXIT_REASON_HLT: |
7500 | return nested_cpu_has(vmcs12, CPU_BASED_HLT_EXITING); | 7514 | return nested_cpu_has(vmcs12, CPU_BASED_HLT_EXITING); |
7501 | case EXIT_REASON_INVD: | 7515 | case EXIT_REASON_INVD: |
7502 | return 1; | 7516 | return true; |
7503 | case EXIT_REASON_INVLPG: | 7517 | case EXIT_REASON_INVLPG: |
7504 | return nested_cpu_has(vmcs12, CPU_BASED_INVLPG_EXITING); | 7518 | return nested_cpu_has(vmcs12, CPU_BASED_INVLPG_EXITING); |
7505 | case EXIT_REASON_RDPMC: | 7519 | case EXIT_REASON_RDPMC: |
7506 | return nested_cpu_has(vmcs12, CPU_BASED_RDPMC_EXITING); | 7520 | return nested_cpu_has(vmcs12, CPU_BASED_RDPMC_EXITING); |
7507 | case EXIT_REASON_RDTSC: | 7521 | case EXIT_REASON_RDTSC: case EXIT_REASON_RDTSCP: |
7508 | return nested_cpu_has(vmcs12, CPU_BASED_RDTSC_EXITING); | 7522 | return nested_cpu_has(vmcs12, CPU_BASED_RDTSC_EXITING); |
7509 | case EXIT_REASON_VMCALL: case EXIT_REASON_VMCLEAR: | 7523 | case EXIT_REASON_VMCALL: case EXIT_REASON_VMCLEAR: |
7510 | case EXIT_REASON_VMLAUNCH: case EXIT_REASON_VMPTRLD: | 7524 | case EXIT_REASON_VMLAUNCH: case EXIT_REASON_VMPTRLD: |
@@ -7516,7 +7530,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7516 | * VMX instructions trap unconditionally. This allows L1 to | 7530 | * VMX instructions trap unconditionally. This allows L1 to |
7517 | * emulate them for its L2 guest, i.e., allows 3-level nesting! | 7531 | * emulate them for its L2 guest, i.e., allows 3-level nesting! |
7518 | */ | 7532 | */ |
7519 | return 1; | 7533 | return true; |
7520 | case EXIT_REASON_CR_ACCESS: | 7534 | case EXIT_REASON_CR_ACCESS: |
7521 | return nested_vmx_exit_handled_cr(vcpu, vmcs12); | 7535 | return nested_vmx_exit_handled_cr(vcpu, vmcs12); |
7522 | case EXIT_REASON_DR_ACCESS: | 7536 | case EXIT_REASON_DR_ACCESS: |
@@ -7527,7 +7541,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7527 | case EXIT_REASON_MSR_WRITE: | 7541 | case EXIT_REASON_MSR_WRITE: |
7528 | return nested_vmx_exit_handled_msr(vcpu, vmcs12, exit_reason); | 7542 | return nested_vmx_exit_handled_msr(vcpu, vmcs12, exit_reason); |
7529 | case EXIT_REASON_INVALID_STATE: | 7543 | case EXIT_REASON_INVALID_STATE: |
7530 | return 1; | 7544 | return true; |
7531 | case EXIT_REASON_MWAIT_INSTRUCTION: | 7545 | case EXIT_REASON_MWAIT_INSTRUCTION: |
7532 | return nested_cpu_has(vmcs12, CPU_BASED_MWAIT_EXITING); | 7546 | return nested_cpu_has(vmcs12, CPU_BASED_MWAIT_EXITING); |
7533 | case EXIT_REASON_MONITOR_INSTRUCTION: | 7547 | case EXIT_REASON_MONITOR_INSTRUCTION: |
@@ -7537,7 +7551,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7537 | nested_cpu_has2(vmcs12, | 7551 | nested_cpu_has2(vmcs12, |
7538 | SECONDARY_EXEC_PAUSE_LOOP_EXITING); | 7552 | SECONDARY_EXEC_PAUSE_LOOP_EXITING); |
7539 | case EXIT_REASON_MCE_DURING_VMENTRY: | 7553 | case EXIT_REASON_MCE_DURING_VMENTRY: |
7540 | return 0; | 7554 | return false; |
7541 | case EXIT_REASON_TPR_BELOW_THRESHOLD: | 7555 | case EXIT_REASON_TPR_BELOW_THRESHOLD: |
7542 | return nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW); | 7556 | return nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW); |
7543 | case EXIT_REASON_APIC_ACCESS: | 7557 | case EXIT_REASON_APIC_ACCESS: |
@@ -7546,7 +7560,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7546 | case EXIT_REASON_APIC_WRITE: | 7560 | case EXIT_REASON_APIC_WRITE: |
7547 | case EXIT_REASON_EOI_INDUCED: | 7561 | case EXIT_REASON_EOI_INDUCED: |
7548 | /* apic_write and eoi_induced should exit unconditionally. */ | 7562 | /* apic_write and eoi_induced should exit unconditionally. */ |
7549 | return 1; | 7563 | return true; |
7550 | case EXIT_REASON_EPT_VIOLATION: | 7564 | case EXIT_REASON_EPT_VIOLATION: |
7551 | /* | 7565 | /* |
7552 | * L0 always deals with the EPT violation. If nested EPT is | 7566 | * L0 always deals with the EPT violation. If nested EPT is |
@@ -7554,7 +7568,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7554 | * missing in the guest EPT table (EPT12), the EPT violation | 7568 | * missing in the guest EPT table (EPT12), the EPT violation |
7555 | * will be injected with nested_ept_inject_page_fault() | 7569 | * will be injected with nested_ept_inject_page_fault() |
7556 | */ | 7570 | */ |
7557 | return 0; | 7571 | return false; |
7558 | case EXIT_REASON_EPT_MISCONFIG: | 7572 | case EXIT_REASON_EPT_MISCONFIG: |
7559 | /* | 7573 | /* |
7560 | * L2 never uses directly L1's EPT, but rather L0's own EPT | 7574 | * L2 never uses directly L1's EPT, but rather L0's own EPT |
@@ -7562,11 +7576,11 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7562 | * (EPT on EPT). So any problems with the structure of the | 7576 | * (EPT on EPT). So any problems with the structure of the |
7563 | * table is L0's fault. | 7577 | * table is L0's fault. |
7564 | */ | 7578 | */ |
7565 | return 0; | 7579 | return false; |
7566 | case EXIT_REASON_WBINVD: | 7580 | case EXIT_REASON_WBINVD: |
7567 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING); | 7581 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING); |
7568 | case EXIT_REASON_XSETBV: | 7582 | case EXIT_REASON_XSETBV: |
7569 | return 1; | 7583 | return true; |
7570 | case EXIT_REASON_XSAVES: case EXIT_REASON_XRSTORS: | 7584 | case EXIT_REASON_XSAVES: case EXIT_REASON_XRSTORS: |
7571 | /* | 7585 | /* |
7572 | * This should never happen, since it is not possible to | 7586 | * This should never happen, since it is not possible to |
@@ -7576,7 +7590,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7576 | */ | 7590 | */ |
7577 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES); | 7591 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES); |
7578 | default: | 7592 | default: |
7579 | return 1; | 7593 | return true; |
7580 | } | 7594 | } |
7581 | } | 7595 | } |
7582 | 7596 | ||
@@ -8511,6 +8525,9 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) | |||
8511 | exec_control); | 8525 | exec_control); |
8512 | } | 8526 | } |
8513 | } | 8527 | } |
8528 | if (nested && !vmx->rdtscp_enabled) | ||
8529 | vmx->nested.nested_vmx_secondary_ctls_high &= | ||
8530 | ~SECONDARY_EXEC_RDTSCP; | ||
8514 | } | 8531 | } |
8515 | 8532 | ||
8516 | /* Exposing INVPCID only when PCID is exposed */ | 8533 | /* Exposing INVPCID only when PCID is exposed */ |
@@ -8611,10 +8628,11 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu, | |||
8611 | struct vmcs12 *vmcs12) | 8628 | struct vmcs12 *vmcs12) |
8612 | { | 8629 | { |
8613 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 8630 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
8631 | int maxphyaddr = cpuid_maxphyaddr(vcpu); | ||
8614 | 8632 | ||
8615 | if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { | 8633 | if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { |
8616 | /* TODO: Also verify bits beyond physical address width are 0 */ | 8634 | if (!PAGE_ALIGNED(vmcs12->apic_access_addr) || |
8617 | if (!PAGE_ALIGNED(vmcs12->apic_access_addr)) | 8635 | vmcs12->apic_access_addr >> maxphyaddr) |
8618 | return false; | 8636 | return false; |
8619 | 8637 | ||
8620 | /* | 8638 | /* |
@@ -8630,8 +8648,8 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu, | |||
8630 | } | 8648 | } |
8631 | 8649 | ||
8632 | if (nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) { | 8650 | if (nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) { |
8633 | /* TODO: Also verify bits beyond physical address width are 0 */ | 8651 | if (!PAGE_ALIGNED(vmcs12->virtual_apic_page_addr) || |
8634 | if (!PAGE_ALIGNED(vmcs12->virtual_apic_page_addr)) | 8652 | vmcs12->virtual_apic_page_addr >> maxphyaddr) |
8635 | return false; | 8653 | return false; |
8636 | 8654 | ||
8637 | if (vmx->nested.virtual_apic_page) /* shouldn't happen */ | 8655 | if (vmx->nested.virtual_apic_page) /* shouldn't happen */ |
@@ -8654,7 +8672,8 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu, | |||
8654 | } | 8672 | } |
8655 | 8673 | ||
8656 | if (nested_cpu_has_posted_intr(vmcs12)) { | 8674 | if (nested_cpu_has_posted_intr(vmcs12)) { |
8657 | if (!IS_ALIGNED(vmcs12->posted_intr_desc_addr, 64)) | 8675 | if (!IS_ALIGNED(vmcs12->posted_intr_desc_addr, 64) || |
8676 | vmcs12->posted_intr_desc_addr >> maxphyaddr) | ||
8658 | return false; | 8677 | return false; |
8659 | 8678 | ||
8660 | if (vmx->nested.pi_desc_page) { /* shouldn't happen */ | 8679 | if (vmx->nested.pi_desc_page) { /* shouldn't happen */ |
@@ -8853,9 +8872,9 @@ static int nested_vmx_check_apicv_controls(struct kvm_vcpu *vcpu, | |||
8853 | 8872 | ||
8854 | static int nested_vmx_check_msr_switch(struct kvm_vcpu *vcpu, | 8873 | static int nested_vmx_check_msr_switch(struct kvm_vcpu *vcpu, |
8855 | unsigned long count_field, | 8874 | unsigned long count_field, |
8856 | unsigned long addr_field, | 8875 | unsigned long addr_field) |
8857 | int maxphyaddr) | ||
8858 | { | 8876 | { |
8877 | int maxphyaddr; | ||
8859 | u64 count, addr; | 8878 | u64 count, addr; |
8860 | 8879 | ||
8861 | if (vmcs12_read_any(vcpu, count_field, &count) || | 8880 | if (vmcs12_read_any(vcpu, count_field, &count) || |
@@ -8865,6 +8884,7 @@ static int nested_vmx_check_msr_switch(struct kvm_vcpu *vcpu, | |||
8865 | } | 8884 | } |
8866 | if (count == 0) | 8885 | if (count == 0) |
8867 | return 0; | 8886 | return 0; |
8887 | maxphyaddr = cpuid_maxphyaddr(vcpu); | ||
8868 | if (!IS_ALIGNED(addr, 16) || addr >> maxphyaddr || | 8888 | if (!IS_ALIGNED(addr, 16) || addr >> maxphyaddr || |
8869 | (addr + count * sizeof(struct vmx_msr_entry) - 1) >> maxphyaddr) { | 8889 | (addr + count * sizeof(struct vmx_msr_entry) - 1) >> maxphyaddr) { |
8870 | pr_warn_ratelimited( | 8890 | pr_warn_ratelimited( |
@@ -8878,19 +8898,16 @@ static int nested_vmx_check_msr_switch(struct kvm_vcpu *vcpu, | |||
8878 | static int nested_vmx_check_msr_switch_controls(struct kvm_vcpu *vcpu, | 8898 | static int nested_vmx_check_msr_switch_controls(struct kvm_vcpu *vcpu, |
8879 | struct vmcs12 *vmcs12) | 8899 | struct vmcs12 *vmcs12) |
8880 | { | 8900 | { |
8881 | int maxphyaddr; | ||
8882 | |||
8883 | if (vmcs12->vm_exit_msr_load_count == 0 && | 8901 | if (vmcs12->vm_exit_msr_load_count == 0 && |
8884 | vmcs12->vm_exit_msr_store_count == 0 && | 8902 | vmcs12->vm_exit_msr_store_count == 0 && |
8885 | vmcs12->vm_entry_msr_load_count == 0) | 8903 | vmcs12->vm_entry_msr_load_count == 0) |
8886 | return 0; /* Fast path */ | 8904 | return 0; /* Fast path */ |
8887 | maxphyaddr = cpuid_maxphyaddr(vcpu); | ||
8888 | if (nested_vmx_check_msr_switch(vcpu, VM_EXIT_MSR_LOAD_COUNT, | 8905 | if (nested_vmx_check_msr_switch(vcpu, VM_EXIT_MSR_LOAD_COUNT, |
8889 | VM_EXIT_MSR_LOAD_ADDR, maxphyaddr) || | 8906 | VM_EXIT_MSR_LOAD_ADDR) || |
8890 | nested_vmx_check_msr_switch(vcpu, VM_EXIT_MSR_STORE_COUNT, | 8907 | nested_vmx_check_msr_switch(vcpu, VM_EXIT_MSR_STORE_COUNT, |
8891 | VM_EXIT_MSR_STORE_ADDR, maxphyaddr) || | 8908 | VM_EXIT_MSR_STORE_ADDR) || |
8892 | nested_vmx_check_msr_switch(vcpu, VM_ENTRY_MSR_LOAD_COUNT, | 8909 | nested_vmx_check_msr_switch(vcpu, VM_ENTRY_MSR_LOAD_COUNT, |
8893 | VM_ENTRY_MSR_LOAD_ADDR, maxphyaddr)) | 8910 | VM_ENTRY_MSR_LOAD_ADDR)) |
8894 | return -EINVAL; | 8911 | return -EINVAL; |
8895 | return 0; | 8912 | return 0; |
8896 | } | 8913 | } |
@@ -9140,8 +9157,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
9140 | exec_control &= ~SECONDARY_EXEC_RDTSCP; | 9157 | exec_control &= ~SECONDARY_EXEC_RDTSCP; |
9141 | /* Take the following fields only from vmcs12 */ | 9158 | /* Take the following fields only from vmcs12 */ |
9142 | exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | | 9159 | exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
9160 | SECONDARY_EXEC_RDTSCP | | ||
9143 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | | 9161 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | |
9144 | SECONDARY_EXEC_APIC_REGISTER_VIRT); | 9162 | SECONDARY_EXEC_APIC_REGISTER_VIRT); |
9145 | if (nested_cpu_has(vmcs12, | 9163 | if (nested_cpu_has(vmcs12, |
9146 | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)) | 9164 | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)) |
9147 | exec_control |= vmcs12->secondary_vm_exec_control; | 9165 | exec_control |= vmcs12->secondary_vm_exec_control; |
@@ -9213,9 +9231,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
9213 | } | 9231 | } |
9214 | 9232 | ||
9215 | if (cpu_has_vmx_msr_bitmap() && | 9233 | if (cpu_has_vmx_msr_bitmap() && |
9216 | exec_control & CPU_BASED_USE_MSR_BITMAPS && | 9234 | exec_control & CPU_BASED_USE_MSR_BITMAPS) { |
9217 | nested_vmx_merge_msr_bitmap(vcpu, vmcs12)) { | 9235 | nested_vmx_merge_msr_bitmap(vcpu, vmcs12); |
9218 | vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_nested)); | 9236 | /* MSR_BITMAP will be set by following vmx_set_efer. */ |
9219 | } else | 9237 | } else |
9220 | exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; | 9238 | exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; |
9221 | 9239 | ||
@@ -9374,7 +9392,6 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) | |||
9374 | } | 9392 | } |
9375 | 9393 | ||
9376 | if (!nested_get_vmcs12_pages(vcpu, vmcs12)) { | 9394 | if (!nested_get_vmcs12_pages(vcpu, vmcs12)) { |
9377 | /*TODO: Also verify bits beyond physical address width are 0*/ | ||
9378 | nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); | 9395 | nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); |
9379 | return 1; | 9396 | return 1; |
9380 | } | 9397 | } |
@@ -9513,7 +9530,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) | |||
9513 | vmcs12->launch_state = 1; | 9530 | vmcs12->launch_state = 1; |
9514 | 9531 | ||
9515 | if (vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT) | 9532 | if (vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT) |
9516 | return kvm_emulate_halt(vcpu); | 9533 | return kvm_vcpu_halt(vcpu); |
9517 | 9534 | ||
9518 | vmx->nested.nested_run_pending = 1; | 9535 | vmx->nested.nested_run_pending = 1; |
9519 | 9536 | ||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index bd7a70be41b3..2b2dd030ea3b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -801,6 +801,17 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu) | |||
801 | } | 801 | } |
802 | EXPORT_SYMBOL_GPL(kvm_get_cr8); | 802 | EXPORT_SYMBOL_GPL(kvm_get_cr8); |
803 | 803 | ||
804 | static void kvm_update_dr0123(struct kvm_vcpu *vcpu) | ||
805 | { | ||
806 | int i; | ||
807 | |||
808 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { | ||
809 | for (i = 0; i < KVM_NR_DB_REGS; i++) | ||
810 | vcpu->arch.eff_db[i] = vcpu->arch.db[i]; | ||
811 | vcpu->arch.switch_db_regs |= KVM_DEBUGREG_RELOAD; | ||
812 | } | ||
813 | } | ||
814 | |||
804 | static void kvm_update_dr6(struct kvm_vcpu *vcpu) | 815 | static void kvm_update_dr6(struct kvm_vcpu *vcpu) |
805 | { | 816 | { |
806 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) | 817 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) |
@@ -2744,7 +2755,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
2744 | case KVM_CAP_USER_NMI: | 2755 | case KVM_CAP_USER_NMI: |
2745 | case KVM_CAP_REINJECT_CONTROL: | 2756 | case KVM_CAP_REINJECT_CONTROL: |
2746 | case KVM_CAP_IRQ_INJECT_STATUS: | 2757 | case KVM_CAP_IRQ_INJECT_STATUS: |
2747 | case KVM_CAP_IRQFD: | ||
2748 | case KVM_CAP_IOEVENTFD: | 2758 | case KVM_CAP_IOEVENTFD: |
2749 | case KVM_CAP_IOEVENTFD_NO_LENGTH: | 2759 | case KVM_CAP_IOEVENTFD_NO_LENGTH: |
2750 | case KVM_CAP_PIT2: | 2760 | case KVM_CAP_PIT2: |
@@ -3150,6 +3160,7 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, | |||
3150 | return -EINVAL; | 3160 | return -EINVAL; |
3151 | 3161 | ||
3152 | memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); | 3162 | memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); |
3163 | kvm_update_dr0123(vcpu); | ||
3153 | vcpu->arch.dr6 = dbgregs->dr6; | 3164 | vcpu->arch.dr6 = dbgregs->dr6; |
3154 | kvm_update_dr6(vcpu); | 3165 | kvm_update_dr6(vcpu); |
3155 | vcpu->arch.dr7 = dbgregs->dr7; | 3166 | vcpu->arch.dr7 = dbgregs->dr7; |
@@ -4115,8 +4126,8 @@ static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len, | |||
4115 | do { | 4126 | do { |
4116 | n = min(len, 8); | 4127 | n = min(len, 8); |
4117 | if (!(vcpu->arch.apic && | 4128 | if (!(vcpu->arch.apic && |
4118 | !kvm_iodevice_write(&vcpu->arch.apic->dev, addr, n, v)) | 4129 | !kvm_iodevice_write(vcpu, &vcpu->arch.apic->dev, addr, n, v)) |
4119 | && kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, addr, n, v)) | 4130 | && kvm_io_bus_write(vcpu, KVM_MMIO_BUS, addr, n, v)) |
4120 | break; | 4131 | break; |
4121 | handled += n; | 4132 | handled += n; |
4122 | addr += n; | 4133 | addr += n; |
@@ -4135,8 +4146,9 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v) | |||
4135 | do { | 4146 | do { |
4136 | n = min(len, 8); | 4147 | n = min(len, 8); |
4137 | if (!(vcpu->arch.apic && | 4148 | if (!(vcpu->arch.apic && |
4138 | !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, n, v)) | 4149 | !kvm_iodevice_read(vcpu, &vcpu->arch.apic->dev, |
4139 | && kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, n, v)) | 4150 | addr, n, v)) |
4151 | && kvm_io_bus_read(vcpu, KVM_MMIO_BUS, addr, n, v)) | ||
4140 | break; | 4152 | break; |
4141 | trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, *(u64 *)v); | 4153 | trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, *(u64 *)v); |
4142 | handled += n; | 4154 | handled += n; |
@@ -4476,7 +4488,8 @@ mmio: | |||
4476 | return X86EMUL_CONTINUE; | 4488 | return X86EMUL_CONTINUE; |
4477 | } | 4489 | } |
4478 | 4490 | ||
4479 | int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, | 4491 | static int emulator_read_write(struct x86_emulate_ctxt *ctxt, |
4492 | unsigned long addr, | ||
4480 | void *val, unsigned int bytes, | 4493 | void *val, unsigned int bytes, |
4481 | struct x86_exception *exception, | 4494 | struct x86_exception *exception, |
4482 | const struct read_write_emulator_ops *ops) | 4495 | const struct read_write_emulator_ops *ops) |
@@ -4539,7 +4552,7 @@ static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt, | |||
4539 | exception, &read_emultor); | 4552 | exception, &read_emultor); |
4540 | } | 4553 | } |
4541 | 4554 | ||
4542 | int emulator_write_emulated(struct x86_emulate_ctxt *ctxt, | 4555 | static int emulator_write_emulated(struct x86_emulate_ctxt *ctxt, |
4543 | unsigned long addr, | 4556 | unsigned long addr, |
4544 | const void *val, | 4557 | const void *val, |
4545 | unsigned int bytes, | 4558 | unsigned int bytes, |
@@ -4630,10 +4643,10 @@ static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) | |||
4630 | int r; | 4643 | int r; |
4631 | 4644 | ||
4632 | if (vcpu->arch.pio.in) | 4645 | if (vcpu->arch.pio.in) |
4633 | r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port, | 4646 | r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port, |
4634 | vcpu->arch.pio.size, pd); | 4647 | vcpu->arch.pio.size, pd); |
4635 | else | 4648 | else |
4636 | r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS, | 4649 | r = kvm_io_bus_write(vcpu, KVM_PIO_BUS, |
4637 | vcpu->arch.pio.port, vcpu->arch.pio.size, | 4650 | vcpu->arch.pio.port, vcpu->arch.pio.size, |
4638 | pd); | 4651 | pd); |
4639 | return r; | 4652 | return r; |
@@ -4706,7 +4719,7 @@ static void emulator_invlpg(struct x86_emulate_ctxt *ctxt, ulong address) | |||
4706 | kvm_mmu_invlpg(emul_to_vcpu(ctxt), address); | 4719 | kvm_mmu_invlpg(emul_to_vcpu(ctxt), address); |
4707 | } | 4720 | } |
4708 | 4721 | ||
4709 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) | 4722 | int kvm_emulate_wbinvd_noskip(struct kvm_vcpu *vcpu) |
4710 | { | 4723 | { |
4711 | if (!need_emulate_wbinvd(vcpu)) | 4724 | if (!need_emulate_wbinvd(vcpu)) |
4712 | return X86EMUL_CONTINUE; | 4725 | return X86EMUL_CONTINUE; |
@@ -4723,19 +4736,29 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) | |||
4723 | wbinvd(); | 4736 | wbinvd(); |
4724 | return X86EMUL_CONTINUE; | 4737 | return X86EMUL_CONTINUE; |
4725 | } | 4738 | } |
4739 | |||
4740 | int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) | ||
4741 | { | ||
4742 | kvm_x86_ops->skip_emulated_instruction(vcpu); | ||
4743 | return kvm_emulate_wbinvd_noskip(vcpu); | ||
4744 | } | ||
4726 | EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd); | 4745 | EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd); |
4727 | 4746 | ||
4747 | |||
4748 | |||
4728 | static void emulator_wbinvd(struct x86_emulate_ctxt *ctxt) | 4749 | static void emulator_wbinvd(struct x86_emulate_ctxt *ctxt) |
4729 | { | 4750 | { |
4730 | kvm_emulate_wbinvd(emul_to_vcpu(ctxt)); | 4751 | kvm_emulate_wbinvd_noskip(emul_to_vcpu(ctxt)); |
4731 | } | 4752 | } |
4732 | 4753 | ||
4733 | int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) | 4754 | static int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, |
4755 | unsigned long *dest) | ||
4734 | { | 4756 | { |
4735 | return kvm_get_dr(emul_to_vcpu(ctxt), dr, dest); | 4757 | return kvm_get_dr(emul_to_vcpu(ctxt), dr, dest); |
4736 | } | 4758 | } |
4737 | 4759 | ||
4738 | int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) | 4760 | static int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, |
4761 | unsigned long value) | ||
4739 | { | 4762 | { |
4740 | 4763 | ||
4741 | return __kvm_set_dr(emul_to_vcpu(ctxt), dr, value); | 4764 | return __kvm_set_dr(emul_to_vcpu(ctxt), dr, value); |
@@ -5817,7 +5840,7 @@ void kvm_arch_exit(void) | |||
5817 | free_percpu(shared_msrs); | 5840 | free_percpu(shared_msrs); |
5818 | } | 5841 | } |
5819 | 5842 | ||
5820 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) | 5843 | int kvm_vcpu_halt(struct kvm_vcpu *vcpu) |
5821 | { | 5844 | { |
5822 | ++vcpu->stat.halt_exits; | 5845 | ++vcpu->stat.halt_exits; |
5823 | if (irqchip_in_kernel(vcpu->kvm)) { | 5846 | if (irqchip_in_kernel(vcpu->kvm)) { |
@@ -5828,6 +5851,13 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu) | |||
5828 | return 0; | 5851 | return 0; |
5829 | } | 5852 | } |
5830 | } | 5853 | } |
5854 | EXPORT_SYMBOL_GPL(kvm_vcpu_halt); | ||
5855 | |||
5856 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) | ||
5857 | { | ||
5858 | kvm_x86_ops->skip_emulated_instruction(vcpu); | ||
5859 | return kvm_vcpu_halt(vcpu); | ||
5860 | } | ||
5831 | EXPORT_SYMBOL_GPL(kvm_emulate_halt); | 5861 | EXPORT_SYMBOL_GPL(kvm_emulate_halt); |
5832 | 5862 | ||
5833 | int kvm_hv_hypercall(struct kvm_vcpu *vcpu) | 5863 | int kvm_hv_hypercall(struct kvm_vcpu *vcpu) |
@@ -5904,7 +5934,7 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid) | |||
5904 | lapic_irq.dest_id = apicid; | 5934 | lapic_irq.dest_id = apicid; |
5905 | 5935 | ||
5906 | lapic_irq.delivery_mode = APIC_DM_REMRD; | 5936 | lapic_irq.delivery_mode = APIC_DM_REMRD; |
5907 | kvm_irq_delivery_to_apic(kvm, 0, &lapic_irq, NULL); | 5937 | kvm_irq_delivery_to_apic(kvm, NULL, &lapic_irq, NULL); |
5908 | } | 5938 | } |
5909 | 5939 | ||
5910 | int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | 5940 | int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) |
@@ -5912,6 +5942,8 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | |||
5912 | unsigned long nr, a0, a1, a2, a3, ret; | 5942 | unsigned long nr, a0, a1, a2, a3, ret; |
5913 | int op_64_bit, r = 1; | 5943 | int op_64_bit, r = 1; |
5914 | 5944 | ||
5945 | kvm_x86_ops->skip_emulated_instruction(vcpu); | ||
5946 | |||
5915 | if (kvm_hv_hypercall_enabled(vcpu->kvm)) | 5947 | if (kvm_hv_hypercall_enabled(vcpu->kvm)) |
5916 | return kvm_hv_hypercall(vcpu); | 5948 | return kvm_hv_hypercall(vcpu); |
5917 | 5949 | ||
@@ -6165,7 +6197,7 @@ void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, | |||
6165 | } | 6197 | } |
6166 | 6198 | ||
6167 | /* | 6199 | /* |
6168 | * Returns 1 to let __vcpu_run() continue the guest execution loop without | 6200 | * Returns 1 to let vcpu_run() continue the guest execution loop without |
6169 | * exiting to the userspace. Otherwise, the value will be returned to the | 6201 | * exiting to the userspace. Otherwise, the value will be returned to the |
6170 | * userspace. | 6202 | * userspace. |
6171 | */ | 6203 | */ |
@@ -6302,6 +6334,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
6302 | set_debugreg(vcpu->arch.eff_db[2], 2); | 6334 | set_debugreg(vcpu->arch.eff_db[2], 2); |
6303 | set_debugreg(vcpu->arch.eff_db[3], 3); | 6335 | set_debugreg(vcpu->arch.eff_db[3], 3); |
6304 | set_debugreg(vcpu->arch.dr6, 6); | 6336 | set_debugreg(vcpu->arch.dr6, 6); |
6337 | vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; | ||
6305 | } | 6338 | } |
6306 | 6339 | ||
6307 | trace_kvm_entry(vcpu->vcpu_id); | 6340 | trace_kvm_entry(vcpu->vcpu_id); |
@@ -6383,42 +6416,47 @@ out: | |||
6383 | return r; | 6416 | return r; |
6384 | } | 6417 | } |
6385 | 6418 | ||
6419 | static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu) | ||
6420 | { | ||
6421 | if (!kvm_arch_vcpu_runnable(vcpu)) { | ||
6422 | srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); | ||
6423 | kvm_vcpu_block(vcpu); | ||
6424 | vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); | ||
6425 | if (!kvm_check_request(KVM_REQ_UNHALT, vcpu)) | ||
6426 | return 1; | ||
6427 | } | ||
6428 | |||
6429 | kvm_apic_accept_events(vcpu); | ||
6430 | switch(vcpu->arch.mp_state) { | ||
6431 | case KVM_MP_STATE_HALTED: | ||
6432 | vcpu->arch.pv.pv_unhalted = false; | ||
6433 | vcpu->arch.mp_state = | ||
6434 | KVM_MP_STATE_RUNNABLE; | ||
6435 | case KVM_MP_STATE_RUNNABLE: | ||
6436 | vcpu->arch.apf.halted = false; | ||
6437 | break; | ||
6438 | case KVM_MP_STATE_INIT_RECEIVED: | ||
6439 | break; | ||
6440 | default: | ||
6441 | return -EINTR; | ||
6442 | break; | ||
6443 | } | ||
6444 | return 1; | ||
6445 | } | ||
6386 | 6446 | ||
6387 | static int __vcpu_run(struct kvm_vcpu *vcpu) | 6447 | static int vcpu_run(struct kvm_vcpu *vcpu) |
6388 | { | 6448 | { |
6389 | int r; | 6449 | int r; |
6390 | struct kvm *kvm = vcpu->kvm; | 6450 | struct kvm *kvm = vcpu->kvm; |
6391 | 6451 | ||
6392 | vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); | 6452 | vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); |
6393 | 6453 | ||
6394 | r = 1; | 6454 | for (;;) { |
6395 | while (r > 0) { | ||
6396 | if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE && | 6455 | if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE && |
6397 | !vcpu->arch.apf.halted) | 6456 | !vcpu->arch.apf.halted) |
6398 | r = vcpu_enter_guest(vcpu); | 6457 | r = vcpu_enter_guest(vcpu); |
6399 | else { | 6458 | else |
6400 | srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); | 6459 | r = vcpu_block(kvm, vcpu); |
6401 | kvm_vcpu_block(vcpu); | ||
6402 | vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); | ||
6403 | if (kvm_check_request(KVM_REQ_UNHALT, vcpu)) { | ||
6404 | kvm_apic_accept_events(vcpu); | ||
6405 | switch(vcpu->arch.mp_state) { | ||
6406 | case KVM_MP_STATE_HALTED: | ||
6407 | vcpu->arch.pv.pv_unhalted = false; | ||
6408 | vcpu->arch.mp_state = | ||
6409 | KVM_MP_STATE_RUNNABLE; | ||
6410 | case KVM_MP_STATE_RUNNABLE: | ||
6411 | vcpu->arch.apf.halted = false; | ||
6412 | break; | ||
6413 | case KVM_MP_STATE_INIT_RECEIVED: | ||
6414 | break; | ||
6415 | default: | ||
6416 | r = -EINTR; | ||
6417 | break; | ||
6418 | } | ||
6419 | } | ||
6420 | } | ||
6421 | |||
6422 | if (r <= 0) | 6460 | if (r <= 0) |
6423 | break; | 6461 | break; |
6424 | 6462 | ||
@@ -6430,6 +6468,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) | |||
6430 | r = -EINTR; | 6468 | r = -EINTR; |
6431 | vcpu->run->exit_reason = KVM_EXIT_INTR; | 6469 | vcpu->run->exit_reason = KVM_EXIT_INTR; |
6432 | ++vcpu->stat.request_irq_exits; | 6470 | ++vcpu->stat.request_irq_exits; |
6471 | break; | ||
6433 | } | 6472 | } |
6434 | 6473 | ||
6435 | kvm_check_async_pf_completion(vcpu); | 6474 | kvm_check_async_pf_completion(vcpu); |
@@ -6438,6 +6477,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) | |||
6438 | r = -EINTR; | 6477 | r = -EINTR; |
6439 | vcpu->run->exit_reason = KVM_EXIT_INTR; | 6478 | vcpu->run->exit_reason = KVM_EXIT_INTR; |
6440 | ++vcpu->stat.signal_exits; | 6479 | ++vcpu->stat.signal_exits; |
6480 | break; | ||
6441 | } | 6481 | } |
6442 | if (need_resched()) { | 6482 | if (need_resched()) { |
6443 | srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); | 6483 | srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); |
@@ -6569,7 +6609,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
6569 | } else | 6609 | } else |
6570 | WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed); | 6610 | WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed); |
6571 | 6611 | ||
6572 | r = __vcpu_run(vcpu); | 6612 | r = vcpu_run(vcpu); |
6573 | 6613 | ||
6574 | out: | 6614 | out: |
6575 | post_kvm_run_save(vcpu); | 6615 | post_kvm_run_save(vcpu); |
@@ -7076,11 +7116,14 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu) | |||
7076 | kvm_clear_exception_queue(vcpu); | 7116 | kvm_clear_exception_queue(vcpu); |
7077 | 7117 | ||
7078 | memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db)); | 7118 | memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db)); |
7119 | kvm_update_dr0123(vcpu); | ||
7079 | vcpu->arch.dr6 = DR6_INIT; | 7120 | vcpu->arch.dr6 = DR6_INIT; |
7080 | kvm_update_dr6(vcpu); | 7121 | kvm_update_dr6(vcpu); |
7081 | vcpu->arch.dr7 = DR7_FIXED_1; | 7122 | vcpu->arch.dr7 = DR7_FIXED_1; |
7082 | kvm_update_dr7(vcpu); | 7123 | kvm_update_dr7(vcpu); |
7083 | 7124 | ||
7125 | vcpu->arch.cr2 = 0; | ||
7126 | |||
7084 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 7127 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
7085 | vcpu->arch.apf.msr_val = 0; | 7128 | vcpu->arch.apf.msr_val = 0; |
7086 | vcpu->arch.st.msr_val = 0; | 7129 | vcpu->arch.st.msr_val = 0; |
@@ -7241,7 +7284,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
7241 | 7284 | ||
7242 | vcpu->arch.pv.pv_unhalted = false; | 7285 | vcpu->arch.pv.pv_unhalted = false; |
7243 | vcpu->arch.emulate_ctxt.ops = &emulate_ops; | 7286 | vcpu->arch.emulate_ctxt.ops = &emulate_ops; |
7244 | if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu)) | 7287 | if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_reset_bsp(vcpu)) |
7245 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | 7288 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
7246 | else | 7289 | else |
7247 | vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED; | 7290 | vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED; |
@@ -7289,6 +7332,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
7289 | vcpu->arch.guest_supported_xcr0 = 0; | 7332 | vcpu->arch.guest_supported_xcr0 = 0; |
7290 | vcpu->arch.guest_xstate_size = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET; | 7333 | vcpu->arch.guest_xstate_size = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET; |
7291 | 7334 | ||
7335 | vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); | ||
7336 | |||
7292 | kvm_async_pf_hash_reset(vcpu); | 7337 | kvm_async_pf_hash_reset(vcpu); |
7293 | kvm_pmu_init(vcpu); | 7338 | kvm_pmu_init(vcpu); |
7294 | 7339 | ||
@@ -7429,7 +7474,7 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | |||
7429 | 7474 | ||
7430 | for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) { | 7475 | for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) { |
7431 | if (!dont || free->arch.rmap[i] != dont->arch.rmap[i]) { | 7476 | if (!dont || free->arch.rmap[i] != dont->arch.rmap[i]) { |
7432 | kvm_kvfree(free->arch.rmap[i]); | 7477 | kvfree(free->arch.rmap[i]); |
7433 | free->arch.rmap[i] = NULL; | 7478 | free->arch.rmap[i] = NULL; |
7434 | } | 7479 | } |
7435 | if (i == 0) | 7480 | if (i == 0) |
@@ -7437,7 +7482,7 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | |||
7437 | 7482 | ||
7438 | if (!dont || free->arch.lpage_info[i - 1] != | 7483 | if (!dont || free->arch.lpage_info[i - 1] != |
7439 | dont->arch.lpage_info[i - 1]) { | 7484 | dont->arch.lpage_info[i - 1]) { |
7440 | kvm_kvfree(free->arch.lpage_info[i - 1]); | 7485 | kvfree(free->arch.lpage_info[i - 1]); |
7441 | free->arch.lpage_info[i - 1] = NULL; | 7486 | free->arch.lpage_info[i - 1] = NULL; |
7442 | } | 7487 | } |
7443 | } | 7488 | } |
@@ -7491,12 +7536,12 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, | |||
7491 | 7536 | ||
7492 | out_free: | 7537 | out_free: |
7493 | for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) { | 7538 | for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) { |
7494 | kvm_kvfree(slot->arch.rmap[i]); | 7539 | kvfree(slot->arch.rmap[i]); |
7495 | slot->arch.rmap[i] = NULL; | 7540 | slot->arch.rmap[i] = NULL; |
7496 | if (i == 0) | 7541 | if (i == 0) |
7497 | continue; | 7542 | continue; |
7498 | 7543 | ||
7499 | kvm_kvfree(slot->arch.lpage_info[i - 1]); | 7544 | kvfree(slot->arch.lpage_info[i - 1]); |
7500 | slot->arch.lpage_info[i - 1] = NULL; | 7545 | slot->arch.lpage_info[i - 1] = NULL; |
7501 | } | 7546 | } |
7502 | return -ENOMEM; | 7547 | return -ENOMEM; |
@@ -7619,6 +7664,23 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
7619 | new = id_to_memslot(kvm->memslots, mem->slot); | 7664 | new = id_to_memslot(kvm->memslots, mem->slot); |
7620 | 7665 | ||
7621 | /* | 7666 | /* |
7667 | * Dirty logging tracks sptes in 4k granularity, meaning that large | ||
7668 | * sptes have to be split. If live migration is successful, the guest | ||
7669 | * in the source machine will be destroyed and large sptes will be | ||
7670 | * created in the destination. However, if the guest continues to run | ||
7671 | * in the source machine (for example if live migration fails), small | ||
7672 | * sptes will remain around and cause bad performance. | ||
7673 | * | ||
7674 | * Scan sptes if dirty logging has been stopped, dropping those | ||
7675 | * which can be collapsed into a single large-page spte. Later | ||
7676 | * page faults will create the large-page sptes. | ||
7677 | */ | ||
7678 | if ((change != KVM_MR_DELETE) && | ||
7679 | (old->flags & KVM_MEM_LOG_DIRTY_PAGES) && | ||
7680 | !(new->flags & KVM_MEM_LOG_DIRTY_PAGES)) | ||
7681 | kvm_mmu_zap_collapsible_sptes(kvm, new); | ||
7682 | |||
7683 | /* | ||
7622 | * Set up write protection and/or dirty logging for the new slot. | 7684 | * Set up write protection and/or dirty logging for the new slot. |
7623 | * | 7685 | * |
7624 | * For KVM_MR_DELETE and KVM_MR_MOVE, the shadow pages of old slot have | 7686 | * For KVM_MR_DELETE and KVM_MR_MOVE, the shadow pages of old slot have |
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig index 4a0890f815c4..08f41caada45 100644 --- a/arch/x86/lguest/Kconfig +++ b/arch/x86/lguest/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config LGUEST_GUEST | 1 | config LGUEST_GUEST |
2 | bool "Lguest guest support" | 2 | bool "Lguest guest support" |
3 | depends on X86_32 && PARAVIRT | 3 | depends on X86_32 && PARAVIRT && PCI |
4 | select TTY | 4 | select TTY |
5 | select VIRTUALIZATION | 5 | select VIRTUALIZATION |
6 | select VIRTIO | 6 | select VIRTIO |
@@ -8,7 +8,7 @@ config LGUEST_GUEST | |||
8 | help | 8 | help |
9 | Lguest is a tiny in-kernel hypervisor. Selecting this will | 9 | Lguest is a tiny in-kernel hypervisor. Selecting this will |
10 | allow your kernel to boot under lguest. This option will increase | 10 | allow your kernel to boot under lguest. This option will increase |
11 | your kernel size by about 6k. If in doubt, say N. | 11 | your kernel size by about 10k. If in doubt, say N. |
12 | 12 | ||
13 | If you say Y here, make sure you say Y (or M) to the virtio block | 13 | If you say Y here, make sure you say Y (or M) to the virtio block |
14 | and net drivers which lguest needs. | 14 | and net drivers which lguest needs. |
diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index c905e89e19fe..1f33b3d1fd68 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c | |||
@@ -69,21 +69,20 @@ EXPORT_SYMBOL(copy_in_user); | |||
69 | * it is not necessary to optimize tail handling. | 69 | * it is not necessary to optimize tail handling. |
70 | */ | 70 | */ |
71 | __visible unsigned long | 71 | __visible unsigned long |
72 | copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest) | 72 | copy_user_handle_tail(char *to, char *from, unsigned len) |
73 | { | 73 | { |
74 | char c; | ||
75 | unsigned zero_len; | ||
76 | |||
77 | for (; len; --len, to++) { | 74 | for (; len; --len, to++) { |
75 | char c; | ||
76 | |||
78 | if (__get_user_nocheck(c, from++, sizeof(char))) | 77 | if (__get_user_nocheck(c, from++, sizeof(char))) |
79 | break; | 78 | break; |
80 | if (__put_user_nocheck(c, to, sizeof(char))) | 79 | if (__put_user_nocheck(c, to, sizeof(char))) |
81 | break; | 80 | break; |
82 | } | 81 | } |
83 | |||
84 | for (c = 0, zero_len = len; zerorest && zero_len; --zero_len) | ||
85 | if (__put_user_nocheck(c, to++, sizeof(char))) | ||
86 | break; | ||
87 | clac(); | 82 | clac(); |
83 | |||
84 | /* If the destination is a kernel buffer, we always clear the end */ | ||
85 | if ((unsigned long)to >= TASK_SIZE_MAX) | ||
86 | memset(to, 0, len); | ||
88 | return len; | 87 | return len; |
89 | } | 88 | } |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 6ac273832f28..e4695985f9de 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -331,7 +331,7 @@ static void probe_pci_root_info(struct pci_root_info *info, | |||
331 | struct list_head *list) | 331 | struct list_head *list) |
332 | { | 332 | { |
333 | int ret; | 333 | int ret; |
334 | struct resource_entry *entry; | 334 | struct resource_entry *entry, *tmp; |
335 | 335 | ||
336 | sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); | 336 | sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); |
337 | info->bridge = device; | 337 | info->bridge = device; |
@@ -345,8 +345,13 @@ static void probe_pci_root_info(struct pci_root_info *info, | |||
345 | dev_dbg(&device->dev, | 345 | dev_dbg(&device->dev, |
346 | "no IO and memory resources present in _CRS\n"); | 346 | "no IO and memory resources present in _CRS\n"); |
347 | else | 347 | else |
348 | resource_list_for_each_entry(entry, list) | 348 | resource_list_for_each_entry_safe(entry, tmp, list) { |
349 | entry->res->name = info->name; | 349 | if ((entry->res->flags & IORESOURCE_WINDOW) == 0 || |
350 | (entry->res->flags & IORESOURCE_DISABLED)) | ||
351 | resource_list_destroy_entry(entry); | ||
352 | else | ||
353 | entry->res->name = info->name; | ||
354 | } | ||
350 | } | 355 | } |
351 | 356 | ||
352 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | 357 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 3d2612b68694..2fb384724ebb 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -513,31 +513,6 @@ void __init pcibios_set_cache_line_size(void) | |||
513 | } | 513 | } |
514 | } | 514 | } |
515 | 515 | ||
516 | /* | ||
517 | * Some device drivers assume dev->irq won't change after calling | ||
518 | * pci_disable_device(). So delay releasing of IRQ resource to driver | ||
519 | * unbinding time. Otherwise it will break PM subsystem and drivers | ||
520 | * like xen-pciback etc. | ||
521 | */ | ||
522 | static int pci_irq_notifier(struct notifier_block *nb, unsigned long action, | ||
523 | void *data) | ||
524 | { | ||
525 | struct pci_dev *dev = to_pci_dev(data); | ||
526 | |||
527 | if (action != BUS_NOTIFY_UNBOUND_DRIVER) | ||
528 | return NOTIFY_DONE; | ||
529 | |||
530 | if (pcibios_disable_irq) | ||
531 | pcibios_disable_irq(dev); | ||
532 | |||
533 | return NOTIFY_OK; | ||
534 | } | ||
535 | |||
536 | static struct notifier_block pci_irq_nb = { | ||
537 | .notifier_call = pci_irq_notifier, | ||
538 | .priority = INT_MIN, | ||
539 | }; | ||
540 | |||
541 | int __init pcibios_init(void) | 516 | int __init pcibios_init(void) |
542 | { | 517 | { |
543 | if (!raw_pci_ops) { | 518 | if (!raw_pci_ops) { |
@@ -550,9 +525,6 @@ int __init pcibios_init(void) | |||
550 | 525 | ||
551 | if (pci_bf_sort >= pci_force_bf) | 526 | if (pci_bf_sort >= pci_force_bf) |
552 | pci_sort_breadthfirst(); | 527 | pci_sort_breadthfirst(); |
553 | |||
554 | bus_register_notifier(&pci_bus_type, &pci_irq_nb); | ||
555 | |||
556 | return 0; | 528 | return 0; |
557 | } | 529 | } |
558 | 530 | ||
@@ -711,6 +683,12 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
711 | return 0; | 683 | return 0; |
712 | } | 684 | } |
713 | 685 | ||
686 | void pcibios_disable_device (struct pci_dev *dev) | ||
687 | { | ||
688 | if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) | ||
689 | pcibios_disable_irq(dev); | ||
690 | } | ||
691 | |||
714 | int pci_ext_cfg_avail(void) | 692 | int pci_ext_cfg_avail(void) |
715 | { | 693 | { |
716 | if (raw_pci_ext_ops) | 694 | if (raw_pci_ext_ops) |
diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c index efb849323c74..852aa4c92da0 100644 --- a/arch/x86/pci/intel_mid_pci.c +++ b/arch/x86/pci/intel_mid_pci.c | |||
@@ -234,10 +234,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) | |||
234 | 234 | ||
235 | static void intel_mid_pci_irq_disable(struct pci_dev *dev) | 235 | static void intel_mid_pci_irq_disable(struct pci_dev *dev) |
236 | { | 236 | { |
237 | if (dev->irq_managed && dev->irq > 0) { | 237 | if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed && |
238 | dev->irq > 0) { | ||
238 | mp_unmap_irq(dev->irq); | 239 | mp_unmap_irq(dev->irq); |
239 | dev->irq_managed = 0; | 240 | dev->irq_managed = 0; |
240 | dev->irq = 0; | ||
241 | } | 241 | } |
242 | } | 242 | } |
243 | 243 | ||
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index e71b3dbd87b8..5dc6ca5e1741 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -1256,9 +1256,22 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1256 | return 0; | 1256 | return 0; |
1257 | } | 1257 | } |
1258 | 1258 | ||
1259 | bool mp_should_keep_irq(struct device *dev) | ||
1260 | { | ||
1261 | if (dev->power.is_prepared) | ||
1262 | return true; | ||
1263 | #ifdef CONFIG_PM | ||
1264 | if (dev->power.runtime_status == RPM_SUSPENDING) | ||
1265 | return true; | ||
1266 | #endif | ||
1267 | |||
1268 | return false; | ||
1269 | } | ||
1270 | |||
1259 | static void pirq_disable_irq(struct pci_dev *dev) | 1271 | static void pirq_disable_irq(struct pci_dev *dev) |
1260 | { | 1272 | { |
1261 | if (io_apic_assign_pci_irqs && dev->irq_managed && dev->irq) { | 1273 | if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) && |
1274 | dev->irq_managed && dev->irq) { | ||
1262 | mp_unmap_irq(dev->irq); | 1275 | mp_unmap_irq(dev->irq); |
1263 | dev->irq = 0; | 1276 | dev->irq = 0; |
1264 | dev->irq_managed = 0; | 1277 | dev->irq_managed = 0; |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index dbc8627a5cdf..02744df576d5 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -85,12 +85,20 @@ static efi_status_t __init phys_efi_set_virtual_address_map( | |||
85 | efi_memory_desc_t *virtual_map) | 85 | efi_memory_desc_t *virtual_map) |
86 | { | 86 | { |
87 | efi_status_t status; | 87 | efi_status_t status; |
88 | unsigned long flags; | ||
89 | pgd_t *save_pgd; | ||
88 | 90 | ||
89 | efi_call_phys_prolog(); | 91 | save_pgd = efi_call_phys_prolog(); |
92 | |||
93 | /* Disable interrupts around EFI calls: */ | ||
94 | local_irq_save(flags); | ||
90 | status = efi_call_phys(efi_phys.set_virtual_address_map, | 95 | status = efi_call_phys(efi_phys.set_virtual_address_map, |
91 | memory_map_size, descriptor_size, | 96 | memory_map_size, descriptor_size, |
92 | descriptor_version, virtual_map); | 97 | descriptor_version, virtual_map); |
93 | efi_call_phys_epilog(); | 98 | local_irq_restore(flags); |
99 | |||
100 | efi_call_phys_epilog(save_pgd); | ||
101 | |||
94 | return status; | 102 | return status; |
95 | } | 103 | } |
96 | 104 | ||
@@ -491,7 +499,8 @@ void __init efi_init(void) | |||
491 | if (efi_memmap_init()) | 499 | if (efi_memmap_init()) |
492 | return; | 500 | return; |
493 | 501 | ||
494 | print_efi_memmap(); | 502 | if (efi_enabled(EFI_DBG)) |
503 | print_efi_memmap(); | ||
495 | } | 504 | } |
496 | 505 | ||
497 | void __init efi_late_init(void) | 506 | void __init efi_late_init(void) |
@@ -939,6 +948,8 @@ static int __init arch_parse_efi_cmdline(char *str) | |||
939 | { | 948 | { |
940 | if (parse_option_str(str, "old_map")) | 949 | if (parse_option_str(str, "old_map")) |
941 | set_bit(EFI_OLD_MEMMAP, &efi.flags); | 950 | set_bit(EFI_OLD_MEMMAP, &efi.flags); |
951 | if (parse_option_str(str, "debug")) | ||
952 | set_bit(EFI_DBG, &efi.flags); | ||
942 | 953 | ||
943 | return 0; | 954 | return 0; |
944 | } | 955 | } |
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index 40e7cda52936..ed5b67338294 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c | |||
@@ -33,11 +33,10 @@ | |||
33 | 33 | ||
34 | /* | 34 | /* |
35 | * To make EFI call EFI runtime service in physical addressing mode we need | 35 | * To make EFI call EFI runtime service in physical addressing mode we need |
36 | * prolog/epilog before/after the invocation to disable interrupt, to | 36 | * prolog/epilog before/after the invocation to claim the EFI runtime service |
37 | * claim EFI runtime service handler exclusively and to duplicate a memory in | 37 | * handler exclusively and to duplicate a memory mapping in low memory space, |
38 | * low memory space say 0 - 3G. | 38 | * say 0 - 3G. |
39 | */ | 39 | */ |
40 | static unsigned long efi_rt_eflags; | ||
41 | 40 | ||
42 | void efi_sync_low_kernel_mappings(void) {} | 41 | void efi_sync_low_kernel_mappings(void) {} |
43 | void __init efi_dump_pagetable(void) {} | 42 | void __init efi_dump_pagetable(void) {} |
@@ -57,21 +56,24 @@ void __init efi_map_region(efi_memory_desc_t *md) | |||
57 | void __init efi_map_region_fixed(efi_memory_desc_t *md) {} | 56 | void __init efi_map_region_fixed(efi_memory_desc_t *md) {} |
58 | void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} | 57 | void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} |
59 | 58 | ||
60 | void __init efi_call_phys_prolog(void) | 59 | pgd_t * __init efi_call_phys_prolog(void) |
61 | { | 60 | { |
62 | struct desc_ptr gdt_descr; | 61 | struct desc_ptr gdt_descr; |
62 | pgd_t *save_pgd; | ||
63 | 63 | ||
64 | local_irq_save(efi_rt_eflags); | 64 | /* Current pgd is swapper_pg_dir, we'll restore it later: */ |
65 | 65 | save_pgd = swapper_pg_dir; | |
66 | load_cr3(initial_page_table); | 66 | load_cr3(initial_page_table); |
67 | __flush_tlb_all(); | 67 | __flush_tlb_all(); |
68 | 68 | ||
69 | gdt_descr.address = __pa(get_cpu_gdt_table(0)); | 69 | gdt_descr.address = __pa(get_cpu_gdt_table(0)); |
70 | gdt_descr.size = GDT_SIZE - 1; | 70 | gdt_descr.size = GDT_SIZE - 1; |
71 | load_gdt(&gdt_descr); | 71 | load_gdt(&gdt_descr); |
72 | |||
73 | return save_pgd; | ||
72 | } | 74 | } |
73 | 75 | ||
74 | void __init efi_call_phys_epilog(void) | 76 | void __init efi_call_phys_epilog(pgd_t *save_pgd) |
75 | { | 77 | { |
76 | struct desc_ptr gdt_descr; | 78 | struct desc_ptr gdt_descr; |
77 | 79 | ||
@@ -79,10 +81,8 @@ void __init efi_call_phys_epilog(void) | |||
79 | gdt_descr.size = GDT_SIZE - 1; | 81 | gdt_descr.size = GDT_SIZE - 1; |
80 | load_gdt(&gdt_descr); | 82 | load_gdt(&gdt_descr); |
81 | 83 | ||
82 | load_cr3(swapper_pg_dir); | 84 | load_cr3(save_pgd); |
83 | __flush_tlb_all(); | 85 | __flush_tlb_all(); |
84 | |||
85 | local_irq_restore(efi_rt_eflags); | ||
86 | } | 86 | } |
87 | 87 | ||
88 | void __init efi_runtime_mkexec(void) | 88 | void __init efi_runtime_mkexec(void) |
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 17e80d829df0..a0ac0f9c307f 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c | |||
@@ -41,9 +41,6 @@ | |||
41 | #include <asm/realmode.h> | 41 | #include <asm/realmode.h> |
42 | #include <asm/time.h> | 42 | #include <asm/time.h> |
43 | 43 | ||
44 | static pgd_t *save_pgd __initdata; | ||
45 | static unsigned long efi_flags __initdata; | ||
46 | |||
47 | /* | 44 | /* |
48 | * We allocate runtime services regions bottom-up, starting from -4G, i.e. | 45 | * We allocate runtime services regions bottom-up, starting from -4G, i.e. |
49 | * 0xffff_ffff_0000_0000 and limit EFI VA mapping space to 64G. | 46 | * 0xffff_ffff_0000_0000 and limit EFI VA mapping space to 64G. |
@@ -78,17 +75,18 @@ static void __init early_code_mapping_set_exec(int executable) | |||
78 | } | 75 | } |
79 | } | 76 | } |
80 | 77 | ||
81 | void __init efi_call_phys_prolog(void) | 78 | pgd_t * __init efi_call_phys_prolog(void) |
82 | { | 79 | { |
83 | unsigned long vaddress; | 80 | unsigned long vaddress; |
81 | pgd_t *save_pgd; | ||
82 | |||
84 | int pgd; | 83 | int pgd; |
85 | int n_pgds; | 84 | int n_pgds; |
86 | 85 | ||
87 | if (!efi_enabled(EFI_OLD_MEMMAP)) | 86 | if (!efi_enabled(EFI_OLD_MEMMAP)) |
88 | return; | 87 | return NULL; |
89 | 88 | ||
90 | early_code_mapping_set_exec(1); | 89 | early_code_mapping_set_exec(1); |
91 | local_irq_save(efi_flags); | ||
92 | 90 | ||
93 | n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE); | 91 | n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE); |
94 | save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL); | 92 | save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL); |
@@ -99,24 +97,29 @@ void __init efi_call_phys_prolog(void) | |||
99 | set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); | 97 | set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); |
100 | } | 98 | } |
101 | __flush_tlb_all(); | 99 | __flush_tlb_all(); |
100 | |||
101 | return save_pgd; | ||
102 | } | 102 | } |
103 | 103 | ||
104 | void __init efi_call_phys_epilog(void) | 104 | void __init efi_call_phys_epilog(pgd_t *save_pgd) |
105 | { | 105 | { |
106 | /* | 106 | /* |
107 | * After the lock is released, the original page table is restored. | 107 | * After the lock is released, the original page table is restored. |
108 | */ | 108 | */ |
109 | int pgd; | 109 | int pgd_idx; |
110 | int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); | 110 | int nr_pgds; |
111 | 111 | ||
112 | if (!efi_enabled(EFI_OLD_MEMMAP)) | 112 | if (!save_pgd) |
113 | return; | 113 | return; |
114 | 114 | ||
115 | for (pgd = 0; pgd < n_pgds; pgd++) | 115 | nr_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); |
116 | set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]); | 116 | |
117 | for (pgd_idx = 0; pgd_idx < nr_pgds; pgd_idx++) | ||
118 | set_pgd(pgd_offset_k(pgd_idx * PGDIR_SIZE), save_pgd[pgd_idx]); | ||
119 | |||
117 | kfree(save_pgd); | 120 | kfree(save_pgd); |
121 | |||
118 | __flush_tlb_all(); | 122 | __flush_tlb_all(); |
119 | local_irq_restore(efi_flags); | ||
120 | early_code_mapping_set_exec(0); | 123 | early_code_mapping_set_exec(0); |
121 | } | 124 | } |
122 | 125 | ||
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c index 1bbedc4b0f88..3005f0c89f2e 100644 --- a/arch/x86/platform/intel-mid/intel-mid.c +++ b/arch/x86/platform/intel-mid/intel-mid.c | |||
@@ -130,7 +130,7 @@ static void intel_mid_arch_setup(void) | |||
130 | intel_mid_ops = get_intel_mid_ops[__intel_mid_cpu_chip](); | 130 | intel_mid_ops = get_intel_mid_ops[__intel_mid_cpu_chip](); |
131 | else { | 131 | else { |
132 | intel_mid_ops = get_intel_mid_ops[INTEL_MID_CPU_CHIP_PENWELL](); | 132 | intel_mid_ops = get_intel_mid_ops[INTEL_MID_CPU_CHIP_PENWELL](); |
133 | pr_info("ARCH: Uknown SoC, assuming PENWELL!\n"); | 133 | pr_info("ARCH: Unknown SoC, assuming PENWELL!\n"); |
134 | } | 134 | } |
135 | 135 | ||
136 | out: | 136 | out: |
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c index 9793322751e0..40d2473836c9 100644 --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c | |||
@@ -82,18 +82,15 @@ static notrace cycle_t vread_pvclock(int *mode) | |||
82 | cycle_t ret; | 82 | cycle_t ret; |
83 | u64 last; | 83 | u64 last; |
84 | u32 version; | 84 | u32 version; |
85 | u32 migrate_count; | ||
85 | u8 flags; | 86 | u8 flags; |
86 | unsigned cpu, cpu1; | 87 | unsigned cpu, cpu1; |
87 | 88 | ||
88 | 89 | ||
89 | /* | 90 | /* |
90 | * Note: hypervisor must guarantee that: | 91 | * When looping to get a consistent (time-info, tsc) pair, we |
91 | * 1. cpu ID number maps 1:1 to per-CPU pvclock time info. | 92 | * also need to deal with the possibility we can switch vcpus, |
92 | * 2. that per-CPU pvclock time info is updated if the | 93 | * so make sure we always re-fetch time-info for the current vcpu. |
93 | * underlying CPU changes. | ||
94 | * 3. that version is increased whenever underlying CPU | ||
95 | * changes. | ||
96 | * | ||
97 | */ | 94 | */ |
98 | do { | 95 | do { |
99 | cpu = __getcpu() & VGETCPU_CPU_MASK; | 96 | cpu = __getcpu() & VGETCPU_CPU_MASK; |
@@ -102,20 +99,27 @@ static notrace cycle_t vread_pvclock(int *mode) | |||
102 | * __getcpu() calls (Gleb). | 99 | * __getcpu() calls (Gleb). |
103 | */ | 100 | */ |
104 | 101 | ||
105 | pvti = get_pvti(cpu); | 102 | /* Make sure migrate_count will change if we leave the VCPU. */ |
103 | do { | ||
104 | pvti = get_pvti(cpu); | ||
105 | migrate_count = pvti->migrate_count; | ||
106 | |||
107 | cpu1 = cpu; | ||
108 | cpu = __getcpu() & VGETCPU_CPU_MASK; | ||
109 | } while (unlikely(cpu != cpu1)); | ||
106 | 110 | ||
107 | version = __pvclock_read_cycles(&pvti->pvti, &ret, &flags); | 111 | version = __pvclock_read_cycles(&pvti->pvti, &ret, &flags); |
108 | 112 | ||
109 | /* | 113 | /* |
110 | * Test we're still on the cpu as well as the version. | 114 | * Test we're still on the cpu as well as the version. |
111 | * We could have been migrated just after the first | 115 | * - We must read TSC of pvti's VCPU. |
112 | * vgetcpu but before fetching the version, so we | 116 | * - KVM doesn't follow the versioning protocol, so data could |
113 | * wouldn't notice a version change. | 117 | * change before version if we left the VCPU. |
114 | */ | 118 | */ |
115 | cpu1 = __getcpu() & VGETCPU_CPU_MASK; | 119 | smp_rmb(); |
116 | } while (unlikely(cpu != cpu1 || | 120 | } while (unlikely((pvti->pvti.version & 1) || |
117 | (pvti->pvti.version & 1) || | 121 | pvti->pvti.version != version || |
118 | pvti->pvti.version != version)); | 122 | pvti->migrate_count != migrate_count)); |
119 | 123 | ||
120 | if (unlikely(!(flags & PVCLOCK_TSC_STABLE_BIT))) | 124 | if (unlikely(!(flags & PVCLOCK_TSC_STABLE_BIT))) |
121 | *mode = VCLOCK_NONE; | 125 | *mode = VCLOCK_NONE; |
diff --git a/arch/x86/vdso/vdso32/sigreturn.S b/arch/x86/vdso/vdso32/sigreturn.S index 31776d0efc8c..d7ec4e251c0a 100644 --- a/arch/x86/vdso/vdso32/sigreturn.S +++ b/arch/x86/vdso/vdso32/sigreturn.S | |||
@@ -17,6 +17,7 @@ | |||
17 | .text | 17 | .text |
18 | .globl __kernel_sigreturn | 18 | .globl __kernel_sigreturn |
19 | .type __kernel_sigreturn,@function | 19 | .type __kernel_sigreturn,@function |
20 | nop /* this guy is needed for .LSTARTFDEDLSI1 below (watch for HACK) */ | ||
20 | ALIGN | 21 | ALIGN |
21 | __kernel_sigreturn: | 22 | __kernel_sigreturn: |
22 | .LSTART_sigreturn: | 23 | .LSTART_sigreturn: |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index bd8b8459c3d0..5240f563076d 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1070,6 +1070,23 @@ static inline void xen_write_cr8(unsigned long val) | |||
1070 | BUG_ON(val); | 1070 | BUG_ON(val); |
1071 | } | 1071 | } |
1072 | #endif | 1072 | #endif |
1073 | |||
1074 | static u64 xen_read_msr_safe(unsigned int msr, int *err) | ||
1075 | { | ||
1076 | u64 val; | ||
1077 | |||
1078 | val = native_read_msr_safe(msr, err); | ||
1079 | switch (msr) { | ||
1080 | case MSR_IA32_APICBASE: | ||
1081 | #ifdef CONFIG_X86_X2APIC | ||
1082 | if (!(cpuid_ecx(1) & (1 << (X86_FEATURE_X2APIC & 31)))) | ||
1083 | #endif | ||
1084 | val &= ~X2APIC_ENABLE; | ||
1085 | break; | ||
1086 | } | ||
1087 | return val; | ||
1088 | } | ||
1089 | |||
1073 | static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) | 1090 | static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) |
1074 | { | 1091 | { |
1075 | int ret; | 1092 | int ret; |
@@ -1240,7 +1257,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { | |||
1240 | 1257 | ||
1241 | .wbinvd = native_wbinvd, | 1258 | .wbinvd = native_wbinvd, |
1242 | 1259 | ||
1243 | .read_msr = native_read_msr_safe, | 1260 | .read_msr = xen_read_msr_safe, |
1244 | .write_msr = xen_write_msr_safe, | 1261 | .write_msr = xen_write_msr_safe, |
1245 | 1262 | ||
1246 | .read_tsc = native_read_tsc, | 1263 | .read_tsc = native_read_tsc, |
@@ -1741,6 +1758,7 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1741 | #ifdef CONFIG_X86_32 | 1758 | #ifdef CONFIG_X86_32 |
1742 | i386_start_kernel(); | 1759 | i386_start_kernel(); |
1743 | #else | 1760 | #else |
1761 | cr4_init_shadow(); /* 32b kernel does this in i386_start_kernel() */ | ||
1744 | x86_64_start_reservations((char *)__pa_symbol(&boot_params)); | 1762 | x86_64_start_reservations((char *)__pa_symbol(&boot_params)); |
1745 | #endif | 1763 | #endif |
1746 | } | 1764 | } |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 740ae3026a14..b47124d4cd67 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -91,6 +91,12 @@ EXPORT_SYMBOL_GPL(xen_p2m_size); | |||
91 | unsigned long xen_max_p2m_pfn __read_mostly; | 91 | unsigned long xen_max_p2m_pfn __read_mostly; |
92 | EXPORT_SYMBOL_GPL(xen_max_p2m_pfn); | 92 | EXPORT_SYMBOL_GPL(xen_max_p2m_pfn); |
93 | 93 | ||
94 | #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT | ||
95 | #define P2M_LIMIT CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT | ||
96 | #else | ||
97 | #define P2M_LIMIT 0 | ||
98 | #endif | ||
99 | |||
94 | static DEFINE_SPINLOCK(p2m_update_lock); | 100 | static DEFINE_SPINLOCK(p2m_update_lock); |
95 | 101 | ||
96 | static unsigned long *p2m_mid_missing_mfn; | 102 | static unsigned long *p2m_mid_missing_mfn; |
@@ -385,9 +391,11 @@ static void __init xen_rebuild_p2m_list(unsigned long *p2m) | |||
385 | void __init xen_vmalloc_p2m_tree(void) | 391 | void __init xen_vmalloc_p2m_tree(void) |
386 | { | 392 | { |
387 | static struct vm_struct vm; | 393 | static struct vm_struct vm; |
394 | unsigned long p2m_limit; | ||
388 | 395 | ||
396 | p2m_limit = (phys_addr_t)P2M_LIMIT * 1024 * 1024 * 1024 / PAGE_SIZE; | ||
389 | vm.flags = VM_ALLOC; | 397 | vm.flags = VM_ALLOC; |
390 | vm.size = ALIGN(sizeof(unsigned long) * xen_max_p2m_pfn, | 398 | vm.size = ALIGN(sizeof(unsigned long) * max(xen_max_p2m_pfn, p2m_limit), |
391 | PMD_SIZE * PMDS_PER_MID_PAGE); | 399 | PMD_SIZE * PMDS_PER_MID_PAGE); |
392 | vm_area_register_early(&vm, PMD_SIZE * PMDS_PER_MID_PAGE); | 400 | vm_area_register_early(&vm, PMD_SIZE * PMDS_PER_MID_PAGE); |
393 | pr_notice("p2m virtual area at %p, size is %lx\n", vm.addr, vm.size); | 401 | pr_notice("p2m virtual area at %p, size is %lx\n", vm.addr, vm.size); |
@@ -563,7 +571,7 @@ static bool alloc_p2m(unsigned long pfn) | |||
563 | if (p2m_pfn == PFN_DOWN(__pa(p2m_missing))) | 571 | if (p2m_pfn == PFN_DOWN(__pa(p2m_missing))) |
564 | p2m_init(p2m); | 572 | p2m_init(p2m); |
565 | else | 573 | else |
566 | p2m_init_identity(p2m, pfn); | 574 | p2m_init_identity(p2m, pfn & ~(P2M_PER_PAGE - 1)); |
567 | 575 | ||
568 | spin_lock_irqsave(&p2m_update_lock, flags); | 576 | spin_lock_irqsave(&p2m_update_lock, flags); |
569 | 577 | ||