| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk}) |
|---|
| 3 | 4 | * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de) |
|---|
| 4 | 5 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
|---|
| 5 | 6 | * Copyright 2003 PathScale, Inc. |
|---|
| 6 | | - * Licensed under the GPL |
|---|
| 7 | 7 | */ |
|---|
| 8 | 8 | |
|---|
| 9 | 9 | #include <linux/stddef.h> |
|---|
| .. | .. |
|---|
| 25 | 25 | #include <linux/threads.h> |
|---|
| 26 | 26 | #include <linux/tracehook.h> |
|---|
| 27 | 27 | #include <asm/current.h> |
|---|
| 28 | | -#include <asm/pgtable.h> |
|---|
| 29 | 28 | #include <asm/mmu_context.h> |
|---|
| 30 | 29 | #include <linux/uaccess.h> |
|---|
| 31 | 30 | #include <as-layout.h> |
|---|
| 32 | 31 | #include <kern_util.h> |
|---|
| 33 | 32 | #include <os.h> |
|---|
| 34 | 33 | #include <skas.h> |
|---|
| 35 | | -#include <timer-internal.h> |
|---|
| 34 | +#include <linux/time-internal.h> |
|---|
| 36 | 35 | |
|---|
| 37 | 36 | /* |
|---|
| 38 | 37 | * This is a per-cpu array. A processor only modifies its entry and it only |
|---|
| .. | .. |
|---|
| 100 | 99 | |
|---|
| 101 | 100 | if (need_resched()) |
|---|
| 102 | 101 | schedule(); |
|---|
| 103 | | - if (test_thread_flag(TIF_SIGPENDING)) |
|---|
| 102 | + if (test_thread_flag(TIF_SIGPENDING) || |
|---|
| 103 | + test_thread_flag(TIF_NOTIFY_SIGNAL)) |
|---|
| 104 | 104 | do_signal(regs); |
|---|
| 105 | | - if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) |
|---|
| 105 | + if (test_thread_flag(TIF_NOTIFY_RESUME)) |
|---|
| 106 | 106 | tracehook_notify_resume(regs); |
|---|
| 107 | 107 | } |
|---|
| 108 | 108 | |
|---|
| .. | .. |
|---|
| 154 | 154 | } |
|---|
| 155 | 155 | |
|---|
| 156 | 156 | int copy_thread(unsigned long clone_flags, unsigned long sp, |
|---|
| 157 | | - unsigned long arg, struct task_struct * p) |
|---|
| 157 | + unsigned long arg, struct task_struct * p, unsigned long tls) |
|---|
| 158 | 158 | { |
|---|
| 159 | 159 | void (*handler)(void); |
|---|
| 160 | | - int kthread = current->flags & PF_KTHREAD; |
|---|
| 160 | + int kthread = current->flags & (PF_KTHREAD | PF_IO_WORKER); |
|---|
| 161 | 161 | int ret = 0; |
|---|
| 162 | 162 | |
|---|
| 163 | 163 | p->thread = (struct thread_struct) INIT_THREAD; |
|---|
| .. | .. |
|---|
| 188 | 188 | * Set a new TLS for the child thread? |
|---|
| 189 | 189 | */ |
|---|
| 190 | 190 | if (clone_flags & CLONE_SETTLS) |
|---|
| 191 | | - ret = arch_copy_tls(p); |
|---|
| 191 | + ret = arch_set_tls(p, tls); |
|---|
| 192 | 192 | } |
|---|
| 193 | 193 | |
|---|
| 194 | 194 | return ret; |
|---|
| .. | .. |
|---|
| 203 | 203 | kmalloc_ok = save_kmalloc_ok; |
|---|
| 204 | 204 | } |
|---|
| 205 | 205 | |
|---|
| 206 | +static void um_idle_sleep(void) |
|---|
| 207 | +{ |
|---|
| 208 | + unsigned long long duration = UM_NSEC_PER_SEC; |
|---|
| 209 | + |
|---|
| 210 | + if (time_travel_mode != TT_MODE_OFF) { |
|---|
| 211 | + time_travel_sleep(duration); |
|---|
| 212 | + } else { |
|---|
| 213 | + os_idle_sleep(duration); |
|---|
| 214 | + } |
|---|
| 215 | +} |
|---|
| 216 | + |
|---|
| 206 | 217 | void arch_cpu_idle(void) |
|---|
| 207 | 218 | { |
|---|
| 208 | 219 | cpu_tasks[current_thread_info()->cpu].pid = os_getpid(); |
|---|
| 209 | | - os_idle_sleep(UM_NSEC_PER_SEC); |
|---|
| 210 | | - local_irq_enable(); |
|---|
| 220 | + um_idle_sleep(); |
|---|
| 221 | + raw_local_irq_enable(); |
|---|
| 211 | 222 | } |
|---|
| 212 | 223 | |
|---|
| 213 | 224 | int __cant_sleep(void) { |
|---|
| .. | .. |
|---|
| 300 | 311 | return count; |
|---|
| 301 | 312 | } |
|---|
| 302 | 313 | |
|---|
| 303 | | -static const struct file_operations sysemu_proc_fops = { |
|---|
| 304 | | - .owner = THIS_MODULE, |
|---|
| 305 | | - .open = sysemu_proc_open, |
|---|
| 306 | | - .read = seq_read, |
|---|
| 307 | | - .llseek = seq_lseek, |
|---|
| 308 | | - .release = single_release, |
|---|
| 309 | | - .write = sysemu_proc_write, |
|---|
| 314 | +static const struct proc_ops sysemu_proc_ops = { |
|---|
| 315 | + .proc_open = sysemu_proc_open, |
|---|
| 316 | + .proc_read = seq_read, |
|---|
| 317 | + .proc_lseek = seq_lseek, |
|---|
| 318 | + .proc_release = single_release, |
|---|
| 319 | + .proc_write = sysemu_proc_write, |
|---|
| 310 | 320 | }; |
|---|
| 311 | 321 | |
|---|
| 312 | 322 | int __init make_proc_sysemu(void) |
|---|
| .. | .. |
|---|
| 315 | 325 | if (!sysemu_supported) |
|---|
| 316 | 326 | return 0; |
|---|
| 317 | 327 | |
|---|
| 318 | | - ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_fops); |
|---|
| 328 | + ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_ops); |
|---|
| 319 | 329 | |
|---|
| 320 | 330 | if (ent == NULL) |
|---|
| 321 | 331 | { |
|---|
| .. | .. |
|---|
| 332 | 342 | { |
|---|
| 333 | 343 | struct task_struct *task = t ? t : current; |
|---|
| 334 | 344 | |
|---|
| 335 | | - if (!(task->ptrace & PT_DTRACE)) |
|---|
| 345 | + if (!test_thread_flag(TIF_SINGLESTEP)) |
|---|
| 336 | 346 | return 0; |
|---|
| 337 | 347 | |
|---|
| 338 | 348 | if (task->thread.singlestep_syscall) |
|---|