Commit 1b94d31d authored by Kan Liang's avatar Kan Liang Committed by Peter Zijlstra

perf/x86/intel/uncore: Record the size of mapped area

Perf cannot validate an address before the actual access to MMIO space
of some uncore units, e.g. IMC on TGL. Accessing an invalid address,
which exceeds mapped area, can trigger oops.

Perf never records the size of mapped area. Generic functions, e.g.
uncore_mmio_read_counter(), cannot get the correct size for address
validation.

Add mmio_map_size in intel_uncore_type to record the size of mapped
area. Print warning message if ioremap fails.
Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/1590679169-61823-2-git-send-email-kan.liang@linux.intel.com
parent 2af834f1
...@@ -61,6 +61,7 @@ struct intel_uncore_type { ...@@ -61,6 +61,7 @@ struct intel_uncore_type {
unsigned msr_offset; unsigned msr_offset;
unsigned mmio_offset; unsigned mmio_offset;
}; };
unsigned mmio_map_size;
unsigned num_shared_regs:8; unsigned num_shared_regs:8;
unsigned single_fixed:1; unsigned single_fixed:1;
unsigned pair_ctr_ctl:1; unsigned pair_ctr_ctl:1;
......
...@@ -426,6 +426,7 @@ static const struct attribute_group snb_uncore_imc_format_group = { ...@@ -426,6 +426,7 @@ static const struct attribute_group snb_uncore_imc_format_group = {
static void snb_uncore_imc_init_box(struct intel_uncore_box *box) static void snb_uncore_imc_init_box(struct intel_uncore_box *box)
{ {
struct intel_uncore_type *type = box->pmu->type;
struct pci_dev *pdev = box->pci_dev; struct pci_dev *pdev = box->pci_dev;
int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET; int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET;
resource_size_t addr; resource_size_t addr;
...@@ -441,7 +442,10 @@ static void snb_uncore_imc_init_box(struct intel_uncore_box *box) ...@@ -441,7 +442,10 @@ static void snb_uncore_imc_init_box(struct intel_uncore_box *box)
addr &= ~(PAGE_SIZE - 1); addr &= ~(PAGE_SIZE - 1);
box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE); box->io_addr = ioremap(addr, type->mmio_map_size);
if (!box->io_addr)
pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL; box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL;
} }
...@@ -597,6 +601,7 @@ static struct intel_uncore_type snb_uncore_imc = { ...@@ -597,6 +601,7 @@ static struct intel_uncore_type snb_uncore_imc = {
.num_counters = 2, .num_counters = 2,
.num_boxes = 1, .num_boxes = 1,
.num_freerunning_types = SNB_PCI_UNCORE_IMC_FREERUNNING_TYPE_MAX, .num_freerunning_types = SNB_PCI_UNCORE_IMC_FREERUNNING_TYPE_MAX,
.mmio_map_size = SNB_UNCORE_PCI_IMC_MAP_SIZE,
.freerunning = snb_uncore_imc_freerunning, .freerunning = snb_uncore_imc_freerunning,
.event_descs = snb_uncore_imc_events, .event_descs = snb_uncore_imc_events,
.format_group = &snb_uncore_imc_format_group, .format_group = &snb_uncore_imc_format_group,
...@@ -1157,6 +1162,7 @@ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box) ...@@ -1157,6 +1162,7 @@ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
{ {
struct pci_dev *pdev = tgl_uncore_get_mc_dev(); struct pci_dev *pdev = tgl_uncore_get_mc_dev();
struct intel_uncore_pmu *pmu = box->pmu; struct intel_uncore_pmu *pmu = box->pmu;
struct intel_uncore_type *type = pmu->type;
resource_size_t addr; resource_size_t addr;
u32 mch_bar; u32 mch_bar;
...@@ -1179,7 +1185,9 @@ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box) ...@@ -1179,7 +1185,9 @@ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
addr |= ((resource_size_t)mch_bar << 32); addr |= ((resource_size_t)mch_bar << 32);
#endif #endif
box->io_addr = ioremap(addr, TGL_UNCORE_PCI_IMC_MAP_SIZE); box->io_addr = ioremap(addr, type->mmio_map_size);
if (!box->io_addr)
pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
} }
static struct intel_uncore_ops tgl_uncore_imc_freerunning_ops = { static struct intel_uncore_ops tgl_uncore_imc_freerunning_ops = {
...@@ -1205,6 +1213,7 @@ static struct intel_uncore_type tgl_uncore_imc_free_running = { ...@@ -1205,6 +1213,7 @@ static struct intel_uncore_type tgl_uncore_imc_free_running = {
.num_counters = 3, .num_counters = 3,
.num_boxes = 2, .num_boxes = 2,
.num_freerunning_types = TGL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX, .num_freerunning_types = TGL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX,
.mmio_map_size = TGL_UNCORE_PCI_IMC_MAP_SIZE,
.freerunning = tgl_uncore_imc_freerunning, .freerunning = tgl_uncore_imc_freerunning,
.ops = &tgl_uncore_imc_freerunning_ops, .ops = &tgl_uncore_imc_freerunning_ops,
.event_descs = tgl_uncore_imc_events, .event_descs = tgl_uncore_imc_events,
......
...@@ -4421,6 +4421,7 @@ static void __snr_uncore_mmio_init_box(struct intel_uncore_box *box, ...@@ -4421,6 +4421,7 @@ static void __snr_uncore_mmio_init_box(struct intel_uncore_box *box,
unsigned int box_ctl, int mem_offset) unsigned int box_ctl, int mem_offset)
{ {
struct pci_dev *pdev = snr_uncore_get_mc_dev(box->dieid); struct pci_dev *pdev = snr_uncore_get_mc_dev(box->dieid);
struct intel_uncore_type *type = box->pmu->type;
resource_size_t addr; resource_size_t addr;
u32 pci_dword; u32 pci_dword;
...@@ -4435,9 +4436,11 @@ static void __snr_uncore_mmio_init_box(struct intel_uncore_box *box, ...@@ -4435,9 +4436,11 @@ static void __snr_uncore_mmio_init_box(struct intel_uncore_box *box,
addr += box_ctl; addr += box_ctl;
box->io_addr = ioremap(addr, SNR_IMC_MMIO_SIZE); box->io_addr = ioremap(addr, type->mmio_map_size);
if (!box->io_addr) if (!box->io_addr) {
pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
return; return;
}
writel(IVBEP_PMON_BOX_CTL_INT, box->io_addr); writel(IVBEP_PMON_BOX_CTL_INT, box->io_addr);
} }
...@@ -4530,6 +4533,7 @@ static struct intel_uncore_type snr_uncore_imc = { ...@@ -4530,6 +4533,7 @@ static struct intel_uncore_type snr_uncore_imc = {
.event_mask = SNBEP_PMON_RAW_EVENT_MASK, .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
.box_ctl = SNR_IMC_MMIO_PMON_BOX_CTL, .box_ctl = SNR_IMC_MMIO_PMON_BOX_CTL,
.mmio_offset = SNR_IMC_MMIO_OFFSET, .mmio_offset = SNR_IMC_MMIO_OFFSET,
.mmio_map_size = SNR_IMC_MMIO_SIZE,
.ops = &snr_uncore_mmio_ops, .ops = &snr_uncore_mmio_ops,
.format_group = &skx_uncore_format_group, .format_group = &skx_uncore_format_group,
}; };
...@@ -4570,6 +4574,7 @@ static struct intel_uncore_type snr_uncore_imc_free_running = { ...@@ -4570,6 +4574,7 @@ static struct intel_uncore_type snr_uncore_imc_free_running = {
.num_counters = 3, .num_counters = 3,
.num_boxes = 1, .num_boxes = 1,
.num_freerunning_types = SNR_IMC_FREERUNNING_TYPE_MAX, .num_freerunning_types = SNR_IMC_FREERUNNING_TYPE_MAX,
.mmio_map_size = SNR_IMC_MMIO_SIZE,
.freerunning = snr_imc_freerunning, .freerunning = snr_imc_freerunning,
.ops = &snr_uncore_imc_freerunning_ops, .ops = &snr_uncore_imc_freerunning_ops,
.event_descs = snr_uncore_imc_freerunning_events, .event_descs = snr_uncore_imc_freerunning_events,
...@@ -4987,6 +4992,7 @@ static struct intel_uncore_type icx_uncore_imc = { ...@@ -4987,6 +4992,7 @@ static struct intel_uncore_type icx_uncore_imc = {
.event_mask = SNBEP_PMON_RAW_EVENT_MASK, .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
.box_ctl = SNR_IMC_MMIO_PMON_BOX_CTL, .box_ctl = SNR_IMC_MMIO_PMON_BOX_CTL,
.mmio_offset = SNR_IMC_MMIO_OFFSET, .mmio_offset = SNR_IMC_MMIO_OFFSET,
.mmio_map_size = SNR_IMC_MMIO_SIZE,
.ops = &icx_uncore_mmio_ops, .ops = &icx_uncore_mmio_ops,
.format_group = &skx_uncore_format_group, .format_group = &skx_uncore_format_group,
}; };
...@@ -5044,6 +5050,7 @@ static struct intel_uncore_type icx_uncore_imc_free_running = { ...@@ -5044,6 +5050,7 @@ static struct intel_uncore_type icx_uncore_imc_free_running = {
.num_counters = 5, .num_counters = 5,
.num_boxes = 4, .num_boxes = 4,
.num_freerunning_types = ICX_IMC_FREERUNNING_TYPE_MAX, .num_freerunning_types = ICX_IMC_FREERUNNING_TYPE_MAX,
.mmio_map_size = SNR_IMC_MMIO_SIZE,
.freerunning = icx_imc_freerunning, .freerunning = icx_imc_freerunning,
.ops = &icx_uncore_imc_freerunning_ops, .ops = &icx_uncore_imc_freerunning_ops,
.event_descs = icx_uncore_imc_freerunning_events, .event_descs = icx_uncore_imc_freerunning_events,
......
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