* git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-2.6-mn10300: (44 commits)
MN10300: Save frame pointer in thread_info struct rather than global var
MN10300: Change "Matsushita" to "Panasonic".
MN10300: Create a defconfig for the ASB2364 board
MN10300: Update the ASB2303 defconfig
MN10300: ASB2364: Add support for SMSC911X and SMC911X
MN10300: ASB2364: Handle the IRQ multiplexer in the FPGA
MN10300: Generic time support
MN10300: Specify an ELF HWCAP flag for MN10300 Atomic Operations Unit support
MN10300: Map userspace atomic op regs as a vmalloc page
MN10300: And Panasonic AM34 subarch and implement SMP
MN10300: Delete idle_timestamp from irq_cpustat_t
MN10300: Make various interrupt priority settings configurable
MN10300: Optimise do_csum()
MN10300: Implement atomic ops using atomic ops unit
MN10300: Make the FPU operate in non-lazy mode under SMP
MN10300: SMP TLB flushing
MN10300: Use the [ID]PTEL2 registers rather than [ID]PTEL for TLB control
MN10300: Make the use of PIDR to mark TLB entries controllable
MN10300: Rename __flush_tlb*() to local_flush_tlb*()
MN10300: AM34 erratum requires MMUCTR read and write on exception entry
...
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <sys/wait.h>
#include <signal.h>
#include <linux/genetlink.h>
int containerset = 0;
char containerpath[1024];
int cfd = 0;
+ int forking = 0;
+ sigset_t sigset;
struct msgtemplate msg;
- while (1) {
- c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:");
+ while (!forking) {
+ c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:c:");
if (c < 0)
break;
err(1, "Invalid pid\n");
cmd_type = TASKSTATS_CMD_ATTR_PID;
break;
+ case 'c':
+
+ /* Block SIGCHLD for sigwait() later */
+ if (sigemptyset(&sigset) == -1)
+ err(1, "Failed to empty sigset");
+ if (sigaddset(&sigset, SIGCHLD))
+ err(1, "Failed to set sigchld in sigset");
+ sigprocmask(SIG_BLOCK, &sigset, NULL);
+
+ /* fork/exec a child */
+ tid = fork();
+ if (tid < 0)
+ err(1, "Fork failed\n");
+ if (tid == 0)
+ if (execvp(argv[optind - 1],
+ &argv[optind - 1]) < 0)
+ exit(-1);
+
+ /* Set the command type and avoid further processing */
+ cmd_type = TASKSTATS_CMD_ATTR_PID;
+ forking = 1;
+ break;
case 'v':
printf("debug on\n");
dbg = 1;
goto err;
}
+ /*
+ * If we forked a child, wait for it to exit. Cannot use waitpid()
+ * as all the delicious data would be reaped as part of the wait
+ */
+ if (tid && forking) {
+ int sig_received;
+ sigwait(&sigset, &sig_received);
+ }
+
if (tid) {
rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
cmd_type, &tid, sizeof(__u32));
1.2 Why are cgroups needed ?
1.3 How are cgroups implemented ?
1.4 What does notify_on_release do ?
- 1.5 How do I use cgroups ?
+ 1.5 What does clone_children do ?
+ 1.6 How do I use cgroups ?
2. Usage Examples and Syntax
2.1 Basic Usage
2.2 Attaching processes
value of their parents notify_on_release setting. The default value of
a cgroup hierarchy's release_agent path is empty.
-1.5 How do I use cgroups ?
+1.5 What does clone_children do ?
+---------------------------------
+
+If the clone_children flag is enabled (1) in a cgroup, then all
+cgroups created beneath will call the post_clone callbacks for each
+subsystem of the newly created cgroup. Usually when this callback is
+implemented for a subsystem, it copies the values of the parent
+subsystem, this is the case for the cpuset.
+
+1.6 How do I use cgroups ?
--------------------------
To start a new job that is to be contained within a cgroup, using
----------------------------
+What: namespace cgroup (ns_cgroup)
+When: 2.6.38
+Why: The ns_cgroup leads to some problems:
+ * cgroup creation is out-of-control
+ * cgroup name can conflict when pids are looping
+ * it is not possible to have a single process handling
+ a lot of namespaces without falling in a exponential creation time
+ * we may want to create a namespace without creating a cgroup
+
+ The ns_cgroup is replaced by a compatibility flag 'clone_children',
+ where a newly created cgroup will copy the parent cgroup values.
+ The userspace has to manually create a cgroup and add a task to
+ the 'tasks' file.
+Who: Daniel Lezcano <daniel.lezcano@free.fr>
+
+----------------------------
+
What: iwlwifi disable_hw_scan module parameters
When: 2.6.40
Why: Hareware scan is the prefer method for iwlwifi devices for
statm Process memory status information
status Process status in human readable form
wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan
+ pagemap Page table
stack Report full stack trace, enable via CONFIG_STACKTRACE
smaps a extension based on maps, showing the memory consumption of
each mapping
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 892 kB
+Anonymous: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
mapping in /proc/PID/maps. The remaining lines show the size of the mapping
(size), the amount of the mapping that is currently resident in RAM (RSS), the
process' proportional share of this mapping (PSS), the number of clean and
-dirty shared pages in the mapping, and the number of clean and dirty private
-pages in the mapping. The "Referenced" indicates the amount of memory
-currently marked as referenced or accessed.
+dirty private pages in the mapping. Note that even a page which is part of a
+MAP_SHARED mapping, but has only a single pte mapped, i.e. is currently used
+by only one process, is accounted as private and not as shared. "Referenced"
+indicates the amount of memory currently marked as referenced or accessed.
+"Anonymous" shows the amount of memory that does not belong to any file. Even
+a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
+and a page is modified, the file page is replaced by a private anonymous copy.
+"Swap" shows how much would-be-anonymous memory is also used, but out on
+swap.
This file is only present if the CONFIG_MMU kernel configuration option is
enabled.
> echo 3 > /proc/PID/clear_refs
Any other value written to /proc/PID/clear_refs will have no effect.
+The /proc/pid/pagemap gives the PFN, which can be used to find the pageflags
+using /proc/kpageflags and number of times a page is mapped using
+/proc/kpagecount. For detailed explanation, see Documentation/vm/pagemap.txt.
1.2 Kernel data
---------------
A convenience function to print out the PHY status neatly.
- int phy_clear_interrupt(struct phy_device *phydev);
- int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
-
- Clear the PHY's interrupt, and configure which ones are allowed,
- respectively. Currently only supports all on, or all off.
-
- int phy_enable_interrupts(struct phy_device *phydev);
- int phy_disable_interrupts(struct phy_device *phydev);
-
- Functions which enable/disable PHY interrupts, clearing them
- before and after, respectively.
-
int phy_start_interrupts(struct phy_device *phydev);
int phy_stop_interrupts(struct phy_device *phydev);
Fills the phydev structure with up-to-date information about the current
settings in the PHY.
- void phy_sanitize_settings(struct phy_device *phydev)
-
- Resolves differences between currently desired settings, and
- supported settings for the given PHY device. Does not make
- the changes in the hardware, though.
-
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
Contains the amount of dirty memory at which the pdflush background writeback
daemon will start writeback.
-If dirty_background_bytes is written, dirty_background_ratio becomes a function
-of its value (dirty_background_bytes / the amount of dirtyable system memory).
+Note: dirty_background_bytes is the counterpart of dirty_background_ratio. Only
+one of them may be specified at a time. When one sysctl is written it is
+immediately taken into account to evaluate the dirty memory limits and the
+other appears as 0 when read.
==============================================================
Contains the amount of dirty memory at which a process generating disk writes
will itself start writeback.
-If dirty_bytes is written, dirty_ratio becomes a function of its value
-(dirty_bytes / the amount of dirtyable system memory).
+Note: dirty_bytes is the counterpart of dirty_ratio. Only one of them may be
+specified at a time. When one sysctl is written it is immediately taken into
+account to evaluate the dirty memory limits and the other appears as 0 when
+read.
Note: the minimum value allowed for dirty_bytes is two pages (in bytes); any
value lower than this limit will be ignored and the old configuration will be
*/
static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
{
- dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
+ dma_addr_t dac_offset = alpha_mv.pci_dac_offset;
int ok = 1;
/* If this is not set, the machine doesn't support DAC at all. */
spin_lock_irqsave(&arena->lock, flags);
for (end = sg + nents; sg < end; ++sg) {
- dma64_addr_t addr;
+ dma_addr_t addr;
size_t size;
long npages, ofs;
dma_addr_t tend;
user_disable_single_step(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
size_t copied;
case PTRACE_PEEKUSR:
force_successful_syscall_return();
ret = get_reg(child, addr);
- DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret));
+ DBG(DBG_MEM, ("peek $%lu->%#lx\n", addr, ret));
break;
/* When I and D space are separate, this will have to be fixed. */
break;
case PTRACE_POKEUSR: /* write the specified register */
- DBG(DBG_MEM, ("poke $%ld<-%#lx\n", addr, data));
+ DBG(DBG_MEM, ("poke $%lu<-%#lx\n", addr, data));
ret = put_reg(child, addr, data);
break;
default:
}
#endif
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
case PTRACE_PEEKUSR:
- ret = ptrace_read_user(child, addr, (unsigned long __user *)data);
+ ret = ptrace_read_user(child, addr, datap);
break;
case PTRACE_POKEUSR:
break;
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (void __user *)data);
+ ret = ptrace_getregs(child, datap);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (void __user *)data);
+ ret = ptrace_setregs(child, datap);
break;
case PTRACE_GETFPREGS:
- ret = ptrace_getfpregs(child, (void __user *)data);
+ ret = ptrace_getfpregs(child, datap);
break;
case PTRACE_SETFPREGS:
- ret = ptrace_setfpregs(child, (void __user *)data);
+ ret = ptrace_setfpregs(child, datap);
break;
#ifdef CONFIG_IWMMXT
case PTRACE_GETWMMXREGS:
- ret = ptrace_getwmmxregs(child, (void __user *)data);
+ ret = ptrace_getwmmxregs(child, datap);
break;
case PTRACE_SETWMMXREGS:
- ret = ptrace_setwmmxregs(child, (void __user *)data);
+ ret = ptrace_setwmmxregs(child, datap);
break;
#endif
case PTRACE_GET_THREAD_AREA:
ret = put_user(task_thread_info(child)->tp_value,
- (unsigned long __user *) data);
+ datap);
break;
case PTRACE_SET_SYSCALL:
#ifdef CONFIG_CRUNCH
case PTRACE_GETCRUNCHREGS:
- ret = ptrace_getcrunchregs(child, (void __user *)data);
+ ret = ptrace_getcrunchregs(child, datap);
break;
case PTRACE_SETCRUNCHREGS:
- ret = ptrace_setcrunchregs(child, (void __user *)data);
+ ret = ptrace_setcrunchregs(child, datap);
break;
#endif
#ifdef CONFIG_VFP
case PTRACE_GETVFPREGS:
- ret = ptrace_getvfpregs(child, (void __user *)data);
+ ret = ptrace_getvfpregs(child, datap);
break;
case PTRACE_SETVFPREGS:
- ret = ptrace_setvfpregs(child, (void __user *)data);
+ ret = ptrace_setvfpregs(child, datap);
break;
#endif
#include <linux/io.h>
#include <linux/cnt32_to_63.h>
-#include <asm/mach/time.h>
#include <asm/mach/time.h>
#include <asm/localtimer.h>
int idx, type;
if (kvaddr >= (void *)FIXADDR_START) {
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
idx = type + KM_TYPE_NR * smp_processor_id();
if (cache_is_vivt())
#else
(void) idx; /* to kill a warning */
#endif
+ kmap_atomic_idx_pop();
} else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
/* this address was obtained through kmap_high_get() */
kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
#include <linux/dmaengine.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
-#include <linux/dmaengine.h>
/* dev types for memcpy */
#define STEDMA40_DEV_DST_MEMORY (-1)
return ret;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ void __user *datap = (void __user *) data;
switch (request) {
/* Read the word at location addr in the child process */
break;
case PTRACE_PEEKUSR:
- ret = ptrace_read_user(child, addr,
- (unsigned long __user *)data);
+ ret = ptrace_read_user(child, addr, datap);
break;
/* Write the word in data at location addr */
break;
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (void __user *)data);
+ ret = ptrace_getregs(child, datap);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (const void __user *)data);
+ ret = ptrace_setregs(child, datap);
break;
default:
* Get contents of register REGNO in task TASK.
*/
static inline long
-get_reg(struct task_struct *task, long regno, unsigned long __user *datap)
+get_reg(struct task_struct *task, unsigned long regno,
+ unsigned long __user *datap)
{
long tmp;
struct pt_regs *regs = task_pt_regs(task);
- if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+ if (regno & 3 || regno > PT_LAST_PSEUDO)
return -EIO;
switch (regno) {
* Write contents of register REGNO in task TASK.
*/
static inline int
-put_reg(struct task_struct *task, long regno, unsigned long data)
+put_reg(struct task_struct *task, unsigned long regno, unsigned long data)
{
struct pt_regs *regs = task_pt_regs(task);
- if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+ if (regno & 3 || regno > PT_LAST_PSEUDO)
return -EIO;
switch (regno) {
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
return copy_regset_to_user(child, &user_bfin_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS:
pr_debug("ptrace: PTRACE_SETREGS\n");
return copy_regset_from_user(child, &user_bfin_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (const void __user *)data);
+ datap);
case_default:
default:
* (in user space) where the result of the ptrace call is written (instead of
* being returned).
*/
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned int regno = addr >> 2;
unsigned long __user *datap = (unsigned long __user *)data;
switch (request) {
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+ if ((addr & 3) || regno > PT_MAX)
break;
- tmp = get_reg(child, addr >> 2);
+ tmp = get_reg(child, regno);
ret = put_user(tmp, datap);
break;
}
/* Write the word at location address in the USER area. */
case PTRACE_POKEUSR:
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+ if ((addr & 3) || regno > PT_MAX)
break;
- addr >>= 2;
-
- if (addr == PT_DCCR) {
+ if (regno == PT_DCCR) {
/* don't allow the tracing process to change stuff like
* interrupt enable, kernel/user bit, dma enables etc.
*/
data &= DCCR_MASK;
data |= get_reg(child, PT_DCCR) & ~DCCR_MASK;
}
- if (put_reg(child, addr, data))
+ if (put_reg(child, regno, data))
break;
ret = 0;
break;
break;
}
- data += sizeof(long);
+ datap++;
}
break;
}
put_reg(child, i, tmp);
- data += sizeof(long);
+ datap++;
}
break;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned int regno = addr >> 2;
unsigned long __user *datap = (unsigned long __user *)data;
switch (request) {
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+ if ((addr & 3) || regno > PT_MAX)
break;
- tmp = get_reg(child, addr >> 2);
+ tmp = get_reg(child, regno);
ret = put_user(tmp, datap);
break;
}
/* Write the word at location address in the USER area. */
case PTRACE_POKEUSR:
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+ if ((addr & 3) || regno > PT_MAX)
break;
- addr >>= 2;
-
- if (addr == PT_CCS) {
+ if (regno == PT_CCS) {
/* don't allow the tracing process to change stuff like
* interrupt enable, kernel/user bit, dma enables etc.
*/
data &= CCS_MASK;
data |= get_reg(child, PT_CCS) & ~CCS_MASK;
}
- if (put_reg(child, addr, data))
+ if (put_reg(child, regno, data))
break;
ret = 0;
break;
user_disable_single_step(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
int ret;
+ int regno = addr >> 2;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
tmp = 0;
ret = -EIO;
- if ((addr & 3) || addr < 0)
+ if (addr & 3)
break;
ret = 0;
- switch (addr >> 2) {
+ switch (regno) {
case 0 ... PT__END - 1:
- tmp = get_reg(child, addr >> 2);
+ tmp = get_reg(child, regno);
break;
case PT__END + 0:
}
if (ret == 0)
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, datap);
break;
}
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0)
+ if (addr & 3)
break;
- ret = 0;
- switch (addr >> 2) {
+ switch (regno) {
case 0 ... PT__END - 1:
- ret = put_reg(child, addr >> 2, data);
- break;
-
- default:
- ret = -EIO;
+ ret = put_reg(child, regno, data);
break;
}
break;
return copy_regset_to_user(child, &user_frv_native_view,
REGSET_GENERAL,
0, sizeof(child->thread.user->i),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS: /* Set all integer regs in the child. */
return copy_regset_from_user(child, &user_frv_native_view,
REGSET_GENERAL,
0, sizeof(child->thread.user->i),
- (const void __user *)data);
+ datap);
case PTRACE_GETFPREGS: /* Get the child FP/Media state. */
return copy_regset_to_user(child, &user_frv_native_view,
REGSET_FPMEDIA,
0, sizeof(child->thread.user->f),
- (void __user *)data);
+ datap);
case PTRACE_SETFPREGS: /* Set the child FP/Media state. */
return copy_regset_from_user(child, &user_frv_native_view,
REGSET_FPMEDIA,
0, sizeof(child->thread.user->f),
- (const void __user *)data);
+ datap);
default:
ret = ptrace_request(child, request, addr, data);
void __kunmap_atomic(void *kvaddr)
{
- int type = kmap_atomic_idx_pop();
+ int type = kmap_atomic_idx();
switch (type) {
case 0: __kunmap_atomic_primary(4, 6); break;
case 1: __kunmap_atomic_primary(5, 7); break;
default:
BUG();
}
+ kmap_atomic_idx_pop();
pagefault_enable();
}
EXPORT_SYMBOL(__kunmap_atomic);
user_disable_single_step(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ int regno = addr >> 2;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
unsigned long tmp = 0;
- if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
+ if ((addr & 3) || addr >= sizeof(struct user)) {
ret = -EIO;
break ;
}
ret = 0; /* Default return condition */
- addr = addr >> 2; /* temporary hack. */
- if (addr < H8300_REGS_NO)
- tmp = h8300_get_reg(child, addr);
+ if (regno < H8300_REGS_NO)
+ tmp = h8300_get_reg(child, regno);
else {
- switch(addr) {
+ switch (regno) {
case 49:
tmp = child->mm->start_code;
break ;
}
}
if (!ret)
- ret = put_user(tmp,(unsigned long *) data);
+ ret = put_user(tmp, datap);
break ;
}
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
- if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
+ if ((addr & 3) || addr >= sizeof(struct user)) {
ret = -EIO;
break ;
}
- addr = addr >> 2; /* temporary hack. */
- if (addr == PT_ORIG_ER0) {
+ if (regno == PT_ORIG_ER0) {
ret = -EIO;
break ;
}
- if (addr < H8300_REGS_NO) {
- ret = h8300_put_reg(child, addr, data);
+ if (regno < H8300_REGS_NO) {
+ ret = h8300_put_reg(child, regno, data);
break ;
}
ret = -EIO;
unsigned long tmp;
for (i = 0; i < H8300_REGS_NO; i++) {
tmp = h8300_get_reg(child, i);
- if (put_user(tmp, (unsigned long *) data)) {
+ if (put_user(tmp, datap)) {
ret = -EFAULT;
break;
}
- data += sizeof(long);
+ datap++;
}
ret = 0;
break;
int i;
unsigned long tmp;
for (i = 0; i < H8300_REGS_NO; i++) {
- if (get_user(tmp, (unsigned long *) data)) {
+ if (get_user(tmp, datap)) {
ret = -EFAULT;
break;
}
h8300_put_reg(child, i, tmp);
- data += sizeof(long);
+ datap++;
}
ret = 0;
break;
#define jiffies64_to_cputime64(__jif) ((__jif) * (NSEC_PER_SEC / HZ))
/*
- * Convert cputime <-> milliseconds
+ * Convert cputime <-> microseconds
*/
-#define cputime_to_msecs(__ct) ((__ct) / NSEC_PER_MSEC)
-#define msecs_to_cputime(__msecs) ((__msecs) * NSEC_PER_MSEC)
+#define cputime_to_usecs(__ct) ((__ct) / NSEC_PER_USEC)
+#define usecs_to_cputime(__usecs) ((__usecs) * NSEC_PER_USEC)
/*
* Convert cputime <-> seconds
}
long
-arch_ptrace (struct task_struct *child, long request, long addr, long data)
+arch_ptrace (struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
switch (request) {
case PTRACE_PEEKTEXT:
}
long
-arch_ptrace(struct task_struct *child, long request, long addr, long data)
+arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/*
* read the word at location addr in the USER area.
*/
case PTRACE_PEEKUSR:
- ret = ptrace_read_user(child, addr,
- (unsigned long __user *)data);
+ ret = ptrace_read_user(child, addr, datap);
break;
/*
break;
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (void __user *)data);
+ ret = ptrace_getregs(child, datap);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (void __user *)data);
+ ret = ptrace_setregs(child, datap);
break;
default:
singlestep_disable(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
int i, ret = 0;
+ int regno = addr >> 2; /* temporary hack. */
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR:
if (addr & 3)
goto out_eio;
- addr >>= 2; /* temporary hack. */
- if (addr >= 0 && addr < 19) {
- tmp = get_reg(child, addr);
- } else if (addr >= 21 && addr < 49) {
- tmp = child->thread.fp[addr - 21];
+ if (regno >= 0 && regno < 19) {
+ tmp = get_reg(child, regno);
+ } else if (regno >= 21 && regno < 49) {
+ tmp = child->thread.fp[regno - 21];
/* Convert internal fpu reg representation
* into long double format
*/
- if (FPU_IS_EMU && (addr < 45) && !(addr % 3))
+ if (FPU_IS_EMU && (regno < 45) && !(regno % 3))
tmp = ((tmp & 0xffff0000) << 15) |
((tmp & 0x0000ffff) << 16);
} else
goto out_eio;
- ret = put_user(tmp, (unsigned long *)data);
+ ret = put_user(tmp, datap);
break;
- case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+ case PTRACE_POKEUSR:
+ /* write the word at location addr in the USER area */
if (addr & 3)
goto out_eio;
- addr >>= 2; /* temporary hack. */
- if (addr == PT_SR) {
+ if (regno == PT_SR) {
data &= SR_MASK;
data |= get_reg(child, PT_SR) & ~SR_MASK;
}
- if (addr >= 0 && addr < 19) {
- if (put_reg(child, addr, data))
+ if (regno >= 0 && regno < 19) {
+ if (put_reg(child, regno, data))
goto out_eio;
- } else if (addr >= 21 && addr < 48) {
+ } else if (regno >= 21 && regno < 48) {
/* Convert long double format
* into internal fpu reg representation
*/
- if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) {
- data = (unsigned long)data << 15;
+ if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {
+ data <<= 15;
data = (data & 0xffff0000) |
((data & 0x0000ffff) >> 1);
}
- child->thread.fp[addr - 21] = data;
+ child->thread.fp[regno - 21] = data;
} else
goto out_eio;
break;
case PTRACE_GETREGS: /* Get all gp regs from the child. */
for (i = 0; i < 19; i++) {
tmp = get_reg(child, i);
- ret = put_user(tmp, (unsigned long *)data);
+ ret = put_user(tmp, datap);
if (ret)
break;
- data += sizeof(long);
+ datap++;
}
break;
case PTRACE_SETREGS: /* Set all gp regs in the child. */
for (i = 0; i < 19; i++) {
- ret = get_user(tmp, (unsigned long *)data);
+ ret = get_user(tmp, datap);
if (ret)
break;
if (i == PT_SR) {
tmp |= get_reg(child, PT_SR) & ~SR_MASK;
}
put_reg(child, i, tmp);
- data += sizeof(long);
+ datap++;
}
break;
case PTRACE_GETFPREGS: /* Get the child FPU state. */
- if (copy_to_user((void *)data, &child->thread.fp,
+ if (copy_to_user(datap, &child->thread.fp,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
case PTRACE_SETFPREGS: /* Set the child FPU state. */
- if (copy_from_user(&child->thread.fp, (void *)data,
+ if (copy_from_user(&child->thread.fp, datap,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
case PTRACE_GET_THREAD_AREA:
- ret = put_user(task_thread_info(child)->tp_value,
- (unsigned long __user *)data);
+ ret = put_user(task_thread_info(child)->tp_value, datap);
break;
default:
user_disable_single_step(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ int regno = addr >> 2;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 3) || addr > sizeof(struct user) - 3)
break;
tmp = 0; /* Default return condition */
- addr = addr >> 2; /* temporary hack. */
ret = -EIO;
- if (addr < 19) {
- tmp = get_reg(child, addr);
- if (addr == PT_SR)
+ if (regno < 19) {
+ tmp = get_reg(child, regno);
+ if (regno == PT_SR)
tmp >>= 16;
- } else if (addr >= 21 && addr < 49) {
- tmp = child->thread.fp[addr - 21];
- } else if (addr == 49) {
+ } else if (regno >= 21 && regno < 49) {
+ tmp = child->thread.fp[regno - 21];
+ } else if (regno == 49) {
tmp = child->mm->start_code;
- } else if (addr == 50) {
+ } else if (regno == 50) {
tmp = child->mm->start_data;
- } else if (addr == 51) {
+ } else if (regno == 51) {
tmp = child->mm->end_code;
} else
break;
- ret = put_user(tmp,(unsigned long *) data);
+ ret = put_user(tmp, datap);
break;
}
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 3) || addr > sizeof(struct user) - 3)
break;
- addr = addr >> 2; /* temporary hack. */
-
- if (addr == PT_SR) {
+ if (regno == PT_SR) {
data &= SR_MASK;
data <<= 16;
data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
}
- if (addr < 19) {
- if (put_reg(child, addr, data))
+ if (regno < 19) {
+ if (put_reg(child, regno, data))
break;
ret = 0;
break;
}
- if (addr >= 21 && addr < 48)
+ if (regno >= 21 && regno < 48)
{
- child->thread.fp[addr - 21] = data;
+ child->thread.fp[regno - 21] = data;
ret = 0;
}
break;
tmp = get_reg(child, i);
if (i == PT_SR)
tmp >>= 16;
- if (put_user(tmp, (unsigned long *) data)) {
+ if (put_user(tmp, datap)) {
ret = -EFAULT;
break;
}
- data += sizeof(long);
+ datap++;
}
ret = 0;
break;
int i;
unsigned long tmp;
for (i = 0; i < 19; i++) {
- if (get_user(tmp, (unsigned long *) data)) {
+ if (get_user(tmp, datap)) {
ret = -EFAULT;
break;
}
tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
}
put_reg(child, i, tmp);
- data += sizeof(long);
+ datap++;
}
ret = 0;
break;
#ifdef PTRACE_GETFPREGS
case PTRACE_GETFPREGS: { /* Get the child FPU state. */
ret = 0;
- if (copy_to_user((void *)data, &child->thread.fp,
+ if (copy_to_user(datap, &child->thread.fp,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
#ifdef PTRACE_SETFPREGS
case PTRACE_SETFPREGS: { /* Set the child FPU state. */
ret = 0;
- if (copy_from_user(&child->thread.fp, (void *)data,
+ if (copy_from_user(&child->thread.fp, datap,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
#endif
case PTRACE_GET_THREAD_AREA:
- ret = put_user(task_thread_info(child)->tp_value,
- (unsigned long __user *)data);
+ ret = put_user(task_thread_info(child)->tp_value, datap);
break;
default:
return (microblaze_reg_t *)((char *)regs + reg_offs);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int rval;
unsigned long val = 0;
} else {
rval = -EIO;
}
- } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+ } else if (addr < PT_SIZE && (addr & 0x3) == 0) {
microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
if (request == PTRACE_PEEKUSR)
val = *reg_addr;
nasid_t nasid;
unsigned int widget_id;
unsigned int irq_cpu;
- dma64_addr_t baddr;
+ u64 baddr;
unsigned int pci_int[8];
};
return 0;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ void __user *addrp = (void __user *) addr;
+ void __user *datavp = (void __user *) data;
+ unsigned long __user *datalp = (void __user *) data;
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
ret = -EIO;
goto out;
}
- ret = put_user(tmp, (unsigned long __user *) data);
+ ret = put_user(tmp, datalp);
break;
}
}
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (__s64 __user *) data);
+ ret = ptrace_getregs(child, datavp);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (__s64 __user *) data);
+ ret = ptrace_setregs(child, datavp);
break;
case PTRACE_GETFPREGS:
- ret = ptrace_getfpregs(child, (__u32 __user *) data);
+ ret = ptrace_getfpregs(child, datavp);
break;
case PTRACE_SETFPREGS:
- ret = ptrace_setfpregs(child, (__u32 __user *) data);
+ ret = ptrace_setfpregs(child, datavp);
break;
case PTRACE_GET_THREAD_AREA:
- ret = put_user(task_thread_info(child)->tp_value,
- (unsigned long __user *) data);
+ ret = put_user(task_thread_info(child)->tp_value, datalp);
break;
case PTRACE_GET_WATCH_REGS:
- ret = ptrace_get_watch_regs(child,
- (struct pt_watch_regs __user *) addr);
+ ret = ptrace_get_watch_regs(child, addrp);
break;
case PTRACE_SET_WATCH_REGS:
- ret = ptrace_set_watch_regs(child,
- (struct pt_watch_regs __user *) addr);
+ ret = ptrace_set_watch_regs(child, addrp);
break;
default:
return;
}
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
#ifdef CONFIG_DEBUG_HIGHMEM
{
int idx = type + KM_TYPE_NR * smp_processor_id();
local_flush_tlb_one(vaddr);
}
#endif
+ kmap_atomic_idx_pop();
pagefault_enable();
}
EXPORT_SYMBOL(__kunmap_atomic);
return;
}
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
#if HIGHMEM_DEBUG
{
local_flush_tlb_one(vaddr);
}
#endif
+
+ kmap_atomic_idx_pop();
pagefault_enable();
}
#endif /* __KERNEL__ */
/*
* handle the arch-specific side of process tracing
*/
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
int ret;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR:
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 3) || addr > sizeof(struct user) - 3)
break;
tmp = 0; /* Default return condition */
if (addr < NR_PTREGS << 2)
tmp = get_stack_long(child,
ptrace_regid_to_frame[addr]);
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, datap);
break;
/* write the word at location addr in the USER area */
case PTRACE_POKEUSR:
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
+ if ((addr & 3) || addr > sizeof(struct user) - 3)
break;
ret = 0;
return copy_regset_to_user(child, &user_mn10300_native_view,
REGSET_GENERAL,
0, NR_PTREGS * sizeof(long),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS: /* Set all integer regs in the child. */
return copy_regset_from_user(child, &user_mn10300_native_view,
REGSET_GENERAL,
0, NR_PTREGS * sizeof(long),
- (const void __user *)data);
+ datap);
case PTRACE_GETFPREGS: /* Get the child FPU state. */
return copy_regset_to_user(child, &user_mn10300_native_view,
REGSET_FPU,
0, sizeof(struct fpu_state_struct),
- (void __user *)data);
+ datap);
case PTRACE_SETFPREGS: /* Set the child FPU state. */
return copy_regset_from_user(child, &user_mn10300_native_view,
REGSET_FPU,
0, sizeof(struct fpu_state_struct),
- (const void __user *)data);
+ datap);
default:
ret = ptrace_request(child, request, addr, data);
pa_psw(task)->l = 0;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
long ret = -EIO;
/* Read the word at location addr in the USER area. For ptraced
processes, the kernel saves all regs on a syscall. */
case PTRACE_PEEKUSR:
- if ((addr & (sizeof(long)-1)) ||
- (unsigned long) addr >= sizeof(struct pt_regs))
+ if ((addr & (sizeof(unsigned long)-1)) ||
+ addr >= sizeof(struct pt_regs))
break;
tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, (unsigned long __user *) data);
break;
/* Write the word at location addr in the USER area. This will need
break;
}
- if ((addr & (sizeof(long)-1)) ||
- (unsigned long) addr >= sizeof(struct pt_regs))
+ if ((addr & (sizeof(unsigned long)-1)) ||
+ addr >= sizeof(struct pt_regs))
break;
if ((addr >= PT_GR1 && addr <= PT_GR31) ||
addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
}
/*
- * Convert cputime <-> milliseconds
+ * Convert cputime <-> microseconds
*/
extern u64 __cputime_msec_factor;
-static inline unsigned long cputime_to_msecs(const cputime_t ct)
+static inline unsigned long cputime_to_usecs(const cputime_t ct)
{
- return mulhdu(ct, __cputime_msec_factor);
+ return mulhdu(ct, __cputime_msec_factor) * USEC_PER_MSEC;
}
-static inline cputime_t msecs_to_cputime(const unsigned long ms)
+static inline cputime_t usecs_to_cputime(const unsigned long us)
{
cputime_t ct;
unsigned long sec;
/* have to be a little careful about overflow */
- ct = ms % 1000;
- sec = ms / 1000;
+ ct = us % 1000000;
+ sec = us / 1000000;
if (ct) {
ct *= tb_ticks_per_sec;
do_div(ct, 1000);
* Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
* we mark them as obsolete now, they will be removed in a future version
*/
-static long arch_ptrace_old(struct task_struct *child, long request, long addr,
- long data)
+static long arch_ptrace_old(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
+ void __user *datavp = (void __user *) data;
+
switch (request) {
case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_GPR, 0, 32 * sizeof(long),
- (void __user *) data);
+ datavp);
case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_GPR, 0, 32 * sizeof(long),
- (const void __user *) data);
+ datavp);
case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_FPR, 0, 32 * sizeof(double),
- (void __user *) data);
+ datavp);
case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_FPR, 0, 32 * sizeof(double),
- (const void __user *) data);
+ datavp);
}
return -EPERM;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret = -EPERM;
+ void __user *datavp = (void __user *) data;
+ unsigned long __user *datalp = datavp;
switch (request) {
/* read the word at location addr in the USER area. */
ret = -EIO;
/* convert to index and check */
#ifdef CONFIG_PPC32
- index = (unsigned long) addr >> 2;
+ index = addr >> 2;
if ((addr & 3) || (index > PT_FPSCR)
|| (child->thread.regs == NULL))
#else
- index = (unsigned long) addr >> 3;
+ index = addr >> 3;
if ((addr & 7) || (index > PT_FPSCR))
#endif
break;
tmp = ((unsigned long *)child->thread.fpr)
[TS_FPRWIDTH * (index - PT_FPR0)];
}
- ret = put_user(tmp,(unsigned long __user *) data);
+ ret = put_user(tmp, datalp);
break;
}
ret = -EIO;
/* convert to index and check */
#ifdef CONFIG_PPC32
- index = (unsigned long) addr >> 2;
+ index = addr >> 2;
if ((addr & 3) || (index > PT_FPSCR)
|| (child->thread.regs == NULL))
#else
- index = (unsigned long) addr >> 3;
+ index = addr >> 3;
if ((addr & 7) || (index > PT_FPSCR))
#endif
break;
dbginfo.features = 0;
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
- if (!access_ok(VERIFY_WRITE, data,
+ if (!access_ok(VERIFY_WRITE, datavp,
sizeof(struct ppc_debug_info)))
return -EFAULT;
- ret = __copy_to_user((struct ppc_debug_info __user *)data,
- &dbginfo, sizeof(struct ppc_debug_info)) ?
+ ret = __copy_to_user(datavp, &dbginfo,
+ sizeof(struct ppc_debug_info)) ?
-EFAULT : 0;
break;
}
case PPC_PTRACE_SETHWDEBUG: {
struct ppc_hw_breakpoint bp_info;
- if (!access_ok(VERIFY_READ, data,
+ if (!access_ok(VERIFY_READ, datavp,
sizeof(struct ppc_hw_breakpoint)))
return -EFAULT;
- ret = __copy_from_user(&bp_info,
- (struct ppc_hw_breakpoint __user *)data,
+ ret = __copy_from_user(&bp_info, datavp,
sizeof(struct ppc_hw_breakpoint)) ?
-EFAULT : 0;
if (!ret)
if (addr > 0)
break;
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
- ret = put_user(child->thread.dac1,
- (unsigned long __user *)data);
+ ret = put_user(child->thread.dac1, datalp);
#else
- ret = put_user(child->thread.dabr,
- (unsigned long __user *)data);
+ ret = put_user(child->thread.dabr, datalp);
#endif
break;
}
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_GPR,
0, sizeof(struct pt_regs),
- (void __user *) data);
+ datavp);
#ifdef CONFIG_PPC64
case PTRACE_SETREGS64:
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_GPR,
0, sizeof(struct pt_regs),
- (const void __user *) data);
+ datavp);
case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_FPR,
0, sizeof(elf_fpregset_t),
- (void __user *) data);
+ datavp);
case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_FPR,
0, sizeof(elf_fpregset_t),
- (const void __user *) data);
+ datavp);
#ifdef CONFIG_ALTIVEC
case PTRACE_GETVRREGS:
REGSET_VMX,
0, (33 * sizeof(vector128) +
sizeof(u32)),
- (void __user *) data);
+ datavp);
case PTRACE_SETVRREGS:
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_VMX,
0, (33 * sizeof(vector128) +
sizeof(u32)),
- (const void __user *) data);
+ datavp);
#endif
#ifdef CONFIG_VSX
case PTRACE_GETVSRREGS:
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_VSX,
0, 32 * sizeof(double),
- (void __user *) data);
+ datavp);
case PTRACE_SETVSRREGS:
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_VSX,
0, 32 * sizeof(double),
- (const void __user *) data);
+ datavp);
#endif
#ifdef CONFIG_SPE
case PTRACE_GETEVRREGS:
/* Get the child spe register state. */
return copy_regset_to_user(child, &user_ppc_native_view,
REGSET_SPE, 0, 35 * sizeof(u32),
- (void __user *) data);
+ datavp);
case PTRACE_SETEVRREGS:
/* Set the child spe register state. */
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_SPE, 0, 35 * sizeof(u32),
- (const void __user *) data);
+ datavp);
#endif
/* Old reverse args ptrace callss */
return;
}
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
#ifdef CONFIG_DEBUG_HIGHMEM
{
local_flush_tlb_page(NULL, vaddr);
}
#endif
+
+ kmap_atomic_idx_pop();
pagefault_enable();
}
EXPORT_SYMBOL(__kunmap_atomic);
#define RIO_ATMU_REGS_OFFSET 0x10c00
#define RIO_P_MSG_REGS_OFFSET 0x11000
#define RIO_S_MSG_REGS_OFFSET 0x13000
+#define RIO_GCCSR 0x13c
#define RIO_ESCSR 0x158
#define RIO_CCSR 0x15c
#define RIO_LTLEDCSR 0x0608
#define RIO_IPWSR_PWD 0x00000008
#define RIO_IPWSR_PWB 0x00000004
+#define RIO_EPWISR_PINT 0x80000000
+#define RIO_EPWISR_PW 0x00000001
+
#define RIO_MSG_DESC_SIZE 32
#define RIO_MSG_BUFFER_SIZE 4096
#define RIO_MIN_TX_RING_SIZE 2
struct rio_priv *priv = port->priv;
u32 epwisr, tmp;
- ipwmr = in_be32(&priv->msg_regs->pwmr);
- ipwsr = in_be32(&priv->msg_regs->pwsr);
-
epwisr = in_be32(priv->regs_win + RIO_EPWISR);
- if (epwisr & 0x80000000) {
- tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
- pr_info("RIO_LTLEDCSR = 0x%x\n", tmp);
- out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
- }
+ if (!(epwisr & RIO_EPWISR_PW))
+ goto pw_done;
- if (!(epwisr & 0x00000001))
- return IRQ_HANDLED;
+ ipwmr = in_be32(&priv->msg_regs->pwmr);
+ ipwsr = in_be32(&priv->msg_regs->pwsr);
#ifdef DEBUG_PW
pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr);
pr_debug(" PWB");
pr_debug(" )\n");
#endif
- out_be32(&priv->msg_regs->pwsr,
- ipwsr & (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD));
-
- if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
- priv->port_write_msg.err_count++;
- pr_info("RIO: Port-Write Transaction Err (%d)\n",
- priv->port_write_msg.err_count);
- }
- if (ipwsr & RIO_IPWSR_PWD) {
- priv->port_write_msg.discard_count++;
- pr_info("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
- priv->port_write_msg.discard_count);
- }
-
/* Schedule deferred processing if PW was received */
if (ipwsr & RIO_IPWSR_QFI) {
/* Save PW message (if there is room in FIFO),
RIO_PW_MSG_SIZE);
} else {
priv->port_write_msg.discard_count++;
- pr_info("RIO: ISR Discarded Port-Write Msg(s) (%d)\n",
+ pr_debug("RIO: ISR Discarded Port-Write Msg(s) (%d)\n",
priv->port_write_msg.discard_count);
}
+ /* Clear interrupt and issue Clear Queue command. This allows
+ * another port-write to be received.
+ */
+ out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_QFI);
+ out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ);
+
schedule_work(&priv->pw_work);
}
- /* Issue Clear Queue command. This allows another
- * port-write to be received.
- */
- out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ);
+ if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
+ priv->port_write_msg.err_count++;
+ pr_debug("RIO: Port-Write Transaction Err (%d)\n",
+ priv->port_write_msg.err_count);
+ /* Clear Transaction Error: port-write controller should be
+ * disabled when clearing this error
+ */
+ out_be32(&priv->msg_regs->pwmr, ipwmr & ~RIO_IPWMR_PWE);
+ out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_TE);
+ out_be32(&priv->msg_regs->pwmr, ipwmr);
+ }
+
+ if (ipwsr & RIO_IPWSR_PWD) {
+ priv->port_write_msg.discard_count++;
+ pr_debug("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
+ priv->port_write_msg.discard_count);
+ out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_PWD);
+ }
+
+pw_done:
+ if (epwisr & RIO_EPWISR_PINT) {
+ tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
+ pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
+ out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
+ }
return IRQ_HANDLED;
}
port->host_deviceid = fsl_rio_get_hdid(port->id);
port->priv = priv;
+ port->phys_efptr = 0x100;
rio_register_mport(port);
priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
port->sys_size ? 65536 : 256);
+ if (port->host_deviceid >= 0)
+ out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST |
+ RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED);
+ else
+ out_be32(priv->regs_win + RIO_GCCSR, 0x00000000);
+
priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
+ RIO_ATMU_REGS_OFFSET);
priv->maint_atmu_regs = priv->atmu_regs + 1;
}
/*
- * Convert cputime to milliseconds and back.
+ * Convert cputime to microseconds and back.
*/
static inline unsigned int
-cputime_to_msecs(const cputime_t cputime)
+cputime_to_usecs(const cputime_t cputime)
{
- return cputime_div(cputime, 4096000);
+ return cputime_div(cputime, 4096);
}
static inline cputime_t
-msecs_to_cputime(const unsigned int m)
+usecs_to_cputime(const unsigned int m)
{
- return (cputime_t) m * 4096000;
+ return (cputime_t) m * 4096;
}
/*
return __poke_user(child, addr, data);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
ptrace_area parea;
int copied, ret;
}
long
-arch_ptrace(struct task_struct *child, long request, long addr, long data)
+arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
unsigned long __user *datap = (void __user *)data;
ret = copy_regset_to_user(child, &user_score_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (void __user *)datap);
+ datap);
break;
case PTRACE_SETREGS:
ret = copy_regset_from_user(child, &user_score_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (const void __user *)datap);
+ datap);
break;
default:
return &user_sh_native_view;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
- struct user * dummy = NULL;
unsigned long __user *datap = (unsigned long __user *)data;
int ret;
if (addr < sizeof(struct pt_regs))
tmp = get_stack_long(child, addr);
- else if (addr >= (long) &dummy->fpu &&
- addr < (long) &dummy->u_fpvalid) {
+ else if (addr >= offsetof(struct user, fpu) &&
+ addr < offsetof(struct user, u_fpvalid)) {
if (!tsk_used_math(child)) {
- if (addr == (long)&dummy->fpu.fpscr)
+ if (addr == offsetof(struct user, fpu.fpscr))
tmp = FPSCR_INIT;
else
tmp = 0;
- } else
- tmp = ((long *)child->thread.xstate)
- [(addr - (long)&dummy->fpu) >> 2];
- } else if (addr == (long) &dummy->u_fpvalid)
+ } else {
+ unsigned long index;
+ index = addr - offsetof(struct user, fpu);
+ tmp = ((unsigned long *)child->thread.xstate)
+ [index >> 2];
+ }
+ } else if (addr == offsetof(struct user, u_fpvalid))
tmp = !!tsk_used_math(child);
else if (addr == PT_TEXT_ADDR)
tmp = child->mm->start_code;
if (addr < sizeof(struct pt_regs))
ret = put_stack_long(child, addr, data);
- else if (addr >= (long) &dummy->fpu &&
- addr < (long) &dummy->u_fpvalid) {
+ else if (addr >= offsetof(struct user, fpu) &&
+ addr < offsetof(struct user, u_fpvalid)) {
+ unsigned long index;
+ index = addr - offsetof(struct user, fpu);
set_stopped_child_used_math(child);
- ((long *)child->thread.xstate)
- [(addr - (long)&dummy->fpu) >> 2] = data;
+ ((unsigned long *)child->thread.xstate)
+ [index >> 2] = data;
ret = 0;
- } else if (addr == (long) &dummy->u_fpvalid) {
+ } else if (addr == offsetof(struct user, u_fpvalid)) {
conditional_stopped_child_used_math(data, child);
ret = 0;
}
return copy_regset_to_user(child, &user_sh_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS:
return copy_regset_from_user(child, &user_sh_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (const void __user *)data);
+ datap);
#ifdef CONFIG_SH_FPU
case PTRACE_GETFPREGS:
return copy_regset_to_user(child, &user_sh_native_view,
REGSET_FPU,
0, sizeof(struct user_fpu_struct),
- (void __user *)data);
+ datap);
case PTRACE_SETFPREGS:
return copy_regset_from_user(child, &user_sh_native_view,
REGSET_FPU,
0, sizeof(struct user_fpu_struct),
- (const void __user *)data);
+ datap);
#endif
#ifdef CONFIG_SH_DSP
case PTRACE_GETDSPREGS:
return copy_regset_to_user(child, &user_sh_native_view,
REGSET_DSP,
0, sizeof(struct pt_dspregs),
- (void __user *)data);
+ datap);
case PTRACE_SETDSPREGS:
return copy_regset_from_user(child, &user_sh_native_view,
REGSET_DSP,
0, sizeof(struct pt_dspregs),
- (const void __user *)data);
+ datap);
#endif
default:
ret = ptrace_request(child, request, addr, data);
return &user_sh64_native_view;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
tmp = get_stack_long(child, addr);
else if ((addr >= offsetof(struct user, fpu)) &&
(addr < offsetof(struct user, u_fpvalid))) {
- tmp = get_fpu_long(child, addr - offsetof(struct user, fpu));
+ unsigned long index;
+ index = addr - offsetof(struct user, fpu);
+ tmp = get_fpu_long(child, index);
} else if (addr == offsetof(struct user, u_fpvalid)) {
tmp = !!tsk_used_math(child);
} else {
break;
}
- ret = put_user(tmp, (unsigned long *)data);
+ ret = put_user(tmp, datap);
break;
}
}
else if ((addr >= offsetof(struct user, fpu)) &&
(addr < offsetof(struct user, u_fpvalid))) {
- ret = put_fpu_long(child, addr - offsetof(struct user, fpu), data);
+ unsigned long index;
+ index = addr - offsetof(struct user, fpu);
+ ret = put_fpu_long(child, index, data);
}
break;
return copy_regset_to_user(child, &user_sh64_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (void __user *)data);
+ datap);
case PTRACE_SETREGS:
return copy_regset_from_user(child, &user_sh64_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
- (const void __user *)data);
+ datap);
#ifdef CONFIG_SH_FPU
case PTRACE_GETFPREGS:
return copy_regset_to_user(child, &user_sh64_native_view,
REGSET_FPU,
0, sizeof(struct user_fpu_struct),
- (void __user *)data);
+ datap);
case PTRACE_SETFPREGS:
return copy_regset_from_user(child, &user_sh64_native_view,
REGSET_FPU,
0, sizeof(struct user_fpu_struct),
- (const void __user *)data);
+ datap);
#endif
default:
ret = ptrace_request(child, request, addr, data);
return ret;
}
-asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
+asmlinkage int sh64_ptrace(long request, long pid,
+ unsigned long addr, unsigned long data)
{
#define WPC_DBRMODE 0x0d104008
static unsigned long first_call;
#define memset_io(d,c,sz) _memset_io(d,c,sz)
+static inline void
+_sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
+ __kernel_size_t n)
+{
+ char *d = dst;
+
+ while (n--) {
+ char tmp = sbus_readb(src);
+ *d++ = tmp;
+ src++;
+ }
+}
+
+#define sbus_memcpy_fromio(d, s, sz) _sbus_memcpy_fromio(d, s, sz)
+
static inline void
_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
{
#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
+static inline void
+_sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
+ __kernel_size_t n)
+{
+ const char *s = src;
+ volatile void __iomem *d = dst;
+
+ while (n--) {
+ char tmp = *s++;
+ sbus_writeb(tmp, d);
+ d++;
+ }
+}
+
+#define sbus_memcpy_toio(d, s, sz) _sbus_memcpy_toio(d, s, sz)
+
static inline void
_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
{
#define memset_io(d,c,sz) _memset_io(d,c,sz)
+static inline void
+_sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
+ __kernel_size_t n)
+{
+ char *d = dst;
+
+ while (n--) {
+ char tmp = sbus_readb(src);
+ *d++ = tmp;
+ src++;
+ }
+}
+
+#define sbus_memcpy_fromio(d, s, sz) _sbus_memcpy_fromio(d, s, sz)
+
static inline void
_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
{
#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz)
+static inline void
+_sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
+ __kernel_size_t n)
+{
+ const char *s = src;
+ volatile void __iomem *d = dst;
+
+ while (n--) {
+ char tmp = *s++;
+ sbus_writeb(tmp, d);
+ d++;
+ }
+}
+
+#define sbus_memcpy_toio(d, s, sz) _sbus_memcpy_toio(d, s, sz)
+
static inline void
_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
{
* types on sparc64. However, it requires that the device
* can drive enough of the 64 bits.
*/
-#define PCI64_REQUIRED_MASK (~(dma64_addr_t)0)
+#define PCI64_REQUIRED_MASK (~(u64)0)
#define PCI64_ADDR_BASE 0xfffc000000000000UL
#ifdef CONFIG_PCI
return &user_sparc32_view;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+struct fps {
+ unsigned long regs[32];
+ unsigned long fsr;
+ unsigned long flags;
+ unsigned long extra;
+ unsigned long fpqd;
+ struct fq {
+ unsigned long *insnaddr;
+ unsigned long insn;
+ } fpq[16];
+};
+
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4];
+ void __user *addr2p;
const struct user_regset_view *view;
+ struct pt_regs __user *pregs;
+ struct fps __user *fps;
int ret;
view = task_user_regset_view(current);
+ addr2p = (void __user *) addr2;
+ pregs = (struct pt_regs __user *) addr;
+ fps = (struct fps __user *) addr;
switch(request) {
case PTRACE_GETREGS: {
- struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-
ret = copy_regset_to_user(child, view, REGSET_GENERAL,
32 * sizeof(u32),
4 * sizeof(u32),
}
case PTRACE_SETREGS: {
- struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-
ret = copy_regset_from_user(child, view, REGSET_GENERAL,
32 * sizeof(u32),
4 * sizeof(u32),
}
case PTRACE_GETFPREGS: {
- struct fps {
- unsigned long regs[32];
- unsigned long fsr;
- unsigned long flags;
- unsigned long extra;
- unsigned long fpqd;
- struct fq {
- unsigned long *insnaddr;
- unsigned long insn;
- } fpq[16];
- };
- struct fps __user *fps = (struct fps __user *) addr;
-
ret = copy_regset_to_user(child, view, REGSET_FP,
0 * sizeof(u32),
32 * sizeof(u32),
}
case PTRACE_SETFPREGS: {
- struct fps {
- unsigned long regs[32];
- unsigned long fsr;
- unsigned long flags;
- unsigned long extra;
- unsigned long fpqd;
- struct fq {
- unsigned long *insnaddr;
- unsigned long insn;
- } fpq[16];
- };
- struct fps __user *fps = (struct fps __user *) addr;
-
ret = copy_regset_from_user(child, view, REGSET_FP,
0 * sizeof(u32),
32 * sizeof(u32),
case PTRACE_READTEXT:
case PTRACE_READDATA:
- ret = ptrace_readdata(child, addr,
- (void __user *) addr2, data);
+ ret = ptrace_readdata(child, addr, addr2p, data);
if (ret == data)
ret = 0;
case PTRACE_WRITETEXT:
case PTRACE_WRITEDATA:
- ret = ptrace_writedata(child, (void __user *) addr2,
- addr, data);
+ ret = ptrace_writedata(child, addr2p, addr, data);
if (ret == data)
ret = 0;
unsigned long fsr;
};
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
const struct user_regset_view *view = task_user_regset_view(current);
unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
struct pt_regs __user *pregs;
struct fps __user *fps;
+ void __user *addr2p;
int ret;
- pregs = (struct pt_regs __user *) (unsigned long) addr;
- fps = (struct fps __user *) (unsigned long) addr;
+ pregs = (struct pt_regs __user *) addr;
+ fps = (struct fps __user *) addr;
+ addr2p = (void __user *) addr2;
switch (request) {
case PTRACE_PEEKUSR:
case PTRACE_READTEXT:
case PTRACE_READDATA:
- ret = ptrace_readdata(child, addr,
- (char __user *)addr2, data);
+ ret = ptrace_readdata(child, addr, addr2p, data);
if (ret == data)
ret = 0;
else if (ret >= 0)
case PTRACE_WRITETEXT:
case PTRACE_WRITEDATA:
- ret = ptrace_writedata(child, (char __user *) addr2,
- addr, data);
+ ret = ptrace_writedata(child, addr2p, addr, data);
if (ret == data)
ret = 0;
else if (ret >= 0)
return;
}
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
#ifdef CONFIG_DEBUG_HIGHMEM
{
#endif
}
#endif
+
+ kmap_atomic_idx_pop();
pagefault_enable();
}
EXPORT_SYMBOL(__kunmap_atomic);
config ARCH_PHYS_ADDR_T_64BIT
def_bool y
+config ARCH_DMA_ADDR_T_64BIT
+ def_bool y
+
config LOCKDEP_SUPPORT
def_bool y
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long __user *datap = (long __user __force *)data;
unsigned long tmp;
switch (request) {
case PTRACE_PEEKUSR: /* Read register from pt_regs. */
- if (addr < 0 || addr >= PTREGS_SIZE)
+ if (addr >= PTREGS_SIZE)
break;
childreg = (char *)task_pt_regs(child) + addr;
#ifdef CONFIG_COMPAT
break;
case PTRACE_POKEUSR: /* Write register in pt_regs. */
- if (addr < 0 || addr >= PTREGS_SIZE)
+ if (addr >= PTREGS_SIZE)
break;
childreg = (char *)task_pt_regs(child) + addr;
#ifdef CONFIG_COMPAT
if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE))
break;
childregs = (long *)task_pt_regs(child);
- for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) {
+ for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long);
+ ++i) {
ret = __put_user(childregs[i], &datap[i]);
if (ret != 0)
break;
if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE))
break;
childregs = (long *)task_pt_regs(child);
- for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) {
+ for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long);
+ ++i) {
ret = __get_user(childregs[i], &datap[i]);
if (ret != 0)
break;
#include <linux/timex.h>
#include <asm/setup.h>
#include <asm/sections.h>
-#include <asm/sections.h>
-#include <asm/cacheflush.h>
#include <asm/cacheflush.h>
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
pte_t pteval = *pte;
int idx, type;
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
idx = type + KM_TYPE_NR*smp_processor_id();
/*
BUG_ON(!pte_present(pteval) && !pte_migrating(pteval));
kmap_atomic_unregister(pte_page(pteval), vaddr);
kpte_clear_flush(pte, vaddr);
+ kmap_atomic_idx_pop();
} else {
/* Must be a lowmem page */
BUG_ON(vaddr < PAGE_OFFSET);
extern int peek_user(struct task_struct * child, long addr, long data);
extern int poke_user(struct task_struct * child, long addr, long data);
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int i, ret;
- unsigned long __user *p = (void __user *)(unsigned long)data;
+ unsigned long __user *p = (void __user *)data;
+ void __user *vp = p;
switch (request) {
/* read word at location addr. */
#endif
#ifdef PTRACE_GETFPREGS
case PTRACE_GETFPREGS: /* Get the child FPU state. */
- ret = get_fpregs((struct user_i387_struct __user *) data,
- child);
+ ret = get_fpregs(vp, child);
break;
#endif
#ifdef PTRACE_SETFPREGS
case PTRACE_SETFPREGS: /* Set the child FPU state. */
- ret = set_fpregs((struct user_i387_struct __user *) data,
- child);
+ ret = set_fpregs(vp, child);
break;
#endif
case PTRACE_GET_THREAD_AREA:
- ret = ptrace_get_thread_area(child, addr,
- (struct user_desc __user *) data);
+ ret = ptrace_get_thread_area(child, addr, vp);
break;
case PTRACE_SET_THREAD_AREA:
- ret = ptrace_set_thread_area(child, addr,
- (struct user_desc __user *) data);
+ ret = ptrace_set_thread_area(child, addr, datavp);
break;
case PTRACE_FAULTINFO: {
* On i386, ptrace_faultinfo is smaller!
*/
ret = copy_to_user(p, &child->thread.arch.faultinfo,
- sizeof(struct ptrace_faultinfo));
+ sizeof(struct ptrace_faultinfo)) ?
+ -EIO : 0;
break;
}
#ifdef PTRACE_ARCH_PRCTL
case PTRACE_ARCH_PRCTL:
/* XXX Calls ptrace on the host - needs some SMP thinking */
- ret = arch_prctl(child, data, (void *) addr);
+ ret = arch_prctl(child, data, (void __user *) addr);
break;
#endif
default:
(unsigned long *) &fpregs);
}
-long subarch_ptrace(struct task_struct *child, long request, long addr,
- long data)
+long subarch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
return -EIO;
}
return restore_fp_registers(userspace_pid[cpu], fpregs);
}
-long subarch_ptrace(struct task_struct *child, long request, long addr,
- long data)
+long subarch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret = -EIO;
+ void __user *datap = (void __user *) data;
switch (request) {
case PTRACE_GETFPXREGS: /* Get the child FPU state. */
- ret = get_fpregs((struct user_i387_struct __user *) data,
- child);
+ ret = get_fpregs(datap, child);
break;
case PTRACE_SETFPXREGS: /* Set the child FPU state. */
- ret = set_fpregs((struct user_i387_struct __user *) data,
- child);
+ ret = set_fpregs(datap, child);
break;
}
config X86_VSMP
bool "ScaleMP vSMP"
+ select PARAVIRT_GUEST
select PARAVIRT
depends on X86_64 && PCI
depends on X86_EXTENDED_PLATFORM
#ifdef CONFIG_X86_32
extern void irq_ctx_init(int cpu);
-extern void irq_ctx_exit(int cpu);
#else
# define irq_ctx_init(cpu) do { } while (0)
-# define irq_ctx_exit(cpu) do { } while (0)
#endif
#define __ARCH_HAS_DO_SOFTIRQ
#define MSR_AMD64_IBSDCLINAD 0xc0011038
#define MSR_AMD64_IBSDCPHYSAD 0xc0011039
#define MSR_AMD64_IBSCTL 0xc001103a
+#define MSR_AMD64_IBSBRTARGET 0xc001103b
/* Fam 10h MSRs */
#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058
#define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16)
/* IbsFetchCtl bits/masks */
-#define IBS_FETCH_RAND_EN (1ULL<<57)
-#define IBS_FETCH_VAL (1ULL<<49)
-#define IBS_FETCH_ENABLE (1ULL<<48)
-#define IBS_FETCH_CNT 0xFFFF0000ULL
-#define IBS_FETCH_MAX_CNT 0x0000FFFFULL
+#define IBS_FETCH_RAND_EN (1ULL<<57)
+#define IBS_FETCH_VAL (1ULL<<49)
+#define IBS_FETCH_ENABLE (1ULL<<48)
+#define IBS_FETCH_CNT 0xFFFF0000ULL
+#define IBS_FETCH_MAX_CNT 0x0000FFFFULL
/* IbsOpCtl bits */
-#define IBS_OP_CNT_CTL (1ULL<<19)
-#define IBS_OP_VAL (1ULL<<18)
-#define IBS_OP_ENABLE (1ULL<<17)
-#define IBS_OP_MAX_CNT 0x0000FFFFULL
+#define IBS_OP_CNT_CTL (1ULL<<19)
+#define IBS_OP_VAL (1ULL<<18)
+#define IBS_OP_ENABLE (1ULL<<17)
+#define IBS_OP_MAX_CNT 0x0000FFFFULL
+#define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */
#ifdef CONFIG_PERF_EVENTS
extern void init_hw_perf_events(void);
void (*smp_prepare_cpus)(unsigned max_cpus);
void (*smp_cpus_done)(unsigned max_cpus);
- void (*smp_send_stop)(void);
+ void (*stop_other_cpus)(int wait);
void (*smp_send_reschedule)(int cpu);
int (*cpu_up)(unsigned cpu);
static inline void smp_send_stop(void)
{
- smp_ops.smp_send_stop();
+ smp_ops.stop_other_cpus(0);
+}
+
+static inline void stop_other_cpus(void)
+{
+ smp_ops.stop_other_cpus(1);
}
static inline void smp_prepare_boot_cpu(void)
* Intel DebugStore bits
*/
int bts, pebs;
+ int bts_active, pebs_active;
int pebs_record_size;
void (*drain_pebs)(struct pt_regs *regs);
struct event_constraint *pebs_constraints;
#endif
-static int reserve_ds_buffers(void);
+static void reserve_ds_buffers(void);
static void release_ds_buffers(void);
static void hw_perf_event_destroy(struct perf_event *event)
if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
(hwc->sample_period == 1)) {
/* BTS is not supported by this architecture. */
- if (!x86_pmu.bts)
+ if (!x86_pmu.bts_active)
return -EOPNOTSUPP;
/* BTS is currently only allowed for user-mode. */
int precise = 0;
/* Support for constant skid */
- if (x86_pmu.pebs)
+ if (x86_pmu.pebs_active) {
precise++;
- /* Support for IP fixup */
- if (x86_pmu.lbr_nr)
- precise++;
+ /* Support for IP fixup */
+ if (x86_pmu.lbr_nr)
+ precise++;
+ }
if (event->attr.precise_ip > precise)
return -EOPNOTSUPP;
if (atomic_read(&active_events) == 0) {
if (!reserve_pmc_hardware())
err = -EBUSY;
- else {
- err = reserve_ds_buffers();
- if (err)
- release_pmc_hardware();
- }
+ else
+ reserve_ds_buffers();
}
if (!err)
atomic_inc(&active_events);
wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
}
+static int alloc_pebs_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+ int node = cpu_to_node(cpu);
+ int max, thresh = 1; /* always use a single PEBS record */
+ void *buffer;
+
+ if (!x86_pmu.pebs)
+ return 0;
+
+ buffer = kmalloc_node(PEBS_BUFFER_SIZE, GFP_KERNEL | __GFP_ZERO, node);
+ if (unlikely(!buffer))
+ return -ENOMEM;
+
+ max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
+
+ ds->pebs_buffer_base = (u64)(unsigned long)buffer;
+ ds->pebs_index = ds->pebs_buffer_base;
+ ds->pebs_absolute_maximum = ds->pebs_buffer_base +
+ max * x86_pmu.pebs_record_size;
+
+ ds->pebs_interrupt_threshold = ds->pebs_buffer_base +
+ thresh * x86_pmu.pebs_record_size;
+
+ return 0;
+}
+
+static void release_pebs_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds || !x86_pmu.pebs)
+ return;
+
+ kfree((void *)(unsigned long)ds->pebs_buffer_base);
+ ds->pebs_buffer_base = 0;
+}
+
+static int alloc_bts_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+ int node = cpu_to_node(cpu);
+ int max, thresh;
+ void *buffer;
+
+ if (!x86_pmu.bts)
+ return 0;
+
+ buffer = kmalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_ZERO, node);
+ if (unlikely(!buffer))
+ return -ENOMEM;
+
+ max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
+ thresh = max / 16;
+
+ ds->bts_buffer_base = (u64)(unsigned long)buffer;
+ ds->bts_index = ds->bts_buffer_base;
+ ds->bts_absolute_maximum = ds->bts_buffer_base +
+ max * BTS_RECORD_SIZE;
+ ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
+ thresh * BTS_RECORD_SIZE;
+
+ return 0;
+}
+
+static void release_bts_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds || !x86_pmu.bts)
+ return;
+
+ kfree((void *)(unsigned long)ds->bts_buffer_base);
+ ds->bts_buffer_base = 0;
+}
+
+static int alloc_ds_buffer(int cpu)
+{
+ int node = cpu_to_node(cpu);
+ struct debug_store *ds;
+
+ ds = kmalloc_node(sizeof(*ds), GFP_KERNEL | __GFP_ZERO, node);
+ if (unlikely(!ds))
+ return -ENOMEM;
+
+ per_cpu(cpu_hw_events, cpu).ds = ds;
+
+ return 0;
+}
+
+static void release_ds_buffer(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds)
+ return;
+
+ per_cpu(cpu_hw_events, cpu).ds = NULL;
+ kfree(ds);
+}
+
static void release_ds_buffers(void)
{
int cpu;
return;
get_online_cpus();
-
for_each_online_cpu(cpu)
fini_debug_store_on_cpu(cpu);
for_each_possible_cpu(cpu) {
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
- if (!ds)
- continue;
-
- per_cpu(cpu_hw_events, cpu).ds = NULL;
-
- kfree((void *)(unsigned long)ds->pebs_buffer_base);
- kfree((void *)(unsigned long)ds->bts_buffer_base);
- kfree(ds);
+ release_pebs_buffer(cpu);
+ release_bts_buffer(cpu);
+ release_ds_buffer(cpu);
}
-
put_online_cpus();
}
-static int reserve_ds_buffers(void)
+static void reserve_ds_buffers(void)
{
- int cpu, err = 0;
+ int bts_err = 0, pebs_err = 0;
+ int cpu;
+
+ x86_pmu.bts_active = 0;
+ x86_pmu.pebs_active = 0;
if (!x86_pmu.bts && !x86_pmu.pebs)
- return 0;
+ return;
+
+ if (!x86_pmu.bts)
+ bts_err = 1;
+
+ if (!x86_pmu.pebs)
+ pebs_err = 1;
get_online_cpus();
for_each_possible_cpu(cpu) {
- struct debug_store *ds;
- void *buffer;
- int max, thresh;
+ if (alloc_ds_buffer(cpu)) {
+ bts_err = 1;
+ pebs_err = 1;
+ }
+
+ if (!bts_err && alloc_bts_buffer(cpu))
+ bts_err = 1;
- err = -ENOMEM;
- ds = kzalloc(sizeof(*ds), GFP_KERNEL);
- if (unlikely(!ds))
+ if (!pebs_err && alloc_pebs_buffer(cpu))
+ pebs_err = 1;
+
+ if (bts_err && pebs_err)
break;
- per_cpu(cpu_hw_events, cpu).ds = ds;
-
- if (x86_pmu.bts) {
- buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
- if (unlikely(!buffer))
- break;
-
- max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
- thresh = max / 16;
-
- ds->bts_buffer_base = (u64)(unsigned long)buffer;
- ds->bts_index = ds->bts_buffer_base;
- ds->bts_absolute_maximum = ds->bts_buffer_base +
- max * BTS_RECORD_SIZE;
- ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
- thresh * BTS_RECORD_SIZE;
- }
+ }
- if (x86_pmu.pebs) {
- buffer = kzalloc(PEBS_BUFFER_SIZE, GFP_KERNEL);
- if (unlikely(!buffer))
- break;
-
- max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
-
- ds->pebs_buffer_base = (u64)(unsigned long)buffer;
- ds->pebs_index = ds->pebs_buffer_base;
- ds->pebs_absolute_maximum = ds->pebs_buffer_base +
- max * x86_pmu.pebs_record_size;
- /*
- * Always use single record PEBS
- */
- ds->pebs_interrupt_threshold = ds->pebs_buffer_base +
- x86_pmu.pebs_record_size;
- }
+ if (bts_err) {
+ for_each_possible_cpu(cpu)
+ release_bts_buffer(cpu);
+ }
- err = 0;
+ if (pebs_err) {
+ for_each_possible_cpu(cpu)
+ release_pebs_buffer(cpu);
}
- if (err)
- release_ds_buffers();
- else {
+ if (bts_err && pebs_err) {
+ for_each_possible_cpu(cpu)
+ release_ds_buffer(cpu);
+ } else {
+ if (x86_pmu.bts && !bts_err)
+ x86_pmu.bts_active = 1;
+
+ if (x86_pmu.pebs && !pebs_err)
+ x86_pmu.pebs_active = 1;
+
for_each_online_cpu(cpu)
init_debug_store_on_cpu(cpu);
}
put_online_cpus();
-
- return err;
}
/*
if (!event)
return 0;
- if (!ds)
+ if (!x86_pmu.bts_active)
return 0;
at = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
struct pebs_record_core *at, *top;
int n;
- if (!ds || !x86_pmu.pebs)
+ if (!x86_pmu.pebs_active)
return;
at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
u64 status = 0;
int bit, n;
- if (!ds || !x86_pmu.pebs)
+ if (!x86_pmu.pebs_active)
return;
at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
#else /* CONFIG_CPU_SUP_INTEL */
-static int reserve_ds_buffers(void)
+static void reserve_ds_buffers(void)
{
- return 0;
}
static void release_ds_buffers(void)
if (kstack_end(stack))
break;
if (i && ((i % STACKSLOTS_PER_LINE) == 0))
- printk("\n%s", log_lvl);
- printk(" %08lx", *stack++);
+ printk(KERN_CONT "\n");
+ printk(KERN_CONT " %08lx", *stack++);
touch_nmi_watchdog();
}
- printk("\n");
+ printk(KERN_CONT "\n");
show_trace_log_lvl(task, regs, sp, bp, log_lvl);
}
if (stack >= irq_stack && stack <= irq_stack_end) {
if (stack == irq_stack_end) {
stack = (unsigned long *) (irq_stack_end[-1]);
- printk(" <EOI> ");
+ printk(KERN_CONT " <EOI> ");
}
} else {
if (((long) stack & (THREAD_SIZE-1)) == 0)
break;
}
if (i && ((i % STACKSLOTS_PER_LINE) == 0))
- printk("\n%s", log_lvl);
- printk(" %016lx", *stack++);
+ printk(KERN_CONT "\n");
+ printk(KERN_CONT " %016lx", *stack++);
touch_nmi_watchdog();
}
preempt_enable();
- printk("\n");
+ printk(KERN_CONT "\n");
show_trace_log_lvl(task, regs, sp, bp, log_lvl);
}
static DEFINE_PER_CPU(union irq_ctx *, hardirq_ctx);
static DEFINE_PER_CPU(union irq_ctx *, softirq_ctx);
-static DEFINE_PER_CPU_MULTIPAGE_ALIGNED(union irq_ctx, hardirq_stack, THREAD_SIZE);
-static DEFINE_PER_CPU_MULTIPAGE_ALIGNED(union irq_ctx, softirq_stack, THREAD_SIZE);
-
static void call_on_stack(void *func, void *stack)
{
asm volatile("xchgl %%ebx,%%esp \n"
if (per_cpu(hardirq_ctx, cpu))
return;
- irqctx = &per_cpu(hardirq_stack, cpu);
+ irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER);
irqctx->tinfo.task = NULL;
irqctx->tinfo.exec_domain = NULL;
irqctx->tinfo.cpu = cpu;
per_cpu(hardirq_ctx, cpu) = irqctx;
- irqctx = &per_cpu(softirq_stack, cpu);
+ irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER);
irqctx->tinfo.task = NULL;
irqctx->tinfo.exec_domain = NULL;
irqctx->tinfo.cpu = cpu;
cpu, per_cpu(hardirq_ctx, cpu), per_cpu(softirq_ctx, cpu));
}
-void irq_ctx_exit(int cpu)
-{
- per_cpu(hardirq_ctx, cpu) = NULL;
-}
-
asmlinkage void do_softirq(void)
{
unsigned long flags;
static const struct user_regset_view user_x86_32_view; /* Initialized below. */
#endif
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
unsigned long tmp;
ret = -EIO;
- if ((addr & (sizeof(data) - 1)) || addr < 0 ||
- addr >= sizeof(struct user))
+ if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user))
break;
tmp = 0; /* Default return condition */
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & (sizeof(data) - 1)) || addr < 0 ||
- addr >= sizeof(struct user))
+ if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user))
break;
if (addr < sizeof(struct user_regs_struct))
#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
case PTRACE_GET_THREAD_AREA:
- if (addr < 0)
+ if ((int) addr < 0)
return -EIO;
ret = do_get_thread_area(child, addr,
- (struct user_desc __user *) data);
+ (struct user_desc __user *)data);
break;
case PTRACE_SET_THREAD_AREA:
- if (addr < 0)
+ if ((int) addr < 0)
return -EIO;
ret = do_set_thread_area(child, addr,
- (struct user_desc __user *) data, 0);
+ (struct user_desc __user *)data, 0);
break;
#endif
/* O.K Now that I'm on the appropriate processor,
* stop all of the others.
*/
- smp_send_stop();
+ stop_other_cpus();
#endif
lapic_shutdown();
irq_exit();
}
-static void native_smp_send_stop(void)
+static void native_stop_other_cpus(int wait)
{
unsigned long flags;
- unsigned long wait;
+ unsigned long timeout;
if (reboot_force)
return;
if (num_online_cpus() > 1) {
apic->send_IPI_allbutself(REBOOT_VECTOR);
- /* Don't wait longer than a second */
- wait = USEC_PER_SEC;
- while (num_online_cpus() > 1 && wait--)
+ /*
+ * Don't wait longer than a second if the caller
+ * didn't ask us to wait.
+ */
+ timeout = USEC_PER_SEC;
+ while (num_online_cpus() > 1 && (wait || timeout--))
udelay(1);
}
.smp_prepare_cpus = native_smp_prepare_cpus,
.smp_cpus_done = native_smp_cpus_done,
- .smp_send_stop = native_smp_send_stop,
+ .stop_other_cpus = native_stop_other_cpus,
.smp_send_reschedule = native_smp_send_reschedule,
.cpu_up = native_cpu_up,
{
idle_task_exit();
reset_lazy_tlbstate();
- irq_ctx_exit(raw_smp_processor_id());
c1e_remove_cpu(raw_smp_processor_id());
mb();
vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) {
int idx, type;
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
idx = type + KM_TYPE_NR * smp_processor_id();
#ifdef CONFIG_DEBUG_HIGHMEM
* attributes or becomes a protected page in a hypervisor.
*/
kpte_clear_flush(kmap_pte-idx, vaddr);
+ kmap_atomic_idx_pop();
}
#ifdef CONFIG_DEBUG_HIGHMEM
else {
#include <asm/numa.h>
#include <asm/cacheflush.h>
#include <asm/init.h>
-#include <linux/bootmem.h>
static int __init parse_direct_gbpages_off(char *arg)
{
vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) {
int idx, type;
- type = kmap_atomic_idx_pop();
+ type = kmap_atomic_idx();
idx = type + KM_TYPE_NR * smp_processor_id();
#ifdef CONFIG_DEBUG_HIGHMEM
* attributes or becomes a protected page in a hypervisor.
*/
kpte_clear_flush(kmap_pte-idx, vaddr);
+ kmap_atomic_idx_pop();
}
pagefault_enable();
case 0x11:
cpu_type = "x86-64/family11h";
break;
+ case 0x12:
+ cpu_type = "x86-64/family12h";
+ break;
+ case 0x14:
+ cpu_type = "x86-64/family14h";
+ break;
default:
return -ENODEV;
}
static u32 ibs_caps;
-struct op_ibs_config {
+struct ibs_config {
unsigned long op_enabled;
unsigned long fetch_enabled;
unsigned long max_cnt_fetch;
unsigned long max_cnt_op;
unsigned long rand_en;
unsigned long dispatched_ops;
+ unsigned long branch_target;
};
-static struct op_ibs_config ibs_config;
-static u64 ibs_op_ctl;
+struct ibs_state {
+ u64 ibs_op_ctl;
+ int branch_target;
+ unsigned long sample_size;
+};
+
+static struct ibs_config ibs_config;
+static struct ibs_state ibs_state;
/*
* IBS cpuid feature detection
* bit 0 is used to indicate the existence of IBS.
*/
#define IBS_CAPS_AVAIL (1U<<0)
+#define IBS_CAPS_FETCHSAM (1U<<1)
+#define IBS_CAPS_OPSAM (1U<<2)
#define IBS_CAPS_RDWROPCNT (1U<<3)
#define IBS_CAPS_OPCNT (1U<<4)
+#define IBS_CAPS_BRNTRGT (1U<<5)
+#define IBS_CAPS_OPCNTEXT (1U<<6)
+
+#define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \
+ | IBS_CAPS_FETCHSAM \
+ | IBS_CAPS_OPSAM)
/*
* IBS APIC setup
/* check IBS cpuid feature flags */
max_level = cpuid_eax(0x80000000);
if (max_level < IBS_CPUID_FEATURES)
- return IBS_CAPS_AVAIL;
+ return IBS_CAPS_DEFAULT;
ibs_caps = cpuid_eax(IBS_CPUID_FEATURES);
if (!(ibs_caps & IBS_CAPS_AVAIL))
/* cpuid flags not valid */
- return IBS_CAPS_AVAIL;
+ return IBS_CAPS_DEFAULT;
return ibs_caps;
}
rdmsrl(MSR_AMD64_IBSOPCTL, ctl);
if (ctl & IBS_OP_VAL) {
rdmsrl(MSR_AMD64_IBSOPRIP, val);
- oprofile_write_reserve(&entry, regs, val,
- IBS_OP_CODE, IBS_OP_SIZE);
+ oprofile_write_reserve(&entry, regs, val, IBS_OP_CODE,
+ ibs_state.sample_size);
oprofile_add_data64(&entry, val);
rdmsrl(MSR_AMD64_IBSOPDATA, val);
oprofile_add_data64(&entry, val);
oprofile_add_data64(&entry, val);
rdmsrl(MSR_AMD64_IBSDCPHYSAD, val);
oprofile_add_data64(&entry, val);
+ if (ibs_state.branch_target) {
+ rdmsrl(MSR_AMD64_IBSBRTARGET, val);
+ oprofile_add_data(&entry, (unsigned long)val);
+ }
oprofile_write_commit(&entry);
/* reenable the IRQ */
- ctl = op_amd_randomize_ibs_op(ibs_op_ctl);
+ ctl = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl);
wrmsrl(MSR_AMD64_IBSOPCTL, ctl);
}
}
if (!ibs_caps)
return;
+ memset(&ibs_state, 0, sizeof(ibs_state));
+
+ /*
+ * Note: Since the max count settings may out of range we
+ * write back the actual used values so that userland can read
+ * it.
+ */
+
if (ibs_config.fetch_enabled) {
- val = (ibs_config.max_cnt_fetch >> 4) & IBS_FETCH_MAX_CNT;
+ val = ibs_config.max_cnt_fetch >> 4;
+ val = min(val, IBS_FETCH_MAX_CNT);
+ ibs_config.max_cnt_fetch = val << 4;
val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0;
val |= IBS_FETCH_ENABLE;
wrmsrl(MSR_AMD64_IBSFETCHCTL, val);
}
if (ibs_config.op_enabled) {
- ibs_op_ctl = ibs_config.max_cnt_op >> 4;
+ val = ibs_config.max_cnt_op >> 4;
if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) {
/*
* IbsOpCurCnt not supported. See
* op_amd_randomize_ibs_op() for details.
*/
- ibs_op_ctl = clamp(ibs_op_ctl, 0x0081ULL, 0xFF80ULL);
+ val = clamp(val, 0x0081ULL, 0xFF80ULL);
+ ibs_config.max_cnt_op = val << 4;
} else {
/*
* The start value is randomized with a
* with the half of the randomized range. Also
* avoid underflows.
*/
- ibs_op_ctl = min(ibs_op_ctl + IBS_RANDOM_MAXCNT_OFFSET,
- IBS_OP_MAX_CNT);
+ val += IBS_RANDOM_MAXCNT_OFFSET;
+ if (ibs_caps & IBS_CAPS_OPCNTEXT)
+ val = min(val, IBS_OP_MAX_CNT_EXT);
+ else
+ val = min(val, IBS_OP_MAX_CNT);
+ ibs_config.max_cnt_op =
+ (val - IBS_RANDOM_MAXCNT_OFFSET) << 4;
+ }
+ val = ((val & ~IBS_OP_MAX_CNT) << 4) | (val & IBS_OP_MAX_CNT);
+ val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0;
+ val |= IBS_OP_ENABLE;
+ ibs_state.ibs_op_ctl = val;
+ ibs_state.sample_size = IBS_OP_SIZE;
+ if (ibs_config.branch_target) {
+ ibs_state.branch_target = 1;
+ ibs_state.sample_size++;
}
- if (ibs_caps & IBS_CAPS_OPCNT && ibs_config.dispatched_ops)
- ibs_op_ctl |= IBS_OP_CNT_CTL;
- ibs_op_ctl |= IBS_OP_ENABLE;
- val = op_amd_randomize_ibs_op(ibs_op_ctl);
+ val = op_amd_randomize_ibs_op(ibs_state.ibs_op_ctl);
wrmsrl(MSR_AMD64_IBSOPCTL, val);
}
}
static inline int ibs_eilvt_valid(void)
{
- u64 val;
int offset;
+ u64 val;
rdmsrl(MSR_AMD64_IBSCTL, val);
+ offset = val & IBSCTL_LVT_OFFSET_MASK;
+
if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
- pr_err(FW_BUG "cpu %d, invalid IBS "
- "interrupt offset %d (MSR%08X=0x%016llx)",
- smp_processor_id(), offset,
- MSR_AMD64_IBSCTL, val);
+ pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
+ smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
return 0;
}
- offset = val & IBSCTL_LVT_OFFSET_MASK;
-
- if (eilvt_is_available(offset))
- return !0;
-
- pr_err(FW_BUG "cpu %d, IBS interrupt offset %d "
- "not available (MSR%08X=0x%016llx)",
- smp_processor_id(), offset,
- MSR_AMD64_IBSCTL, val);
+ if (!eilvt_is_available(offset)) {
+ pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
+ smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
+ return 0;
+ }
- return 0;
+ return 1;
}
static inline int get_ibs_offset(void)
/* model specific files */
/* setup some reasonable defaults */
+ memset(&ibs_config, 0, sizeof(ibs_config));
ibs_config.max_cnt_fetch = 250000;
- ibs_config.fetch_enabled = 0;
ibs_config.max_cnt_op = 250000;
- ibs_config.op_enabled = 0;
- ibs_config.dispatched_ops = 0;
-
- dir = oprofilefs_mkdir(sb, root, "ibs_fetch");
- oprofilefs_create_ulong(sb, dir, "enable",
- &ibs_config.fetch_enabled);
- oprofilefs_create_ulong(sb, dir, "max_count",
- &ibs_config.max_cnt_fetch);
- oprofilefs_create_ulong(sb, dir, "rand_enable",
- &ibs_config.rand_en);
-
- dir = oprofilefs_mkdir(sb, root, "ibs_op");
- oprofilefs_create_ulong(sb, dir, "enable",
- &ibs_config.op_enabled);
- oprofilefs_create_ulong(sb, dir, "max_count",
- &ibs_config.max_cnt_op);
- if (ibs_caps & IBS_CAPS_OPCNT)
- oprofilefs_create_ulong(sb, dir, "dispatched_ops",
- &ibs_config.dispatched_ops);
+
+ if (ibs_caps & IBS_CAPS_FETCHSAM) {
+ dir = oprofilefs_mkdir(sb, root, "ibs_fetch");
+ oprofilefs_create_ulong(sb, dir, "enable",
+ &ibs_config.fetch_enabled);
+ oprofilefs_create_ulong(sb, dir, "max_count",
+ &ibs_config.max_cnt_fetch);
+ oprofilefs_create_ulong(sb, dir, "rand_enable",
+ &ibs_config.rand_en);
+ }
+
+ if (ibs_caps & IBS_CAPS_OPSAM) {
+ dir = oprofilefs_mkdir(sb, root, "ibs_op");
+ oprofilefs_create_ulong(sb, dir, "enable",
+ &ibs_config.op_enabled);
+ oprofilefs_create_ulong(sb, dir, "max_count",
+ &ibs_config.max_cnt_op);
+ if (ibs_caps & IBS_CAPS_OPCNT)
+ oprofilefs_create_ulong(sb, dir, "dispatched_ops",
+ &ibs_config.dispatched_ops);
+ if (ibs_caps & IBS_CAPS_BRNTRGT)
+ oprofilefs_create_ulong(sb, dir, "branch_target",
+ &ibs_config.branch_target);
+ }
return 0;
}
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/reboot.h>
-#include <asm/setup.h>
#include <asm/stackprotector.h>
#include <asm/hypervisor.h>
struct sched_shutdown r = { .reason = reason };
#ifdef CONFIG_SMP
- smp_send_stop();
+ stop_other_cpus();
#endif
if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
BUG();
}
-static void xen_smp_send_stop(void)
+static void xen_stop_other_cpus(int wait)
{
- smp_call_function(stop_self, NULL, 0);
+ smp_call_function(stop_self, NULL, wait);
}
static void xen_smp_send_reschedule(int cpu)
.cpu_disable = xen_cpu_disable,
.play_dead = xen_play_dead,
- .smp_send_stop = xen_smp_send_stop,
+ .stop_other_cpus = xen_stop_other_cpus,
.smp_send_reschedule = xen_smp_send_reschedule,
.send_call_func_ipi = xen_smp_send_call_function_ipi,
return 0;
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
int ret = -EPERM;
+ void __user *datap = (void __user *) data;
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
break;
case PTRACE_PEEKUSR: /* read register specified by addr. */
- ret = ptrace_peekusr(child, addr, (void __user *) data);
+ ret = ptrace_peekusr(child, addr, datap);
break;
case PTRACE_POKETEXT: /* write the word at location addr. */
break;
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, (void __user *) data);
+ ret = ptrace_getregs(child, datap);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, (void __user *) data);
+ ret = ptrace_setregs(child, datap);
break;
case PTRACE_GETXTREGS:
- ret = ptrace_getxregs(child, (void __user *) data);
+ ret = ptrace_getxregs(child, datap);
break;
case PTRACE_SETXTREGS:
- ret = ptrace_setxregs(child, (void __user *) data);
+ ret = ptrace_setxregs(child, datap);
break;
default:
eprom = (base+EPROM_SIZE-sizeof(struct midway_eprom));
if (readl(&eprom->magic) != ENI155_MAGIC) {
printk("\n");
- printk(KERN_ERR KERN_ERR DEV_LABEL "(itf %d): bad "
- "magic - expected 0x%x, got 0x%x\n",dev->number,
- ENI155_MAGIC,(unsigned) readl(&eprom->magic));
+ printk(KERN_ERR DEV_LABEL
+ "(itf %d): bad magic - expected 0x%x, got 0x%x\n",
+ dev->number, ENI155_MAGIC,
+ (unsigned)readl(&eprom->magic));
error = -EINVAL;
goto unmap;
}
struct mailbox mailbox;
/* Got a packet for us */
+ memset(&st_loc, 0, sizeof(st_loc));
ret = do_ac_read(i, buf, &st_loc, &mailbox);
spin_unlock_irqrestore(&apbs[i].mutex, flags);
set_current_state(TASK_RUNNING);
struct hvc_struct *hp;
set_freezable();
- __set_current_state(TASK_RUNNING);
do {
poll_mask = 0;
hvc_kicked = 0;
obj-$(CONFIG_COMPUTONE) += ip2.o
-ip2-objs := ip2main.o
+ip2-y := ip2main.o
# Makefile for the ipmi drivers.
#
-ipmi_si-objs := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o
+ipmi_si-y := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o
obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o
obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
.smi_gone = ipmi_smi_gone,
};
-static __init int init_ipmi_devintf(void)
+static int __init init_ipmi_devintf(void)
{
int rv;
}
module_init(init_ipmi_devintf);
-static __exit void cleanup_ipmi(void)
+static void __exit cleanup_ipmi(void)
{
struct ipmi_reg_list *entry, *entry2;
mutex_lock(®_list_mutex);
return 0;
}
-static __init int ipmi_init_msghandler_mod(void)
+static int __init ipmi_init_msghandler_mod(void)
{
ipmi_init_msghandler();
return 0;
}
-static __exit void cleanup_ipmi(void)
+static void __exit cleanup_ipmi(void)
{
int count;
return rv;
}
-static __devinit void hardcode_find_bmc(void)
+static void __devinit hardcode_find_bmc(void)
{
int i;
struct smi_info *info;
s8 spmi_id[1]; /* A '\0' terminated array starts here. */
};
-static __devinit int try_init_spmi(struct SPMITable *spmi)
+static int __devinit try_init_spmi(struct SPMITable *spmi)
{
struct smi_info *info;
return 0;
}
-static __devinit void spmi_find_bmc(void)
+static void __devinit spmi_find_bmc(void)
{
acpi_status status;
struct SPMITable *spmi;
return 0;
}
-static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
+static void __devinit try_init_dmi(struct dmi_ipmi_data *ipmi_data)
{
struct smi_info *info;
{ .port = 0 }
};
-static __devinit void default_find_bmc(void)
+static void __devinit default_find_bmc(void)
{
struct smi_info *info;
int i;
return rv;
}
-static __devinit int init_ipmi_si(void)
+static int __devinit init_ipmi_si(void)
{
int i;
char *str;
kfree(to_clean);
}
-static __exit void cleanup_ipmi_si(void)
+static void __exit cleanup_ipmi_si(void)
{
struct smi_info *e, *tmp_e;
* in order to insure that the setup succeeds in a deterministic time frame.
* It will check if the interrupt setup succeeded.
*/
-static int mmtimer_setup(int cpu, int comparator, unsigned long expires)
+static int mmtimer_setup(int cpu, int comparator, unsigned long expires,
+ u64 *set_completion_time)
{
-
switch (comparator) {
case 0:
mmtimer_setup_int_0(cpu, expires);
break;
}
/* We might've missed our expiration time */
- if (rtc_time() <= expires)
+ *set_completion_time = rtc_time();
+ if (*set_completion_time <= expires)
return 1;
/*
#define TIMER_OFF 0xbadcabLL /* Timer is not setup */
#define TIMER_SET 0 /* Comparator is set for this timer */
+#define MMTIMER_INTERVAL_RETRY_INCREMENT_DEFAULT 40
+
/* There is one of these for each timer */
struct mmtimer {
struct rb_node list;
};
static struct mmtimer_node *timers;
+static unsigned mmtimer_interval_retry_increment =
+ MMTIMER_INTERVAL_RETRY_INCREMENT_DEFAULT;
+module_param(mmtimer_interval_retry_increment, uint, 0644);
+MODULE_PARM_DESC(mmtimer_interval_retry_increment,
+ "RTC ticks to add to expiration on interval retry (default 40)");
/*
* Add a new mmtimer struct to the node's mmtimer list.
struct mmtimer_node *n = &timers[nodeid];
struct mmtimer *x;
struct k_itimer *t;
- int o;
+ u64 expires, exp, set_completion_time;
+ int i;
restart:
if (n->next == NULL)
if (!t->it.mmtimer.incr) {
/* Not an interval timer */
if (!mmtimer_setup(x->cpu, COMPARATOR,
- t->it.mmtimer.expires)) {
+ t->it.mmtimer.expires,
+ &set_completion_time)) {
/* Late setup, fire now */
tasklet_schedule(&n->tasklet);
}
}
/* Interval timer */
- o = 0;
- while (!mmtimer_setup(x->cpu, COMPARATOR, t->it.mmtimer.expires)) {
- unsigned long e, e1;
- struct rb_node *next;
- t->it.mmtimer.expires += t->it.mmtimer.incr << o;
- t->it_overrun += 1 << o;
- o++;
- if (o > 20) {
+ i = 0;
+ expires = exp = t->it.mmtimer.expires;
+ while (!mmtimer_setup(x->cpu, COMPARATOR, expires,
+ &set_completion_time)) {
+ int to;
+
+ i++;
+ expires = set_completion_time +
+ mmtimer_interval_retry_increment + (1 << i);
+ /* Calculate overruns as we go. */
+ to = ((u64)(expires - exp) / t->it.mmtimer.incr);
+ if (to) {
+ t->it_overrun += to;
+ t->it.mmtimer.expires += t->it.mmtimer.incr * to;
+ exp = t->it.mmtimer.expires;
+ }
+ if (i > 20) {
printk(KERN_ALERT "mmtimer: cannot reschedule timer\n");
t->it.mmtimer.clock = TIMER_OFF;
n->next = rb_next(&x->list);
kfree(x);
goto restart;
}
-
- e = t->it.mmtimer.expires;
- next = rb_next(&x->list);
-
- if (next == NULL)
- continue;
-
- e1 = rb_entry(next, struct mmtimer, list)->
- timer->it.mmtimer.expires;
- if (e > e1) {
- n->next = next;
- rb_erase(&x->list, &n->timer_head);
- mmtimer_add_list(x);
- goto restart;
- }
}
}
obj-$(CONFIG_MWAVE) += mwave.o
-mwave-objs := mwavedd.o smapi.o tp3780i.o 3780i.o
+mwave-y := mwavedd.o smapi.o tp3780i.o 3780i.o
# To have the mwave driver disable other uarts if necessary
# EXTRA_CFLAGS += -DMWAVE_FUTZ_WITH_OTHER_DEVICES
# To compile in lots (~20 KiB) of run-time enablable printk()s for debugging:
-EXTRA_CFLAGS += -DMW_TRACE
+ccflags-y := -DMW_TRACE
outb(oldlcr, baseio + UART_LCR);
}
+#ifdef CONFIG_PCI
static void mxser_disable_must_enchance_mode(unsigned long baseio)
{
u8 oldlcr;
outb(efr, baseio + MOXA_MUST_EFR_REGISTER);
outb(oldlcr, baseio + UART_LCR);
}
+#endif
static void mxser_set_must_xon1_value(unsigned long baseio, u8 value)
{
outb(oldlcr, baseio + UART_LCR);
}
+#ifdef CONFIG_PCI
static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId)
{
u8 oldlcr;
*pId = inb(baseio + MOXA_MUST_HWID_REGISTER);
outb(oldlcr, baseio + UART_LCR);
}
+#endif
static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio)
{
obj-$(CONFIG_IPWIRELESS) += ipwireless.o
-ipwireless-objs := hardware.o main.o network.o tty.o
+ipwireless-y := hardware.o main.o network.o tty.o
case PPGETTIME:
to_jiffies = pp->pdev->timeout;
+ memset(&par_timeout, 0, sizeof(par_timeout));
par_timeout.tv_sec = to_jiffies / HZ;
par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ);
if (copy_to_user (argp, &par_timeout, sizeof(struct timeval)))
#include <linux/time.h>
#include <linux/io.h>
#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/ramoops.h>
#define RAMOOPS_KERNMSG_HDR "===="
#define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval))
cxt->count = (cxt->count + 1) % cxt->max_count;
}
-static int __init ramoops_init(void)
+static int __init ramoops_probe(struct platform_device *pdev)
{
+ struct ramoops_platform_data *pdata = pdev->dev.platform_data;
struct ramoops_context *cxt = &oops_cxt;
int err = -EINVAL;
+ if (pdata) {
+ mem_size = pdata->mem_size;
+ mem_address = pdata->mem_address;
+ }
+
if (!mem_size) {
printk(KERN_ERR "ramoops: invalid size specification");
goto fail3;
return err;
}
-static void __exit ramoops_exit(void)
+static int __exit ramoops_remove(struct platform_device *pdev)
{
struct ramoops_context *cxt = &oops_cxt;
iounmap(cxt->virt_addr);
release_mem_region(cxt->phys_addr, cxt->size);
+ return 0;
}
+static struct platform_driver ramoops_driver = {
+ .remove = __exit_p(ramoops_remove),
+ .driver = {
+ .name = "ramoops",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ramoops_init(void)
+{
+ return platform_driver_probe(&ramoops_driver, ramoops_probe);
+}
+
+static void __exit ramoops_exit(void)
+{
+ platform_driver_unregister(&ramoops_driver);
+}
module_init(ramoops_init);
module_exit(ramoops_exit);
obj-$(CONFIG_RIO) += rio.o
-rio-objs := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \
+rio-y := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \
rioparam.o rioroute.o riotable.o riotty.o
ret = tty_register_driver(rocket_driver);
if (ret < 0) {
printk(KERN_ERR "Couldn't install tty RocketPort driver\n");
- goto err_tty;
+ goto err_controller;
}
#ifdef ROCKET_DEBUG_OPEN