Commit 3158ebe6 authored by David S. Miller's avatar David S. Miller

Sparc64 updates

- TLB infrastructure changes
- Make flush_tlb_pgtables not need to cook up
a dummy vma
- Update for do_fork return value change
- Update defconfig
parent 0684fe0a
......@@ -281,12 +281,16 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDESCSI is not set
#
# ATA host chipset support
# ATA host chip set support
#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_BLK_DEV_RZ1000 is not set
#
# PCI host chip set support
#
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
......@@ -393,7 +397,6 @@ CONFIG_SCSI_FCAL=m
# Fusion MPT device support
#
CONFIG_FUSION=m
# CONFIG_FUSION_BOOT is not set
#
# (ability to boot linux kernel from Fusion device is DISABLED!)
......@@ -622,6 +625,9 @@ CONFIG_SOUND_GAMEPORT=y
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
# CONFIG_QIFACE_COMPAT is not set
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
# CONFIG_REISERFS_FS is not set
......@@ -782,10 +788,11 @@ CONFIG_USB_DEVICEFS=y
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=m
# CONFIG_USB_UHCI_HCD_ALT is not set
CONFIG_USB_UHCI=y
# CONFIG_USB_UHCI_ALT is not set
CONFIG_USB_OHCI=y
#
# USB Device Class drivers
......@@ -802,6 +809,7 @@ CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_DPCM=y
CONFIG_USB_STORAGE_HP8200e=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
# CONFIG_USB_STORAGE_JUMPSHOT is not set
#
......@@ -809,7 +817,7 @@ CONFIG_USB_STORAGE_SDDR09=y
#
CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y
# CONFIG_USB_HIDDEV is not set
CONFIG_USB_HIDDEV=y
CONFIG_USB_WACOM=m
#
......
......@@ -1429,7 +1429,7 @@ sys_fork: clr %o1
sys_clone: flushw
movrz %o1, %fp, %o1
mov 0, %o3
ba,pt %xcc, do_fork_FIXME_NOW_RETURNS_TASK_STRUCT
ba,pt %xcc, sparc_do_fork
add %sp, STACK_BIAS + REGWIN_SZ, %o2
ret_from_syscall:
/* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in
......
......@@ -582,6 +582,17 @@ void fault_in_user_windows(void)
do_exit(SIGILL);
}
asmlinkage int sparc_do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size)
{
struct task_struct *p = do_fork(clone_flags, stack_start,
regs, stack_size);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
/* Copy a Sparc thread. The fork() return value conventions
* under SunOS are nothing short of bletcherous:
* Parent --> %o0 == childs pid, %o1 == 0
......
......@@ -824,30 +824,26 @@ void smp_flush_tlb_mm(struct mm_struct *mm)
}
}
void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
struct mm_struct *mm = vma->vm_mm;
{
u32 ctx = CTX_HWBITS(mm->context);
int cpu = smp_processor_id();
u32 ctx = CTX_HWBITS(mm->context);
int cpu = smp_processor_id();
start &= PAGE_MASK;
end = PAGE_ALIGN(end);
start &= PAGE_MASK;
end = PAGE_ALIGN(end);
if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) {
mm->cpu_vm_mask = (1UL << cpu);
goto local_flush_and_out;
}
if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) {
mm->cpu_vm_mask = (1UL << cpu);
goto local_flush_and_out;
}
smp_cross_call_masked(&xcall_flush_tlb_range,
ctx, start, end,
mm->cpu_vm_mask);
smp_cross_call_masked(&xcall_flush_tlb_range,
ctx, start, end,
mm->cpu_vm_mask);
local_flush_and_out:
__flush_tlb_range(ctx, start, SECONDARY_CONTEXT, end, PAGE_SIZE, (end-start));
}
local_flush_and_out:
__flush_tlb_range(ctx, start, SECONDARY_CONTEXT, end, PAGE_SIZE, (end-start));
}
void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end)
......
......@@ -5,8 +5,8 @@
* x86 doesn't need any special per-pte or
* per-vma handling..
*/
#define tlb_start_vma(tlb, vma) do { } while (0)
#define tlb_end_vma(tlb, vma) do { } while (0)
#define tlb_start_vma(tlb, vma, start, end) do { } while (0)
#define tlb_end_vma(tlb, vma, start, end) do { } while (0)
#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
/*
......
#ifndef _SPARC64_TLB_H
#define _SPARC64_TLB_H
#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
#define tlb_start_vma(tlb, vma, start, end) \
flush_cache_range(vma, start, end)
#define tlb_end_vma(tlb, vma, start, end) \
flush_tlb_range(vma, start, end)
#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
#include <asm-generic/tlb.h>
#define pmd_free_tlb(tlb, pmd) pmd_free(pmd)
#define pte_free_tlb(tlb, pte) pte_free(pte)
#endif /* _SPARC64_TLB_H */
......@@ -36,6 +36,16 @@ do { if(CTX_VALID((__vma)->vm_mm->context)) { \
} \
} while(0)
#define flush_tlb_vpte_range(__mm, start, end) \
do { if(CTX_VALID((__mm)->context)) { \
unsigned long __start = (start)&PAGE_MASK; \
unsigned long __end = PAGE_ALIGN(end); \
__flush_tlb_range(CTX_HWBITS((__mm)->context), __start, \
SECONDARY_CONTEXT, __end, PAGE_SIZE, \
(__end - __start)); \
} \
} while(0)
#define flush_tlb_page(vma, page) \
do { struct mm_struct *__mm = (vma)->vm_mm; \
if(CTX_VALID(__mm->context)) \
......@@ -43,11 +53,18 @@ do { struct mm_struct *__mm = (vma)->vm_mm; \
SECONDARY_CONTEXT); \
} while(0)
#define flush_tlb_vpte_page(mm, addr) \
do { struct mm_struct *__mm = (mm); \
if(CTX_VALID(__mm->context)) \
__flush_tlb_page(CTX_HWBITS(__mm->context), (addr)&PAGE_MASK, \
SECONDARY_CONTEXT); \
} while(0)
#else /* CONFIG_SMP */
extern void smp_flush_tlb_all(void);
extern void smp_flush_tlb_mm(struct mm_struct *mm);
extern void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
extern void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
unsigned long end);
extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page);
......@@ -56,11 +73,15 @@ extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page);
#define flush_tlb_all() smp_flush_tlb_all()
#define flush_tlb_mm(mm) smp_flush_tlb_mm(mm)
#define flush_tlb_range(vma, start, end) \
smp_flush_tlb_range(vma, start, end)
smp_flush_tlb_range((vma)->vm_mm, start, end)
#define flush_tlb_vpte_range(mm, start, end) \
smp_flush_tlb_range(mm, start, end)
#define flush_tlb_kernel_range(start, end) \
smp_flush_tlb_kernel_range(start, end)
#define flush_tlb_page(vma, page) \
smp_flush_tlb_page((vma)->vm_mm, page)
#define flush_tlb_vpte_page(mm, page) \
smp_flush_tlb_page((mm), page)
#endif /* ! CONFIG_SMP */
......@@ -81,13 +102,10 @@ static __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long st
vpte_base = (tlb_type == spitfire ?
VPTE_BASE_SPITFIRE :
VPTE_BASE_CHEETAH);
{
struct vm_area_struct vma;
vma.vm_mm = mm;
flush_tlb_range(&vma,
vpte_base + (s >> (PAGE_SHIFT - 3)),
vpte_base + (e >> (PAGE_SHIFT - 3)));
}
flush_tlb_vpte_range(mm,
vpte_base + (s >> (PAGE_SHIFT - 3)),
vpte_base + (e >> (PAGE_SHIFT - 3)));
}
#endif /* _SPARC64_TLBFLUSH_H */
......@@ -391,18 +391,19 @@ static void zap_pmd_range(mmu_gather_t *tlb, pgd_t * dir, unsigned long address,
void unmap_page_range(mmu_gather_t *tlb, struct vm_area_struct *vma, unsigned long address, unsigned long end)
{
unsigned long start = address;
pgd_t * dir;
if (address >= end)
BUG();
dir = pgd_offset(vma->vm_mm, address);
tlb_start_vma(tlb, vma);
tlb_start_vma(tlb, vma, start, end);
do {
zap_pmd_range(tlb, dir, address, end - address);
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
tlb_end_vma(tlb, vma);
tlb_end_vma(tlb, vma, start, end);
}
/*
......
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