Merge "Merge upstream linux-stable v3.10.36 into msm-3.10"
This commit is contained in:
commit
16296e0178
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 28
|
||||
SUBLEVEL = 36
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define _ASM_MIPSREGS_H
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/hazards.h>
|
||||
#include <asm/war.h>
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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, ¶m, 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -432,6 +432,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
|
|||
pin_name(pin));
|
||||
}
|
||||
|
||||
kfree(entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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, ¤t->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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 },
|
||||
|
||||
|
|
|
@ -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 */
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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", },
|
||||
{},
|
||||
};
|
||||
|
|
|
@ -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 },
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:"
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue