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 ...@@ -281,12 +281,16 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDESCSI is not set # 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 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_RZ1000 is not set
#
# PCI host chip set support
#
# CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_BLK_DEV_IDEDMA_PCI=y
...@@ -393,7 +397,6 @@ CONFIG_SCSI_FCAL=m ...@@ -393,7 +397,6 @@ CONFIG_SCSI_FCAL=m
# Fusion MPT device support # Fusion MPT device support
# #
CONFIG_FUSION=m CONFIG_FUSION=m
# CONFIG_FUSION_BOOT is not set
# #
# (ability to boot linux kernel from Fusion device is DISABLED!) # (ability to boot linux kernel from Fusion device is DISABLED!)
...@@ -622,6 +625,9 @@ CONFIG_SOUND_GAMEPORT=y ...@@ -622,6 +625,9 @@ CONFIG_SOUND_GAMEPORT=y
# File systems # File systems
# #
# CONFIG_QUOTA is not set # 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_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m CONFIG_AUTOFS4_FS=m
# CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_FS is not set
...@@ -782,10 +788,11 @@ CONFIG_USB_DEVICEFS=y ...@@ -782,10 +788,11 @@ CONFIG_USB_DEVICEFS=y
# USB Host Controller Drivers # USB Host Controller Drivers
# #
CONFIG_USB_EHCI_HCD=m 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=y
# CONFIG_USB_UHCI_ALT is not set # CONFIG_USB_UHCI_ALT is not set
CONFIG_USB_OHCI=y
# #
# USB Device Class drivers # USB Device Class drivers
...@@ -802,6 +809,7 @@ CONFIG_USB_STORAGE_ISD200=y ...@@ -802,6 +809,7 @@ CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_DPCM=y CONFIG_USB_STORAGE_DPCM=y
CONFIG_USB_STORAGE_HP8200e=y CONFIG_USB_STORAGE_HP8200e=y
CONFIG_USB_STORAGE_SDDR09=y CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
# CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set
# #
...@@ -809,7 +817,7 @@ CONFIG_USB_STORAGE_SDDR09=y ...@@ -809,7 +817,7 @@ CONFIG_USB_STORAGE_SDDR09=y
# #
CONFIG_USB_HID=y CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y CONFIG_USB_HIDINPUT=y
# CONFIG_USB_HIDDEV is not set CONFIG_USB_HIDDEV=y
CONFIG_USB_WACOM=m CONFIG_USB_WACOM=m
# #
......
...@@ -1429,7 +1429,7 @@ sys_fork: clr %o1 ...@@ -1429,7 +1429,7 @@ sys_fork: clr %o1
sys_clone: flushw sys_clone: flushw
movrz %o1, %fp, %o1 movrz %o1, %fp, %o1
mov 0, %o3 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 add %sp, STACK_BIAS + REGWIN_SZ, %o2
ret_from_syscall: ret_from_syscall:
/* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in /* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in
......
...@@ -582,6 +582,17 @@ void fault_in_user_windows(void) ...@@ -582,6 +582,17 @@ void fault_in_user_windows(void)
do_exit(SIGILL); 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 /* Copy a Sparc thread. The fork() return value conventions
* under SunOS are nothing short of bletcherous: * under SunOS are nothing short of bletcherous:
* Parent --> %o0 == childs pid, %o1 == 0 * Parent --> %o0 == childs pid, %o1 == 0
......
...@@ -824,30 +824,26 @@ void smp_flush_tlb_mm(struct mm_struct *mm) ...@@ -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) 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; start &= PAGE_MASK;
end = PAGE_ALIGN(end); end = PAGE_ALIGN(end);
if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) { if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) {
mm->cpu_vm_mask = (1UL << cpu); mm->cpu_vm_mask = (1UL << cpu);
goto local_flush_and_out; goto local_flush_and_out;
} }
smp_cross_call_masked(&xcall_flush_tlb_range, smp_cross_call_masked(&xcall_flush_tlb_range,
ctx, start, end, ctx, start, end,
mm->cpu_vm_mask); mm->cpu_vm_mask);
local_flush_and_out: local_flush_and_out:
__flush_tlb_range(ctx, start, SECONDARY_CONTEXT, end, PAGE_SIZE, (end-start)); __flush_tlb_range(ctx, start, SECONDARY_CONTEXT, end, PAGE_SIZE, (end-start));
}
} }
void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end) void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end)
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
* x86 doesn't need any special per-pte or * x86 doesn't need any special per-pte or
* per-vma handling.. * per-vma handling..
*/ */
#define tlb_start_vma(tlb, vma) do { } while (0) #define tlb_start_vma(tlb, vma, start, end) do { } while (0)
#define tlb_end_vma(tlb, vma) 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) #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> #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)) { \ ...@@ -36,6 +36,16 @@ do { if(CTX_VALID((__vma)->vm_mm->context)) { \
} \ } \
} while(0) } 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) \ #define flush_tlb_page(vma, page) \
do { struct mm_struct *__mm = (vma)->vm_mm; \ do { struct mm_struct *__mm = (vma)->vm_mm; \
if(CTX_VALID(__mm->context)) \ if(CTX_VALID(__mm->context)) \
...@@ -43,11 +53,18 @@ do { struct mm_struct *__mm = (vma)->vm_mm; \ ...@@ -43,11 +53,18 @@ do { struct mm_struct *__mm = (vma)->vm_mm; \
SECONDARY_CONTEXT); \ SECONDARY_CONTEXT); \
} while(0) } 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 */ #else /* CONFIG_SMP */
extern void smp_flush_tlb_all(void); extern void smp_flush_tlb_all(void);
extern void smp_flush_tlb_mm(struct mm_struct *mm); 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); unsigned long end);
extern void smp_flush_tlb_kernel_range(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); 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); ...@@ -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_all() smp_flush_tlb_all()
#define flush_tlb_mm(mm) smp_flush_tlb_mm(mm) #define flush_tlb_mm(mm) smp_flush_tlb_mm(mm)
#define flush_tlb_range(vma, start, end) \ #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) \ #define flush_tlb_kernel_range(start, end) \
smp_flush_tlb_kernel_range(start, end) smp_flush_tlb_kernel_range(start, end)
#define flush_tlb_page(vma, page) \ #define flush_tlb_page(vma, page) \
smp_flush_tlb_page((vma)->vm_mm, 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 */ #endif /* ! CONFIG_SMP */
...@@ -81,13 +102,10 @@ static __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long st ...@@ -81,13 +102,10 @@ static __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long st
vpte_base = (tlb_type == spitfire ? vpte_base = (tlb_type == spitfire ?
VPTE_BASE_SPITFIRE : VPTE_BASE_SPITFIRE :
VPTE_BASE_CHEETAH); VPTE_BASE_CHEETAH);
{
struct vm_area_struct vma; flush_tlb_vpte_range(mm,
vma.vm_mm = mm; vpte_base + (s >> (PAGE_SHIFT - 3)),
flush_tlb_range(&vma, vpte_base + (e >> (PAGE_SHIFT - 3)));
vpte_base + (s >> (PAGE_SHIFT - 3)),
vpte_base + (e >> (PAGE_SHIFT - 3)));
}
} }
#endif /* _SPARC64_TLBFLUSH_H */ #endif /* _SPARC64_TLBFLUSH_H */
...@@ -391,18 +391,19 @@ static void zap_pmd_range(mmu_gather_t *tlb, pgd_t * dir, unsigned long address, ...@@ -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) 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; pgd_t * dir;
if (address >= end) if (address >= end)
BUG(); BUG();
dir = pgd_offset(vma->vm_mm, address); dir = pgd_offset(vma->vm_mm, address);
tlb_start_vma(tlb, vma); tlb_start_vma(tlb, vma, start, end);
do { do {
zap_pmd_range(tlb, dir, address, end - address); zap_pmd_range(tlb, dir, address, end - address);
address = (address + PGDIR_SIZE) & PGDIR_MASK; address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++; dir++;
} while (address && (address < end)); } 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