Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: arch/tile: mark "hardwall" device as non-seekable asm-generic/stat.h: support 64-bit file time_t for stat() arch/tile: don't allow user code to set the PL via ptrace or signal return arch/tile: correct double syscall restart for nested signals arch/tile: avoid __must_check warning on one strict_strtol check arch/tile: bomb raw_local_irq_ to arch_local_irq_ arch/tile: complete migration to new kmap_atomic scheme
This commit is contained in:
commit
0660a9b16a
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
#include <asm/kmap_types.h>
|
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/homecache.h>
|
#include <asm/homecache.h>
|
||||||
|
|
||||||
|
@ -16,28 +16,42 @@
|
|||||||
#define _ASM_TILE_KMAP_TYPES_H
|
#define _ASM_TILE_KMAP_TYPES_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In TILE Linux each set of four of these uses another 16MB chunk of
|
* In 32-bit TILE Linux we have to balance the desire to have a lot of
|
||||||
* address space, given 64 tiles and 64KB pages, so we only enable
|
* nested atomic mappings with the fact that large page sizes and many
|
||||||
* ones that are required by the kernel configuration.
|
* processors chew up address space quickly. In a typical
|
||||||
|
* 64-processor, 64KB-page layout build, making KM_TYPE_NR one larger
|
||||||
|
* adds 4MB of required address-space. For now we leave KM_TYPE_NR
|
||||||
|
* set to depth 8.
|
||||||
*/
|
*/
|
||||||
enum km_type {
|
enum km_type {
|
||||||
|
KM_TYPE_NR = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We provide dummy definitions of all the stray values that used to be
|
||||||
|
* required for kmap_atomic() and no longer are.
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
KM_BOUNCE_READ,
|
KM_BOUNCE_READ,
|
||||||
KM_SKB_SUNRPC_DATA,
|
KM_SKB_SUNRPC_DATA,
|
||||||
KM_SKB_DATA_SOFTIRQ,
|
KM_SKB_DATA_SOFTIRQ,
|
||||||
KM_USER0,
|
KM_USER0,
|
||||||
KM_USER1,
|
KM_USER1,
|
||||||
KM_BIO_SRC_IRQ,
|
KM_BIO_SRC_IRQ,
|
||||||
|
KM_BIO_DST_IRQ,
|
||||||
|
KM_PTE0,
|
||||||
|
KM_PTE1,
|
||||||
KM_IRQ0,
|
KM_IRQ0,
|
||||||
KM_IRQ1,
|
KM_IRQ1,
|
||||||
KM_SOFTIRQ0,
|
KM_SOFTIRQ0,
|
||||||
KM_SOFTIRQ1,
|
KM_SOFTIRQ1,
|
||||||
KM_MEMCPY0,
|
KM_SYNC_ICACHE,
|
||||||
KM_MEMCPY1,
|
KM_SYNC_DCACHE,
|
||||||
#if defined(CONFIG_HIGHPTE)
|
KM_UML_USERCOPY,
|
||||||
KM_PTE0,
|
KM_IRQ_PTE,
|
||||||
KM_PTE1,
|
KM_NMI,
|
||||||
#endif
|
KM_NMI_PTE,
|
||||||
KM_TYPE_NR
|
KM_KDB
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _ASM_TILE_KMAP_TYPES_H */
|
#endif /* _ASM_TILE_KMAP_TYPES_H */
|
||||||
|
@ -344,10 +344,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
|||||||
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
|
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
|
||||||
|
|
||||||
#if defined(CONFIG_HIGHPTE)
|
#if defined(CONFIG_HIGHPTE)
|
||||||
extern pte_t *_pte_offset_map(pmd_t *, unsigned long address, enum km_type);
|
extern pte_t *pte_offset_map(pmd_t *, unsigned long address);
|
||||||
#define pte_offset_map(dir, address) \
|
#define pte_unmap(pte) kunmap_atomic(pte)
|
||||||
_pte_offset_map(dir, address, KM_PTE0)
|
|
||||||
#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
|
|
||||||
#else
|
#else
|
||||||
#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
|
#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
|
||||||
#define pte_unmap(pte) do { } while (0)
|
#define pte_unmap(pte) do { } while (0)
|
||||||
|
@ -1 +1,4 @@
|
|||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
#define __ARCH_WANT_STAT64 /* Used for compat_sys_stat64() etc. */
|
||||||
|
#endif
|
||||||
#include <asm-generic/stat.h>
|
#include <asm-generic/stat.h>
|
||||||
|
@ -41,6 +41,7 @@ __SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr)
|
|||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
#define __ARCH_WANT_SYS_LLSEEK
|
#define __ARCH_WANT_SYS_LLSEEK
|
||||||
#endif
|
#endif
|
||||||
|
#define __ARCH_WANT_SYS_NEWFSTATAT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _ASM_TILE_UNISTD_H */
|
#endif /* _ASM_TILE_UNISTD_H */
|
||||||
|
@ -148,11 +148,11 @@ long tile_compat_sys_msgrcv(int msqid,
|
|||||||
#define compat_sys_readahead sys32_readahead
|
#define compat_sys_readahead sys32_readahead
|
||||||
#define compat_sys_sync_file_range compat_sys_sync_file_range2
|
#define compat_sys_sync_file_range compat_sys_sync_file_range2
|
||||||
|
|
||||||
/* The native 64-bit "struct stat" matches the 32-bit "struct stat64". */
|
/* We leverage the "struct stat64" type for 32-bit time_t/nsec. */
|
||||||
#define compat_sys_stat64 sys_newstat
|
#define compat_sys_stat64 sys_stat64
|
||||||
#define compat_sys_lstat64 sys_newlstat
|
#define compat_sys_lstat64 sys_lstat64
|
||||||
#define compat_sys_fstat64 sys_newfstat
|
#define compat_sys_fstat64 sys_fstat64
|
||||||
#define compat_sys_fstatat64 sys_newfstatat
|
#define compat_sys_fstatat64 sys_fstatat64
|
||||||
|
|
||||||
/* The native sys_ptrace dynamically handles compat binaries. */
|
/* The native sys_ptrace dynamically handles compat binaries. */
|
||||||
#define compat_sys_ptrace sys_ptrace
|
#define compat_sys_ptrace sys_ptrace
|
||||||
|
@ -54,7 +54,7 @@ void early_printk(const char *fmt, ...)
|
|||||||
void early_panic(const char *fmt, ...)
|
void early_panic(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
raw_local_irq_disable_all();
|
arch_local_irq_disable_all();
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
early_printk("Kernel panic - not syncing: ");
|
early_printk("Kernel panic - not syncing: ");
|
||||||
early_vprintk(fmt, ap);
|
early_vprintk(fmt, ap);
|
||||||
|
@ -151,12 +151,12 @@ enum direction_protect {
|
|||||||
|
|
||||||
static void enable_firewall_interrupts(void)
|
static void enable_firewall_interrupts(void)
|
||||||
{
|
{
|
||||||
raw_local_irq_unmask_now(INT_UDN_FIREWALL);
|
arch_local_irq_unmask_now(INT_UDN_FIREWALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disable_firewall_interrupts(void)
|
static void disable_firewall_interrupts(void)
|
||||||
{
|
{
|
||||||
raw_local_irq_mask_now(INT_UDN_FIREWALL);
|
arch_local_irq_mask_now(INT_UDN_FIREWALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up hardwall on this cpu based on the passed hardwall_info. */
|
/* Set up hardwall on this cpu based on the passed hardwall_info. */
|
||||||
@ -768,13 +768,13 @@ static int hardwall_release(struct inode *inode, struct file *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations dev_hardwall_fops = {
|
static const struct file_operations dev_hardwall_fops = {
|
||||||
|
.open = nonseekable_open,
|
||||||
.unlocked_ioctl = hardwall_ioctl,
|
.unlocked_ioctl = hardwall_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
.compat_ioctl = hardwall_compat_ioctl,
|
.compat_ioctl = hardwall_compat_ioctl,
|
||||||
#endif
|
#endif
|
||||||
.flush = hardwall_flush,
|
.flush = hardwall_flush,
|
||||||
.release = hardwall_release,
|
.release = hardwall_release,
|
||||||
.llseek = noop_llseek,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cdev hardwall_dev;
|
static struct cdev hardwall_dev;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#define IS_HW_CLEARED 1
|
#define IS_HW_CLEARED 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The set of interrupts we enable for raw_local_irq_enable().
|
* The set of interrupts we enable for arch_local_irq_enable().
|
||||||
* This is initialized to have just a single interrupt that the kernel
|
* This is initialized to have just a single interrupt that the kernel
|
||||||
* doesn't actually use as a sentinel. During kernel init,
|
* doesn't actually use as a sentinel. During kernel init,
|
||||||
* interrupts are added as the kernel gets prepared to support them.
|
* interrupts are added as the kernel gets prepared to support them.
|
||||||
@ -225,7 +225,7 @@ void __cpuinit setup_irq_regs(void)
|
|||||||
/* Enable interrupt delivery. */
|
/* Enable interrupt delivery. */
|
||||||
unmask_irqs(~0UL);
|
unmask_irqs(~0UL);
|
||||||
#if CHIP_HAS_IPI()
|
#if CHIP_HAS_IPI()
|
||||||
raw_local_irq_unmask(INT_IPI_K);
|
arch_local_irq_unmask(INT_IPI_K);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,13 +182,13 @@ static void kexec_find_and_set_command_line(struct kimage *image)
|
|||||||
|
|
||||||
if ((entry & IND_SOURCE)) {
|
if ((entry & IND_SOURCE)) {
|
||||||
void *va =
|
void *va =
|
||||||
kmap_atomic_pfn(entry >> PAGE_SHIFT, KM_USER0);
|
kmap_atomic_pfn(entry >> PAGE_SHIFT);
|
||||||
r = kexec_bn2cl(va);
|
r = kexec_bn2cl(va);
|
||||||
if (r) {
|
if (r) {
|
||||||
command_line = r;
|
command_line = r;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
kunmap_atomic(va, KM_USER0);
|
kunmap_atomic(va);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ static void kexec_find_and_set_command_line(struct kimage *image)
|
|||||||
|
|
||||||
hverr = hv_set_command_line(
|
hverr = hv_set_command_line(
|
||||||
(HV_VirtAddr) command_line, strlen(command_line));
|
(HV_VirtAddr) command_line, strlen(command_line));
|
||||||
kunmap_atomic(command_line, KM_USER0);
|
kunmap_atomic(command_line);
|
||||||
} else {
|
} else {
|
||||||
pr_info("%s: no command line found; making empty\n",
|
pr_info("%s: no command line found; making empty\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -34,7 +34,7 @@ void __cpuinit init_messaging(void)
|
|||||||
panic("hv_register_message_state: error %d", rc);
|
panic("hv_register_message_state: error %d", rc);
|
||||||
|
|
||||||
/* Make sure downcall interrupts will be enabled. */
|
/* Make sure downcall interrupts will be enabled. */
|
||||||
raw_local_irq_unmask(INT_INTCTRL_K);
|
arch_local_irq_unmask(INT_INTCTRL_K);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hv_message_intr(struct pt_regs *regs, int intnum)
|
void hv_message_intr(struct pt_regs *regs, int intnum)
|
||||||
|
@ -50,10 +50,10 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||||||
{
|
{
|
||||||
unsigned long __user *datap = (long __user __force *)data;
|
unsigned long __user *datap = (long __user __force *)data;
|
||||||
unsigned long tmp;
|
unsigned long tmp;
|
||||||
int i;
|
|
||||||
long ret = -EIO;
|
long ret = -EIO;
|
||||||
unsigned long *childregs;
|
|
||||||
char *childreg;
|
char *childreg;
|
||||||
|
struct pt_regs copyregs;
|
||||||
|
int ex1_offset;
|
||||||
|
|
||||||
switch (request) {
|
switch (request) {
|
||||||
|
|
||||||
@ -80,6 +80,16 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||||||
if (addr >= PTREGS_SIZE)
|
if (addr >= PTREGS_SIZE)
|
||||||
break;
|
break;
|
||||||
childreg = (char *)task_pt_regs(child) + addr;
|
childreg = (char *)task_pt_regs(child) + addr;
|
||||||
|
|
||||||
|
/* Guard against overwrites of the privilege level. */
|
||||||
|
ex1_offset = PTREGS_OFFSET_EX1;
|
||||||
|
#if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN)
|
||||||
|
if (is_compat_task()) /* point at low word */
|
||||||
|
ex1_offset += sizeof(compat_long_t);
|
||||||
|
#endif
|
||||||
|
if (addr == ex1_offset)
|
||||||
|
data = PL_ICS_EX1(USER_PL, EX1_ICS(data));
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
if (is_compat_task()) {
|
if (is_compat_task()) {
|
||||||
if (addr & (sizeof(compat_long_t)-1))
|
if (addr & (sizeof(compat_long_t)-1))
|
||||||
@ -96,26 +106,19 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PTRACE_GETREGS: /* Get all registers from the child. */
|
case PTRACE_GETREGS: /* Get all registers from the child. */
|
||||||
if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE))
|
if (copy_to_user(datap, task_pt_regs(child),
|
||||||
break;
|
sizeof(struct pt_regs)) == 0) {
|
||||||
childregs = (long *)task_pt_regs(child);
|
ret = 0;
|
||||||
for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long);
|
|
||||||
++i) {
|
|
||||||
ret = __put_user(childregs[i], &datap[i]);
|
|
||||||
if (ret != 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PTRACE_SETREGS: /* Set all registers in the child. */
|
case PTRACE_SETREGS: /* Set all registers in the child. */
|
||||||
if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE))
|
if (copy_from_user(©regs, datap,
|
||||||
break;
|
sizeof(struct pt_regs)) == 0) {
|
||||||
childregs = (long *)task_pt_regs(child);
|
copyregs.ex1 =
|
||||||
for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long);
|
PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1));
|
||||||
++i) {
|
*task_pt_regs(child) = copyregs;
|
||||||
ret = __get_user(childregs[i], &datap[i]);
|
ret = 0;
|
||||||
if (ret != 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
void machine_halt(void)
|
void machine_halt(void)
|
||||||
{
|
{
|
||||||
warn_early_printk();
|
warn_early_printk();
|
||||||
raw_local_irq_disable_all();
|
arch_local_irq_disable_all();
|
||||||
smp_send_stop();
|
smp_send_stop();
|
||||||
hv_halt();
|
hv_halt();
|
||||||
}
|
}
|
||||||
@ -35,14 +35,14 @@ void machine_halt(void)
|
|||||||
void machine_power_off(void)
|
void machine_power_off(void)
|
||||||
{
|
{
|
||||||
warn_early_printk();
|
warn_early_printk();
|
||||||
raw_local_irq_disable_all();
|
arch_local_irq_disable_all();
|
||||||
smp_send_stop();
|
smp_send_stop();
|
||||||
hv_power_off();
|
hv_power_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
void machine_restart(char *cmd)
|
void machine_restart(char *cmd)
|
||||||
{
|
{
|
||||||
raw_local_irq_disable_all();
|
arch_local_irq_disable_all();
|
||||||
smp_send_stop();
|
smp_send_stop();
|
||||||
hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd);
|
hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd);
|
||||||
}
|
}
|
||||||
|
@ -868,14 +868,14 @@ void __cpuinit setup_cpu(int boot)
|
|||||||
|
|
||||||
/* Allow asynchronous TLB interrupts. */
|
/* Allow asynchronous TLB interrupts. */
|
||||||
#if CHIP_HAS_TILE_DMA()
|
#if CHIP_HAS_TILE_DMA()
|
||||||
raw_local_irq_unmask(INT_DMATLB_MISS);
|
arch_local_irq_unmask(INT_DMATLB_MISS);
|
||||||
raw_local_irq_unmask(INT_DMATLB_ACCESS);
|
arch_local_irq_unmask(INT_DMATLB_ACCESS);
|
||||||
#endif
|
#endif
|
||||||
#if CHIP_HAS_SN_PROC()
|
#if CHIP_HAS_SN_PROC()
|
||||||
raw_local_irq_unmask(INT_SNITLB_MISS);
|
arch_local_irq_unmask(INT_SNITLB_MISS);
|
||||||
#endif
|
#endif
|
||||||
#ifdef __tilegx__
|
#ifdef __tilegx__
|
||||||
raw_local_irq_unmask(INT_SINGLE_STEP_K);
|
arch_local_irq_unmask(INT_SINGLE_STEP_K);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -71,6 +71,9 @@ int restore_sigcontext(struct pt_regs *regs,
|
|||||||
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
|
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
|
||||||
err |= __get_user(regs->regs[i], &sc->gregs[i]);
|
err |= __get_user(regs->regs[i], &sc->gregs[i]);
|
||||||
|
|
||||||
|
/* Ensure that the PL is always set to USER_PL. */
|
||||||
|
regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1));
|
||||||
|
|
||||||
regs->faultnum = INT_SWINT_1_SIGRETURN;
|
regs->faultnum = INT_SWINT_1_SIGRETURN;
|
||||||
|
|
||||||
err |= __get_user(*pr0, &sc->gregs[0]);
|
err |= __get_user(*pr0, &sc->gregs[0]);
|
||||||
@ -330,7 +333,7 @@ void do_signal(struct pt_regs *regs)
|
|||||||
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
|
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Did we come from a system call? */
|
/* Did we come from a system call? */
|
||||||
@ -358,4 +361,8 @@ void do_signal(struct pt_regs *regs)
|
|||||||
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
|
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
|
||||||
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
|
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* Avoid double syscall restart if there are nested signals. */
|
||||||
|
regs->faultnum = INT_SWINT_1_SIGRETURN;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ static void smp_start_cpu_interrupt(void)
|
|||||||
static void smp_stop_cpu_interrupt(void)
|
static void smp_stop_cpu_interrupt(void)
|
||||||
{
|
{
|
||||||
set_cpu_online(smp_processor_id(), 0);
|
set_cpu_online(smp_processor_id(), 0);
|
||||||
raw_local_irq_disable_all();
|
arch_local_irq_disable_all();
|
||||||
for (;;)
|
for (;;)
|
||||||
asm("nap");
|
asm("nap");
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ static int tile_timer_set_next_event(unsigned long ticks,
|
|||||||
{
|
{
|
||||||
BUG_ON(ticks > MAX_TICK);
|
BUG_ON(ticks > MAX_TICK);
|
||||||
__insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks);
|
__insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks);
|
||||||
raw_local_irq_unmask_now(INT_TILE_TIMER);
|
arch_local_irq_unmask_now(INT_TILE_TIMER);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ static int tile_timer_set_next_event(unsigned long ticks,
|
|||||||
static void tile_timer_set_mode(enum clock_event_mode mode,
|
static void tile_timer_set_mode(enum clock_event_mode mode,
|
||||||
struct clock_event_device *evt)
|
struct clock_event_device *evt)
|
||||||
{
|
{
|
||||||
raw_local_irq_mask_now(INT_TILE_TIMER);
|
arch_local_irq_mask_now(INT_TILE_TIMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -172,7 +172,7 @@ void __cpuinit setup_tile_timer(void)
|
|||||||
evt->cpumask = cpumask_of(smp_processor_id());
|
evt->cpumask = cpumask_of(smp_processor_id());
|
||||||
|
|
||||||
/* Start out with timer not firing. */
|
/* Start out with timer not firing. */
|
||||||
raw_local_irq_mask_now(INT_TILE_TIMER);
|
arch_local_irq_mask_now(INT_TILE_TIMER);
|
||||||
|
|
||||||
/* Register tile timer. */
|
/* Register tile timer. */
|
||||||
clockevents_register_device(evt);
|
clockevents_register_device(evt);
|
||||||
@ -188,7 +188,7 @@ void do_timer_interrupt(struct pt_regs *regs, int fault_num)
|
|||||||
* Mask the timer interrupt here, since we are a oneshot timer
|
* Mask the timer interrupt here, since we are a oneshot timer
|
||||||
* and there are now by definition no events pending.
|
* and there are now by definition no events pending.
|
||||||
*/
|
*/
|
||||||
raw_local_irq_mask(INT_TILE_TIMER);
|
arch_local_irq_mask(INT_TILE_TIMER);
|
||||||
|
|
||||||
/* Track time spent here in an interrupt context */
|
/* Track time spent here in an interrupt context */
|
||||||
irq_enter();
|
irq_enter();
|
||||||
|
@ -54,7 +54,7 @@ typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long);
|
|||||||
* we must run with interrupts disabled to avoid the risk of some
|
* we must run with interrupts disabled to avoid the risk of some
|
||||||
* other code seeing the incoherent data in our cache. (Recall that
|
* other code seeing the incoherent data in our cache. (Recall that
|
||||||
* our cache is indexed by PA, so even if the other code doesn't use
|
* our cache is indexed by PA, so even if the other code doesn't use
|
||||||
* our KM_MEMCPY virtual addresses, they'll still hit in cache using
|
* our kmap_atomic virtual addresses, they'll still hit in cache using
|
||||||
* the normal VAs that aren't supposed to hit in cache.)
|
* the normal VAs that aren't supposed to hit in cache.)
|
||||||
*/
|
*/
|
||||||
static void memcpy_multicache(void *dest, const void *source,
|
static void memcpy_multicache(void *dest, const void *source,
|
||||||
@ -64,6 +64,7 @@ static void memcpy_multicache(void *dest, const void *source,
|
|||||||
unsigned long flags, newsrc, newdst;
|
unsigned long flags, newsrc, newdst;
|
||||||
pmd_t *pmdp;
|
pmd_t *pmdp;
|
||||||
pte_t *ptep;
|
pte_t *ptep;
|
||||||
|
int type0, type1;
|
||||||
int cpu = get_cpu();
|
int cpu = get_cpu();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -77,7 +78,8 @@ static void memcpy_multicache(void *dest, const void *source,
|
|||||||
sim_allow_multiple_caching(1);
|
sim_allow_multiple_caching(1);
|
||||||
|
|
||||||
/* Set up the new dest mapping */
|
/* Set up the new dest mapping */
|
||||||
idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + KM_MEMCPY0;
|
type0 = kmap_atomic_idx_push();
|
||||||
|
idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + type0;
|
||||||
newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1));
|
newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1));
|
||||||
pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst);
|
pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst);
|
||||||
ptep = pte_offset_kernel(pmdp, newdst);
|
ptep = pte_offset_kernel(pmdp, newdst);
|
||||||
@ -87,7 +89,8 @@ static void memcpy_multicache(void *dest, const void *source,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the new source mapping */
|
/* Set up the new source mapping */
|
||||||
idx += (KM_MEMCPY0 - KM_MEMCPY1);
|
type1 = kmap_atomic_idx_push();
|
||||||
|
idx += (type0 - type1);
|
||||||
src_pte = hv_pte_set_nc(src_pte);
|
src_pte = hv_pte_set_nc(src_pte);
|
||||||
src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */
|
src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */
|
||||||
newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1));
|
newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1));
|
||||||
@ -119,6 +122,8 @@ static void memcpy_multicache(void *dest, const void *source,
|
|||||||
* We're done: notify the simulator that all is back to normal,
|
* We're done: notify the simulator that all is back to normal,
|
||||||
* and re-enable interrupts and pre-emption.
|
* and re-enable interrupts and pre-emption.
|
||||||
*/
|
*/
|
||||||
|
kmap_atomic_idx_pop();
|
||||||
|
kmap_atomic_idx_pop();
|
||||||
sim_allow_multiple_caching(0);
|
sim_allow_multiple_caching(0);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
put_cpu();
|
put_cpu();
|
||||||
|
@ -227,7 +227,7 @@ EXPORT_SYMBOL(kmap_atomic_prot);
|
|||||||
void *__kmap_atomic(struct page *page)
|
void *__kmap_atomic(struct page *page)
|
||||||
{
|
{
|
||||||
/* PAGE_NONE is a magic value that tells us to check immutability. */
|
/* PAGE_NONE is a magic value that tells us to check immutability. */
|
||||||
return kmap_atomic_prot(page, type, PAGE_NONE);
|
return kmap_atomic_prot(page, PAGE_NONE);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__kmap_atomic);
|
EXPORT_SYMBOL(__kmap_atomic);
|
||||||
|
|
||||||
|
@ -988,8 +988,12 @@ static long __write_once initfree = 1;
|
|||||||
/* Select whether to free (1) or mark unusable (0) the __init pages. */
|
/* Select whether to free (1) or mark unusable (0) the __init pages. */
|
||||||
static int __init set_initfree(char *str)
|
static int __init set_initfree(char *str)
|
||||||
{
|
{
|
||||||
strict_strtol(str, 0, &initfree);
|
long val;
|
||||||
pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't");
|
if (strict_strtol(str, 0, &val)) {
|
||||||
|
initfree = val;
|
||||||
|
pr_info("initfree: %s free init pages\n",
|
||||||
|
initfree ? "will" : "won't");
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
__setup("initfree=", set_initfree);
|
__setup("initfree=", set_initfree);
|
||||||
|
@ -134,9 +134,9 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_HIGHPTE)
|
#if defined(CONFIG_HIGHPTE)
|
||||||
pte_t *_pte_offset_map(pmd_t *dir, unsigned long address, enum km_type type)
|
pte_t *_pte_offset_map(pmd_t *dir, unsigned long address)
|
||||||
{
|
{
|
||||||
pte_t *pte = kmap_atomic(pmd_page(*dir), type) +
|
pte_t *pte = kmap_atomic(pmd_page(*dir)) +
|
||||||
(pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK;
|
(pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK;
|
||||||
return &pte[pte_index(address)];
|
return &pte[pte_index(address)];
|
||||||
}
|
}
|
||||||
|
@ -33,18 +33,18 @@ struct stat {
|
|||||||
int st_blksize; /* Optimal block size for I/O. */
|
int st_blksize; /* Optimal block size for I/O. */
|
||||||
int __pad2;
|
int __pad2;
|
||||||
long st_blocks; /* Number 512-byte blocks allocated. */
|
long st_blocks; /* Number 512-byte blocks allocated. */
|
||||||
int st_atime; /* Time of last access. */
|
long st_atime; /* Time of last access. */
|
||||||
unsigned int st_atime_nsec;
|
unsigned long st_atime_nsec;
|
||||||
int st_mtime; /* Time of last modification. */
|
long st_mtime; /* Time of last modification. */
|
||||||
unsigned int st_mtime_nsec;
|
unsigned long st_mtime_nsec;
|
||||||
int st_ctime; /* Time of last status change. */
|
long st_ctime; /* Time of last status change. */
|
||||||
unsigned int st_ctime_nsec;
|
unsigned long st_ctime_nsec;
|
||||||
unsigned int __unused4;
|
unsigned int __unused4;
|
||||||
unsigned int __unused5;
|
unsigned int __unused5;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if __BITS_PER_LONG != 64
|
|
||||||
/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
|
/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
|
||||||
|
#if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64)
|
||||||
struct stat64 {
|
struct stat64 {
|
||||||
unsigned long long st_dev; /* Device. */
|
unsigned long long st_dev; /* Device. */
|
||||||
unsigned long long st_ino; /* File serial number. */
|
unsigned long long st_ino; /* File serial number. */
|
||||||
|
Loading…
Reference in New Issue
Block a user