Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Linus Torvalds committed Jun 2, 2015
2 parents fec345b + 494e5b6 commit 2459c60
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 59 deletions.
3 changes: 2 additions & 1 deletion arch/sparc/include/asm/cpudata_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ typedef struct {
unsigned int icache_line_size;
unsigned int ecache_size;
unsigned int ecache_line_size;
int core_id;
unsigned short sock_id;
unsigned short core_id;
int proc_id;
} cpuinfo_sparc;

Expand Down
22 changes: 21 additions & 1 deletion arch/sparc/include/asm/pgtable_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,12 +308,26 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
" sllx %1, 32, %1\n"
" or %0, %1, %0\n"
" .previous\n"
" .section .sun_m7_2insn_patch, \"ax\"\n"
" .word 661b\n"
" sethi %%uhi(%4), %1\n"
" sethi %%hi(%4), %0\n"
" .word 662b\n"
" or %1, %%ulo(%4), %1\n"
" or %0, %%lo(%4), %0\n"
" .word 663b\n"
" sllx %1, 32, %1\n"
" or %0, %1, %0\n"
" .previous\n"
: "=r" (mask), "=r" (tmp)
: "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U |
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U),
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V |
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V),
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
_PAGE_CP_4V | _PAGE_E_4V |
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V));

return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
Expand Down Expand Up @@ -342,9 +356,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
" andn %0, %4, %0\n"
" or %0, %5, %0\n"
" .previous\n"
" .section .sun_m7_2insn_patch, \"ax\"\n"
" .word 661b\n"
" andn %0, %6, %0\n"
" or %0, %5, %0\n"
" .previous\n"
: "=r" (val)
: "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
"i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V));
"i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V),
"i" (_PAGE_CP_4V));

return __pgprot(val);
}
Expand Down
3 changes: 2 additions & 1 deletion arch/sparc/include/asm/topology_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
#ifdef CONFIG_SMP
#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).core_id)
#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
#define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu])
#define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
#endif /* CONFIG_SMP */

extern cpumask_t cpu_core_map[NR_CPUS];
extern cpumask_t cpu_core_sib_map[NR_CPUS];
static inline const struct cpumask *cpu_coregroup_mask(int cpu)
{
return &cpu_core_map[cpu];
Expand Down
2 changes: 2 additions & 0 deletions arch/sparc/include/asm/trap_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ struct sun4v_2insn_patch_entry {
};
extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
__sun4v_2insn_patch_end;
extern struct sun4v_2insn_patch_entry __sun_m7_2insn_patch,
__sun_m7_2insn_patch_end;


#endif /* !(__ASSEMBLY__) */
Expand Down
2 changes: 2 additions & 0 deletions arch/sparc/kernel/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
struct sun4v_1insn_patch_entry *);
void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
struct sun4v_2insn_patch_entry *);
void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *,
struct sun4v_2insn_patch_entry *);
extern unsigned int dcache_parity_tl1_occurred;
extern unsigned int icache_parity_tl1_occurred;

Expand Down
1 change: 0 additions & 1 deletion arch/sparc/kernel/leon_pci_grpci2.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,6 @@ static int grpci2_of_probe(struct platform_device *ofdev)
err = -ENOMEM;
goto err1;
}
memset(grpci2priv, 0, sizeof(*grpci2priv));
priv->regs = regs;
priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */
priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT;
Expand Down
136 changes: 110 additions & 26 deletions arch/sparc/kernel/mdesc.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,45 +614,68 @@ static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp)
}
}

static void mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id)
static void find_back_node_value(struct mdesc_handle *hp, u64 node,
char *srch_val,
void (*func)(struct mdesc_handle *, u64, int),
u64 val, int depth)
{
u64 a;

mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
u64 t = mdesc_arc_target(hp, a);
const char *name;
const u64 *id;
u64 arc;

name = mdesc_node_name(hp, t);
if (!strcmp(name, "cpu")) {
id = mdesc_get_property(hp, t, "id", NULL);
if (*id < NR_CPUS)
cpu_data(*id).core_id = core_id;
} else {
u64 j;
/* Since we have an estimate of recursion depth, do a sanity check. */
if (depth == 0)
return;

mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) {
u64 n = mdesc_arc_target(hp, j);
const char *n_name;
mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) {
u64 n = mdesc_arc_target(hp, arc);
const char *name = mdesc_node_name(hp, n);

n_name = mdesc_node_name(hp, n);
if (strcmp(n_name, "cpu"))
continue;
if (!strcmp(srch_val, name))
(*func)(hp, n, val);

id = mdesc_get_property(hp, n, "id", NULL);
if (*id < NR_CPUS)
cpu_data(*id).core_id = core_id;
}
}
find_back_node_value(hp, n, srch_val, func, val, depth-1);
}
}

static void __mark_core_id(struct mdesc_handle *hp, u64 node,
int core_id)
{
const u64 *id = mdesc_get_property(hp, node, "id", NULL);

if (*id < num_possible_cpus())
cpu_data(*id).core_id = core_id;
}

static void __mark_sock_id(struct mdesc_handle *hp, u64 node,
int sock_id)
{
const u64 *id = mdesc_get_property(hp, node, "id", NULL);

if (*id < num_possible_cpus())
cpu_data(*id).sock_id = sock_id;
}

static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
int core_id)
{
find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10);
}

static void mark_sock_ids(struct mdesc_handle *hp, u64 mp,
int sock_id)
{
find_back_node_value(hp, mp, "cpu", __mark_sock_id, sock_id, 10);
}

static void set_core_ids(struct mdesc_handle *hp)
{
int idx;
u64 mp;

idx = 1;

/* Identify unique cores by looking for cpus backpointed to by
* level 1 instruction caches.
*/
mdesc_for_each_node_by_name(hp, mp, "cache") {
const u64 *level;
const char *type;
Expand All @@ -667,11 +690,72 @@ static void set_core_ids(struct mdesc_handle *hp)
continue;

mark_core_ids(hp, mp, idx);
idx++;
}
}

static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level)
{
u64 mp;
int idx = 1;
int fnd = 0;

/* Identify unique sockets by looking for cpus backpointed to by
* shared level n caches.
*/
mdesc_for_each_node_by_name(hp, mp, "cache") {
const u64 *cur_lvl;

cur_lvl = mdesc_get_property(hp, mp, "level", NULL);
if (*cur_lvl != level)
continue;

mark_sock_ids(hp, mp, idx);
idx++;
fnd = 1;
}
return fnd;
}

static void set_sock_ids_by_socket(struct mdesc_handle *hp, u64 mp)
{
int idx = 1;

mdesc_for_each_node_by_name(hp, mp, "socket") {
u64 a;

mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
u64 t = mdesc_arc_target(hp, a);
const char *name;
const u64 *id;

name = mdesc_node_name(hp, t);
if (strcmp(name, "cpu"))
continue;

id = mdesc_get_property(hp, t, "id", NULL);
if (*id < num_possible_cpus())
cpu_data(*id).sock_id = idx;
}
idx++;
}
}

static void set_sock_ids(struct mdesc_handle *hp)
{
u64 mp;

/* If machine description exposes sockets data use it.
* Otherwise fallback to use shared L3 or L2 caches.
*/
mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets");
if (mp != MDESC_NODE_NULL)
return set_sock_ids_by_socket(hp, mp);

if (!set_sock_ids_by_cache(hp, 3))
set_sock_ids_by_cache(hp, 2);
}

static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
{
u64 a;
Expand Down Expand Up @@ -707,7 +791,6 @@ static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
continue;

mark_proc_ids(hp, mp, idx);

idx++;
}
}
Expand Down Expand Up @@ -900,6 +983,7 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask)

set_core_ids(hp);
set_proc_ids(hp);
set_sock_ids(hp);

mdesc_release(hp);

Expand Down
59 changes: 51 additions & 8 deletions arch/sparc/kernel/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,38 @@ static int __init pcibios_init(void)
subsys_initcall(pcibios_init);

#ifdef CONFIG_SYSFS

#define SLOT_NAME_SIZE 11 /* Max decimal digits + null in u32 */

static void pcie_bus_slot_names(struct pci_bus *pbus)
{
struct pci_dev *pdev;
struct pci_bus *bus;

list_for_each_entry(pdev, &pbus->devices, bus_list) {
char name[SLOT_NAME_SIZE];
struct pci_slot *pci_slot;
const u32 *slot_num;
int len;

slot_num = of_get_property(pdev->dev.of_node,
"physical-slot#", &len);

if (slot_num == NULL || len != 4)
continue;

snprintf(name, sizeof(name), "%u", slot_num[0]);
pci_slot = pci_create_slot(pbus, slot_num[0], name, NULL);

if (IS_ERR(pci_slot))
pr_err("PCI: pci_create_slot returned %ld.\n",
PTR_ERR(pci_slot));
}

list_for_each_entry(bus, &pbus->children, node)
pcie_bus_slot_names(bus);
}

static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus)
{
const struct pci_slot_names {
Expand Down Expand Up @@ -1053,18 +1085,29 @@ static int __init of_pci_slot_init(void)

while ((pbus = pci_find_next_bus(pbus)) != NULL) {
struct device_node *node;
struct pci_dev *pdev;

pdev = list_first_entry(&pbus->devices, struct pci_dev,
bus_list);

if (pbus->self) {
/* PCI->PCI bridge */
node = pbus->self->dev.of_node;
if (pdev && pci_is_pcie(pdev)) {
pcie_bus_slot_names(pbus);
} else {
struct pci_pbm_info *pbm = pbus->sysdata;

/* Host PCI controller */
node = pbm->op->dev.of_node;
}
if (pbus->self) {

/* PCI->PCI bridge */
node = pbus->self->dev.of_node;

} else {
struct pci_pbm_info *pbm = pbus->sysdata;

pci_bus_slot_names(node, pbus);
/* Host PCI controller */
node = pbm->op->dev.of_node;
}

pci_bus_slot_names(node, pbus);
}
}

return 0;
Expand Down
21 changes: 21 additions & 0 deletions arch/sparc/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,24 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
}
}

void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
struct sun4v_2insn_patch_entry *end)
{
while (start < end) {
unsigned long addr = start->addr;

*(unsigned int *) (addr + 0) = start->insns[0];
wmb();
__asm__ __volatile__("flush %0" : : "r" (addr + 0));

*(unsigned int *) (addr + 4) = start->insns[1];
wmb();
__asm__ __volatile__("flush %0" : : "r" (addr + 4));

start++;
}
}

static void __init sun4v_patch(void)
{
extern void sun4v_hvapi_init(void);
Expand All @@ -267,6 +285,9 @@ static void __init sun4v_patch(void)

sun4v_patch_2insn_range(&__sun4v_2insn_patch,
&__sun4v_2insn_patch_end);
if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7)
sun_m7_patch_2insn_range(&__sun_m7_2insn_patch,
&__sun_m7_2insn_patch_end);

sun4v_hvapi_init();
}
Expand Down
Loading

0 comments on commit 2459c60

Please sign in to comment.