Skip to content

Commit 2459c60

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull Sparc fixes from David Miller: 1) Setup the core/threads/sockets bitmaps correctly so that 'lscpus' and friends operate properly. Frtom Chris Hyser. 2) The bit that normally means "Cached Virtually" on sun4v systems, actually changes meaning in M7 and later chips. Fix from Khalid Aziz. 3) One some PCI-E systems we need to probe different OF properties to fill in the PCI slot information properly, from Eric Snowberg. 4) Kill an extraneous memset after kzalloc(), from Christophe Jaillet. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc: sparc: Resolve conflict between sparc v9 and M7 on usage of bit 9 of TTE sparc64: pci slots information is not populated in sysfs sparc: kernel: GRPCI2: Remove a useless memset sparc64: Setup sysfs to mark LDOM sockets, cores and threads correctly
2 parents fec345b + 494e5b6 commit 2459c60

File tree

12 files changed

+282
-59
lines changed

12 files changed

+282
-59
lines changed

arch/sparc/include/asm/cpudata_64.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ typedef struct {
2424
unsigned int icache_line_size;
2525
unsigned int ecache_size;
2626
unsigned int ecache_line_size;
27-
int core_id;
27+
unsigned short sock_id;
28+
unsigned short core_id;
2829
int proc_id;
2930
} cpuinfo_sparc;
3031

arch/sparc/include/asm/pgtable_64.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,26 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
308308
" sllx %1, 32, %1\n"
309309
" or %0, %1, %0\n"
310310
" .previous\n"
311+
" .section .sun_m7_2insn_patch, \"ax\"\n"
312+
" .word 661b\n"
313+
" sethi %%uhi(%4), %1\n"
314+
" sethi %%hi(%4), %0\n"
315+
" .word 662b\n"
316+
" or %1, %%ulo(%4), %1\n"
317+
" or %0, %%lo(%4), %0\n"
318+
" .word 663b\n"
319+
" sllx %1, 32, %1\n"
320+
" or %0, %1, %0\n"
321+
" .previous\n"
311322
: "=r" (mask), "=r" (tmp)
312323
: "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
313324
_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U |
314325
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U),
315326
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
316327
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V |
328+
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V),
329+
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
330+
_PAGE_CP_4V | _PAGE_E_4V |
317331
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V));
318332

319333
return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
@@ -342,9 +356,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
342356
" andn %0, %4, %0\n"
343357
" or %0, %5, %0\n"
344358
" .previous\n"
359+
" .section .sun_m7_2insn_patch, \"ax\"\n"
360+
" .word 661b\n"
361+
" andn %0, %6, %0\n"
362+
" or %0, %5, %0\n"
363+
" .previous\n"
345364
: "=r" (val)
346365
: "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
347-
"i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V));
366+
"i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V),
367+
"i" (_PAGE_CP_4V));
348368

349369
return __pgprot(val);
350370
}

arch/sparc/include/asm/topology_64.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
4040
#ifdef CONFIG_SMP
4141
#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
4242
#define topology_core_id(cpu) (cpu_data(cpu).core_id)
43-
#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
43+
#define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu])
4444
#define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
4545
#endif /* CONFIG_SMP */
4646

4747
extern cpumask_t cpu_core_map[NR_CPUS];
48+
extern cpumask_t cpu_core_sib_map[NR_CPUS];
4849
static inline const struct cpumask *cpu_coregroup_mask(int cpu)
4950
{
5051
return &cpu_core_map[cpu];

arch/sparc/include/asm/trap_block.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ struct sun4v_2insn_patch_entry {
7979
};
8080
extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
8181
__sun4v_2insn_patch_end;
82+
extern struct sun4v_2insn_patch_entry __sun_m7_2insn_patch,
83+
__sun_m7_2insn_patch_end;
8284

8385

8486
#endif /* !(__ASSEMBLY__) */

arch/sparc/kernel/entry.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
6969
struct sun4v_1insn_patch_entry *);
7070
void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
7171
struct sun4v_2insn_patch_entry *);
72+
void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *,
73+
struct sun4v_2insn_patch_entry *);
7274
extern unsigned int dcache_parity_tl1_occurred;
7375
extern unsigned int icache_parity_tl1_occurred;
7476

arch/sparc/kernel/leon_pci_grpci2.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,6 @@ static int grpci2_of_probe(struct platform_device *ofdev)
723723
err = -ENOMEM;
724724
goto err1;
725725
}
726-
memset(grpci2priv, 0, sizeof(*grpci2priv));
727726
priv->regs = regs;
728727
priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */
729728
priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT;

arch/sparc/kernel/mdesc.c

Lines changed: 110 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -614,45 +614,68 @@ static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp)
614614
}
615615
}
616616

617-
static void mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id)
617+
static void find_back_node_value(struct mdesc_handle *hp, u64 node,
618+
char *srch_val,
619+
void (*func)(struct mdesc_handle *, u64, int),
620+
u64 val, int depth)
618621
{
619-
u64 a;
620-
621-
mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
622-
u64 t = mdesc_arc_target(hp, a);
623-
const char *name;
624-
const u64 *id;
622+
u64 arc;
625623

626-
name = mdesc_node_name(hp, t);
627-
if (!strcmp(name, "cpu")) {
628-
id = mdesc_get_property(hp, t, "id", NULL);
629-
if (*id < NR_CPUS)
630-
cpu_data(*id).core_id = core_id;
631-
} else {
632-
u64 j;
624+
/* Since we have an estimate of recursion depth, do a sanity check. */
625+
if (depth == 0)
626+
return;
633627

634-
mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) {
635-
u64 n = mdesc_arc_target(hp, j);
636-
const char *n_name;
628+
mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) {
629+
u64 n = mdesc_arc_target(hp, arc);
630+
const char *name = mdesc_node_name(hp, n);
637631

638-
n_name = mdesc_node_name(hp, n);
639-
if (strcmp(n_name, "cpu"))
640-
continue;
632+
if (!strcmp(srch_val, name))
633+
(*func)(hp, n, val);
641634

642-
id = mdesc_get_property(hp, n, "id", NULL);
643-
if (*id < NR_CPUS)
644-
cpu_data(*id).core_id = core_id;
645-
}
646-
}
635+
find_back_node_value(hp, n, srch_val, func, val, depth-1);
647636
}
648637
}
649638

639+
static void __mark_core_id(struct mdesc_handle *hp, u64 node,
640+
int core_id)
641+
{
642+
const u64 *id = mdesc_get_property(hp, node, "id", NULL);
643+
644+
if (*id < num_possible_cpus())
645+
cpu_data(*id).core_id = core_id;
646+
}
647+
648+
static void __mark_sock_id(struct mdesc_handle *hp, u64 node,
649+
int sock_id)
650+
{
651+
const u64 *id = mdesc_get_property(hp, node, "id", NULL);
652+
653+
if (*id < num_possible_cpus())
654+
cpu_data(*id).sock_id = sock_id;
655+
}
656+
657+
static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
658+
int core_id)
659+
{
660+
find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10);
661+
}
662+
663+
static void mark_sock_ids(struct mdesc_handle *hp, u64 mp,
664+
int sock_id)
665+
{
666+
find_back_node_value(hp, mp, "cpu", __mark_sock_id, sock_id, 10);
667+
}
668+
650669
static void set_core_ids(struct mdesc_handle *hp)
651670
{
652671
int idx;
653672
u64 mp;
654673

655674
idx = 1;
675+
676+
/* Identify unique cores by looking for cpus backpointed to by
677+
* level 1 instruction caches.
678+
*/
656679
mdesc_for_each_node_by_name(hp, mp, "cache") {
657680
const u64 *level;
658681
const char *type;
@@ -667,11 +690,72 @@ static void set_core_ids(struct mdesc_handle *hp)
667690
continue;
668691

669692
mark_core_ids(hp, mp, idx);
693+
idx++;
694+
}
695+
}
696+
697+
static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level)
698+
{
699+
u64 mp;
700+
int idx = 1;
701+
int fnd = 0;
702+
703+
/* Identify unique sockets by looking for cpus backpointed to by
704+
* shared level n caches.
705+
*/
706+
mdesc_for_each_node_by_name(hp, mp, "cache") {
707+
const u64 *cur_lvl;
708+
709+
cur_lvl = mdesc_get_property(hp, mp, "level", NULL);
710+
if (*cur_lvl != level)
711+
continue;
712+
713+
mark_sock_ids(hp, mp, idx);
714+
idx++;
715+
fnd = 1;
716+
}
717+
return fnd;
718+
}
719+
720+
static void set_sock_ids_by_socket(struct mdesc_handle *hp, u64 mp)
721+
{
722+
int idx = 1;
670723

724+
mdesc_for_each_node_by_name(hp, mp, "socket") {
725+
u64 a;
726+
727+
mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
728+
u64 t = mdesc_arc_target(hp, a);
729+
const char *name;
730+
const u64 *id;
731+
732+
name = mdesc_node_name(hp, t);
733+
if (strcmp(name, "cpu"))
734+
continue;
735+
736+
id = mdesc_get_property(hp, t, "id", NULL);
737+
if (*id < num_possible_cpus())
738+
cpu_data(*id).sock_id = idx;
739+
}
671740
idx++;
672741
}
673742
}
674743

744+
static void set_sock_ids(struct mdesc_handle *hp)
745+
{
746+
u64 mp;
747+
748+
/* If machine description exposes sockets data use it.
749+
* Otherwise fallback to use shared L3 or L2 caches.
750+
*/
751+
mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets");
752+
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);
757+
}
758+
675759
static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
676760
{
677761
u64 a;
@@ -707,7 +791,6 @@ static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
707791
continue;
708792

709793
mark_proc_ids(hp, mp, idx);
710-
711794
idx++;
712795
}
713796
}
@@ -900,6 +983,7 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask)
900983

901984
set_core_ids(hp);
902985
set_proc_ids(hp);
986+
set_sock_ids(hp);
903987

904988
mdesc_release(hp);
905989

arch/sparc/kernel/pci.c

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,38 @@ static int __init pcibios_init(void)
10021002
subsys_initcall(pcibios_init);
10031003

10041004
#ifdef CONFIG_SYSFS
1005+
1006+
#define SLOT_NAME_SIZE 11 /* Max decimal digits + null in u32 */
1007+
1008+
static void pcie_bus_slot_names(struct pci_bus *pbus)
1009+
{
1010+
struct pci_dev *pdev;
1011+
struct pci_bus *bus;
1012+
1013+
list_for_each_entry(pdev, &pbus->devices, bus_list) {
1014+
char name[SLOT_NAME_SIZE];
1015+
struct pci_slot *pci_slot;
1016+
const u32 *slot_num;
1017+
int len;
1018+
1019+
slot_num = of_get_property(pdev->dev.of_node,
1020+
"physical-slot#", &len);
1021+
1022+
if (slot_num == NULL || len != 4)
1023+
continue;
1024+
1025+
snprintf(name, sizeof(name), "%u", slot_num[0]);
1026+
pci_slot = pci_create_slot(pbus, slot_num[0], name, NULL);
1027+
1028+
if (IS_ERR(pci_slot))
1029+
pr_err("PCI: pci_create_slot returned %ld.\n",
1030+
PTR_ERR(pci_slot));
1031+
}
1032+
1033+
list_for_each_entry(bus, &pbus->children, node)
1034+
pcie_bus_slot_names(bus);
1035+
}
1036+
10051037
static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus)
10061038
{
10071039
const struct pci_slot_names {
@@ -1053,18 +1085,29 @@ static int __init of_pci_slot_init(void)
10531085

10541086
while ((pbus = pci_find_next_bus(pbus)) != NULL) {
10551087
struct device_node *node;
1088+
struct pci_dev *pdev;
1089+
1090+
pdev = list_first_entry(&pbus->devices, struct pci_dev,
1091+
bus_list);
10561092

1057-
if (pbus->self) {
1058-
/* PCI->PCI bridge */
1059-
node = pbus->self->dev.of_node;
1093+
if (pdev && pci_is_pcie(pdev)) {
1094+
pcie_bus_slot_names(pbus);
10601095
} else {
1061-
struct pci_pbm_info *pbm = pbus->sysdata;
10621096

1063-
/* Host PCI controller */
1064-
node = pbm->op->dev.of_node;
1065-
}
1097+
if (pbus->self) {
1098+
1099+
/* PCI->PCI bridge */
1100+
node = pbus->self->dev.of_node;
1101+
1102+
} else {
1103+
struct pci_pbm_info *pbm = pbus->sysdata;
10661104

1067-
pci_bus_slot_names(node, pbus);
1105+
/* Host PCI controller */
1106+
node = pbm->op->dev.of_node;
1107+
}
1108+
1109+
pci_bus_slot_names(node, pbus);
1110+
}
10681111
}
10691112

10701113
return 0;

arch/sparc/kernel/setup_64.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,24 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
255255
}
256256
}
257257

258+
void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
259+
struct sun4v_2insn_patch_entry *end)
260+
{
261+
while (start < end) {
262+
unsigned long addr = start->addr;
263+
264+
*(unsigned int *) (addr + 0) = start->insns[0];
265+
wmb();
266+
__asm__ __volatile__("flush %0" : : "r" (addr + 0));
267+
268+
*(unsigned int *) (addr + 4) = start->insns[1];
269+
wmb();
270+
__asm__ __volatile__("flush %0" : : "r" (addr + 4));
271+
272+
start++;
273+
}
274+
}
275+
258276
static void __init sun4v_patch(void)
259277
{
260278
extern void sun4v_hvapi_init(void);
@@ -267,6 +285,9 @@ static void __init sun4v_patch(void)
267285

268286
sun4v_patch_2insn_range(&__sun4v_2insn_patch,
269287
&__sun4v_2insn_patch_end);
288+
if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7)
289+
sun_m7_patch_2insn_range(&__sun_m7_2insn_patch,
290+
&__sun_m7_2insn_patch_end);
270291

271292
sun4v_hvapi_init();
272293
}

0 commit comments

Comments
 (0)