Commit 2459c609 authored by Linus Torvalds's avatar Linus Torvalds

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
parents fec345ba 494e5b6f
...@@ -24,7 +24,8 @@ typedef struct { ...@@ -24,7 +24,8 @@ typedef struct {
unsigned int icache_line_size; unsigned int icache_line_size;
unsigned int ecache_size; unsigned int ecache_size;
unsigned int ecache_line_size; unsigned int ecache_line_size;
int core_id; unsigned short sock_id;
unsigned short core_id;
int proc_id; int proc_id;
} cpuinfo_sparc; } cpuinfo_sparc;
......
...@@ -308,12 +308,26 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) ...@@ -308,12 +308,26 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
" sllx %1, 32, %1\n" " sllx %1, 32, %1\n"
" or %0, %1, %0\n" " or %0, %1, %0\n"
" .previous\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) : "=r" (mask), "=r" (tmp)
: "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U |
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U),
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_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)); _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V));
return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
...@@ -342,9 +356,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot) ...@@ -342,9 +356,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
" andn %0, %4, %0\n" " andn %0, %4, %0\n"
" or %0, %5, %0\n" " or %0, %5, %0\n"
" .previous\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) : "=r" (val)
: "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U), : "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); return __pgprot(val);
} }
......
...@@ -40,11 +40,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus) ...@@ -40,11 +40,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id) #define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).core_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)) #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
extern cpumask_t cpu_core_map[NR_CPUS]; 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) static inline const struct cpumask *cpu_coregroup_mask(int cpu)
{ {
return &cpu_core_map[cpu]; return &cpu_core_map[cpu];
......
...@@ -79,6 +79,8 @@ struct sun4v_2insn_patch_entry { ...@@ -79,6 +79,8 @@ struct sun4v_2insn_patch_entry {
}; };
extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
__sun4v_2insn_patch_end; __sun4v_2insn_patch_end;
extern struct sun4v_2insn_patch_entry __sun_m7_2insn_patch,
__sun_m7_2insn_patch_end;
#endif /* !(__ASSEMBLY__) */ #endif /* !(__ASSEMBLY__) */
......
...@@ -69,6 +69,8 @@ void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, ...@@ -69,6 +69,8 @@ void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
struct sun4v_1insn_patch_entry *); struct sun4v_1insn_patch_entry *);
void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
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 dcache_parity_tl1_occurred;
extern unsigned int icache_parity_tl1_occurred; extern unsigned int icache_parity_tl1_occurred;
......
...@@ -723,7 +723,6 @@ static int grpci2_of_probe(struct platform_device *ofdev) ...@@ -723,7 +723,6 @@ static int grpci2_of_probe(struct platform_device *ofdev)
err = -ENOMEM; err = -ENOMEM;
goto err1; goto err1;
} }
memset(grpci2priv, 0, sizeof(*grpci2priv));
priv->regs = regs; priv->regs = regs;
priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */ priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */
priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT; priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT;
......
...@@ -614,37 +614,56 @@ static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp) ...@@ -614,37 +614,56 @@ 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; u64 arc;
mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { /* Since we have an estimate of recursion depth, do a sanity check. */
u64 t = mdesc_arc_target(hp, a); if (depth == 0)
const char *name; return;
const u64 *id;
name = mdesc_node_name(hp, t); mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) {
if (!strcmp(name, "cpu")) { u64 n = mdesc_arc_target(hp, arc);
id = mdesc_get_property(hp, t, "id", NULL); const char *name = mdesc_node_name(hp, n);
if (*id < NR_CPUS)
cpu_data(*id).core_id = core_id;
} else {
u64 j;
mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) { if (!strcmp(srch_val, name))
u64 n = mdesc_arc_target(hp, j); (*func)(hp, n, val);
const char *n_name;
n_name = mdesc_node_name(hp, n); find_back_node_value(hp, n, srch_val, func, val, depth-1);
if (strcmp(n_name, "cpu")) }
continue; }
id = mdesc_get_property(hp, n, "id", NULL); static void __mark_core_id(struct mdesc_handle *hp, u64 node,
if (*id < NR_CPUS) 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; 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) static void set_core_ids(struct mdesc_handle *hp)
...@@ -653,6 +672,10 @@ static void set_core_ids(struct mdesc_handle *hp) ...@@ -653,6 +672,10 @@ static void set_core_ids(struct mdesc_handle *hp)
u64 mp; u64 mp;
idx = 1; 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") { mdesc_for_each_node_by_name(hp, mp, "cache") {
const u64 *level; const u64 *level;
const char *type; const char *type;
...@@ -667,11 +690,72 @@ static void set_core_ids(struct mdesc_handle *hp) ...@@ -667,11 +690,72 @@ static void set_core_ids(struct mdesc_handle *hp)
continue; continue;
mark_core_ids(hp, mp, idx); 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++; 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) static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
{ {
u64 a; u64 a;
...@@ -707,7 +791,6 @@ static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name) ...@@ -707,7 +791,6 @@ static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
continue; continue;
mark_proc_ids(hp, mp, idx); mark_proc_ids(hp, mp, idx);
idx++; idx++;
} }
} }
...@@ -900,6 +983,7 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask) ...@@ -900,6 +983,7 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask)
set_core_ids(hp); set_core_ids(hp);
set_proc_ids(hp); set_proc_ids(hp);
set_sock_ids(hp);
mdesc_release(hp); mdesc_release(hp);
......
...@@ -1002,6 +1002,38 @@ static int __init pcibios_init(void) ...@@ -1002,6 +1002,38 @@ static int __init pcibios_init(void)
subsys_initcall(pcibios_init); subsys_initcall(pcibios_init);
#ifdef CONFIG_SYSFS #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) static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus)
{ {
const struct pci_slot_names { const struct pci_slot_names {
...@@ -1053,10 +1085,20 @@ static int __init of_pci_slot_init(void) ...@@ -1053,10 +1085,20 @@ static int __init of_pci_slot_init(void)
while ((pbus = pci_find_next_bus(pbus)) != NULL) { while ((pbus = pci_find_next_bus(pbus)) != NULL) {
struct device_node *node; struct device_node *node;
struct pci_dev *pdev;
pdev = list_first_entry(&pbus->devices, struct pci_dev,
bus_list);
if (pdev && pci_is_pcie(pdev)) {
pcie_bus_slot_names(pbus);
} else {
if (pbus->self) { if (pbus->self) {
/* PCI->PCI bridge */ /* PCI->PCI bridge */
node = pbus->self->dev.of_node; node = pbus->self->dev.of_node;
} else { } else {
struct pci_pbm_info *pbm = pbus->sysdata; struct pci_pbm_info *pbm = pbus->sysdata;
...@@ -1066,6 +1108,7 @@ static int __init of_pci_slot_init(void) ...@@ -1066,6 +1108,7 @@ static int __init of_pci_slot_init(void)
pci_bus_slot_names(node, pbus); pci_bus_slot_names(node, pbus);
} }
}
return 0; return 0;
} }
......
...@@ -255,6 +255,24 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start, ...@@ -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) static void __init sun4v_patch(void)
{ {
extern void sun4v_hvapi_init(void); extern void sun4v_hvapi_init(void);
...@@ -267,6 +285,9 @@ static void __init sun4v_patch(void) ...@@ -267,6 +285,9 @@ static void __init sun4v_patch(void)
sun4v_patch_2insn_range(&__sun4v_2insn_patch, sun4v_patch_2insn_range(&__sun4v_2insn_patch,
&__sun4v_2insn_patch_end); &__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(); sun4v_hvapi_init();
} }
......
...@@ -60,8 +60,12 @@ DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; ...@@ -60,8 +60,12 @@ DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
cpumask_t cpu_core_map[NR_CPUS] __read_mostly = cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
{ [0 ... NR_CPUS-1] = CPU_MASK_NONE }; { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = {
[0 ... NR_CPUS-1] = CPU_MASK_NONE };
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
EXPORT_SYMBOL(cpu_core_map); EXPORT_SYMBOL(cpu_core_map);
EXPORT_SYMBOL(cpu_core_sib_map);
static cpumask_t smp_commenced_mask; static cpumask_t smp_commenced_mask;
...@@ -1243,6 +1247,15 @@ void smp_fill_in_sib_core_maps(void) ...@@ -1243,6 +1247,15 @@ void smp_fill_in_sib_core_maps(void)
} }
} }
for_each_present_cpu(i) {
unsigned int j;
for_each_present_cpu(j) {
if (cpu_data(i).sock_id == cpu_data(j).sock_id)
cpumask_set_cpu(j, &cpu_core_sib_map[i]);
}
}
for_each_present_cpu(i) { for_each_present_cpu(i) {
unsigned int j; unsigned int j;
......
...@@ -138,6 +138,11 @@ SECTIONS ...@@ -138,6 +138,11 @@ SECTIONS
*(.pause_3insn_patch) *(.pause_3insn_patch)
__pause_3insn_patch_end = .; __pause_3insn_patch_end = .;
} }
.sun_m7_2insn_patch : {
__sun_m7_2insn_patch = .;
*(.sun_m7_2insn_patch)
__sun_m7_2insn_patch_end = .;
}
PERCPU_SECTION(SMP_CACHE_BYTES) PERCPU_SECTION(SMP_CACHE_BYTES)
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "init_64.h" #include "init_64.h"
unsigned long kern_linear_pte_xor[4] __read_mostly; unsigned long kern_linear_pte_xor[4] __read_mostly;
static unsigned long page_cache4v_flag;
/* A bitmap, two bits for every 256MB of physical memory. These two /* A bitmap, two bits for every 256MB of physical memory. These two
* bits determine what page size we use for kernel linear * bits determine what page size we use for kernel linear
...@@ -1909,11 +1910,24 @@ static void __init sun4u_linear_pte_xor_finalize(void) ...@@ -1909,11 +1910,24 @@ static void __init sun4u_linear_pte_xor_finalize(void)
static void __init sun4v_linear_pte_xor_finalize(void) static void __init sun4v_linear_pte_xor_finalize(void)
{ {
unsigned long pagecv_flag;
/* Bit 9 of TTE is no longer CV bit on M7 processor and it instead
* enables MCD error. Do not set bit 9 on M7 processor.
*/
switch (sun4v_chip_type) {
case SUN4V_CHIP_SPARC_M7:
pagecv_flag = 0x00;
break;
default:
pagecv_flag = _PAGE_CV_4V;
break;
}
#ifndef CONFIG_DEBUG_PAGEALLOC #ifndef CONFIG_DEBUG_PAGEALLOC
if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) { if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) {
kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^ kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^
PAGE_OFFSET; PAGE_OFFSET;
kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V | kern_linear_pte_xor[1] |= (_PAGE_CP_4V | pagecv_flag |
_PAGE_P_4V | _PAGE_W_4V); _PAGE_P_4V | _PAGE_W_4V);
} else { } else {
kern_linear_pte_xor[1] = kern_linear_pte_xor[0]; kern_linear_pte_xor[1] = kern_linear_pte_xor[0];
...@@ -1922,7 +1936,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) ...@@ -1922,7 +1936,7 @@ static void __init sun4v_linear_pte_xor_finalize(void)
if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) { if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) {
kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^ kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^
PAGE_OFFSET; PAGE_OFFSET;
kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V | kern_linear_pte_xor[2] |= (_PAGE_CP_4V | pagecv_flag |
_PAGE_P_4V | _PAGE_W_4V); _PAGE_P_4V | _PAGE_W_4V);
} else { } else {
kern_linear_pte_xor[2] = kern_linear_pte_xor[1]; kern_linear_pte_xor[2] = kern_linear_pte_xor[1];
...@@ -1931,7 +1945,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) ...@@ -1931,7 +1945,7 @@ static void __init sun4v_linear_pte_xor_finalize(void)
if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) { if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) {
kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^ kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^
PAGE_OFFSET; PAGE_OFFSET;
kern_linear_pte_xor[3] |= (_PAGE_CP_4V | _PAGE_CV_4V | kern_linear_pte_xor[3] |= (_PAGE_CP_4V | pagecv_flag |
_PAGE_P_4V | _PAGE_W_4V); _PAGE_P_4V | _PAGE_W_4V);
} else { } else {
kern_linear_pte_xor[3] = kern_linear_pte_xor[2]; kern_linear_pte_xor[3] = kern_linear_pte_xor[2];
...@@ -1958,6 +1972,13 @@ static phys_addr_t __init available_memory(void) ...@@ -1958,6 +1972,13 @@ static phys_addr_t __init available_memory(void)
return available; return available;
} }
#define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U)
#define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V)
#define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U)
#define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V)
#define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R)
#define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R)
/* We need to exclude reserved regions. This exclusion will include /* We need to exclude reserved regions. This exclusion will include
* vmlinux and initrd. To be more precise the initrd size could be used to * vmlinux and initrd. To be more precise the initrd size could be used to
* compute a new lower limit because it is freed later during initialization. * compute a new lower limit because it is freed later during initialization.
...@@ -2034,6 +2055,25 @@ void __init paging_init(void) ...@@ -2034,6 +2055,25 @@ void __init paging_init(void)
memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb)); memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb));
#endif #endif
/* TTE.cv bit on sparc v9 occupies the same position as TTE.mcde
* bit on M7 processor. This is a conflicting usage of the same
* bit. Enabling TTE.cv on M7 would turn on Memory Corruption
* Detection error on all pages and this will lead to problems
* later. Kernel does not run with MCD enabled and hence rest
* of the required steps to fully configure memory corruption
* detection are not taken. We need to ensure TTE.mcde is not
* set on M7 processor. Compute the value of cacheability
* flag for use later taking this into consideration.
*/
switch (sun4v_chip_type) {
case SUN4V_CHIP_SPARC_M7:
page_cache4v_flag = _PAGE_CP_4V;
break;
default:
page_cache4v_flag = _PAGE_CACHE_4V;
break;
}
if (tlb_type == hypervisor) if (tlb_type == hypervisor)
sun4v_pgprot_init(); sun4v_pgprot_init();
else else
...@@ -2274,13 +2314,6 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -2274,13 +2314,6 @@ void free_initrd_mem(unsigned long start, unsigned long end)
} }
#endif #endif
#define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U)
#define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V)
#define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U)
#define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V)
#define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R)
#define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R)
pgprot_t PAGE_KERNEL __read_mostly; pgprot_t PAGE_KERNEL __read_mostly;
EXPORT_SYMBOL(PAGE_KERNEL); EXPORT_SYMBOL(PAGE_KERNEL);
...@@ -2312,8 +2345,7 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, ...@@ -2312,8 +2345,7 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend,
_PAGE_P_4U | _PAGE_W_4U); _PAGE_P_4U | _PAGE_W_4U);
if (tlb_type == hypervisor) if (tlb_type == hypervisor)
pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V | pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V |
_PAGE_CP_4V | _PAGE_CV_4V | page_cache4v_flag | _PAGE_P_4V | _PAGE_W_4V);
_PAGE_P_4V | _PAGE_W_4V);
pte_base |= _PAGE_PMD_HUGE; pte_base |= _PAGE_PMD_HUGE;
...@@ -2450,14 +2482,14 @@ static void __init sun4v_pgprot_init(void) ...@@ -2450,14 +2482,14 @@ static void __init sun4v_pgprot_init(void)
int i; int i;
PAGE_KERNEL = __pgprot (_PAGE_PRESENT_4V | _PAGE_VALID | PAGE_KERNEL = __pgprot (_PAGE_PRESENT_4V | _PAGE_VALID |
_PAGE_CACHE_4V | _PAGE_P_4V | page_cache4v_flag | _PAGE_P_4V |
__ACCESS_BITS_4V | __DIRTY_BITS_4V | __ACCESS_BITS_4V | __DIRTY_BITS_4V |
_PAGE_EXEC_4V); _PAGE_EXEC_4V);
PAGE_KERNEL_LOCKED = PAGE_KERNEL; PAGE_KERNEL_LOCKED = PAGE_KERNEL;
_PAGE_IE = _PAGE_IE_4V; _PAGE_IE = _PAGE_IE_4V;
_PAGE_E = _PAGE_E_4V; _PAGE_E = _PAGE_E_4V;
_PAGE_CACHE = _PAGE_CACHE_4V; _PAGE_CACHE = page_cache4v_flag;
#ifdef CONFIG_DEBUG_PAGEALLOC #ifdef CONFIG_DEBUG_PAGEALLOC
kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET; kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET;
...@@ -2465,8 +2497,8 @@ static void __init sun4v_pgprot_init(void) ...@@ -2465,8 +2497,8 @@ static void __init sun4v_pgprot_init(void)
kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^ kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^
PAGE_OFFSET; PAGE_OFFSET;
#endif #endif
kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | kern_linear_pte_xor[0] |= (page_cache4v_flag | _PAGE_P_4V |
_PAGE_P_4V | _PAGE_W_4V); _PAGE_W_4V);
for (i = 1; i < 4; i++) for (i = 1; i < 4; i++)
kern_linear_pte_xor[i] = kern_linear_pte_xor[0]; kern_linear_pte_xor[i] = kern_linear_pte_xor[0];
...@@ -2479,12 +2511,12 @@ static void __init sun4v_pgprot_init(void) ...@@ -2479,12 +2511,12 @@ static void __init sun4v_pgprot_init(void)
_PAGE_SZ4MB_4V | _PAGE_SZ512K_4V | _PAGE_SZ4MB_4V | _PAGE_SZ512K_4V |
_PAGE_SZ64K_4V | _PAGE_SZ8K_4V); _PAGE_SZ64K_4V | _PAGE_SZ8K_4V);
page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | _PAGE_CACHE_4V; page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | page_cache4v_flag;
page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag |
__ACCESS_BITS_4V | _PAGE_WRITE_4V | _PAGE_EXEC_4V); __ACCESS_BITS_4V | _PAGE_WRITE_4V | _PAGE_EXEC_4V);
page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag |
__ACCESS_BITS_4V | _PAGE_EXEC_4V); __ACCESS_BITS_4V | _PAGE_EXEC_4V);
page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V | page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag |
__ACCESS_BITS_4V | _PAGE_EXEC_4V); __ACCESS_BITS_4V | _PAGE_EXEC_4V);
page_exec_bit = _PAGE_EXEC_4V; page_exec_bit = _PAGE_EXEC_4V;
...@@ -2542,7 +2574,7 @@ static unsigned long kern_large_tte(unsigned long paddr) ...@@ -2542,7 +2574,7 @@ static unsigned long kern_large_tte(unsigned long paddr)
_PAGE_EXEC_4U | _PAGE_L_4U | _PAGE_W_4U); _PAGE_EXEC_4U | _PAGE_L_4U | _PAGE_W_4U);
if (tlb_type == hypervisor) if (tlb_type == hypervisor)
val = (_PAGE_VALID | _PAGE_SZ4MB_4V | val = (_PAGE_VALID | _PAGE_SZ4MB_4V |
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | page_cache4v_flag | _PAGE_P_4V |
_PAGE_EXEC_4V | _PAGE_W_4V); _PAGE_EXEC_4V | _PAGE_W_4V);
return val | paddr; return val | paddr;
......
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