Merge branch 'linux-linaro-lsk-v4.4' into linux-linaro-lsk-v4.4-android
This commit is contained in:
commit
582ee3a96f
247 changed files with 2985 additions and 1152 deletions
|
@ -10289,9 +10289,11 @@ S: Maintained
|
|||
F: drivers/net/ethernet/dlink/sundance.c
|
||||
|
||||
SUPERH
|
||||
M: Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
M: Rich Felker <dalias@libc.org>
|
||||
L: linux-sh@vger.kernel.org
|
||||
Q: http://patchwork.kernel.org/project/linux-sh/list/
|
||||
S: Orphan
|
||||
S: Maintained
|
||||
F: Documentation/sh/
|
||||
F: arch/sh/
|
||||
F: drivers/sh/
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 1
|
||||
SUBLEVEL = 3
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
|
|
|
@ -303,16 +303,6 @@
|
|||
gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
reg_usb2_1_vbus: v5-vbus1 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "v5.0-vbus1";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
enable-active-high;
|
||||
regulator-always-on;
|
||||
gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
reg_sata0: pwr-sata0 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "pwr_en_sata0";
|
||||
|
|
|
@ -86,10 +86,12 @@
|
|||
macb0: ethernet@f8020000 {
|
||||
phy-mode = "rmii";
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>;
|
||||
|
||||
phy0: ethernet-phy@1 {
|
||||
interrupt-parent = <&pioE>;
|
||||
interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
@ -152,6 +154,10 @@
|
|||
atmel,pins =
|
||||
<AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
|
||||
};
|
||||
pinctrl_macb0_phy_irq: macb0_phy_irq_0 {
|
||||
atmel,pins =
|
||||
<AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -160,8 +160,15 @@
|
|||
};
|
||||
|
||||
macb0: ethernet@f8020000 {
|
||||
pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>;
|
||||
phy-mode = "rmii";
|
||||
status = "okay";
|
||||
|
||||
ethernet-phy@1 {
|
||||
reg = <0x1>;
|
||||
interrupt-parent = <&pioE>;
|
||||
interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
mmc1: mmc@fc000000 {
|
||||
|
@ -193,6 +200,10 @@
|
|||
|
||||
pinctrl@fc06a000 {
|
||||
board {
|
||||
pinctrl_macb0_phy_irq: macb0_phy_irq {
|
||||
atmel,pins =
|
||||
<AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
|
||||
};
|
||||
pinctrl_mmc0_cd: mmc0_cd {
|
||||
atmel,pins =
|
||||
<AT91_PIOE 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
interrupt-parent = <&gpio5>;
|
||||
interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */
|
||||
ref-clock-frequency = <26000000>;
|
||||
tcxo-clock-frequency = <26000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -130,6 +130,16 @@
|
|||
};
|
||||
};
|
||||
|
||||
&gpio8 {
|
||||
/* TI trees use GPIO instead of msecure, see also muxing */
|
||||
p234 {
|
||||
gpio-hog;
|
||||
gpios = <10 GPIO_ACTIVE_HIGH>;
|
||||
output-high;
|
||||
line-name = "gpio8_234/msecure";
|
||||
};
|
||||
};
|
||||
|
||||
&omap5_pmx_core {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <
|
||||
|
@ -213,6 +223,13 @@
|
|||
>;
|
||||
};
|
||||
|
||||
/* TI trees use GPIO mode; msecure mode does not work reliably? */
|
||||
palmas_msecure_pins: palmas_msecure_pins {
|
||||
pinctrl-single,pins = <
|
||||
OMAP5_IOPAD(0x180, PIN_OUTPUT | MUX_MODE6) /* gpio8_234 */
|
||||
>;
|
||||
};
|
||||
|
||||
usbhost_pins: pinmux_usbhost_pins {
|
||||
pinctrl-single,pins = <
|
||||
0x84 (PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */
|
||||
|
@ -278,6 +295,12 @@
|
|||
&usbhost_wkup_pins
|
||||
>;
|
||||
|
||||
palmas_sys_nirq_pins: pinmux_palmas_sys_nirq_pins {
|
||||
pinctrl-single,pins = <
|
||||
OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1 */
|
||||
>;
|
||||
};
|
||||
|
||||
usbhost_wkup_pins: pinmux_usbhost_wkup_pins {
|
||||
pinctrl-single,pins = <
|
||||
0x1A (PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */
|
||||
|
@ -345,6 +368,8 @@
|
|||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
ti,system-power-controller;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&palmas_sys_nirq_pins &palmas_msecure_pins>;
|
||||
|
||||
extcon_usb3: palmas_usb {
|
||||
compatible = "ti,palmas-usb-vid";
|
||||
|
@ -358,6 +383,14 @@
|
|||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
rtc {
|
||||
compatible = "ti,palmas-rtc";
|
||||
interrupt-parent = <&palmas>;
|
||||
interrupts = <8 IRQ_TYPE_NONE>;
|
||||
ti,backup-battery-chargeable;
|
||||
ti,backup-battery-charge-high-current;
|
||||
};
|
||||
|
||||
palmas_pmic {
|
||||
compatible = "ti,palmas-pmic";
|
||||
interrupt-parent = <&palmas>;
|
||||
|
|
|
@ -1342,7 +1342,7 @@
|
|||
dbgu: serial@fc069000 {
|
||||
compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
|
||||
reg = <0xfc069000 0x200>;
|
||||
interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>;
|
||||
interrupts = <45 IRQ_TYPE_LEVEL_HIGH 7>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_dbgu>;
|
||||
clocks = <&dbgu_clk>;
|
||||
|
|
|
@ -127,22 +127,14 @@
|
|||
};
|
||||
mmcsd_default_mode: mmcsd_default {
|
||||
mmcsd_default_cfg1 {
|
||||
/* MCCLK */
|
||||
pins = "GPIO8_B10";
|
||||
ste,output = <0>;
|
||||
};
|
||||
mmcsd_default_cfg2 {
|
||||
/* MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2 */
|
||||
pins = "GPIO10_C11", "GPIO15_A12",
|
||||
"GPIO16_C13", "GPIO23_D15";
|
||||
ste,output = <1>;
|
||||
};
|
||||
mmcsd_default_cfg3 {
|
||||
/* MCCMD, MCDAT3-0, MCMSFBCLK */
|
||||
pins = "GPIO9_A10", "GPIO11_B11",
|
||||
"GPIO12_A11", "GPIO13_C12",
|
||||
"GPIO14_B12", "GPIO24_C15";
|
||||
ste,input = <1>;
|
||||
/*
|
||||
* MCCLK, MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2
|
||||
* MCCMD, MCDAT3-0, MCMSFBCLK
|
||||
*/
|
||||
pins = "GPIO8_B10", "GPIO9_A10", "GPIO10_C11", "GPIO11_B11",
|
||||
"GPIO12_A11", "GPIO13_C12", "GPIO14_B12", "GPIO15_A12",
|
||||
"GPIO16_C13", "GPIO23_D15", "GPIO24_C15";
|
||||
ste,output = <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -802,10 +794,21 @@
|
|||
clock-names = "mclk", "apb_pclk";
|
||||
interrupt-parent = <&vica>;
|
||||
interrupts = <22>;
|
||||
max-frequency = <48000000>;
|
||||
max-frequency = <400000>;
|
||||
bus-width = <4>;
|
||||
cap-mmc-highspeed;
|
||||
cap-sd-highspeed;
|
||||
full-pwr-cycle;
|
||||
/*
|
||||
* The STw4811 circuit used with the Nomadik strictly
|
||||
* requires that all of these signal direction pins be
|
||||
* routed and used for its 4-bit levelshifter.
|
||||
*/
|
||||
st,sig-dir-dat0;
|
||||
st,sig-dir-dat2;
|
||||
st,sig-dir-dat31;
|
||||
st,sig-dir-cmd;
|
||||
st,sig-pin-fbclk;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmcsd_default_mux>, <&mmcsd_default_mode>;
|
||||
vmmc-supply = <&vmmc_regulator>;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
#include <asm/hardware/icst.h>
|
||||
|
||||
/*
|
||||
|
@ -29,7 +29,11 @@ EXPORT_SYMBOL(icst525_s2div);
|
|||
|
||||
unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco)
|
||||
{
|
||||
return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]);
|
||||
u64 dividend = p->ref * 2 * (u64)(vco.v + 8);
|
||||
u32 divisor = (vco.r + 2) * p->s2div[vco.s];
|
||||
|
||||
do_div(dividend, divisor);
|
||||
return (unsigned long)dividend;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(icst_hz);
|
||||
|
@ -58,6 +62,7 @@ icst_hz_to_vco(const struct icst_params *p, unsigned long freq)
|
|||
|
||||
if (f > p->vco_min && f <= p->vco_max)
|
||||
break;
|
||||
i++;
|
||||
} while (i < 8);
|
||||
|
||||
if (i >= 8)
|
||||
|
|
|
@ -86,13 +86,18 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
|
|||
stmfd sp!, {lr} @ save registers on stack
|
||||
/* Setup so that we will disable and enable l2 */
|
||||
mov r1, #0x1
|
||||
adrl r2, l2dis_3630 @ may be too distant for plain adr
|
||||
str r1, [r2]
|
||||
adrl r3, l2dis_3630_offset @ may be too distant for plain adr
|
||||
ldr r2, [r3] @ value for offset
|
||||
str r1, [r2, r3] @ write to l2dis_3630
|
||||
ldmfd sp!, {pc} @ restore regs and return
|
||||
ENDPROC(enable_omap3630_toggle_l2_on_restore)
|
||||
|
||||
.text
|
||||
/* Function to call rom code to save secure ram context */
|
||||
/*
|
||||
* Function to call rom code to save secure ram context. This gets
|
||||
* relocated to SRAM, so it can be all in .data section. Otherwise
|
||||
* we need to initialize api_params separately.
|
||||
*/
|
||||
.data
|
||||
.align 3
|
||||
ENTRY(save_secure_ram_context)
|
||||
stmfd sp!, {r4 - r11, lr} @ save registers on stack
|
||||
|
@ -126,6 +131,8 @@ ENDPROC(save_secure_ram_context)
|
|||
ENTRY(save_secure_ram_context_sz)
|
||||
.word . - save_secure_ram_context
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* ======================
|
||||
* == Idle entry point ==
|
||||
|
@ -289,12 +296,6 @@ wait_sdrc_ready:
|
|||
bic r5, r5, #0x40
|
||||
str r5, [r4]
|
||||
|
||||
/*
|
||||
* PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
|
||||
* base instead.
|
||||
* Be careful not to clobber r7 when maintaing this code.
|
||||
*/
|
||||
|
||||
is_dll_in_lock_mode:
|
||||
/* Is dll in lock mode? */
|
||||
ldr r4, sdrc_dlla_ctrl
|
||||
|
@ -302,11 +303,7 @@ is_dll_in_lock_mode:
|
|||
tst r5, #0x4
|
||||
bne exit_nonoff_modes @ Return if locked
|
||||
/* wait till dll locks */
|
||||
adr r7, kick_counter
|
||||
wait_dll_lock_timed:
|
||||
ldr r4, wait_dll_lock_counter
|
||||
add r4, r4, #1
|
||||
str r4, [r7, #wait_dll_lock_counter - kick_counter]
|
||||
ldr r4, sdrc_dlla_status
|
||||
/* Wait 20uS for lock */
|
||||
mov r6, #8
|
||||
|
@ -330,9 +327,6 @@ kick_dll:
|
|||
orr r6, r6, #(1<<3) @ enable dll
|
||||
str r6, [r4]
|
||||
dsb
|
||||
ldr r4, kick_counter
|
||||
add r4, r4, #1
|
||||
str r4, [r7] @ kick_counter
|
||||
b wait_dll_lock_timed
|
||||
|
||||
exit_nonoff_modes:
|
||||
|
@ -360,15 +354,6 @@ sdrc_dlla_status:
|
|||
.word SDRC_DLLA_STATUS_V
|
||||
sdrc_dlla_ctrl:
|
||||
.word SDRC_DLLA_CTRL_V
|
||||
/*
|
||||
* When exporting to userspace while the counters are in SRAM,
|
||||
* these 2 words need to be at the end to facilitate retrival!
|
||||
*/
|
||||
kick_counter:
|
||||
.word 0
|
||||
wait_dll_lock_counter:
|
||||
.word 0
|
||||
|
||||
ENTRY(omap3_do_wfi_sz)
|
||||
.word . - omap3_do_wfi
|
||||
|
||||
|
@ -437,7 +422,9 @@ ENTRY(omap3_restore)
|
|||
cmp r2, #0x0 @ Check if target power state was OFF or RET
|
||||
bne logic_l1_restore
|
||||
|
||||
ldr r0, l2dis_3630
|
||||
adr r1, l2dis_3630_offset @ address for offset
|
||||
ldr r0, [r1] @ value for offset
|
||||
ldr r0, [r1, r0] @ value at l2dis_3630
|
||||
cmp r0, #0x1 @ should we disable L2 on 3630?
|
||||
bne skipl2dis
|
||||
mrc p15, 0, r0, c1, c0, 1
|
||||
|
@ -449,12 +436,14 @@ skipl2dis:
|
|||
and r1, #0x700
|
||||
cmp r1, #0x300
|
||||
beq l2_inv_gp
|
||||
adr r0, l2_inv_api_params_offset
|
||||
ldr r3, [r0]
|
||||
add r3, r3, r0 @ r3 points to dummy parameters
|
||||
mov r0, #40 @ set service ID for PPA
|
||||
mov r12, r0 @ copy secure Service ID in r12
|
||||
mov r1, #0 @ set task id for ROM code in r1
|
||||
mov r2, #4 @ set some flags in r2, r6
|
||||
mov r6, #0xff
|
||||
adr r3, l2_inv_api_params @ r3 points to dummy parameters
|
||||
dsb @ data write barrier
|
||||
dmb @ data memory barrier
|
||||
smc #1 @ call SMI monitor (smi #1)
|
||||
|
@ -488,8 +477,8 @@ skipl2dis:
|
|||
b logic_l1_restore
|
||||
|
||||
.align
|
||||
l2_inv_api_params:
|
||||
.word 0x1, 0x00
|
||||
l2_inv_api_params_offset:
|
||||
.long l2_inv_api_params - .
|
||||
l2_inv_gp:
|
||||
/* Execute smi to invalidate L2 cache */
|
||||
mov r12, #0x1 @ set up to invalidate L2
|
||||
|
@ -506,7 +495,9 @@ l2_inv_gp:
|
|||
mov r12, #0x2
|
||||
smc #0 @ Call SMI monitor (smieq)
|
||||
logic_l1_restore:
|
||||
ldr r1, l2dis_3630
|
||||
adr r0, l2dis_3630_offset @ adress for offset
|
||||
ldr r1, [r0] @ value for offset
|
||||
ldr r1, [r0, r1] @ value at l2dis_3630
|
||||
cmp r1, #0x1 @ Test if L2 re-enable needed on 3630
|
||||
bne skipl2reen
|
||||
mrc p15, 0, r1, c1, c0, 1
|
||||
|
@ -535,9 +526,17 @@ control_stat:
|
|||
.word CONTROL_STAT
|
||||
control_mem_rta:
|
||||
.word CONTROL_MEM_RTA_CTRL
|
||||
l2dis_3630_offset:
|
||||
.long l2dis_3630 - .
|
||||
|
||||
.data
|
||||
l2dis_3630:
|
||||
.word 0
|
||||
|
||||
.data
|
||||
l2_inv_api_params:
|
||||
.word 0x1, 0x00
|
||||
|
||||
/*
|
||||
* Internal functions
|
||||
*/
|
||||
|
|
|
@ -29,12 +29,6 @@
|
|||
dsb
|
||||
.endm
|
||||
|
||||
ppa_zero_params:
|
||||
.word 0x0
|
||||
|
||||
ppa_por_params:
|
||||
.word 1, 0
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP4
|
||||
|
||||
/*
|
||||
|
@ -266,7 +260,9 @@ ENTRY(omap4_cpu_resume)
|
|||
beq skip_ns_smp_enable
|
||||
ppa_actrl_retry:
|
||||
mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX
|
||||
adr r3, ppa_zero_params @ Pointer to parameters
|
||||
adr r1, ppa_zero_params_offset
|
||||
ldr r3, [r1]
|
||||
add r3, r3, r1 @ Pointer to ppa_zero_params
|
||||
mov r1, #0x0 @ Process ID
|
||||
mov r2, #0x4 @ Flag
|
||||
mov r6, #0xff
|
||||
|
@ -303,7 +299,9 @@ skip_ns_smp_enable:
|
|||
ldr r0, =OMAP4_PPA_L2_POR_INDEX
|
||||
ldr r1, =OMAP44XX_SAR_RAM_BASE
|
||||
ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
|
||||
adr r3, ppa_por_params
|
||||
adr r1, ppa_por_params_offset
|
||||
ldr r3, [r1]
|
||||
add r3, r3, r1 @ Pointer to ppa_por_params
|
||||
str r4, [r3, #0x04]
|
||||
mov r1, #0x0 @ Process ID
|
||||
mov r2, #0x4 @ Flag
|
||||
|
@ -328,6 +326,8 @@ skip_l2en:
|
|||
#endif
|
||||
|
||||
b cpu_resume @ Jump to generic resume
|
||||
ppa_por_params_offset:
|
||||
.long ppa_por_params - .
|
||||
ENDPROC(omap4_cpu_resume)
|
||||
#endif /* CONFIG_ARCH_OMAP4 */
|
||||
|
||||
|
@ -380,4 +380,13 @@ ENTRY(omap_do_wfi)
|
|||
nop
|
||||
|
||||
ldmfd sp!, {pc}
|
||||
ppa_zero_params_offset:
|
||||
.long ppa_zero_params - .
|
||||
ENDPROC(omap_do_wfi)
|
||||
|
||||
.data
|
||||
ppa_zero_params:
|
||||
.word 0
|
||||
|
||||
ppa_por_params:
|
||||
.word 1, 0
|
||||
|
|
|
@ -933,6 +933,10 @@ static int __init __iommu_dma_init(void)
|
|||
ret = register_iommu_dma_ops_notifier(&platform_bus_type);
|
||||
if (!ret)
|
||||
ret = register_iommu_dma_ops_notifier(&amba_bustype);
|
||||
|
||||
/* handle devices queued before this arch_initcall */
|
||||
if (!ret)
|
||||
__iommu_attach_notifier(NULL, BUS_NOTIFY_ADD_DEVICE, NULL);
|
||||
return ret;
|
||||
}
|
||||
arch_initcall(__iommu_dma_init);
|
||||
|
|
|
@ -57,6 +57,9 @@ static int change_memory_common(unsigned long addr, int numpages,
|
|||
if (end < MODULES_VADDR || end >= MODULES_END)
|
||||
return -EINVAL;
|
||||
|
||||
if (!numpages)
|
||||
return 0;
|
||||
|
||||
data.set_mask = set_mask;
|
||||
data.clear_mask = clear_mask;
|
||||
|
||||
|
|
|
@ -81,7 +81,10 @@ static struct resource code_resource = {
|
|||
};
|
||||
|
||||
unsigned long memory_start;
|
||||
EXPORT_SYMBOL(memory_start);
|
||||
|
||||
unsigned long memory_end;
|
||||
EXPORT_SYMBOL(memory_end);
|
||||
|
||||
void __init setup_arch(char **);
|
||||
int get_cpuinfo(char *);
|
||||
|
|
|
@ -54,24 +54,12 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
|
|||
return pte_wrprotect(pte);
|
||||
}
|
||||
|
||||
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
pte_t old_pte = *ptep;
|
||||
set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
|
||||
}
|
||||
void huge_ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep);
|
||||
|
||||
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
pte_t pte, int dirty)
|
||||
{
|
||||
int changed = !pte_same(*ptep, pte);
|
||||
if (changed) {
|
||||
set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
|
||||
flush_tlb_page(vma, addr);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
pte_t pte, int dirty);
|
||||
|
||||
static inline pte_t huge_ptep_get(pte_t *ptep)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef _PARISC_SIGINFO_H
|
||||
#define _PARISC_SIGINFO_H
|
||||
|
||||
#if defined(__LP64__)
|
||||
#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
|
||||
#endif
|
||||
|
||||
#include <asm-generic/siginfo.h>
|
||||
|
||||
#undef NSIGTRAP
|
||||
|
|
|
@ -105,15 +105,13 @@ static inline void purge_tlb_entries_huge(struct mm_struct *mm, unsigned long ad
|
|||
addr |= _HUGE_PAGE_SIZE_ENCODING_DEFAULT;
|
||||
|
||||
for (i = 0; i < (1 << (HPAGE_SHIFT-REAL_HPAGE_SHIFT)); i++) {
|
||||
mtsp(mm->context, 1);
|
||||
pdtlb(addr);
|
||||
if (unlikely(split_tlb))
|
||||
pitlb(addr);
|
||||
purge_tlb_entries(mm, addr);
|
||||
addr += (1UL << REAL_HPAGE_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
/* __set_huge_pte_at() must be called holding the pa_tlb_lock. */
|
||||
static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t entry)
|
||||
{
|
||||
unsigned long addr_start;
|
||||
|
@ -123,14 +121,9 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
|||
addr_start = addr;
|
||||
|
||||
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
|
||||
/* Directly write pte entry. We could call set_pte_at(mm, addr, ptep, entry)
|
||||
* instead, but then we get double locking on pa_tlb_lock. */
|
||||
*ptep = entry;
|
||||
set_pte(ptep, entry);
|
||||
ptep++;
|
||||
|
||||
/* Drop the PAGE_SIZE/non-huge tlb entry */
|
||||
purge_tlb_entries(mm, addr);
|
||||
|
||||
addr += PAGE_SIZE;
|
||||
pte_val(entry) += PAGE_SIZE;
|
||||
}
|
||||
|
@ -138,18 +131,61 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
|||
purge_tlb_entries_huge(mm, addr_start);
|
||||
}
|
||||
|
||||
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t entry)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
purge_tlb_start(flags);
|
||||
__set_huge_pte_at(mm, addr, ptep, entry);
|
||||
purge_tlb_end(flags);
|
||||
}
|
||||
|
||||
|
||||
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep)
|
||||
{
|
||||
unsigned long flags;
|
||||
pte_t entry;
|
||||
|
||||
purge_tlb_start(flags);
|
||||
entry = *ptep;
|
||||
set_huge_pte_at(mm, addr, ptep, __pte(0));
|
||||
__set_huge_pte_at(mm, addr, ptep, __pte(0));
|
||||
purge_tlb_end(flags);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
void huge_ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
unsigned long flags;
|
||||
pte_t old_pte;
|
||||
|
||||
purge_tlb_start(flags);
|
||||
old_pte = *ptep;
|
||||
__set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
|
||||
purge_tlb_end(flags);
|
||||
}
|
||||
|
||||
int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
pte_t pte, int dirty)
|
||||
{
|
||||
unsigned long flags;
|
||||
int changed;
|
||||
|
||||
purge_tlb_start(flags);
|
||||
changed = !pte_same(*ptep, pte);
|
||||
if (changed) {
|
||||
__set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
|
||||
}
|
||||
purge_tlb_end(flags);
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
int pmd_huge(pmd_t pmd)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -81,6 +81,7 @@ struct pci_dn;
|
|||
#define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */
|
||||
#define EEH_PE_CFG_RESTRICTED (1 << 9) /* Block config on error */
|
||||
#define EEH_PE_REMOVED (1 << 10) /* Removed permanently */
|
||||
#define EEH_PE_PRI_BUS (1 << 11) /* Cached primary bus */
|
||||
|
||||
struct eeh_pe {
|
||||
int type; /* PE type: PHB/Bus/Device */
|
||||
|
|
|
@ -564,6 +564,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
|
|||
*/
|
||||
eeh_pe_state_mark(pe, EEH_PE_KEEP);
|
||||
if (bus) {
|
||||
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
|
||||
pci_lock_rescan_remove();
|
||||
pcibios_remove_pci_devices(bus);
|
||||
pci_unlock_rescan_remove();
|
||||
|
@ -803,6 +804,7 @@ perm_error:
|
|||
* the their PCI config any more.
|
||||
*/
|
||||
if (frozen_bus) {
|
||||
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
|
||||
eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
|
||||
|
||||
pci_lock_rescan_remove();
|
||||
|
@ -886,6 +888,7 @@ static void eeh_handle_special_event(void)
|
|||
continue;
|
||||
|
||||
/* Notify all devices to be down */
|
||||
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
|
||||
bus = eeh_pe_bus_get(phb_pe);
|
||||
eeh_pe_dev_traverse(pe,
|
||||
eeh_report_failure, NULL);
|
||||
|
|
|
@ -883,32 +883,29 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
|
|||
const char *eeh_pe_loc_get(struct eeh_pe *pe)
|
||||
{
|
||||
struct pci_bus *bus = eeh_pe_bus_get(pe);
|
||||
struct device_node *dn = pci_bus_to_OF_node(bus);
|
||||
struct device_node *dn;
|
||||
const char *loc = NULL;
|
||||
|
||||
if (!dn)
|
||||
goto out;
|
||||
while (bus) {
|
||||
dn = pci_bus_to_OF_node(bus);
|
||||
if (!dn) {
|
||||
bus = bus->parent;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* PHB PE or root PE ? */
|
||||
if (pci_is_root_bus(bus)) {
|
||||
loc = of_get_property(dn, "ibm,loc-code", NULL);
|
||||
if (!loc)
|
||||
if (pci_is_root_bus(bus))
|
||||
loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);
|
||||
if (loc)
|
||||
goto out;
|
||||
else
|
||||
loc = of_get_property(dn, "ibm,slot-location-code",
|
||||
NULL);
|
||||
|
||||
/* Check the root port */
|
||||
dn = dn->child;
|
||||
if (!dn)
|
||||
goto out;
|
||||
if (loc)
|
||||
return loc;
|
||||
|
||||
bus = bus->parent;
|
||||
}
|
||||
|
||||
loc = of_get_property(dn, "ibm,loc-code", NULL);
|
||||
if (!loc)
|
||||
loc = of_get_property(dn, "ibm,slot-location-code", NULL);
|
||||
|
||||
out:
|
||||
return loc ? loc : "N/A";
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -931,7 +928,7 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
|
|||
bus = pe->phb->bus;
|
||||
} else if (pe->type & EEH_PE_BUS ||
|
||||
pe->type & EEH_PE_DEVICE) {
|
||||
if (pe->bus) {
|
||||
if (pe->state & EEH_PE_PRI_BUS) {
|
||||
bus = pe->bus;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -2153,7 +2153,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
|||
|
||||
/* Emulate H_SET_DABR/X on P8 for the sake of compat mode guests */
|
||||
2: rlwimi r5, r4, 5, DAWRX_DR | DAWRX_DW
|
||||
rlwimi r5, r4, 1, DAWRX_WT
|
||||
rlwimi r5, r4, 2, DAWRX_WT
|
||||
clrrdi r4, r4, 3
|
||||
std r4, VCPU_DAWR(r3)
|
||||
std r5, VCPU_DAWRX(r3)
|
||||
|
|
|
@ -919,21 +919,17 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
|||
r = -ENXIO;
|
||||
break;
|
||||
}
|
||||
vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
|
||||
val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
|
||||
break;
|
||||
case KVM_REG_PPC_VSCR:
|
||||
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
||||
r = -ENXIO;
|
||||
break;
|
||||
}
|
||||
vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
|
||||
val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
|
||||
break;
|
||||
case KVM_REG_PPC_VRSAVE:
|
||||
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
||||
r = -ENXIO;
|
||||
break;
|
||||
}
|
||||
vcpu->arch.vrsave = set_reg_val(reg->id, val);
|
||||
val = get_reg_val(reg->id, vcpu->arch.vrsave);
|
||||
break;
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
default:
|
||||
|
@ -974,17 +970,21 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
|
|||
r = -ENXIO;
|
||||
break;
|
||||
}
|
||||
val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0];
|
||||
vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
|
||||
break;
|
||||
case KVM_REG_PPC_VSCR:
|
||||
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
||||
r = -ENXIO;
|
||||
break;
|
||||
}
|
||||
val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]);
|
||||
vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
|
||||
break;
|
||||
case KVM_REG_PPC_VRSAVE:
|
||||
val = get_reg_val(reg->id, vcpu->arch.vrsave);
|
||||
if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
|
||||
r = -ENXIO;
|
||||
break;
|
||||
}
|
||||
vcpu->arch.vrsave = set_reg_val(reg->id, val);
|
||||
break;
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
default:
|
||||
|
|
|
@ -444,9 +444,12 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
|
|||
* PCI devices of the PE are expected to be removed prior
|
||||
* to PE reset.
|
||||
*/
|
||||
if (!edev->pe->bus)
|
||||
if (!(edev->pe->state & EEH_PE_PRI_BUS)) {
|
||||
edev->pe->bus = pci_find_bus(hose->global_number,
|
||||
pdn->busno);
|
||||
if (edev->pe->bus)
|
||||
edev->pe->state |= EEH_PE_PRI_BUS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable EEH explicitly so that we will do EEH check
|
||||
|
|
|
@ -3034,6 +3034,7 @@ static void pnv_pci_ioda_shutdown(struct pci_controller *hose)
|
|||
|
||||
static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
|
||||
.dma_dev_setup = pnv_pci_dma_dev_setup,
|
||||
.dma_bus_setup = pnv_pci_dma_bus_setup,
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
.setup_msi_irqs = pnv_setup_msi_irqs,
|
||||
.teardown_msi_irqs = pnv_teardown_msi_irqs,
|
||||
|
|
|
@ -601,6 +601,9 @@ int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
|
|||
u64 rpn = __pa(uaddr) >> tbl->it_page_shift;
|
||||
long i;
|
||||
|
||||
if (proto_tce & TCE_PCI_WRITE)
|
||||
proto_tce |= TCE_PCI_READ;
|
||||
|
||||
for (i = 0; i < npages; i++) {
|
||||
unsigned long newtce = proto_tce |
|
||||
((rpn + i) << tbl->it_page_shift);
|
||||
|
@ -622,6 +625,9 @@ int pnv_tce_xchg(struct iommu_table *tbl, long index,
|
|||
|
||||
BUG_ON(*hpa & ~IOMMU_PAGE_MASK(tbl));
|
||||
|
||||
if (newtce & TCE_PCI_WRITE)
|
||||
newtce |= TCE_PCI_READ;
|
||||
|
||||
oldtce = xchg(pnv_tce(tbl, idx), cpu_to_be64(newtce));
|
||||
*hpa = be64_to_cpu(oldtce) & ~(TCE_PCI_READ | TCE_PCI_WRITE);
|
||||
*direction = iommu_tce_direction(oldtce);
|
||||
|
@ -762,6 +768,26 @@ void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
|
|||
phb->dma_dev_setup(phb, pdev);
|
||||
}
|
||||
|
||||
void pnv_pci_dma_bus_setup(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_controller *hose = bus->sysdata;
|
||||
struct pnv_phb *phb = hose->private_data;
|
||||
struct pnv_ioda_pe *pe;
|
||||
|
||||
list_for_each_entry(pe, &phb->ioda.pe_list, list) {
|
||||
if (!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)))
|
||||
continue;
|
||||
|
||||
if (!pe->pbus)
|
||||
continue;
|
||||
|
||||
if (bus->number == ((pe->rid >> 8) & 0xFF)) {
|
||||
pe->pbus = bus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pnv_pci_shutdown(void)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
|
|
|
@ -235,6 +235,7 @@ extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
|
|||
extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
|
||||
|
||||
extern void pnv_pci_dma_dev_setup(struct pci_dev *pdev);
|
||||
extern void pnv_pci_dma_bus_setup(struct pci_bus *bus);
|
||||
extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type);
|
||||
extern void pnv_teardown_msi_irqs(struct pci_dev *pdev);
|
||||
|
||||
|
|
|
@ -157,7 +157,9 @@ ENTRY(chacha20_4block_xor_ssse3)
|
|||
# done with the slightly better performing SSSE3 byte shuffling,
|
||||
# 7/12-bit word rotation uses traditional shift+OR.
|
||||
|
||||
sub $0x40,%rsp
|
||||
mov %rsp,%r11
|
||||
sub $0x80,%rsp
|
||||
and $~63,%rsp
|
||||
|
||||
# x0..15[0-3] = s0..3[0..3]
|
||||
movq 0x00(%rdi),%xmm1
|
||||
|
@ -620,6 +622,6 @@ ENTRY(chacha20_4block_xor_ssse3)
|
|||
pxor %xmm1,%xmm15
|
||||
movdqu %xmm15,0xf0(%rsi)
|
||||
|
||||
add $0x40,%rsp
|
||||
mov %r11,%rsp
|
||||
ret
|
||||
ENDPROC(chacha20_4block_xor_ssse3)
|
||||
|
|
|
@ -363,20 +363,18 @@ static inline enum page_cache_mode pgprot2cachemode(pgprot_t pgprot)
|
|||
}
|
||||
static inline pgprot_t pgprot_4k_2_large(pgprot_t pgprot)
|
||||
{
|
||||
pgprotval_t val = pgprot_val(pgprot);
|
||||
pgprot_t new;
|
||||
unsigned long val;
|
||||
|
||||
val = pgprot_val(pgprot);
|
||||
pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) |
|
||||
((val & _PAGE_PAT) << (_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT));
|
||||
return new;
|
||||
}
|
||||
static inline pgprot_t pgprot_large_2_4k(pgprot_t pgprot)
|
||||
{
|
||||
pgprotval_t val = pgprot_val(pgprot);
|
||||
pgprot_t new;
|
||||
unsigned long val;
|
||||
|
||||
val = pgprot_val(pgprot);
|
||||
pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) |
|
||||
((val & _PAGE_PAT_LARGE) >>
|
||||
(_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT));
|
||||
|
|
|
@ -232,17 +232,31 @@ ENDPROC(copy_user_enhanced_fast_string)
|
|||
|
||||
/*
|
||||
* copy_user_nocache - Uncached memory copy with exception handling
|
||||
* This will force destination/source out of cache for more performance.
|
||||
* This will force destination out of cache for more performance.
|
||||
*
|
||||
* Note: Cached memory copy is used when destination or size is not
|
||||
* naturally aligned. That is:
|
||||
* - Require 8-byte alignment when size is 8 bytes or larger.
|
||||
* - Require 4-byte alignment when size is 4 bytes.
|
||||
*/
|
||||
ENTRY(__copy_user_nocache)
|
||||
ASM_STAC
|
||||
|
||||
/* If size is less than 8 bytes, go to 4-byte copy */
|
||||
cmpl $8,%edx
|
||||
jb 20f /* less then 8 bytes, go to byte copy loop */
|
||||
jb .L_4b_nocache_copy_entry
|
||||
|
||||
/* If destination is not 8-byte aligned, "cache" copy to align it */
|
||||
ALIGN_DESTINATION
|
||||
|
||||
/* Set 4x8-byte copy count and remainder */
|
||||
movl %edx,%ecx
|
||||
andl $63,%edx
|
||||
shrl $6,%ecx
|
||||
jz 17f
|
||||
jz .L_8b_nocache_copy_entry /* jump if count is 0 */
|
||||
|
||||
/* Perform 4x8-byte nocache loop-copy */
|
||||
.L_4x8b_nocache_copy_loop:
|
||||
1: movq (%rsi),%r8
|
||||
2: movq 1*8(%rsi),%r9
|
||||
3: movq 2*8(%rsi),%r10
|
||||
|
@ -262,60 +276,106 @@ ENTRY(__copy_user_nocache)
|
|||
leaq 64(%rsi),%rsi
|
||||
leaq 64(%rdi),%rdi
|
||||
decl %ecx
|
||||
jnz 1b
|
||||
17: movl %edx,%ecx
|
||||
jnz .L_4x8b_nocache_copy_loop
|
||||
|
||||
/* Set 8-byte copy count and remainder */
|
||||
.L_8b_nocache_copy_entry:
|
||||
movl %edx,%ecx
|
||||
andl $7,%edx
|
||||
shrl $3,%ecx
|
||||
jz 20f
|
||||
18: movq (%rsi),%r8
|
||||
19: movnti %r8,(%rdi)
|
||||
jz .L_4b_nocache_copy_entry /* jump if count is 0 */
|
||||
|
||||
/* Perform 8-byte nocache loop-copy */
|
||||
.L_8b_nocache_copy_loop:
|
||||
20: movq (%rsi),%r8
|
||||
21: movnti %r8,(%rdi)
|
||||
leaq 8(%rsi),%rsi
|
||||
leaq 8(%rdi),%rdi
|
||||
decl %ecx
|
||||
jnz 18b
|
||||
20: andl %edx,%edx
|
||||
jz 23f
|
||||
jnz .L_8b_nocache_copy_loop
|
||||
|
||||
/* If no byte left, we're done */
|
||||
.L_4b_nocache_copy_entry:
|
||||
andl %edx,%edx
|
||||
jz .L_finish_copy
|
||||
|
||||
/* If destination is not 4-byte aligned, go to byte copy: */
|
||||
movl %edi,%ecx
|
||||
andl $3,%ecx
|
||||
jnz .L_1b_cache_copy_entry
|
||||
|
||||
/* Set 4-byte copy count (1 or 0) and remainder */
|
||||
movl %edx,%ecx
|
||||
21: movb (%rsi),%al
|
||||
22: movb %al,(%rdi)
|
||||
andl $3,%edx
|
||||
shrl $2,%ecx
|
||||
jz .L_1b_cache_copy_entry /* jump if count is 0 */
|
||||
|
||||
/* Perform 4-byte nocache copy: */
|
||||
30: movl (%rsi),%r8d
|
||||
31: movnti %r8d,(%rdi)
|
||||
leaq 4(%rsi),%rsi
|
||||
leaq 4(%rdi),%rdi
|
||||
|
||||
/* If no bytes left, we're done: */
|
||||
andl %edx,%edx
|
||||
jz .L_finish_copy
|
||||
|
||||
/* Perform byte "cache" loop-copy for the remainder */
|
||||
.L_1b_cache_copy_entry:
|
||||
movl %edx,%ecx
|
||||
.L_1b_cache_copy_loop:
|
||||
40: movb (%rsi),%al
|
||||
41: movb %al,(%rdi)
|
||||
incq %rsi
|
||||
incq %rdi
|
||||
decl %ecx
|
||||
jnz 21b
|
||||
23: xorl %eax,%eax
|
||||
jnz .L_1b_cache_copy_loop
|
||||
|
||||
/* Finished copying; fence the prior stores */
|
||||
.L_finish_copy:
|
||||
xorl %eax,%eax
|
||||
ASM_CLAC
|
||||
sfence
|
||||
ret
|
||||
|
||||
.section .fixup,"ax"
|
||||
30: shll $6,%ecx
|
||||
.L_fixup_4x8b_copy:
|
||||
shll $6,%ecx
|
||||
addl %ecx,%edx
|
||||
jmp 60f
|
||||
40: lea (%rdx,%rcx,8),%rdx
|
||||
jmp 60f
|
||||
50: movl %ecx,%edx
|
||||
60: sfence
|
||||
jmp .L_fixup_handle_tail
|
||||
.L_fixup_8b_copy:
|
||||
lea (%rdx,%rcx,8),%rdx
|
||||
jmp .L_fixup_handle_tail
|
||||
.L_fixup_4b_copy:
|
||||
lea (%rdx,%rcx,4),%rdx
|
||||
jmp .L_fixup_handle_tail
|
||||
.L_fixup_1b_copy:
|
||||
movl %ecx,%edx
|
||||
.L_fixup_handle_tail:
|
||||
sfence
|
||||
jmp copy_user_handle_tail
|
||||
.previous
|
||||
|
||||
_ASM_EXTABLE(1b,30b)
|
||||
_ASM_EXTABLE(2b,30b)
|
||||
_ASM_EXTABLE(3b,30b)
|
||||
_ASM_EXTABLE(4b,30b)
|
||||
_ASM_EXTABLE(5b,30b)
|
||||
_ASM_EXTABLE(6b,30b)
|
||||
_ASM_EXTABLE(7b,30b)
|
||||
_ASM_EXTABLE(8b,30b)
|
||||
_ASM_EXTABLE(9b,30b)
|
||||
_ASM_EXTABLE(10b,30b)
|
||||
_ASM_EXTABLE(11b,30b)
|
||||
_ASM_EXTABLE(12b,30b)
|
||||
_ASM_EXTABLE(13b,30b)
|
||||
_ASM_EXTABLE(14b,30b)
|
||||
_ASM_EXTABLE(15b,30b)
|
||||
_ASM_EXTABLE(16b,30b)
|
||||
_ASM_EXTABLE(18b,40b)
|
||||
_ASM_EXTABLE(19b,40b)
|
||||
_ASM_EXTABLE(21b,50b)
|
||||
_ASM_EXTABLE(22b,50b)
|
||||
_ASM_EXTABLE(1b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(2b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(3b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(4b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(5b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(6b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(7b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(8b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(9b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(10b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(11b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(12b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(13b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(14b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(15b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(16b,.L_fixup_4x8b_copy)
|
||||
_ASM_EXTABLE(20b,.L_fixup_8b_copy)
|
||||
_ASM_EXTABLE(21b,.L_fixup_8b_copy)
|
||||
_ASM_EXTABLE(30b,.L_fixup_4b_copy)
|
||||
_ASM_EXTABLE(31b,.L_fixup_4b_copy)
|
||||
_ASM_EXTABLE(40b,.L_fixup_1b_copy)
|
||||
_ASM_EXTABLE(41b,.L_fixup_1b_copy)
|
||||
ENDPROC(__copy_user_nocache)
|
||||
|
|
|
@ -287,6 +287,9 @@ static noinline int vmalloc_fault(unsigned long address)
|
|||
if (!pmd_k)
|
||||
return -1;
|
||||
|
||||
if (pmd_huge(*pmd_k))
|
||||
return 0;
|
||||
|
||||
pte_k = pte_offset_kernel(pmd_k, address);
|
||||
if (!pte_present(*pte_k))
|
||||
return -1;
|
||||
|
@ -360,8 +363,6 @@ void vmalloc_sync_all(void)
|
|||
* 64-bit:
|
||||
*
|
||||
* Handle a fault on the vmalloc area
|
||||
*
|
||||
* This assumes no large pages in there.
|
||||
*/
|
||||
static noinline int vmalloc_fault(unsigned long address)
|
||||
{
|
||||
|
@ -403,17 +404,23 @@ static noinline int vmalloc_fault(unsigned long address)
|
|||
if (pud_none(*pud_ref))
|
||||
return -1;
|
||||
|
||||
if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
|
||||
if (pud_none(*pud) || pud_pfn(*pud) != pud_pfn(*pud_ref))
|
||||
BUG();
|
||||
|
||||
if (pud_huge(*pud))
|
||||
return 0;
|
||||
|
||||
pmd = pmd_offset(pud, address);
|
||||
pmd_ref = pmd_offset(pud_ref, address);
|
||||
if (pmd_none(*pmd_ref))
|
||||
return -1;
|
||||
|
||||
if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
|
||||
if (pmd_none(*pmd) || pmd_pfn(*pmd) != pmd_pfn(*pmd_ref))
|
||||
BUG();
|
||||
|
||||
if (pmd_huge(*pmd))
|
||||
return 0;
|
||||
|
||||
pte_ref = pte_offset_kernel(pmd_ref, address);
|
||||
if (!pte_present(*pte_ref))
|
||||
return -1;
|
||||
|
|
|
@ -33,7 +33,7 @@ struct cpa_data {
|
|||
pgd_t *pgd;
|
||||
pgprot_t mask_set;
|
||||
pgprot_t mask_clr;
|
||||
int numpages;
|
||||
unsigned long numpages;
|
||||
int flags;
|
||||
unsigned long pfn;
|
||||
unsigned force_split : 1;
|
||||
|
@ -1345,7 +1345,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
|
|||
* CPA operation. Either a large page has been
|
||||
* preserved or a single page update happened.
|
||||
*/
|
||||
BUG_ON(cpa->numpages > numpages);
|
||||
BUG_ON(cpa->numpages > numpages || !cpa->numpages);
|
||||
numpages -= cpa->numpages;
|
||||
if (cpa->flags & (CPA_PAGES_ARRAY | CPA_ARRAY))
|
||||
cpa->curpage++;
|
||||
|
|
|
@ -68,6 +68,18 @@ static struct bio *blk_bio_write_same_split(struct request_queue *q,
|
|||
return bio_split(bio, q->limits.max_write_same_sectors, GFP_NOIO, bs);
|
||||
}
|
||||
|
||||
static inline unsigned get_max_io_size(struct request_queue *q,
|
||||
struct bio *bio)
|
||||
{
|
||||
unsigned sectors = blk_max_size_offset(q, bio->bi_iter.bi_sector);
|
||||
unsigned mask = queue_logical_block_size(q) - 1;
|
||||
|
||||
/* aligned to logical block size */
|
||||
sectors &= ~(mask >> 9);
|
||||
|
||||
return sectors;
|
||||
}
|
||||
|
||||
static struct bio *blk_bio_segment_split(struct request_queue *q,
|
||||
struct bio *bio,
|
||||
struct bio_set *bs,
|
||||
|
@ -79,11 +91,9 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
|
|||
unsigned front_seg_size = bio->bi_seg_front_size;
|
||||
bool do_split = true;
|
||||
struct bio *new = NULL;
|
||||
const unsigned max_sectors = get_max_io_size(q, bio);
|
||||
|
||||
bio_for_each_segment(bv, bio, iter) {
|
||||
if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q))
|
||||
goto split;
|
||||
|
||||
/*
|
||||
* If the queue doesn't support SG gaps and adding this
|
||||
* offset would create a gap, disallow it.
|
||||
|
@ -91,6 +101,21 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
|
|||
if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset))
|
||||
goto split;
|
||||
|
||||
if (sectors + (bv.bv_len >> 9) > max_sectors) {
|
||||
/*
|
||||
* Consider this a new segment if we're splitting in
|
||||
* the middle of this vector.
|
||||
*/
|
||||
if (nsegs < queue_max_segments(q) &&
|
||||
sectors < max_sectors) {
|
||||
nsegs++;
|
||||
sectors = max_sectors;
|
||||
}
|
||||
if (sectors)
|
||||
goto split;
|
||||
/* Make this single bvec as the 1st segment */
|
||||
}
|
||||
|
||||
if (bvprvp && blk_queue_cluster(q)) {
|
||||
if (seg_size + bv.bv_len > queue_max_segment_size(q))
|
||||
goto new_segment;
|
||||
|
|
|
@ -76,6 +76,8 @@ int af_alg_register_type(const struct af_alg_type *type)
|
|||
goto unlock;
|
||||
|
||||
type->ops->owner = THIS_MODULE;
|
||||
if (type->ops_nokey)
|
||||
type->ops_nokey->owner = THIS_MODULE;
|
||||
node->type = type;
|
||||
list_add(&node->list, &alg_types);
|
||||
err = 0;
|
||||
|
@ -125,6 +127,26 @@ int af_alg_release(struct socket *sock)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(af_alg_release);
|
||||
|
||||
void af_alg_release_parent(struct sock *sk)
|
||||
{
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned int nokey = ask->nokey_refcnt;
|
||||
bool last = nokey && !ask->refcnt;
|
||||
|
||||
sk = ask->parent;
|
||||
ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
ask->nokey_refcnt -= nokey;
|
||||
if (!last)
|
||||
last = !--ask->refcnt;
|
||||
release_sock(sk);
|
||||
|
||||
if (last)
|
||||
sock_put(sk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(af_alg_release_parent);
|
||||
|
||||
static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
{
|
||||
const u32 forbidden = CRYPTO_ALG_INTERNAL;
|
||||
|
@ -133,6 +155,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||
struct sockaddr_alg *sa = (void *)uaddr;
|
||||
const struct af_alg_type *type;
|
||||
void *private;
|
||||
int err;
|
||||
|
||||
if (sock->state == SS_CONNECTED)
|
||||
return -EINVAL;
|
||||
|
@ -160,16 +183,22 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||
return PTR_ERR(private);
|
||||
}
|
||||
|
||||
err = -EBUSY;
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt | ask->nokey_refcnt)
|
||||
goto unlock;
|
||||
|
||||
swap(ask->type, type);
|
||||
swap(ask->private, private);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(sk);
|
||||
|
||||
alg_do_release(type, private);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int alg_setkey(struct sock *sk, char __user *ukey,
|
||||
|
@ -202,11 +231,15 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
|
|||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
const struct af_alg_type *type;
|
||||
int err = -ENOPROTOOPT;
|
||||
int err = -EBUSY;
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock;
|
||||
|
||||
type = ask->type;
|
||||
|
||||
err = -ENOPROTOOPT;
|
||||
if (level != SOL_ALG || !type)
|
||||
goto unlock;
|
||||
|
||||
|
@ -238,6 +271,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
|
|||
struct alg_sock *ask = alg_sk(sk);
|
||||
const struct af_alg_type *type;
|
||||
struct sock *sk2;
|
||||
unsigned int nokey;
|
||||
int err;
|
||||
|
||||
lock_sock(sk);
|
||||
|
@ -257,20 +291,29 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
|
|||
security_sk_clone(sk, sk2);
|
||||
|
||||
err = type->accept(ask->private, sk2);
|
||||
if (err) {
|
||||
sk_free(sk2);
|
||||
|
||||
nokey = err == -ENOKEY;
|
||||
if (nokey && type->accept_nokey)
|
||||
err = type->accept_nokey(ask->private, sk2);
|
||||
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
sk2->sk_family = PF_ALG;
|
||||
|
||||
sock_hold(sk);
|
||||
if (nokey || !ask->refcnt++)
|
||||
sock_hold(sk);
|
||||
ask->nokey_refcnt += nokey;
|
||||
alg_sk(sk2)->parent = sk;
|
||||
alg_sk(sk2)->type = type;
|
||||
alg_sk(sk2)->nokey_refcnt = nokey;
|
||||
|
||||
newsock->ops = type->ops;
|
||||
newsock->state = SS_CONNECTED;
|
||||
|
||||
if (nokey)
|
||||
newsock->ops = type->ops_nokey;
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
|
|
|
@ -451,6 +451,7 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
|
|||
struct ahash_alg *alg = crypto_ahash_alg(hash);
|
||||
|
||||
hash->setkey = ahash_nosetkey;
|
||||
hash->has_setkey = false;
|
||||
hash->export = ahash_no_export;
|
||||
hash->import = ahash_no_import;
|
||||
|
||||
|
@ -463,8 +464,10 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
|
|||
hash->finup = alg->finup ?: ahash_def_finup;
|
||||
hash->digest = alg->digest;
|
||||
|
||||
if (alg->setkey)
|
||||
if (alg->setkey) {
|
||||
hash->setkey = alg->setkey;
|
||||
hash->has_setkey = true;
|
||||
}
|
||||
if (alg->export)
|
||||
hash->export = alg->export;
|
||||
if (alg->import)
|
||||
|
|
|
@ -34,6 +34,11 @@ struct hash_ctx {
|
|||
struct ahash_request req;
|
||||
};
|
||||
|
||||
struct algif_hash_tfm {
|
||||
struct crypto_ahash *hash;
|
||||
bool has_key;
|
||||
};
|
||||
|
||||
static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored)
|
||||
{
|
||||
|
@ -49,7 +54,8 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||
|
||||
lock_sock(sk);
|
||||
if (!ctx->more) {
|
||||
err = crypto_ahash_init(&ctx->req);
|
||||
err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req),
|
||||
&ctx->completion);
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
@ -120,6 +126,7 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
|
|||
} else {
|
||||
if (!ctx->more) {
|
||||
err = crypto_ahash_init(&ctx->req);
|
||||
err = af_alg_wait_for_completion(err, &ctx->completion);
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
@ -235,19 +242,151 @@ static struct proto_ops algif_hash_ops = {
|
|||
.accept = hash_accept,
|
||||
};
|
||||
|
||||
static int hash_check_key(struct socket *sock)
|
||||
{
|
||||
int err = 0;
|
||||
struct sock *psk;
|
||||
struct alg_sock *pask;
|
||||
struct algif_hash_tfm *tfm;
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock_child;
|
||||
|
||||
psk = ask->parent;
|
||||
pask = alg_sk(ask->parent);
|
||||
tfm = pask->private;
|
||||
|
||||
err = -ENOKEY;
|
||||
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
||||
if (!tfm->has_key)
|
||||
goto unlock;
|
||||
|
||||
if (!pask->refcnt++)
|
||||
sock_hold(psk);
|
||||
|
||||
ask->refcnt = 1;
|
||||
sock_put(psk);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(psk);
|
||||
unlock_child:
|
||||
release_sock(sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hash_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_sendmsg(sock, msg, size);
|
||||
}
|
||||
|
||||
static ssize_t hash_sendpage_nokey(struct socket *sock, struct page *page,
|
||||
int offset, size_t size, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_sendpage(sock, page, offset, size, flags);
|
||||
}
|
||||
|
||||
static int hash_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_recvmsg(sock, msg, ignored, flags);
|
||||
}
|
||||
|
||||
static int hash_accept_nokey(struct socket *sock, struct socket *newsock,
|
||||
int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_accept(sock, newsock, flags);
|
||||
}
|
||||
|
||||
static struct proto_ops algif_hash_ops_nokey = {
|
||||
.family = PF_ALG,
|
||||
|
||||
.connect = sock_no_connect,
|
||||
.socketpair = sock_no_socketpair,
|
||||
.getname = sock_no_getname,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = sock_no_shutdown,
|
||||
.getsockopt = sock_no_getsockopt,
|
||||
.mmap = sock_no_mmap,
|
||||
.bind = sock_no_bind,
|
||||
.setsockopt = sock_no_setsockopt,
|
||||
.poll = sock_no_poll,
|
||||
|
||||
.release = af_alg_release,
|
||||
.sendmsg = hash_sendmsg_nokey,
|
||||
.sendpage = hash_sendpage_nokey,
|
||||
.recvmsg = hash_recvmsg_nokey,
|
||||
.accept = hash_accept_nokey,
|
||||
};
|
||||
|
||||
static void *hash_bind(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
return crypto_alloc_ahash(name, type, mask);
|
||||
struct algif_hash_tfm *tfm;
|
||||
struct crypto_ahash *hash;
|
||||
|
||||
tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
||||
if (!tfm)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
hash = crypto_alloc_ahash(name, type, mask);
|
||||
if (IS_ERR(hash)) {
|
||||
kfree(tfm);
|
||||
return ERR_CAST(hash);
|
||||
}
|
||||
|
||||
tfm->hash = hash;
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
static void hash_release(void *private)
|
||||
{
|
||||
crypto_free_ahash(private);
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
|
||||
crypto_free_ahash(tfm->hash);
|
||||
kfree(tfm);
|
||||
}
|
||||
|
||||
static int hash_setkey(void *private, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return crypto_ahash_setkey(private, key, keylen);
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
int err;
|
||||
|
||||
err = crypto_ahash_setkey(tfm->hash, key, keylen);
|
||||
tfm->has_key = !err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void hash_sock_destruct(struct sock *sk)
|
||||
|
@ -261,12 +400,14 @@ static void hash_sock_destruct(struct sock *sk)
|
|||
af_alg_release_parent(sk);
|
||||
}
|
||||
|
||||
static int hash_accept_parent(void *private, struct sock *sk)
|
||||
static int hash_accept_parent_nokey(void *private, struct sock *sk)
|
||||
{
|
||||
struct hash_ctx *ctx;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private);
|
||||
unsigned ds = crypto_ahash_digestsize(private);
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
struct crypto_ahash *hash = tfm->hash;
|
||||
unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(hash);
|
||||
unsigned ds = crypto_ahash_digestsize(hash);
|
||||
|
||||
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
||||
if (!ctx)
|
||||
|
@ -286,7 +427,7 @@ static int hash_accept_parent(void *private, struct sock *sk)
|
|||
|
||||
ask->private = ctx;
|
||||
|
||||
ahash_request_set_tfm(&ctx->req, private);
|
||||
ahash_request_set_tfm(&ctx->req, hash);
|
||||
ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
af_alg_complete, &ctx->completion);
|
||||
|
||||
|
@ -295,12 +436,24 @@ static int hash_accept_parent(void *private, struct sock *sk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hash_accept_parent(void *private, struct sock *sk)
|
||||
{
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
|
||||
if (!tfm->has_key && crypto_ahash_has_setkey(tfm->hash))
|
||||
return -ENOKEY;
|
||||
|
||||
return hash_accept_parent_nokey(private, sk);
|
||||
}
|
||||
|
||||
static const struct af_alg_type algif_type_hash = {
|
||||
.bind = hash_bind,
|
||||
.release = hash_release,
|
||||
.setkey = hash_setkey,
|
||||
.accept = hash_accept_parent,
|
||||
.accept_nokey = hash_accept_parent_nokey,
|
||||
.ops = &algif_hash_ops,
|
||||
.ops_nokey = &algif_hash_ops_nokey,
|
||||
.name = "hash",
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
|
|
@ -31,6 +31,11 @@ struct skcipher_sg_list {
|
|||
struct scatterlist sg[0];
|
||||
};
|
||||
|
||||
struct skcipher_tfm {
|
||||
struct crypto_skcipher *skcipher;
|
||||
bool has_key;
|
||||
};
|
||||
|
||||
struct skcipher_ctx {
|
||||
struct list_head tsgl;
|
||||
struct af_alg_sgl rsgl;
|
||||
|
@ -60,18 +65,10 @@ struct skcipher_async_req {
|
|||
struct skcipher_async_rsgl first_sgl;
|
||||
struct list_head list;
|
||||
struct scatterlist *tsg;
|
||||
char iv[];
|
||||
atomic_t *inflight;
|
||||
struct skcipher_request req;
|
||||
};
|
||||
|
||||
#define GET_SREQ(areq, ctx) (struct skcipher_async_req *)((char *)areq + \
|
||||
crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req)))
|
||||
|
||||
#define GET_REQ_SIZE(ctx) \
|
||||
crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req))
|
||||
|
||||
#define GET_IV_SIZE(ctx) \
|
||||
crypto_skcipher_ivsize(crypto_skcipher_reqtfm(&ctx->req))
|
||||
|
||||
#define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
|
||||
sizeof(struct scatterlist) - 1)
|
||||
|
||||
|
@ -97,15 +94,12 @@ static void skcipher_free_async_sgls(struct skcipher_async_req *sreq)
|
|||
|
||||
static void skcipher_async_cb(struct crypto_async_request *req, int err)
|
||||
{
|
||||
struct sock *sk = req->data;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct skcipher_ctx *ctx = ask->private;
|
||||
struct skcipher_async_req *sreq = GET_SREQ(req, ctx);
|
||||
struct skcipher_async_req *sreq = req->data;
|
||||
struct kiocb *iocb = sreq->iocb;
|
||||
|
||||
atomic_dec(&ctx->inflight);
|
||||
atomic_dec(sreq->inflight);
|
||||
skcipher_free_async_sgls(sreq);
|
||||
kfree(req);
|
||||
kzfree(sreq);
|
||||
iocb->ki_complete(iocb, err, err);
|
||||
}
|
||||
|
||||
|
@ -301,8 +295,11 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct skcipher_ctx *ctx = ask->private;
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(&ctx->req);
|
||||
struct skcipher_tfm *skc = pask->private;
|
||||
struct crypto_skcipher *tfm = skc->skcipher;
|
||||
unsigned ivsize = crypto_skcipher_ivsize(tfm);
|
||||
struct skcipher_sg_list *sgl;
|
||||
struct af_alg_control con = {};
|
||||
|
@ -387,7 +384,8 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||
|
||||
sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
|
||||
sg = sgl->sg;
|
||||
sg_unmark_end(sg + sgl->cur);
|
||||
if (sgl->cur)
|
||||
sg_unmark_end(sg + sgl->cur - 1);
|
||||
do {
|
||||
i = sgl->cur;
|
||||
plen = min_t(int, len, PAGE_SIZE);
|
||||
|
@ -503,37 +501,43 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg,
|
|||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct skcipher_ctx *ctx = ask->private;
|
||||
struct skcipher_tfm *skc = pask->private;
|
||||
struct crypto_skcipher *tfm = skc->skcipher;
|
||||
struct skcipher_sg_list *sgl;
|
||||
struct scatterlist *sg;
|
||||
struct skcipher_async_req *sreq;
|
||||
struct skcipher_request *req;
|
||||
struct skcipher_async_rsgl *last_rsgl = NULL;
|
||||
unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx);
|
||||
unsigned int reqlen = sizeof(struct skcipher_async_req) +
|
||||
GET_REQ_SIZE(ctx) + GET_IV_SIZE(ctx);
|
||||
unsigned int txbufs = 0, len = 0, tx_nents;
|
||||
unsigned int reqsize = crypto_skcipher_reqsize(tfm);
|
||||
unsigned int ivsize = crypto_skcipher_ivsize(tfm);
|
||||
int err = -ENOMEM;
|
||||
bool mark = false;
|
||||
char *iv;
|
||||
|
||||
sreq = kzalloc(sizeof(*sreq) + reqsize + ivsize, GFP_KERNEL);
|
||||
if (unlikely(!sreq))
|
||||
goto out;
|
||||
|
||||
req = &sreq->req;
|
||||
iv = (char *)(req + 1) + reqsize;
|
||||
sreq->iocb = msg->msg_iocb;
|
||||
INIT_LIST_HEAD(&sreq->list);
|
||||
sreq->inflight = &ctx->inflight;
|
||||
|
||||
lock_sock(sk);
|
||||
req = kmalloc(reqlen, GFP_KERNEL);
|
||||
if (unlikely(!req))
|
||||
goto unlock;
|
||||
|
||||
sreq = GET_SREQ(req, ctx);
|
||||
sreq->iocb = msg->msg_iocb;
|
||||
memset(&sreq->first_sgl, '\0', sizeof(struct skcipher_async_rsgl));
|
||||
INIT_LIST_HEAD(&sreq->list);
|
||||
tx_nents = skcipher_all_sg_nents(ctx);
|
||||
sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL);
|
||||
if (unlikely(!sreq->tsg)) {
|
||||
kfree(req);
|
||||
if (unlikely(!sreq->tsg))
|
||||
goto unlock;
|
||||
}
|
||||
sg_init_table(sreq->tsg, tx_nents);
|
||||
memcpy(sreq->iv, ctx->iv, GET_IV_SIZE(ctx));
|
||||
skcipher_request_set_tfm(req, crypto_skcipher_reqtfm(&ctx->req));
|
||||
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
skcipher_async_cb, sk);
|
||||
memcpy(iv, ctx->iv, ivsize);
|
||||
skcipher_request_set_tfm(req, tfm);
|
||||
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||
skcipher_async_cb, sreq);
|
||||
|
||||
while (iov_iter_count(&msg->msg_iter)) {
|
||||
struct skcipher_async_rsgl *rsgl;
|
||||
|
@ -609,20 +613,22 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg,
|
|||
sg_mark_end(sreq->tsg + txbufs - 1);
|
||||
|
||||
skcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg,
|
||||
len, sreq->iv);
|
||||
len, iv);
|
||||
err = ctx->enc ? crypto_skcipher_encrypt(req) :
|
||||
crypto_skcipher_decrypt(req);
|
||||
if (err == -EINPROGRESS) {
|
||||
atomic_inc(&ctx->inflight);
|
||||
err = -EIOCBQUEUED;
|
||||
sreq = NULL;
|
||||
goto unlock;
|
||||
}
|
||||
free:
|
||||
skcipher_free_async_sgls(sreq);
|
||||
kfree(req);
|
||||
unlock:
|
||||
skcipher_wmem_wakeup(sk);
|
||||
release_sock(sk);
|
||||
kzfree(sreq);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -631,9 +637,12 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
|
|||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct skcipher_ctx *ctx = ask->private;
|
||||
unsigned bs = crypto_skcipher_blocksize(crypto_skcipher_reqtfm(
|
||||
&ctx->req));
|
||||
struct skcipher_tfm *skc = pask->private;
|
||||
struct crypto_skcipher *tfm = skc->skcipher;
|
||||
unsigned bs = crypto_skcipher_blocksize(tfm);
|
||||
struct skcipher_sg_list *sgl;
|
||||
struct scatterlist *sg;
|
||||
int err = -EAGAIN;
|
||||
|
@ -642,13 +651,6 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
|
|||
|
||||
lock_sock(sk);
|
||||
while (msg_data_left(msg)) {
|
||||
sgl = list_first_entry(&ctx->tsgl,
|
||||
struct skcipher_sg_list, list);
|
||||
sg = sgl->sg;
|
||||
|
||||
while (!sg->length)
|
||||
sg++;
|
||||
|
||||
if (!ctx->used) {
|
||||
err = skcipher_wait_for_data(sk, flags);
|
||||
if (err)
|
||||
|
@ -669,6 +671,13 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
|
|||
if (!used)
|
||||
goto free;
|
||||
|
||||
sgl = list_first_entry(&ctx->tsgl,
|
||||
struct skcipher_sg_list, list);
|
||||
sg = sgl->sg;
|
||||
|
||||
while (!sg->length)
|
||||
sg++;
|
||||
|
||||
skcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used,
|
||||
ctx->iv);
|
||||
|
||||
|
@ -748,19 +757,139 @@ static struct proto_ops algif_skcipher_ops = {
|
|||
.poll = skcipher_poll,
|
||||
};
|
||||
|
||||
static int skcipher_check_key(struct socket *sock)
|
||||
{
|
||||
int err = 0;
|
||||
struct sock *psk;
|
||||
struct alg_sock *pask;
|
||||
struct skcipher_tfm *tfm;
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock_child;
|
||||
|
||||
psk = ask->parent;
|
||||
pask = alg_sk(ask->parent);
|
||||
tfm = pask->private;
|
||||
|
||||
err = -ENOKEY;
|
||||
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
||||
if (!tfm->has_key)
|
||||
goto unlock;
|
||||
|
||||
if (!pask->refcnt++)
|
||||
sock_hold(psk);
|
||||
|
||||
ask->refcnt = 1;
|
||||
sock_put(psk);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(psk);
|
||||
unlock_child:
|
||||
release_sock(sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = skcipher_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skcipher_sendmsg(sock, msg, size);
|
||||
}
|
||||
|
||||
static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
|
||||
int offset, size_t size, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = skcipher_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skcipher_sendpage(sock, page, offset, size, flags);
|
||||
}
|
||||
|
||||
static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = skcipher_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skcipher_recvmsg(sock, msg, ignored, flags);
|
||||
}
|
||||
|
||||
static struct proto_ops algif_skcipher_ops_nokey = {
|
||||
.family = PF_ALG,
|
||||
|
||||
.connect = sock_no_connect,
|
||||
.socketpair = sock_no_socketpair,
|
||||
.getname = sock_no_getname,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = sock_no_shutdown,
|
||||
.getsockopt = sock_no_getsockopt,
|
||||
.mmap = sock_no_mmap,
|
||||
.bind = sock_no_bind,
|
||||
.accept = sock_no_accept,
|
||||
.setsockopt = sock_no_setsockopt,
|
||||
|
||||
.release = af_alg_release,
|
||||
.sendmsg = skcipher_sendmsg_nokey,
|
||||
.sendpage = skcipher_sendpage_nokey,
|
||||
.recvmsg = skcipher_recvmsg_nokey,
|
||||
.poll = skcipher_poll,
|
||||
};
|
||||
|
||||
static void *skcipher_bind(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
return crypto_alloc_skcipher(name, type, mask);
|
||||
struct skcipher_tfm *tfm;
|
||||
struct crypto_skcipher *skcipher;
|
||||
|
||||
tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
||||
if (!tfm)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
skcipher = crypto_alloc_skcipher(name, type, mask);
|
||||
if (IS_ERR(skcipher)) {
|
||||
kfree(tfm);
|
||||
return ERR_CAST(skcipher);
|
||||
}
|
||||
|
||||
tfm->skcipher = skcipher;
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
static void skcipher_release(void *private)
|
||||
{
|
||||
crypto_free_skcipher(private);
|
||||
struct skcipher_tfm *tfm = private;
|
||||
|
||||
crypto_free_skcipher(tfm->skcipher);
|
||||
kfree(tfm);
|
||||
}
|
||||
|
||||
static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return crypto_skcipher_setkey(private, key, keylen);
|
||||
struct skcipher_tfm *tfm = private;
|
||||
int err;
|
||||
|
||||
err = crypto_skcipher_setkey(tfm->skcipher, key, keylen);
|
||||
tfm->has_key = !err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void skcipher_wait(struct sock *sk)
|
||||
|
@ -788,24 +917,26 @@ static void skcipher_sock_destruct(struct sock *sk)
|
|||
af_alg_release_parent(sk);
|
||||
}
|
||||
|
||||
static int skcipher_accept_parent(void *private, struct sock *sk)
|
||||
static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
|
||||
{
|
||||
struct skcipher_ctx *ctx;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(private);
|
||||
struct skcipher_tfm *tfm = private;
|
||||
struct crypto_skcipher *skcipher = tfm->skcipher;
|
||||
unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(skcipher);
|
||||
|
||||
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(private),
|
||||
ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher),
|
||||
GFP_KERNEL);
|
||||
if (!ctx->iv) {
|
||||
sock_kfree_s(sk, ctx, len);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(ctx->iv, 0, crypto_skcipher_ivsize(private));
|
||||
memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher));
|
||||
|
||||
INIT_LIST_HEAD(&ctx->tsgl);
|
||||
ctx->len = len;
|
||||
|
@ -818,8 +949,9 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
|
|||
|
||||
ask->private = ctx;
|
||||
|
||||
skcipher_request_set_tfm(&ctx->req, private);
|
||||
skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
skcipher_request_set_tfm(&ctx->req, skcipher);
|
||||
skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_SLEEP |
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
af_alg_complete, &ctx->completion);
|
||||
|
||||
sk->sk_destruct = skcipher_sock_destruct;
|
||||
|
@ -827,12 +959,24 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int skcipher_accept_parent(void *private, struct sock *sk)
|
||||
{
|
||||
struct skcipher_tfm *tfm = private;
|
||||
|
||||
if (!tfm->has_key && crypto_skcipher_has_setkey(tfm->skcipher))
|
||||
return -ENOKEY;
|
||||
|
||||
return skcipher_accept_parent_nokey(private, sk);
|
||||
}
|
||||
|
||||
static const struct af_alg_type algif_type_skcipher = {
|
||||
.bind = skcipher_bind,
|
||||
.release = skcipher_release,
|
||||
.setkey = skcipher_setkey,
|
||||
.accept = skcipher_accept_parent,
|
||||
.accept_nokey = skcipher_accept_parent_nokey,
|
||||
.ops = &algif_skcipher_ops,
|
||||
.ops_nokey = &algif_skcipher_ops_nokey,
|
||||
.name = "skcipher",
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
|
|
@ -172,4 +172,3 @@ MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
|
|||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_CRYPTO("crc32c");
|
||||
MODULE_ALIAS_CRYPTO("crc32c-generic");
|
||||
MODULE_SOFTDEP("pre: crc32c");
|
||||
|
|
|
@ -499,6 +499,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
if (link->dump == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
down_read(&crypto_alg_sem);
|
||||
list_for_each_entry(alg, &crypto_alg_list, cra_list)
|
||||
dump_alloc += CRYPTO_REPORT_MAXSIZE;
|
||||
|
||||
|
@ -508,8 +509,11 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
.done = link->done,
|
||||
.min_dump_alloc = dump_alloc,
|
||||
};
|
||||
return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
|
||||
err = netlink_dump_start(crypto_nlsk, skb, nlh, &c);
|
||||
}
|
||||
up_read(&crypto_alg_sem);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
|
||||
|
|
|
@ -354,9 +354,10 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
|
|||
crt->final = shash_async_final;
|
||||
crt->finup = shash_async_finup;
|
||||
crt->digest = shash_async_digest;
|
||||
crt->setkey = shash_async_setkey;
|
||||
|
||||
crt->has_setkey = alg->setkey != shash_no_setkey;
|
||||
|
||||
if (alg->setkey)
|
||||
crt->setkey = shash_async_setkey;
|
||||
if (alg->export)
|
||||
crt->export = shash_async_export;
|
||||
if (alg->import)
|
||||
|
|
|
@ -118,6 +118,7 @@ static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
|
|||
skcipher->decrypt = skcipher_decrypt_blkcipher;
|
||||
|
||||
skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher);
|
||||
skcipher->has_setkey = calg->cra_blkcipher.max_keysize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -210,6 +211,7 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
|
|||
skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
|
||||
skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) +
|
||||
sizeof(struct ablkcipher_request);
|
||||
skcipher->has_setkey = calg->cra_ablkcipher.max_keysize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -264,6 +264,26 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
|||
{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b2), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b3), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b4), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b5), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b6), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b7), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19bE), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19bF), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c0), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c1), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c2), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c3), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c4), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c5), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c6), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19c7), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
|
||||
|
|
|
@ -495,8 +495,8 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
|
|||
}
|
||||
}
|
||||
|
||||
/* fabricate port_map from cap.nr_ports */
|
||||
if (!port_map) {
|
||||
/* fabricate port_map from cap.nr_ports for < AHCI 1.3 */
|
||||
if (!port_map && vers < 0x10300) {
|
||||
port_map = (1 << ahci_nr_ports(cap)) - 1;
|
||||
dev_warn(dev, "forcing PORTS_IMPL to 0x%x\n", port_map);
|
||||
|
||||
|
|
|
@ -513,10 +513,15 @@ static int platform_drv_probe(struct device *_dev)
|
|||
return ret;
|
||||
|
||||
ret = dev_pm_domain_attach(_dev, true);
|
||||
if (ret != -EPROBE_DEFER && drv->probe) {
|
||||
ret = drv->probe(dev);
|
||||
if (ret)
|
||||
dev_pm_domain_detach(_dev, true);
|
||||
if (ret != -EPROBE_DEFER) {
|
||||
if (drv->probe) {
|
||||
ret = drv->probe(dev);
|
||||
if (ret)
|
||||
dev_pm_domain_detach(_dev, true);
|
||||
} else {
|
||||
/* don't fail if just dev_pm_domain_attach failed */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
|
||||
|
|
|
@ -76,7 +76,7 @@ static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm)
|
|||
*/
|
||||
static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp)
|
||||
{
|
||||
struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL);
|
||||
struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_NOIO);
|
||||
if (!zstrm)
|
||||
return NULL;
|
||||
|
||||
|
@ -85,7 +85,7 @@ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp)
|
|||
* allocate 2 pages. 1 for compressed data, plus 1 extra for the
|
||||
* case when compressed size is larger than the original one
|
||||
*/
|
||||
zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
|
||||
zstrm->buffer = (void *)__get_free_pages(GFP_NOIO | __GFP_ZERO, 1);
|
||||
if (!zstrm->private || !zstrm->buffer) {
|
||||
zcomp_strm_free(comp, zstrm);
|
||||
zstrm = NULL;
|
||||
|
|
|
@ -10,17 +10,36 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/lz4.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include "zcomp_lz4.h"
|
||||
|
||||
static void *zcomp_lz4_create(void)
|
||||
{
|
||||
return kzalloc(LZ4_MEM_COMPRESS, GFP_KERNEL);
|
||||
void *ret;
|
||||
|
||||
/*
|
||||
* This function can be called in swapout/fs write path
|
||||
* so we can't use GFP_FS|IO. And it assumes we already
|
||||
* have at least one stream in zram initialization so we
|
||||
* don't do best effort to allocate more stream in here.
|
||||
* A default stream will work well without further multiple
|
||||
* streams. That's why we use NORETRY | NOWARN.
|
||||
*/
|
||||
ret = kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY |
|
||||
__GFP_NOWARN);
|
||||
if (!ret)
|
||||
ret = __vmalloc(LZ4_MEM_COMPRESS,
|
||||
GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN |
|
||||
__GFP_ZERO | __GFP_HIGHMEM,
|
||||
PAGE_KERNEL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void zcomp_lz4_destroy(void *private)
|
||||
{
|
||||
kfree(private);
|
||||
kvfree(private);
|
||||
}
|
||||
|
||||
static int zcomp_lz4_compress(const unsigned char *src, unsigned char *dst,
|
||||
|
|
|
@ -10,17 +10,36 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/lzo.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include "zcomp_lzo.h"
|
||||
|
||||
static void *lzo_create(void)
|
||||
{
|
||||
return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
|
||||
void *ret;
|
||||
|
||||
/*
|
||||
* This function can be called in swapout/fs write path
|
||||
* so we can't use GFP_FS|IO. And it assumes we already
|
||||
* have at least one stream in zram initialization so we
|
||||
* don't do best effort to allocate more stream in here.
|
||||
* A default stream will work well without further multiple
|
||||
* streams. That's why we use NORETRY | NOWARN.
|
||||
*/
|
||||
ret = kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY |
|
||||
__GFP_NOWARN);
|
||||
if (!ret)
|
||||
ret = __vmalloc(LZO1X_MEM_COMPRESS,
|
||||
GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN |
|
||||
__GFP_ZERO | __GFP_HIGHMEM,
|
||||
PAGE_KERNEL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lzo_destroy(void *private)
|
||||
{
|
||||
kfree(private);
|
||||
kvfree(private);
|
||||
}
|
||||
|
||||
static int lzo_compress(const unsigned char *src, unsigned char *dst,
|
||||
|
|
|
@ -1325,7 +1325,6 @@ static int zram_remove(struct zram *zram)
|
|||
|
||||
pr_info("Removed device: %s\n", zram->disk->disk_name);
|
||||
|
||||
idr_remove(&zram_index_idr, zram->disk->first_minor);
|
||||
blk_cleanup_queue(zram->disk->queue);
|
||||
del_gendisk(zram->disk);
|
||||
put_disk(zram->disk);
|
||||
|
@ -1367,10 +1366,12 @@ static ssize_t hot_remove_store(struct class *class,
|
|||
mutex_lock(&zram_index_mutex);
|
||||
|
||||
zram = idr_find(&zram_index_idr, dev_id);
|
||||
if (zram)
|
||||
if (zram) {
|
||||
ret = zram_remove(zram);
|
||||
else
|
||||
idr_remove(&zram_index_idr, dev_id);
|
||||
} else {
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
mutex_unlock(&zram_index_mutex);
|
||||
return ret ? ret : count;
|
||||
|
|
|
@ -783,7 +783,7 @@ static void atmel_sha_finish_req(struct ahash_request *req, int err)
|
|||
dd->flags &= ~(SHA_FLAGS_BUSY | SHA_FLAGS_FINAL | SHA_FLAGS_CPU |
|
||||
SHA_FLAGS_DMA_READY | SHA_FLAGS_OUTPUT_READY);
|
||||
|
||||
clk_disable_unprepare(dd->iclk);
|
||||
clk_disable(dd->iclk);
|
||||
|
||||
if (req->base.complete)
|
||||
req->base.complete(&req->base, err);
|
||||
|
@ -796,7 +796,7 @@ static int atmel_sha_hw_init(struct atmel_sha_dev *dd)
|
|||
{
|
||||
int err;
|
||||
|
||||
err = clk_prepare_enable(dd->iclk);
|
||||
err = clk_enable(dd->iclk);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -823,7 +823,7 @@ static void atmel_sha_hw_version_init(struct atmel_sha_dev *dd)
|
|||
dev_info(dd->dev,
|
||||
"version: 0x%x\n", dd->hw_version);
|
||||
|
||||
clk_disable_unprepare(dd->iclk);
|
||||
clk_disable(dd->iclk);
|
||||
}
|
||||
|
||||
static int atmel_sha_handle_queue(struct atmel_sha_dev *dd,
|
||||
|
@ -1411,6 +1411,10 @@ static int atmel_sha_probe(struct platform_device *pdev)
|
|||
goto res_err;
|
||||
}
|
||||
|
||||
err = clk_prepare(sha_dd->iclk);
|
||||
if (err)
|
||||
goto res_err;
|
||||
|
||||
atmel_sha_hw_version_init(sha_dd);
|
||||
|
||||
atmel_sha_get_cap(sha_dd);
|
||||
|
@ -1422,12 +1426,12 @@ static int atmel_sha_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(pdata)) {
|
||||
dev_err(&pdev->dev, "platform data not available\n");
|
||||
err = PTR_ERR(pdata);
|
||||
goto res_err;
|
||||
goto iclk_unprepare;
|
||||
}
|
||||
}
|
||||
if (!pdata->dma_slave) {
|
||||
err = -ENXIO;
|
||||
goto res_err;
|
||||
goto iclk_unprepare;
|
||||
}
|
||||
err = atmel_sha_dma_init(sha_dd, pdata);
|
||||
if (err)
|
||||
|
@ -1458,6 +1462,8 @@ err_algs:
|
|||
if (sha_dd->caps.has_dma)
|
||||
atmel_sha_dma_cleanup(sha_dd);
|
||||
err_sha_dma:
|
||||
iclk_unprepare:
|
||||
clk_unprepare(sha_dd->iclk);
|
||||
res_err:
|
||||
tasklet_kill(&sha_dd->done_task);
|
||||
sha_dd_err:
|
||||
|
@ -1484,12 +1490,7 @@ static int atmel_sha_remove(struct platform_device *pdev)
|
|||
if (sha_dd->caps.has_dma)
|
||||
atmel_sha_dma_cleanup(sha_dd);
|
||||
|
||||
iounmap(sha_dd->io_base);
|
||||
|
||||
clk_put(sha_dd->iclk);
|
||||
|
||||
if (sha_dd->irq >= 0)
|
||||
free_irq(sha_dd->irq, sha_dd);
|
||||
clk_unprepare(sha_dd->iclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -534,8 +534,8 @@ static int caam_probe(struct platform_device *pdev)
|
|||
* long pointers in master configuration register
|
||||
*/
|
||||
clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH |
|
||||
MCFGR_WDENABLE | (sizeof(dma_addr_t) == sizeof(u64) ?
|
||||
MCFGR_LONG_PTR : 0));
|
||||
MCFGR_AWCACHE_BUFF | MCFGR_WDENABLE |
|
||||
(sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
|
||||
|
||||
/*
|
||||
* Read the Compile Time paramters and SCFGR to determine
|
||||
|
|
|
@ -306,7 +306,7 @@ static int mv_cesa_dev_dma_init(struct mv_cesa_dev *cesa)
|
|||
return -ENOMEM;
|
||||
|
||||
dma->padding_pool = dmam_pool_create("cesa_padding", dev, 72, 1, 0);
|
||||
if (!dma->cache_pool)
|
||||
if (!dma->padding_pool)
|
||||
return -ENOMEM;
|
||||
|
||||
cesa->dma = dma;
|
||||
|
|
|
@ -39,6 +39,7 @@ static struct sun4i_ss_alg_template ss_algs[] = {
|
|||
.import = sun4i_hash_import_md5,
|
||||
.halg = {
|
||||
.digestsize = MD5_DIGEST_SIZE,
|
||||
.statesize = sizeof(struct md5_state),
|
||||
.base = {
|
||||
.cra_name = "md5",
|
||||
.cra_driver_name = "md5-sun4i-ss",
|
||||
|
@ -66,6 +67,7 @@ static struct sun4i_ss_alg_template ss_algs[] = {
|
|||
.import = sun4i_hash_import_sha1,
|
||||
.halg = {
|
||||
.digestsize = SHA1_DIGEST_SIZE,
|
||||
.statesize = sizeof(struct sha1_state),
|
||||
.base = {
|
||||
.cra_name = "sha1",
|
||||
.cra_driver_name = "sha1-sun4i-ss",
|
||||
|
|
|
@ -357,8 +357,19 @@ static void mt_feature_mapping(struct hid_device *hdev,
|
|||
break;
|
||||
}
|
||||
|
||||
td->inputmode = field->report->id;
|
||||
td->inputmode_index = usage->usage_index;
|
||||
if (td->inputmode < 0) {
|
||||
td->inputmode = field->report->id;
|
||||
td->inputmode_index = usage->usage_index;
|
||||
} else {
|
||||
/*
|
||||
* Some elan panels wrongly declare 2 input mode
|
||||
* features, and silently ignore when we set the
|
||||
* value in the second field. Skip the second feature
|
||||
* and hope for the best.
|
||||
*/
|
||||
dev_info(&hdev->dev,
|
||||
"Ignoring the extra HID_DG_INPUTMODE\n");
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_DG_CONTACTMAX:
|
||||
|
|
|
@ -477,8 +477,6 @@ static void hid_ctrl(struct urb *urb)
|
|||
struct usbhid_device *usbhid = hid->driver_data;
|
||||
int unplug = 0, status = urb->status;
|
||||
|
||||
spin_lock(&usbhid->lock);
|
||||
|
||||
switch (status) {
|
||||
case 0: /* success */
|
||||
if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
|
||||
|
@ -498,6 +496,8 @@ static void hid_ctrl(struct urb *urb)
|
|||
hid_warn(urb->dev, "ctrl urb status %d received\n", status);
|
||||
}
|
||||
|
||||
spin_lock(&usbhid->lock);
|
||||
|
||||
if (unplug) {
|
||||
usbhid->ctrltail = usbhid->ctrlhead;
|
||||
} else {
|
||||
|
|
|
@ -313,6 +313,10 @@ int of_hwspin_lock_get_id(struct device_node *np, int index)
|
|||
hwlock = radix_tree_deref_slot(slot);
|
||||
if (unlikely(!hwlock))
|
||||
continue;
|
||||
if (radix_tree_is_indirect_ptr(hwlock)) {
|
||||
slot = radix_tree_iter_retry(&iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hwlock->bank->dev->of_node == args.np) {
|
||||
ret = 0;
|
||||
|
|
|
@ -173,6 +173,7 @@ config STK8312
|
|||
config STK8BA50
|
||||
tristate "Sensortek STK8BA50 3-Axis Accelerometer Driver"
|
||||
depends on I2C
|
||||
depends on IIO_TRIGGER
|
||||
help
|
||||
Say yes here to get support for the Sensortek STK8BA50 3-axis
|
||||
accelerometer.
|
||||
|
|
|
@ -372,6 +372,7 @@ config TWL6030_GPADC
|
|||
config VF610_ADC
|
||||
tristate "Freescale vf610 ADC driver"
|
||||
depends on OF
|
||||
depends on HAS_IOMEM
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
help
|
||||
|
|
|
@ -289,7 +289,7 @@ static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
|
|||
goto error_kfifo_free;
|
||||
|
||||
indio_dev->setup_ops = setup_ops;
|
||||
indio_dev->modes |= INDIO_BUFFER_HARDWARE;
|
||||
indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -300,6 +300,7 @@ static int mcp4725_probe(struct i2c_client *client,
|
|||
data->client = client;
|
||||
|
||||
indio_dev->dev.parent = &client->dev;
|
||||
indio_dev->name = id->name;
|
||||
indio_dev->info = &mcp4725_info;
|
||||
indio_dev->channels = &mcp4725_channel;
|
||||
indio_dev->num_channels = 1;
|
||||
|
|
|
@ -43,7 +43,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev,
|
|||
return -ENOMEM;
|
||||
|
||||
rx = adis->buffer;
|
||||
tx = rx + indio_dev->scan_bytes;
|
||||
tx = rx + scan_count;
|
||||
|
||||
spi_message_init(&adis->msg);
|
||||
|
||||
|
|
|
@ -351,6 +351,8 @@ EXPORT_SYMBOL_GPL(iio_channel_get);
|
|||
|
||||
void iio_channel_release(struct iio_channel *channel)
|
||||
{
|
||||
if (!channel)
|
||||
return;
|
||||
iio_device_put(channel->indio_dev);
|
||||
kfree(channel);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,9 @@ static const struct iio_chan_spec acpi_als_channels[] = {
|
|||
.realbits = 32,
|
||||
.storagebits = 32,
|
||||
},
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
/* _RAW is here for backward ABI compatibility */
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_PROCESSED),
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -152,7 +154,7 @@ static int acpi_als_read_raw(struct iio_dev *indio_dev,
|
|||
s32 temp_val;
|
||||
int ret;
|
||||
|
||||
if (mask != IIO_CHAN_INFO_RAW)
|
||||
if ((mask != IIO_CHAN_INFO_PROCESSED) && (mask != IIO_CHAN_INFO_RAW))
|
||||
return -EINVAL;
|
||||
|
||||
/* we support only illumination (_ALI) so far. */
|
||||
|
|
|
@ -180,7 +180,7 @@ static const struct ltr501_samp_table ltr501_ps_samp_table[] = {
|
|||
{500000, 2000000}
|
||||
};
|
||||
|
||||
static unsigned int ltr501_match_samp_freq(const struct ltr501_samp_table *tab,
|
||||
static int ltr501_match_samp_freq(const struct ltr501_samp_table *tab,
|
||||
int len, int val, int val2)
|
||||
{
|
||||
int i, freq;
|
||||
|
|
|
@ -117,7 +117,7 @@ static int mpl115_read_raw(struct iio_dev *indio_dev,
|
|||
*val = ret >> 6;
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
*val = 605;
|
||||
*val = -605;
|
||||
*val2 = 750000;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
|
|
|
@ -1222,7 +1222,7 @@ static int elantech_set_input_params(struct psmouse *psmouse)
|
|||
input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2,
|
||||
ETP_WMAX_V2, 0, 0);
|
||||
}
|
||||
input_mt_init_slots(dev, 2, 0);
|
||||
input_mt_init_slots(dev, 2, INPUT_MT_SEMI_MT);
|
||||
input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
|
||||
input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
|
||||
break;
|
||||
|
|
|
@ -458,8 +458,6 @@ int vmmouse_init(struct psmouse *psmouse)
|
|||
priv->abs_dev = abs_dev;
|
||||
psmouse->private = priv;
|
||||
|
||||
input_set_capability(rel_dev, EV_REL, REL_WHEEL);
|
||||
|
||||
/* Set up and register absolute device */
|
||||
snprintf(priv->phys, sizeof(priv->phys), "%s/input1",
|
||||
psmouse->ps2dev.serio->phys);
|
||||
|
@ -475,10 +473,6 @@ int vmmouse_init(struct psmouse *psmouse)
|
|||
abs_dev->id.version = psmouse->model;
|
||||
abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;
|
||||
|
||||
error = input_register_device(priv->abs_dev);
|
||||
if (error)
|
||||
goto init_fail;
|
||||
|
||||
/* Set absolute device capabilities */
|
||||
input_set_capability(abs_dev, EV_KEY, BTN_LEFT);
|
||||
input_set_capability(abs_dev, EV_KEY, BTN_RIGHT);
|
||||
|
@ -488,6 +482,13 @@ int vmmouse_init(struct psmouse *psmouse)
|
|||
input_set_abs_params(abs_dev, ABS_X, 0, VMMOUSE_MAX_X, 0, 0);
|
||||
input_set_abs_params(abs_dev, ABS_Y, 0, VMMOUSE_MAX_Y, 0, 0);
|
||||
|
||||
error = input_register_device(priv->abs_dev);
|
||||
if (error)
|
||||
goto init_fail;
|
||||
|
||||
/* Add wheel capability to the relative device */
|
||||
input_set_capability(rel_dev, EV_REL, REL_WHEEL);
|
||||
|
||||
psmouse->protocol_handler = vmmouse_process_byte;
|
||||
psmouse->disconnect = vmmouse_disconnect;
|
||||
psmouse->reconnect = vmmouse_reconnect;
|
||||
|
|
|
@ -257,6 +257,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Fujitsu Lifebook U745 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Fujitsu T70H */
|
||||
.matches = {
|
||||
|
|
|
@ -1905,7 +1905,7 @@ static void do_attach(struct iommu_dev_data *dev_data,
|
|||
/* Update device table */
|
||||
set_dte_entry(dev_data->devid, domain, ats);
|
||||
if (alias != dev_data->devid)
|
||||
set_dte_entry(dev_data->devid, domain, ats);
|
||||
set_dte_entry(alias, domain, ats);
|
||||
|
||||
device_flush_dte(dev_data);
|
||||
}
|
||||
|
|
|
@ -1347,7 +1347,7 @@ void dmar_disable_qi(struct intel_iommu *iommu)
|
|||
|
||||
raw_spin_lock_irqsave(&iommu->register_lock, flags);
|
||||
|
||||
sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
|
||||
sts = readl(iommu->reg + DMAR_GSTS_REG);
|
||||
if (!(sts & DMA_GSTS_QIES))
|
||||
goto end;
|
||||
|
||||
|
|
|
@ -1489,7 +1489,7 @@ static void iommu_disable_dev_iotlb(struct device_domain_info *info)
|
|||
{
|
||||
struct pci_dev *pdev;
|
||||
|
||||
if (dev_is_pci(info->dev))
|
||||
if (!dev_is_pci(info->dev))
|
||||
return;
|
||||
|
||||
pdev = to_pci_dev(info->dev);
|
||||
|
|
|
@ -249,12 +249,30 @@ static void intel_flush_pasid_dev(struct intel_svm *svm, struct intel_svm_dev *s
|
|||
static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
|
||||
{
|
||||
struct intel_svm *svm = container_of(mn, struct intel_svm, notifier);
|
||||
struct intel_svm_dev *sdev;
|
||||
|
||||
/* This might end up being called from exit_mmap(), *before* the page
|
||||
* tables are cleared. And __mmu_notifier_release() will delete us from
|
||||
* the list of notifiers so that our invalidate_range() callback doesn't
|
||||
* get called when the page tables are cleared. So we need to protect
|
||||
* against hardware accessing those page tables.
|
||||
*
|
||||
* We do it by clearing the entry in the PASID table and then flushing
|
||||
* the IOTLB and the PASID table caches. This might upset hardware;
|
||||
* perhaps we'll want to point the PASID to a dummy PGD (like the zero
|
||||
* page) so that we end up taking a fault that the hardware really
|
||||
* *has* to handle gracefully without affecting other processes.
|
||||
*/
|
||||
svm->iommu->pasid_table[svm->pasid].val = 0;
|
||||
wmb();
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(sdev, &svm->devs, list) {
|
||||
intel_flush_pasid_dev(svm, sdev, svm->pasid);
|
||||
intel_flush_svm_range_dev(svm, sdev, 0, -1, 0, !svm->mm);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
/* There's no need to do any flush because we can't get here if there
|
||||
* are any devices left anyway. */
|
||||
WARN_ON(!list_empty(&svm->devs));
|
||||
}
|
||||
|
||||
static const struct mmu_notifier_ops intel_mmuops = {
|
||||
|
@ -379,7 +397,6 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
|
|||
goto out;
|
||||
}
|
||||
iommu->pasid_table[svm->pasid].val = (u64)__pa(mm->pgd) | 1;
|
||||
mm = NULL;
|
||||
} else
|
||||
iommu->pasid_table[svm->pasid].val = (u64)__pa(init_mm.pgd) | 1 | (1ULL << 11);
|
||||
wmb();
|
||||
|
@ -442,11 +459,11 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
|
|||
kfree_rcu(sdev, rcu);
|
||||
|
||||
if (list_empty(&svm->devs)) {
|
||||
mmu_notifier_unregister(&svm->notifier, svm->mm);
|
||||
|
||||
idr_remove(&svm->iommu->pasid_idr, svm->pasid);
|
||||
if (svm->mm)
|
||||
mmput(svm->mm);
|
||||
mmu_notifier_unregister(&svm->notifier, svm->mm);
|
||||
|
||||
/* We mandate that no page faults may be outstanding
|
||||
* for the PASID when intel_svm_unbind_mm() is called.
|
||||
* If that is not obeyed, subtle errors will happen.
|
||||
|
@ -507,6 +524,10 @@ static irqreturn_t prq_event_thread(int irq, void *d)
|
|||
struct intel_svm *svm = NULL;
|
||||
int head, tail, handled = 0;
|
||||
|
||||
/* Clear PPR bit before reading head/tail registers, to
|
||||
* ensure that we get a new interrupt if needed. */
|
||||
writel(DMA_PRS_PPR, iommu->reg + DMAR_PRS_REG);
|
||||
|
||||
tail = dmar_readq(iommu->reg + DMAR_PQT_REG) & PRQ_RING_MASK;
|
||||
head = dmar_readq(iommu->reg + DMAR_PQH_REG) & PRQ_RING_MASK;
|
||||
while (head != tail) {
|
||||
|
@ -551,6 +572,9 @@ static irqreturn_t prq_event_thread(int irq, void *d)
|
|||
* any faults on kernel addresses. */
|
||||
if (!svm->mm)
|
||||
goto bad_req;
|
||||
/* If the mm is already defunct, don't handle faults. */
|
||||
if (!atomic_inc_not_zero(&svm->mm->mm_users))
|
||||
goto bad_req;
|
||||
down_read(&svm->mm->mmap_sem);
|
||||
vma = find_extend_vma(svm->mm, address);
|
||||
if (!vma || address < vma->vm_start)
|
||||
|
@ -567,6 +591,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
|
|||
result = QI_RESP_SUCCESS;
|
||||
invalid:
|
||||
up_read(&svm->mm->mmap_sem);
|
||||
mmput(svm->mm);
|
||||
bad_req:
|
||||
/* Accounting for major/minor faults? */
|
||||
rcu_read_lock();
|
||||
|
|
|
@ -629,7 +629,7 @@ static void iommu_disable_irq_remapping(struct intel_iommu *iommu)
|
|||
|
||||
raw_spin_lock_irqsave(&iommu->register_lock, flags);
|
||||
|
||||
sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
|
||||
sts = readl(iommu->reg + DMAR_GSTS_REG);
|
||||
if (!(sts & DMA_GSTS_IRES))
|
||||
goto end;
|
||||
|
||||
|
|
|
@ -405,17 +405,18 @@ static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
|
|||
arm_lpae_iopte *start, *end;
|
||||
unsigned long table_size;
|
||||
|
||||
/* Only leaf entries at the last level */
|
||||
if (lvl == ARM_LPAE_MAX_LEVELS - 1)
|
||||
return;
|
||||
|
||||
if (lvl == ARM_LPAE_START_LVL(data))
|
||||
table_size = data->pgd_size;
|
||||
else
|
||||
table_size = 1UL << data->pg_shift;
|
||||
|
||||
start = ptep;
|
||||
end = (void *)ptep + table_size;
|
||||
|
||||
/* Only leaf entries at the last level */
|
||||
if (lvl == ARM_LPAE_MAX_LEVELS - 1)
|
||||
end = ptep;
|
||||
else
|
||||
end = (void *)ptep + table_size;
|
||||
|
||||
while (ptep != end) {
|
||||
arm_lpae_iopte pte = *ptep++;
|
||||
|
|
|
@ -2017,28 +2017,32 @@ int md_integrity_register(struct mddev *mddev)
|
|||
}
|
||||
EXPORT_SYMBOL(md_integrity_register);
|
||||
|
||||
/* Disable data integrity if non-capable/non-matching disk is being added */
|
||||
void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev)
|
||||
/*
|
||||
* Attempt to add an rdev, but only if it is consistent with the current
|
||||
* integrity profile
|
||||
*/
|
||||
int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev)
|
||||
{
|
||||
struct blk_integrity *bi_rdev;
|
||||
struct blk_integrity *bi_mddev;
|
||||
char name[BDEVNAME_SIZE];
|
||||
|
||||
if (!mddev->gendisk)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
bi_rdev = bdev_get_integrity(rdev->bdev);
|
||||
bi_mddev = blk_get_integrity(mddev->gendisk);
|
||||
|
||||
if (!bi_mddev) /* nothing to do */
|
||||
return;
|
||||
if (rdev->raid_disk < 0) /* skip spares */
|
||||
return;
|
||||
if (bi_rdev && blk_integrity_compare(mddev->gendisk,
|
||||
rdev->bdev->bd_disk) >= 0)
|
||||
return;
|
||||
WARN_ON_ONCE(!mddev->suspended);
|
||||
printk(KERN_NOTICE "disabling data integrity on %s\n", mdname(mddev));
|
||||
blk_integrity_unregister(mddev->gendisk);
|
||||
return 0;
|
||||
|
||||
if (blk_integrity_compare(mddev->gendisk, rdev->bdev->bd_disk) != 0) {
|
||||
printk(KERN_NOTICE "%s: incompatible integrity profile for %s\n",
|
||||
mdname(mddev), bdevname(rdev->bdev, name));
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(md_integrity_add_rdev);
|
||||
|
||||
|
|
|
@ -657,7 +657,7 @@ extern void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev);
|
|||
extern void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors);
|
||||
extern int md_check_no_bitmap(struct mddev *mddev);
|
||||
extern int md_integrity_register(struct mddev *mddev);
|
||||
extern void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev);
|
||||
extern int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev);
|
||||
extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale);
|
||||
|
||||
extern void mddev_init(struct mddev *mddev);
|
||||
|
|
|
@ -257,6 +257,9 @@ static int multipath_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
disk_stack_limits(mddev->gendisk, rdev->bdev,
|
||||
rdev->data_offset << 9);
|
||||
|
||||
err = md_integrity_add_rdev(rdev, mddev);
|
||||
if (err)
|
||||
break;
|
||||
spin_lock_irq(&conf->device_lock);
|
||||
mddev->degraded--;
|
||||
rdev->raid_disk = path;
|
||||
|
@ -264,9 +267,6 @@ static int multipath_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
spin_unlock_irq(&conf->device_lock);
|
||||
rcu_assign_pointer(p->rdev, rdev);
|
||||
err = 0;
|
||||
mddev_suspend(mddev);
|
||||
md_integrity_add_rdev(rdev, mddev);
|
||||
mddev_resume(mddev);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1589,6 +1589,9 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
if (mddev->recovery_disabled == conf->recovery_disabled)
|
||||
return -EBUSY;
|
||||
|
||||
if (md_integrity_add_rdev(rdev, mddev))
|
||||
return -ENXIO;
|
||||
|
||||
if (rdev->raid_disk >= 0)
|
||||
first = last = rdev->raid_disk;
|
||||
|
||||
|
@ -1632,9 +1635,6 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
break;
|
||||
}
|
||||
}
|
||||
mddev_suspend(mddev);
|
||||
md_integrity_add_rdev(rdev, mddev);
|
||||
mddev_resume(mddev);
|
||||
if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
|
||||
print_conf(conf);
|
||||
|
|
|
@ -1698,6 +1698,9 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
if (rdev->saved_raid_disk < 0 && !_enough(conf, 1, -1))
|
||||
return -EINVAL;
|
||||
|
||||
if (md_integrity_add_rdev(rdev, mddev))
|
||||
return -ENXIO;
|
||||
|
||||
if (rdev->raid_disk >= 0)
|
||||
first = last = rdev->raid_disk;
|
||||
|
||||
|
@ -1739,9 +1742,6 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
|
|||
rcu_assign_pointer(p->rdev, rdev);
|
||||
break;
|
||||
}
|
||||
mddev_suspend(mddev);
|
||||
md_integrity_add_rdev(rdev, mddev);
|
||||
mddev_resume(mddev);
|
||||
if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
|
||||
|
||||
|
|
|
@ -478,7 +478,6 @@ static const struct i2c_device_id ir_kbd_id[] = {
|
|||
{ "ir_rx_z8f0811_hdpvr", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ir_kbd_id);
|
||||
|
||||
static struct i2c_driver ir_kbd_driver = {
|
||||
.driver = {
|
||||
|
|
|
@ -1211,6 +1211,8 @@ static int alsa_device_init(struct saa7134_dev *dev)
|
|||
|
||||
static int alsa_device_exit(struct saa7134_dev *dev)
|
||||
{
|
||||
if (!snd_saa7134_cards[dev->nr])
|
||||
return 1;
|
||||
|
||||
snd_card_free(snd_saa7134_cards[dev->nr]);
|
||||
snd_saa7134_cards[dev->nr] = NULL;
|
||||
|
@ -1260,7 +1262,8 @@ static void saa7134_alsa_exit(void)
|
|||
int idx;
|
||||
|
||||
for (idx = 0; idx < SNDRV_CARDS; idx++) {
|
||||
snd_card_free(snd_saa7134_cards[idx]);
|
||||
if (snd_saa7134_cards[idx])
|
||||
snd_card_free(snd_saa7134_cards[idx]);
|
||||
}
|
||||
|
||||
saa7134_dmasound_init = NULL;
|
||||
|
|
|
@ -3995,6 +3995,9 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!mtd->name && mtd->dev.parent)
|
||||
mtd->name = dev_name(mtd->dev.parent);
|
||||
|
||||
/* Set the default functions */
|
||||
nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
|
||||
|
||||
|
|
|
@ -351,7 +351,6 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
|
|||
case COUNTRY_CODE_SPAIN:
|
||||
case COUNTRY_CODE_FRANCE:
|
||||
case COUNTRY_CODE_ISRAEL:
|
||||
case COUNTRY_CODE_WORLD_WIDE_13:
|
||||
return &rtl_regdom_12_13;
|
||||
case COUNTRY_CODE_MKK:
|
||||
case COUNTRY_CODE_MKK1:
|
||||
|
@ -360,6 +359,7 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
|
|||
return &rtl_regdom_14_60_64;
|
||||
case COUNTRY_CODE_GLOBAL_DOMAIN:
|
||||
return &rtl_regdom_14;
|
||||
case COUNTRY_CODE_WORLD_WIDE_13:
|
||||
case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL:
|
||||
return &rtl_regdom_12_13_5g_all;
|
||||
default:
|
||||
|
|
|
@ -95,8 +95,6 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
|||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
|
||||
rtl8821ae_bt_reg_init(hw);
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
|
||||
rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
|
||||
rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
|
||||
|
||||
rtlpriv->dm.dm_initialgain_enable = 1;
|
||||
|
@ -168,12 +166,15 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
|||
rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
|
||||
rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear;
|
||||
rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
|
||||
rtlpriv->cfg->mod_params->sw_crypto =
|
||||
rtlpriv->cfg->mod_params->sw_crypto;
|
||||
rtlpriv->cfg->mod_params->disable_watchdog =
|
||||
rtlpriv->cfg->mod_params->disable_watchdog;
|
||||
if (rtlpriv->cfg->mod_params->disable_watchdog)
|
||||
pr_info("watchdog disabled\n");
|
||||
rtlpriv->psc.reg_fwctrl_lps = 3;
|
||||
rtlpriv->psc.reg_max_lps_awakeintvl = 5;
|
||||
rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
|
||||
|
||||
/* for ASPM, you can close aspm through
|
||||
* set const_support_pciaspm = 0
|
||||
|
|
|
@ -207,19 +207,23 @@ static inline int __must_check wlcore_write_reg(struct wl1271 *wl, int reg,
|
|||
|
||||
static inline void wl1271_power_off(struct wl1271 *wl)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags))
|
||||
return;
|
||||
|
||||
ret = wl->if_ops->power(wl->dev, false);
|
||||
if (wl->if_ops->power)
|
||||
ret = wl->if_ops->power(wl->dev, false);
|
||||
if (!ret)
|
||||
clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
|
||||
}
|
||||
|
||||
static inline int wl1271_power_on(struct wl1271 *wl)
|
||||
{
|
||||
int ret = wl->if_ops->power(wl->dev, true);
|
||||
int ret = 0;
|
||||
|
||||
if (wl->if_ops->power)
|
||||
ret = wl->if_ops->power(wl->dev, true);
|
||||
if (ret == 0)
|
||||
set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
|
||||
|
||||
|
|
|
@ -73,7 +73,10 @@
|
|||
*/
|
||||
#define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
|
||||
|
||||
#define WSPI_MAX_NUM_OF_CHUNKS (SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
|
||||
/* Maximum number of SPI write chunks */
|
||||
#define WSPI_MAX_NUM_OF_CHUNKS \
|
||||
((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1)
|
||||
|
||||
|
||||
struct wl12xx_spi_glue {
|
||||
struct device *dev;
|
||||
|
@ -268,9 +271,10 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
|
|||
void *buf, size_t len, bool fixed)
|
||||
{
|
||||
struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
|
||||
struct spi_transfer t[2 * (WSPI_MAX_NUM_OF_CHUNKS + 1)];
|
||||
/* SPI write buffers - 2 for each chunk */
|
||||
struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
|
||||
struct spi_message m;
|
||||
u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
|
||||
u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */
|
||||
u32 *cmd;
|
||||
u32 chunk_len;
|
||||
int i;
|
||||
|
|
|
@ -77,6 +77,59 @@ static bool is_namespace_io(struct device *dev)
|
|||
return dev ? dev->type == &namespace_io_device_type : false;
|
||||
}
|
||||
|
||||
static int is_uuid_busy(struct device *dev, void *data)
|
||||
{
|
||||
u8 *uuid1 = data, *uuid2 = NULL;
|
||||
|
||||
if (is_namespace_pmem(dev)) {
|
||||
struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
|
||||
|
||||
uuid2 = nspm->uuid;
|
||||
} else if (is_namespace_blk(dev)) {
|
||||
struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
|
||||
|
||||
uuid2 = nsblk->uuid;
|
||||
} else if (is_nd_btt(dev)) {
|
||||
struct nd_btt *nd_btt = to_nd_btt(dev);
|
||||
|
||||
uuid2 = nd_btt->uuid;
|
||||
} else if (is_nd_pfn(dev)) {
|
||||
struct nd_pfn *nd_pfn = to_nd_pfn(dev);
|
||||
|
||||
uuid2 = nd_pfn->uuid;
|
||||
}
|
||||
|
||||
if (uuid2 && memcmp(uuid1, uuid2, NSLABEL_UUID_LEN) == 0)
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_namespace_uuid_busy(struct device *dev, void *data)
|
||||
{
|
||||
if (is_nd_pmem(dev) || is_nd_blk(dev))
|
||||
return device_for_each_child(dev, data, is_uuid_busy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nd_is_uuid_unique - verify that no other namespace has @uuid
|
||||
* @dev: any device on a nvdimm_bus
|
||||
* @uuid: uuid to check
|
||||
*/
|
||||
bool nd_is_uuid_unique(struct device *dev, u8 *uuid)
|
||||
{
|
||||
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
|
||||
|
||||
if (!nvdimm_bus)
|
||||
return false;
|
||||
WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm_bus->dev));
|
||||
if (device_for_each_child(&nvdimm_bus->dev, uuid,
|
||||
is_namespace_uuid_busy) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pmem_should_map_pages(struct device *dev)
|
||||
{
|
||||
struct nd_region *nd_region = to_nd_region(dev->parent);
|
||||
|
|
|
@ -134,62 +134,6 @@ int nd_region_to_nstype(struct nd_region *nd_region)
|
|||
}
|
||||
EXPORT_SYMBOL(nd_region_to_nstype);
|
||||
|
||||
static int is_uuid_busy(struct device *dev, void *data)
|
||||
{
|
||||
struct nd_region *nd_region = to_nd_region(dev->parent);
|
||||
u8 *uuid = data;
|
||||
|
||||
switch (nd_region_to_nstype(nd_region)) {
|
||||
case ND_DEVICE_NAMESPACE_PMEM: {
|
||||
struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
|
||||
|
||||
if (!nspm->uuid)
|
||||
break;
|
||||
if (memcmp(uuid, nspm->uuid, NSLABEL_UUID_LEN) == 0)
|
||||
return -EBUSY;
|
||||
break;
|
||||
}
|
||||
case ND_DEVICE_NAMESPACE_BLK: {
|
||||
struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
|
||||
|
||||
if (!nsblk->uuid)
|
||||
break;
|
||||
if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) == 0)
|
||||
return -EBUSY;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_namespace_uuid_busy(struct device *dev, void *data)
|
||||
{
|
||||
if (is_nd_pmem(dev) || is_nd_blk(dev))
|
||||
return device_for_each_child(dev, data, is_uuid_busy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nd_is_uuid_unique - verify that no other namespace has @uuid
|
||||
* @dev: any device on a nvdimm_bus
|
||||
* @uuid: uuid to check
|
||||
*/
|
||||
bool nd_is_uuid_unique(struct device *dev, u8 *uuid)
|
||||
{
|
||||
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
|
||||
|
||||
if (!nvdimm_bus)
|
||||
return false;
|
||||
WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm_bus->dev));
|
||||
if (device_for_each_child(&nvdimm_bus->dev, uuid,
|
||||
is_namespace_uuid_busy) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static ssize_t size_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
|
|
@ -140,6 +140,8 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
|
|||
type_mask |= IORESOURCE_TYPE_BITS;
|
||||
|
||||
pci_bus_for_each_resource(bus, r, i) {
|
||||
resource_size_t min_used = min;
|
||||
|
||||
if (!r)
|
||||
continue;
|
||||
|
||||
|
@ -163,12 +165,12 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
|
|||
* overrides "min".
|
||||
*/
|
||||
if (avail.start)
|
||||
min = avail.start;
|
||||
min_used = avail.start;
|
||||
|
||||
max = avail.end;
|
||||
|
||||
/* Ok, try it out.. */
|
||||
ret = allocate_resource(r, res, size, min, max,
|
||||
ret = allocate_resource(r, res, size, min_used, max,
|
||||
align, alignf, alignf_data);
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
|
|
@ -302,7 +302,8 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
|
|||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, pp->irq,
|
||||
dra7xx_pcie_msi_irq_handler, IRQF_SHARED,
|
||||
dra7xx_pcie_msi_irq_handler,
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"dra7-pcie-msi", pp);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to request irq\n");
|
||||
|
|
|
@ -522,7 +522,8 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
|
|||
|
||||
ret = devm_request_irq(&pdev->dev, pp->msi_irq,
|
||||
exynos_pcie_msi_irq_handler,
|
||||
IRQF_SHARED, "exynos-pcie", pp);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"exynos-pcie", pp);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to request msi irq\n");
|
||||
return ret;
|
||||
|
|
|
@ -537,7 +537,8 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
|
|||
|
||||
ret = devm_request_irq(&pdev->dev, pp->msi_irq,
|
||||
imx6_pcie_msi_handler,
|
||||
IRQF_SHARED, "mx6-pcie-msi", pp);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"mx6-pcie-msi", pp);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to request MSI irq\n");
|
||||
return ret;
|
||||
|
|
|
@ -1288,7 +1288,7 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
|
|||
|
||||
msi->irq = err;
|
||||
|
||||
err = request_irq(msi->irq, tegra_pcie_msi_irq, 0,
|
||||
err = request_irq(msi->irq, tegra_pcie_msi_irq, IRQF_NO_THREAD,
|
||||
tegra_msi_irq_chip.name, pcie);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
|
||||
|
|
|
@ -720,14 +720,16 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
|
|||
|
||||
/* Two irqs are for MSI, but they are also used for non-MSI irqs */
|
||||
err = devm_request_irq(&pdev->dev, msi->irq1, rcar_pcie_msi_irq,
|
||||
IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
rcar_msi_irq_chip.name, pcie);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = devm_request_irq(&pdev->dev, msi->irq2, rcar_pcie_msi_irq,
|
||||
IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
rcar_msi_irq_chip.name, pcie);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
|
||||
goto err;
|
||||
|
|
|
@ -279,7 +279,8 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
|
|||
return -ENODEV;
|
||||
}
|
||||
ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler,
|
||||
IRQF_SHARED, "spear1340-pcie", pp);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"spear1340-pcie", pp);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to request irq %d\n", pp->irq);
|
||||
return ret;
|
||||
|
|
|
@ -781,7 +781,8 @@ static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port)
|
|||
|
||||
port->irq = irq_of_parse_and_map(node, 0);
|
||||
err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler,
|
||||
IRQF_SHARED, "xilinx-pcie", port);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
"xilinx-pcie", port);
|
||||
if (err) {
|
||||
dev_err(dev, "unable to request irq %d\n", port->irq);
|
||||
return err;
|
||||
|
|
|
@ -715,6 +715,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
|
|||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
/* Our job is to use irqs and status from the power module
|
||||
* to keep the transceiver disabled when nothing's connected.
|
||||
|
@ -750,6 +751,7 @@ static int twl4030_usb_remove(struct platform_device *pdev)
|
|||
struct twl4030_usb *twl = platform_get_drvdata(pdev);
|
||||
int val;
|
||||
|
||||
usb_remove_phy(&twl->phy);
|
||||
pm_runtime_get_sync(twl->dev);
|
||||
cancel_delayed_work(&twl->id_workaround_work);
|
||||
device_remove_file(twl->dev, &dev_attr_vbus);
|
||||
|
@ -757,6 +759,13 @@ static int twl4030_usb_remove(struct platform_device *pdev)
|
|||
/* set transceiver mode to power on defaults */
|
||||
twl4030_usb_set_mode(twl, -1);
|
||||
|
||||
/* idle ulpi before powering off */
|
||||
if (cable_present(twl->linkstat))
|
||||
pm_runtime_put_noidle(twl->dev);
|
||||
pm_runtime_mark_last_busy(twl->dev);
|
||||
pm_runtime_put_sync_suspend(twl->dev);
|
||||
pm_runtime_disable(twl->dev);
|
||||
|
||||
/* autogate 60MHz ULPI clock,
|
||||
* clear dpll clock request for i2c access,
|
||||
* disable 32KHz
|
||||
|
@ -771,11 +780,6 @@ static int twl4030_usb_remove(struct platform_device *pdev)
|
|||
/* disable complete OTG block */
|
||||
twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
|
||||
|
||||
if (cable_present(twl->linkstat))
|
||||
pm_runtime_put_noidle(twl->dev);
|
||||
pm_runtime_mark_last_busy(twl->dev);
|
||||
pm_runtime_put(twl->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ struct scu_ipc_data {
|
|||
|
||||
static int scu_reg_access(u32 cmd, struct scu_ipc_data *data)
|
||||
{
|
||||
int count = data->count;
|
||||
unsigned int count = data->count;
|
||||
|
||||
if (count == 0 || count == 3 || count > 4)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -562,7 +562,7 @@ static int mode_select_handle_sense(struct scsi_device *sdev,
|
|||
/*
|
||||
* Command Lock contention
|
||||
*/
|
||||
err = SCSI_DH_RETRY;
|
||||
err = SCSI_DH_IMM_RETRY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -612,6 +612,8 @@ retry:
|
|||
err = mode_select_handle_sense(sdev, h->sense);
|
||||
if (err == SCSI_DH_RETRY && retry_cnt--)
|
||||
goto retry;
|
||||
if (err == SCSI_DH_IMM_RETRY)
|
||||
goto retry;
|
||||
}
|
||||
if (err == SCSI_DH_OK) {
|
||||
h->state = RDAC_STATE_ACTIVE;
|
||||
|
|
|
@ -205,6 +205,7 @@ static struct {
|
|||
{"Intel", "Multi-Flex", NULL, BLIST_NO_RSOC},
|
||||
{"iRiver", "iFP Mass Driver", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
|
||||
{"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN},
|
||||
{"Marvell", "Console", NULL, BLIST_SKIP_VPD_PAGES},
|
||||
{"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
|
||||
{"MATSHITA", "DMC-LC5", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
|
||||
{"MATSHITA", "DMC-LC40", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
|
||||
|
@ -227,6 +228,7 @@ static struct {
|
|||
{"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
|
||||
{"Promise", "", NULL, BLIST_SPARSELUN},
|
||||
{"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024},
|
||||
{"SYNOLOGY", "iSCSI Storage", NULL, BLIST_MAX_1024},
|
||||
{"QUANTUM", "XP34301", "1071", BLIST_NOTQ},
|
||||
{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
|
||||
{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
|
||||
|
|
|
@ -1192,16 +1192,18 @@ static void __scsi_remove_target(struct scsi_target *starget)
|
|||
void scsi_remove_target(struct device *dev)
|
||||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(dev->parent);
|
||||
struct scsi_target *starget;
|
||||
struct scsi_target *starget, *last_target = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
restart:
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
list_for_each_entry(starget, &shost->__targets, siblings) {
|
||||
if (starget->state == STARGET_DEL)
|
||||
if (starget->state == STARGET_DEL ||
|
||||
starget == last_target)
|
||||
continue;
|
||||
if (starget->dev.parent == dev || &starget->dev == dev) {
|
||||
kref_get(&starget->reap_ref);
|
||||
last_target = starget;
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
__scsi_remove_target(starget);
|
||||
scsi_target_reap(starget);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue