diff options
Diffstat (limited to 'arch')
136 files changed, 1355 insertions, 2165 deletions
diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index feed50ce89fa..caa270261521 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -3,23 +3,19 @@ generic-y += bugs.h generic-y += compat.h generic-y += device.h generic-y += div64.h -generic-y += dma-mapping.h generic-y += emergency-restart.h generic-y += extable.h -generic-y += fb.h generic-y += ftrace.h generic-y += hardirq.h generic-y += hw_irq.h generic-y += irq_regs.h generic-y += irq_work.h -generic-y += kmap_types.h generic-y += local.h generic-y += local64.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h generic-y += msi.h generic-y += parport.h -generic-y += pci.h generic-y += percpu.h generic-y += preempt.h generic-y += topology.h diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 49bfbd879caa..f1b86cef0905 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -216,6 +216,14 @@ struct bcr_fp_arcv2 { #endif }; +struct bcr_actionpoint { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int pad:21, min:1, num:2, ver:8; +#else + unsigned int ver:8, num:2, min:1, pad:21; +#endif +}; + #include <soc/arc/timers.h> struct bcr_bpu_arcompact { @@ -283,7 +291,7 @@ struct cpuinfo_arc_cache { }; struct cpuinfo_arc_bpu { - unsigned int ver, full, num_cache, num_pred; + unsigned int ver, full, num_cache, num_pred, ret_stk; }; struct cpuinfo_arc_ccm { @@ -302,7 +310,7 @@ struct cpuinfo_arc { struct { unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, swape:1, pad1:2, fpu_sp:1, fpu_dp:1, dual:1, dual_enb:1, pad2:4, - debug:1, ap:1, smart:1, rtt:1, pad3:4, + ap_num:4, ap_full:1, smart:1, rtt:1, pad3:1, timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4; } extn; struct bcr_mpy extn_mpy; diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h index ee9246184033..202b74c339f0 100644 --- a/arch/arc/include/asm/bitops.h +++ b/arch/arc/include/asm/bitops.h @@ -340,7 +340,7 @@ static inline __attribute__ ((const)) int __fls(unsigned long x) /* * __ffs: Similar to ffs, but zero based (0-31) */ -static inline __attribute__ ((const)) int __ffs(unsigned long word) +static inline __attribute__ ((const)) unsigned long __ffs(unsigned long word) { if (!word) return word; @@ -400,9 +400,9 @@ static inline __attribute__ ((const)) int ffs(unsigned long x) /* * __ffs: Similar to ffs, but zero based (0-31) */ -static inline __attribute__ ((const)) int __ffs(unsigned long x) +static inline __attribute__ ((const)) unsigned long __ffs(unsigned long x) { - int n; + unsigned long n; asm volatile( " ffs.f %0, %1 \n" /* 0:31; 31(Z) if src 0 */ diff --git a/arch/arc/include/asm/perf_event.h b/arch/arc/include/asm/perf_event.h index 9185541035cc..6958545390f0 100644 --- a/arch/arc/include/asm/perf_event.h +++ b/arch/arc/include/asm/perf_event.h @@ -103,7 +103,8 @@ static const char * const arc_pmu_ev_hw_map[] = { /* counts condition */ [PERF_COUNT_HW_INSTRUCTIONS] = "iall", - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmp", /* Excludes ZOL jumps */ + /* All jump instructions that are taken */ + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmptak", [PERF_COUNT_ARC_BPOK] = "bpok", /* NP-NT, PT-T, PNT-NT */ #ifdef CONFIG_ISA_ARCV2 [PERF_COUNT_HW_BRANCH_MISSES] = "bpmp", diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c index 8aec462d90fb..861a8aea51f9 100644 --- a/arch/arc/kernel/perf_event.c +++ b/arch/arc/kernel/perf_event.c @@ -1,15 +1,10 @@ -/* - * Linux performance counter support for ARC700 series - * - * Copyright (C) 2013-2015 Synopsys, Inc. (www.synopsys.com) - * - * This code is inspired by the perf support of various other architectures. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Linux performance counter support for ARC CPUs. +// This code is inspired by the perf support of various other architectures. +// +// Copyright (C) 2013-2018 Synopsys, Inc. (www.synopsys.com) + #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/module.h> @@ -19,12 +14,31 @@ #include <asm/arcregs.h> #include <asm/stacktrace.h> +/* HW holds 8 symbols + one for null terminator */ +#define ARCPMU_EVENT_NAME_LEN 9 + +enum arc_pmu_attr_groups { + ARCPMU_ATTR_GR_EVENTS, + ARCPMU_ATTR_GR_FORMATS, + ARCPMU_NR_ATTR_GR +}; + +struct arc_pmu_raw_event_entry { + char name[ARCPMU_EVENT_NAME_LEN]; +}; + struct arc_pmu { struct pmu pmu; unsigned int irq; int n_counters; + int n_events; u64 max_period; int ev_hw_idx[PERF_COUNT_ARC_HW_MAX]; + + struct arc_pmu_raw_event_entry *raw_entry; + struct attribute **attrs; + struct perf_pmu_events_attr *attr; + const struct attribute_group *attr_groups[ARCPMU_NR_ATTR_GR + 1]; }; struct arc_pmu_cpu { @@ -49,6 +63,7 @@ static int callchain_trace(unsigned int addr, void *data) { struct arc_callchain_trace *ctrl = data; struct perf_callchain_entry_ctx *entry = ctrl->perf_stuff; + perf_callchain_store(entry, addr); if (ctrl->depth++ < 3) @@ -57,8 +72,8 @@ static int callchain_trace(unsigned int addr, void *data) return -1; } -void -perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) +void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, + struct pt_regs *regs) { struct arc_callchain_trace ctrl = { .depth = 0, @@ -68,8 +83,8 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re arc_unwind_core(NULL, regs, callchain_trace, &ctrl); } -void -perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) +void perf_callchain_user(struct perf_callchain_entry_ctx *entry, + struct pt_regs *regs) { /* * User stack can't be unwound trivially with kernel dwarf unwinder @@ -82,10 +97,10 @@ static struct arc_pmu *arc_pmu; static DEFINE_PER_CPU(struct arc_pmu_cpu, arc_pmu_cpu); /* read counter #idx; note that counter# != event# on ARC! */ -static uint64_t arc_pmu_read_counter(int idx) +static u64 arc_pmu_read_counter(int idx) { - uint32_t tmp; - uint64_t result; + u32 tmp; + u64 result; /* * ARC supports making 'snapshots' of the counters, so we don't @@ -94,7 +109,7 @@ static uint64_t arc_pmu_read_counter(int idx) write_aux_reg(ARC_REG_PCT_INDEX, idx); tmp = read_aux_reg(ARC_REG_PCT_CONTROL); write_aux_reg(ARC_REG_PCT_CONTROL, tmp | ARC_REG_PCT_CONTROL_SN); - result = (uint64_t) (read_aux_reg(ARC_REG_PCT_SNAPH)) << 32; + result = (u64) (read_aux_reg(ARC_REG_PCT_SNAPH)) << 32; result |= read_aux_reg(ARC_REG_PCT_SNAPL); return result; @@ -103,9 +118,9 @@ static uint64_t arc_pmu_read_counter(int idx) static void arc_perf_event_update(struct perf_event *event, struct hw_perf_event *hwc, int idx) { - uint64_t prev_raw_count = local64_read(&hwc->prev_count); - uint64_t new_raw_count = arc_pmu_read_counter(idx); - int64_t delta = new_raw_count - prev_raw_count; + u64 prev_raw_count = local64_read(&hwc->prev_count); + u64 new_raw_count = arc_pmu_read_counter(idx); + s64 delta = new_raw_count - prev_raw_count; /* * We aren't afraid of hwc->prev_count changing beneath our feet @@ -155,7 +170,7 @@ static int arc_pmu_event_init(struct perf_event *event) int ret; if (!is_sampling_event(event)) { - hwc->sample_period = arc_pmu->max_period; + hwc->sample_period = arc_pmu->max_period; hwc->last_period = hwc->sample_period; local64_set(&hwc->period_left, hwc->sample_period); } @@ -192,6 +207,18 @@ static int arc_pmu_event_init(struct perf_event *event) pr_debug("init cache event with h/w %08x \'%s\'\n", (int)hwc->config, arc_pmu_ev_hw_map[ret]); return 0; + + case PERF_TYPE_RAW: + if (event->attr.config >= arc_pmu->n_events) + return -ENOENT; + + hwc->config |= event->attr.config; + pr_debug("init raw event with idx %lld \'%s\'\n", + event->attr.config, + arc_pmu->raw_entry[event->attr.config].name); + + return 0; + default: return -ENOENT; } @@ -200,7 +227,7 @@ static int arc_pmu_event_init(struct perf_event *event) /* starts all counters */ static void arc_pmu_enable(struct pmu *pmu) { - uint32_t tmp; + u32 tmp; tmp = read_aux_reg(ARC_REG_PCT_CONTROL); write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x1); } @@ -208,7 +235,7 @@ static void arc_pmu_enable(struct pmu *pmu) /* stops all counters */ static void arc_pmu_disable(struct pmu *pmu) { - uint32_t tmp; + u32 tmp; tmp = read_aux_reg(ARC_REG_PCT_CONTROL); write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x0); } @@ -228,7 +255,7 @@ static int arc_pmu_event_set_period(struct perf_event *event) local64_set(&hwc->period_left, left); hwc->last_period = period; overflow = 1; - } else if (unlikely(left <= 0)) { + } else if (unlikely(left <= 0)) { /* left underflowed by less than period. */ left += period; local64_set(&hwc->period_left, left); @@ -246,8 +273,8 @@ static int arc_pmu_event_set_period(struct perf_event *event) write_aux_reg(ARC_REG_PCT_INDEX, idx); /* Write value */ - write_aux_reg(ARC_REG_PCT_COUNTL, (u32)value); - write_aux_reg(ARC_REG_PCT_COUNTH, (value >> 32)); + write_aux_reg(ARC_REG_PCT_COUNTL, lower_32_bits(value)); + write_aux_reg(ARC_REG_PCT_COUNTH, upper_32_bits(value)); perf_event_update_userpage(event); @@ -277,7 +304,7 @@ static void arc_pmu_start(struct perf_event *event, int flags) /* Enable interrupt for this counter */ if (is_sampling_event(event)) write_aux_reg(ARC_REG_PCT_INT_CTRL, - read_aux_reg(ARC_REG_PCT_INT_CTRL) | (1 << idx)); + read_aux_reg(ARC_REG_PCT_INT_CTRL) | BIT(idx)); /* enable ARC pmu here */ write_aux_reg(ARC_REG_PCT_INDEX, idx); /* counter # */ @@ -295,9 +322,9 @@ static void arc_pmu_stop(struct perf_event *event, int flags) * Reset interrupt flag by writing of 1. This is required * to make sure pending interrupt was not left. */ - write_aux_reg(ARC_REG_PCT_INT_ACT, 1 << idx); + write_aux_reg(ARC_REG_PCT_INT_ACT, BIT(idx)); write_aux_reg(ARC_REG_PCT_INT_CTRL, - read_aux_reg(ARC_REG_PCT_INT_CTRL) & ~(1 << idx)); + read_aux_reg(ARC_REG_PCT_INT_CTRL) & ~BIT(idx)); } if (!(event->hw.state & PERF_HES_STOPPED)) { @@ -349,9 +376,10 @@ static int arc_pmu_add(struct perf_event *event, int flags) if (is_sampling_event(event)) { /* Mimic full counter overflow as other arches do */ - write_aux_reg(ARC_REG_PCT_INT_CNTL, (u32)arc_pmu->max_period); + write_aux_reg(ARC_REG_PCT_INT_CNTL, + lower_32_bits(arc_pmu->max_period)); write_aux_reg(ARC_REG_PCT_INT_CNTH, - (arc_pmu->max_period >> 32)); + upper_32_bits(arc_pmu->max_period)); } write_aux_reg(ARC_REG_PCT_CONFIG, 0); @@ -392,7 +420,7 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev) idx = __ffs(active_ints); /* Reset interrupt flag by writing of 1 */ - write_aux_reg(ARC_REG_PCT_INT_ACT, 1 << idx); + write_aux_reg(ARC_REG_PCT_INT_ACT, BIT(idx)); /* * On reset of "interrupt active" bit corresponding @@ -400,7 +428,7 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev) * Now we need to re-enable interrupt for the counter. */ write_aux_reg(ARC_REG_PCT_INT_CTRL, - read_aux_reg(ARC_REG_PCT_INT_CTRL) | (1 << idx)); + read_aux_reg(ARC_REG_PCT_INT_CTRL) | BIT(idx)); event = pmu_cpu->act_counter[idx]; hwc = &event->hw; @@ -414,7 +442,7 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev) arc_pmu_stop(event, 0); } - active_ints &= ~(1U << idx); + active_ints &= ~BIT(idx); } while (active_ints); done: @@ -441,19 +469,108 @@ static void arc_cpu_pmu_irq_init(void *data) write_aux_reg(ARC_REG_PCT_INT_ACT, 0xffffffff); } +/* Event field occupies the bottom 15 bits of our config field */ +PMU_FORMAT_ATTR(event, "config:0-14"); +static struct attribute *arc_pmu_format_attrs[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group arc_pmu_format_attr_gr = { + .name = "format", + .attrs = arc_pmu_format_attrs, +}; + +static ssize_t arc_pmu_events_sysfs_show(struct device *dev, + struct device_attribute *attr, + char *page) +{ + struct perf_pmu_events_attr *pmu_attr; + + pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr); + return sprintf(page, "event=0x%04llx\n", pmu_attr->id); +} + +/* + * We don't add attrs here as we don't have pre-defined list of perf events. + * We will generate and add attrs dynamically in probe() after we read HW + * configuration. + */ +static struct attribute_group arc_pmu_events_attr_gr = { + .name = "events", +}; + +static void arc_pmu_add_raw_event_attr(int j, char *str) +{ + memmove(arc_pmu->raw_entry[j].name, str, ARCPMU_EVENT_NAME_LEN - 1); + arc_pmu->attr[j].attr.attr.name = arc_pmu->raw_entry[j].name; + arc_pmu->attr[j].attr.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444); + arc_pmu->attr[j].attr.show = arc_pmu_events_sysfs_show; + arc_pmu->attr[j].id = j; + arc_pmu->attrs[j] = &(arc_pmu->attr[j].attr.attr); +} + +static int arc_pmu_raw_alloc(struct device *dev) +{ + arc_pmu->attr = devm_kmalloc_array(dev, arc_pmu->n_events + 1, + sizeof(*arc_pmu->attr), GFP_KERNEL | __GFP_ZERO); + if (!arc_pmu->attr) + return -ENOMEM; + + arc_pmu->attrs = devm_kmalloc_array(dev, arc_pmu->n_events + 1, + sizeof(*arc_pmu->attrs), GFP_KERNEL | __GFP_ZERO); + if (!arc_pmu->attrs) + return -ENOMEM; + + arc_pmu->raw_entry = devm_kmalloc_array(dev, arc_pmu->n_events, + sizeof(*arc_pmu->raw_entry), GFP_KERNEL | __GFP_ZERO); + if (!arc_pmu->raw_entry) + return -ENOMEM; + + return 0; +} + +static inline bool event_in_hw_event_map(int i, char *name) +{ + if (!arc_pmu_ev_hw_map[i]) + return false; + + if (!strlen(arc_pmu_ev_hw_map[i])) + return false; + + if (strcmp(arc_pmu_ev_hw_map[i], name)) + return false; + + return true; +} + +static void arc_pmu_map_hw_event(int j, char *str) +{ + int i; + + /* See if HW condition has been mapped to a perf event_id */ + for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) { + if (event_in_hw_event_map(i, str)) { + pr_debug("mapping perf event %2d to h/w event \'%8s\' (idx %d)\n", + i, str, j); + arc_pmu->ev_hw_idx[i] = j; + } + } +} + static int arc_pmu_device_probe(struct platform_device *pdev) { struct arc_reg_pct_build pct_bcr; struct arc_reg_cc_build cc_bcr; - int i, j, has_interrupts; + int i, has_interrupts; int counter_size; /* in bits */ union cc_name { struct { - uint32_t word0, word1; + u32 word0, word1; char sentinel; } indiv; - char str[9]; + char str[ARCPMU_EVENT_NAME_LEN]; } cc_name; @@ -463,15 +580,22 @@ static int arc_pmu_device_probe(struct platform_device *pdev) return -ENODEV; } BUILD_BUG_ON(ARC_PERF_MAX_COUNTERS > 32); - BUG_ON(pct_bcr.c > ARC_PERF_MAX_COUNTERS); + if (WARN_ON(pct_bcr.c > ARC_PERF_MAX_COUNTERS)) + return -EINVAL; READ_BCR(ARC_REG_CC_BUILD, cc_bcr); - BUG_ON(!cc_bcr.v); /* Counters exist but No countable conditions ? */ + if (WARN(!cc_bcr.v, "Counters exist but No countable conditions?")) + return -EINVAL; arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL); if (!arc_pmu) return -ENOMEM; + arc_pmu->n_events = cc_bcr.c; + + if (arc_pmu_raw_alloc(&pdev->dev)) + return -ENOMEM; + has_interrupts = is_isa_arcv2() ? pct_bcr.i : 0; arc_pmu->n_counters = pct_bcr.c; @@ -481,30 +605,26 @@ static int arc_pmu_device_probe(struct platform_device *pdev) pr_info("ARC perf\t: %d counters (%d bits), %d conditions%s\n", arc_pmu->n_counters, counter_size, cc_bcr.c, - has_interrupts ? ", [overflow IRQ support]":""); + has_interrupts ? ", [overflow IRQ support]" : ""); - cc_name.str[8] = 0; + cc_name.str[ARCPMU_EVENT_NAME_LEN - 1] = 0; for (i = 0; i < PERF_COUNT_ARC_HW_MAX; i++) arc_pmu->ev_hw_idx[i] = -1; /* loop thru all available h/w condition indexes */ - for (j = 0; j < cc_bcr.c; j++) { - write_aux_reg(ARC_REG_CC_INDEX, j); + for (i = 0; i < cc_bcr.c; i++) { + write_aux_reg(ARC_REG_CC_INDEX, i); cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0); cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1); - /* See if it has been mapped to a perf event_id */ - for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) { - if (arc_pmu_ev_hw_map[i] && - !strcmp(arc_pmu_ev_hw_map[i], cc_name.str) && - strlen(arc_pmu_ev_hw_map[i])) { - pr_debug("mapping perf event %2d to h/w event \'%8s\' (idx %d)\n", - i, cc_name.str, j); - arc_pmu->ev_hw_idx[i] = j; - } - } + arc_pmu_map_hw_event(i, cc_name.str); + arc_pmu_add_raw_event_attr(i, cc_name.str); } + arc_pmu_events_attr_gr.attrs = arc_pmu->attrs; + arc_pmu->attr_groups[ARCPMU_ATTR_GR_EVENTS] = &arc_pmu_events_attr_gr; + arc_pmu->attr_groups[ARCPMU_ATTR_GR_FORMATS] = &arc_pmu_format_attr_gr; + arc_pmu->pmu = (struct pmu) { .pmu_enable = arc_pmu_enable, .pmu_disable = arc_pmu_disable, @@ -514,6 +634,7 @@ static int arc_pmu_device_probe(struct platform_device *pdev) .start = arc_pmu_start, .stop = arc_pmu_stop, .read = arc_pmu_read, + .attr_groups = arc_pmu->attr_groups, }; if (has_interrupts) { @@ -535,17 +656,19 @@ static int arc_pmu_device_probe(struct platform_device *pdev) } else arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; - return perf_pmu_register(&arc_pmu->pmu, pdev->name, PERF_TYPE_RAW); + /* + * perf parser doesn't really like '-' symbol in events name, so let's + * use '_' in arc pct name as it goes to kernel PMU event prefix. + */ + return perf_pmu_register(&arc_pmu->pmu, "arc_pct", PERF_TYPE_RAW); } -#ifdef CONFIG_OF static const struct of_device_id arc_pmu_match[] = { { .compatible = "snps,arc700-pct" }, { .compatible = "snps,archs-pct" }, {}, }; MODULE_DEVICE_TABLE(of, arc_pmu_match); -#endif static struct platform_driver arc_pmu_driver = { .driver = { diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 2e018b8c2e19..feb90093e6b1 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -123,6 +123,7 @@ static void read_arc_build_cfg_regs(void) struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; const struct id_to_str *tbl; struct bcr_isa_arcv2 isa; + struct bcr_actionpoint ap; FIX_PTR(cpu); @@ -195,6 +196,7 @@ static void read_arc_build_cfg_regs(void) cpu->bpu.full = bpu.ft; cpu->bpu.num_cache = 256 << bpu.bce; cpu->bpu.num_pred = 2048 << bpu.pte; + cpu->bpu.ret_stk = 4 << bpu.rse; if (cpu->core.family >= 0x54) { unsigned int exec_ctrl; @@ -207,8 +209,11 @@ static void read_arc_build_cfg_regs(void) } } - READ_BCR(ARC_REG_AP_BCR, bcr); - cpu->extn.ap = bcr.ver ? 1 : 0; + READ_BCR(ARC_REG_AP_BCR, ap); + if (ap.ver) { + cpu->extn.ap_num = 2 << ap.num; + cpu->extn.ap_full = !!ap.min; + } READ_BCR(ARC_REG_SMART_BCR, bcr); cpu->extn.smart = bcr.ver ? 1 : 0; @@ -216,8 +221,6 @@ static void read_arc_build_cfg_regs(void) READ_BCR(ARC_REG_RTT_BCR, bcr); cpu->extn.rtt = bcr.ver ? 1 : 0; - cpu->extn.debug = cpu->extn.ap | cpu->extn.smart | cpu->extn.rtt; - READ_BCR(ARC_REG_ISA_CFG_BCR, isa); /* some hacks for lack of feature BCR info in old ARC700 cores */ @@ -299,10 +302,10 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) if (cpu->bpu.ver) n += scnprintf(buf + n, len - n, - "BPU\t\t: %s%s match, cache:%d, Predict Table:%d", + "BPU\t\t: %s%s match, cache:%d, Predict Table:%d Return stk: %d", IS_AVAIL1(cpu->bpu.full, "full"), IS_AVAIL1(!cpu->bpu.full, "partial"), - cpu->bpu.num_cache, cpu->bpu.num_pred); + cpu->bpu.num_cache, cpu->bpu.num_pred, cpu->bpu.ret_stk); if (is_isa_arcv2()) { struct bcr_lpb lpb; @@ -336,11 +339,17 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) IS_AVAIL1(cpu->extn.fpu_sp, "SP "), IS_AVAIL1(cpu->extn.fpu_dp, "DP ")); - if (cpu->extn.debug) - n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s%s\n", - IS_AVAIL1(cpu->extn.ap, "ActionPoint "), + if (cpu->extn.ap_num | cpu->extn.smart | cpu->extn.rtt) { + n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s", IS_AVAIL1(cpu->extn.smart, "smaRT "), IS_AVAIL1(cpu->extn.rtt, "RTT ")); + if (cpu->extn.ap_num) { + n += scnprintf(buf + n, len - n, "ActionPoint %d/%s", + cpu->extn.ap_num, + cpu->extn.ap_full ? "full":"min"); + } + n += scnprintf(buf + n, len - n, "\n"); + } if (cpu->dccm.sz || cpu->iccm.sz) n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n", diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index e8d9fb452346..215f515442e0 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c @@ -18,6 +18,8 @@ #include <asm/arcregs.h> #include <asm/irqflags.h> +#define ARC_PATH_MAX 256 + /* * Common routine to print scratch regs (r0-r12) or callee regs (r13-r25) * -Prints 3 regs per line and a CR. @@ -58,11 +60,12 @@ static void show_callee_regs(struct callee_regs *cregs) print_reg_file(&(cregs->r13), 13); } -static void print_task_path_n_nm(struct task_struct *tsk, char *buf) +static void print_task_path_n_nm(struct task_struct *tsk) { char *path_nm = NULL; struct mm_struct *mm; struct file *exe_file; + char buf[ARC_PATH_MAX]; mm = get_task_mm(tsk); if (!mm) @@ -72,7 +75,7 @@ static void print_task_path_n_nm(struct task_struct *tsk, char *buf) mmput(mm); if (exe_file) { - path_nm = file_path(exe_file, buf, 255); + path_nm = file_path(exe_file, buf, ARC_PATH_MAX-1); fput(exe_file); } @@ -80,10 +83,9 @@ done: pr_info("Path: %s\n", !IS_ERR(path_nm) ? path_nm : "?"); } -static void show_faulting_vma(unsigned long address, char *buf) +static void show_faulting_vma(unsigned long address) { struct vm_area_struct *vma; - char *nm = buf; struct mm_struct *active_mm = current->active_mm; /* can't use print_vma_addr() yet as it doesn't check for @@ -96,8 +98,11 @@ static void show_faulting_vma(unsigned long address, char *buf) * if the container VMA is not found */ if (vma && (vma->vm_start <= address)) { + char buf[ARC_PATH_MAX]; + char *nm = "?"; + if (vma->vm_file) { - nm = file_path(vma->vm_file, buf, PAGE_SIZE - 1); + nm = file_path(vma->vm_file, buf, ARC_PATH_MAX-1); if (IS_ERR(nm)) nm = "?"; } @@ -173,13 +178,14 @@ void show_regs(struct pt_regs *regs) { struct task_struct *tsk = current; struct callee_regs *cregs; - char *buf; - buf = (char *)__get_free_page(GFP_KERNEL); - if (!buf) - return; + /* + * generic code calls us with preemption disabled, but some calls + * here could sleep, so re-enable to avoid lockdep splat + */ + preempt_enable(); - print_task_path_n_nm(tsk, buf); + print_task_path_n_nm(tsk); show_regs_print_info(KERN_INFO); show_ecr_verbose(regs); @@ -189,7 +195,7 @@ void show_regs(struct pt_regs *regs) (void *)regs->blink, (void *)regs->ret); if (user_mode(regs)) - show_faulting_vma(regs->ret, buf); /* faulting code, not data */ + show_faulting_vma(regs->ret); /* faulting code, not data */ pr_info("[STAT32]: 0x%08lx", regs->status32); @@ -222,7 +228,7 @@ void show_regs(struct pt_regs *regs) if (cregs) show_callee_regs(cregs); - free_page((unsigned long)buf); + preempt_disable(); } void show_kernel_fault_diag(const char *str, struct pt_regs *regs, diff --git a/arch/arc/lib/memset-archs.S b/arch/arc/lib/memset-archs.S index 62ad4bcb841a..f230bb7092fd 100644 --- a/arch/arc/lib/memset-archs.S +++ b/arch/arc/lib/memset-archs.S @@ -7,11 +7,39 @@ */ #include <linux/linkage.h> +#include <asm/cache.h> -#undef PREALLOC_NOT_AVAIL +/* + * The memset implementation below is optimized to use prefetchw and prealloc + * instruction in case of CPU with 64B L1 data cache line (L1_CACHE_SHIFT == 6) + * If you want to implement optimized memset for other possible L1 data cache + * line lengths (32B and 128B) you should rewrite code carefully checking + * we don't call any prefetchw/prealloc instruction for L1 cache lines which + * don't belongs to memset area. + */ + +#if L1_CACHE_SHIFT == 6 + +.macro PREALLOC_INSTR reg, off + prealloc [\reg, \off] +.endm + +.macro PREFETCHW_INSTR reg, off + prefetchw [\reg, \off] +.endm + +#else + +.macro PREALLOC_INSTR +.endm + +.macro PREFETCHW_INSTR +.endm + +#endif ENTRY_CFI(memset) - prefetchw [r0] ; Prefetch the write location + PREFETCHW_INSTR r0, 0 ; Prefetch the first write location mov.f 0, r2 ;;; if size is zero jz.d [blink] @@ -48,11 +76,8 @@ ENTRY_CFI(memset) lpnz @.Lset64bytes ;; LOOP START -#ifdef PREALLOC_NOT_AVAIL - prefetchw [r3, 64] ;Prefetch the next write location -#else - prealloc [r3, 64] -#endif + PREALLOC_INSTR r3, 64 ; alloc next line w/o fetching + #ifdef CONFIG_ARC_HAS_LL64 std.ab r4, [r3, 8] std.ab r4, [r3, 8] @@ -85,7 +110,6 @@ ENTRY_CFI(memset) lsr.f lp_count, r2, 5 ;Last remaining max 124 bytes lpnz .Lset32bytes ;; LOOP START - prefetchw [r3, 32] ;Prefetch the next write location #ifdef CONFIG_ARC_HAS_LL64 std.ab r4, [r3, 8] std.ab r4, [r3, 8] diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c index a1d723197084..8df1638259f3 100644 --- a/arch/arc/mm/fault.c +++ b/arch/arc/mm/fault.c @@ -141,12 +141,17 @@ good_area: */ fault = handle_mm_fault(vma, address, flags); - /* If Pagefault was interrupted by SIGKILL, exit page fault "early" */ if (fatal_signal_pending(current)) { - if ((fault & VM_FAULT_ERROR) && !(fault & VM_FAULT_RETRY)) - up_read(&mm->mmap_sem); - if (user_mode(regs)) + + /* + * if fault retry, mmap_sem already relinquished by core mm + * so OK to return to user mode (with signal handled first) + */ + if (fault & VM_FAULT_RETRY) { + if (!user_mode(regs)) + goto no_context; return; + } } perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c index 43bf4c3a1290..e1ab2d7f1d64 100644 --- a/arch/arc/mm/init.c +++ b/arch/arc/mm/init.c @@ -119,7 +119,8 @@ void __init setup_arch_memory(void) */ memblock_add_node(low_mem_start, low_mem_sz, 0); - memblock_reserve(low_mem_start, __pa(_end) - low_mem_start); + memblock_reserve(CONFIG_LINUX_LINK_BASE, + __pa(_end) - CONFIG_LINUX_LINK_BASE); #ifdef CONFIG_BLK_DEV_INITRD if (phys_initrd_size) { diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts index a3c9b346721d..f04bc3e15332 100644 --- a/arch/arm/boot/dts/da850-evm.dts +++ b/arch/arm/boot/dts/da850-evm.dts @@ -94,6 +94,28 @@ regulator-boot-on; }; + baseboard_3v3: fixedregulator-3v3 { + /* TPS73701DCQ */ + compatible = "regulator-fixed"; + regulator-name = "baseboard_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vbat>; + regulator-always-on; + regulator-boot-on; + }; + + baseboard_1v8: fixedregulator-1v8 { + /* TPS73701DCQ */ + compatible = "regulator-fixed"; + regulator-name = "baseboard_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vbat>; + regulator-always-on; + regulator-boot-on; + }; + backlight_lcd: backlight-regulator { compatible = "regulator-fixed"; regulator-name = "lcd_backlight_pwr"; @@ -105,7 +127,7 @@ sound { compatible = "simple-audio-card"; - simple-audio-card,name = "DA850/OMAP-L138 EVM"; + simple-audio-card,name = "DA850-OMAPL138 EVM"; simple-audio-card,widgets = "Line", "Line In", "Line", "Line Out"; @@ -210,10 +232,9 @@ /* Regulators */ IOVDD-supply = <&vdcdc2_reg>; - /* Derived from VBAT: Baseboard 3.3V / 1.8V */ - AVDD-supply = <&vbat>; - DRVDD-supply = <&vbat>; - DVDD-supply = <&vbat>; + AVDD-supply = <&baseboard_3v3>; + DRVDD-supply = <&baseboard_3v3>; + DVDD-supply = <&baseboard_1v8>; }; tca6416: gpio@20 { compatible = "ti,tca6416"; diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts index 0177e3ed20fe..3a2fa6e035a3 100644 --- a/arch/arm/boot/dts/da850-lcdk.dts +++ b/arch/arm/boot/dts/da850-lcdk.dts @@ -39,9 +39,39 @@ }; }; + vcc_5vd: fixedregulator-vcc_5vd { + compatible = "regulator-fixed"; + regulator-name = "vcc_5vd"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + vcc_3v3d: fixedregulator-vcc_3v3d { + /* TPS650250 - VDCDC1 */ + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3d"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_5vd>; + regulator-always-on; + regulator-boot-on; + }; + + vcc_1v8d: fixedregulator-vcc_1v8d { + /* TPS650250 - VDCDC2 */ + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8d"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_5vd>; + regulator-always-on; + regulator-boot-on; + }; + sound { compatible = "simple-audio-card"; - simple-audio-card,name = "DA850/OMAP-L138 LCDK"; + simple-audio-card,name = "DA850-OMAPL138 LCDK"; simple-audio-card,widgets = "Line", "Line In", "Line", "Line Out"; @@ -221,6 +251,12 @@ compatible = "ti,tlv320aic3106"; reg = <0x18>; status = "okay"; + + /* Regulators */ + IOVDD-supply = <&vcc_3v3d>; + AVDD-supply = <&vcc_3v3d>; + DRVDD-supply = <&vcc_3v3d>; + DVDD-supply = <&vcc_1v8d>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi index cbaf06f2f78e..eb917462b219 100644 --- a/arch/arm/boot/dts/kirkwood-dnskw.dtsi +++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi @@ -36,8 +36,8 @@ compatible = "gpio-fan"; pinctrl-0 = <&pmx_fan_high_speed &pmx_fan_low_speed>; pinctrl-names = "default"; - gpios = <&gpio1 14 GPIO_ACTIVE_LOW - &gpio1 13 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH + &gpio1 13 GPIO_ACTIVE_HIGH>; gpio-fan,speed-map = <0 0 3000 1 6000 2>; diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 6bb506edb1f5..e96a9743b220 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -66,9 +66,6 @@ CONFIG_MACH_MIOA701=y CONFIG_PXA_EZX=y CONFIG_MACH_MP900C=y CONFIG_ARCH_PXA_PALM=y -CONFIG_MACH_RAUMFELD_RC=y -CONFIG_MACH_RAUMFELD_CONNECTOR=y -CONFIG_MACH_RAUMFELD_SPEAKER=y CONFIG_PXA_SHARPSL=y CONFIG_MACH_POODLE=y CONFIG_MACH_CORGI=y @@ -498,7 +495,6 @@ CONFIG_SND_PXA2XX_SOC_E800=m CONFIG_SND_PXA2XX_SOC_EM_X270=m CONFIG_SND_PXA2XX_SOC_PALM27X=y CONFIG_SND_SOC_ZYLONITE=m -CONFIG_SND_SOC_RAUMFELD=m CONFIG_SND_PXA2XX_SOC_HX4700=m CONFIG_SND_PXA2XX_SOC_MAGICIAN=m CONFIG_SND_PXA2XX_SOC_MIOA701=m diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig deleted file mode 100644 index 2dd56e9a484e..000000000000 --- a/arch/arm/configs/raumfeld_defconfig +++ /dev/null @@ -1,197 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_LBDAF is not set -# CONFIG_BLK_DEV_BSG is not set -CONFIG_ARCH_PXA=y -CONFIG_MACH_RAUMFELD_RC=y -CONFIG_MACH_RAUMFELD_CONNECTOR=y -CONFIG_MACH_RAUMFELD_SPEAKER=y -CONFIG_NO_HZ=y -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -CONFIG_CMDLINE="console=ttyS0,115200 rw" -CONFIG_CPU_FREQ=y -CONFIG_CPU_IDLE=y -CONFIG_PM=y -CONFIG_APM_EMULATION=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_PNP=y -CONFIG_SYN_COOKIES=y -CONFIG_IPV6=y -CONFIG_CFG80211=y -CONFIG_MAC80211=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_NFTL=y -CONFIG_NFTL_RW=y -CONFIG_MTD_BLOCK2MTD=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_MARVELL=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_ISL29003=y -CONFIG_IIO=y -CONFIG_AD5446=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_SG=y -CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y -CONFIG_SMSC911X=y -CONFIG_LIBERTAS=y -CONFIG_LIBERTAS_SDIO=m -CONFIG_USB_USBNET=y -# CONFIG_USB_NET_AX8817X is not set -# CONFIG_USB_NET_NET1080 is not set -CONFIG_USB_NET_MCS7830=y -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_ZAURUS is not set -CONFIG_INPUT_EVDEV=y -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_EETI=m -CONFIG_INPUT_MISC=y -CONFIG_INPUT_GPIO_ROTARY_ENCODER=y -CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_PXA=y -CONFIG_SPI=y -CONFIG_SPI_DEBUG=y -CONFIG_SPI_GPIO=y -CONFIG_SPI_SPIDEV=y -CONFIG_DEBUG_GPIO=y -CONFIG_W1_MASTER_GPIO=m -CONFIG_POWER_SUPPLY=y -CONFIG_PDA_POWER=y -CONFIG_BATTERY_DS2760=m -CONFIG_SENSORS_LIS3_SPI=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_DEBUG=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_MAX8660=y -CONFIG_FB=y -CONFIG_FB_PXA=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set -CONFIG_BACKLIGHT_PWM=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -CONFIG_SOUND=y -CONFIG_SND=y -# CONFIG_SND_DRIVERS is not set -# CONFIG_SND_USB is not set -CONFIG_SND_SOC=y -CONFIG_SND_PXA2XX_SOC=y -CONFIG_SND_SOC_RAUMFELD=y -CONFIG_HID_DRAGONRISE=y -CONFIG_HID_GYRATION=y -CONFIG_HID_TWINHAN=y -CONFIG_HID_NTRIG=y -CONFIG_HID_PANTHERLORD=y -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_SUNPLUS=y -CONFIG_HID_GREENASIA=y -CONFIG_HID_SMARTJOYPLUS=y -CONFIG_HID_TOPSEED=y -CONFIG_HID_THRUSTMASTER=y -CONFIG_HID_ZEROPLUS=y -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_MON=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_USBAT=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_MMC=y -CONFIG_MMC_PXA=m -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_LT3593=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_BACKLIGHT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_PXA=y -CONFIG_DMADEVICES=y -CONFIG_UIO=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XIP=y -CONFIG_EXT3_FS=y -CONFIG_FSCACHE=y -CONFIG_FSCACHE_STATS=y -CONFIG_CACHEFILES=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_UBIFS_FS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -CONFIG_NFS_FSCACHE=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_737=y -CONFIG_NLS_CODEPAGE_775=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_CODEPAGE_852=y -CONFIG_NLS_CODEPAGE_855=y -CONFIG_NLS_CODEPAGE_857=y -CONFIG_NLS_CODEPAGE_860=y -CONFIG_NLS_CODEPAGE_861=y -CONFIG_NLS_CODEPAGE_862=y -CONFIG_NLS_CODEPAGE_863=y -CONFIG_NLS_CODEPAGE_864=y -CONFIG_NLS_CODEPAGE_865=y -CONFIG_NLS_CODEPAGE_866=y -CONFIG_NLS_CODEPAGE_869=y -CONFIG_NLS_CODEPAGE_936=y -CONFIG_NLS_CODEPAGE_950=y -CONFIG_NLS_CODEPAGE_932=y -CONFIG_NLS_CODEPAGE_949=y -CONFIG_NLS_CODEPAGE_874=y -CONFIG_NLS_ISO8859_8=y -CONFIG_NLS_CODEPAGE_1250=y -CONFIG_NLS_CODEPAGE_1251=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_2=y -CONFIG_NLS_ISO8859_3=y -CONFIG_NLS_ISO8859_4=y -CONFIG_NLS_ISO8859_5=y -CONFIG_NLS_ISO8859_6=y -CONFIG_NLS_ISO8859_7=y -CONFIG_NLS_ISO8859_9=y -CONFIG_NLS_ISO8859_13=y -CONFIG_NLS_ISO8859_14=y -CONFIG_NLS_ISO8859_15=y -CONFIG_NLS_KOI8_R=y -CONFIG_NLS_KOI8_U=y -CONFIG_NLS_UTF8=y -CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_USER=y -CONFIG_DEBUG_LL=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h index b3ef061d8b74..2c403e7c782d 100644 --- a/arch/arm/include/asm/xen/page-coherent.h +++ b/arch/arm/include/asm/xen/page-coherent.h @@ -1 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H +#define _ASM_ARM_XEN_PAGE_COHERENT_H + +#include <linux/dma-mapping.h> +#include <asm/page.h> #include <xen/arm/page-coherent.h> + +static inline const struct dma_map_ops *xen_get_dma_ops(struct device *dev) +{ + if (dev && dev->archdata.dev_dma_ops) + return dev->archdata.dev_dma_ops; + return get_arch_dma_ops(NULL); +} + +static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs) +{ + return xen_get_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs); +} + +static inline void xen_free_coherent_pages(struct device *hwdev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs) +{ + xen_get_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs); +} + +static inline void xen_dma_map_page(struct device *hwdev, struct page *page, + dma_addr_t dev_addr, unsigned long offset, size_t size, + enum dma_data_direction dir, unsigned long attrs) +{ + unsigned long page_pfn = page_to_xen_pfn(page); + unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr); + unsigned long compound_pages = + (1<<compound_order(page)) * XEN_PFN_PER_PAGE; + bool local = (page_pfn <= dev_pfn) && + (dev_pfn - page_pfn < compound_pages); + + /* + * Dom0 is mapped 1:1, while the Linux page can span across + * multiple Xen pages, it's not possible for it to contain a + * mix of local and foreign Xen pages. So if the first xen_pfn + * == mfn the page is local otherwise it's a foreign page + * grant-mapped in dom0. If the page is local we can safely + * call the native dma_ops function, otherwise we call the xen + * specific function. + */ + if (local) + xen_get_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs); + else + __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs); +} + +static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, + size_t size, enum dma_data_direction dir, unsigned long attrs) +{ + unsigned long pfn = PFN_DOWN(handle); + /* + * Dom0 is mapped 1:1, while the Linux page can be spanned accross + * multiple Xen page, it's not possible to have a mix of local and + * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a + * foreign mfn will always return false. If the page is local we can + * safely call the native dma_ops function, otherwise we call the xen + * specific function. + */ + if (pfn_valid(pfn)) { + if (xen_get_dma_ops(hwdev)->unmap_page) + xen_get_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs); + } else + __xen_dma_unmap_page(hwdev, handle, size, dir, attrs); +} + +static inline void xen_dma_sync_single_for_cpu(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + unsigned long pfn = PFN_DOWN(handle); + if (pfn_valid(pfn)) { + if (xen_get_dma_ops(hwdev)->sync_single_for_cpu) + xen_get_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir); + } else + __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir); +} + +static inline void xen_dma_sync_single_for_device(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + unsigned long pfn = PFN_DOWN(handle); + if (pfn_valid(pfn)) { + if (xen_get_dma_ops(hwdev)->sync_single_for_device) + xen_get_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir); + } else + __xen_dma_sync_single_for_device(hwdev, handle, size, dir); +} + +#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */ diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index e52ec1619b70..3a2124212a7f 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -18,7 +18,7 @@ #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/platform_data/pcf857x.h> -#include <linux/platform_data/at24.h> +#include <linux/property.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/spi/spi.h> @@ -52,62 +52,19 @@ static const short da830_evm_usb11_pins[] = { -1 }; -static da8xx_ocic_handler_t da830_evm_usb_ocic_handler; - -static int da830_evm_usb_set_power(unsigned port, int on) -{ - gpio_set_value(ON_BD_USB_DRV, on); - return 0; -} - -static int da830_evm_usb_get_power(unsigned port) -{ - return gpio_get_value(ON_BD_USB_DRV); -} - -static int da830_evm_usb_get_oci(unsigned port) -{ - return !gpio_get_value(ON_BD_USB_OVC); -} - -static irqreturn_t da830_evm_usb_ocic_irq(int, void *); - -static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler) -{ - int irq = gpio_to_irq(ON_BD_USB_OVC); - int error = 0; - - if (handler != NULL) { - da830_evm_usb_ocic_handler = handler; - - error = request_irq(irq, da830_evm_usb_ocic_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "OHCI over-current indicator", NULL); - if (error) - pr_err("%s: could not request IRQ to watch over-current indicator changes\n", - __func__); - } else - free_irq(irq, NULL); - - return error; -} +static struct gpiod_lookup_table da830_evm_usb_gpio_lookup = { + .dev_id = "ohci-da8xx", + .table = { + GPIO_LOOKUP("davinci_gpio", ON_BD_USB_DRV, "vbus", 0), + GPIO_LOOKUP("davinci_gpio", ON_BD_USB_OVC, "oc", 0), + }, +}; static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = { - .set_power = da830_evm_usb_set_power, - .get_power = da830_evm_usb_get_power, - .get_oci = da830_evm_usb_get_oci, - .ocic_notify = da830_evm_usb_ocic_notify, - /* TPS2065 switch @ 5V */ .potpgt = (3 + 1) / 2, /* 3 ms max */ }; -static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id) -{ - da830_evm_usb_ocic_handler(&da830_evm_usb11_pdata, 1); - return IRQ_HANDLED; -} - static __init void da830_evm_usb_init(void) { int ret; @@ -142,21 +99,7 @@ static __init void da830_evm_usb_init(void) return; } - ret = gpio_request(ON_BD_USB_DRV, "ON_BD_USB_DRV"); - if (ret) { - pr_err("%s: failed to request GPIO for USB 1.1 port power control: %d\n", - __func__, ret); - return; - } - gpio_direction_output(ON_BD_USB_DRV, 0); - - ret = gpio_request(ON_BD_USB_OVC, "ON_BD_USB_OVC"); - if (ret) { - pr_err("%s: failed to request GPIO for USB 1.1 port over-current indicator: %d\n", - __func__, ret); - return; - } - gpio_direction_input(ON_BD_USB_OVC); + gpiod_add_lookup_table(&da830_evm_usb_gpio_lookup); ret = da8xx_register_usb11(&da830_evm_usb11_pdata); if (ret) @@ -208,9 +151,9 @@ static struct gpiod_lookup_table mmc_gpios_table = { .dev_id = "da830-mmc.0", .table = { /* gpio chip 1 contains gpio range 32-63 */ - GPIO_LOOKUP("davinci_gpio.0", DA830_MMCSD_CD_PIN, "cd", + GPIO_LOOKUP("davinci_gpio", DA830_MMCSD_CD_PIN, "cd", GPIO_ACTIVE_LOW), - GPIO_LOOKUP("davinci_gpio.0", DA830_MMCSD_WP_PIN, "wp", + GPIO_LOOKUP("davinci_gpio", DA830_MMCSD_WP_PIN, "wp", GPIO_ACTIVE_LOW), }, }; @@ -457,12 +400,9 @@ static struct nvmem_cell_lookup da830_evm_nvmem_cell_lookup = { .con_id = "mac-address", }; -static struct at24_platform_data da830_evm_i2c_eeprom_info = { - .byte_len = SZ_256K / 8, - .page_size = 64, - .flags = AT24_FLAG_ADDR16, - .setup = davinci_get_mac_addr, - .context = (void *)0x7f00, +static const struct property_entry da830_evm_i2c_eeprom_properties[] = { + PROPERTY_ENTRY_U32("pagesize", 64), + { } }; static int __init da830_evm_ui_expander_setup(struct i2c_client *client, @@ -496,7 +436,7 @@ static struct pcf857x_platform_data __initdata da830_evm_ui_expander_info = { static struct i2c_board_info __initdata da830_evm_i2c_devices[] = { { I2C_BOARD_INFO("24c256", 0x50), - .platform_data = &da830_evm_i2c_eeprom_info, + .properties = da830_evm_i2c_eeprom_properties, }, { I2C_BOARD_INFO("tlv320aic3x", 0x18), diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 6a29baf0a289..56d0e0257048 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -150,32 +150,6 @@ static struct spi_board_info da850evm_spi_info[] = { }, }; -#ifdef CONFIG_MTD -static void da850_evm_m25p80_notify_add(struct mtd_info *mtd) -{ - char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; - size_t retlen; - - if (!strcmp(mtd->name, "MAC-Address")) { - mtd_read(mtd, 0, ETH_ALEN, &retlen, mac_addr); - if (retlen == ETH_ALEN) - pr_info("Read MAC addr from SPI Flash: %pM\n", - mac_addr); - } -} - -static struct mtd_notifier da850evm_spi_notifier = { - .add = da850_evm_m25p80_notify_add, -}; - -static void da850_evm_setup_mac_addr(void) -{ - register_mtd_user(&da850evm_spi_notifier); -} -#else -static void da850_evm_setup_mac_addr(void) { } -#endif - static struct mtd_partition da850_evm_norflash_partition[] = { { .name = "bootloaders + env", @@ -805,9 +779,9 @@ static struct gpiod_lookup_table mmc_gpios_table = { .dev_id = "da830-mmc.0", .table = { /* gpio chip 2 contains gpio range 64-95 */ - GPIO_LOOKUP("davinci_gpio.0", DA850_MMCSD_CD_PIN, "cd", + GPIO_LOOKUP("davinci_gpio", DA850_MMCSD_CD_PIN, "cd", GPIO_ACTIVE_LOW), - GPIO_LOOKUP("davinci_gpio.0", DA850_MMCSD_WP_PIN, "wp", + GPIO_LOOKUP("davinci_gpio", DA850_MMCSD_WP_PIN, "wp", GPIO_ACTIVE_HIGH), }, }; @@ -1064,6 +1038,17 @@ static const short da850_evm_rmii_pins[] = { -1 }; +static struct gpiod_hog da850_evm_emac_gpio_hogs[] = { + { + .chip_label = "davinci_gpio", + .chip_hwnum = DA850_MII_MDIO_CLKEN_PIN, + .line_name = "mdio_clk_en", + .lflags = 0, + /* dflags set in da850_evm_config_emac() */ + }, + { } +}; + static int __init da850_evm_config_emac(void) { void __iomem *cfg_chip3_base; @@ -1102,14 +1087,9 @@ static int __init da850_evm_config_emac(void) if (ret) pr_warn("%s:GPIO(2,6) mux setup failed\n", __func__); - ret = gpio_request(DA850_MII_MDIO_CLKEN_PIN, "mdio_clk_en"); - if (ret) { - pr_warn("Cannot open GPIO %d\n", DA850_MII_MDIO_CLKEN_PIN); - return ret; - } - - /* Enable/Disable MII MDIO clock */ - gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en); + da850_evm_emac_gpio_hogs[0].dflags = rmii_en ? GPIOD_OUT_HIGH + : GPIOD_OUT_LOW; + gpiod_add_hogs(da850_evm_emac_gpio_hogs); soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID; @@ -1494,8 +1474,6 @@ static __init void da850_evm_init(void) if (ret) pr_warn("%s: SATA registration failed: %d\n", __func__, ret); - da850_evm_setup_mac_addr(); - ret = da8xx_register_rproc(); if (ret) pr_warn("%s: dsp/rproc registration failed: %d\n", diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index f53a461a606f..f7fa960c23e3 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -117,9 +117,9 @@ static struct platform_device davinci_nand_device = { static struct gpiod_lookup_table i2c_recovery_gpiod_table = { .dev_id = "i2c_davinci.1", .table = { - GPIO_LOOKUP("davinci_gpio.0", DM355_I2C_SDA_PIN, "sda", + GPIO_LOOKUP("davinci_gpio", DM355_I2C_SDA_PIN, "sda", GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), - GPIO_LOOKUP("davinci_gpio.0", DM355_I2C_SCL_PIN, "scl", + GPIO_LOOKUP("davinci_gpio", DM355_I2C_SCL_PIN, "scl", GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, }; diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index e3b0b701e395..f21dc8d3b28c 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -18,7 +18,7 @@ #include <linux/i2c.h> #include <linux/io.h> #include <linux/clk.h> -#include <linux/platform_data/at24.h> +#include <linux/property.h> #include <linux/leds.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> @@ -225,18 +225,15 @@ static struct nvmem_cell_lookup davinci_nvmem_cell_lookup = { .con_id = "mac-address", }; -static struct at24_platform_data eeprom_info = { - .byte_len = (256*1024) / 8, - .page_size = 64, - .flags = AT24_FLAG_ADDR16, - .setup = davinci_get_mac_addr, - .context = (void *)0x7f00, +static const struct property_entry eeprom_properties[] = { + PROPERTY_ENTRY_U32("pagesize", 64), + { } }; static struct i2c_board_info i2c_info[] = { { I2C_BOARD_INFO("24c256", 0x50), - .platform_data = &eeprom_info, + .properties = eeprom_properties, }, { I2C_BOARD_INFO("tlv320aic3x", 0x18), diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index e1428115067f..ecd30643c2c4 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -16,8 +16,8 @@ #include <linux/gpio/machine.h> #include <linux/i2c.h> #include <linux/platform_data/pcf857x.h> -#include <linux/platform_data/at24.h> #include <linux/platform_data/gpio-davinci.h> +#include <linux/property.h> #include <linux/mtd/mtd.h> #include <linux/mtd/rawnand.h> #include <linux/mtd/partitions.h> @@ -532,12 +532,9 @@ static struct nvmem_cell_lookup dm644evm_nvmem_cell_lookup = { .con_id = "mac-address", }; -static struct at24_platform_data eeprom_info = { - .byte_len = (256*1024) / 8, - .page_size = 64, - .flags = AT24_FLAG_ADDR16, - .setup = davinci_get_mac_addr, - .context = (void *)0x7f00, +static const struct property_entry eeprom_properties[] = { + PROPERTY_ENTRY_U32("pagesize", 64), + { } }; /* @@ -647,7 +644,7 @@ static struct i2c_board_info __initdata i2c_info[] = { }, { I2C_BOARD_INFO("24c256", 0x50), - .platform_data = &eeprom_info, + .properties = eeprom_properties, }, { I2C_BOARD_INFO("tlv320aic33", 0x1b), @@ -660,9 +657,9 @@ static struct i2c_board_info __initdata i2c_info[] = { static struct gpiod_lookup_table i2c_recovery_gpiod_table = { .dev_id = "i2c_davinci.1", .table = { - GPIO_LOOKUP("davinci_gpio.0", DM644X_I2C_SDA_PIN, "sda", + GPIO_LOOKUP("davinci_gpio", DM644X_I2C_SDA_PIN, "sda", GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), - GPIO_LOOKUP("davinci_gpio.0", DM644X_I2C_SCL_PIN, "scl", + GPIO_LOOKUP("davinci_gpio", DM644X_I2C_SCL_PIN, "scl", GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), }, }; diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 8d5be6dd2019..02b57face113 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -22,7 +22,7 @@ #include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/i2c.h> -#include <linux/platform_data/at24.h> +#include <linux/property.h> #include <linux/platform_data/pcf857x.h> #include <linux/platform_data/ti-aemif.h> @@ -364,12 +364,9 @@ static struct nvmem_cell_lookup dm646x_evm_nvmem_cell_lookup = { .con_id = "mac-address", }; -static struct at24_platform_data eeprom_info = { - .byte_len = (256*1024) / 8, - .page_size = 64, - .flags = AT24_FLAG_ADDR16, - .setup = davinci_get_mac_addr, - .context = (void *)0x7f00, +static const struct property_entry eeprom_properties[] = { + PROPERTY_ENTRY_U32("pagesize", 64), + { } }; #endif @@ -440,7 +437,7 @@ static void evm_init_cpld(void) static struct i2c_board_info __initdata i2c_info[] = { { I2C_BOARD_INFO("24c256", 0x50), - .platform_data = &eeprom_info, + .properties = eeprom_properties, }, { I2C_BOARD_INFO("pcf8574a", 0x38), diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 8df16e81b69e..a381b26328d8 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -14,11 +14,13 @@ #include <linux/init.h> #include <linux/console.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/mtd/partitions.h> +#include <linux/notifier.h> +#include <linux/nvmem-consumer.h> #include <linux/nvmem-provider.h> #include <linux/regulator/machine.h> #include <linux/i2c.h> -#include <linux/platform_data/at24.h> #include <linux/etherdevice.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> @@ -117,11 +119,15 @@ static void mityomapl138_cpufreq_init(const char *partnum) static void mityomapl138_cpufreq_init(const char *partnum) { } #endif -static void read_factory_config(struct nvmem_device *nvmem, void *context) +static int read_factory_config(struct notifier_block *nb, + unsigned long event, void *data) { int ret; const char *partnum = NULL; - struct davinci_soc_info *soc_info = &davinci_soc_info; + struct nvmem_device *nvmem = data; + + if (strcmp(nvmem_dev_name(nvmem), "1-00500") != 0) + return NOTIFY_DONE; if (!IS_BUILTIN(CONFIG_NVMEM)) { pr_warn("Factory Config not available without CONFIG_NVMEM\n"); @@ -147,21 +153,20 @@ static void read_factory_config(struct nvmem_device *nvmem, void *context) goto bad_config; } - pr_info("Found MAC = %pM\n", factory_config.mac); - if (is_valid_ether_addr(factory_config.mac)) - memcpy(soc_info->emac_pdata->mac_addr, - factory_config.mac, ETH_ALEN); - else - pr_warn("Invalid MAC found in factory config block\n"); - partnum = factory_config.partnum; pr_info("Part Number = %s\n", partnum); bad_config: /* default maximum speed is valid for all platforms */ mityomapl138_cpufreq_init(partnum); + + return NOTIFY_STOP; } +static struct notifier_block mityomapl138_nvmem_notifier = { + .notifier_call = read_factory_config, +}; + /* * We don't define a cell for factory config as it will be accessed from the * board file using the nvmem notifier chain. @@ -187,12 +192,10 @@ static struct nvmem_cell_lookup mityomapl138_nvmem_cell_lookup = { .con_id = "mac-address", }; -static struct at24_platform_data mityomapl138_fd_chip = { - .byte_len = 256, - .page_size = 8, - .flags = AT24_FLAG_READONLY | AT24_FLAG_IRUGO, - .setup = read_factory_config, - .context = NULL, +static const struct property_entry mityomapl138_fd_chip_properties[] = { + PROPERTY_ENTRY_U32("pagesize", 8), + PROPERTY_ENTRY_BOOL("read-only"), + { } }; static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = { @@ -321,7 +324,7 @@ static struct i2c_board_info __initdata mityomap_tps65023_info[] = { }, { I2C_BOARD_INFO("24c02", 0x50), - .platform_data = &mityomapl138_fd_chip, + .properties = mityomapl138_fd_chip_properties, }, }; @@ -569,6 +572,7 @@ static void __init mityomapl138_init(void) davinci_serial_init(da8xx_serial_device); + nvmem_register_notifier(&mityomapl138_nvmem_notifier); nvmem_add_cell_table(&mityomapl138_nvmem_cell_table); nvmem_add_cell_lookups(&mityomapl138_nvmem_cell_lookup, 1); diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 8e8d51f4a276..88a0c62eee86 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -134,9 +134,9 @@ static const short hawk_mmcsd0_pins[] = { static struct gpiod_lookup_table mmc_gpios_table = { .dev_id = "da830-mmc.0", .table = { - GPIO_LOOKUP("davinci_gpio.0", DA850_HAWK_MMCSD_CD_PIN, "cd", + GPIO_LOOKUP("davinci_gpio", DA850_HAWK_MMCSD_CD_PIN, "cd", GPIO_ACTIVE_LOW), - GPIO_LOOKUP("davinci_gpio.0", DA850_HAWK_MMCSD_WP_PIN, "wp", + GPIO_LOOKUP("davinci_gpio", DA850_HAWK_MMCSD_WP_PIN, "wp", GPIO_ACTIVE_LOW), }, }; @@ -294,66 +294,24 @@ static int omapl138_hawk_register_aemif(void) return platform_device_register(&omapl138_hawk_aemif_device); } -static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); -static da8xx_ocic_handler_t hawk_usb_ocic_handler; - static const short da850_hawk_usb11_pins[] = { DA850_GPIO2_4, DA850_GPIO6_13, -1 }; -static int hawk_usb_set_power(unsigned port, int on) -{ - gpio_set_value(DA850_USB1_VBUS_PIN, on); - return 0; -} - -static int hawk_usb_get_power(unsigned port) -{ - return gpio_get_value(DA850_USB1_VBUS_PIN); -} - -static int hawk_usb_get_oci(unsigned port) -{ - return !gpio_get_value(DA850_USB1_OC_PIN); -} - -static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) -{ - int irq = gpio_to_irq(DA850_USB1_OC_PIN); - int error = 0; - - if (handler != NULL) { - hawk_usb_ocic_handler = handler; - - error = request_irq(irq, omapl138_hawk_usb_ocic_irq, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, - "OHCI over-current indicator", NULL); - if (error) - pr_err("%s: could not request IRQ to watch " - "over-current indicator changes\n", __func__); - } else { - free_irq(irq, NULL); - } - return error; -} +static struct gpiod_lookup_table hawk_usb_gpio_lookup = { + .dev_id = "ohci-da8xx", + .table = { + GPIO_LOOKUP("davinci_gpio", DA850_USB1_VBUS_PIN, "vbus", 0), + GPIO_LOOKUP("davinci_gpio", DA850_USB1_OC_PIN, "oc", 0), + }, +}; static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { - .set_power = hawk_usb_set_power, - .get_power = hawk_usb_get_power, - .get_oci = hawk_usb_get_oci, - .ocic_notify = hawk_usb_ocic_notify, /* TPS2087 switch @ 5V */ .potpgt = (3 + 1) / 2, /* 3 ms max */ }; -static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) -{ - hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); - return IRQ_HANDLED; -} - static __init void omapl138_hawk_usb_init(void) { int ret; @@ -374,34 +332,13 @@ static __init void omapl138_hawk_usb_init(void) pr_warn("%s: USB PHY registration failed: %d\n", __func__, ret); - ret = gpio_request_one(DA850_USB1_VBUS_PIN, - GPIOF_DIR_OUT, "USB1 VBUS"); - if (ret < 0) { - pr_err("%s: failed to request GPIO for USB 1.1 port " - "power control: %d\n", __func__, ret); - return; - } - - ret = gpio_request_one(DA850_USB1_OC_PIN, - GPIOF_DIR_IN, "USB1 OC"); - if (ret < 0) { - pr_err("%s: failed to request GPIO for USB 1.1 port " - "over-current indicator: %d\n", __func__, ret); - goto usb11_setup_oc_fail; - } + gpiod_add_lookup_table(&hawk_usb_gpio_lookup); ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); - if (ret) { + if (ret) pr_warn("%s: USB 1.1 registration failed: %d\n", __func__, ret); - goto usb11_setup_fail; - } return; - -usb11_setup_fail: - gpio_free(DA850_USB1_OC_PIN); -usb11_setup_oc_fail: - gpio_free(DA850_USB1_VBUS_PIN); } static __init void omapl138_hawk_init(void) diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 792bb84d5011..ff14de1396c8 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -26,7 +26,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/i2c.h> -#include <linux/platform_data/at24.h> +#include <linux/property.h> #include <linux/mtd/mtd.h> #include <linux/mtd/rawnand.h> #include <linux/mtd/partitions.h> @@ -92,16 +92,15 @@ static struct platform_device davinci_sffsdr_nandflash_device = { .resource = davinci_sffsdr_nandflash_resource, }; -static struct at24_platform_data eeprom_info = { - .byte_len = (64*1024) / 8, - .page_size = 32, - .flags = AT24_FLAG_ADDR16, +static const struct property_entry eeprom_properties[] = { + PROPERTY_ENTRY_U32("pagesize", 32), + { } }; static struct i2c_board_info __initdata i2c_info[] = { { - I2C_BOARD_INFO("24lc64", 0x50), - .platform_data = &eeprom_info, + I2C_BOARD_INFO("24c64", 0x50), + .properties = eeprom_properties, }, /* Other I2C devices: * MSP430, addr 0x23 (not used) diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index e1d0f0d841ff..0c638fe15dcb 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -26,21 +26,6 @@ EXPORT_SYMBOL(davinci_soc_info); void __iomem *davinci_intc_base; int davinci_intc_type; -void davinci_get_mac_addr(struct nvmem_device *nvmem, void *context) -{ - char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; - off_t offset = (off_t)context; - - if (!IS_BUILTIN(CONFIG_NVMEM)) { - pr_warn("Cannot read MAC addr from EEPROM without CONFIG_NVMEM\n"); - return; - } - - /* Read MAC addr from EEPROM */ - if (nvmem_device_read(nvmem, offset, ETH_ALEN, mac_addr) == ETH_ALEN) - pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); -} - static int __init davinci_init_id(struct davinci_soc_info *soc_info) { int i; diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index c6a533699b00..85b74ac943f0 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -26,7 +26,6 @@ #include <mach/gpio-ep93xx.h> #include <mach/hardware.h> #include <mach/irqs.h> -#include <mach/gpio-ep93xx.h> #include <asm/mach-types.h> #include <asm/mach/map.h> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 8af2f7e91d13..35ff620537e6 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -29,9 +29,10 @@ obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o obj-$(CONFIG_SOC_IMX6SLL) += cpuidle-imx6sx.o obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6sx.o +obj-$(CONFIG_SOC_IMX7ULP) += cpuidle-imx7ulp.o endif -ifdef CONFIG_SND_IMX_SOC +ifdef CONFIG_SND_SOC_IMX_PCM_FIQ obj-y += ssi-fiq.o obj-y += ssi-fiq-ksym.o endif diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index bc915e5b4d56..c51764a85fd7 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -72,6 +72,15 @@ enum mxc_cpu_pwr_mode { STOP_POWER_OFF, /* STOP + SRPG */ }; +enum ulp_cpu_pwr_mode { + ULP_PM_HSRUN, /* High speed run mode */ + ULP_PM_RUN, /* Run mode */ + ULP_PM_WAIT, /* Wait mode */ + ULP_PM_STOP, /* Stop mode */ + ULP_PM_VLPS, /* Very low power stop mode */ + ULP_PM_VLLS, /* very low leakage stop mode */ +}; + void imx_enable_cpu(int cpu, bool enable); void imx_set_cpu_jump(int cpu, void *jump_addr); u32 imx_get_cpu_arg(int cpu); @@ -98,6 +107,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode); void imx6_set_int_mem_clk_lpm(bool enable); void imx6sl_set_wait_clk(bool enter); int imx_mmdc_get_ddr_type(void); +int imx7ulp_set_lpm(enum ulp_cpu_pwr_mode mode); void imx_cpu_die(unsigned int cpu); int imx_cpu_kill(unsigned int cpu); diff --git a/arch/arm/mach-imx/cpuidle-imx7ulp.c b/arch/arm/mach-imx/cpuidle-imx7ulp.c new file mode 100644 index 000000000000..ca86c967d19e --- /dev/null +++ b/arch/arm/mach-imx/cpuidle-imx7ulp.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP + * Anson Huang <Anson.Huang@nxp.com> + */ + +#include <linux/cpuidle.h> +#include <linux/module.h> +#include <asm/cpuidle.h> + +#include "common.h" +#include "cpuidle.h" + +static int imx7ulp_enter_wait(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + if (index == 1) + imx7ulp_set_lpm(ULP_PM_WAIT); + else + imx7ulp_set_lpm(ULP_PM_STOP); + + cpu_do_idle(); + + imx7ulp_set_lpm(ULP_PM_RUN); + + return index; +} + +static struct cpuidle_driver imx7ulp_cpuidle_driver = { + .name = "imx7ulp_cpuidle", + .owner = THIS_MODULE, + .states = { + /* WFI */ + ARM_CPUIDLE_WFI_STATE, + /* WAIT */ + { + .exit_latency = 50, + .target_residency = 75, + .enter = imx7ulp_enter_wait, + .name = "WAIT", + .desc = "PSTOP2", + }, + /* STOP */ + { + .exit_latency = 100, + .target_residency = 150, + .enter = imx7ulp_enter_wait, + .name = "STOP", + .desc = "PSTOP1", + }, + }, + .state_count = 3, + .safe_state_index = 0, +}; + +int __init imx7ulp_cpuidle_init(void) +{ + return cpuidle_register(&imx7ulp_cpuidle_driver, NULL); +} diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h index f9140128ba05..7694c8f810a4 100644 --- a/arch/arm/mach-imx/cpuidle.h +++ b/arch/arm/mach-imx/cpuidle.h @@ -15,6 +15,7 @@ extern int imx5_cpuidle_init(void); extern int imx6q_cpuidle_init(void); extern int imx6sl_cpuidle_init(void); extern int imx6sx_cpuidle_init(void); +extern int imx7ulp_cpuidle_init(void); #else static inline int imx5_cpuidle_init(void) { @@ -32,4 +33,8 @@ static inline int imx6sx_cpuidle_init(void) { return 0; } +static inline int imx7ulp_cpuidle_init(void) +{ + return 0; +} #endif diff --git a/arch/arm/mach-imx/mach-imx7ulp.c b/arch/arm/mach-imx/mach-imx7ulp.c index 33937ebf66b5..11ac71aaf965 100644 --- a/arch/arm/mach-imx/mach-imx7ulp.c +++ b/arch/arm/mach-imx/mach-imx7ulp.c @@ -6,17 +6,57 @@ */ #include <linux/irqchip.h> +#include <linux/mfd/syscon.h> #include <linux/of_platform.h> +#include <linux/regmap.h> #include <asm/mach/arch.h> #include "common.h" +#include "cpuidle.h" #include "hardware.h" +#define SIM_JTAG_ID_REG 0x8c + +static void __init imx7ulp_set_revision(void) +{ + struct regmap *sim; + u32 revision; + + sim = syscon_regmap_lookup_by_compatible("fsl,imx7ulp-sim"); + if (IS_ERR(sim)) { + pr_warn("failed to find fsl,imx7ulp-sim regmap!\n"); + return; + } + + if (regmap_read(sim, SIM_JTAG_ID_REG, &revision)) { + pr_warn("failed to read sim regmap!\n"); + return; + } + + /* + * bit[31:28] of JTAG_ID register defines revision as below from B0: + * 0001 B0 + * 0010 B1 + */ + switch (revision >> 28) { + case 1: + imx_set_soc_revision(IMX_CHIP_REVISION_2_0); + break; + case 2: + imx_set_soc_revision(IMX_CHIP_REVISION_2_1); + break; + default: + imx_set_soc_revision(IMX_CHIP_REVISION_1_0); + break; + } +} + static void __init imx7ulp_init_machine(void) { imx7ulp_pm_init(); mxc_set_cpu_type(MXC_CPU_IMX7ULP); + imx7ulp_set_revision(); of_platform_default_populate(NULL, NULL, imx_soc_device_init()); } @@ -25,7 +65,13 @@ static const char *const imx7ulp_dt_compat[] __initconst = { NULL, }; +static void __init imx7ulp_init_late(void) +{ + imx7ulp_cpuidle_init(); +} + DT_MACHINE_START(IMX7ulp, "Freescale i.MX7ULP (Device Tree)") .init_machine = imx7ulp_init_machine, .dt_compat = imx7ulp_dt_compat, + .init_late = imx7ulp_init_late, MACHINE_END diff --git a/arch/arm/mach-imx/pm-imx7ulp.c b/arch/arm/mach-imx/pm-imx7ulp.c index cf6a380c2b8d..7b2f7387e662 100644 --- a/arch/arm/mach-imx/pm-imx7ulp.c +++ b/arch/arm/mach-imx/pm-imx7ulp.c @@ -9,21 +9,60 @@ #include <linux/of.h> #include <linux/of_address.h> +#include "common.h" + #define SMC_PMCTRL 0x10 #define BP_PMCTRL_PSTOPO 16 #define PSTOPO_PSTOP3 0x3 +#define PSTOPO_PSTOP2 0x2 +#define PSTOPO_PSTOP1 0x1 +#define BP_PMCTRL_RUNM 8 +#define RUNM_RUN 0 +#define BP_PMCTRL_STOPM 0 +#define STOPM_STOP 0 + +#define BM_PMCTRL_PSTOPO (3 << BP_PMCTRL_PSTOPO) +#define BM_PMCTRL_RUNM (3 << BP_PMCTRL_RUNM) +#define BM_PMCTRL_STOPM (7 << BP_PMCTRL_STOPM) + +static void __iomem *smc1_base; + +int imx7ulp_set_lpm(enum ulp_cpu_pwr_mode mode) +{ + u32 val = readl_relaxed(smc1_base + SMC_PMCTRL); + + /* clear all */ + val &= ~(BM_PMCTRL_RUNM | BM_PMCTRL_STOPM | BM_PMCTRL_PSTOPO); + + switch (mode) { + case ULP_PM_RUN: + /* system/bus clock enabled */ + val |= PSTOPO_PSTOP3 << BP_PMCTRL_PSTOPO; + break; + case ULP_PM_WAIT: + /* system clock disabled, bus clock enabled */ + val |= PSTOPO_PSTOP2 << BP_PMCTRL_PSTOPO; + break; + case ULP_PM_STOP: + /* system/bus clock disabled */ + val |= PSTOPO_PSTOP1 << BP_PMCTRL_PSTOPO; + break; + default: + return -EINVAL; + } + + writel_relaxed(val, smc1_base + SMC_PMCTRL); + + return 0; +} void __init imx7ulp_pm_init(void) { struct device_node *np; - void __iomem *smc1_base; np = of_find_compatible_node(NULL, NULL, "fsl,imx7ulp-smc1"); smc1_base = of_iomap(np, 0); WARN_ON(!smc1_base); - /* Partial Stop mode 3 with system/bus clock enabled */ - writel_relaxed(PSTOPO_PSTOP3 << BP_PMCTRL_PSTOPO, - smc1_base + SMC_PMCTRL); - iounmap(smc1_base); + imx7ulp_set_lpm(ULP_PM_RUN); } diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index a109f6482413..8dfad012dfae 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -390,10 +390,14 @@ static int __ref impd1_probe(struct lm_device *dev) char *mmciname; lookup = devm_kzalloc(&dev->dev, - sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup), + struct_size(lookup, table, 3), GFP_KERNEL); chipname = devm_kstrdup(&dev->dev, devname, GFP_KERNEL); - mmciname = kasprintf(GFP_KERNEL, "lm%x:00700", dev->id); + mmciname = devm_kasprintf(&dev->dev, GFP_KERNEL, + "lm%x:00700", dev->id); + if (!lookup || !chipname || !mmciname) + return -ENOMEM; + lookup->dev_id = mmciname; /* * Offsets on GPIO block 1: diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index dc8e4f4b7ade..8839c72fdee3 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -454,24 +454,6 @@ config MACH_TREO680 Say Y here if you intend to run this kernel on Palm Treo 680 smartphone. -config MACH_RAUMFELD_RC - bool "Raumfeld Controller" - select CPU_PXA300 - select POWER_SUPPLY - select PXA3xx - -config MACH_RAUMFELD_CONNECTOR - bool "Raumfeld Connector" - select CPU_PXA300 - select POWER_SUPPLY - select PXA3xx - -config MACH_RAUMFELD_SPEAKER - bool "Raumfeld Speaker" - select CPU_PXA300 - select POWER_SUPPLY - select PXA3xx - config PXA_SHARPSL bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models" select SHARP_PARAM diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 0a8e9611052f..f70728930c4f 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -86,9 +86,6 @@ obj-$(CONFIG_MACH_POODLE) += poodle.o obj-$(CONFIG_MACH_TOSA) += tosa.o obj-$(CONFIG_MACH_ICONTROL) += icontrol.o mxm8x10.o obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o -obj-$(CONFIG_MACH_RAUMFELD_RC) += raumfeld.o -obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR) += raumfeld.o -obj-$(CONFIG_MACH_RAUMFELD_SPEAKER) += raumfeld.o obj-$(CONFIG_MACH_ZIPIT2) += z2.o obj-$(CONFIG_PXA_SYSTEMS_CPLDS) += pxa_cplds_irqs.o diff --git a/arch/arm/mach-pxa/include/mach/pxa25x-udc.h b/arch/arm/mach-pxa/include/mach/pxa25x-udc.h deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/arch/arm/mach-pxa/include/mach/pxa25x-udc.h +++ /dev/null diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c deleted file mode 100644 index e1db072756f2..000000000000 --- a/arch/arm/mach-pxa/raumfeld.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* - * arch/arm/mach-pxa/raumfeld.c - * - * Support for the following Raumfeld devices: - * - * * Controller - * * Connector - * * Speaker S/M - * - * See http://www.raumfeld.com for details. - * - * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/property.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/gpio.h> -#include <linux/gpio/machine.h> -#include <linux/smsc911x.h> -#include <linux/input.h> -#include <linux/gpio_keys.h> -#include <linux/leds.h> -#include <linux/w1-gpio.h> -#include <linux/sched.h> -#include <linux/pwm.h> -#include <linux/pwm_backlight.h> -#include <linux/i2c.h> -#include <linux/platform_data/i2c-pxa.h> -#include <linux/spi/spi.h> -#include <linux/spi/spi_gpio.h> -#include <linux/lis3lv02d.h> -#include <linux/pda_power.h> -#include <linux/power_supply.h> -#include <linux/regulator/max8660.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/consumer.h> -#include <linux/delay.h> - -#include <asm/system_info.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#include "pxa300.h" -#include <linux/platform_data/usb-ohci-pxa27x.h> -#include <linux/platform_data/video-pxafb.h> -#include <linux/platform_data/mmc-pxamci.h> -#include <linux/platform_data/mtd-nand-pxa3xx.h> - -#include "generic.h" -#include "devices.h" - -/* common GPIO definitions */ - -/* inputs */ -#define GPIO_ON_OFF (14) -#define GPIO_VOLENC_A (19) -#define GPIO_VOLENC_B (20) -#define GPIO_CHARGE_DONE (23) -#define GPIO_CHARGE_IND (27) -#define GPIO_TOUCH_IRQ (32) -#define GPIO_ETH_IRQ (40) -#define GPIO_SPI_MISO (98) -#define GPIO_ACCEL_IRQ (104) -#define GPIO_RESCUE_BOOT (115) -#define GPIO_DOCK_DETECT (116) -#define GPIO_KEY1 (117) -#define GPIO_KEY2 (118) -#define GPIO_KEY3 (119) -#define GPIO_CHARGE_USB_OK (112) -#define GPIO_CHARGE_DC_OK (101) -#define GPIO_CHARGE_USB_SUSP (102) - -/* outputs */ -#define GPIO_SHUTDOWN_SUPPLY (16) -#define GPIO_SHUTDOWN_BATT (18) -#define GPIO_CHRG_PEN2 (31) -#define GPIO_TFT_VA_EN (33) -#define GPIO_SPDIF_CS (34) -#define GPIO_LED2 (35) -#define GPIO_LED1 (36) -#define GPIO_SPDIF_RESET (38) -#define GPIO_SPI_CLK (95) -#define GPIO_MCLK_DAC_CS (96) -#define GPIO_SPI_MOSI (97) -#define GPIO_W1_PULLUP_ENABLE (105) -#define GPIO_DISPLAY_ENABLE (106) -#define GPIO_MCLK_RESET (111) -#define GPIO_W2W_RESET (113) -#define GPIO_W2W_PDN (114) -#define GPIO_CODEC_RESET (120) -#define GPIO_AUDIO_VA_ENABLE (124) -#define GPIO_ACCEL_CS (125) -#define GPIO_ONE_WIRE (126) - -/* - * GPIO configurations - */ -static mfp_cfg_t raumfeld_controller_pin_config[] __initdata = { - /* UART1 */ - GPIO77_UART1_RXD, - GPIO78_UART1_TXD, - GPIO79_UART1_CTS, - GPIO81_UART1_DSR, - GPIO83_UART1_DTR, - GPIO84_UART1_RTS, - - /* UART3 */ - GPIO110_UART3_RXD, - - /* USB Host */ - GPIO0_2_USBH_PEN, - GPIO1_2_USBH_PWR, - - /* I2C */ - GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT, - GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT, - - /* SPI */ - GPIO34_GPIO, /* SPDIF_CS */ - GPIO96_GPIO, /* MCLK_CS */ - GPIO125_GPIO, /* ACCEL_CS */ - - /* MMC */ - GPIO3_MMC1_DAT0, - GPIO4_MMC1_DAT1, - GPIO5_MMC1_DAT2, - GPIO6_MMC1_DAT3, - GPIO7_MMC1_CLK, - GPIO8_MMC1_CMD, - - /* One-wire */ - GPIO126_GPIO | MFP_LPM_FLOAT, - GPIO105_GPIO | MFP_PULL_LOW | MFP_LPM_PULL_LOW, - - /* CHRG_USB_OK */ - GPIO101_GPIO | MFP_PULL_HIGH, - /* CHRG_USB_OK */ - GPIO112_GPIO | MFP_PULL_HIGH, - /* CHRG_USB_SUSP */ - GPIO102_GPIO, - /* DISPLAY_ENABLE */ - GPIO106_GPIO, - /* DOCK_DETECT */ - GPIO116_GPIO | MFP_LPM_FLOAT | MFP_PULL_FLOAT, - - /* LCD */ - GPIO54_LCD_LDD_0, - GPIO55_LCD_LDD_1, - GPIO56_LCD_LDD_2, - GPIO57_LCD_LDD_3, - GPIO58_LCD_LDD_4, - GPIO59_LCD_LDD_5, - GPIO60_LCD_LDD_6, - GPIO61_LCD_LDD_7, - GPIO62_LCD_LDD_8, - GPIO63_LCD_LDD_9, - GPIO64_LCD_LDD_10, - GPIO65_LCD_LDD_11, - GPIO66_LCD_LDD_12, - GPIO67_LCD_LDD_13, - GPIO68_LCD_LDD_14, - GPIO69_LCD_LDD_15, - GPIO70_LCD_LDD_16, - GPIO71_LCD_LDD_17, - GPIO72_LCD_FCLK, - GPIO73_LCD_LCLK, - GPIO74_LCD_PCLK, - GPIO75_LCD_BIAS, -}; - -static mfp_cfg_t raumfeld_connector_pin_config[] __initdata = { - /* UART1 */ - GPIO77_UART1_RXD, - GPIO78_UART1_TXD, - GPIO79_UART1_CTS, - GPIO81_UART1_DSR, - GPIO83_UART1_DTR, - GPIO84_UART1_RTS, - - /* UART3 */ - GPIO110_UART3_RXD, - - /* USB Host */ - GPIO0_2_USBH_PEN, - GPIO1_2_USBH_PWR, - - /* I2C */ - GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT, - GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT, - - /* SPI */ - GPIO34_GPIO, /* SPDIF_CS */ - GPIO96_GPIO, /* MCLK_CS */ - GPIO125_GPIO, /* ACCEL_CS */ - - /* MMC */ - GPIO3_MMC1_DAT0, - GPIO4_MMC1_DAT1, - GPIO5_MMC1_DAT2, - GPIO6_MMC1_DAT3, - GPIO7_MMC1_CLK, - GPIO8_MMC1_CMD, - - /* Ethernet */ - GPIO1_nCS2, /* CS */ - GPIO40_GPIO | MFP_PULL_HIGH, /* IRQ */ - - /* SSP for I2S */ - GPIO85_SSP1_SCLK, - GPIO89_SSP1_EXTCLK, - GPIO86_SSP1_FRM, - GPIO87_SSP1_TXD, - GPIO88_SSP1_RXD, - GPIO90_SSP1_SYSCLK, - - /* SSP2 for S/PDIF */ - GPIO25_SSP2_SCLK, - GPIO26_SSP2_FRM, - GPIO27_SSP2_TXD, - GPIO29_SSP2_EXTCLK, - - /* LEDs */ - GPIO35_GPIO | MFP_LPM_PULL_LOW, - GPIO36_GPIO | MFP_LPM_DRIVE_HIGH, -}; - -static mfp_cfg_t raumfeld_speaker_pin_config[] __initdata = { - /* UART1 */ - GPIO77_UART1_RXD, - GPIO78_UART1_TXD, - GPIO79_UART1_CTS, - GPIO81_UART1_DSR, - GPIO83_UART1_DTR, - GPIO84_UART1_RTS, - - /* UART3 */ - GPIO110_UART3_RXD, - - /* USB Host */ - GPIO0_2_USBH_PEN, - GPIO1_2_USBH_PWR, - - /* I2C */ - GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT, - GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT, - - /* SPI */ - GPIO34_GPIO, /* SPDIF_CS */ - GPIO96_GPIO, /* MCLK_CS */ - GPIO125_GPIO, /* ACCEL_CS */ - - /* MMC */ - GPIO3_MMC1_DAT0, - GPIO4_MMC1_DAT1, - GPIO5_MMC1_DAT2, - GPIO6_MMC1_DAT3, - GPIO7_MMC1_CLK, - GPIO8_MMC1_CMD, - - /* Ethernet */ - GPIO1_nCS2, /* CS */ - GPIO40_GPIO | MFP_PULL_HIGH, /* IRQ */ - - /* SSP for I2S */ - GPIO85_SSP1_SCLK, - GPIO89_SSP1_EXTCLK, - GPIO86_SSP1_FRM, - GPIO87_SSP1_TXD, - GPIO88_SSP1_RXD, - GPIO90_SSP1_SYSCLK, - - /* LEDs */ - GPIO35_GPIO | MFP_LPM_PULL_LOW, - GPIO36_GPIO | MFP_LPM_DRIVE_HIGH, -}; - -/* - * SMSC LAN9220 Ethernet - */ - -static struct resource smc91x_resources[] = { - { - .start = PXA3xx_CS2_PHYS, - .end = PXA3xx_CS2_PHYS + 0xfffff, - .flags = IORESOURCE_MEM, - }, - { - .start = PXA_GPIO_TO_IRQ(GPIO_ETH_IRQ), - .end = PXA_GPIO_TO_IRQ(GPIO_ETH_IRQ), - .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, - } -}; - -static struct smsc911x_platform_config raumfeld_smsc911x_config = { - .phy_interface = PHY_INTERFACE_MODE_MII, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, -}; - -static struct platform_device smc91x_device = { - .name = "smsc911x", - .id = -1, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, - .dev = { - .platform_data = &raumfeld_smsc911x_config, - } -}; - -/** - * NAND - */ - -static struct mtd_partition raumfeld_nand_partitions[] = { - { - .name = "Bootloader", - .offset = 0, - .size = 0xa0000, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "BootloaderEnvironment", - .offset = 0xa0000, - .size = 0x20000, - }, - { - .name = "BootloaderSplashScreen", - .offset = 0xc0000, - .size = 0x60000, - }, - { - .name = "UBI", - .offset = 0x120000, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct pxa3xx_nand_platform_data raumfeld_nand_info = { - .keep_config = 1, - .parts = raumfeld_nand_partitions, - .nr_parts = ARRAY_SIZE(raumfeld_nand_partitions), -}; - -/** - * USB (OHCI) support - */ - -static struct pxaohci_platform_data raumfeld_ohci_info = { - .port_mode = PMM_GLOBAL_MODE, - .flags = ENABLE_PORT1, -}; - -/** - * Rotary encoder input device - */ - -static struct gpiod_lookup_table raumfeld_rotary_gpios_table = { - .dev_id = "rotary-encoder.0", - .table = { - GPIO_LOOKUP_IDX("gpio-0", - GPIO_VOLENC_A, NULL, 0, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("gpio-0", - GPIO_VOLENC_B, NULL, 1, GPIO_ACTIVE_HIGH), - { }, - }, -}; - -static const struct property_entry raumfeld_rotary_properties[] __initconst = { - PROPERTY_ENTRY_U32("rotary-encoder,steps-per-period", 24), - PROPERTY_ENTRY_U32("linux,axis", REL_X), - PROPERTY_ENTRY_U32("rotary-encoder,relative_axis", 1), - { }, -}; - -static struct platform_device rotary_encoder_device = { - .name = "rotary-encoder", - .id = 0, -}; - -/** - * GPIO buttons - */ - -static struct gpio_keys_button gpio_keys_button[] = { - { - .code = KEY_F1, - .type = EV_KEY, - .gpio = GPIO_KEY1, - .active_low = 1, - .wakeup = 0, - .debounce_interval = 5, /* ms */ - .desc = "Button 1", - }, - { - .code = KEY_F2, - .type = EV_KEY, - .gpio = GPIO_KEY2, - .active_low = 1, - .wakeup = 0, - .debounce_interval = 5, /* ms */ - .desc = "Button 2", - }, - { - .code = KEY_F3, - .type = EV_KEY, - .gpio = GPIO_KEY3, - .active_low = 1, - .wakeup = 0, - .debounce_interval = 5, /* ms */ - .desc = "Button 3", - }, - { - .code = KEY_F4, - .type = EV_KEY, - .gpio = GPIO_RESCUE_BOOT, - .active_low = 0, - .wakeup = 0, - .debounce_interval = 5, /* ms */ - .desc = "rescue boot button", - }, - { - .code = KEY_F5, - .type = EV_KEY, - .gpio = GPIO_DOCK_DETECT, - .active_low = 1, - .wakeup = 0, - .debounce_interval = 5, /* ms */ - .desc = "dock detect", - }, - { - .code = KEY_F6, - .type = EV_KEY, - .gpio = GPIO_ON_OFF, - .active_low = 0, - .wakeup = 0, - .debounce_interval = 5, /* ms */ - .desc = "on_off button", - }, -}; - -static struct gpio_keys_platform_data gpio_keys_platform_data = { - .buttons = gpio_keys_button, - .nbuttons = ARRAY_SIZE(gpio_keys_button), - .rep = 0, -}; - -static struct platform_device raumfeld_gpio_keys_device = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &gpio_keys_platform_data, - } -}; - -/** - * GPIO LEDs - */ - -static struct gpio_led raumfeld_leds[] = { - { - .name = "raumfeld:1", - .gpio = GPIO_LED1, - .active_low = 1, - .default_state = LEDS_GPIO_DEFSTATE_ON, - }, - { - .name = "raumfeld:2", - .gpio = GPIO_LED2, - .active_low = 0, - .default_state = LEDS_GPIO_DEFSTATE_OFF, - } -}; - -static struct gpio_led_platform_data raumfeld_led_platform_data = { - .leds = raumfeld_leds, - .num_leds = ARRAY_SIZE(raumfeld_leds), -}; - -static struct platform_device raumfeld_led_device = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &raumfeld_led_platform_data, - }, -}; - -/** - * One-wire (W1 bus) support - */ - -static void w1_enable_external_pullup(int enable) -{ - gpio_set_value(GPIO_W1_PULLUP_ENABLE, enable); - msleep(100); -} - -static struct gpiod_lookup_table raumfeld_w1_gpiod_table = { - .dev_id = "w1-gpio", - .table = { - GPIO_LOOKUP_IDX("gpio-pxa", GPIO_ONE_WIRE, NULL, 0, - GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), - }, -}; - -static struct w1_gpio_platform_data w1_gpio_platform_data = { - .enable_external_pullup = w1_enable_external_pullup, -}; - -static struct platform_device raumfeld_w1_gpio_device = { - .name = "w1-gpio", - .dev = { - .platform_data = &w1_gpio_platform_data - } -}; - -static void __init raumfeld_w1_init(void) -{ - int ret = gpio_request(GPIO_W1_PULLUP_ENABLE, - "W1 external pullup enable"); - - if (ret < 0) - pr_warn("Unable to request GPIO_W1_PULLUP_ENABLE\n"); - else - gpio_direction_output(GPIO_W1_PULLUP_ENABLE, 0); - - gpiod_add_lookup_table(&raumfeld_w1_gpiod_table); - platform_device_register(&raumfeld_w1_gpio_device); -} - -/** - * Framebuffer device - */ - -static struct pwm_lookup raumfeld_pwm_lookup[] = { - PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight", NULL, 10000, - PWM_POLARITY_NORMAL), -}; - -/* PWM controlled backlight */ -static struct platform_pwm_backlight_data raumfeld_pwm_backlight_data = { - .max_brightness = 100, - .dft_brightness = 100, - .enable_gpio = -1, -}; - -static struct platform_device raumfeld_pwm_backlight_device = { - .name = "pwm-backlight", - .dev = { - .parent = &pxa27x_device_pwm0.dev, - .platform_data = &raumfeld_pwm_backlight_data, - } -}; - -/* LT3593 controlled backlight */ -static struct gpio_led raumfeld_lt3593_led = { - .name = "backlight", - .gpio = mfp_to_gpio(MFP_PIN_GPIO17), - .default_state = LEDS_GPIO_DEFSTATE_ON, -}; - -static struct gpio_led_platform_data raumfeld_lt3593_platform_data = { - .leds = &raumfeld_lt3593_led, - .num_leds = 1, -}; - -static struct platform_device raumfeld_lt3593_device = { - .name = "leds-lt3593", - .id = -1, - .dev = { - .platform_data = &raumfeld_lt3593_platform_data, - }, -}; - -static struct pxafb_mode_info sharp_lq043t3dx02_mode = { - .pixclock = 111000, - .xres = 480, - .yres = 272, - .bpp = 16, - .hsync_len = 41, - .left_margin = 2, - .right_margin = 1, - .vsync_len = 10, - .upper_margin = 3, - .lower_margin = 1, - .sync = 0, -}; - -static struct pxafb_mach_info raumfeld_sharp_lcd_info = { - .modes = &sharp_lq043t3dx02_mode, - .num_modes = 1, - .video_mem_size = 0x400000, - .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, -#ifdef CONFIG_PXA3XX_GCU - .acceleration_enabled = 1, -#endif -}; - -static void __init raumfeld_lcd_init(void) -{ - int ret; - - ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable"); - if (ret < 0) - pr_warn("Unable to request GPIO_TFT_VA_EN\n"); - else - gpio_direction_output(GPIO_TFT_VA_EN, 1); - - msleep(100); - - ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable"); - if (ret < 0) - pr_warn("Unable to request GPIO_DISPLAY_ENABLE\n"); - else - gpio_direction_output(GPIO_DISPLAY_ENABLE, 1); - - /* Hardware revision 2 has the backlight regulator controlled - * by an LT3593, earlier and later devices use PWM for that. */ - if ((system_rev & 0xff) == 2) { - platform_device_register(&raumfeld_lt3593_device); - } else { - mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT; - pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1); - pwm_add_table(raumfeld_pwm_lookup, - ARRAY_SIZE(raumfeld_pwm_lookup)); - platform_device_register(&raumfeld_pwm_backlight_device); - } - - pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info); - platform_device_register(&pxa3xx_device_gcu); -} - -/** - * SPI devices - */ - -static struct spi_gpio_platform_data raumfeld_spi_platform_data = { - .num_chipselect = 3, -}; - -static struct platform_device raumfeld_spi_device = { - .name = "spi_gpio", - .id = 0, - .dev = { - .platform_data = &raumfeld_spi_platform_data, - } -}; - -static struct gpiod_lookup_table raumfeld_spi_gpiod_table = { - .dev_id = "spi_gpio", - .table = { - GPIO_LOOKUP("gpio-0", GPIO_SPI_CLK, - "sck", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio-0", GPIO_SPI_MOSI, - "mosi", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio-0", GPIO_SPI_MISO, - "miso", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX("gpio-0", GPIO_SPDIF_CS, - "cs", 0, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX("gpio-0", GPIO_ACCEL_CS, - "cs", 1, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX("gpio-0", GPIO_MCLK_DAC_CS, - "cs", 2, GPIO_ACTIVE_HIGH), - { }, - }, -}; - -static struct lis3lv02d_platform_data lis3_pdata = { - .click_flags = LIS3_CLICK_SINGLE_X | - LIS3_CLICK_SINGLE_Y | - LIS3_CLICK_SINGLE_Z, - .irq_cfg = LIS3_IRQ1_CLICK | LIS3_IRQ2_CLICK, - .wakeup_flags = LIS3_WAKEUP_X_LO | LIS3_WAKEUP_X_HI | - LIS3_WAKEUP_Y_LO | LIS3_WAKEUP_Y_HI | - LIS3_WAKEUP_Z_LO | LIS3_WAKEUP_Z_HI, - .wakeup_thresh = 10, - .click_thresh_x = 10, - .click_thresh_y = 10, - .click_thresh_z = 10, -}; - -#define SPI_AK4104 \ -{ \ - .modalias = "ak4104-codec", \ - .max_speed_hz = 10000, \ - .bus_num = 0, \ - .chip_select = 0, \ -} - -#define SPI_LIS3 \ -{ \ - .modalias = "lis3lv02d_spi", \ - .max_speed_hz = 1000000, \ - .bus_num = 0, \ - .chip_select = 1, \ - .platform_data = &lis3_pdata, \ - .irq = PXA_GPIO_TO_IRQ(GPIO_ACCEL_IRQ), \ -} - -#define SPI_DAC7512 \ -{ \ - .modalias = "dac7512", \ - .max_speed_hz = 1000000, \ - .bus_num = 0, \ - .chip_select = 2, \ -} - -static struct spi_board_info connector_spi_devices[] __initdata = { - SPI_AK4104, - SPI_DAC7512, -}; - -static struct spi_board_info speaker_spi_devices[] __initdata = { - SPI_DAC7512, -}; - -static struct spi_board_info controller_spi_devices[] __initdata = { - SPI_LIS3, -}; - -/** - * MMC for Marvell Libertas 8688 via SDIO - */ - -static int raumfeld_mci_init(struct device *dev, irq_handler_t isr, void *data) -{ - gpio_set_value(GPIO_W2W_RESET, 1); - gpio_set_value(GPIO_W2W_PDN, 1); - - return 0; -} - -static void raumfeld_mci_exit(struct device *dev, void *data) -{ - gpio_set_value(GPIO_W2W_RESET, 0); - gpio_set_value(GPIO_W2W_PDN, 0); -} - -static struct pxamci_platform_data raumfeld_mci_platform_data = { - .init = raumfeld_mci_init, - .exit = raumfeld_mci_exit, - .detect_delay_ms = 200, -}; - -/* - * External power / charge logic - */ - -static int power_supply_init(struct device *dev) -{ - return 0; -} - -static void power_supply_exit(struct device *dev) -{ -} - -static int raumfeld_is_ac_online(void) -{ - return !gpio_get_value(GPIO_CHARGE_DC_OK); -} - -static int raumfeld_is_usb_online(void) -{ - return 0; -} - -static char *raumfeld_power_supplicants[] = { "ds2760-battery.0" }; - -static void raumfeld_power_signal_charged(void) -{ - struct power_supply *psy = - power_supply_get_by_name(raumfeld_power_supplicants[0]); - - if (psy) { - power_supply_set_battery_charged(psy); - power_supply_put(psy); - } -} - -static int raumfeld_power_resume(void) -{ - /* check if GPIO_CHARGE_DONE went low while we were sleeping */ - if (!gpio_get_value(GPIO_CHARGE_DONE)) - raumfeld_power_signal_charged(); - - return 0; -} - -static struct pda_power_pdata power_supply_info = { - .init = power_supply_init, - .is_ac_online = raumfeld_is_ac_online, - .is_usb_online = raumfeld_is_usb_online, - .exit = power_supply_exit, - .supplied_to = raumfeld_power_supplicants, - .num_supplicants = ARRAY_SIZE(raumfeld_power_supplicants), - .resume = raumfeld_power_resume, -}; - -static struct resource power_supply_resources[] = { - { - .name = "ac", - .flags = IORESOURCE_IRQ | - IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, - .start = GPIO_CHARGE_DC_OK, - .end = GPIO_CHARGE_DC_OK, - }, -}; - -static irqreturn_t charge_done_irq(int irq, void *dev_id) -{ - raumfeld_power_signal_charged(); - return IRQ_HANDLED; -} - -static struct platform_device raumfeld_power_supply = { - .name = "pda-power", - .id = -1, - .dev = { - .platform_data = &power_supply_info, - }, - .resource = power_supply_resources, - .num_resources = ARRAY_SIZE(power_supply_resources), -}; - -static void __init raumfeld_power_init(void) -{ - int ret; - - /* Set PEN2 high to enable maximum charge current */ - ret = gpio_request(GPIO_CHRG_PEN2, "CHRG_PEN2"); - if (ret < 0) - pr_warn("Unable to request GPIO_CHRG_PEN2\n"); - else - gpio_direction_output(GPIO_CHRG_PEN2, 1); - - ret = gpio_request(GPIO_CHARGE_DC_OK, "CABLE_DC_OK"); - if (ret < 0) - pr_warn("Unable to request GPIO_CHARGE_DC_OK\n"); - - ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP"); - if (ret < 0) - pr_warn("Unable to request GPIO_CHARGE_USB_SUSP\n"); - else - gpio_direction_output(GPIO_CHARGE_USB_SUSP, 0); - - power_supply_resources[0].start = gpio_to_irq(GPIO_CHARGE_DC_OK); - power_supply_resources[0].end = gpio_to_irq(GPIO_CHARGE_DC_OK); - - ret = request_irq(gpio_to_irq(GPIO_CHARGE_DONE), - &charge_done_irq, IORESOURCE_IRQ_LOWEDGE, - "charge_done", NULL); - - if (ret < 0) - printk(KERN_ERR "%s: unable to register irq %d\n", __func__, - GPIO_CHARGE_DONE); - else - platform_device_register(&raumfeld_power_supply); -} - -/* Fixed regulator for AUDIO_VA, 0-0048 maps to the cs4270 codec device */ - -static struct regulator_consumer_supply audio_va_consumer_supply = - REGULATOR_SUPPLY("va", "0-0048"); - -static struct regulator_init_data audio_va_initdata = { - .consumer_supplies = &audio_va_consumer_supply, - .num_consumer_supplies = 1, - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, -}; - -static struct fixed_voltage_config audio_va_config = { - .supply_name = "audio_va", - .microvolts = 5000000, - .enable_high = 1, - .enabled_at_boot = 0, - .init_data = &audio_va_initdata, -}; - -static struct platform_device audio_va_device = { - .name = "reg-fixed-voltage", - .id = 0, - .dev = { - .platform_data = &audio_va_config, - }, -}; - -static struct gpiod_lookup_table audio_va_gpiod_table = { - .dev_id = "reg-fixed-voltage.0", - .table = { - GPIO_LOOKUP("gpio-pxa", GPIO_AUDIO_VA_ENABLE, - NULL, GPIO_ACTIVE_HIGH), - { }, - }, -}; - -/* Dummy supplies for Codec's VD/VLC */ - -static struct regulator_consumer_supply audio_dummy_supplies[] = { - REGULATOR_SUPPLY("vd", "0-0048"), - REGULATOR_SUPPLY("vlc", "0-0048"), -}; - -static struct regulator_init_data audio_dummy_initdata = { - .consumer_supplies = audio_dummy_supplies, - .num_consumer_supplies = ARRAY_SIZE(audio_dummy_supplies), - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, -}; - -static struct fixed_voltage_config audio_dummy_config = { - .supply_name = "audio_vd", - .microvolts = 3300000, - .init_data = &audio_dummy_initdata, -}; - -static struct platform_device audio_supply_dummy_device = { - .name = "reg-fixed-voltage", - .id = 1, - .dev = { - .platform_data = &audio_dummy_config, - }, -}; - -static struct platform_device *audio_regulator_devices[] = { - &audio_va_device, - &audio_supply_dummy_device, -}; - -/** - * Regulator support via MAX8660 - */ - -static struct regulator_consumer_supply vcc_mmc_supply = - REGULATOR_SUPPLY("vmmc", "pxa2xx-mci.0"); - -static struct regulator_init_data vcc_mmc_init_data = { - .constraints = { - .min_uV = 3300000, - .max_uV = 3300000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .valid_ops_mask = REGULATOR_CHANGE_STATUS | - REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_MODE, - }, - .consumer_supplies = &vcc_mmc_supply, - .num_consumer_supplies = 1, -}; - -static struct max8660_subdev_data max8660_v6_subdev_data = { - .id = MAX8660_V6, - .name = "vmmc", - .platform_data = &vcc_mmc_init_data, -}; - -static struct max8660_platform_data max8660_pdata = { - .subdevs = &max8660_v6_subdev_data, - .num_subdevs = 1, -}; - -/** - * I2C devices - */ - -static struct i2c_board_info raumfeld_pwri2c_board_info = { - .type = "max8660", - .addr = 0x34, - .platform_data = &max8660_pdata, -}; - -static struct i2c_board_info raumfeld_connector_i2c_board_info __initdata = { - .type = "cs4270", - .addr = 0x48, -}; - -static struct gpiod_lookup_table raumfeld_controller_gpios_table = { - .dev_id = "0-000a", - .table = { - GPIO_LOOKUP("gpio-pxa", - GPIO_TOUCH_IRQ, "attn", GPIO_ACTIVE_HIGH), - { }, - }, -}; - -static const struct resource raumfeld_controller_resources[] __initconst = { - { - .start = PXA_GPIO_TO_IRQ(GPIO_TOUCH_IRQ), - .end = PXA_GPIO_TO_IRQ(GPIO_TOUCH_IRQ), - .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH, - }, -}; - -static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = { - .type = "eeti_ts", - .addr = 0x0a, - .resources = raumfeld_controller_resources, - .num_resources = ARRAY_SIZE(raumfeld_controller_resources), -}; - -static struct platform_device *raumfeld_common_devices[] = { - &raumfeld_gpio_keys_device, - &raumfeld_led_device, - &raumfeld_spi_device, -}; - -static void __init raumfeld_audio_init(void) -{ - int ret; - - ret = gpio_request(GPIO_CODEC_RESET, "cs4270 reset"); - if (ret < 0) - pr_warn("unable to request GPIO_CODEC_RESET\n"); - else - gpio_direction_output(GPIO_CODEC_RESET, 1); - - ret = gpio_request(GPIO_SPDIF_RESET, "ak4104 s/pdif reset"); - if (ret < 0) - pr_warn("unable to request GPIO_SPDIF_RESET\n"); - else - gpio_direction_output(GPIO_SPDIF_RESET, 1); - - ret = gpio_request(GPIO_MCLK_RESET, "MCLK reset"); - if (ret < 0) - pr_warn("unable to request GPIO_MCLK_RESET\n"); - else - gpio_direction_output(GPIO_MCLK_RESET, 1); - - gpiod_add_lookup_table(&audio_va_gpiod_table); - platform_add_devices(ARRAY_AND_SIZE(audio_regulator_devices)); -} - -static void __init raumfeld_common_init(void) -{ - int ret; - - /* The on/off button polarity has changed after revision 1 */ - if ((system_rev & 0xff) > 1) { - int i; - - for (i = 0; i < ARRAY_SIZE(gpio_keys_button); i++) - if (!strcmp(gpio_keys_button[i].desc, "on_off button")) - gpio_keys_button[i].active_low = 1; - } - - enable_irq_wake(IRQ_WAKEUP0); - - pxa3xx_set_nand_info(&raumfeld_nand_info); - pxa3xx_set_i2c_power_info(NULL); - pxa_set_ohci_info(&raumfeld_ohci_info); - pxa_set_mci_info(&raumfeld_mci_platform_data); - pxa_set_i2c_info(NULL); - pxa_set_ffuart_info(NULL); - - ret = gpio_request(GPIO_W2W_RESET, "Wi2Wi reset"); - if (ret < 0) - pr_warn("Unable to request GPIO_W2W_RESET\n"); - else - gpio_direction_output(GPIO_W2W_RESET, 0); - - ret = gpio_request(GPIO_W2W_PDN, "Wi2Wi powerup"); - if (ret < 0) - pr_warn("Unable to request GPIO_W2W_PDN\n"); - else - gpio_direction_output(GPIO_W2W_PDN, 0); - - /* this can be used to switch off the device */ - ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown"); - if (ret < 0) - pr_warn("Unable to request GPIO_SHUTDOWN_SUPPLY\n"); - else - gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0); - - gpiod_add_lookup_table(&raumfeld_spi_gpiod_table); - platform_add_devices(ARRAY_AND_SIZE(raumfeld_common_devices)); - i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1); -} - -static void __init __maybe_unused raumfeld_controller_init(void) -{ - int ret; - - pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_controller_pin_config)); - - gpiod_add_lookup_table(&raumfeld_rotary_gpios_table); - device_add_properties(&rotary_encoder_device.dev, - raumfeld_rotary_properties); - platform_device_register(&rotary_encoder_device); - - spi_register_board_info(ARRAY_AND_SIZE(controller_spi_devices)); - - gpiod_add_lookup_table(&raumfeld_controller_gpios_table); - i2c_register_board_info(0, &raumfeld_controller_i2c_board_info, 1); - - ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown"); - if (ret < 0) - pr_warn("Unable to request GPIO_SHUTDOWN_BATT\n"); - else - gpio_direction_output(GPIO_SHUTDOWN_BATT, 0); - - raumfeld_common_init(); - raumfeld_power_init(); - raumfeld_lcd_init(); - raumfeld_w1_init(); -} - -static void __init __maybe_unused raumfeld_connector_init(void) -{ - pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_connector_pin_config)); - spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices)); - i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1); - - platform_device_register(&smc91x_device); - - raumfeld_audio_init(); - raumfeld_common_init(); -} - -static void __init __maybe_unused raumfeld_speaker_init(void) -{ - pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_speaker_pin_config)); - spi_register_board_info(ARRAY_AND_SIZE(speaker_spi_devices)); - i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1); - - platform_device_register(&smc91x_device); - - gpiod_add_lookup_table(&raumfeld_rotary_gpios_table); - device_add_properties(&rotary_encoder_device.dev, - raumfeld_rotary_properties); - platform_device_register(&rotary_encoder_device); - - raumfeld_audio_init(); - raumfeld_common_init(); -} - -/* physical memory regions */ -#define RAUMFELD_SDRAM_BASE 0xa0000000 /* SDRAM region */ - -#ifdef CONFIG_MACH_RAUMFELD_RC -MACHINE_START(RAUMFELD_RC, "Raumfeld Controller") - .atag_offset = 0x100, - .init_machine = raumfeld_controller_init, - .map_io = pxa3xx_map_io, - .nr_irqs = PXA_NR_IRQS, - .init_irq = pxa3xx_init_irq, - .handle_irq = pxa3xx_handle_irq, - .init_time = pxa_timer_init, - .restart = pxa_restart, -MACHINE_END -#endif - -#ifdef CONFIG_MACH_RAUMFELD_CONNECTOR -MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector") - .atag_offset = 0x100, - .init_machine = raumfeld_connector_init, - .map_io = pxa3xx_map_io, - .nr_irqs = PXA_NR_IRQS, - .init_irq = pxa3xx_init_irq, - .handle_irq = pxa3xx_handle_irq, - .init_time = pxa_timer_init, - .restart = pxa_restart, -MACHINE_END -#endif - -#ifdef CONFIG_MACH_RAUMFELD_SPEAKER -MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker") - .atag_offset = 0x100, - .init_machine = raumfeld_speaker_init, - .map_io = pxa3xx_map_io, - .nr_irqs = PXA_NR_IRQS, - .init_irq = pxa3xx_init_irq, - .handle_irq = pxa3xx_handle_irq, - .init_time = pxa_timer_init, - .restart = pxa_restart, -MACHINE_END -#endif diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c index 5fb6f79059a8..afd98971d903 100644 --- a/arch/arm/mach-socfpga/socfpga.c +++ b/arch/arm/mach-socfpga/socfpga.c @@ -32,6 +32,8 @@ void __iomem *rst_manager_base_addr; void __iomem *sdr_ctl_base_addr; unsigned long socfpga_cpu1start_addr; +extern void __init socfpga_reset_init(void); + static void __init socfpga_sysmgr_init(void) { struct device_node *np; @@ -64,6 +66,7 @@ static void __init socfpga_init_irq(void) if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM)) socfpga_init_ocram_ecc(); + socfpga_reset_init(); } static void __init socfpga_arria10_init_irq(void) @@ -74,6 +77,7 @@ static void __init socfpga_arria10_init_irq(void) socfpga_init_arria10_l2_ecc(); if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM)) socfpga_init_arria10_ocram_ecc(); + socfpga_reset_init(); } static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index d0e0bd4af05d..a231815f549b 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -147,6 +147,10 @@ config ARCH_MXC bool "ARMv8 based NXP i.MX SoC family" select ARM64_ERRATUM_843419 select ARM64_ERRATUM_845719 + select IMX_GPCV2 + select IMX_GPCV2_PM_DOMAINS + select PM + select PM_GENERIC_DOMAINS help This enables support for the ARMv8 based SoCs in the NXP i.MX family. diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi index 29ea7e81ec4c..329f8ceeebea 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi @@ -183,7 +183,7 @@ pinctrl-0 = <&cp0_pcie_pins>; num-lanes = <4>; num-viewport = <8>; - reset-gpio = <&cp0_gpio1 20 GPIO_ACTIVE_LOW>; + reset-gpios = <&cp0_gpio2 20 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi index 7d94c1fa592a..7f799cb5668e 100644 --- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi @@ -28,6 +28,23 @@ method = "smc"; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* + * This area matches the mapping done with a + * mainline U-Boot, and should be updated by the + * bootloader. + */ + + psci-area@4000000 { + reg = <0x0 0x4000000 0x0 0x200000>; + no-map; + }; + }; + ap806 { #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 3ef443cfbab6..c8432e24207e 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -506,11 +506,15 @@ CONFIG_SND_SOC_ROCKCHIP=m CONFIG_SND_SOC_ROCKCHIP_SPDIF=m CONFIG_SND_SOC_ROCKCHIP_RT5645=m CONFIG_SND_SOC_RK3399_GRU_SOUND=m +CONFIG_SND_MESON_AXG_SOUND_CARD=m CONFIG_SND_SOC_SAMSUNG=y CONFIG_SND_SOC_RCAR=m CONFIG_SND_SOC_AK4613=m CONFIG_SND_SIMPLE_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD=m +CONFIG_SND_SOC_ES7134=m +CONFIG_SND_SOC_ES7241=m +CONFIG_SND_SOC_TAS571X=m CONFIG_I2C_HID=m CONFIG_USB=y CONFIG_USB_OTG=y diff --git a/arch/arm64/include/asm/asm-prototypes.h b/arch/arm64/include/asm/asm-prototypes.h index 2173ad32d550..1c9a3a0c5fa5 100644 --- a/arch/arm64/include/asm/asm-prototypes.h +++ b/arch/arm64/include/asm/asm-prototypes.h @@ -2,7 +2,7 @@ #ifndef __ASM_PROTOTYPES_H #define __ASM_PROTOTYPES_H /* - * CONFIG_MODEVERIONS requires a C declaration to generate the appropriate CRC + * CONFIG_MODVERSIONS requires a C declaration to generate the appropriate CRC * for each symbol. Since commit: * * 4efca4ed05cbdfd1 ("kbuild: modversions for EXPORT_SYMBOL() for asm") diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h index 13dd42c3ad4e..926434f413fa 100644 --- a/arch/arm64/include/asm/cache.h +++ b/arch/arm64/include/asm/cache.h @@ -58,6 +58,10 @@ */ #define ARCH_DMA_MINALIGN (128) +#ifdef CONFIG_KASAN_SW_TAGS +#define ARCH_SLAB_MINALIGN (1ULL << KASAN_SHADOW_SCALE_SHIFT) +#endif + #ifndef __ASSEMBLY__ #include <linux/bitops.h> diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h index 3dd3d664c5c5..4658c937e173 100644 --- a/arch/arm64/include/asm/device.h +++ b/arch/arm64/include/asm/device.h @@ -20,9 +20,6 @@ struct dev_archdata { #ifdef CONFIG_IOMMU_API void *iommu; /* private IOMMU data */ #endif -#ifdef CONFIG_XEN - const struct dma_map_ops *dev_dma_ops; -#endif }; struct pdev_archdata { diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index 7689c7aa1d77..3e8063f4f9d3 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -16,6 +16,8 @@ #ifndef __ASM_MMU_H #define __ASM_MMU_H +#include <asm/cputype.h> + #define MMCF_AARCH32 0x1 /* mm context flag for AArch32 executables */ #define USER_ASID_BIT 48 #define USER_ASID_FLAG (UL(1) << USER_ASID_BIT) @@ -44,6 +46,48 @@ static inline bool arm64_kernel_unmapped_at_el0(void) cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0); } +static inline bool arm64_kernel_use_ng_mappings(void) +{ + bool tx1_bug; + + /* What's a kpti? Use global mappings if we don't know. */ + if (!IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) + return false; + + /* + * Note: this function is called before the CPU capabilities have + * been configured, so our early mappings will be global. If we + * later determine that kpti is required, then + * kpti_install_ng_mappings() will make them non-global. + */ + if (arm64_kernel_unmapped_at_el0()) + return true; + + if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE)) + return false; + + /* + * KASLR is enabled so we're going to be enabling kpti on non-broken + * CPUs regardless of their susceptibility to Meltdown. Rather + * than force everybody to go through the G -> nG dance later on, + * just put down non-global mappings from the beginning. + */ + if (!IS_ENABLED(CONFIG_CAVIUM_ERRATUM_27456)) { + tx1_bug = false; +#ifndef MODULE + } else if (!static_branch_likely(&arm64_const_caps_ready)) { + extern const struct midr_range cavium_erratum_27456_cpus[]; + + tx1_bug = is_midr_in_range_list(read_cpuid_id(), + cavium_erratum_27456_cpus); +#endif + } else { + tx1_bug = __cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_27456); + } + + return !tx1_bug && kaslr_offset() > 0; +} + typedef void (*bp_hardening_cb_t)(void); struct bp_hardening_data { diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index 78b942c1bea4..986e41c4c32b 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -37,8 +37,8 @@ #define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) #define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) -#define PTE_MAYBE_NG (arm64_kernel_unmapped_at_el0() ? PTE_NG : 0) -#define PMD_MAYBE_NG (arm64_kernel_unmapped_at_el0() ? PMD_SECT_NG : 0) +#define PTE_MAYBE_NG (arm64_kernel_use_ng_mappings() ? PTE_NG : 0) +#define PMD_MAYBE_NG (arm64_kernel_use_ng_mappings() ? PMD_SECT_NG : 0) #define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG) #define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG) diff --git a/arch/arm64/include/asm/xen/page-coherent.h b/arch/arm64/include/asm/xen/page-coherent.h index b3ef061d8b74..d88e56b90b93 100644 --- a/arch/arm64/include/asm/xen/page-coherent.h +++ b/arch/arm64/include/asm/xen/page-coherent.h @@ -1 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ARM64_XEN_PAGE_COHERENT_H +#define _ASM_ARM64_XEN_PAGE_COHERENT_H + +#include <linux/dma-mapping.h> +#include <asm/page.h> #include <xen/arm/page-coherent.h> + +static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs) +{ + return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs); +} + +static inline void xen_free_coherent_pages(struct device *hwdev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs) +{ + dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs); +} + +static inline void xen_dma_sync_single_for_cpu(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + unsigned long pfn = PFN_DOWN(handle); + + if (pfn_valid(pfn)) + dma_direct_sync_single_for_cpu(hwdev, handle, size, dir); + else + __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir); +} + +static inline void xen_dma_sync_single_for_device(struct device *hwdev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + unsigned long pfn = PFN_DOWN(handle); + if (pfn_valid(pfn)) + dma_direct_sync_single_for_device(hwdev, handle, size, dir); + else + __xen_dma_sync_single_for_device(hwdev, handle, size, dir); +} + +static inline void xen_dma_map_page(struct device *hwdev, struct page *page, + dma_addr_t dev_addr, unsigned long offset, size_t size, + enum dma_data_direction dir, unsigned long attrs) +{ + unsigned long page_pfn = page_to_xen_pfn(page); + unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr); + unsigned long compound_pages = + (1<<compound_order(page)) * XEN_PFN_PER_PAGE; + bool local = (page_pfn <= dev_pfn) && + (dev_pfn - page_pfn < compound_pages); + + if (local) + dma_direct_map_page(hwdev, page, offset, size, dir, attrs); + else + __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs); +} + +static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, + size_t size, enum dma_data_direction dir, unsigned long attrs) +{ + unsigned long pfn = PFN_DOWN(handle); + /* + * Dom0 is mapped 1:1, while the Linux page can be spanned accross + * multiple Xen page, it's not possible to have a mix of local and + * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a + * foreign mfn will always return false. If the page is local we can + * safely call the native dma_ops function, otherwise we call the xen + * specific function. + */ + if (pfn_valid(pfn)) + dma_direct_unmap_page(hwdev, handle, size, dir, attrs); + else + __xen_dma_unmap_page(hwdev, handle, size, dir, attrs); +} + +#endif /* _ASM_ARM64_XEN_PAGE_COHERENT_H */ diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 09ac548c9d44..9950bb0cbd52 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -553,7 +553,7 @@ static const struct midr_range arm64_repeat_tlbi_cpus[] = { #endif #ifdef CONFIG_CAVIUM_ERRATUM_27456 -static const struct midr_range cavium_erratum_27456_cpus[] = { +const struct midr_range cavium_erratum_27456_cpus[] = { /* Cavium ThunderX, T88 pass 1.x - 2.1 */ MIDR_RANGE(MIDR_THUNDERX, 0, 0, 1, 1), /* Cavium ThunderX, T81 pass 1.0 */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 4f272399de89..f6d84e2c92fe 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -983,7 +983,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, /* Useful for KASLR robustness */ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) - return true; + return kaslr_offset() > 0; /* Don't force KPTI for CPUs that are not vulnerable */ if (is_midr_in_range_list(read_cpuid_id(), kpti_safe_list)) @@ -1003,7 +1003,12 @@ kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused) static bool kpti_applied = false; int cpu = smp_processor_id(); - if (kpti_applied) + /* + * We don't need to rewrite the page-tables if either we've done + * it already or we have KASLR enabled and therefore have not + * created any global mappings at all. + */ + if (kpti_applied || kaslr_offset() > 0) return; remap_fn = (void *)__pa_symbol(idmap_kpti_install_ng_mappings); diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index c7213674cb24..15d79a8e5e5e 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -475,6 +475,7 @@ ENDPROC(__primary_switched) ENTRY(kimage_vaddr) .quad _text - TEXT_OFFSET +EXPORT_SYMBOL(kimage_vaddr) /* * If we're fortunate enough to boot at EL2, ensure that the world is diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c index f0e6ab8abe9c..ba6b41790fcd 100644 --- a/arch/arm64/kernel/kaslr.c +++ b/arch/arm64/kernel/kaslr.c @@ -14,6 +14,7 @@ #include <linux/sched.h> #include <linux/types.h> +#include <asm/cacheflush.h> #include <asm/fixmap.h> #include <asm/kernel-pgtable.h> #include <asm/memory.h> @@ -43,7 +44,7 @@ static __init u64 get_kaslr_seed(void *fdt) return ret; } -static __init const u8 *get_cmdline(void *fdt) +static __init const u8 *kaslr_get_cmdline(void *fdt) { static __initconst const u8 default_cmdline[] = CONFIG_CMDLINE; @@ -109,7 +110,7 @@ u64 __init kaslr_early_init(u64 dt_phys) * Check if 'nokaslr' appears on the command line, and * return 0 if that is the case. */ - cmdline = get_cmdline(fdt); + cmdline = kaslr_get_cmdline(fdt); str = strstr(cmdline, "nokaslr"); if (str == cmdline || (str > cmdline && *(str - 1) == ' ')) return 0; @@ -169,5 +170,8 @@ u64 __init kaslr_early_init(u64 dt_phys) module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21; module_alloc_base &= PAGE_MASK; + __flush_dcache_area(&module_alloc_base, sizeof(module_alloc_base)); + __flush_dcache_area(&memstart_offset_seed, sizeof(memstart_offset_seed)); + return offset; } diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 10e33860e47a..f2c211a6229b 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -87,7 +87,9 @@ static int setup_dtb(struct kimage *image, /* add kaslr-seed */ ret = fdt_delprop(dtb, off, FDT_PROP_KASLR_SEED); - if (ret && (ret != -FDT_ERR_NOTFOUND)) + if (ret == -FDT_ERR_NOTFOUND) + ret = 0; + else if (ret) goto out; if (rng_is_initialized()) { diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index fb0908456a1f..78c0a72f822c 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -466,9 +466,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, __iommu_setup_dma_ops(dev, dma_base, size, iommu); #ifdef CONFIG_XEN - if (xen_initial_domain()) { - dev->archdata.dev_dma_ops = dev->dma_ops; + if (xen_initial_domain()) dev->dma_ops = xen_dma_ops; - } #endif } diff --git a/arch/c6x/include/uapi/asm/Kbuild b/arch/c6x/include/uapi/asm/Kbuild index 0febf1a07c30..6c6f6301012e 100644 --- a/arch/c6x/include/uapi/asm/Kbuild +++ b/arch/c6x/include/uapi/asm/Kbuild @@ -1,4 +1,5 @@ include include/uapi/asm-generic/Kbuild.asm generic-y += kvm_para.h +generic-y += shmparam.h generic-y += ucontext.h diff --git a/arch/csky/include/asm/io.h b/arch/csky/include/asm/io.h index ecae6b358f95..c1dfa9c10e36 100644 --- a/arch/csky/include/asm/io.h +++ b/arch/csky/include/asm/io.h @@ -15,6 +15,31 @@ extern void iounmap(void *addr); extern int remap_area_pages(unsigned long address, phys_addr_t phys_addr, size_t size, unsigned long flags); +/* + * I/O memory access primitives. Reads are ordered relative to any + * following Normal memory access. Writes are ordered relative to any prior + * Normal memory access. + * + * For CACHEV1 (807, 810), store instruction could fast retire, so we need + * another mb() to prevent st fast retire. + * + * For CACHEV2 (860), store instruction with PAGE_ATTR_NO_BUFFERABLE won't + * fast retire. + */ +#define readb(c) ({ u8 __v = readb_relaxed(c); rmb(); __v; }) +#define readw(c) ({ u16 __v = readw_relaxed(c); rmb(); __v; }) +#define readl(c) ({ u32 __v = readl_relaxed(c); rmb(); __v; }) + +#ifdef CONFIG_CPU_HAS_CACHEV2 +#define writeb(v,c) ({ wmb(); writeb_relaxed((v),(c)); }) +#define writew(v,c) ({ wmb(); writew_relaxed((v),(c)); }) +#define writel(v,c) ({ wmb(); writel_relaxed((v),(c)); }) +#else +#define writeb(v,c) ({ wmb(); writeb_relaxed((v),(c)); mb(); }) +#define writew(v,c) ({ wmb(); writew_relaxed((v),(c)); mb(); }) +#define writel(v,c) ({ wmb(); writel_relaxed((v),(c)); mb(); }) +#endif + #define ioremap_nocache(phy, sz) ioremap(phy, sz) #define ioremap_wc ioremap_nocache #define ioremap_wt ioremap_nocache diff --git a/arch/csky/include/asm/pgalloc.h b/arch/csky/include/asm/pgalloc.h index bf4f4a0e140e..d213bb47b717 100644 --- a/arch/csky/include/asm/pgalloc.h +++ b/arch/csky/include/asm/pgalloc.h @@ -24,41 +24,34 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, extern void pgd_init(unsigned long *p); -static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, - unsigned long address) +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) { pte_t *pte; - unsigned long *kaddr, i; + unsigned long i; - pte = (pte_t *) __get_free_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL, - PTE_ORDER); - kaddr = (unsigned long *)pte; - if (address & 0x80000000) - for (i = 0; i < (PAGE_SIZE/4); i++) - *(kaddr + i) = 0x1; - else - clear_page(kaddr); + pte = (pte_t *) __get_free_page(GFP_KERNEL); + if (!pte) + return NULL; + + for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++) + (pte + i)->pte_low = _PAGE_GLOBAL; return pte; } -static inline struct page *pte_alloc_one(struct mm_struct *mm, - unsigned long address) +static inline struct page *pte_alloc_one(struct mm_struct *mm) { struct page *pte; - unsigned long *kaddr, i; - - pte = alloc_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL, PTE_ORDER); - if (pte) { - kaddr = kmap_atomic(pte); - if (address & 0x80000000) { - for (i = 0; i < (PAGE_SIZE/4); i++) - *(kaddr + i) = 0x1; - } else - clear_page(kaddr); - kunmap_atomic(kaddr); - pgtable_page_ctor(pte); + + pte = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0); + if (!pte) + return NULL; + + if (!pgtable_page_ctor(pte)) { + __free_page(pte); + return NULL; } + return pte; } diff --git a/arch/csky/kernel/module.c b/arch/csky/kernel/module.c index 65abab0c7a47..b5ad7d9de18c 100644 --- a/arch/csky/kernel/module.c +++ b/arch/csky/kernel/module.c @@ -12,7 +12,7 @@ #include <linux/spinlock.h> #include <asm/pgtable.h> -#if defined(__CSKYABIV2__) +#ifdef CONFIG_CPU_CK810 #define IS_BSR32(hi16, lo16) (((hi16) & 0xFC00) == 0xE000) #define IS_JSRI32(hi16, lo16) ((hi16) == 0xEAE0) @@ -25,6 +25,26 @@ *(uint16_t *)(addr) = 0xE8Fa; \ *((uint16_t *)(addr) + 1) = 0x0000; \ } while (0) + +static void jsri_2_lrw_jsr(uint32_t *location) +{ + uint16_t *location_tmp = (uint16_t *)location; + + if (IS_BSR32(*location_tmp, *(location_tmp + 1))) + return; + + if (IS_JSRI32(*location_tmp, *(location_tmp + 1))) { + /* jsri 0x... --> lrw r26, 0x... */ + CHANGE_JSRI_TO_LRW(location); + /* lsli r0, r0 --> jsr r26 */ + SET_JSR32_R26(location + 1); + } +} +#else +static void inline jsri_2_lrw_jsr(uint32_t *location) +{ + return; +} #endif int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, @@ -35,9 +55,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, Elf32_Sym *sym; uint32_t *location; short *temp; -#if defined(__CSKYABIV2__) - uint16_t *location_tmp; -#endif for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { /* This is where to make the change */ @@ -59,18 +76,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, case R_CSKY_PCRELJSR_IMM11BY2: break; case R_CSKY_PCRELJSR_IMM26BY2: -#if defined(__CSKYABIV2__) - location_tmp = (uint16_t *)location; - if (IS_BSR32(*location_tmp, *(location_tmp + 1))) - break; - - if (IS_JSRI32(*location_tmp, *(location_tmp + 1))) { - /* jsri 0x... --> lrw r26, 0x... */ - CHANGE_JSRI_TO_LRW(location); - /* lsli r0, r0 --> jsr r26 */ - SET_JSR32_R26(location + 1); - } -#endif + jsri_2_lrw_jsr(location); break; case R_CSKY_ADDR_HI16: temp = ((short *)location) + 1; diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile index 4003ddc616e1..f801f3708a89 100644 --- a/arch/h8300/Makefile +++ b/arch/h8300/Makefile @@ -37,8 +37,6 @@ libs-y += arch/$(ARCH)/lib/ boot := arch/h8300/boot -archmrproper: - archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/h8300/include/uapi/asm/Kbuild b/arch/h8300/include/uapi/asm/Kbuild index 0febf1a07c30..6c6f6301012e 100644 --- a/arch/h8300/include/uapi/asm/Kbuild +++ b/arch/h8300/include/uapi/asm/Kbuild @@ -1,4 +1,5 @@ include include/uapi/asm-generic/Kbuild.asm generic-y += kvm_para.h +generic-y += shmparam.h generic-y += ucontext.h diff --git a/arch/hexagon/include/uapi/asm/Kbuild b/arch/hexagon/include/uapi/asm/Kbuild index c1b06dcf6cf8..61d955c1747a 100644 --- a/arch/hexagon/include/uapi/asm/Kbuild +++ b/arch/hexagon/include/uapi/asm/Kbuild @@ -1,3 +1,4 @@ include include/uapi/asm-generic/Kbuild.asm +generic-y += shmparam.h generic-y += ucontext.h diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 320d86f192ee..171290f9f1de 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -16,8 +16,6 @@ KBUILD_DEFCONFIG := generic_defconfig NM := $(CROSS_COMPILE)nm -B READELF := $(CROSS_COMPILE)readelf -export AWK - CHECKFLAGS += -D__ia64=1 -D__ia64__=1 -D_LP64 -D__LP64__ OBJCOPYFLAGS := --strip-all diff --git a/arch/m68k/include/uapi/asm/Kbuild b/arch/m68k/include/uapi/asm/Kbuild index 960bf1e4be53..b8b3525271fa 100644 --- a/arch/m68k/include/uapi/asm/Kbuild +++ b/arch/m68k/include/uapi/asm/Kbuild @@ -2,3 +2,4 @@ include include/uapi/asm-generic/Kbuild.asm generated-y += unistd_32.h generic-y += kvm_para.h +generic-y += shmparam.h diff --git a/arch/microblaze/include/uapi/asm/Kbuild b/arch/microblaze/include/uapi/asm/Kbuild index 97823ec46e97..28823e3db825 100644 --- a/arch/microblaze/include/uapi/asm/Kbuild +++ b/arch/microblaze/include/uapi/asm/Kbuild @@ -2,4 +2,5 @@ include include/uapi/asm-generic/Kbuild.asm generated-y += unistd_32.h generic-y += kvm_para.h +generic-y += shmparam.h generic-y += ucontext.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 787290781b8c..0d14f51d0002 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -3155,6 +3155,7 @@ config MIPS32_O32 config MIPS32_N32 bool "Kernel support for n32 binaries" depends on 64BIT + select ARCH_WANT_COMPAT_IPC_PARSE_VERSION select COMPAT select MIPS32_COMPAT select SYSVIPC_COMPAT if SYSVIPC diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 6054d49e608e..fe3773539eff 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -173,6 +173,31 @@ void __init plat_mem_setup(void) pm_power_off = bcm47xx_machine_halt; } +#ifdef CONFIG_BCM47XX_BCMA +static struct device * __init bcm47xx_setup_device(void) +{ + struct device *dev; + int err; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + err = dev_set_name(dev, "bcm47xx_soc"); + if (err) { + pr_err("Failed to set SoC device name: %d\n", err); + kfree(dev); + return NULL; + } + + err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (err) + pr_err("Failed to set SoC DMA mask: %d\n", err); + + return dev; +} +#endif + /* * This finishes bus initialization doing things that were not possible without * kmalloc. Make sure to call it late enough (after mm_init). @@ -183,6 +208,10 @@ void __init bcm47xx_bus_setup(void) if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { int err; + bcm47xx_bus.bcma.dev = bcm47xx_setup_device(); + if (!bcm47xx_bus.bcma.dev) + panic("Failed to setup SoC device\n"); + err = bcma_host_soc_init(&bcm47xx_bus.bcma); if (err) panic("Failed to initialize BCMA bus (err %d)", err); @@ -235,6 +264,8 @@ static int __init bcm47xx_register_bus_complete(void) #endif #ifdef CONFIG_BCM47XX_BCMA case BCM47XX_BUS_TYPE_BCMA: + if (device_register(bcm47xx_bus.bcma.dev)) + pr_err("Failed to register SoC device\n"); bcma_bus_register(&bcm47xx_bus.bcma.bus); break; #endif diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 2c79ab52977a..8bf43c5a7bc7 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -98,7 +98,7 @@ static void octeon_kexec_smp_down(void *ignored) " sync \n" " synci ($0) \n"); - relocated_kexec_smp_wait(NULL); + kexec_reboot(); } #endif diff --git a/arch/mips/configs/ath79_defconfig b/arch/mips/configs/ath79_defconfig index 4e4ec779f182..6f981af67826 100644 --- a/arch/mips/configs/ath79_defconfig +++ b/arch/mips/configs/ath79_defconfig @@ -66,6 +66,7 @@ CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_PCI is not set CONFIG_SERIAL_8250_NR_UARTS=1 CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AR933X=y CONFIG_SERIAL_AR933X_CONSOLE=y # CONFIG_HW_RANDOM is not set diff --git a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h index c6b63a409641..6dd8ad2409dc 100644 --- a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h +++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h @@ -18,8 +18,6 @@ #define INT_NUM_EXTRA_START (INT_NUM_IM4_IRL0 + 32) #define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0) -#define MIPS_CPU_TIMER_IRQ 7 - #define MAX_IM 5 #endif /* _FALCON_IRQ__ */ diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h index 141076325307..0b424214a5e9 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h @@ -19,8 +19,6 @@ #define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0) -#define MIPS_CPU_TIMER_IRQ 7 - #define MAX_IM 5 #endif diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index 6256d35dbf4d..bedb5047aff3 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c @@ -74,14 +74,15 @@ static int __init vdma_init(void) get_order(VDMA_PGTBL_SIZE)); BUG_ON(!pgtbl); dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE); - pgtbl = (VDMA_PGTBL_ENTRY *)KSEG1ADDR(pgtbl); + pgtbl = (VDMA_PGTBL_ENTRY *)CKSEG1ADDR((unsigned long)pgtbl); /* * Clear the R4030 translation table */ vdma_pgtbl_init(); - r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE, CPHYSADDR(pgtbl)); + r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE, + CPHYSADDR((unsigned long)pgtbl)); r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE); r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0); diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index f0bc3312ed11..6549499eb202 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -224,9 +224,11 @@ static struct irq_chip ltq_eiu_type = { .irq_set_type = ltq_eiu_settype, }; -static void ltq_hw_irqdispatch(int module) +static void ltq_hw_irq_handler(struct irq_desc *desc) { + int module = irq_desc_get_irq(desc) - 2; u32 irq; + int hwirq; irq = ltq_icu_r32(module, LTQ_ICU_IM0_IOSR); if (irq == 0) @@ -237,7 +239,8 @@ static void ltq_hw_irqdispatch(int module) * other bits might be bogus */ irq = __fls(irq); - do_IRQ((int)irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module)); + hwirq = irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module); + generic_handle_irq(irq_linear_revmap(ltq_domain, hwirq)); /* if this is a EBU irq, we need to ack it or get a deadlock */ if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT) @@ -245,49 +248,6 @@ static void ltq_hw_irqdispatch(int module) LTQ_EBU_PCC_ISTAT); } -#define DEFINE_HWx_IRQDISPATCH(x) \ - static void ltq_hw ## x ## _irqdispatch(void) \ - { \ - ltq_hw_irqdispatch(x); \ - } -DEFINE_HWx_IRQDISPATCH(0) -DEFINE_HWx_IRQDISPATCH(1) -DEFINE_HWx_IRQDISPATCH(2) -DEFINE_HWx_IRQDISPATCH(3) -DEFINE_HWx_IRQDISPATCH(4) - -#if MIPS_CPU_TIMER_IRQ == 7 -static void ltq_hw5_irqdispatch(void) -{ - do_IRQ(MIPS_CPU_TIMER_IRQ); -} -#else -DEFINE_HWx_IRQDISPATCH(5) -#endif - -static void ltq_hw_irq_handler(struct irq_desc *desc) -{ - ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2); -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; - int irq; - - if (!pending) { - spurious_interrupt(); - return; - } - - pending >>= CAUSEB_IP; - while (pending) { - irq = fls(pending) - 1; - do_IRQ(MIPS_CPU_IRQ_BASE + irq); - pending &= ~BIT(irq); - } -} - static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { struct irq_chip *chip = <q_irq_type; @@ -343,38 +303,13 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) for (i = 0; i < MAX_IM; i++) irq_set_chained_handler(i + 2, ltq_hw_irq_handler); - if (cpu_has_vint) { - pr_info("Setting up vectored interrupts\n"); - set_vi_handler(2, ltq_hw0_irqdispatch); - set_vi_handler(3, ltq_hw1_irqdispatch); - set_vi_handler(4, ltq_hw2_irqdispatch); - set_vi_handler(5, ltq_hw3_irqdispatch); - set_vi_handler(6, ltq_hw4_irqdispatch); - set_vi_handler(7, ltq_hw5_irqdispatch); - } - ltq_domain = irq_domain_add_linear(node, (MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE, &irq_domain_ops, 0); -#ifndef CONFIG_MIPS_MT_SMP - set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | - IE_IRQ3 | IE_IRQ4 | IE_IRQ5); -#else - set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 | - IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); -#endif - /* tell oprofile which irq to use */ ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); - /* - * if the timer irq is not one of the mips irqs we need to - * create a mapping - */ - if (MIPS_CPU_TIMER_IRQ != 7) - irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ); - /* the external interrupts are optional and xway only */ eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway"); if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { @@ -411,7 +346,7 @@ EXPORT_SYMBOL_GPL(get_c0_perfcount_int); unsigned int get_c0_compare_int(void) { - return MIPS_CPU_TIMER_IRQ; + return CP0_LEGACY_COMPARE_IRQ; } static struct of_device_id __initdata of_irq_ids[] = { diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c index 982859f2b2a3..5e6a1a45cbd2 100644 --- a/arch/mips/lantiq/xway/dma.c +++ b/arch/mips/lantiq/xway/dma.c @@ -129,9 +129,9 @@ ltq_dma_alloc(struct ltq_dma_channel *ch) unsigned long flags; ch->desc = 0; - ch->desc_base = dma_zalloc_coherent(ch->dev, - LTQ_DESC_NUM * LTQ_DESC_SIZE, - &ch->phys, GFP_ATOMIC); + ch->desc_base = dma_alloc_coherent(ch->dev, + LTQ_DESC_NUM * LTQ_DESC_SIZE, + &ch->phys, GFP_ATOMIC); spin_lock_irqsave(<q_dma_lock, flags); ltq_dma_w32(ch->nr, LTQ_DMA_CS); diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c index 2a5bb849b10e..288b58b00dc8 100644 --- a/arch/mips/pci/msi-octeon.c +++ b/arch/mips/pci/msi-octeon.c @@ -369,7 +369,9 @@ int __init octeon_msi_initialize(void) int irq; struct irq_chip *msi; - if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE) { + if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_INVALID) { + return 0; + } else if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE) { msi_rcv_reg[0] = CVMX_PEXP_NPEI_MSI_RCV0; msi_rcv_reg[1] = CVMX_PEXP_NPEI_MSI_RCV1; msi_rcv_reg[2] = CVMX_PEXP_NPEI_MSI_RCV2; diff --git a/arch/nds32/Makefile b/arch/nds32/Makefile index 0a935c136ec2..ac3482882cf9 100644 --- a/arch/nds32/Makefile +++ b/arch/nds32/Makefile @@ -3,9 +3,6 @@ OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment -S KBUILD_DEFCONFIG := defconfig -comma = , - - ifdef CONFIG_FUNCTION_TRACER arch-y += -malways-save-lp -mno-relax endif @@ -54,8 +51,6 @@ endif boot := arch/nds32/boot core-y += $(boot)/dts/ -.PHONY: FORCE - Image: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ @@ -68,9 +63,6 @@ prepare: vdso_prepare vdso_prepare: prepare0 $(Q)$(MAKE) $(build)=arch/nds32/kernel/vdso include/generated/vdso-offsets.h -CLEAN_FILES += include/asm-nds32/constants.h* - -# We use MRPROPER_FILES and CLEAN_FILES now archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/openrisc/Makefile b/arch/openrisc/Makefile index 70e06d34006c..bf10141c7426 100644 --- a/arch/openrisc/Makefile +++ b/arch/openrisc/Makefile @@ -20,7 +20,6 @@ KBUILD_DEFCONFIG := or1ksim_defconfig OBJCOPYFLAGS := -O binary -R .note -R .comment -S -LDFLAGS_vmlinux := LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) KBUILD_CFLAGS += -pipe -ffixed-r10 -D__linux__ @@ -50,5 +49,3 @@ else BUILTIN_DTB := n endif core-$(BUILTIN_DTB) += arch/openrisc/boot/dts/ - -all: vmlinux diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h index bc8191a34db7..a44682c8adc3 100644 --- a/arch/openrisc/include/asm/uaccess.h +++ b/arch/openrisc/include/asm/uaccess.h @@ -58,8 +58,12 @@ /* Ensure that addr is below task's addr_limit */ #define __addr_ok(addr) ((unsigned long) addr < get_fs()) -#define access_ok(addr, size) \ - __range_ok((unsigned long)addr, (unsigned long)size) +#define access_ok(addr, size) \ +({ \ + unsigned long __ao_addr = (unsigned long)(addr); \ + unsigned long __ao_size = (unsigned long)(size); \ + __range_ok(__ao_addr, __ao_size); \ +}) /* * These are the main single-value transfer routines. They automatically diff --git a/arch/openrisc/include/uapi/asm/Kbuild b/arch/openrisc/include/uapi/asm/Kbuild index 0febf1a07c30..6c6f6301012e 100644 --- a/arch/openrisc/include/uapi/asm/Kbuild +++ b/arch/openrisc/include/uapi/asm/Kbuild @@ -1,4 +1,5 @@ include include/uapi/asm-generic/Kbuild.asm generic-y += kvm_para.h +generic-y += shmparam.h generic-y += ucontext.h diff --git a/arch/powerpc/include/uapi/asm/perf_regs.h b/arch/powerpc/include/uapi/asm/perf_regs.h index ff91192407d1..f599064dd8dc 100644 --- a/arch/powerpc/include/uapi/asm/perf_regs.h +++ b/arch/powerpc/include/uapi/asm/perf_regs.h @@ -47,6 +47,7 @@ enum perf_event_powerpc_regs { PERF_REG_POWERPC_DAR, PERF_REG_POWERPC_DSISR, PERF_REG_POWERPC_SIER, + PERF_REG_POWERPC_MMCRA, PERF_REG_POWERPC_MAX, }; #endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */ diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 57deb1e9ffea..20cc816b3508 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -852,11 +852,12 @@ start_here: /* set up the PTE pointers for the Abatron bdiGDB. */ - tovirt(r6,r6) lis r5, abatron_pteptrs@h ori r5, r5, abatron_pteptrs@l stw r5, 0xf0(0) /* Must match your Abatron config file */ tophys(r5,r5) + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l stw r6, 0(r5) /* Now turn on the MMU for real! */ diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index bd5e6834ca69..6794466f6420 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -755,11 +755,12 @@ SYSCALL_DEFINE0(rt_sigreturn) if (restore_tm_sigcontexts(current, &uc->uc_mcontext, &uc_transact->uc_mcontext)) goto badframe; - } + } else #endif - /* Fall through, for non-TM restore */ - if (!MSR_TM_ACTIVE(msr)) { + { /* + * Fall through, for non-TM restore + * * Unset MSR[TS] on the thread regs since MSR from user * context does not have MSR active, and recheckpoint was * not called since restore_tm_sigcontexts() was not called diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index 29746dc28df5..517662a56bdc 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -967,13 +967,6 @@ out: } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) -unsigned long __init arch_syscall_addr(int nr) -{ - return sys_call_table[nr*2]; -} -#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 */ - #ifdef PPC64_ELF_ABI_v1 char *arch_ftrace_match_adjust(char *str, const char *search) { diff --git a/arch/powerpc/perf/perf_regs.c b/arch/powerpc/perf/perf_regs.c index 5c36b3a8d47a..3349f3f8fe84 100644 --- a/arch/powerpc/perf/perf_regs.c +++ b/arch/powerpc/perf/perf_regs.c @@ -70,6 +70,7 @@ static unsigned int pt_regs_offset[PERF_REG_POWERPC_MAX] = { PT_REGS_OFFSET(PERF_REG_POWERPC_DAR, dar), PT_REGS_OFFSET(PERF_REG_POWERPC_DSISR, dsisr), PT_REGS_OFFSET(PERF_REG_POWERPC_SIER, dar), + PT_REGS_OFFSET(PERF_REG_POWERPC_MMCRA, dsisr), }; u64 perf_reg_value(struct pt_regs *regs, int idx) @@ -83,6 +84,11 @@ u64 perf_reg_value(struct pt_regs *regs, int idx) !is_sier_available())) return 0; + if (idx == PERF_REG_POWERPC_MMCRA && + (IS_ENABLED(CONFIG_FSL_EMB_PERF_EVENT) || + IS_ENABLED(CONFIG_PPC32))) + return 0; + return regs_get_register(regs, pt_regs_offset[idx]); } diff --git a/arch/powerpc/platforms/4xx/ocm.c b/arch/powerpc/platforms/4xx/ocm.c index a1aaa1569d7c..f0e488d97567 100644 --- a/arch/powerpc/platforms/4xx/ocm.c +++ b/arch/powerpc/platforms/4xx/ocm.c @@ -237,12 +237,12 @@ static int ocm_debugfs_show(struct seq_file *m, void *v) continue; seq_printf(m, "PPC4XX OCM : %d\n", ocm->index); - seq_printf(m, "PhysAddr : %pa[p]\n", &(ocm->phys)); + seq_printf(m, "PhysAddr : %pa\n", &(ocm->phys)); seq_printf(m, "MemTotal : %d Bytes\n", ocm->memtotal); seq_printf(m, "MemTotal(NC) : %d Bytes\n", ocm->nc.memtotal); seq_printf(m, "MemTotal(C) : %d Bytes\n\n", ocm->c.memtotal); - seq_printf(m, "NC.PhysAddr : %pa[p]\n", &(ocm->nc.phys)); + seq_printf(m, "NC.PhysAddr : %pa\n", &(ocm->nc.phys)); seq_printf(m, "NC.VirtAddr : 0x%p\n", ocm->nc.virt); seq_printf(m, "NC.MemTotal : %d Bytes\n", ocm->nc.memtotal); seq_printf(m, "NC.MemFree : %d Bytes\n", ocm->nc.memfree); @@ -252,7 +252,7 @@ static int ocm_debugfs_show(struct seq_file *m, void *v) blk->size, blk->owner); } - seq_printf(m, "\nC.PhysAddr : %pa[p]\n", &(ocm->c.phys)); + seq_printf(m, "\nC.PhysAddr : %pa\n", &(ocm->c.phys)); seq_printf(m, "C.VirtAddr : 0x%p\n", ocm->c.virt); seq_printf(m, "C.MemTotal : %d Bytes\n", ocm->c.memtotal); seq_printf(m, "C.MemFree : %d Bytes\n", ocm->c.memfree); diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index e66644e0fb40..9438fa0fc355 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -538,8 +538,7 @@ static void __init chrp_init_IRQ(void) /* see if there is a keyboard in the device tree with a parent of type "adb" */ for_each_node_by_name(kbd, "keyboard") - if (kbd->parent && kbd->parent->type - && strcmp(kbd->parent->type, "adb") == 0) + if (of_node_is_type(kbd->parent, "adb")) break; of_node_put(kbd); if (kbd) diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c index d18d16489a15..bdf9b716e848 100644 --- a/arch/powerpc/platforms/pasemi/dma_lib.c +++ b/arch/powerpc/platforms/pasemi/dma_lib.c @@ -255,7 +255,7 @@ int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, int ring_size) chan->ring_size = ring_size; - chan->ring_virt = dma_zalloc_coherent(&dma_pdev->dev, + chan->ring_virt = dma_alloc_coherent(&dma_pdev->dev, ring_size * sizeof(u64), &chan->ring_dma, GFP_KERNEL); diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index d7f742ed48ba..3f58c7dbd581 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c @@ -564,7 +564,7 @@ struct iommu_table_group *pnv_try_setup_npu_table_group(struct pnv_ioda_pe *pe) } } else { /* Create a group for 1 GPU and attached NPUs for POWER8 */ - pe->npucomp = kzalloc(sizeof(pe->npucomp), GFP_KERNEL); + pe->npucomp = kzalloc(sizeof(*pe->npucomp), GFP_KERNEL); table_group = &pe->npucomp->table_group; table_group->ops = &pnv_npu_peers_ops; iommu_register_group(table_group, hose->global_number, diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 1d6406a051f1..7db3119f8a5b 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2681,7 +2681,8 @@ static void pnv_pci_ioda_setup_iommu_api(void) list_for_each_entry(hose, &hose_list, list_node) { phb = hose->private_data; - if (phb->type == PNV_PHB_NPU_NVLINK) + if (phb->type == PNV_PHB_NPU_NVLINK || + phb->type == PNV_PHB_NPU_OCAPI) continue; list_for_each_entry(pe, &phb->ioda.pe_list, list) { diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index 7725825d887d..37a77e57893e 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -264,7 +264,9 @@ void __init pSeries_final_fixup(void) if (!of_device_is_compatible(nvdn->parent, "ibm,power9-npu")) continue; +#ifdef CONFIG_PPC_POWERNV WARN_ON_ONCE(pnv_npu2_init(hose)); +#endif break; } } diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index 8b0ebf3940d2..ebed46f80254 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c @@ -756,9 +756,10 @@ fsl_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) } /* Initialize outbound message descriptor ring */ - rmu->msg_tx_ring.virt = dma_zalloc_coherent(priv->dev, - rmu->msg_tx_ring.size * RIO_MSG_DESC_SIZE, - &rmu->msg_tx_ring.phys, GFP_KERNEL); + rmu->msg_tx_ring.virt = dma_alloc_coherent(priv->dev, + rmu->msg_tx_ring.size * RIO_MSG_DESC_SIZE, + &rmu->msg_tx_ring.phys, + GFP_KERNEL); if (!rmu->msg_tx_ring.virt) { rc = -ENOMEM; goto out_dma; diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index e0d7d61779a6..feeeaa60697c 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -28,11 +28,13 @@ config RISCV select GENERIC_STRNLEN_USER select GENERIC_SMP_IDLE_THREAD select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A + select HAVE_ARCH_AUDITSYSCALL select HAVE_MEMBLOCK_NODE_MAP select HAVE_DMA_CONTIGUOUS select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_GENERIC_DMA_COHERENT select HAVE_PERF_EVENTS + select HAVE_SYSCALL_TRACEPOINTS select IRQ_DOMAIN select RISCV_ISA_A if SMP select SPARSE_IRQ @@ -40,6 +42,7 @@ config RISCV select HAVE_ARCH_TRACEHOOK select HAVE_PCI select MODULES_USE_ELF_RELA if MODULES + select MODULE_SECTIONS if MODULES select THREAD_INFO_IN_TASK select PCI_DOMAINS_GENERIC if PCI select PCI_MSI if PCI @@ -152,7 +155,6 @@ choice bool "2GiB" config MAXPHYSMEM_128GB depends on 64BIT && CMODEL_MEDANY - select MODULE_SECTIONS if MODULES bool "128GiB" endchoice diff --git a/arch/riscv/include/asm/module.h b/arch/riscv/include/asm/module.h index cd2af4b013e3..46202dad365d 100644 --- a/arch/riscv/include/asm/module.h +++ b/arch/riscv/include/asm/module.h @@ -9,12 +9,12 @@ #define MODULE_ARCH_VERMAGIC "riscv" struct module; -u64 module_emit_got_entry(struct module *mod, u64 val); -u64 module_emit_plt_entry(struct module *mod, u64 val); +unsigned long module_emit_got_entry(struct module *mod, unsigned long val); +unsigned long module_emit_plt_entry(struct module *mod, unsigned long val); #ifdef CONFIG_MODULE_SECTIONS struct mod_section { - struct elf64_shdr *shdr; + Elf_Shdr *shdr; int num_entries; int max_entries; }; @@ -26,18 +26,18 @@ struct mod_arch_specific { }; struct got_entry { - u64 symbol_addr; /* the real variable address */ + unsigned long symbol_addr; /* the real variable address */ }; -static inline struct got_entry emit_got_entry(u64 val) +static inline struct got_entry emit_got_entry(unsigned long val) { return (struct got_entry) {val}; } -static inline struct got_entry *get_got_entry(u64 val, +static inline struct got_entry *get_got_entry(unsigned long val, const struct mod_section *sec) { - struct got_entry *got = (struct got_entry *)sec->shdr->sh_addr; + struct got_entry *got = (struct got_entry *)(sec->shdr->sh_addr); int i; for (i = 0; i < sec->num_entries; i++) { if (got[i].symbol_addr == val) @@ -62,7 +62,9 @@ struct plt_entry { #define REG_T0 0x5 #define REG_T1 0x6 -static inline struct plt_entry emit_plt_entry(u64 val, u64 plt, u64 got_plt) +static inline struct plt_entry emit_plt_entry(unsigned long val, + unsigned long plt, + unsigned long got_plt) { /* * U-Type encoding: @@ -76,7 +78,7 @@ static inline struct plt_entry emit_plt_entry(u64 val, u64 plt, u64 got_plt) * +------------+------------+--------+----------+----------+ * */ - u64 offset = got_plt - plt; + unsigned long offset = got_plt - plt; u32 hi20 = (offset + 0x800) & 0xfffff000; u32 lo12 = (offset - hi20); return (struct plt_entry) { @@ -86,7 +88,7 @@ static inline struct plt_entry emit_plt_entry(u64 val, u64 plt, u64 got_plt) }; } -static inline int get_got_plt_idx(u64 val, const struct mod_section *sec) +static inline int get_got_plt_idx(unsigned long val, const struct mod_section *sec) { struct got_entry *got_plt = (struct got_entry *)sec->shdr->sh_addr; int i; @@ -97,9 +99,9 @@ static inline int get_got_plt_idx(u64 val, const struct mod_section *sec) return -1; } -static inline struct plt_entry *get_plt_entry(u64 val, - const struct mod_section *sec_plt, - const struct mod_section *sec_got_plt) +static inline struct plt_entry *get_plt_entry(unsigned long val, + const struct mod_section *sec_plt, + const struct mod_section *sec_got_plt) { struct plt_entry *plt = (struct plt_entry *)sec_plt->shdr->sh_addr; int got_plt_idx = get_got_plt_idx(val, sec_got_plt); diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h index bbe1862e8f80..d35ec2f41381 100644 --- a/arch/riscv/include/asm/ptrace.h +++ b/arch/riscv/include/asm/ptrace.h @@ -113,6 +113,11 @@ static inline void frame_pointer_set(struct pt_regs *regs, SET_FP(regs, val); } +static inline unsigned long regs_return_value(struct pt_regs *regs) +{ + return regs->a0; +} + #endif /* __ASSEMBLY__ */ #endif /* _ASM_RISCV_PTRACE_H */ diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h index 8d25f8904c00..bba3da6ef157 100644 --- a/arch/riscv/include/asm/syscall.h +++ b/arch/riscv/include/asm/syscall.h @@ -18,6 +18,7 @@ #ifndef _ASM_RISCV_SYSCALL_H #define _ASM_RISCV_SYSCALL_H +#include <uapi/linux/audit.h> #include <linux/sched.h> #include <linux/err.h> @@ -99,4 +100,13 @@ static inline void syscall_set_arguments(struct task_struct *task, memcpy(®s->a1 + i * sizeof(regs->a1), args, n * sizeof(regs->a0)); } +static inline int syscall_get_arch(void) +{ +#ifdef CONFIG_64BIT + return AUDIT_ARCH_RISCV64; +#else + return AUDIT_ARCH_RISCV32; +#endif +} + #endif /* _ASM_RISCV_SYSCALL_H */ diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h index f8fa1cd2dad9..1c9cc8389928 100644 --- a/arch/riscv/include/asm/thread_info.h +++ b/arch/riscv/include/asm/thread_info.h @@ -80,13 +80,19 @@ struct thread_info { #define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */ #define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ +#define TIF_SYSCALL_AUDIT 7 /* syscall auditing */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) +#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_WORK_MASK \ (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED) +#define _TIF_SYSCALL_WORK \ + (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT) + #endif /* _ASM_RISCV_THREAD_INFO_H */ diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h index fef96f117b4d..073ee80fdf74 100644 --- a/arch/riscv/include/asm/unistd.h +++ b/arch/riscv/include/asm/unistd.h @@ -19,3 +19,5 @@ #define __ARCH_WANT_SYS_CLONE #include <uapi/asm/unistd.h> + +#define NR_syscalls (__NR_syscalls) diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 13d4826ab2a1..355166f57205 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -201,7 +201,7 @@ handle_syscall: REG_S s2, PT_SEPC(sp) /* Trace syscalls, but only if requested by the user. */ REG_L t0, TASK_TI_FLAGS(tp) - andi t0, t0, _TIF_SYSCALL_TRACE + andi t0, t0, _TIF_SYSCALL_WORK bnez t0, handle_syscall_trace_enter check_syscall_nr: /* Check to make sure we don't jump to a bogus syscall number. */ @@ -221,7 +221,7 @@ ret_from_syscall: REG_S a0, PT_A0(sp) /* Trace syscalls, but only if requested by the user. */ REG_L t0, TASK_TI_FLAGS(tp) - andi t0, t0, _TIF_SYSCALL_TRACE + andi t0, t0, _TIF_SYSCALL_WORK bnez t0, handle_syscall_trace_exit ret_from_exception: diff --git a/arch/riscv/kernel/module-sections.c b/arch/riscv/kernel/module-sections.c index bbbd26e19bfd..c9ae48333114 100644 --- a/arch/riscv/kernel/module-sections.c +++ b/arch/riscv/kernel/module-sections.c @@ -9,14 +9,14 @@ #include <linux/kernel.h> #include <linux/module.h> -u64 module_emit_got_entry(struct module *mod, u64 val) +unsigned long module_emit_got_entry(struct module *mod, unsigned long val) { struct mod_section *got_sec = &mod->arch.got; int i = got_sec->num_entries; struct got_entry *got = get_got_entry(val, got_sec); if (got) - return (u64)got; + return (unsigned long)got; /* There is no duplicate entry, create a new one */ got = (struct got_entry *)got_sec->shdr->sh_addr; @@ -25,10 +25,10 @@ u64 module_emit_got_entry(struct module *mod, u64 val) got_sec->num_entries++; BUG_ON(got_sec->num_entries > got_sec->max_entries); - return (u64)&got[i]; + return (unsigned long)&got[i]; } -u64 module_emit_plt_entry(struct module *mod, u64 val) +unsigned long module_emit_plt_entry(struct module *mod, unsigned long val) { struct mod_section *got_plt_sec = &mod->arch.got_plt; struct got_entry *got_plt; @@ -37,27 +37,29 @@ u64 module_emit_plt_entry(struct module *mod, u64 val) int i = plt_sec->num_entries; if (plt) - return (u64)plt; + return (unsigned long)plt; /* There is no duplicate entry, create a new one */ got_plt = (struct got_entry *)got_plt_sec->shdr->sh_addr; got_plt[i] = emit_got_entry(val); plt = (struct plt_entry *)plt_sec->shdr->sh_addr; - plt[i] = emit_plt_entry(val, (u64)&plt[i], (u64)&got_plt[i]); + plt[i] = emit_plt_entry(val, + (unsigned long)&plt[i], + (unsigned long)&got_plt[i]); plt_sec->num_entries++; got_plt_sec->num_entries++; BUG_ON(plt_sec->num_entries > plt_sec->max_entries); - return (u64)&plt[i]; + return (unsigned long)&plt[i]; } -static int is_rela_equal(const Elf64_Rela *x, const Elf64_Rela *y) +static int is_rela_equal(const Elf_Rela *x, const Elf_Rela *y) { return x->r_info == y->r_info && x->r_addend == y->r_addend; } -static bool duplicate_rela(const Elf64_Rela *rela, int idx) +static bool duplicate_rela(const Elf_Rela *rela, int idx) { int i; for (i = 0; i < idx; i++) { @@ -67,13 +69,13 @@ static bool duplicate_rela(const Elf64_Rela *rela, int idx) return false; } -static void count_max_entries(Elf64_Rela *relas, int num, +static void count_max_entries(Elf_Rela *relas, int num, unsigned int *plts, unsigned int *gots) { unsigned int type, i; for (i = 0; i < num; i++) { - type = ELF64_R_TYPE(relas[i].r_info); + type = ELF_RISCV_R_TYPE(relas[i].r_info); if (type == R_RISCV_CALL_PLT) { if (!duplicate_rela(relas, i)) (*plts)++; @@ -118,9 +120,9 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, /* Calculate the maxinum number of entries */ for (i = 0; i < ehdr->e_shnum; i++) { - Elf64_Rela *relas = (void *)ehdr + sechdrs[i].sh_offset; - int num_rela = sechdrs[i].sh_size / sizeof(Elf64_Rela); - Elf64_Shdr *dst_sec = sechdrs + sechdrs[i].sh_info; + Elf_Rela *relas = (void *)ehdr + sechdrs[i].sh_offset; + int num_rela = sechdrs[i].sh_size / sizeof(Elf_Rela); + Elf_Shdr *dst_sec = sechdrs + sechdrs[i].sh_info; if (sechdrs[i].sh_type != SHT_RELA) continue; diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c index 60f1e02eed36..2ae5e0284f56 100644 --- a/arch/riscv/kernel/ptrace.c +++ b/arch/riscv/kernel/ptrace.c @@ -18,12 +18,15 @@ #include <asm/ptrace.h> #include <asm/syscall.h> #include <asm/thread_info.h> +#include <linux/audit.h> #include <linux/ptrace.h> #include <linux/elf.h> #include <linux/regset.h> #include <linux/sched.h> #include <linux/sched/task_stack.h> #include <linux/tracehook.h> + +#define CREATE_TRACE_POINTS #include <trace/events/syscalls.h> enum riscv_regset { @@ -163,15 +166,19 @@ void do_syscall_trace_enter(struct pt_regs *regs) if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_enter(regs, syscall_get_nr(current, regs)); #endif + + audit_syscall_entry(regs->a7, regs->a0, regs->a1, regs->a2, regs->a3); } void do_syscall_trace_exit(struct pt_regs *regs) { + audit_syscall_exit(regs); + if (test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, 0); #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) - trace_sys_exit(regs, regs->regs[0]); + trace_sys_exit(regs, regs_return_value(regs)); #endif } diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index fc8006a042eb..6e079e94b638 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -149,7 +149,14 @@ asmlinkage void __init setup_vm(void) void __init parse_dtb(unsigned int hartid, void *dtb) { - early_init_dt_scan(__va(dtb)); + if (!early_init_dt_scan(__va(dtb))) + return; + + pr_err("No DTB passed to the kernel\n"); +#ifdef CONFIG_CMDLINE_FORCE + strlcpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); + pr_info("Forcing kernel command line to: %s\n", boot_command_line); +#endif } static void __init setup_bootmem(void) diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c index 57b1383e5ef7..246635eac7bb 100644 --- a/arch/riscv/kernel/smp.c +++ b/arch/riscv/kernel/smp.c @@ -23,6 +23,7 @@ #include <linux/smp.h> #include <linux/sched.h> #include <linux/seq_file.h> +#include <linux/delay.h> #include <asm/sbi.h> #include <asm/tlbflush.h> @@ -31,6 +32,7 @@ enum ipi_message_type { IPI_RESCHEDULE, IPI_CALL_FUNC, + IPI_CPU_STOP, IPI_MAX }; @@ -66,6 +68,13 @@ int setup_profiling_timer(unsigned int multiplier) return -EINVAL; } +static void ipi_stop(void) +{ + set_cpu_online(smp_processor_id(), false); + while (1) + wait_for_interrupt(); +} + void riscv_software_interrupt(void) { unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits; @@ -94,6 +103,11 @@ void riscv_software_interrupt(void) generic_smp_call_function_interrupt(); } + if (ops & (1 << IPI_CPU_STOP)) { + stats[IPI_CPU_STOP]++; + ipi_stop(); + } + BUG_ON((ops >> IPI_MAX) != 0); /* Order data access and bit testing. */ @@ -121,6 +135,7 @@ send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation) static const char * const ipi_names[] = { [IPI_RESCHEDULE] = "Rescheduling interrupts", [IPI_CALL_FUNC] = "Function call interrupts", + [IPI_CPU_STOP] = "CPU stop interrupts", }; void show_ipi_stats(struct seq_file *p, int prec) @@ -146,15 +161,29 @@ void arch_send_call_function_single_ipi(int cpu) send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC); } -static void ipi_stop(void *unused) -{ - while (1) - wait_for_interrupt(); -} - void smp_send_stop(void) { - on_each_cpu(ipi_stop, NULL, 1); + unsigned long timeout; + + if (num_online_cpus() > 1) { + cpumask_t mask; + + cpumask_copy(&mask, cpu_online_mask); + cpumask_clear_cpu(smp_processor_id(), &mask); + + if (system_state <= SYSTEM_RUNNING) + pr_crit("SMP: stopping secondary CPUs\n"); + send_ipi_message(&mask, IPI_CPU_STOP); + } + + /* Wait up to one second for other CPUs to stop */ + timeout = USEC_PER_SEC; + while (num_online_cpus() > 1 && timeout--) + udelay(1); + + if (num_online_cpus() > 1) + pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", + cpumask_pr_args(cpu_online_mask)); } void smp_send_reschedule(int cpu) diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index 65df1dfdc303..1e1395d63dab 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -18,6 +18,8 @@ #include <asm/cache.h> #include <asm/thread_info.h> +#define MAX_BYTES_PER_LONG 0x10 + OUTPUT_ARCH(riscv) ENTRY(_start) @@ -74,8 +76,6 @@ SECTIONS *(.sbss*) } - BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0) - EXCEPTION_TABLE(0x10) NOTES @@ -83,6 +83,10 @@ SECTIONS *(.rel.dyn*) } + BSS_SECTION(MAX_BYTES_PER_LONG, + MAX_BYTES_PER_LONG, + MAX_BYTES_PER_LONG) + _end = .; STABS_DEBUG diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index ccbb53e22024..8d04e6f3f796 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -25,7 +25,7 @@ static inline int init_new_context(struct task_struct *tsk, atomic_set(&mm->context.flush_count, 0); mm->context.gmap_asce = 0; mm->context.flush_mm = 0; - mm->context.compat_mm = 0; + mm->context.compat_mm = test_thread_flag(TIF_31BIT); #ifdef CONFIG_PGSTE mm->context.alloc_pgste = page_table_allocate_pgste || test_thread_flag(TIF_PGSTE) || @@ -90,8 +90,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, { int cpu = smp_processor_id(); - if (prev == next) - return; S390_lowcore.user_asce = next->context.asce; cpumask_set_cpu(cpu, &next->context.cpu_attach_mask); /* Clear previous user-ASCE from CR1 and CR7 */ @@ -103,7 +101,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, __ctl_load(S390_lowcore.vdso_asce, 7, 7); clear_cpu_flag(CIF_ASCE_SECONDARY); } - cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask); + if (prev != next) + cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask); } #define finish_arch_post_lock_switch finish_arch_post_lock_switch diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index af5c2b3f7065..a8c7789b246b 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -63,10 +63,10 @@ static noinline __init void detect_machine_type(void) if (stsi(vmms, 3, 2, 2) || !vmms->count) return; - /* Running under KVM? If not we assume z/VM */ + /* Detect known hypervisors */ if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3)) S390_lowcore.machine_flags |= MACHINE_FLAG_KVM; - else + else if (!memcmp(vmms->vm[0].cpi, "\xa9\x61\xe5\xd4", 4)) S390_lowcore.machine_flags |= MACHINE_FLAG_VM; } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 72dd23ef771b..7ed90a759135 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -1006,6 +1006,8 @@ void __init setup_arch(char **cmdline_p) pr_info("Linux is running under KVM in 64-bit mode\n"); else if (MACHINE_IS_LPAR) pr_info("Linux is running natively in 64-bit mode\n"); + else + pr_info("Linux is running as a guest in 64-bit mode\n"); /* Have one command line that is parsed and saved in /proc/cmdline */ /* boot_command_line has been already set up in early.c */ diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index f82b3d3c36e2..b198ece2aad6 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -381,8 +381,13 @@ void smp_call_online_cpu(void (*func)(void *), void *data) */ void smp_call_ipl_cpu(void (*func)(void *), void *data) { + struct lowcore *lc = pcpu_devices->lowcore; + + if (pcpu_devices[0].address == stap()) + lc = &S390_lowcore; + pcpu_delegate(&pcpu_devices[0], func, data, - pcpu_devices->lowcore->nodat_stack); + lc->nodat_stack); } int smp_find_processor_id(u16 address) @@ -1166,7 +1171,11 @@ static ssize_t __ref rescan_store(struct device *dev, { int rc; + rc = lock_device_hotplug_sysfs(); + if (rc) + return rc; rc = smp_rescan_cpus(); + unlock_device_hotplug(); return rc ? rc : count; } static DEVICE_ATTR_WO(rescan); diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index ebe748a9f472..4ff354887db4 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -224,10 +224,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) vdso_pages = vdso64_pages; #ifdef CONFIG_COMPAT - if (is_compat_task()) { + mm->context.compat_mm = is_compat_task(); + if (mm->context.compat_mm) vdso_pages = vdso32_pages; - mm->context.compat_mm = 1; - } #endif /* * vDSO has a problem and was disabled, just don't "enable" it for diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild index 0febf1a07c30..6c6f6301012e 100644 --- a/arch/unicore32/include/uapi/asm/Kbuild +++ b/arch/unicore32/include/uapi/asm/Kbuild @@ -1,4 +1,5 @@ include include/uapi/asm-generic/Kbuild.asm generic-y += kvm_para.h +generic-y += shmparam.h generic-y += ucontext.h diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6185d4f33296..26387c7bf305 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -198,7 +198,7 @@ config X86 select IRQ_FORCED_THREADING select NEED_SG_DMA_LENGTH select PCI_DOMAINS if PCI - select PCI_LOCKLESS_CONFIG + select PCI_LOCKLESS_CONFIG if PCI select PERF_EVENTS select RTC_LIB select RTC_MC146818_LIB @@ -446,7 +446,7 @@ config RETPOLINE branches. Requires a compiler with -mindirect-branch=thunk-extern support for full protection. The kernel may run slower. -config RESCTRL +config X86_RESCTRL bool "Resource Control support" depends on X86 && (CPU_SUP_INTEL || CPU_SUP_AMD) select KERNFS @@ -617,7 +617,7 @@ config X86_INTEL_QUARK config X86_INTEL_LPSS bool "Intel Low Power Subsystem Support" - depends on X86 && ACPI + depends on X86 && ACPI && PCI select COMMON_CLK select PINCTRL select IOSF_MBI diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 8eaf8952c408..39913770a44d 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -361,7 +361,8 @@ ENTRY(entry_INT80_compat) /* Need to switch before accessing the thread stack. */ SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi - movq %rsp, %rdi + /* In the Xen PV case we already run on the thread stack. */ + ALTERNATIVE "movq %rsp, %rdi", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp pushq 6*8(%rdi) /* regs->ss */ @@ -370,8 +371,9 @@ ENTRY(entry_INT80_compat) pushq 3*8(%rdi) /* regs->cs */ pushq 2*8(%rdi) /* regs->ip */ pushq 1*8(%rdi) /* regs->orig_ax */ - pushq (%rdi) /* pt_regs->di */ +.Lint80_keep_stack: + pushq %rsi /* pt_regs->si */ xorl %esi, %esi /* nospec si */ pushq %rdx /* pt_regs->dx */ diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 0ca50611e8ce..19d18fae6ec6 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -178,6 +178,10 @@ static inline void switch_ldt(struct mm_struct *prev, struct mm_struct *next) void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk); +/* + * Init a new mm. Used on mm copies, like at fork() + * and on mm's that are brand-new, like at execve(). + */ static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { @@ -228,8 +232,22 @@ do { \ } while (0) #endif +static inline void arch_dup_pkeys(struct mm_struct *oldmm, + struct mm_struct *mm) +{ +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS + if (!cpu_feature_enabled(X86_FEATURE_OSPKE)) + return; + + /* Duplicate the oldmm pkey state in mm: */ + mm->context.pkey_allocation_map = oldmm->context.pkey_allocation_map; + mm->context.execute_only_pkey = oldmm->context.execute_only_pkey; +#endif +} + static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) { + arch_dup_pkeys(oldmm, mm); paravirt_arch_dup_mmap(oldmm, mm); return ldt_dup_context(oldmm, mm); } diff --git a/arch/x86/include/asm/resctrl_sched.h b/arch/x86/include/asm/resctrl_sched.h index 54990fe2a3ae..40ebddde6ac2 100644 --- a/arch/x86/include/asm/resctrl_sched.h +++ b/arch/x86/include/asm/resctrl_sched.h @@ -2,7 +2,7 @@ #ifndef _ASM_X86_RESCTRL_SCHED_H #define _ASM_X86_RESCTRL_SCHED_H -#ifdef CONFIG_RESCTRL +#ifdef CONFIG_X86_RESCTRL #include <linux/sched.h> #include <linux/jump_label.h> @@ -88,6 +88,6 @@ static inline void resctrl_sched_in(void) static inline void resctrl_sched_in(void) {} -#endif /* CONFIG_RESCTRL */ +#endif /* CONFIG_X86_RESCTRL */ #endif /* _ASM_X86_RESCTRL_SCHED_H */ diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index a77445d1b034..780f2b42c8ef 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -711,7 +711,7 @@ static __must_check inline bool user_access_begin(const void __user *ptr, size_t { if (unlikely(!access_ok(ptr,len))) return 0; - __uaccess_begin(); + __uaccess_begin_nospec(); return 1; } #define user_access_begin(a,b) user_access_begin(a,b) diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index ac78f90aea56..b6fa0869f7aa 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -39,7 +39,7 @@ obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o obj-$(CONFIG_X86_MCE) += mce/ obj-$(CONFIG_MTRR) += mtrr/ obj-$(CONFIG_MICROCODE) += microcode/ -obj-$(CONFIG_RESCTRL) += resctrl/ +obj-$(CONFIG_X86_RESCTRL) += resctrl/ obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 8654b8b0c848..1de0f4170178 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -215,7 +215,7 @@ static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = static enum spectre_v2_user_mitigation spectre_v2_user __ro_after_init = SPECTRE_V2_USER_NONE; -#ifdef RETPOLINE +#ifdef CONFIG_RETPOLINE static bool spectre_v2_bad_module; bool retpoline_module_ok(bool has_retpoline) diff --git a/arch/x86/kernel/cpu/resctrl/Makefile b/arch/x86/kernel/cpu/resctrl/Makefile index 6895049ceef7..1cabe6fd8e11 100644 --- a/arch/x86/kernel/cpu/resctrl/Makefile +++ b/arch/x86/kernel/cpu/resctrl/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_RESCTRL) += core.o rdtgroup.o monitor.o -obj-$(CONFIG_RESCTRL) += ctrlmondata.o pseudo_lock.o +obj-$(CONFIG_X86_RESCTRL) += core.o rdtgroup.o monitor.o +obj-$(CONFIG_X86_RESCTRL) += ctrlmondata.o pseudo_lock.o CFLAGS_pseudo_lock.o = -I$(src) diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index c8b07d8ea5a2..17ffc869cab8 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -470,6 +470,7 @@ int crash_load_segments(struct kimage *image) kbuf.memsz = kbuf.bufsz; kbuf.buf_align = ELF_CORE_HEADER_ALIGN; + kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; ret = kexec_add_buffer(&kbuf); if (ret) { vfree((void *)image->arch.elf_headers); diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index b0acb22e5a46..dfd3aca82c61 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -21,10 +21,6 @@ #define HPET_MASK CLOCKSOURCE_MASK(32) -/* FSEC = 10^-15 - NSEC = 10^-9 */ -#define FSEC_PER_NSEC 1000000L - #define HPET_DEV_USED_BIT 2 #define HPET_DEV_USED (1 << HPET_DEV_USED_BIT) #define HPET_DEV_VALID 0x8 diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c index 278cd07228dd..0d5efa34f359 100644 --- a/arch/x86/kernel/kexec-bzimage64.c +++ b/arch/x86/kernel/kexec-bzimage64.c @@ -434,6 +434,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel, kbuf.memsz = PAGE_ALIGN(header->init_size); kbuf.buf_align = header->kernel_alignment; kbuf.buf_min = MIN_KERNEL_LOAD_ADDR; + kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; ret = kexec_add_buffer(&kbuf); if (ret) goto out_free_params; @@ -448,6 +449,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel, kbuf.bufsz = kbuf.memsz = initrd_len; kbuf.buf_align = PAGE_SIZE; kbuf.buf_min = MIN_INITRD_LOAD_ADDR; + kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; ret = kexec_add_buffer(&kbuf); if (ret) goto out_free_params; diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index ba4bfb7f6a36..5c93a65ee1e5 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -457,6 +457,7 @@ static void __send_ipi_mask(const struct cpumask *mask, int vector) #else u64 ipi_bitmap = 0; #endif + long ret; if (cpumask_empty(mask)) return; @@ -482,8 +483,9 @@ static void __send_ipi_mask(const struct cpumask *mask, int vector) } else if (apic_id < min + KVM_IPI_CLUSTER_SIZE) { max = apic_id < max ? max : apic_id; } else { - kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap, + ret = kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap, (unsigned long)(ipi_bitmap >> BITS_PER_LONG), min, icr); + WARN_ONCE(ret < 0, "KVM: failed to send PV IPI: %ld", ret); min = max = apic_id; ipi_bitmap = 0; } @@ -491,8 +493,9 @@ static void __send_ipi_mask(const struct cpumask *mask, int vector) } if (ipi_bitmap) { - kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap, + ret = kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap, (unsigned long)(ipi_bitmap >> BITS_PER_LONG), min, icr); + WARN_ONCE(ret < 0, "KVM: failed to send PV IPI: %ld", ret); } local_irq_restore(flags); diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index e9f777bfed40..3fae23834069 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -297,15 +297,16 @@ static int __init tsc_setup(char *str) __setup("tsc=", tsc_setup); -#define MAX_RETRIES 5 -#define SMI_TRESHOLD 50000 +#define MAX_RETRIES 5 +#define TSC_DEFAULT_THRESHOLD 0x20000 /* - * Read TSC and the reference counters. Take care of SMI disturbance + * Read TSC and the reference counters. Take care of any disturbances */ static u64 tsc_read_refs(u64 *p, int hpet) { u64 t1, t2; + u64 thresh = tsc_khz ? tsc_khz >> 5 : TSC_DEFAULT_THRESHOLD; int i; for (i = 0; i < MAX_RETRIES; i++) { @@ -315,7 +316,7 @@ static u64 tsc_read_refs(u64 *p, int hpet) else *p = acpi_pm_read_early(); t2 = get_cycles(); - if ((t2 - t1) < SMI_TRESHOLD) + if ((t2 - t1) < thresh) return t2; } return ULLONG_MAX; @@ -703,15 +704,15 @@ static unsigned long pit_hpet_ptimer_calibrate_cpu(void) * zero. In each wait loop iteration we read the TSC and check * the delta to the previous read. We keep track of the min * and max values of that delta. The delta is mostly defined - * by the IO time of the PIT access, so we can detect when a - * SMI/SMM disturbance happened between the two reads. If the + * by the IO time of the PIT access, so we can detect when + * any disturbance happened between the two reads. If the * maximum time is significantly larger than the minimum time, * then we discard the result and have another try. * * 2) Reference counter. If available we use the HPET or the * PMTIMER as a reference to check the sanity of that value. * We use separate TSC readouts and check inside of the - * reference read for a SMI/SMM disturbance. We dicard + * reference read for any possible disturbance. We dicard * disturbed values here as well. We do that around the PIT * calibration delay loop as we have to wait for a certain * amount of time anyway. @@ -744,7 +745,7 @@ static unsigned long pit_hpet_ptimer_calibrate_cpu(void) if (ref1 == ref2) continue; - /* Check, whether the sampling was disturbed by an SMI */ + /* Check, whether the sampling was disturbed */ if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX) continue; @@ -1268,7 +1269,7 @@ static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work); */ static void tsc_refine_calibration_work(struct work_struct *work) { - static u64 tsc_start = -1, ref_start; + static u64 tsc_start = ULLONG_MAX, ref_start; static int hpet; u64 tsc_stop, ref_stop, delta; unsigned long freq; @@ -1283,14 +1284,15 @@ static void tsc_refine_calibration_work(struct work_struct *work) * delayed the first time we expire. So set the workqueue * again once we know timers are working. */ - if (tsc_start == -1) { + if (tsc_start == ULLONG_MAX) { +restart: /* * Only set hpet once, to avoid mixing hardware * if the hpet becomes enabled later. */ hpet = is_hpet_enabled(); - schedule_delayed_work(&tsc_irqwork, HZ); tsc_start = tsc_read_refs(&ref_start, hpet); + schedule_delayed_work(&tsc_irqwork, HZ); return; } @@ -1300,9 +1302,9 @@ static void tsc_refine_calibration_work(struct work_struct *work) if (ref_start == ref_stop) goto out; - /* Check, whether the sampling was disturbed by an SMI */ - if (tsc_start == ULLONG_MAX || tsc_stop == ULLONG_MAX) - goto out; + /* Check, whether the sampling was disturbed */ + if (tsc_stop == ULLONG_MAX) + goto restart; delta = tsc_stop - tsc_start; delta *= 1000000LL; diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 69b3a7c30013..31ecf7a76d5a 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -2,10 +2,6 @@ ccflags-y += -Iarch/x86/kvm -CFLAGS_x86.o := -I. -CFLAGS_svm.o := -I. -CFLAGS_vmx.o := -I. - KVM := ../../../virt/kvm kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index c90a5352d158..89d20ed1d2e8 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1636,7 +1636,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) ret = kvm_hvcall_signal_event(vcpu, fast, ingpa); if (ret != HV_STATUS_INVALID_PORT_ID) break; - /* maybe userspace knows this conn_id: fall through */ + /* fall through - maybe userspace knows this conn_id. */ case HVCALL_POST_MESSAGE: /* don't bother userspace if it has no way to handle it */ if (unlikely(rep || !vcpu_to_synic(vcpu)->active)) { @@ -1832,7 +1832,6 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, ent->eax |= HV_X64_MSR_VP_INDEX_AVAILABLE; ent->eax |= HV_X64_MSR_RESET_AVAILABLE; ent->eax |= HV_MSR_REFERENCE_TSC_AVAILABLE; - ent->eax |= HV_X64_MSR_GUEST_IDLE_AVAILABLE; ent->eax |= HV_X64_ACCESS_FREQUENCY_MSRS; ent->eax |= HV_X64_ACCESS_REENLIGHTENMENT; @@ -1848,11 +1847,11 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, case HYPERV_CPUID_ENLIGHTMENT_INFO: ent->eax |= HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED; ent->eax |= HV_X64_APIC_ACCESS_RECOMMENDED; - ent->eax |= HV_X64_SYSTEM_RESET_RECOMMENDED; ent->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED; ent->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED; ent->eax |= HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED; - ent->eax |= HV_X64_ENLIGHTENED_VMCS_RECOMMENDED; + if (evmcs_ver) + ent->eax |= HV_X64_ENLIGHTENED_VMCS_RECOMMENDED; /* * Default number of spinlock retry attempts, matches diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 9f089e2e09d0..4b6c2da7265c 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1035,6 +1035,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, switch (delivery_mode) { case APIC_DM_LOWEST: vcpu->arch.apic_arb_prio++; + /* fall through */ case APIC_DM_FIXED: if (unlikely(trig_mode && !level)) break; @@ -1874,6 +1875,7 @@ int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) case APIC_LVT0: apic_manage_nmi_watchdog(apic, val); + /* fall through */ case APIC_LVTTHMR: case APIC_LVTPC: case APIC_LVT1: diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index ce770b446238..da9c42349b1f 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -4371,6 +4371,7 @@ __reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, rsvd_bits(maxphyaddr, 51); rsvd_check->rsvd_bits_mask[1][4] = rsvd_check->rsvd_bits_mask[0][4]; + /* fall through */ case PT64_ROOT_4LEVEL: rsvd_check->rsvd_bits_mask[0][3] = exb_bit_rsvd | nonleaf_bit8_rsvd | rsvd_bits(7, 7) | diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 307e5bddb6d9..f13a3a24d360 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3414,6 +3414,14 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) kvm_mmu_reset_context(&svm->vcpu); kvm_mmu_load(&svm->vcpu); + /* + * Drop what we picked up for L2 via svm_complete_interrupts() so it + * doesn't end up in L1. + */ + svm->vcpu.arch.nmi_injected = false; + kvm_clear_exception_queue(&svm->vcpu); + kvm_clear_interrupt_queue(&svm->vcpu); + return 0; } @@ -4395,7 +4403,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) case MSR_IA32_APICBASE: if (kvm_vcpu_apicv_active(vcpu)) avic_update_vapic_bar(to_svm(vcpu), data); - /* Follow through */ + /* Fall through */ default: return kvm_set_msr_common(vcpu, msr); } @@ -4504,28 +4512,19 @@ static int avic_incomplete_ipi_interception(struct vcpu_svm *svm) kvm_lapic_reg_write(apic, APIC_ICR, icrl); break; case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING: { - int i; - struct kvm_vcpu *vcpu; - struct kvm *kvm = svm->vcpu.kvm; struct kvm_lapic *apic = svm->vcpu.arch.apic; /* - * At this point, we expect that the AVIC HW has already - * set the appropriate IRR bits on the valid target - * vcpus. So, we just need to kick the appropriate vcpu. + * Update ICR high and low, then emulate sending IPI, + * which is handled when writing APIC_ICR. */ - kvm_for_each_vcpu(i, vcpu, kvm) { - bool m = kvm_apic_match_dest(vcpu, apic, - icrl & KVM_APIC_SHORT_MASK, - GET_APIC_DEST_FIELD(icrh), - icrl & KVM_APIC_DEST_MASK); - - if (m && !avic_vcpu_is_running(vcpu)) - kvm_vcpu_wake_up(vcpu); - } + kvm_lapic_reg_write(apic, APIC_ICR2, icrh); + kvm_lapic_reg_write(apic, APIC_ICR, icrl); break; } case AVIC_IPI_FAILURE_INVALID_TARGET: + WARN_ONCE(1, "Invalid IPI target: index=%u, vcpu=%d, icr=%#0x:%#0x\n", + index, svm->vcpu.vcpu_id, icrh, icrl); break; case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE: WARN_ONCE(1, "Invalid backing page\n"); @@ -6278,6 +6277,9 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) int asid, ret; ret = -EBUSY; + if (unlikely(sev->active)) + return ret; + asid = sev_asid_new(); if (asid < 0) return ret; diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 705f40ae2532..6432d08c7de7 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -1465,7 +1465,7 @@ TRACE_EVENT(kvm_hv_send_ipi_ex, #endif /* _TRACE_KVM_H */ #undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH arch/x86/kvm +#define TRACE_INCLUDE_PATH ../../arch/x86/kvm #undef TRACE_INCLUDE_FILE #define TRACE_INCLUDE_FILE trace diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c index 95bc2247478d..5466c6d85cf3 100644 --- a/arch/x86/kvm/vmx/evmcs.c +++ b/arch/x86/kvm/vmx/evmcs.c @@ -332,16 +332,17 @@ int nested_enable_evmcs(struct kvm_vcpu *vcpu, uint16_t *vmcs_version) { struct vcpu_vmx *vmx = to_vmx(vcpu); + bool evmcs_already_enabled = vmx->nested.enlightened_vmcs_enabled; + + vmx->nested.enlightened_vmcs_enabled = true; if (vmcs_version) *vmcs_version = nested_get_evmcs_version(vcpu); /* We don't support disabling the feature for simplicity. */ - if (vmx->nested.enlightened_vmcs_enabled) + if (evmcs_already_enabled) return 0; - vmx->nested.enlightened_vmcs_enabled = true; - vmx->nested.msrs.pinbased_ctls_high &= ~EVMCS1_UNSUPPORTED_PINCTRL; vmx->nested.msrs.entry_ctls_high &= ~EVMCS1_UNSUPPORTED_VMENTRY_CTRL; vmx->nested.msrs.exit_ctls_high &= ~EVMCS1_UNSUPPORTED_VMEXIT_CTRL; diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 3170e291215d..8ff20523661b 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -55,7 +55,7 @@ static u16 shadow_read_write_fields[] = { static int max_shadow_read_write_fields = ARRAY_SIZE(shadow_read_write_fields); -void init_vmcs_shadow_fields(void) +static void init_vmcs_shadow_fields(void) { int i, j; @@ -4140,11 +4140,11 @@ static int enter_vmx_operation(struct kvm_vcpu *vcpu) if (r < 0) goto out_vmcs02; - vmx->nested.cached_vmcs12 = kmalloc(VMCS12_SIZE, GFP_KERNEL); + vmx->nested.cached_vmcs12 = kzalloc(VMCS12_SIZE, GFP_KERNEL); if (!vmx->nested.cached_vmcs12) goto out_cached_vmcs12; - vmx->nested.cached_shadow_vmcs12 = kmalloc(VMCS12_SIZE, GFP_KERNEL); + vmx->nested.cached_shadow_vmcs12 = kzalloc(VMCS12_SIZE, GFP_KERNEL); if (!vmx->nested.cached_shadow_vmcs12) goto out_cached_shadow_vmcs12; @@ -4540,9 +4540,8 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu) * given physical address won't match the required * VMCS12_REVISION identifier. */ - nested_vmx_failValid(vcpu, + return nested_vmx_failValid(vcpu, VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID); - return kvm_skip_emulated_instruction(vcpu); } new_vmcs12 = kmap(page); if (new_vmcs12->hdr.revision_id != VMCS12_REVISION || @@ -5264,13 +5263,17 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu, copy_shadow_to_vmcs12(vmx); } - if (copy_to_user(user_kvm_nested_state->data, vmcs12, sizeof(*vmcs12))) + /* + * Copy over the full allocated size of vmcs12 rather than just the size + * of the struct. + */ + if (copy_to_user(user_kvm_nested_state->data, vmcs12, VMCS12_SIZE)) return -EFAULT; if (nested_cpu_has_shadow_vmcs(vmcs12) && vmcs12->vmcs_link_pointer != -1ull) { if (copy_to_user(user_kvm_nested_state->data + VMCS12_SIZE, - get_shadow_vmcs12(vcpu), sizeof(*vmcs12))) + get_shadow_vmcs12(vcpu), VMCS12_SIZE)) return -EFAULT; } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 4d39f731bc33..4341175339f3 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -423,7 +423,7 @@ static void check_ept_pointer_match(struct kvm *kvm) to_kvm_vmx(kvm)->ept_pointers_match = EPT_POINTERS_MATCH; } -int kvm_fill_hv_flush_list_func(struct hv_guest_mapping_flush_list *flush, +static int kvm_fill_hv_flush_list_func(struct hv_guest_mapping_flush_list *flush, void *data) { struct kvm_tlb_range *range = data; @@ -453,7 +453,7 @@ static int hv_remote_flush_tlb_with_range(struct kvm *kvm, struct kvm_tlb_range *range) { struct kvm_vcpu *vcpu; - int ret = -ENOTSUPP, i; + int ret = 0, i; spin_lock(&to_kvm_vmx(kvm)->ept_pointer_lock); @@ -1773,7 +1773,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) if (!msr_info->host_initiated && !guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP)) return 1; - /* Otherwise falls through */ + /* Else, falls through */ default: msr = find_msr_entry(vmx, msr_info->index); if (msr) { @@ -2014,7 +2014,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) /* Check reserved bit, higher 32 bits should be zero */ if ((data >> 32) != 0) return 1; - /* Otherwise falls through */ + /* Else, falls through */ default: msr = find_msr_entry(vmx, msr_index); if (msr) { @@ -2344,7 +2344,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, case 37: /* AAT100 */ case 44: /* BC86,AAY89,BD102 */ case 46: /* BA97 */ - _vmexit_control &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL; + _vmentry_control &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL; _vmexit_control &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL; pr_warn_once("kvm: VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL " "does not work properly. Using workaround\n"); @@ -6362,72 +6362,9 @@ static void vmx_update_hv_timer(struct kvm_vcpu *vcpu) vmx->loaded_vmcs->hv_timer_armed = false; } -static void vmx_vcpu_run(struct kvm_vcpu *vcpu) +static void __vmx_vcpu_run(struct kvm_vcpu *vcpu, struct vcpu_vmx *vmx) { - struct vcpu_vmx *vmx = to_vmx(vcpu); - unsigned long cr3, cr4, evmcs_rsp; - - /* Record the guest's net vcpu time for enforced NMI injections. */ - if (unlikely(!enable_vnmi && - vmx->loaded_vmcs->soft_vnmi_blocked)) - vmx->loaded_vmcs->entry_time = ktime_get(); - - /* Don't enter VMX if guest state is invalid, let the exit handler - start emulation until we arrive back to a valid state */ - if (vmx->emulation_required) - return; - - if (vmx->ple_window_dirty) { - vmx->ple_window_dirty = false; - vmcs_write32(PLE_WINDOW, vmx->ple_window); - } - - if (vmx->nested.need_vmcs12_sync) - nested_sync_from_vmcs12(vcpu); - - if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty)) - vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]); - if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty)) - vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); - - cr3 = __get_current_cr3_fast(); - if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) { - vmcs_writel(HOST_CR3, cr3); - vmx->loaded_vmcs->host_state.cr3 = cr3; - } - - cr4 = cr4_read_shadow(); - if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) { - vmcs_writel(HOST_CR4, cr4); - vmx->loaded_vmcs->host_state.cr4 = cr4; - } - - /* When single-stepping over STI and MOV SS, we must clear the - * corresponding interruptibility bits in the guest state. Otherwise - * vmentry fails as it then expects bit 14 (BS) in pending debug - * exceptions being set, but that's not correct for the guest debugging - * case. */ - if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) - vmx_set_interrupt_shadow(vcpu, 0); - - if (static_cpu_has(X86_FEATURE_PKU) && - kvm_read_cr4_bits(vcpu, X86_CR4_PKE) && - vcpu->arch.pkru != vmx->host_pkru) - __write_pkru(vcpu->arch.pkru); - - pt_guest_enter(vmx); - - atomic_switch_perf_msrs(vmx); - - vmx_update_hv_timer(vcpu); - - /* - * If this vCPU has touched SPEC_CTRL, restore the guest's value if - * it's non-zero. Since vmentry is serialising on affected CPUs, there - * is no need to worry about the conditional branch over the wrmsr - * being speculatively taken. - */ - x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0); + unsigned long evmcs_rsp; vmx->__launched = vmx->loaded_vmcs->launched; @@ -6567,6 +6504,77 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) , "eax", "ebx", "edi" #endif ); +} +STACK_FRAME_NON_STANDARD(__vmx_vcpu_run); + +static void vmx_vcpu_run(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + unsigned long cr3, cr4; + + /* Record the guest's net vcpu time for enforced NMI injections. */ + if (unlikely(!enable_vnmi && + vmx->loaded_vmcs->soft_vnmi_blocked)) + vmx->loaded_vmcs->entry_time = ktime_get(); + + /* Don't enter VMX if guest state is invalid, let the exit handler + start emulation until we arrive back to a valid state */ + if (vmx->emulation_required) + return; + + if (vmx->ple_window_dirty) { + vmx->ple_window_dirty = false; + vmcs_write32(PLE_WINDOW, vmx->ple_window); + } + + if (vmx->nested.need_vmcs12_sync) + nested_sync_from_vmcs12(vcpu); + + if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty)) + vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]); + if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty)) + vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); + + cr3 = __get_current_cr3_fast(); + if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) { + vmcs_writel(HOST_CR3, cr3); + vmx->loaded_vmcs->host_state.cr3 = cr3; + } + + cr4 = cr4_read_shadow(); + if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) { + vmcs_writel(HOST_CR4, cr4); + vmx->loaded_vmcs->host_state.cr4 = cr4; + } + + /* When single-stepping over STI and MOV SS, we must clear the + * corresponding interruptibility bits in the guest state. Otherwise + * vmentry fails as it then expects bit 14 (BS) in pending debug + * exceptions being set, but that's not correct for the guest debugging + * case. */ + if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) + vmx_set_interrupt_shadow(vcpu, 0); + + if (static_cpu_has(X86_FEATURE_PKU) && + kvm_read_cr4_bits(vcpu, X86_CR4_PKE) && + vcpu->arch.pkru != vmx->host_pkru) + __write_pkru(vcpu->arch.pkru); + + pt_guest_enter(vmx); + + atomic_switch_perf_msrs(vmx); + + vmx_update_hv_timer(vcpu); + + /* + * If this vCPU has touched SPEC_CTRL, restore the guest's value if + * it's non-zero. Since vmentry is serialising on affected CPUs, there + * is no need to worry about the conditional branch over the wrmsr + * being speculatively taken. + */ + x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0); + + __vmx_vcpu_run(vcpu, vmx); /* * We do not use IBRS in the kernel. If this vCPU has used the @@ -6648,7 +6656,6 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) vmx_recover_nmi_blocking(vmx); vmx_complete_interrupts(vmx); } -STACK_FRAME_NON_STANDARD(vmx_vcpu_run); static struct kvm *vmx_vm_alloc(void) { @@ -7044,7 +7051,7 @@ static void update_intel_pt_cfg(struct kvm_vcpu *vcpu) /* unmask address range configure area */ for (i = 0; i < vmx->pt_desc.addr_range; i++) - vmx->pt_desc.ctl_bitmask &= ~(0xf << (32 + i * 4)); + vmx->pt_desc.ctl_bitmask &= ~(0xfULL << (32 + i * 4)); } static void vmx_cpuid_update(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 02c8e095a239..3d27206f6c01 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3834,6 +3834,8 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, case KVM_CAP_HYPERV_SYNIC2: if (cap->args[0]) return -EINVAL; + /* fall through */ + case KVM_CAP_HYPERV_SYNIC: if (!irqchip_in_kernel(vcpu->kvm)) return -EINVAL; @@ -6480,8 +6482,7 @@ restart: toggle_interruptibility(vcpu, ctxt->interruptibility); vcpu->arch.emulate_regs_need_sync_to_vcpu = false; kvm_rip_write(vcpu, ctxt->eip); - if (r == EMULATE_DONE && - (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP))) + if (r == EMULATE_DONE && ctxt->tf) kvm_vcpu_do_singlestep(vcpu, &r); if (!ctxt->have_exception || exception_type(ctxt->exception.vector) == EXCPT_TRAP) @@ -7093,10 +7094,10 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) case KVM_HC_CLOCK_PAIRING: ret = kvm_pv_clock_pairing(vcpu, a0, a1); break; +#endif case KVM_HC_SEND_IPI: ret = kvm_pv_send_ipi(vcpu->kvm, a0, a1, a2, a3, op_64_bit); break; -#endif default: ret = -KVM_ENOSYS; break; @@ -7937,6 +7938,7 @@ static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu) vcpu->arch.pv.pv_unhalted = false; vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; + /* fall through */ case KVM_MP_STATE_RUNNABLE: vcpu->arch.apf.halted = false; break; diff --git a/arch/x86/lib/kaslr.c b/arch/x86/lib/kaslr.c index 79778ab200e4..a53665116458 100644 --- a/arch/x86/lib/kaslr.c +++ b/arch/x86/lib/kaslr.c @@ -36,8 +36,8 @@ static inline u16 i8254(void) u16 status, timer; do { - outb(I8254_PORT_CONTROL, - I8254_CMD_READBACK | I8254_SELECT_COUNTER0); + outb(I8254_CMD_READBACK | I8254_SELECT_COUNTER0, + I8254_PORT_CONTROL); status = inb(I8254_PORT_COUNTER0); timer = inb(I8254_PORT_COUNTER0); timer |= inb(I8254_PORT_COUNTER0) << 8; diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c index a19ef1a416ff..4aa9b1480866 100644 --- a/arch/x86/mm/mem_encrypt_identity.c +++ b/arch/x86/mm/mem_encrypt_identity.c @@ -158,8 +158,8 @@ static void __init sme_populate_pgd(struct sme_populate_pgd_data *ppd) pmd = pmd_offset(pud, ppd->vaddr); if (pmd_none(*pmd)) { pte = ppd->pgtable_area; - memset(pte, 0, sizeof(pte) * PTRS_PER_PTE); - ppd->pgtable_area += sizeof(pte) * PTRS_PER_PTE; + memset(pte, 0, sizeof(*pte) * PTRS_PER_PTE); + ppd->pgtable_area += sizeof(*pte) * PTRS_PER_PTE; set_pmd(pmd, __pmd(PMD_FLAGS | __pa(pte))); } diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 2f6787fc7106..c54a493e139a 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -898,10 +898,7 @@ static u64 xen_read_msr_safe(unsigned int msr, int *err) val = native_read_msr_safe(msr, err); switch (msr) { case MSR_IA32_APICBASE: -#ifdef CONFIG_X86_X2APIC - if (!(cpuid_ecx(1) & (1 << (X86_FEATURE_X2APIC & 31)))) -#endif - val &= ~X2APIC_ENABLE; + val &= ~X2APIC_ENABLE; break; } return val; diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 72bf446c3fee..6e29794573b7 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -361,8 +361,6 @@ void xen_timer_resume(void) { int cpu; - pvclock_resume(); - if (xen_clockevent != &xen_vcpuop_clockevent) return; @@ -379,12 +377,15 @@ static const struct pv_time_ops xen_time_ops __initconst = { }; static struct pvclock_vsyscall_time_info *xen_clock __read_mostly; +static u64 xen_clock_value_saved; void xen_save_time_memory_area(void) { struct vcpu_register_time_memory_area t; int ret; + xen_clock_value_saved = xen_clocksource_read() - xen_sched_clock_offset; + if (!xen_clock) return; @@ -404,7 +405,7 @@ void xen_restore_time_memory_area(void) int ret; if (!xen_clock) - return; + goto out; t.addr.v = &xen_clock->pvti; @@ -421,6 +422,11 @@ void xen_restore_time_memory_area(void) if (ret != 0) pr_notice("Cannot restore secondary vcpu_time_info (err %d)", ret); + +out: + /* Need pvclock_resume() before using xen_clocksource_read(). */ + pvclock_resume(); + xen_sched_clock_offset = xen_clocksource_read() - xen_clock_value_saved; } static void xen_setup_vsyscall_time_info(void) |