Skip to content

Commit 04ed7d9

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull sparc fixes from David Miller: "Several sparc64 bug fixes here: 1) Make the user copy routines on sparc64 return a properly accurate residual length when an exception occurs. 2) We can get enormous kernel TLB range flush requests from vmalloc unmaps, so handle these more gracefully by doing full flushes instead of going page-by-page. 3) Cope properly with negative branch offsets in sparc jump-label support, from James Clarke. 4) Some old-style decl GCC warning fixups from Tobias Klauser" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc: sparc64: Handle extremely large kernel TLB range flushes more gracefully. sparc64: Fix illegal relative branches in hypervisor patched TLB cross-call code. sparc64: Fix instruction count in comment for __hypervisor_flush_tlb_pending. sparc64: Handle extremely large kernel TSB range flushes sanely. sparc: Handle negative offsets in arch_jump_label_transform sparc64: Fix illegal relative branches in hypervisor patched TLB code. sparc64: Delete now unused user copy fixup functions. sparc64: Delete now unused user copy assembler helpers. sparc64: Convert U3copy_{from,to}_user to accurate exception reporting. sparc64: Convert NG2copy_{from,to}_user to accurate exception reporting. sparc64: Convert NGcopy_{from,to}_user to accurate exception reporting. sparc64: Convert NG4copy_{from,to}_user to accurate exception reporting. sparc64: Convert U1copy_{from,to}_user to accurate exception reporting. sparc64: Convert GENcopy_{from,to}_user to accurate exception reporting. sparc64: Convert copy_in_user to accurate exception reporting. sparc64: Prepare to move to more saner user copy exception handling. sparc64: Delete __ret_efault. sparc32: Fix old style declaration GCC warnings sparc64: Fix old style declaration GCC warnings sparc64: Setup a scheduling domain for highest level cache.
2 parents 2a26d99 + a74ad5e commit 04ed7d9

32 files changed

Lines changed: 1400 additions & 723 deletions

arch/sparc/include/asm/cpudata_64.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ typedef struct {
2424
unsigned int icache_line_size;
2525
unsigned int ecache_size;
2626
unsigned int ecache_line_size;
27-
unsigned short sock_id;
27+
unsigned short sock_id; /* physical package */
2828
unsigned short core_id;
29-
int proc_id;
29+
unsigned short max_cache_id; /* groupings of highest shared cache */
30+
unsigned short proc_id; /* strand (aka HW thread) id */
3031
} cpuinfo_sparc;
3132

3233
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);

arch/sparc/include/asm/spinlock_32.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
134134
*(volatile __u32 *)&lp->lock = ~0U;
135135
}
136136

137-
static void inline arch_write_unlock(arch_rwlock_t *lock)
137+
static inline void arch_write_unlock(arch_rwlock_t *lock)
138138
{
139139
__asm__ __volatile__(
140140
" st %%g0, [%0]"

arch/sparc/include/asm/spinlock_64.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long fla
9696

9797
/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
9898

99-
static void inline arch_read_lock(arch_rwlock_t *lock)
99+
static inline void arch_read_lock(arch_rwlock_t *lock)
100100
{
101101
unsigned long tmp1, tmp2;
102102

@@ -119,7 +119,7 @@ static void inline arch_read_lock(arch_rwlock_t *lock)
119119
: "memory");
120120
}
121121

122-
static int inline arch_read_trylock(arch_rwlock_t *lock)
122+
static inline int arch_read_trylock(arch_rwlock_t *lock)
123123
{
124124
int tmp1, tmp2;
125125

@@ -140,7 +140,7 @@ static int inline arch_read_trylock(arch_rwlock_t *lock)
140140
return tmp1;
141141
}
142142

143-
static void inline arch_read_unlock(arch_rwlock_t *lock)
143+
static inline void arch_read_unlock(arch_rwlock_t *lock)
144144
{
145145
unsigned long tmp1, tmp2;
146146

@@ -156,7 +156,7 @@ static void inline arch_read_unlock(arch_rwlock_t *lock)
156156
: "memory");
157157
}
158158

159-
static void inline arch_write_lock(arch_rwlock_t *lock)
159+
static inline void arch_write_lock(arch_rwlock_t *lock)
160160
{
161161
unsigned long mask, tmp1, tmp2;
162162

@@ -181,7 +181,7 @@ static void inline arch_write_lock(arch_rwlock_t *lock)
181181
: "memory");
182182
}
183183

184-
static void inline arch_write_unlock(arch_rwlock_t *lock)
184+
static inline void arch_write_unlock(arch_rwlock_t *lock)
185185
{
186186
__asm__ __volatile__(
187187
" stw %%g0, [%0]"
@@ -190,7 +190,7 @@ static void inline arch_write_unlock(arch_rwlock_t *lock)
190190
: "memory");
191191
}
192192

193-
static int inline arch_write_trylock(arch_rwlock_t *lock)
193+
static inline int arch_write_trylock(arch_rwlock_t *lock)
194194
{
195195
unsigned long mask, tmp1, tmp2, result;
196196

arch/sparc/include/asm/topology_64.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,20 @@ int __node_distance(int, int);
4444
#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
4545
#define topology_core_id(cpu) (cpu_data(cpu).core_id)
4646
#define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu])
47+
#define topology_core_cache_cpumask(cpu) (&cpu_core_sib_cache_map[cpu])
4748
#define topology_sibling_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
4849
#endif /* CONFIG_SMP */
4950

5051
extern cpumask_t cpu_core_map[NR_CPUS];
5152
extern cpumask_t cpu_core_sib_map[NR_CPUS];
53+
extern cpumask_t cpu_core_sib_cache_map[NR_CPUS];
54+
55+
/**
56+
* Return cores that shares the last level cache.
57+
*/
5258
static inline const struct cpumask *cpu_coregroup_mask(int cpu)
5359
{
54-
return &cpu_core_map[cpu];
60+
return &cpu_core_sib_cache_map[cpu];
5561
}
5662

5763
#endif /* _ASM_SPARC64_TOPOLOGY_H */

arch/sparc/include/asm/uaccess_64.h

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ static inline int access_ok(int type, const void __user * addr, unsigned long si
8282
return 1;
8383
}
8484

85-
void __ret_efault(void);
8685
void __retl_efault(void);
8786

8887
/* Uh, these should become the main single-value transfer routines..
@@ -189,55 +188,34 @@ int __get_user_bad(void);
189188
unsigned long __must_check ___copy_from_user(void *to,
190189
const void __user *from,
191190
unsigned long size);
192-
unsigned long copy_from_user_fixup(void *to, const void __user *from,
193-
unsigned long size);
194191
static inline unsigned long __must_check
195192
copy_from_user(void *to, const void __user *from, unsigned long size)
196193
{
197-
unsigned long ret;
198-
199194
check_object_size(to, size, false);
200195

201-
ret = ___copy_from_user(to, from, size);
202-
if (unlikely(ret))
203-
ret = copy_from_user_fixup(to, from, size);
204-
205-
return ret;
196+
return ___copy_from_user(to, from, size);
206197
}
207198
#define __copy_from_user copy_from_user
208199

209200
unsigned long __must_check ___copy_to_user(void __user *to,
210201
const void *from,
211202
unsigned long size);
212-
unsigned long copy_to_user_fixup(void __user *to, const void *from,
213-
unsigned long size);
214203
static inline unsigned long __must_check
215204
copy_to_user(void __user *to, const void *from, unsigned long size)
216205
{
217-
unsigned long ret;
218-
219206
check_object_size(from, size, true);
220207

221-
ret = ___copy_to_user(to, from, size);
222-
if (unlikely(ret))
223-
ret = copy_to_user_fixup(to, from, size);
224-
return ret;
208+
return ___copy_to_user(to, from, size);
225209
}
226210
#define __copy_to_user copy_to_user
227211

228212
unsigned long __must_check ___copy_in_user(void __user *to,
229213
const void __user *from,
230214
unsigned long size);
231-
unsigned long copy_in_user_fixup(void __user *to, void __user *from,
232-
unsigned long size);
233215
static inline unsigned long __must_check
234216
copy_in_user(void __user *to, void __user *from, unsigned long size)
235217
{
236-
unsigned long ret = ___copy_in_user(to, from, size);
237-
238-
if (unlikely(ret))
239-
ret = copy_in_user_fixup(to, from, size);
240-
return ret;
218+
return ___copy_in_user(to, from, size);
241219
}
242220
#define __copy_in_user copy_in_user
243221

arch/sparc/kernel/head_64.S

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -926,48 +926,11 @@ tlb_type: .word 0 /* Must NOT end up in BSS */
926926
EXPORT_SYMBOL(tlb_type)
927927
.section ".fixup",#alloc,#execinstr
928928

929-
.globl __ret_efault, __retl_efault, __ret_one, __retl_one
930-
ENTRY(__ret_efault)
931-
ret
932-
restore %g0, -EFAULT, %o0
933-
ENDPROC(__ret_efault)
934-
EXPORT_SYMBOL(__ret_efault)
935-
936929
ENTRY(__retl_efault)
937930
retl
938931
mov -EFAULT, %o0
939932
ENDPROC(__retl_efault)
940933

941-
ENTRY(__retl_one)
942-
retl
943-
mov 1, %o0
944-
ENDPROC(__retl_one)
945-
946-
ENTRY(__retl_one_fp)
947-
VISExitHalf
948-
retl
949-
mov 1, %o0
950-
ENDPROC(__retl_one_fp)
951-
952-
ENTRY(__ret_one_asi)
953-
wr %g0, ASI_AIUS, %asi
954-
ret
955-
restore %g0, 1, %o0
956-
ENDPROC(__ret_one_asi)
957-
958-
ENTRY(__retl_one_asi)
959-
wr %g0, ASI_AIUS, %asi
960-
retl
961-
mov 1, %o0
962-
ENDPROC(__retl_one_asi)
963-
964-
ENTRY(__retl_one_asi_fp)
965-
wr %g0, ASI_AIUS, %asi
966-
VISExitHalf
967-
retl
968-
mov 1, %o0
969-
ENDPROC(__retl_one_asi_fp)
970-
971934
ENTRY(__retl_o1)
972935
retl
973936
mov %o1, %o0

arch/sparc/kernel/jump_label.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,30 @@
1313
void arch_jump_label_transform(struct jump_entry *entry,
1414
enum jump_label_type type)
1515
{
16-
u32 val;
1716
u32 *insn = (u32 *) (unsigned long) entry->code;
17+
u32 val;
1818

1919
if (type == JUMP_LABEL_JMP) {
2020
s32 off = (s32)entry->target - (s32)entry->code;
21+
bool use_v9_branch = false;
22+
23+
BUG_ON(off & 3);
2124

2225
#ifdef CONFIG_SPARC64
23-
/* ba,pt %xcc, . + (off << 2) */
24-
val = 0x10680000 | ((u32) off >> 2);
25-
#else
26-
/* ba . + (off << 2) */
27-
val = 0x10800000 | ((u32) off >> 2);
26+
if (off <= 0xfffff && off >= -0x100000)
27+
use_v9_branch = true;
2828
#endif
29+
if (use_v9_branch) {
30+
/* WDISP19 - target is . + immed << 2 */
31+
/* ba,pt %xcc, . + off */
32+
val = 0x10680000 | (((u32) off >> 2) & 0x7ffff);
33+
} else {
34+
/* WDISP22 - target is . + immed << 2 */
35+
BUG_ON(off > 0x7fffff);
36+
BUG_ON(off < -0x800000);
37+
/* ba . + off */
38+
val = 0x10800000 | (((u32) off >> 2) & 0x3fffff);
39+
}
2940
} else {
3041
val = 0x01000000;
3142
}

arch/sparc/kernel/mdesc.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -645,13 +645,20 @@ static void __mark_core_id(struct mdesc_handle *hp, u64 node,
645645
cpu_data(*id).core_id = core_id;
646646
}
647647

648-
static void __mark_sock_id(struct mdesc_handle *hp, u64 node,
649-
int sock_id)
648+
static void __mark_max_cache_id(struct mdesc_handle *hp, u64 node,
649+
int max_cache_id)
650650
{
651651
const u64 *id = mdesc_get_property(hp, node, "id", NULL);
652652

653-
if (*id < num_possible_cpus())
654-
cpu_data(*id).sock_id = sock_id;
653+
if (*id < num_possible_cpus()) {
654+
cpu_data(*id).max_cache_id = max_cache_id;
655+
656+
/**
657+
* On systems without explicit socket descriptions socket
658+
* is max_cache_id
659+
*/
660+
cpu_data(*id).sock_id = max_cache_id;
661+
}
655662
}
656663

657664
static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
@@ -660,10 +667,11 @@ static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
660667
find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10);
661668
}
662669

663-
static void mark_sock_ids(struct mdesc_handle *hp, u64 mp,
664-
int sock_id)
670+
static void mark_max_cache_ids(struct mdesc_handle *hp, u64 mp,
671+
int max_cache_id)
665672
{
666-
find_back_node_value(hp, mp, "cpu", __mark_sock_id, sock_id, 10);
673+
find_back_node_value(hp, mp, "cpu", __mark_max_cache_id,
674+
max_cache_id, 10);
667675
}
668676

669677
static void set_core_ids(struct mdesc_handle *hp)
@@ -694,23 +702,23 @@ static void set_core_ids(struct mdesc_handle *hp)
694702
}
695703
}
696704

697-
static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level)
705+
static int set_max_cache_ids_by_cache(struct mdesc_handle *hp, int level)
698706
{
699707
u64 mp;
700708
int idx = 1;
701709
int fnd = 0;
702710

703-
/* Identify unique sockets by looking for cpus backpointed to by
704-
* shared level n caches.
711+
/**
712+
* Identify unique highest level of shared cache by looking for cpus
713+
* backpointed to by shared level N caches.
705714
*/
706715
mdesc_for_each_node_by_name(hp, mp, "cache") {
707716
const u64 *cur_lvl;
708717

709718
cur_lvl = mdesc_get_property(hp, mp, "level", NULL);
710719
if (*cur_lvl != level)
711720
continue;
712-
713-
mark_sock_ids(hp, mp, idx);
721+
mark_max_cache_ids(hp, mp, idx);
714722
idx++;
715723
fnd = 1;
716724
}
@@ -745,15 +753,17 @@ static void set_sock_ids(struct mdesc_handle *hp)
745753
{
746754
u64 mp;
747755

748-
/* If machine description exposes sockets data use it.
749-
* Otherwise fallback to use shared L3 or L2 caches.
756+
/**
757+
* Find the highest level of shared cache which pre-T7 is also
758+
* the socket.
750759
*/
760+
if (!set_max_cache_ids_by_cache(hp, 3))
761+
set_max_cache_ids_by_cache(hp, 2);
762+
763+
/* If machine description exposes sockets data use it.*/
751764
mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets");
752765
if (mp != MDESC_NODE_NULL)
753-
return set_sock_ids_by_socket(hp, mp);
754-
755-
if (!set_sock_ids_by_cache(hp, 3))
756-
set_sock_ids_by_cache(hp, 2);
766+
set_sock_ids_by_socket(hp, mp);
757767
}
758768

759769
static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)

arch/sparc/kernel/smp_64.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,13 @@ cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
6363
cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = {
6464
[0 ... NR_CPUS-1] = CPU_MASK_NONE };
6565

66+
cpumask_t cpu_core_sib_cache_map[NR_CPUS] __read_mostly = {
67+
[0 ... NR_CPUS - 1] = CPU_MASK_NONE };
68+
6669
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
6770
EXPORT_SYMBOL(cpu_core_map);
6871
EXPORT_SYMBOL(cpu_core_sib_map);
72+
EXPORT_SYMBOL(cpu_core_sib_cache_map);
6973

7074
static cpumask_t smp_commenced_mask;
7175

@@ -1265,6 +1269,10 @@ void smp_fill_in_sib_core_maps(void)
12651269
unsigned int j;
12661270

12671271
for_each_present_cpu(j) {
1272+
if (cpu_data(i).max_cache_id ==
1273+
cpu_data(j).max_cache_id)
1274+
cpumask_set_cpu(j, &cpu_core_sib_cache_map[i]);
1275+
12681276
if (cpu_data(i).sock_id == cpu_data(j).sock_id)
12691277
cpumask_set_cpu(j, &cpu_core_sib_map[i]);
12701278
}

arch/sparc/lib/GENcopy_from_user.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
* Copyright (C) 2007 David S. Miller (davem@davemloft.net)
44
*/
55

6-
#define EX_LD(x) \
6+
#define EX_LD(x,y) \
77
98: x; \
88
.section __ex_table,"a";\
99
.align 4; \
10-
.word 98b, __retl_one; \
10+
.word 98b, y; \
1111
.text; \
1212
.align 4;
1313

0 commit comments

Comments
 (0)