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 updates from David Miller:

 1) Recognize M8 cpus, just basic chip ID matching, from Allen Pais.

 2) Prevent crashes when bringing up sunvdc virtual block devices in
    some environments. From Jim Quigley.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
  sunvdc: prevent sunvdc panic when mpgroup disk added to guest domain
  sparc64: Increase max_phys_bits to 51 and VA bits to 53 for M8.
  sparc64: recognize and support sparc M8 cpu type
  sparc64: properly name the cpu constants
  • Loading branch information
Linus Torvalds committed Aug 10, 2017
2 parents 8d31f80 + 3ee7059 commit f213ad3
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 11 deletions.
16 changes: 16 additions & 0 deletions arch/sparc/include/asm/spitfire.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,26 @@
#define SUN4V_CHIP_NIAGARA5 0x05
#define SUN4V_CHIP_SPARC_M6 0x06
#define SUN4V_CHIP_SPARC_M7 0x07
#define SUN4V_CHIP_SPARC_M8 0x08
#define SUN4V_CHIP_SPARC64X 0x8a
#define SUN4V_CHIP_SPARC_SN 0x8b
#define SUN4V_CHIP_UNKNOWN 0xff

/*
* The following CPU_ID_xxx constants are used
* to identify the CPU type in the setup phase
* (see head_64.S)
*/
#define CPU_ID_NIAGARA1 ('1')
#define CPU_ID_NIAGARA2 ('2')
#define CPU_ID_NIAGARA3 ('3')
#define CPU_ID_NIAGARA4 ('4')
#define CPU_ID_NIAGARA5 ('5')
#define CPU_ID_M6 ('6')
#define CPU_ID_M7 ('7')
#define CPU_ID_M8 ('8')
#define CPU_ID_SONOMA1 ('N')

#ifndef __ASSEMBLY__

enum ultra_tlb_layout {
Expand Down
6 changes: 6 additions & 0 deletions arch/sparc/kernel/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,12 @@ static void __init sun4v_cpu_probe(void)
sparc_pmu_type = "sparc-m7";
break;

case SUN4V_CHIP_SPARC_M8:
sparc_cpu_type = "SPARC-M8";
sparc_fpu_type = "SPARC-M8 integrated FPU";
sparc_pmu_type = "sparc-m8";
break;

case SUN4V_CHIP_SPARC_SN:
sparc_cpu_type = "SPARC-SN";
sparc_fpu_type = "SPARC-SN integrated FPU";
Expand Down
1 change: 1 addition & 0 deletions arch/sparc/kernel/cpumap.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index)
case SUN4V_CHIP_NIAGARA5:
case SUN4V_CHIP_SPARC_M6:
case SUN4V_CHIP_SPARC_M7:
case SUN4V_CHIP_SPARC_M8:
case SUN4V_CHIP_SPARC_SN:
case SUN4V_CHIP_SPARC64X:
rover_inc_table = niagara_iterate_method;
Expand Down
22 changes: 14 additions & 8 deletions arch/sparc/kernel/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -424,22 +424,25 @@ EXPORT_SYMBOL(sun4v_chip_type)
nop

70: ldub [%g1 + 7], %g2
cmp %g2, '3'
cmp %g2, CPU_ID_NIAGARA3
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA3, %g4
cmp %g2, '4'
cmp %g2, CPU_ID_NIAGARA4
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA4, %g4
cmp %g2, '5'
cmp %g2, CPU_ID_NIAGARA5
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA5, %g4
cmp %g2, '6'
cmp %g2, CPU_ID_M6
be,pt %xcc, 5f
mov SUN4V_CHIP_SPARC_M6, %g4
cmp %g2, '7'
cmp %g2, CPU_ID_M7
be,pt %xcc, 5f
mov SUN4V_CHIP_SPARC_M7, %g4
cmp %g2, 'N'
cmp %g2, CPU_ID_M8
be,pt %xcc, 5f
mov SUN4V_CHIP_SPARC_M8, %g4
cmp %g2, CPU_ID_SONOMA1
be,pt %xcc, 5f
mov SUN4V_CHIP_SPARC_SN, %g4
ba,pt %xcc, 49f
Expand All @@ -448,10 +451,10 @@ EXPORT_SYMBOL(sun4v_chip_type)
91: sethi %hi(prom_cpu_compatible), %g1
or %g1, %lo(prom_cpu_compatible), %g1
ldub [%g1 + 17], %g2
cmp %g2, '1'
cmp %g2, CPU_ID_NIAGARA1
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA1, %g4
cmp %g2, '2'
cmp %g2, CPU_ID_NIAGARA2
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA2, %g4

Expand Down Expand Up @@ -600,6 +603,9 @@ niagara_tlb_fixup:
be,pt %xcc, niagara4_patch
nop
cmp %g1, SUN4V_CHIP_SPARC_M7
be,pt %xcc, niagara4_patch
nop
cmp %g1, SUN4V_CHIP_SPARC_M8
be,pt %xcc, niagara4_patch
nop
cmp %g1, SUN4V_CHIP_SPARC_SN
Expand Down
15 changes: 13 additions & 2 deletions arch/sparc/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,17 @@ 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 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_SN)

switch (sun4v_chip_type) {
case SUN4V_CHIP_SPARC_M7:
case SUN4V_CHIP_SPARC_M8:
case SUN4V_CHIP_SPARC_SN:
sun_m7_patch_2insn_range(&__sun_m7_2insn_patch,
&__sun_m7_2insn_patch_end);
break;
default:
break;
}

sun4v_hvapi_init();
}
Expand Down Expand Up @@ -529,6 +536,7 @@ static void __init init_sparc64_elf_hwcap(void)
sun4v_chip_type == SUN4V_CHIP_NIAGARA5 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M6 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M7 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M8 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_SN ||
sun4v_chip_type == SUN4V_CHIP_SPARC64X)
cap |= HWCAP_SPARC_BLKINIT;
Expand All @@ -538,6 +546,7 @@ static void __init init_sparc64_elf_hwcap(void)
sun4v_chip_type == SUN4V_CHIP_NIAGARA5 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M6 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M7 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M8 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_SN ||
sun4v_chip_type == SUN4V_CHIP_SPARC64X)
cap |= HWCAP_SPARC_N2;
Expand Down Expand Up @@ -568,6 +577,7 @@ static void __init init_sparc64_elf_hwcap(void)
sun4v_chip_type == SUN4V_CHIP_NIAGARA5 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M6 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M7 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M8 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_SN ||
sun4v_chip_type == SUN4V_CHIP_SPARC64X)
cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 |
Expand All @@ -578,6 +588,7 @@ static void __init init_sparc64_elf_hwcap(void)
sun4v_chip_type == SUN4V_CHIP_NIAGARA5 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M6 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M7 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M8 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_SN ||
sun4v_chip_type == SUN4V_CHIP_SPARC64X)
cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC |
Expand Down
14 changes: 13 additions & 1 deletion arch/sparc/mm/init_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1944,12 +1944,22 @@ static void __init setup_page_offset(void)
break;
case SUN4V_CHIP_SPARC_M7:
case SUN4V_CHIP_SPARC_SN:
default:
/* M7 and later support 52-bit virtual addresses. */
sparc64_va_hole_top = 0xfff8000000000000UL;
sparc64_va_hole_bottom = 0x0008000000000000UL;
max_phys_bits = 49;
break;
case SUN4V_CHIP_SPARC_M8:
default:
/* M8 and later support 54-bit virtual addresses.
* However, restricting M8 and above VA bits to 53
* as 4-level page table cannot support more than
* 53 VA bits.
*/
sparc64_va_hole_top = 0xfff0000000000000UL;
sparc64_va_hole_bottom = 0x0010000000000000UL;
max_phys_bits = 51;
break;
}
}

Expand Down Expand Up @@ -2161,6 +2171,7 @@ static void __init sun4v_linear_pte_xor_finalize(void)
*/
switch (sun4v_chip_type) {
case SUN4V_CHIP_SPARC_M7:
case SUN4V_CHIP_SPARC_M8:
case SUN4V_CHIP_SPARC_SN:
pagecv_flag = 0x00;
break;
Expand Down Expand Up @@ -2313,6 +2324,7 @@ void __init paging_init(void)
*/
switch (sun4v_chip_type) {
case SUN4V_CHIP_SPARC_M7:
case SUN4V_CHIP_SPARC_M8:
case SUN4V_CHIP_SPARC_SN:
page_cache4v_flag = _PAGE_CP_4V;
break;
Expand Down
61 changes: 61 additions & 0 deletions drivers/block/sunvdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,56 @@ static void print_version(void)
printk(KERN_INFO "%s", version);
}

struct vdc_check_port_data {
int dev_no;
char *type;
};

static int vdc_device_probed(struct device *dev, void *arg)
{
struct vio_dev *vdev = to_vio_dev(dev);
struct vdc_check_port_data *port_data;

port_data = (struct vdc_check_port_data *)arg;

if ((vdev->dev_no == port_data->dev_no) &&
(!(strcmp((char *)&vdev->type, port_data->type))) &&
dev_get_drvdata(dev)) {
/* This device has already been configured
* by vdc_port_probe()
*/
return 1;
} else {
return 0;
}
}

/* Determine whether the VIO device is part of an mpgroup
* by locating all the virtual-device-port nodes associated
* with the parent virtual-device node for the VIO device
* and checking whether any of these nodes are vdc-ports
* which have already been configured.
*
* Returns true if this device is part of an mpgroup and has
* already been probed.
*/
static bool vdc_port_mpgroup_check(struct vio_dev *vdev)
{
struct vdc_check_port_data port_data;
struct device *dev;

port_data.dev_no = vdev->dev_no;
port_data.type = (char *)&vdev->type;

dev = device_find_child(vdev->dev.parent, &port_data,
vdc_device_probed);

if (dev)
return true;

return false;
}

static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
{
struct mdesc_handle *hp;
Expand All @@ -893,6 +943,14 @@ static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
goto err_out_release_mdesc;
}

/* Check if this device is part of an mpgroup */
if (vdc_port_mpgroup_check(vdev)) {
printk(KERN_WARNING
"VIO: Ignoring extra vdisk port %s",
dev_name(&vdev->dev));
goto err_out_release_mdesc;
}

port = kzalloc(sizeof(*port), GFP_KERNEL);
err = -ENOMEM;
if (!port) {
Expand Down Expand Up @@ -943,6 +1001,9 @@ static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
if (err)
goto err_out_free_tx_ring;

/* Note that the device driver_data is used to determine
* whether the port has been probed.
*/
dev_set_drvdata(&vdev->dev, port);

mdesc_release(hp);
Expand Down

0 comments on commit f213ad3

Please sign in to comment.