Merge "Merge upstream linux-stable v3.10.36 into msm-3.10"

This commit is contained in:
Linux Build Service Account 2014-05-05 15:09:00 -07:00 committed by Gerrit - the friendly Code Review server
commit 16296e0178
509 changed files with 4720 additions and 2218 deletions

View File

@ -1,7 +1,7 @@
* Marvell Orion SATA
Required Properties:
- compatibility : "marvell,orion-sata"
- compatibility : "marvell,orion-sata" or "marvell,armada-370-sata"
- reg : Address range of controller
- interrupts : Interrupt controller is using
- nr-ports : Number of SATA ports in use.

View File

@ -1372,8 +1372,8 @@ may allocate from based on an estimation of its current memory and swap use.
For example, if a task is using all allowed memory, its badness score will be
1000. If it is using half of its allowed memory, its score will be 500.
There is an additional factor included in the badness score: root
processes are given 3% extra memory over other tasks.
There is an additional factor included in the badness score: the current memory
and swap usage is discounted by 3% for root processes.
The amount of "allowed" memory depends on the context in which the oom killer
was called. If it is due to the memory assigned to the allocating task's cpuset

View File

@ -24,6 +24,7 @@ Supported adapters:
* Intel Lynx Point-LP (PCH)
* Intel Avoton (SOC)
* Intel Wellsburg (PCH)
* Intel Coleto Creek (PCH)
Datasheets: Publicly available at the Intel website
On Intel Patsburg and later chipsets, both the normal host SMBus controller

View File

@ -1,6 +1,6 @@
VERSION = 3
PATCHLEVEL = 10
SUBLEVEL = 28
SUBLEVEL = 36
EXTRAVERSION =
NAME = TOSSUG Baby Fish

View File

@ -233,6 +233,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
static inline void __flush_icache_all(void)
{
__flush_icache_preferred();
dsb();
}
/*

View File

@ -37,10 +37,10 @@ struct outer_cache_fns {
void (*resume)(void);
};
#ifdef CONFIG_OUTER_CACHE
extern struct outer_cache_fns outer_cache;
#ifdef CONFIG_OUTER_CACHE
static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
{
if (outer_cache.inv_range)

View File

@ -144,19 +144,22 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
static inline int arch_spin_trylock(arch_spinlock_t *lock)
{
unsigned long tmp;
unsigned long contended, res;
u32 slock;
__asm__ __volatile__(
" ldrex %0, [%2]\n"
" subs %1, %0, %0, ror #16\n"
" addeq %0, %0, %3\n"
" strexeq %1, %0, [%2]"
: "=&r" (slock), "=&r" (tmp)
: "r" (&lock->slock), "I" (1 << TICKET_SHIFT)
: "cc");
do {
__asm__ __volatile__(
" ldrex %0, [%3]\n"
" mov %2, #0\n"
" subs %1, %0, %0, ror #16\n"
" addeq %0, %0, %4\n"
" strexeq %2, %0, [%3]"
: "=&r" (slock), "=&r" (contended), "=&r" (res)
: "r" (&lock->slock), "I" (1 << TICKET_SHIFT)
: "cc");
} while (res);
if (tmp == 0) {
if (!contended) {
smp_mb();
return 1;
} else {
@ -214,17 +217,20 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
static inline int arch_write_trylock(arch_rwlock_t *rw)
{
unsigned long tmp;
unsigned long contended, res;
__asm__ __volatile__(
" ldrex %0, [%1]\n"
" teq %0, #0\n"
" strexeq %0, %2, [%1]"
: "=&r" (tmp)
: "r" (&rw->lock), "r" (0x80000000)
: "cc");
do {
__asm__ __volatile__(
" ldrex %0, [%2]\n"
" mov %1, #0\n"
" teq %0, #0\n"
" strexeq %1, %3, [%2]"
: "=&r" (contended), "=&r" (res)
: "r" (&rw->lock), "r" (0x80000000)
: "cc");
} while (res);
if (tmp == 0) {
if (!contended) {
smp_mb();
return 1;
} else {
@ -302,18 +308,26 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
static inline int arch_read_trylock(arch_rwlock_t *rw)
{
unsigned long tmp, tmp2 = 1;
unsigned long contended, res;
__asm__ __volatile__(
" ldrex %0, [%2]\n"
" adds %0, %0, #1\n"
" strexpl %1, %0, [%2]\n"
: "=&r" (tmp), "+r" (tmp2)
: "r" (&rw->lock)
: "cc");
do {
__asm__ __volatile__(
" ldrex %0, [%2]\n"
" mov %1, #0\n"
" adds %0, %0, #1\n"
" strexpl %1, %0, [%2]"
: "=&r" (contended), "=&r" (res)
: "r" (&rw->lock)
: "cc");
} while (res);
smp_mb();
return tmp2 == 0;
/* If the lock is negative, then it is already held for write. */
if (contended < 0x80000000) {
smp_mb();
return 1;
} else {
return 0;
}
}
/* read_can_lock - would read_trylock() succeed? */

View File

@ -535,15 +535,23 @@ void __init dump_machine_table(void)
int __init arm_add_memory(phys_addr_t start, phys_addr_t size)
{
u64 aligned_start;
/*
* Ensure that start/size are aligned to a page boundary.
* Size is appropriately rounded down, start is rounded up.
*/
size -= start & ~PAGE_MASK;
start = PAGE_ALIGN(start);
aligned_start = PAGE_ALIGN(start);
#ifndef CONFIG_ARM_LPAE
if (start + size < start) {
#ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT
if (aligned_start > ULONG_MAX) {
printk(KERN_CRIT "Ignoring memory at 0x%08llx outside "
"32-bit physical address space\n", (long long)start);
return -EINVAL;
}
if (aligned_start + size > ULONG_MAX) {
printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in "
"32-bit physical address space\n", (long long)start);
/*
@ -551,10 +559,24 @@ int __init arm_add_memory(phys_addr_t start, phys_addr_t size)
* 32 bits, we use ULONG_MAX as the upper limit rather than 4GB.
* This means we lose a page after masking.
*/
size = ULONG_MAX - start;
size = ULONG_MAX - aligned_start;
}
#endif
if (aligned_start < PHYS_OFFSET) {
if (aligned_start + size <= PHYS_OFFSET) {
pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n",
aligned_start, aligned_start + size);
return -EINVAL;
}
pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n",
aligned_start, (u64)PHYS_OFFSET);
size -= PHYS_OFFSET - aligned_start;
aligned_start = PHYS_OFFSET;
}
size = size & ~(phys_addr_t)(PAGE_SIZE - 1);
/*

View File

@ -101,7 +101,7 @@ static void sam9_smc_cs_read(void __iomem *base,
/* Pulse register */
val = __raw_readl(base + AT91_SMC_PULSE);
config->nwe_setup = val & AT91_SMC_NWEPULSE;
config->nwe_pulse = val & AT91_SMC_NWEPULSE;
config->ncs_write_pulse = (val & AT91_SMC_NCS_WRPULSE) >> 8;
config->nrd_pulse = (val & AT91_SMC_NRDPULSE) >> 16;
config->ncs_read_pulse = (val & AT91_SMC_NCS_RDPULSE) >> 24;

View File

@ -65,14 +65,12 @@ void highbank_set_cpu_jump(int cpu, void *jump_addr)
HB_JUMP_TABLE_PHYS(cpu) + 15);
}
#ifdef CONFIG_CACHE_L2X0
static void highbank_l2x0_disable(void)
{
outer_flush_all();
/* Disable PL310 L2 Cache controller */
highbank_smc1(0x102, 0x0);
}
#endif
static void __init highbank_init_irq(void)
{
@ -81,12 +79,13 @@ static void __init highbank_init_irq(void)
if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9"))
highbank_scu_map_io();
#ifdef CONFIG_CACHE_L2X0
/* Enable PL310 L2 Cache controller */
highbank_smc1(0x102, 0x1);
l2x0_of_init(0, ~0UL);
outer_cache.disable = highbank_l2x0_disable;
#endif
if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
highbank_smc1(0x102, 0x1);
l2x0_of_init(0, ~0UL);
outer_cache.disable = highbank_l2x0_disable;
}
}
static void __init highbank_timer_init(void)

View File

@ -1335,7 +1335,7 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
of_property_read_bool(np, "gpmc,time-para-granularity");
}
#ifdef CONFIG_MTD_NAND
#if IS_ENABLED(CONFIG_MTD_NAND)
static const char * const nand_ecc_opts[] = {
[OMAP_ECC_HAMMING_CODE_DEFAULT] = "sw",
@ -1391,7 +1391,7 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
}
#endif
#ifdef CONFIG_MTD_ONENAND
#if IS_ENABLED(CONFIG_MTD_ONENAND)
static int gpmc_probe_onenand_child(struct platform_device *pdev,
struct device_node *child)
{

View File

@ -13,6 +13,8 @@
#ifndef __ASM_ARCH_COLLIE_H
#define __ASM_ARCH_COLLIE_H
#include "hardware.h" /* Gives GPIO_MAX */
extern void locomolcd_power(int on);
#define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1)

View File

@ -23,6 +23,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/of.h>
#include <linux/irqchip.h>
#include <linux/clk/tegra.h>
@ -81,10 +82,20 @@ void tegra_assert_system_reset(enum reboot_mode mode, const char *cmd)
static void __init tegra_init_cache(void)
{
#ifdef CONFIG_CACHE_L2X0
static const struct of_device_id pl310_ids[] __initconst = {
{ .compatible = "arm,pl310-cache", },
{}
};
struct device_node *np;
int ret;
void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
u32 aux_ctrl, cache_type;
np = of_find_matching_node(NULL, pl310_ids);
if (!np)
return;
cache_type = readl(p + L2X0_CACHE_TYPE);
aux_ctrl = (cache_type & 0x700) << (17-8);
aux_ctrl |= 0x7C400001;

View File

@ -1390,7 +1390,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
*handle = DMA_ERROR_CODE;
size = PAGE_ALIGN(size);
if (gfp & GFP_ATOMIC)
if (!(gfp & __GFP_WAIT))
return __iommu_alloc_atomic(dev, size, handle);
pages = __iommu_alloc_buffer(dev, size, gfp, attrs);

View File

@ -206,7 +206,6 @@ __v6_setup:
mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
#ifdef CONFIG_MMU
mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
mcr p15, 0, r0, c2, c0, 2 @ TTB control register
@ -216,6 +215,8 @@ __v6_setup:
ALT_UP(orr r8, r8, #TTB_FLAGS_UP)
mcr p15, 0, r8, c2, c0, 1 @ load TTB1
#endif /* CONFIG_MMU */
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer and
@ complete invalidations
adr r5, v6_crval
ldmia r5, {r5, r6}
#ifdef CONFIG_CPU_ENDIAN_BE8

View File

@ -337,7 +337,6 @@ __v7_setup:
3: mov r10, #0
mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
dsb
#ifdef CONFIG_MMU
mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
v7_ttb_setup r10, r4, r8, r5 @ TTBCR, TTBRx setup
@ -371,6 +370,7 @@ __v7_setup:
mcr p15, 3, r0, c15, c0, 2
#endif
dsb @ Complete invalidations
#ifndef CONFIG_ARM_THUMBEE
mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE
and r0, r0, #(0xf << 12) @ ThumbEE enabled field

View File

@ -637,10 +637,10 @@ load_ind:
emit(ARM_MUL(r_A, r_A, r_X), ctx);
break;
case BPF_S_ALU_DIV_K:
/* current k == reciprocal_value(userspace k) */
if (k == 1)
break;
emit_mov_i(r_scratch, k, ctx);
/* A = top 32 bits of the product */
emit(ARM_UMULL(r_scratch, r_A, r_A, r_scratch), ctx);
emit_udiv(r_A, r_A, r_scratch, ctx);
break;
case BPF_S_ALU_DIV_X:
update_on_xread(ctx);

View File

@ -11,7 +11,7 @@ all: uImage vmlinux.elf
KBUILD_DEFCONFIG := atstk1002_defconfig
KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic
KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic -D__linux__
KBUILD_AFLAGS += -mrelax -mno-pic
KBUILD_CFLAGS_MODULE += -mno-relax
LDFLAGS_vmlinux += --relax

View File

@ -11,6 +11,7 @@
#define FRAM_VERSION "1.0"
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/mm.h>
#include <linux/io.h>

View File

@ -14,6 +14,7 @@
#define _ASM_MIPSREGS_H
#include <linux/linkage.h>
#include <linux/types.h>
#include <asm/hazards.h>
#include <asm/war.h>

View File

@ -132,7 +132,6 @@ void mark_rodata_ro(void);
static inline void *kmap(struct page *page)
{
might_sleep();
flush_dcache_page(page);
return page_address(page);
}
@ -144,7 +143,6 @@ static inline void kunmap(struct page *page)
static inline void *kmap_atomic(struct page *page)
{
pagefault_disable();
flush_dcache_page(page);
return page_address(page);
}

View File

@ -29,7 +29,8 @@ struct page;
void clear_page_asm(void *page);
void copy_page_asm(void *to, void *from);
#define clear_user_page(vto, vaddr, page) clear_page_asm(vto)
#define copy_user_page(vto, vfrom, vaddr, page) copy_page_asm(vto, vfrom)
void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
struct page *pg);
/* #define CONFIG_PARISC_TMPALIAS */

View File

@ -388,6 +388,20 @@ void flush_kernel_dcache_page_addr(void *addr)
}
EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
struct page *pg)
{
/* Copy using kernel mapping. No coherency is needed (all in
kunmap) for the `to' page. However, the `from' page needs to
be flushed through a mapping equivalent to the user mapping
before it can be accessed through the kernel mapping. */
preempt_disable();
flush_dcache_page_asm(__pa(vfrom), vaddr);
preempt_enable();
copy_page_asm(vto, vfrom);
}
EXPORT_SYMBOL(copy_user_page);
void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
{
unsigned long flags;

View File

@ -22,7 +22,15 @@ struct device_node;
static inline int cpu_to_node(int cpu)
{
return numa_cpu_lookup_table[cpu];
int nid;
nid = numa_cpu_lookup_table[cpu];
/*
* During early boot, the numa-cpu lookup table might not have been
* setup for all CPUs yet. In such cases, default to node 0.
*/
return (nid < 0) ? 0 : nid;
}
#define parent_node(node) (node)

View File

@ -788,6 +788,9 @@ static void remove_cache_dir(struct cache_dir *cache_dir)
{
remove_index_dirs(cache_dir);
/* Remove cache dir from sysfs */
kobject_del(cache_dir->kobj);
kobject_put(cache_dir->kobj);
kfree(cache_dir);

View File

@ -108,17 +108,19 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
size_t csize, unsigned long offset, int userbuf)
{
void *vaddr;
phys_addr_t paddr;
if (!csize)
return 0;
csize = min_t(size_t, csize, PAGE_SIZE);
paddr = pfn << PAGE_SHIFT;
if ((min_low_pfn < pfn) && (pfn < max_pfn)) {
vaddr = __va(pfn << PAGE_SHIFT);
if (memblock_is_region_memory(paddr, csize)) {
vaddr = __va(paddr);
csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
} else {
vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0);
vaddr = __ioremap(paddr, PAGE_SIZE, 0);
csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
iounmap(vaddr);
}

View File

@ -81,6 +81,7 @@ _GLOBAL(relocate)
6: blr
.balign 8
p_dyn: .llong __dynamic_start - 0b
p_rela: .llong __rela_dyn_start - 0b
p_st: .llong _stext - 0b

View File

@ -82,10 +82,13 @@ void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu)
/* CPU points to the first thread of the core */
if (cpu != me && cpu >= 0 && cpu < nr_cpu_ids) {
#ifdef CONFIG_KVM_XICS
int real_cpu = cpu + vcpu->arch.ptid;
if (paca[real_cpu].kvm_hstate.xics_phys)
xics_wake_cpu(real_cpu);
else if (cpu_online(cpu))
else
#endif
if (cpu_online(cpu))
smp_send_reschedule(cpu);
}
put_cpu();
@ -1090,7 +1093,9 @@ static void kvmppc_start_thread(struct kvm_vcpu *vcpu)
smp_wmb();
#if defined(CONFIG_PPC_ICP_NATIVE) && defined(CONFIG_SMP)
if (vcpu->arch.ptid) {
#ifdef CONFIG_KVM_XICS
xics_wake_cpu(cpu);
#endif
++vc->n_woken;
}
#endif

View File

@ -127,7 +127,7 @@ static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500,
}
static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
unsigned int eaddr, int as)
gva_t eaddr, int as)
{
struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
unsigned int victim, tsized;

View File

@ -31,6 +31,8 @@
#include <asm/sparsemem.h>
#include <asm/prom.h>
#include <asm/smp.h>
#include <asm/cputhreads.h>
#include <asm/topology.h>
#include <asm/firmware.h>
#include <asm/paca.h>
#include <asm/hvcall.h>
@ -152,9 +154,22 @@ static void __init get_node_active_region(unsigned long pfn,
}
}
static void map_cpu_to_node(int cpu, int node)
static void reset_numa_cpu_lookup_table(void)
{
unsigned int cpu;
for_each_possible_cpu(cpu)
numa_cpu_lookup_table[cpu] = -1;
}
static void update_numa_cpu_lookup_table(unsigned int cpu, int node)
{
numa_cpu_lookup_table[cpu] = node;
}
static void map_cpu_to_node(int cpu, int node)
{
update_numa_cpu_lookup_table(cpu, node);
dbg("adding cpu %d to node %d\n", cpu, node);
@ -519,11 +534,24 @@ static int of_drconf_to_nid_single(struct of_drconf_cell *drmem,
*/
static int __cpuinit numa_setup_cpu(unsigned long lcpu)
{
int nid = 0;
struct device_node *cpu = of_get_cpu_node(lcpu, NULL);
int nid;
struct device_node *cpu;
/*
* If a valid cpu-to-node mapping is already available, use it
* directly instead of querying the firmware, since it represents
* the most recent mapping notified to us by the platform (eg: VPHN).
*/
if ((nid = numa_cpu_lookup_table[lcpu]) >= 0) {
map_cpu_to_node(lcpu, nid);
return nid;
}
cpu = of_get_cpu_node(lcpu, NULL);
if (!cpu) {
WARN_ON(1);
nid = 0;
goto out;
}
@ -1066,6 +1094,7 @@ void __init do_init_bootmem(void)
*/
setup_node_to_cpumask_map();
reset_numa_cpu_lookup_table();
register_cpu_notifier(&ppc64_numa_nb);
cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE,
(void *)(unsigned long)boot_cpuid);
@ -1443,6 +1472,33 @@ static int update_cpu_topology(void *data)
return 0;
}
static int update_lookup_table(void *data)
{
struct topology_update_data *update;
if (!data)
return -EINVAL;
/*
* Upon topology update, the numa-cpu lookup table needs to be updated
* for all threads in the core, including offline CPUs, to ensure that
* future hotplug operations respect the cpu-to-node associativity
* properly.
*/
for (update = data; update; update = update->next) {
int nid, base, j;
nid = update->new_nid;
base = cpu_first_thread_sibling(update->cpu);
for (j = 0; j < threads_per_core; j++) {
update_numa_cpu_lookup_table(base + j, nid);
}
}
return 0;
}
/*
* Update the node maps and sysfs entries for each cpu whose home node
* has changed. Returns 1 when the topology has changed, and 0 otherwise.
@ -1511,6 +1567,14 @@ int arch_update_cpu_topology(void)
stop_machine(update_cpu_topology, &updates[0], &updated_cpus);
/*
* Update the numa-cpu lookup table with the new mappings, even for
* offline CPUs. It is best to perform this update from the stop-
* machine context.
*/
stop_machine(update_lookup_table, &updates[0],
cpumask_of(raw_smp_processor_id()));
for (ud = &updates[0]; ud; ud = ud->next) {
unregister_cpu_under_node(ud->cpu, ud->old_nid);
register_cpu_under_node(ud->cpu, ud->new_nid);

View File

@ -209,10 +209,11 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
}
PPC_DIVWU(r_A, r_A, r_X);
break;
case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
case BPF_S_ALU_DIV_K: /* A /= K */
if (K == 1)
break;
PPC_LI32(r_scratch1, K);
/* Top 32 bits of 64bit result -> A */
PPC_MULHWU(r_A, r_A, r_scratch1);
PPC_DIVWU(r_A, r_A, r_scratch1);
break;
case BPF_S_ALU_AND_X:
ctx->seen |= SEEN_XREG;

View File

@ -34,12 +34,7 @@
#include "offline_states.h"
/* This version can't take the spinlock, because it never returns */
static struct rtas_args rtas_stop_self_args = {
.token = RTAS_UNKNOWN_SERVICE,
.nargs = 0,
.nret = 1,
.rets = &rtas_stop_self_args.args[0],
};
static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE;
static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) =
CPU_STATE_OFFLINE;
@ -92,15 +87,20 @@ void set_default_offline_state(int cpu)
static void rtas_stop_self(void)
{
struct rtas_args *args = &rtas_stop_self_args;
struct rtas_args args = {
.token = cpu_to_be32(rtas_stop_self_token),
.nargs = 0,
.nret = 1,
.rets = &args.args[0],
};
local_irq_disable();
BUG_ON(args->token == RTAS_UNKNOWN_SERVICE);
BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);
printk("cpu %u (hwid %u) Ready to die...\n",
smp_processor_id(), hard_smp_processor_id());
enter_rtas(__pa(args));
enter_rtas(__pa(&args));
panic("Alas, I survived.\n");
}
@ -391,10 +391,10 @@ static int __init pseries_cpu_hotplug_init(void)
}
}
rtas_stop_self_args.token = rtas_token("stop-self");
rtas_stop_self_token = rtas_token("stop-self");
qcss_tok = rtas_token("query-cpu-stopped-state");
if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE ||
if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE ||
qcss_tok == RTAS_UNKNOWN_SERVICE) {
printk(KERN_INFO "CPU Hotplug not supported by firmware "
"- disabling.\n");

View File

@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include "crypt_s390.h"
#define AES_KEYLEN_128 1
@ -32,6 +33,7 @@
#define AES_KEYLEN_256 4
static u8 *ctrblk;
static DEFINE_SPINLOCK(ctrblk_lock);
static char keylen_flag;
struct s390_aes_ctx {
@ -756,43 +758,67 @@ static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
return aes_set_key(tfm, in_key, key_len);
}
static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes)
{
unsigned int i, n;
/* only use complete blocks, max. PAGE_SIZE */
n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(AES_BLOCK_SIZE - 1);
for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) {
memcpy(ctrptr + i, ctrptr + i - AES_BLOCK_SIZE,
AES_BLOCK_SIZE);
crypto_inc(ctrptr + i, AES_BLOCK_SIZE);
}
return n;
}
static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
struct s390_aes_ctx *sctx, struct blkcipher_walk *walk)
{
int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE);
unsigned int i, n, nbytes;
u8 buf[AES_BLOCK_SIZE];
u8 *out, *in;
unsigned int n, nbytes;
u8 buf[AES_BLOCK_SIZE], ctrbuf[AES_BLOCK_SIZE];
u8 *out, *in, *ctrptr = ctrbuf;
if (!walk->nbytes)
return ret;
memcpy(ctrblk, walk->iv, AES_BLOCK_SIZE);
if (spin_trylock(&ctrblk_lock))
ctrptr = ctrblk;
memcpy(ctrptr, walk->iv, AES_BLOCK_SIZE);
while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) {
out = walk->dst.virt.addr;
in = walk->src.virt.addr;
while (nbytes >= AES_BLOCK_SIZE) {
/* only use complete blocks, max. PAGE_SIZE */
n = (nbytes > PAGE_SIZE) ? PAGE_SIZE :
nbytes & ~(AES_BLOCK_SIZE - 1);
for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) {
memcpy(ctrblk + i, ctrblk + i - AES_BLOCK_SIZE,
AES_BLOCK_SIZE);
crypto_inc(ctrblk + i, AES_BLOCK_SIZE);
}
ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrblk);
if (ret < 0 || ret != n)
if (ctrptr == ctrblk)
n = __ctrblk_init(ctrptr, nbytes);
else
n = AES_BLOCK_SIZE;
ret = crypt_s390_kmctr(func, sctx->key, out, in,
n, ctrptr);
if (ret < 0 || ret != n) {
if (ctrptr == ctrblk)
spin_unlock(&ctrblk_lock);
return -EIO;
}
if (n > AES_BLOCK_SIZE)
memcpy(ctrblk, ctrblk + n - AES_BLOCK_SIZE,
memcpy(ctrptr, ctrptr + n - AES_BLOCK_SIZE,
AES_BLOCK_SIZE);
crypto_inc(ctrblk, AES_BLOCK_SIZE);
crypto_inc(ctrptr, AES_BLOCK_SIZE);
out += n;
in += n;
nbytes -= n;
}
ret = blkcipher_walk_done(desc, walk, nbytes);
}
if (ctrptr == ctrblk) {
if (nbytes)
memcpy(ctrbuf, ctrptr, AES_BLOCK_SIZE);
else
memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE);
spin_unlock(&ctrblk_lock);
}
/*
* final block may be < AES_BLOCK_SIZE, copy only nbytes
*/
@ -800,14 +826,15 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
out = walk->dst.virt.addr;
in = walk->src.virt.addr;
ret = crypt_s390_kmctr(func, sctx->key, buf, in,
AES_BLOCK_SIZE, ctrblk);
AES_BLOCK_SIZE, ctrbuf);
if (ret < 0 || ret != AES_BLOCK_SIZE)
return -EIO;
memcpy(out, buf, nbytes);
crypto_inc(ctrblk, AES_BLOCK_SIZE);
crypto_inc(ctrbuf, AES_BLOCK_SIZE);
ret = blkcipher_walk_done(desc, walk, 0);
memcpy(walk->iv, ctrbuf, AES_BLOCK_SIZE);
}
memcpy(walk->iv, ctrblk, AES_BLOCK_SIZE);
return ret;
}

View File

@ -25,6 +25,7 @@
#define DES3_KEY_SIZE (3 * DES_KEY_SIZE)
static u8 *ctrblk;
static DEFINE_SPINLOCK(ctrblk_lock);
struct s390_des_ctx {
u8 iv[DES_BLOCK_SIZE];
@ -105,29 +106,35 @@ static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
}
static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
u8 *iv, struct blkcipher_walk *walk)
struct blkcipher_walk *walk)
{
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
int ret = blkcipher_walk_virt(desc, walk);
unsigned int nbytes = walk->nbytes;
struct {
u8 iv[DES_BLOCK_SIZE];
u8 key[DES3_KEY_SIZE];
} param;
if (!nbytes)
goto out;
memcpy(iv, walk->iv, DES_BLOCK_SIZE);
memcpy(param.iv, walk->iv, DES_BLOCK_SIZE);
memcpy(param.key, ctx->key, DES3_KEY_SIZE);
do {
/* only use complete blocks */
unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
u8 *out = walk->dst.virt.addr;
u8 *in = walk->src.virt.addr;
ret = crypt_s390_kmc(func, iv, out, in, n);
ret = crypt_s390_kmc(func, &param, out, in, n);
if (ret < 0 || ret != n)
return -EIO;
nbytes &= DES_BLOCK_SIZE - 1;
ret = blkcipher_walk_done(desc, walk, nbytes);
} while ((nbytes = walk->nbytes));
memcpy(walk->iv, iv, DES_BLOCK_SIZE);
memcpy(walk->iv, param.iv, DES_BLOCK_SIZE);
out:
return ret;
@ -179,22 +186,20 @@ static int cbc_des_encrypt(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes)
{
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
struct blkcipher_walk walk;
blkcipher_walk_init(&walk, dst, src, nbytes);
return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, ctx->iv, &walk);
return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, &walk);
}
static int cbc_des_decrypt(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes)
{
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
struct blkcipher_walk walk;
blkcipher_walk_init(&walk, dst, src, nbytes);
return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, ctx->iv, &walk);
return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, &walk);
}
static struct crypto_alg cbc_des_alg = {
@ -327,22 +332,20 @@ static int cbc_des3_encrypt(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes)
{
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
struct blkcipher_walk walk;
blkcipher_walk_init(&walk, dst, src, nbytes);
return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, ctx->iv, &walk);
return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, &walk);
}
static int cbc_des3_decrypt(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes)
{
struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
struct blkcipher_walk walk;
blkcipher_walk_init(&walk, dst, src, nbytes);
return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, ctx->iv, &walk);
return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, &walk);
}
static struct crypto_alg cbc_des3_alg = {
@ -366,54 +369,80 @@ static struct crypto_alg cbc_des3_alg = {
}
};
static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes)
{
unsigned int i, n;
/* align to block size, max. PAGE_SIZE */
n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(DES_BLOCK_SIZE - 1);
for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) {
memcpy(ctrptr + i, ctrptr + i - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
crypto_inc(ctrptr + i, DES_BLOCK_SIZE);
}
return n;
}
static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
struct s390_des_ctx *ctx, struct blkcipher_walk *walk)
struct s390_des_ctx *ctx,
struct blkcipher_walk *walk)
{
int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE);
unsigned int i, n, nbytes;
u8 buf[DES_BLOCK_SIZE];
u8 *out, *in;
unsigned int n, nbytes;
u8 buf[DES_BLOCK_SIZE], ctrbuf[DES_BLOCK_SIZE];
u8 *out, *in, *ctrptr = ctrbuf;
memcpy(ctrblk, walk->iv, DES_BLOCK_SIZE);
if (!walk->nbytes)
return ret;
if (spin_trylock(&ctrblk_lock))
ctrptr = ctrblk;
memcpy(ctrptr, walk->iv, DES_BLOCK_SIZE);
while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) {
out = walk->dst.virt.addr;
in = walk->src.virt.addr;
while (nbytes >= DES_BLOCK_SIZE) {
/* align to block size, max. PAGE_SIZE */
n = (nbytes > PAGE_SIZE) ? PAGE_SIZE :
nbytes & ~(DES_BLOCK_SIZE - 1);
for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) {
memcpy(ctrblk + i, ctrblk + i - DES_BLOCK_SIZE,
DES_BLOCK_SIZE);
crypto_inc(ctrblk + i, DES_BLOCK_SIZE);
}
ret = crypt_s390_kmctr(func, ctx->key, out, in, n, ctrblk);
if (ret < 0 || ret != n)
if (ctrptr == ctrblk)
n = __ctrblk_init(ctrptr, nbytes);
else
n = DES_BLOCK_SIZE;
ret = crypt_s390_kmctr(func, ctx->key, out, in,
n, ctrptr);
if (ret < 0 || ret != n) {
if (ctrptr == ctrblk)
spin_unlock(&ctrblk_lock);
return -EIO;
}
if (n > DES_BLOCK_SIZE)
memcpy(ctrblk, ctrblk + n - DES_BLOCK_SIZE,
memcpy(ctrptr, ctrptr + n - DES_BLOCK_SIZE,
DES_BLOCK_SIZE);
crypto_inc(ctrblk, DES_BLOCK_SIZE);
crypto_inc(ctrptr, DES_BLOCK_SIZE);
out += n;
in += n;
nbytes -= n;
}
ret = blkcipher_walk_done(desc, walk, nbytes);
}
if (ctrptr == ctrblk) {
if (nbytes)
memcpy(ctrbuf, ctrptr, DES_BLOCK_SIZE);
else
memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE);
spin_unlock(&ctrblk_lock);
}
/* final block may be < DES_BLOCK_SIZE, copy only nbytes */
if (nbytes) {
out = walk->dst.virt.addr;
in = walk->src.virt.addr;
ret = crypt_s390_kmctr(func, ctx->key, buf, in,
DES_BLOCK_SIZE, ctrblk);
DES_BLOCK_SIZE, ctrbuf);
if (ret < 0 || ret != DES_BLOCK_SIZE)
return -EIO;
memcpy(out, buf, nbytes);
crypto_inc(ctrblk, DES_BLOCK_SIZE);
crypto_inc(ctrbuf, DES_BLOCK_SIZE);
ret = blkcipher_walk_done(desc, walk, 0);
memcpy(walk->iv, ctrbuf, DES_BLOCK_SIZE);
}
memcpy(walk->iv, ctrblk, DES_BLOCK_SIZE);
return ret;
}

View File

@ -35,11 +35,11 @@ struct statfs {
struct statfs64 {
unsigned int f_type;
unsigned int f_bsize;
unsigned long f_blocks;
unsigned long f_bfree;
unsigned long f_bavail;
unsigned long f_files;
unsigned long f_ffree;
unsigned long long f_blocks;
unsigned long long f_bfree;
unsigned long long f_bavail;
unsigned long long f_files;
unsigned long long f_ffree;
__kernel_fsid_t f_fsid;
unsigned int f_namelen;
unsigned int f_frsize;

View File

@ -59,7 +59,7 @@ ENTRY(startup_continue)
.quad 0 # cr12: tracing off
.quad 0 # cr13: home space segment table
.quad 0xc0000000 # cr14: machine check handling off
.quad 0 # cr15: linkage stack operations
.quad .Llinkage_stack # cr15: linkage stack operations
.Lpcmsk:.quad 0x0000000180000000
.L4malign:.quad 0xffffffffffc00000
.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
@ -67,12 +67,15 @@ ENTRY(startup_continue)
.Lparmaddr:
.quad PARMAREA
.align 64
.Lduct: .long 0,0,0,0,.Lduald,0,0,0
.Lduct: .long 0,.Laste,.Laste,0,.Lduald,0,0,0
.long 0,0,0,0,0,0,0,0
.Laste: .quad 0,0xffffffffffffffff,0,0,0,0,0,0
.align 128
.Lduald:.rept 8
.long 0x80000000,0,0,0 # invalid access-list entries
.endr
.Llinkage_stack:
.long 0,0,0x89000000,0,0,0,0x8a000000,0
ENTRY(_ehead)

View File

@ -130,7 +130,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)
int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
{
int code = (vcpu->arch.sie_block->ipb & 0xfff0000) >> 16;
int code = kvm_s390_get_base_disp_rs(vcpu) & 0xffff;
trace_kvm_s390_handle_diag(vcpu, code);
switch (code) {

View File

@ -12,6 +12,8 @@
#include <linux/mm.h>
#include <linux/gfp.h>
#include <linux/init.h>
#include <asm/setup.h>
#include <asm/ipl.h>
#define ESSA_SET_STABLE 1
#define ESSA_SET_UNUSED 2
@ -41,6 +43,14 @@ void __init cmma_init(void)
if (!cmma_flag)
return;
/*
* Disable CMM for dump, otherwise the tprot based memory
* detection can fail because of unstable pages.
*/
if (OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP) {
cmma_flag = 0;
return;
}
asm volatile(
" .insn rrf,0xb9ab0000,%1,%1,0,0\n"
"0: la %0,0\n"

View File

@ -335,14 +335,16 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
EMIT4_PCREL(0xa7840000, (jit->ret0_ip - jit->prg));
/* lhi %r4,0 */
EMIT4(0xa7480000);
/* dr %r4,%r12 */
EMIT2(0x1d4c);
/* dlr %r4,%r12 */
EMIT4(0xb997004c);
break;
case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K) */
/* m %r4,<d(K)>(%r13) */
EMIT4_DISP(0x5c40d000, EMIT_CONST(K));
/* lr %r5,%r4 */
EMIT2(0x1854);
case BPF_S_ALU_DIV_K: /* A /= K */
if (K == 1)
break;
/* lhi %r4,0 */
EMIT4(0xa7480000);
/* dl %r4,<d(K)>(%r13) */
EMIT6_DISP(0xe340d000, 0x0097, EMIT_CONST(K));
break;
case BPF_S_ALU_MOD_X: /* A %= X */
jit->seen |= SEEN_XREG | SEEN_RET0;
@ -352,16 +354,21 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
EMIT4_PCREL(0xa7840000, (jit->ret0_ip - jit->prg));
/* lhi %r4,0 */
EMIT4(0xa7480000);
/* dr %r4,%r12 */
EMIT2(0x1d4c);
/* dlr %r4,%r12 */
EMIT4(0xb997004c);
/* lr %r5,%r4 */
EMIT2(0x1854);
break;
case BPF_S_ALU_MOD_K: /* A %= K */
if (K == 1) {
/* lhi %r5,0 */
EMIT4(0xa7580000);
break;
}
/* lhi %r4,0 */
EMIT4(0xa7480000);
/* d %r4,<d(K)>(%r13) */
EMIT4_DISP(0x5d40d000, EMIT_CONST(K));
/* dl %r4,<d(K)>(%r13) */
EMIT6_DISP(0xe340d000, 0x0097, EMIT_CONST(K));
/* lr %r5,%r4 */
EMIT2(0x1854);
break;

View File

@ -13,6 +13,7 @@
#include <linux/kdebug.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/sched.h>
#include <asm/cacheflush.h>
#include <asm/traps.h>

View File

@ -497,9 +497,20 @@ void bpf_jit_compile(struct sk_filter *fp)
case BPF_S_ALU_MUL_K: /* A *= K */
emit_alu_K(MUL, K);
break;
case BPF_S_ALU_DIV_K: /* A /= K */
emit_alu_K(MUL, K);
emit_read_y(r_A);
case BPF_S_ALU_DIV_K: /* A /= K with K != 0*/
if (K == 1)
break;
emit_write_y(G0);
#ifdef CONFIG_SPARC32
/* The Sparc v8 architecture requires
* three instructions between a %y
* register write and the first use.
*/
emit_nop();
emit_nop();
emit_nop();
#endif
emit_alu_K(DIV, K);
break;
case BPF_S_ALU_DIV_X: /* A /= X; */
emit_cmpi(r_X, 0);

View File

@ -281,7 +281,6 @@ long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
u32 dummy, u32 low, u32 high);
long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count,
u32 dummy, u32 low, u32 high);
long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len);
long compat_sys_sync_file_range2(int fd, unsigned int flags,
u32 offset_lo, u32 offset_hi,
u32 nbytes_lo, u32 nbytes_hi);

View File

@ -119,9 +119,10 @@ static inline void setup_node_to_cpumask_map(void) { }
extern const struct cpumask *cpu_coregroup_mask(int cpu);
#ifdef ENABLE_TOPO_DEFINES
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
#ifdef ENABLE_TOPO_DEFINES
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))

View File

@ -79,30 +79,38 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
return get_phys_to_machine(pfn) != INVALID_P2M_ENTRY;
}
static inline unsigned long mfn_to_pfn(unsigned long mfn)
static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn)
{
unsigned long pfn;
int ret = 0;
int ret;
if (xen_feature(XENFEAT_auto_translated_physmap))
return mfn;
if (unlikely(mfn >= machine_to_phys_nr)) {
pfn = ~0;
goto try_override;
}
pfn = 0;
if (unlikely(mfn >= machine_to_phys_nr))
return ~0;
/*
* The array access can fail (e.g., device space beyond end of RAM).
* In such cases it doesn't matter what we return (we return garbage),
* but we must handle the fault without crashing!
*/
ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
try_override:
/* ret might be < 0 if there are no entries in the m2p for mfn */
if (ret < 0)
pfn = ~0;
else if (get_phys_to_machine(pfn) != mfn)
return ~0;
return pfn;
}
static inline unsigned long mfn_to_pfn(unsigned long mfn)
{
unsigned long pfn;
if (xen_feature(XENFEAT_auto_translated_physmap))
return mfn;
pfn = mfn_to_pfn_no_overrides(mfn);
if (get_phys_to_machine(pfn) != mfn) {
/*
* If this appears to be a foreign mfn (because the pfn
* doesn't map back to the mfn), then check the local override
@ -111,6 +119,7 @@ try_override:
* m2p_find_override_pfn returns ~0 if it doesn't find anything.
*/
pfn = m2p_find_override_pfn(mfn, ~0);
}
/*
* pfn is ~0 if there are no entries in the m2p for mfn or if the

View File

@ -179,6 +179,7 @@
#define MSR_AMD64_PATCH_LOADER 0xc0010020
#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
#define MSR_AMD64_OSVW_STATUS 0xc0010141
#define MSR_AMD64_LS_CFG 0xc0011020
#define MSR_AMD64_DC_CFG 0xc0011022
#define MSR_AMD64_BU_CFG2 0xc001102a
#define MSR_AMD64_IBSFETCHCTL 0xc0011030

View File

@ -508,6 +508,16 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
}
#endif
/* F16h erratum 793, CVE-2013-6885 */
if (c->x86 == 0x16 && c->x86_model <= 0xf) {
u64 val;
rdmsrl(MSR_AMD64_LS_CFG, val);
if (!(val & BIT(15)))
wrmsrl(MSR_AMD64_LS_CFG, val | BIT(15));
}
}
static const int amd_erratum_383[];

View File

@ -284,8 +284,13 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
raw_local_save_flags(eflags);
BUG_ON(eflags & X86_EFLAGS_AC);
if (cpu_has(c, X86_FEATURE_SMAP))
if (cpu_has(c, X86_FEATURE_SMAP)) {
#ifdef CONFIG_X86_SMAP
set_in_cr4(X86_CR4_SMAP);
#else
clear_in_cr4(X86_CR4_SMAP);
#endif
}
}
/*

View File

@ -628,7 +628,7 @@ static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c)
tlb_flushall_shift = 5;
break;
case 0x63a: /* Ivybridge */
tlb_flushall_shift = 1;
tlb_flushall_shift = 2;
break;
default:
tlb_flushall_shift = 6;

View File

@ -1165,6 +1165,9 @@ static void x86_pmu_del(struct perf_event *event, int flags)
for (i = 0; i < cpuc->n_events; i++) {
if (event == cpuc->event_list[i]) {
if (i >= cpuc->n_events - cpuc->n_added)
--cpuc->n_added;
if (x86_pmu.put_event_constraints)
x86_pmu.put_event_constraints(cpuc, event);

View File

@ -77,8 +77,7 @@ within(unsigned long addr, unsigned long start, unsigned long end)
return addr >= start && addr < end;
}
static int
do_ftrace_mod_code(unsigned long ip, const void *new_code)
static unsigned long text_ip_addr(unsigned long ip)
{
/*
* On x86_64, kernel text mappings are mapped read-only with
@ -91,7 +90,7 @@ do_ftrace_mod_code(unsigned long ip, const void *new_code)
if (within(ip, (unsigned long)_text, (unsigned long)_etext))
ip = (unsigned long)__va(__pa_symbol(ip));
return probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE);
return ip;
}
static const unsigned char *ftrace_nop_replace(void)
@ -123,8 +122,10 @@ ftrace_modify_code_direct(unsigned long ip, unsigned const char *old_code,
if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
return -EINVAL;
ip = text_ip_addr(ip);
/* replace the text with the new text */
if (do_ftrace_mod_code(ip, new_code))
if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))
return -EPERM;
sync_core();
@ -221,37 +222,51 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
return -EINVAL;
}
int ftrace_update_ftrace_func(ftrace_func_t func)
static unsigned long ftrace_update_func;
static int update_ftrace_func(unsigned long ip, void *new)
{
unsigned long ip = (unsigned long)(&ftrace_call);
unsigned char old[MCOUNT_INSN_SIZE], *new;
unsigned char old[MCOUNT_INSN_SIZE];
int ret;
memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
new = ftrace_call_replace(ip, (unsigned long)func);
memcpy(old, (void *)ip, MCOUNT_INSN_SIZE);
ftrace_update_func = ip;
/* Make sure the breakpoints see the ftrace_update_func update */
smp_wmb();
/* See comment above by declaration of modifying_ftrace_code */
atomic_inc(&modifying_ftrace_code);
ret = ftrace_modify_code(ip, old, new);
atomic_dec(&modifying_ftrace_code);
return ret;
}
int ftrace_update_ftrace_func(ftrace_func_t func)
{
unsigned long ip = (unsigned long)(&ftrace_call);
unsigned char *new;
int ret;
new = ftrace_call_replace(ip, (unsigned long)func);
ret = update_ftrace_func(ip, new);
/* Also update the regs callback function */
if (!ret) {
ip = (unsigned long)(&ftrace_regs_call);
memcpy(old, &ftrace_regs_call, MCOUNT_INSN_SIZE);
new = ftrace_call_replace(ip, (unsigned long)func);
ret = ftrace_modify_code(ip, old, new);
ret = update_ftrace_func(ip, new);
}
atomic_dec(&modifying_ftrace_code);
return ret;
}
static int is_ftrace_caller(unsigned long ip)
{
if (ip == (unsigned long)(&ftrace_call) ||
ip == (unsigned long)(&ftrace_regs_call))
if (ip == ftrace_update_func)
return 1;
return 0;
@ -677,45 +692,41 @@ int __init ftrace_dyn_arch_init(void *data)
#ifdef CONFIG_DYNAMIC_FTRACE
extern void ftrace_graph_call(void);
static int ftrace_mod_jmp(unsigned long ip,
int old_offset, int new_offset)
static unsigned char *ftrace_jmp_replace(unsigned long ip, unsigned long addr)
{
unsigned char code[MCOUNT_INSN_SIZE];
static union ftrace_code_union calc;
if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
return -EFAULT;
/* Jmp not a call (ignore the .e8) */
calc.e8 = 0xe9;
calc.offset = ftrace_calc_offset(ip + MCOUNT_INSN_SIZE, addr);
if (code[0] != 0xe9 || old_offset != *(int *)(&code[1]))
return -EINVAL;
/*
* ftrace external locks synchronize the access to the static variable.
*/
return calc.code;
}
*(int *)(&code[1]) = new_offset;
static int ftrace_mod_jmp(unsigned long ip, void *func)
{
unsigned char *new;
if (do_ftrace_mod_code(ip, &code))
return -EPERM;
new = ftrace_jmp_replace(ip, (unsigned long)func);
return 0;
return update_ftrace_func(ip, new);
}
int ftrace_enable_ftrace_graph_caller(void)
{
unsigned long ip = (unsigned long)(&ftrace_graph_call);
int old_offset, new_offset;
old_offset = (unsigned long)(&ftrace_stub) - (ip + MCOUNT_INSN_SIZE);
new_offset = (unsigned long)(&ftrace_graph_caller) - (ip + MCOUNT_INSN_SIZE);
return ftrace_mod_jmp(ip, old_offset, new_offset);
return ftrace_mod_jmp(ip, &ftrace_graph_caller);
}
int ftrace_disable_ftrace_graph_caller(void)
{
unsigned long ip = (unsigned long)(&ftrace_graph_call);
int old_offset, new_offset;
old_offset = (unsigned long)(&ftrace_graph_caller) - (ip + MCOUNT_INSN_SIZE);
new_offset = (unsigned long)(&ftrace_stub) - (ip + MCOUNT_INSN_SIZE);
return ftrace_mod_jmp(ip, old_offset, new_offset);
return ftrace_mod_jmp(ip, &ftrace_stub);
}
#endif /* !CONFIG_DYNAMIC_FTRACE */

View File

@ -566,6 +566,10 @@ ENDPROC(early_idt_handlers)
/* This is global to keep gas from relaxing the jumps */
ENTRY(early_idt_handler)
cld
cmpl $2,(%esp) # X86_TRAP_NMI
je is_nmi # Ignore NMI
cmpl $2,%ss:early_recursion_flag
je hlt_loop
incl %ss:early_recursion_flag
@ -616,8 +620,9 @@ ex_entry:
pop %edx
pop %ecx
pop %eax
addl $8,%esp /* drop vector number and error code */
decl %ss:early_recursion_flag
is_nmi:
addl $8,%esp /* drop vector number and error code */
iret
ENDPROC(early_idt_handler)

View File

@ -343,6 +343,9 @@ early_idt_handlers:
ENTRY(early_idt_handler)
cld
cmpl $2,(%rsp) # X86_TRAP_NMI
je is_nmi # Ignore NMI
cmpl $2,early_recursion_flag(%rip)
jz 1f
incl early_recursion_flag(%rip)
@ -405,8 +408,9 @@ ENTRY(early_idt_handler)
popq %rdx
popq %rcx
popq %rax
addq $16,%rsp # drop vector number and error code
decl early_recursion_flag(%rip)
is_nmi:
addq $16,%rsp # drop vector number and error code
INTERRUPT_RETURN
ENDPROC(early_idt_handler)

View File

@ -86,10 +86,19 @@ EXPORT_SYMBOL(__kernel_fpu_begin);
void __kernel_fpu_end(void)
{
if (use_eager_fpu())
math_state_restore();
else
if (use_eager_fpu()) {
/*
* For eager fpu, most the time, tsk_used_math() is true.
* Restore the user math as we are done with the kernel usage.
* At few instances during thread exit, signal handling etc,
* tsk_used_math() is false. Those few places will take proper
* actions, so we don't need to restore the math here.
*/
if (likely(tsk_used_math(current)))
math_state_restore();
} else {
stts();
}
}
EXPORT_SYMBOL(__kernel_fpu_end);

View File

@ -100,8 +100,10 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
flag |= __GFP_ZERO;
again:
page = NULL;
if (!(flag & GFP_ATOMIC))
/* CMA can be used only in the context which permits sleeping */
if (flag & __GFP_WAIT)
page = dma_alloc_from_contiguous(dev, count, get_order(size));
/* fallback */
if (!page)
page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));
if (!page)

View File

@ -529,7 +529,7 @@ static void quirk_amd_nb_node(struct pci_dev *dev)
return;
pci_read_config_dword(nb_ht, 0x60, &val);
node = val & 7;
node = pcibus_to_node(dev->bus) | (val & 7);
/*
* Some hardware may return an invalid node ID,
* so check it first:

View File

@ -37,6 +37,7 @@
#include "irq.h"
#include "i8254.h"
#include "x86.h"
#ifndef CONFIG_X86_64
#define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
@ -349,6 +350,23 @@ static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
atomic_set(&ps->pending, 0);
ps->irq_ack = 1;
/*
* Do not allow the guest to program periodic timers with small
* interval, since the hrtimers are not throttled by the host
* scheduler.
*/
if (ps->is_periodic) {
s64 min_period = min_timer_period_us * 1000LL;
if (ps->period < min_period) {
pr_info_ratelimited(
"kvm: requested %lld ns "
"i8254 timer period limited to %lld ns\n",
ps->period, min_period);
ps->period = min_period;
}
}
hrtimer_start(&ps->timer, ktime_add_ns(ktime_get(), interval),
HRTIMER_MODE_ABS);
}

View File

@ -71,9 +71,6 @@
#define VEC_POS(v) ((v) & (32 - 1))
#define REG_POS(v) (((v) >> 5) << 4)
static unsigned int min_timer_period_us = 500;
module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR);
static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val)
{
*((u32 *) (apic->regs + reg_off)) = val;
@ -1369,7 +1366,7 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
vcpu->arch.apic_base = value;
/* update jump label if enable bit changes */
if ((vcpu->arch.apic_base ^ value) & MSR_IA32_APICBASE_ENABLE) {
if ((old_value ^ value) & MSR_IA32_APICBASE_ENABLE) {
if (value & MSR_IA32_APICBASE_ENABLE)
static_key_slow_dec_deferred(&apic_hw_disabled);
else

View File

@ -2585,6 +2585,9 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
int emulate = 0;
gfn_t pseudo_gfn;
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return 0;
for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
if (iterator.level == level) {
mmu_set_spte(vcpu, iterator.sptep, ACC_ALL,
@ -2748,6 +2751,9 @@ static bool fast_page_fault(struct kvm_vcpu *vcpu, gva_t gva, int level,
bool ret = false;
u64 spte = 0ull;
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return false;
if (!page_fault_can_be_fast(vcpu, error_code))
return false;
@ -3139,6 +3145,9 @@ static u64 walk_shadow_page_get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr)
struct kvm_shadow_walk_iterator iterator;
u64 spte = 0ull;
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return spte;
walk_shadow_page_lockless_begin(vcpu);
for_each_shadow_entry_lockless(vcpu, addr, iterator, spte)
if (!is_shadow_present_pte(spte))
@ -4329,6 +4338,9 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
u64 spte;
int nr_sptes = 0;
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return nr_sptes;
walk_shadow_page_lockless_begin(vcpu);
for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
sptes[iterator.level-1] = spte;

View File

@ -423,6 +423,9 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
if (FNAME(gpte_changed)(vcpu, gw, top_level))
goto out_gpte_changed;
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
goto out_gpte_changed;
for (shadow_walk_init(&it, vcpu, addr);
shadow_walk_okay(&it) && it.level > gw->level;
shadow_walk_next(&it)) {
@ -671,6 +674,11 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
*/
mmu_topup_memory_caches(vcpu);
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) {
WARN_ON(1);
return;
}
spin_lock(&vcpu->kvm->mmu_lock);
for_each_shadow_entry(vcpu, gva, iterator) {
level = iterator.level;

View File

@ -2985,10 +2985,8 @@ static int cr8_write_interception(struct vcpu_svm *svm)
u8 cr8_prev = kvm_get_cr8(&svm->vcpu);
/* instruction emulation calls kvm_set_cr8() */
r = cr_interception(svm);
if (irqchip_in_kernel(svm->vcpu.kvm)) {
clr_cr_intercept(svm, INTERCEPT_CR8_WRITE);
if (irqchip_in_kernel(svm->vcpu.kvm))
return r;
}
if (cr8_prev <= kvm_get_cr8(&svm->vcpu))
return r;
kvm_run->exit_reason = KVM_EXIT_SET_TPR;
@ -3550,6 +3548,8 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK))
return;
clr_cr_intercept(svm, INTERCEPT_CR8_WRITE);
if (irr == -1)
return;

View File

@ -7133,8 +7133,8 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
struct vcpu_vmx *vmx = to_vmx(vcpu);
free_vpid(vmx);
free_nested(vmx);
free_loaded_vmcs(vmx->loaded_vmcs);
free_nested(vmx);
kfree(vmx->guest_msrs);
kvm_vcpu_uninit(vcpu);
kmem_cache_free(kvm_vcpu_cache, vmx);

View File

@ -94,6 +94,9 @@ EXPORT_SYMBOL_GPL(kvm_x86_ops);
static bool ignore_msrs = 0;
module_param(ignore_msrs, bool, S_IRUGO | S_IWUSR);
unsigned int min_timer_period_us = 500;
module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR);
bool kvm_has_tsc_control;
EXPORT_SYMBOL_GPL(kvm_has_tsc_control);
u32 kvm_max_guest_tsc_khz;
@ -5979,7 +5982,7 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu)
frag->len -= len;
}
if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) {
if (vcpu->mmio_cur_fragment >= vcpu->mmio_nr_fragments) {
vcpu->mmio_needed = 0;
if (vcpu->mmio_is_write)
return 1;

View File

@ -124,5 +124,7 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
extern u64 host_xcr0;
extern unsigned int min_timer_period_us;
extern struct static_key kvm_no_apic_vcpu;
#endif

View File

@ -989,6 +989,12 @@ static int fault_in_kernel_space(unsigned long address)
static inline bool smap_violation(int error_code, struct pt_regs *regs)
{
if (!IS_ENABLED(CONFIG_X86_SMAP))
return false;
if (!static_cpu_has(X86_FEATURE_SMAP))
return false;
if (error_code & PF_USER)
return false;
@ -1090,11 +1096,9 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (unlikely(error_code & PF_RSVD))
pgtable_bad(regs, error_code, address);
if (static_cpu_has(X86_FEATURE_SMAP)) {
if (unlikely(smap_violation(error_code, regs))) {
bad_area_nosemaphore(regs, error_code, address);
return;
}
if (unlikely(smap_violation(error_code, regs))) {
bad_area_nosemaphore(regs, error_code, address);
return;
}
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);

View File

@ -140,7 +140,7 @@ bpf_slow_path_byte_msh:
push %r9; \
push SKBDATA; \
/* rsi already has offset */ \
mov $SIZE,%ecx; /* size */ \
mov $SIZE,%edx; /* size */ \
call bpf_internal_load_pointer_neg_helper; \
test %rax,%rax; \
pop SKBDATA; \

View File

@ -324,15 +324,21 @@ void bpf_jit_compile(struct sk_filter *fp)
EMIT2(0x89, 0xd0); /* mov %edx,%eax */
break;
case BPF_S_ALU_MOD_K: /* A %= K; */
if (K == 1) {
CLEAR_A();
break;
}
EMIT2(0x31, 0xd2); /* xor %edx,%edx */
EMIT1(0xb9);EMIT(K, 4); /* mov imm32,%ecx */
EMIT2(0xf7, 0xf1); /* div %ecx */
EMIT2(0x89, 0xd0); /* mov %edx,%eax */
break;
case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */
EMIT(K, 4);
EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */
case BPF_S_ALU_DIV_K: /* A /= K */
if (K == 1)
break;
EMIT2(0x31, 0xd2); /* xor %edx,%edx */
EMIT1(0xb9);EMIT(K, 4); /* mov imm32,%ecx */
EMIT2(0xf7, 0xf1); /* div %ecx */
break;
case BPF_S_ALU_AND_X:
seen |= SEEN_XREG;

View File

@ -438,7 +438,7 @@ void __init efi_reserve_boot_services(void)
* - Not within any part of the kernel
* - Not the bios reserved area
*/
if ((start+size >= __pa_symbol(_text)
if ((start + size > __pa_symbol(_text)
&& start <= __pa_symbol(_end)) ||
!e820_all_mapped(start, start+size, E820_RAM) ||
memblock_is_region_reserved(start, size)) {

View File

@ -878,7 +878,6 @@ int m2p_add_override(unsigned long mfn, struct page *page,
unsigned long uninitialized_var(address);
unsigned level;
pte_t *ptep = NULL;
int ret = 0;
pfn = page_to_pfn(page);
if (!PageHighMem(page)) {
@ -925,8 +924,8 @@ int m2p_add_override(unsigned long mfn, struct page *page,
* frontend pages while they are being shared with the backend,
* because mfn_to_pfn (that ends up being called by GUPF) will
* return the backend pfn rather than the frontend pfn. */
ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
if (ret == 0 && get_phys_to_machine(pfn) == mfn)
pfn = mfn_to_pfn_no_overrides(mfn);
if (get_phys_to_machine(pfn) == mfn)
set_phys_to_machine(pfn, FOREIGN_FRAME(mfn));
return 0;
@ -941,7 +940,6 @@ int m2p_remove_override(struct page *page,
unsigned long uninitialized_var(address);
unsigned level;
pte_t *ptep = NULL;
int ret = 0;
pfn = page_to_pfn(page);
mfn = get_phys_to_machine(pfn);
@ -1019,8 +1017,8 @@ int m2p_remove_override(struct page *page,
* the original pfn causes mfn_to_pfn(mfn) to return the frontend
* pfn again. */
mfn &= ~FOREIGN_FRAME_BIT;
ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
if (ret == 0 && get_phys_to_machine(pfn) == FOREIGN_FRAME(mfn) &&
pfn = mfn_to_pfn_no_overrides(mfn);
if (get_phys_to_machine(pfn) == FOREIGN_FRAME(mfn) &&
m2p_find_override(mfn) == NULL)
set_phys_to_machine(pfn, mfn);

View File

@ -245,6 +245,15 @@ static void __init xen_smp_prepare_boot_cpu(void)
old memory can be recycled */
make_lowmem_page_readwrite(xen_initial_gdt);
#ifdef CONFIG_X86_32
/*
* Xen starts us with XEN_FLAT_RING1_DS, but linux code
* expects __USER_DS
*/
loadsegment(ds, __USER_DS);
loadsegment(es, __USER_DS);
#endif
xen_filter_cpu_maps();
xen_setup_vcpu_info_placement();
}

View File

@ -22,25 +22,37 @@ extern void do_unhandled(struct pt_regs *regs, unsigned long exccause);
static inline void spill_registers(void)
{
#if XCHAL_NUM_AREGS > 16
__asm__ __volatile__ (
"movi a14, "__stringify((1 << PS_EXCM_BIT) | LOCKLEVEL)"\n\t"
"mov a12, a0\n\t"
"rsr a13, sar\n\t"
"xsr a14, ps\n\t"
"movi a0, _spill_registers\n\t"
"rsync\n\t"
"callx0 a0\n\t"
"mov a0, a12\n\t"
"wsr a13, sar\n\t"
"wsr a14, ps\n\t"
: :
#if defined(CONFIG_FRAME_POINTER)
: "a2", "a3", "a4", "a11", "a12", "a13", "a14", "a15",
#else
: "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15",
" call12 1f\n"
" _j 2f\n"
" retw\n"
" .align 4\n"
"1:\n"
" _entry a1, 48\n"
" addi a12, a0, 3\n"
#if XCHAL_NUM_AREGS > 32
" .rept (" __stringify(XCHAL_NUM_AREGS) " - 32) / 12\n"
" _entry a1, 48\n"
" mov a12, a0\n"
" .endr\n"
#endif
" _entry a1, 48\n"
#if XCHAL_NUM_AREGS % 12 == 0
" mov a8, a8\n"
#elif XCHAL_NUM_AREGS % 12 == 4
" mov a12, a12\n"
#elif XCHAL_NUM_AREGS % 12 == 8
" mov a4, a4\n"
#endif
" retw\n"
"2:\n"
: : : "a12", "a13", "memory");
#else
__asm__ __volatile__ (
" mov a12, a12\n"
: : : "memory");
#endif
"memory");
}
#endif /* _XTENSA_TRAPS_H */

View File

@ -1912,6 +1912,43 @@ ENTRY(system_call)
ENDPROC(system_call)
/*
* Spill live registers on the kernel stack macro.
*
* Entry condition: ps.woe is set, ps.excm is cleared
* Exit condition: windowstart has single bit set
* May clobber: a12, a13
*/
.macro spill_registers_kernel
#if XCHAL_NUM_AREGS > 16
call12 1f
_j 2f
retw
.align 4
1:
_entry a1, 48
addi a12, a0, 3
#if XCHAL_NUM_AREGS > 32
.rept (XCHAL_NUM_AREGS - 32) / 12
_entry a1, 48
mov a12, a0
.endr
#endif
_entry a1, 48
#if XCHAL_NUM_AREGS % 12 == 0
mov a8, a8
#elif XCHAL_NUM_AREGS % 12 == 4
mov a12, a12
#elif XCHAL_NUM_AREGS % 12 == 8
mov a4, a4
#endif
retw
2:
#else
mov a12, a12
#endif
.endm
/*
* Task switch.
@ -1924,21 +1961,20 @@ ENTRY(_switch_to)
entry a1, 16
mov a12, a2 # preserve 'prev' (a2)
mov a13, a3 # and 'next' (a3)
mov a10, a2 # preserve 'prev' (a2)
mov a11, a3 # and 'next' (a3)
l32i a4, a2, TASK_THREAD_INFO
l32i a5, a3, TASK_THREAD_INFO
save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
s32i a0, a12, THREAD_RA # save return address
s32i a1, a12, THREAD_SP # save stack pointer
s32i a0, a10, THREAD_RA # save return address
s32i a1, a10, THREAD_SP # save stack pointer
/* Disable ints while we manipulate the stack pointer. */
movi a14, (1 << PS_EXCM_BIT) | LOCKLEVEL
xsr a14, ps
rsil a14, LOCKLEVEL
rsr a3, excsave1
rsync
s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */
@ -1953,7 +1989,7 @@ ENTRY(_switch_to)
/* Flush register file. */
call0 _spill_registers # destroys a3, a4, and SAR
spill_registers_kernel
/* Set kernel stack (and leave critical section)
* Note: It's save to set it here. The stack will not be overwritten
@ -1969,13 +2005,13 @@ ENTRY(_switch_to)
/* restore context of the task 'next' */
l32i a0, a13, THREAD_RA # restore return address
l32i a1, a13, THREAD_SP # restore stack pointer
l32i a0, a11, THREAD_RA # restore return address
l32i a1, a11, THREAD_SP # restore stack pointer
load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
wsr a14, ps
mov a2, a12 # return 'prev'
mov a2, a10 # return 'prev'
rsync
retw

View File

@ -195,7 +195,7 @@ void platform_calibrate_ccount(void)
* Ethernet -- OpenCores Ethernet MAC (ethoc driver)
*/
static struct resource ethoc_res[] __initdata = {
static struct resource ethoc_res[] = {
[0] = { /* register space */
.start = OETH_REGS_PADDR,
.end = OETH_REGS_PADDR + OETH_REGS_SIZE - 1,
@ -213,7 +213,7 @@ static struct resource ethoc_res[] __initdata = {
},
};
static struct ethoc_platform_data ethoc_pdata __initdata = {
static struct ethoc_platform_data ethoc_pdata = {
/*
* The MAC address for these boards is 00:50:c2:13:6f:xx.
* The last byte (here as zero) is read from the DIP switches on the
@ -223,7 +223,7 @@ static struct ethoc_platform_data ethoc_pdata __initdata = {
.phy_id = -1,
};
static struct platform_device ethoc_device __initdata = {
static struct platform_device ethoc_device = {
.name = "ethoc",
.id = -1,
.num_resources = ARRAY_SIZE(ethoc_res),
@ -237,13 +237,13 @@ static struct platform_device ethoc_device __initdata = {
* UART
*/
static struct resource serial_resource __initdata = {
static struct resource serial_resource = {
.start = DUART16552_PADDR,
.end = DUART16552_PADDR + 0x1f,
.flags = IORESOURCE_MEM,
};
static struct plat_serial8250_port serial_platform_data[] __initdata = {
static struct plat_serial8250_port serial_platform_data[] = {
[0] = {
.mapbase = DUART16552_PADDR,
.irq = DUART16552_INTNUM,
@ -256,7 +256,7 @@ static struct plat_serial8250_port serial_platform_data[] __initdata = {
{ },
};
static struct platform_device xtavnet_uart __initdata = {
static struct platform_device xtavnet_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {

View File

@ -121,6 +121,14 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
atomic_inc(&bb.done);
submit_bio(type, bio);
/*
* We can loop for a long time in here, if someone does
* full device discards (like mkfs). Be nice and allow
* us to schedule out to avoid softlocking if preempt
* is disabled.
*/
cond_resched();
}
blk_finish_plug(&plug);

View File

@ -96,7 +96,7 @@ static inline struct request *__elv_next_request(struct request_queue *q)
q->flush_queue_delayed = 1;
return NULL;
}
if (unlikely(blk_queue_dying(q)) ||
if (unlikely(blk_queue_bypass(q)) ||
!q->elevator->type->ops.elevator_dispatch_fn(q, 0))
return NULL;
}

View File

@ -33,6 +33,7 @@
#include <linux/proc_fs.h>
#include <linux/acpi.h>
#include <linux/slab.h>
#include <linux/regulator/machine.h>
#ifdef CONFIG_X86
#include <asm/mpspec.h>
#endif
@ -705,6 +706,14 @@ void __init acpi_early_init(void)
goto error0;
}
/*
* If the system is using ACPI then we can be reasonably
* confident that any regulators are managed by the firmware
* so tell the regulator core it has everything it needs to
* know.
*/
regulator_has_full_constraints();
return;
error0:

View File

@ -432,6 +432,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
pin_name(pin));
}
kfree(entry);
return 0;
}

View File

@ -59,6 +59,12 @@ struct throttling_tstate {
int target_state; /* target T-state */
};
struct acpi_processor_throttling_arg {
struct acpi_processor *pr;
int target_state;
bool force;
};
#define THROTTLING_PRECHANGE (1)
#define THROTTLING_POSTCHANGE (2)
@ -1063,16 +1069,24 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
return 0;
}
static long acpi_processor_throttling_fn(void *data)
{
struct acpi_processor_throttling_arg *arg = data;
struct acpi_processor *pr = arg->pr;
return pr->throttling.acpi_processor_set_throttling(pr,
arg->target_state, arg->force);
}
int acpi_processor_set_throttling(struct acpi_processor *pr,
int state, bool force)
{
cpumask_var_t saved_mask;
int ret = 0;
unsigned int i;
struct acpi_processor *match_pr;
struct acpi_processor_throttling *p_throttling;
struct acpi_processor_throttling_arg arg;
struct throttling_tstate t_state;
cpumask_var_t online_throttling_cpus;
if (!pr)
return -EINVAL;
@ -1083,14 +1097,6 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
if ((state < 0) || (state > (pr->throttling.state_count - 1)))
return -EINVAL;
if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
return -ENOMEM;
if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL)) {
free_cpumask_var(saved_mask);
return -ENOMEM;
}
if (cpu_is_offline(pr->id)) {
/*
* the cpu pointed by pr->id is offline. Unnecessary to change
@ -1099,17 +1105,15 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
return -ENODEV;
}
cpumask_copy(saved_mask, &current->cpus_allowed);
t_state.target_state = state;
p_throttling = &(pr->throttling);
cpumask_and(online_throttling_cpus, cpu_online_mask,
p_throttling->shared_cpu_map);
/*
* The throttling notifier will be called for every
* affected cpu in order to get one proper T-state.
* The notifier event is THROTTLING_PRECHANGE.
*/
for_each_cpu(i, online_throttling_cpus) {
for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) {
t_state.cpu = i;
acpi_processor_throttling_notifier(THROTTLING_PRECHANGE,
&t_state);
@ -1121,21 +1125,18 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
* it can be called only for the cpu pointed by pr.
*/
if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
/* FIXME: use work_on_cpu() */
if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
/* Can't migrate to the pr->id CPU. Exit */
ret = -ENODEV;
goto exit;
}
ret = p_throttling->acpi_processor_set_throttling(pr,
t_state.target_state, force);
arg.pr = pr;
arg.target_state = state;
arg.force = force;
ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg);
} else {
/*
* When the T-state coordination is SW_ALL or HW_ALL,
* it is necessary to set T-state for every affected
* cpus.
*/
for_each_cpu(i, online_throttling_cpus) {
for_each_cpu_and(i, cpu_online_mask,
p_throttling->shared_cpu_map) {
match_pr = per_cpu(processors, i);
/*
* If the pointer is invalid, we will report the
@ -1156,13 +1157,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
"on CPU %d\n", i));
continue;
}
t_state.cpu = i;
/* FIXME: use work_on_cpu() */
if (set_cpus_allowed_ptr(current, cpumask_of(i)))
continue;
ret = match_pr->throttling.
acpi_processor_set_throttling(
match_pr, t_state.target_state, force);
arg.pr = match_pr;
arg.target_state = state;
arg.force = force;
ret = work_on_cpu(pr->id, acpi_processor_throttling_fn,
&arg);
}
}
/*
@ -1171,17 +1171,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
* affected cpu to update the T-states.
* The notifier event is THROTTLING_POSTCHANGE
*/
for_each_cpu(i, online_throttling_cpus) {
for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) {
t_state.cpu = i;
acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE,
&t_state);
}
/* restore the previous state */
/* FIXME: use work_on_cpu() */
set_cpus_allowed_ptr(current, saved_mask);
exit:
free_cpumask_var(online_throttling_cpus);
free_cpumask_var(saved_mask);
return ret;
}

View File

@ -77,18 +77,24 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
switch (ares->type) {
case ACPI_RESOURCE_TYPE_MEMORY24:
memory24 = &ares->data.memory24;
if (!memory24->address_length)
return false;
acpi_dev_get_memresource(res, memory24->minimum,
memory24->address_length,
memory24->write_protect);
break;
case ACPI_RESOURCE_TYPE_MEMORY32:
memory32 = &ares->data.memory32;
if (!memory32->address_length)
return false;
acpi_dev_get_memresource(res, memory32->minimum,
memory32->address_length,
memory32->write_protect);
break;
case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
fixed_memory32 = &ares->data.fixed_memory32;
if (!fixed_memory32->address_length)
return false;
acpi_dev_get_memresource(res, fixed_memory32->address,
fixed_memory32->address_length,
fixed_memory32->write_protect);
@ -144,12 +150,16 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
switch (ares->type) {
case ACPI_RESOURCE_TYPE_IO:
io = &ares->data.io;
if (!io->address_length)
return false;
acpi_dev_get_ioresource(res, io->minimum,
io->address_length,
io->io_decode);
break;
case ACPI_RESOURCE_TYPE_FIXED_IO:
fixed_io = &ares->data.fixed_io;
if (!fixed_io->address_length)
return false;
acpi_dev_get_ioresource(res, fixed_io->address,
fixed_io->address_length,
ACPI_DECODE_10);

View File

@ -78,6 +78,17 @@ static int acpi_sleep_prepare(u32 acpi_state)
return 0;
}
static bool acpi_sleep_state_supported(u8 sleep_state)
{
acpi_status status;
u8 type_a, type_b;
status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b);
return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware
|| (acpi_gbl_FADT.sleep_control.address
&& acpi_gbl_FADT.sleep_status.address));
}
#ifdef CONFIG_ACPI_SLEEP
static u32 acpi_target_sleep_state = ACPI_STATE_S0;
@ -600,15 +611,9 @@ static void acpi_sleep_suspend_setup(void)
{
int i;
for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) {
acpi_status status;
u8 type_a, type_b;
status = acpi_get_sleep_type_data(i, &type_a, &type_b);
if (ACPI_SUCCESS(status)) {
for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++)
if (acpi_sleep_state_supported(i))
sleep_states[i] = 1;
}
}
suspend_set_ops(old_suspend_ordering ?
&acpi_suspend_ops_old : &acpi_suspend_ops);
@ -739,11 +744,7 @@ static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
static void acpi_sleep_hibernate_setup(void)
{
acpi_status status;
u8 type_a, type_b;
status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b);
if (ACPI_FAILURE(status))
if (!acpi_sleep_state_supported(ACPI_STATE_S4))
return;
hibernation_set_ops(old_suspend_ordering ?
@ -792,8 +793,6 @@ static void acpi_power_off(void)
int __init acpi_sleep_init(void)
{
acpi_status status;
u8 type_a, type_b;
char supported[ACPI_S_STATE_COUNT * 3 + 1];
char *pos = supported;
int i;
@ -808,8 +807,7 @@ int __init acpi_sleep_init(void)
acpi_sleep_suspend_setup();
acpi_sleep_hibernate_setup();
status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
if (ACPI_SUCCESS(status)) {
if (acpi_sleep_state_supported(ACPI_STATE_S5)) {
sleep_states[ACPI_STATE_S5] = 1;
pm_power_off_prepare = acpi_power_off_prepare;
pm_power_off = acpi_power_off;

View File

@ -733,6 +733,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
union acpi_object *o;
struct acpi_video_device_brightness *br = NULL;
int result = -EINVAL;
u32 value;
if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@ -763,7 +764,12 @@ acpi_video_init_brightness(struct acpi_video_device *device)
printk(KERN_ERR PREFIX "Invalid data\n");
continue;
}
br->levels[count] = (u32) o->integer.value;
value = (u32) o->integer.value;
/* Skip duplicate entries */
if (count > 2 && br->levels[count - 1] == value)
continue;
br->levels[count] = value;
if (br->levels[count] > max_level)
max_level = br->levels[count];

View File

@ -61,6 +61,7 @@ enum board_ids {
/* board IDs by feature in alphabetical order */
board_ahci,
board_ahci_ign_iferr,
board_ahci_noncq,
board_ahci_nosntf,
board_ahci_yes_fbs,
@ -119,6 +120,13 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
[board_ahci_noncq] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
[board_ahci_nosntf] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_SNTF),
.flags = AHCI_FLAG_COMMON,
@ -450,6 +458,12 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */
{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */
/*
* Samsung SSDs found on some macbooks. NCQ times out.
* https://bugzilla.kernel.org/show_bug.cgi?id=60731
*/
{ PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq },
/* Enmotus */
{ PCI_DEVICE(0x1c44, 0x8000), board_ahci },

View File

@ -2199,6 +2199,16 @@ int ata_dev_configure(struct ata_device *dev)
if (rc)
return rc;
/* some WD SATA-1 drives have issues with LPM, turn on NOLPM for them */
if ((dev->horkage & ATA_HORKAGE_WD_BROKEN_LPM) &&
(id[ATA_ID_SATA_CAPABILITY] & 0xe) == 0x2)
dev->horkage |= ATA_HORKAGE_NOLPM;
if (dev->horkage & ATA_HORKAGE_NOLPM) {
ata_dev_warn(dev, "LPM support broken, forcing max_power\n");
dev->link->ap->target_lpm_policy = ATA_LPM_MAX_POWER;
}
/* let ACPI work its magic */
rc = ata_acpi_on_devcfg(dev);
if (rc)
@ -4142,6 +4152,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
/* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */
{ "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA },
{ "ST1000LM024 HN-M101MBB", "2BA30001", ATA_HORKAGE_BROKEN_FPDMA_AA },
/* Blacklist entries taken from Silicon Image 3124/3132
Windows driver .inf file - also several Linux problem reports */
@ -4189,6 +4200,23 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER },
{ "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER },
/*
* Some WD SATA-I drives spin up and down erratically when the link
* is put into the slumber mode. We don't have full list of the
* affected devices. Disable LPM if the device matches one of the
* known prefixes and is SATA-1. As a side effect LPM partial is
* lost too.
*
* https://bugzilla.kernel.org/show_bug.cgi?id=57211
*/
{ "WDC WD800JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM },
{ "WDC WD1200JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM },
{ "WDC WD1600JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM },
{ "WDC WD2000JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM },
{ "WDC WD2500JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM },
{ "WDC WD3000JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM },
{ "WDC WD3200JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM },
/* End Marker */
{ }
};

View File

@ -447,8 +447,11 @@ static void sata_pmp_quirks(struct ata_port *ap)
* otherwise. Don't try hard to recover it.
*/
ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY;
} else if (vendor == 0x197b && devid == 0x2352) {
/* chip found in Thermaltake BlackX Duet, jmicron JMB350? */
} else if (vendor == 0x197b && (devid == 0x2352 || devid == 0x0325)) {
/*
* 0x2352: found in Thermaltake BlackX Duet, jmicron JMB350?
* 0x0325: jmicron JMB394.
*/
ata_for_each_link(link, ap, EDGE) {
/* SRST breaks detection and disks get misclassified
* LPM disabled to avoid potential problems

View File

@ -112,12 +112,14 @@ static const char *ata_lpm_policy_names[] = {
[ATA_LPM_MIN_POWER] = "min_power",
};
static ssize_t ata_scsi_lpm_store(struct device *dev,
static ssize_t ata_scsi_lpm_store(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct Scsi_Host *shost = class_to_shost(device);
struct ata_port *ap = ata_shost_to_port(shost);
struct ata_link *link;
struct ata_device *dev;
enum ata_lpm_policy policy;
unsigned long flags;
@ -133,10 +135,20 @@ static ssize_t ata_scsi_lpm_store(struct device *dev,
return -EINVAL;
spin_lock_irqsave(ap->lock, flags);
ata_for_each_link(link, ap, EDGE) {
ata_for_each_dev(dev, &ap->link, ENABLED) {
if (dev->horkage & ATA_HORKAGE_NOLPM) {
count = -EOPNOTSUPP;
goto out_unlock;
}
}
}
ap->target_lpm_policy = policy;
ata_port_schedule_eh(ap);
out_unlock:
spin_unlock_irqrestore(ap->lock, flags);
return count;
}

View File

@ -304,6 +304,7 @@ enum {
MV5_LTMODE = 0x30,
MV5_PHY_CTL = 0x0C,
SATA_IFCFG = 0x050,
LP_PHY_CTL = 0x058,
MV_M2_PREAMP_MASK = 0x7e0,
@ -431,6 +432,7 @@ enum {
MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */
MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */
MV_HP_QUIRK_LED_BLINK_EN = (1 << 12), /* is led blinking enabled? */
MV_HP_FIX_LP_PHY_CTL = (1 << 13), /* fix speed in LP_PHY_CTL ? */
/* Port private flags (pp_flags) */
MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */
@ -1353,6 +1355,7 @@ static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val)
if (ofs != 0xffffffffU) {
void __iomem *addr = mv_ap_base(link->ap) + ofs;
struct mv_host_priv *hpriv = link->ap->host->private_data;
if (sc_reg_in == SCR_CONTROL) {
/*
* Workaround for 88SX60x1 FEr SATA#26:
@ -1369,6 +1372,18 @@ static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val)
*/
if ((val & 0xf) == 1 || (readl(addr) & 0xf) == 1)
val |= 0xf000;
if (hpriv->hp_flags & MV_HP_FIX_LP_PHY_CTL) {
void __iomem *lp_phy_addr =
mv_ap_base(link->ap) + LP_PHY_CTL;
/*
* Set PHY speed according to SControl speed.
*/
if ((val & 0xf0) == 0x10)
writelfl(0x7, lp_phy_addr);
else
writelfl(0x227, lp_phy_addr);
}
}
writelfl(val, addr);
return 0;
@ -4111,6 +4126,15 @@ static int mv_platform_probe(struct platform_device *pdev)
if (rc)
goto err;
/*
* To allow disk hotplug on Armada 370/XP SoCs, the PHY speed must be
* updated in the LP_PHY_CTL register.
*/
if (pdev->dev.of_node &&
of_device_is_compatible(pdev->dev.of_node,
"marvell,armada-370-sata"))
hpriv->hp_flags |= MV_HP_FIX_LP_PHY_CTL;
/* initialize adapter */
rc = mv_init_host(host);
if (rc)
@ -4216,6 +4240,7 @@ static int mv_platform_resume(struct platform_device *pdev)
#ifdef CONFIG_OF
static struct of_device_id mv_sata_dt_ids[] = {
{ .compatible = "marvell,armada-370-sata", },
{ .compatible = "marvell,orion-sata", },
{},
};

View File

@ -157,6 +157,7 @@ static const struct sil_drivelist {
{ "ST380011ASL", SIL_QUIRK_MOD15WRITE },
{ "ST3120022ASL", SIL_QUIRK_MOD15WRITE },
{ "ST3160021ASL", SIL_QUIRK_MOD15WRITE },
{ "TOSHIBA MK2561GSYN", SIL_QUIRK_MOD15WRITE },
{ "Maxtor 4D060H3", SIL_QUIRK_UDMA5MAX },
{ }
};

View File

@ -899,7 +899,7 @@ bio_pageinc(struct bio *bio)
* but this has never been seen here.
*/
if (unlikely(PageCompound(page)))
if (compound_trans_head(page) != page) {
if (compound_head(page) != page) {
pr_crit("page tail used for block I/O\n");
BUG();
}

View File

@ -1518,13 +1518,16 @@ static void blkback_changed(struct xenbus_device *dev,
case XenbusStateReconfiguring:
case XenbusStateReconfigured:
case XenbusStateUnknown:
case XenbusStateClosed:
break;
case XenbusStateConnected:
blkfront_connect(info);
break;
case XenbusStateClosed:
if (dev->state == XenbusStateClosed)
break;
/* Missed the backend's Closing state -- fallthrough */
case XenbusStateClosing:
blkfront_closing(info);
break;

View File

@ -190,7 +190,7 @@ static int bind_get(int number, dev_t *dev)
struct raw_device_data *rawdev;
struct block_device *bdev;
if (number <= 0 || number >= MAX_RAW_MINORS)
if (number <= 0 || number >= max_raw_minors)
return -EINVAL;
rawdev = &raw_devices[number];

View File

@ -410,6 +410,8 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
&chip->vendor.read_queue)
== 0) {
burstcnt = get_burstcount(chip);
if (burstcnt < 0)
return burstcnt;
len = min_t(int, burstcnt, count - size);
I2C_READ_DATA(client, TPM_DATA_FIFO, buf + size, len);
size += len;
@ -451,7 +453,8 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf,
size_t len)
{
u32 status, burstcnt = 0, i, size;
u32 status, i, size;
int burstcnt = 0;
int ret;
u8 data;
struct i2c_client *client;
@ -482,6 +485,8 @@ static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf,
for (i = 0; i < len - 1;) {
burstcnt = get_burstcount(chip);
if (burstcnt < 0)
return burstcnt;
size = min_t(int, len - i - 1, burstcnt);
ret = I2C_WRITE_DATA(client, TPM_DATA_FIFO, buf, size);
if (ret < 0)

View File

@ -172,7 +172,7 @@ static ssize_t tpm_store_ppi_request(struct device *dev,
* is updated with function index from SUBREQ to SUBREQ2 since PPI
* version 1.1
*/
if (strcmp(version, "1.1") == -1)
if (strcmp(version, "1.1") < 0)
params[2].integer.value = TPM_PPI_FN_SUBREQ;
else
params[2].integer.value = TPM_PPI_FN_SUBREQ2;
@ -182,7 +182,7 @@ static ssize_t tpm_store_ppi_request(struct device *dev,
* string/package type. For PPI version 1.0 and 1.1, use buffer type
* for compatibility, and use package type since 1.2 according to spec.
*/
if (strcmp(version, "1.2") == -1) {
if (strcmp(version, "1.2") < 0) {
params[3].type = ACPI_TYPE_BUFFER;
params[3].buffer.length = sizeof(req);
sscanf(buf, "%d", &req);
@ -248,7 +248,7 @@ static ssize_t tpm_show_ppi_transition_action(struct device *dev,
* (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for
* compatibility, define params[3].type as buffer, if PPI version < 1.2
*/
if (strcmp(version, "1.2") == -1) {
if (strcmp(version, "1.2") < 0) {
params[3].type = ACPI_TYPE_BUFFER;
params[3].buffer.length = 0;
params[3].buffer.pointer = NULL;
@ -390,7 +390,7 @@ static ssize_t show_ppi_operations(char *buf, u32 start, u32 end)
kfree(output.pointer);
output.length = ACPI_ALLOCATE_BUFFER;
output.pointer = NULL;
if (strcmp(version, "1.2") == -1)
if (strcmp(version, "1.2") < 0)
return -EPERM;
params[2].integer.value = TPM_PPI_FN_GETOPR;

View File

@ -48,7 +48,7 @@ static inline int32_t div_fp(int32_t x, int32_t y)
}
struct sample {
int core_pct_busy;
int32_t core_pct_busy;
u64 aperf;
u64 mperf;
int freq;
@ -68,7 +68,7 @@ struct _pid {
int32_t i_gain;
int32_t d_gain;
int deadband;
int last_err;
int32_t last_err;
};
struct cpudata {
@ -153,16 +153,15 @@ static inline void pid_d_gain_set(struct _pid *pid, int percent)
pid->d_gain = div_fp(int_tofp(percent), int_tofp(100));
}
static signed int pid_calc(struct _pid *pid, int busy)
static signed int pid_calc(struct _pid *pid, int32_t busy)
{
signed int err, result;
signed int result;
int32_t pterm, dterm, fp_error;
int32_t integral_limit;
err = pid->setpoint - busy;
fp_error = int_tofp(err);
fp_error = int_tofp(pid->setpoint) - busy;
if (abs(err) <= pid->deadband)
if (abs(fp_error) <= int_tofp(pid->deadband))
return 0;
pterm = mul_fp(pid->p_gain, fp_error);
@ -176,8 +175,8 @@ static signed int pid_calc(struct _pid *pid, int busy)
if (pid->integral < -integral_limit)
pid->integral = -integral_limit;
dterm = mul_fp(pid->d_gain, (err - pid->last_err));
pid->last_err = err;
dterm = mul_fp(pid->d_gain, fp_error - pid->last_err);
pid->last_err = fp_error;
result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm;
@ -367,12 +366,13 @@ static int intel_pstate_turbo_pstate(void)
static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
{
int max_perf = cpu->pstate.turbo_pstate;
int max_perf_adj;
int min_perf;
if (limits.no_turbo)
max_perf = cpu->pstate.max_pstate;
max_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.max_perf));
*max = clamp_t(int, max_perf,
max_perf_adj = fp_toint(mul_fp(int_tofp(max_perf), limits.max_perf));
*max = clamp_t(int, max_perf_adj,
cpu->pstate.min_pstate, cpu->pstate.turbo_pstate);
min_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.min_perf));
@ -394,7 +394,10 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
trace_cpu_frequency(pstate * 100000, cpu->cpu);
cpu->pstate.current_pstate = pstate;
wrmsrl(MSR_IA32_PERF_CTL, pstate << 8);
if (limits.no_turbo)
wrmsrl(MSR_IA32_PERF_CTL, BIT(32) | (pstate << 8));
else
wrmsrl(MSR_IA32_PERF_CTL, pstate << 8);
}
@ -432,8 +435,9 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
struct sample *sample)
{
u64 core_pct;
core_pct = div64_u64(sample->aperf * 100, sample->mperf);
sample->freq = cpu->pstate.max_pstate * core_pct * 1000;
core_pct = div64_u64(int_tofp(sample->aperf * 100),
sample->mperf);
sample->freq = fp_toint(cpu->pstate.max_pstate * core_pct * 1000);
sample->core_pct_busy = core_pct;
}
@ -465,22 +469,19 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
mod_timer_pinned(&cpu->timer, jiffies + delay);
}
static inline int intel_pstate_get_scaled_busy(struct cpudata *cpu)
static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
{
int32_t busy_scaled;
int32_t core_busy, max_pstate, current_pstate;
core_busy = int_tofp(cpu->samples[cpu->sample_ptr].core_pct_busy);
core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy;
max_pstate = int_tofp(cpu->pstate.max_pstate);
current_pstate = int_tofp(cpu->pstate.current_pstate);
busy_scaled = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
return fp_toint(busy_scaled);
return mul_fp(core_busy, div_fp(max_pstate, current_pstate));
}
static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
{
int busy_scaled;
int32_t busy_scaled;
struct _pid *pid;
signed int ctl = 0;
int steps;
@ -523,6 +524,11 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
ICPU(0x2a, default_policy),
ICPU(0x2d, default_policy),
ICPU(0x3a, default_policy),
ICPU(0x3c, default_policy),
ICPU(0x3e, default_policy),
ICPU(0x3f, default_policy),
ICPU(0x45, default_policy),
ICPU(0x46, default_policy),
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);

View File

@ -1100,7 +1100,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
{
struct powernow_k8_data *data;
struct init_on_cpu init_on_cpu;
int rc;
int rc, cpu;
smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1);
if (rc)
@ -1169,7 +1169,9 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n",
data->currfid, data->currvid);
per_cpu(powernow_data, pol->cpu) = data;
/* Point all the CPUs in this policy to the same data */
for_each_cpu(cpu, pol->cpus)
per_cpu(powernow_data, cpu) = data;
return 0;
@ -1184,6 +1186,7 @@ err_out:
static int powernowk8_cpu_exit(struct cpufreq_policy *pol)
{
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
int cpu;
if (!data)
return -EINVAL;
@ -1194,7 +1197,8 @@ static int powernowk8_cpu_exit(struct cpufreq_policy *pol)
kfree(data->powernow_table);
kfree(data);
per_cpu(powernow_data, pol->cpu) = NULL;
for_each_cpu(cpu, pol->cpus)
per_cpu(powernow_data, cpu) = NULL;
return 0;
}

View File

@ -77,7 +77,8 @@ static irqreturn_t ioat_dma_do_interrupt(int irq, void *data)
attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
for_each_set_bit(bit, &attnstatus, BITS_PER_LONG) {
chan = ioat_chan_by_index(instance, bit);
tasklet_schedule(&chan->cleanup_task);
if (test_bit(IOAT_RUN, &chan->state))
tasklet_schedule(&chan->cleanup_task);
}
writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
@ -93,7 +94,8 @@ static irqreturn_t ioat_dma_do_interrupt_msix(int irq, void *data)
{
struct ioat_chan_common *chan = data;
tasklet_schedule(&chan->cleanup_task);
if (test_bit(IOAT_RUN, &chan->state))
tasklet_schedule(&chan->cleanup_task);
return IRQ_HANDLED;
}
@ -116,7 +118,6 @@ void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *c
chan->timer.function = device->timer_fn;
chan->timer.data = data;
tasklet_init(&chan->cleanup_task, device->cleanup_fn, data);
tasklet_disable(&chan->cleanup_task);
}
/**
@ -354,13 +355,49 @@ static int ioat1_dma_alloc_chan_resources(struct dma_chan *c)
writel(((u64) chan->completion_dma) >> 32,
chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH);
tasklet_enable(&chan->cleanup_task);
set_bit(IOAT_RUN, &chan->state);
ioat1_dma_start_null_desc(ioat); /* give chain to dma device */
dev_dbg(to_dev(chan), "%s: allocated %d descriptors\n",
__func__, ioat->desccount);
return ioat->desccount;
}
void ioat_stop(struct ioat_chan_common *chan)
{
struct ioatdma_device *device = chan->device;
struct pci_dev *pdev = device->pdev;
int chan_id = chan_num(chan);
struct msix_entry *msix;
/* 1/ stop irq from firing tasklets
* 2/ stop the tasklet from re-arming irqs
*/
clear_bit(IOAT_RUN, &chan->state);
/* flush inflight interrupts */
switch (device->irq_mode) {
case IOAT_MSIX:
msix = &device->msix_entries[chan_id];
synchronize_irq(msix->vector);
break;
case IOAT_MSI:
case IOAT_INTX:
synchronize_irq(pdev->irq);
break;
default:
break;
}
/* flush inflight timers */
del_timer_sync(&chan->timer);
/* flush inflight tasklet runs */
tasklet_kill(&chan->cleanup_task);
/* final cleanup now that everything is quiesced and can't re-arm */
device->cleanup_fn((unsigned long) &chan->common);
}
/**
* ioat1_dma_free_chan_resources - release all the descriptors
* @chan: the channel to be cleaned
@ -379,9 +416,7 @@ static void ioat1_dma_free_chan_resources(struct dma_chan *c)
if (ioat->desccount == 0)
return;
tasklet_disable(&chan->cleanup_task);
del_timer_sync(&chan->timer);
ioat1_cleanup(ioat);
ioat_stop(chan);
/* Delay 100ms after reset to allow internal DMA logic to quiesce
* before removing DMA descriptor resources.
@ -526,8 +561,11 @@ ioat1_dma_prep_memcpy(struct dma_chan *c, dma_addr_t dma_dest,
static void ioat1_cleanup_event(unsigned long data)
{
struct ioat_dma_chan *ioat = to_ioat_chan((void *) data);
struct ioat_chan_common *chan = &ioat->base;
ioat1_cleanup(ioat);
if (!test_bit(IOAT_RUN, &chan->state))
return;
writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET);
}

View File

@ -370,6 +370,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type);
void ioat_kobject_del(struct ioatdma_device *device);
int ioat_dma_setup_interrupts(struct ioatdma_device *device);
void ioat_stop(struct ioat_chan_common *chan);
extern const struct sysfs_ops ioat_sysfs_ops;
extern struct ioat_sysfs_entry ioat_version_attr;
extern struct ioat_sysfs_entry ioat_cap_attr;

View File

@ -190,8 +190,11 @@ static void ioat2_cleanup(struct ioat2_dma_chan *ioat)
void ioat2_cleanup_event(unsigned long data)
{
struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
struct ioat_chan_common *chan = &ioat->base;
ioat2_cleanup(ioat);
if (!test_bit(IOAT_RUN, &chan->state))
return;
writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET);
}
@ -553,10 +556,10 @@ int ioat2_alloc_chan_resources(struct dma_chan *c)
ioat->issued = 0;
ioat->tail = 0;
ioat->alloc_order = order;
set_bit(IOAT_RUN, &chan->state);
spin_unlock_bh(&ioat->prep_lock);
spin_unlock_bh(&chan->cleanup_lock);
tasklet_enable(&chan->cleanup_task);
ioat2_start_null_desc(ioat);
/* check that we got off the ground */
@ -566,7 +569,6 @@ int ioat2_alloc_chan_resources(struct dma_chan *c)
} while (i++ < 20 && !is_ioat_active(status) && !is_ioat_idle(status));
if (is_ioat_active(status) || is_ioat_idle(status)) {
set_bit(IOAT_RUN, &chan->state);
return 1 << ioat->alloc_order;
} else {
u32 chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
@ -809,11 +811,8 @@ void ioat2_free_chan_resources(struct dma_chan *c)
if (!ioat->ring)
return;
tasklet_disable(&chan->cleanup_task);
del_timer_sync(&chan->timer);
device->cleanup_fn((unsigned long) c);
ioat_stop(chan);
device->reset_hw(chan);
clear_bit(IOAT_RUN, &chan->state);
spin_lock_bh(&chan->cleanup_lock);
spin_lock_bh(&ioat->prep_lock);

View File

@ -635,8 +635,11 @@ static void ioat3_cleanup(struct ioat2_dma_chan *ioat)
static void ioat3_cleanup_event(unsigned long data)
{
struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
struct ioat_chan_common *chan = &ioat->base;
ioat3_cleanup(ioat);
if (!test_bit(IOAT_RUN, &chan->state))
return;
writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET);
}

View File

@ -1587,6 +1587,7 @@ static void dma_tasklet(unsigned long data)
struct d40_chan *d40c = (struct d40_chan *) data;
struct d40_desc *d40d;
unsigned long flags;
bool callback_active;
dma_async_tx_callback callback;
void *callback_param;
@ -1614,6 +1615,7 @@ static void dma_tasklet(unsigned long data)
}
/* Callback to client */
callback_active = !!(d40d->txd.flags & DMA_PREP_INTERRUPT);
callback = d40d->txd.callback;
callback_param = d40d->txd.callback_param;
@ -1636,7 +1638,7 @@ static void dma_tasklet(unsigned long data)
spin_unlock_irqrestore(&d40c->lock, flags);
if (callback && (d40d->txd.flags & DMA_PREP_INTERRUPT))
if (callback_active && callback)
callback(callback_param);
return;

View File

@ -1182,9 +1182,11 @@ static int e752x_get_devs(struct pci_dev *pdev, int dev_idx,
pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL,
pvt->dev_info->err_dev, pvt->bridge_ck);
if (pvt->bridge_ck == NULL)
if (pvt->bridge_ck == NULL) {
pvt->bridge_ck = pci_scan_single_device(pdev->bus,
PCI_DEVFN(0, 1));
pci_dev_get(pvt->bridge_ck);
}
if (pvt->bridge_ck == NULL) {
e752x_printk(KERN_ERR, "error reporting device not found:"

View File

@ -559,7 +559,8 @@ static void edac_mc_workq_function(struct work_struct *work_req)
*
* called with the mem_ctls_mutex held
*/
static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec)
static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec,
bool init)
{
edac_dbg(0, "\n");
@ -567,7 +568,9 @@ static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec)
if (mci->op_state != OP_RUNNING_POLL)
return;
INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function);
if (init)
INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function);
mod_delayed_work(edac_workqueue, &mci->work, msecs_to_jiffies(msec));
}
@ -601,7 +604,7 @@ static void edac_mc_workq_teardown(struct mem_ctl_info *mci)
* user space has updated our poll period value, need to
* reset our workq delays
*/
void edac_mc_reset_delay_period(int value)
void edac_mc_reset_delay_period(unsigned long value)
{
struct mem_ctl_info *mci;
struct list_head *item;
@ -611,7 +614,7 @@ void edac_mc_reset_delay_period(int value)
list_for_each(item, &mc_devices) {
mci = list_entry(item, struct mem_ctl_info, link);
edac_mc_workq_setup(mci, (unsigned long) value);
edac_mc_workq_setup(mci, value, false);
}
mutex_unlock(&mem_ctls_mutex);
@ -782,7 +785,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
/* This instance is NOW RUNNING */
mci->op_state = OP_RUNNING_POLL;
edac_mc_workq_setup(mci, edac_mc_get_poll_msec());
edac_mc_workq_setup(mci, edac_mc_get_poll_msec(), true);
} else {
mci->op_state = OP_RUNNING_INTERRUPT;
}

Some files were not shown because too many files have changed in this diff Show More