Commit 0660a9b1 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 65f75ace d02db4f8
...@@ -23,7 +23,6 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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)
......
#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) ...@@ -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, ...@@ -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, ...) ...@@ -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 { ...@@ -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) ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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(&copyregs, 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 @@ ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, &current->saved_sigmask, NULL); sigprocmask(SIG_SETMASK, &current->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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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); ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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); ...@@ -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; ...@@ -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) ...@@ -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 { ...@@ -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. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment