Merge android-4.4.118 (5f7f76a) into msm-4.4

* refs/heads/tmp-5f7f76a
  Linux 4.4.118
  net: dst_cache_per_cpu_dst_set() can be static
  crypto: s5p-sss - Fix kernel Oops in AES-ECB mode
  KVM: nVMX: invvpid handling improvements
  KVM: VMX: clean up declaration of VPID/EPT invalidation types
  kvm: nVMX: Fix kernel panics induced by illegal INVEPT/INVVPID types
  KVM: nVMX: vmx_complete_nested_posted_interrupt() can't fail
  KVM: nVMX: kmap() can't fail
  x86/speculation: Fix typo IBRS_ATT, which should be IBRS_ALL
  x86/spectre: Simplify spectre_v2 command line parsing
  x86/retpoline: Avoid retpolines for built-in __init functions
  x86/kvm: Update spectre-v1 mitigation
  x86/paravirt: Remove 'noreplace-paravirt' cmdline option
  x86/spectre: Fix spelling mistake: "vunerable"-> "vulnerable"
  x86/spectre: Report get_user mitigation for spectre_v1
  nl80211: Sanitize array index in parse_txq_params
  vfs, fdtable: Prevent bounds-check bypass via speculative execution
  x86/syscall: Sanitize syscall table de-references under speculation
  x86/get_user: Use pointer masking to limit speculation
  x86: Introduce barrier_nospec
  x86: Implement array_index_mask_nospec
  array_index_nospec: Sanitize speculative array de-references
  Documentation: Document array_index_nospec
  x86/spectre: Check CONFIG_RETPOLINE in command line parser
  x86/cpu/bugs: Make retpoline module warning conditional
  x86/bugs: Drop one "mitigation" from dmesg
  x86/nospec: Fix header guards names
  module/retpoline: Warn about missing retpoline in module
  KVM: VMX: Make indirect call speculation safe
  KVM: x86: Make indirect calls in emulator speculation safe
  x86/retpoline: Remove the esp/rsp thunk
  KVM: async_pf: Fix #DF due to inject "Page not Present" and "Page Ready" exceptions simultaneously
  kasan: rework Kconfig settings
  drm/gma500: remove helper function
  x86/microcode/AMD: Change load_microcode_amd()'s param to bool to fix preemptibility bug
  genksyms: Fix segfault with invalid declarations
  dell-wmi, dell-laptop: depends DMI
  netlink: fix nla_put_{u8,u16,u32} for KASAN
  ASoC: Intel: Kconfig: fix build when ACPI is not enabled
  ARM: tegra: select USB_ULPI from EHCI rather than platform
  ncr5380: shut up gcc indentation warning
  usb: phy: msm add regulator dependency
  idle: i7300: add PCI dependency
  binfmt_elf: compat: avoid unused function warning
  isdn: sc: work around type mismatch warning
  power: bq27xxx_battery: mark some symbols __maybe_unused
  Revert "power: bq27xxx_battery: Remove unneeded dependency in Kconfig"
  ncpfs: fix unused variable warning
  gpio: xgene: mark PM functions as __maybe_unused
  net: hp100: remove unnecessary #ifdefs
  dmaengine: zx: fix build warning
  perf/x86: Shut up false-positive -Wmaybe-uninitialized warning
  wireless: cw1200: use __maybe_unused to hide pm functions_
  cw1200: fix bogus maybe-uninitialized warning
  v4l: remove MEDIA_TUNER dependency for VIDEO_TUNER
  hdpvr: hide unused variable
  drm/gma500: Sanity-check pipe index
  serial: 8250_mid: fix broken DMA dependency
  ASoC: rockchip: use __maybe_unused to hide st_irq_syscfg_resume
  ISDN: eicon: reduce stack size of sig_ind function
  em28xx: only use mt9v011 if camera support is enabled
  go7007: add MEDIA_CAMERA_SUPPORT dependency
  KVM: add X86_LOCAL_APIC dependency
  Input: tca8418_keypad - hide gcc-4.9 -Wmaybe-uninitialized warning
  drm/nouveau: hide gcc-4.9 -Wmaybe-uninitialized
  tc358743: fix register i2c_rd/wr functions
  staging: unisys: visorinput depends on INPUT
  i2c: remove __init from i2c_register_board_info()
  b2c2: flexcop: avoid unused function warnings
  infiniband: cxgb4: use %pR format string for printing resources
  iio: adc: axp288: remove redundant duplicate const on axp288_adc_channels
  ASoC: mediatek: add i2c dependency
  genirq/msi: Add stubs for get_cached_msi_msg/pci_write_msi_msg
  tty: cyclades: cyz_interrupt is only used for PCI
  drm/vmwgfx: use *_32_bits() macros
  tlan: avoid unused label with PCI=n
  tc1100-wmi: fix build warning when CONFIG_PM not enabled
  ipv4: ipconfig: avoid unused ic_proto_used symbol
  netfilter: ipvs: avoid unused variable warnings
  x86/platform/olpc: Fix resume handler build warning
  staging: wilc1000: fix kbuild test robot error
  rtlwifi: fix gcc-6 indentation warning
  USB: cdc_subset: only build when one driver is enabled
  hwrng: exynos - use __maybe_unused to hide pm functions
  fbdev: sm712fb: avoid unused function warnings
  Drivers: hv: vmbus: fix build warning
  modsign: hide openssl output in silent builds
  fbdev: s6e8ax0: avoid unused function warnings
  mtd: cfi: enforce valid geometry configuration
  mtd: sh_flctl: pass FIFO as physical address
  amd-xgbe: Fix unused suspend handlers build warning
  fbdev: auo_k190x: avoid unused function warnings
  driver-core: use 'dev' argument in dev_dbg_ratelimited stub
  target/user: Fix cast from pointer to phys_addr_t
  tty: hvc_xen: hide xen_console_remove when unused
  usb: musb/ux500: remove duplicate check for dma_is_compatible
  pwc: hide unused label
  SCSI: initio: remove duplicate module device table
  scsi: mvumi: use __maybe_unused to hide pm functions
  video: Use bool instead int pointer for get_opt_bool() argument
  fbdev: sis: enforce selection of at least one backend
  staging: ste_rmi4: avoid unused function warnings
  video: fbdev: sis: remove unused variable
  scsi: fdomain: drop fdomain_pci_tbl when built-in
  mptfusion: hide unused seq_mpt_print_ioc_summary function
  mtd: maps: add __init attribute
  mtd: ichxrom: maybe-uninitialized with gcc-4.9
  md: avoid warning for 32-bit sector_t
  profile: hide unused functions when !CONFIG_PROC_FS
  dpt_i2o: fix build warning
  drivers/net: fix eisa_driver probe section mismatch
  scsi: sim710: fix build warning
  x86/boot: Avoid warning for zero-filling .bss
  thermal: spear: use __maybe_unused for PM functions
  ssb: mark ssb_bus_register as __maybe_unused
  reiserfs: avoid a -Wmaybe-uninitialized warning
  ALSA: hda/ca0132 - fix possible NULL pointer use
  arm64: Kconfig: select COMPAT_BINFMT_ELF only when BINFMT_ELF is set
  scsi: advansys: fix uninitialized data access
  x86/platform: Add PCI dependency for PUNIT_ATOM_DEBUG
  x86: add MULTIUSER dependency for KVM
  thermal: fix INTEL_SOC_DTS_IOSF_CORE dependencies
  x86/build: Silence the build with "make -s"
  tools build: Add tools tree support for 'make -s'
  x86/fpu/math-emu: Fix possible uninitialized variable use
  arm64: define BUG() instruction without CONFIG_BUG
  x86/ras/inject: Make it depend on X86_LOCAL_APIC=y
  scsi: advansys: fix build warning for PCI=n
  video: fbdev: via: remove possibly unused variables
  platform/x86: intel_mid_thermal: Fix suspend handlers unused warning
  gpio: intel-mid: Fix build warning when !CONFIG_PM
  vmxnet3: prevent building with 64K pages
  isdn: icn: remove a #warning
  virtio_balloon: prevent uninitialized variable use
  hippi: Fix a Fix a possible sleep-in-atomic bug in rr_close
  xen: XEN_ACPI_PROCESSOR is Dom0-only
  x86/mm/kmmio: Fix mmiotrace for page unaligned addresses
  mm/early_ioremap: Fix boot hang with earlyprintk=efi,keep
  dmaengine: jz4740: disable/unprepare clk if probe fails
  drm/armada: fix leak of crtc structure
  xfrm: Fix stack-out-of-bounds with misconfigured transport mode policies.
  spi: sun4i: disable clocks in the remove function
  ASoC: rockchip: disable clock on error
  clk: fix a panic error caused by accessing NULL pointer
  dmaengine: at_hdmac: fix potential NULL pointer dereference in atc_prep_dma_interleaved
  dmaengine: ioat: Fix error handling path
  509: fix printing uninitialized stack memory when OID is empty
  btrfs: Fix possible off-by-one in btrfs_search_path_in_tree
  net_sched: red: Avoid illegal values
  net_sched: red: Avoid devision by zero
  gianfar: fix a flooded alignment reports because of padding issue.
  s390/dasd: prevent prefix I/O error
  powerpc/perf: Fix oops when grouping different pmu events
  ipvlan: Add the skb->mark as flow4's member to lookup route
  scripts/kernel-doc: Don't fail with status != 0 if error encountered with -none
  RDMA/cma: Make sure that PSN is not over max allowed
  pinctrl: sunxi: Fix A80 interrupt pin bank
  media: s5k6aa: describe some function parameters
  perf bench numa: Fixup discontiguous/sparse numa nodes
  perf top: Fix window dimensions change handling
  ARM: dts: am4372: Correct the interrupts_properties of McASP
  ARM: dts: Fix omap4 hang with GPS connected to USB by using wakeupgen
  ARM: AM33xx: PRM: Remove am33xx_pwrdm_read_prev_pwrst function
  ARM: OMAP2+: Fix SRAM virt to phys translation for save_secure_ram_context
  usb: build drivers/usb/common/ when USB_SUPPORT is set
  usbip: keep usbip_device sockfd state in sync with tcp_socket
  staging: iio: adc: ad7192: fix external frequency setting
  binder: check for binder_thread allocation failure in binder_poll()
  staging: android: ashmem: Fix a race condition in pin ioctls
  dn_getsockoptdecnet: move nf_{get/set}sockopt outside sock lock
  Make DST_CACHE a silent config option
  arm64: dts: add #cooling-cells to CPU nodes
  video: fbdev/mmp: add MODULE_LICENSE
  ASoC: ux500: add MODULE_LICENSE tag
  net: avoid skb_warn_bad_offload on IS_ERR
  netfilter: xt_RATEEST: acquire xt_rateest_mutex for hash insert
  netfilter: on sockopt() acquire sock lock only in the required scope
  netfilter: ipt_CLUSTERIP: fix out-of-bounds accesses in clusterip_tg_check()
  netfilter: x_tables: avoid out-of-bounds reads in xt_request_find_{match|target}
  netfilter: x_tables: fix int overflow in xt_alloc_table_info()
  KVM: x86: fix escape of guest dr6 to the host
  crypto: x86/twofish-3way - Fix %rbp usage
  selinux: skip bounded transition processing if the policy isn't loaded
  selinux: ensure the context is NUL terminated in security_context_to_sid_core()
  Provide a function to create a NUL-terminated string from unterminated data
  drm: Require __GFP_NOFAIL for the legacy drm_modeset_lock_all
  blktrace: fix unlocked registration of tracepoints
  xfrm: check id proto in validate_tmpl()
  xfrm: Fix stack-out-of-bounds read on socket policy lookup.
  mm,vmscan: Make unregister_shrinker() no-op if register_shrinker() failed.
  cfg80211: check dev_set_name() return value
  net: replace dst_cache ip6_tunnel implementation with the generic one
  net: add dst_cache support
  ANDROID: sdcardfs: Hold i_mutex for i_size_write
  BACKPORT, FROMGIT: crypto: speck - add test vectors for Speck64-XTS
  BACKPORT, FROMGIT: crypto: speck - add test vectors for Speck128-XTS
  BACKPORT, FROMGIT: crypto: arm/speck - add NEON-accelerated implementation of Speck-XTS
  FROMGIT: crypto: speck - export common helpers
  BACKPORT, FROMGIT: crypto: speck - add support for the Speck block cipher
  UPSTREAM: ANDROID: binder: synchronize_rcu() when using POLLFREE.
  f2fs: updates on v4.16-rc1

Conflicts:
	net/Kconfig
	net/core/Makefile

Change-Id: I659b0444812b04252f1f1fba8bc62410ce42b061
Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
This commit is contained in:
Srinivasarao P 2018-02-27 19:08:13 +05:30
commit 8720164c1a
247 changed files with 6323 additions and 2327 deletions

View file

@ -186,3 +186,9 @@ Date: August 2017
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org> Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
Description: Description:
Controls sleep time of GC urgent mode Controls sleep time of GC urgent mode
What: /sys/fs/f2fs/<disk>/readdir_ra
Date: November 2017
Contact: "Sheng Yong" <shengyong1@huawei.com>
Description:
Controls readahead inode block in readdir.

View file

@ -2635,8 +2635,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
norandmaps Don't use address space randomization. Equivalent to norandmaps Don't use address space randomization. Equivalent to
echo 0 > /proc/sys/kernel/randomize_va_space echo 0 > /proc/sys/kernel/randomize_va_space
noreplace-paravirt [X86,IA-64,PV_OPS] Don't patch paravirt_ops
noreplace-smp [X86-32,SMP] Don't replace SMP instructions noreplace-smp [X86-32,SMP] Don't replace SMP instructions
with UP alternatives with UP alternatives

View file

@ -0,0 +1,90 @@
This document explains potential effects of speculation, and how undesirable
effects can be mitigated portably using common APIs.
===========
Speculation
===========
To improve performance and minimize average latencies, many contemporary CPUs
employ speculative execution techniques such as branch prediction, performing
work which may be discarded at a later stage.
Typically speculative execution cannot be observed from architectural state,
such as the contents of registers. However, in some cases it is possible to
observe its impact on microarchitectural state, such as the presence or
absence of data in caches. Such state may form side-channels which can be
observed to extract secret information.
For example, in the presence of branch prediction, it is possible for bounds
checks to be ignored by code which is speculatively executed. Consider the
following code:
int load_array(int *array, unsigned int index)
{
if (index >= MAX_ARRAY_ELEMS)
return 0;
else
return array[index];
}
Which, on arm64, may be compiled to an assembly sequence such as:
CMP <index>, #MAX_ARRAY_ELEMS
B.LT less
MOV <returnval>, #0
RET
less:
LDR <returnval>, [<array>, <index>]
RET
It is possible that a CPU mis-predicts the conditional branch, and
speculatively loads array[index], even if index >= MAX_ARRAY_ELEMS. This
value will subsequently be discarded, but the speculated load may affect
microarchitectural state which can be subsequently measured.
More complex sequences involving multiple dependent memory accesses may
result in sensitive information being leaked. Consider the following
code, building on the prior example:
int load_dependent_arrays(int *arr1, int *arr2, int index)
{
int val1, val2,
val1 = load_array(arr1, index);
val2 = load_array(arr2, val1);
return val2;
}
Under speculation, the first call to load_array() may return the value
of an out-of-bounds address, while the second call will influence
microarchitectural state dependent on this value. This may provide an
arbitrary read primitive.
====================================
Mitigating speculation side-channels
====================================
The kernel provides a generic API to ensure that bounds checks are
respected even under speculation. Architectures which are affected by
speculation-based side-channels are expected to implement these
primitives.
The array_index_nospec() helper in <linux/nospec.h> can be used to
prevent information from being leaked via side-channels.
A call to array_index_nospec(index, size) returns a sanitized index
value that is bounded to [0, size) even under cpu speculation
conditions.
This can be used to protect the earlier load_array() example:
int load_array(int *array, unsigned int index)
{
if (index >= MAX_ARRAY_ELEMS)
return 0;
else {
index = array_index_nospec(index, MAX_ARRAY_ELEMS);
return array[index];
}
}

View file

@ -1,6 +1,6 @@
VERSION = 4 VERSION = 4
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 117 SUBLEVEL = 118
EXTRAVERSION = EXTRAVERSION =
NAME = Blurry Fish Butt NAME = Blurry Fish Butt
@ -87,10 +87,12 @@ endif
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4 ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),) ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
quiet=silent_ quiet=silent_
tools_silent=s
endif endif
else # make-3.8x else # make-3.8x
ifneq ($(filter s% -s%,$(MAKEFLAGS)),) ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
quiet=silent_ quiet=silent_
tools_silent=-s
endif endif
endif endif
@ -1553,11 +1555,11 @@ image_name:
# Clear a bunch of variables before executing the submake # Clear a bunch of variables before executing the submake
tools/: FORCE tools/: FORCE
$(Q)mkdir -p $(objtree)/tools $(Q)mkdir -p $(objtree)/tools
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/
tools/%: FORCE tools/%: FORCE
$(Q)mkdir -p $(objtree)/tools $(Q)mkdir -p $(objtree)/tools
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $* $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $*
# Single targets # Single targets
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------

View file

@ -807,7 +807,8 @@
reg = <0x48038000 0x2000>, reg = <0x48038000 0x2000>,
<0x46000000 0x400000>; <0x46000000 0x400000>;
reg-names = "mpu", "dat"; reg-names = "mpu", "dat";
interrupts = <80>, <81>; interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "tx", "rx"; interrupt-names = "tx", "rx";
status = "disabled"; status = "disabled";
dmas = <&edma 8>, dmas = <&edma 8>,
@ -821,7 +822,8 @@
reg = <0x4803C000 0x2000>, reg = <0x4803C000 0x2000>,
<0x46400000 0x400000>; <0x46400000 0x400000>;
reg-names = "mpu", "dat"; reg-names = "mpu", "dat";
interrupts = <82>, <83>; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "tx", "rx"; interrupt-names = "tx", "rx";
status = "disabled"; status = "disabled";
dmas = <&edma 10>, dmas = <&edma 10>,

View file

@ -844,14 +844,12 @@
usbhsohci: ohci@4a064800 { usbhsohci: ohci@4a064800 {
compatible = "ti,ohci-omap3"; compatible = "ti,ohci-omap3";
reg = <0x4a064800 0x400>; reg = <0x4a064800 0x400>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
}; };
usbhsehci: ehci@4a064c00 { usbhsehci: ehci@4a064c00 {
compatible = "ti,ehci-omap"; compatible = "ti,ehci-omap";
reg = <0x4a064c00 0x400>; reg = <0x4a064c00 0x400>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
}; };
}; };

View file

@ -120,4 +120,11 @@ config CRYPTO_GHASH_ARM_CE
that uses the 64x64 to 128 bit polynomial multiplication (vmull.p64) that uses the 64x64 to 128 bit polynomial multiplication (vmull.p64)
that is part of the ARMv8 Crypto Extensions that is part of the ARMv8 Crypto Extensions
config CRYPTO_SPECK_NEON
tristate "NEON accelerated Speck cipher algorithms"
depends on KERNEL_MODE_NEON
select CRYPTO_BLKCIPHER
select CRYPTO_GF128MUL
select CRYPTO_SPECK
endif endif

View file

@ -8,6 +8,7 @@ obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o
obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha512-arm.o obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha512-arm.o
obj-$(CONFIG_CRYPTO_SPECK_NEON) += speck-neon.o
ce-obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o ce-obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
ce-obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o ce-obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
@ -36,6 +37,7 @@ sha1-arm-ce-y := sha1-ce-core.o sha1-ce-glue.o
sha2-arm-ce-y := sha2-ce-core.o sha2-ce-glue.o sha2-arm-ce-y := sha2-ce-core.o sha2-ce-glue.o
aes-arm-ce-y := aes-ce-core.o aes-ce-glue.o aes-arm-ce-y := aes-ce-core.o aes-ce-glue.o
ghash-arm-ce-y := ghash-ce-core.o ghash-ce-glue.o ghash-arm-ce-y := ghash-ce-core.o ghash-ce-glue.o
speck-neon-y := speck-neon-core.o speck-neon-glue.o
quiet_cmd_perl = PERL $@ quiet_cmd_perl = PERL $@
cmd_perl = $(PERL) $(<) > $(@) cmd_perl = $(PERL) $(<) > $(@)

View file

@ -0,0 +1,432 @@
// SPDX-License-Identifier: GPL-2.0
/*
* NEON-accelerated implementation of Speck128-XTS and Speck64-XTS
*
* Copyright (c) 2018 Google, Inc
*
* Author: Eric Biggers <ebiggers@google.com>
*/
#include <linux/linkage.h>
.text
.fpu neon
// arguments
ROUND_KEYS .req r0 // const {u64,u32} *round_keys
NROUNDS .req r1 // int nrounds
DST .req r2 // void *dst
SRC .req r3 // const void *src
NBYTES .req r4 // unsigned int nbytes
TWEAK .req r5 // void *tweak
// registers which hold the data being encrypted/decrypted
X0 .req q0
X0_L .req d0
X0_H .req d1
Y0 .req q1
Y0_H .req d3
X1 .req q2
X1_L .req d4
X1_H .req d5
Y1 .req q3
Y1_H .req d7
X2 .req q4
X2_L .req d8
X2_H .req d9
Y2 .req q5
Y2_H .req d11
X3 .req q6
X3_L .req d12
X3_H .req d13
Y3 .req q7
Y3_H .req d15
// the round key, duplicated in all lanes
ROUND_KEY .req q8
ROUND_KEY_L .req d16
ROUND_KEY_H .req d17
// index vector for vtbl-based 8-bit rotates
ROTATE_TABLE .req d18
// multiplication table for updating XTS tweaks
GF128MUL_TABLE .req d19
GF64MUL_TABLE .req d19
// current XTS tweak value(s)
TWEAKV .req q10
TWEAKV_L .req d20
TWEAKV_H .req d21
TMP0 .req q12
TMP0_L .req d24
TMP0_H .req d25
TMP1 .req q13
TMP2 .req q14
TMP3 .req q15
.align 4
.Lror64_8_table:
.byte 1, 2, 3, 4, 5, 6, 7, 0
.Lror32_8_table:
.byte 1, 2, 3, 0, 5, 6, 7, 4
.Lrol64_8_table:
.byte 7, 0, 1, 2, 3, 4, 5, 6
.Lrol32_8_table:
.byte 3, 0, 1, 2, 7, 4, 5, 6
.Lgf128mul_table:
.byte 0, 0x87
.fill 14
.Lgf64mul_table:
.byte 0, 0x1b, (0x1b << 1), (0x1b << 1) ^ 0x1b
.fill 12
/*
* _speck_round_128bytes() - Speck encryption round on 128 bytes at a time
*
* Do one Speck encryption round on the 128 bytes (8 blocks for Speck128, 16 for
* Speck64) stored in X0-X3 and Y0-Y3, using the round key stored in all lanes
* of ROUND_KEY. 'n' is the lane size: 64 for Speck128, or 32 for Speck64.
*
* The 8-bit rotates are implemented using vtbl instead of vshr + vsli because
* the vtbl approach is faster on some processors and the same speed on others.
*/
.macro _speck_round_128bytes n
// x = ror(x, 8)
vtbl.8 X0_L, {X0_L}, ROTATE_TABLE
vtbl.8 X0_H, {X0_H}, ROTATE_TABLE
vtbl.8 X1_L, {X1_L}, ROTATE_TABLE
vtbl.8 X1_H, {X1_H}, ROTATE_TABLE
vtbl.8 X2_L, {X2_L}, ROTATE_TABLE
vtbl.8 X2_H, {X2_H}, ROTATE_TABLE
vtbl.8 X3_L, {X3_L}, ROTATE_TABLE
vtbl.8 X3_H, {X3_H}, ROTATE_TABLE
// x += y
vadd.u\n X0, Y0
vadd.u\n X1, Y1
vadd.u\n X2, Y2
vadd.u\n X3, Y3
// x ^= k
veor X0, ROUND_KEY
veor X1, ROUND_KEY
veor X2, ROUND_KEY
veor X3, ROUND_KEY
// y = rol(y, 3)
vshl.u\n TMP0, Y0, #3
vshl.u\n TMP1, Y1, #3
vshl.u\n TMP2, Y2, #3
vshl.u\n TMP3, Y3, #3
vsri.u\n TMP0, Y0, #(\n - 3)
vsri.u\n TMP1, Y1, #(\n - 3)
vsri.u\n TMP2, Y2, #(\n - 3)
vsri.u\n TMP3, Y3, #(\n - 3)
// y ^= x
veor Y0, TMP0, X0
veor Y1, TMP1, X1
veor Y2, TMP2, X2
veor Y3, TMP3, X3
.endm
/*
* _speck_unround_128bytes() - Speck decryption round on 128 bytes at a time
*
* This is the inverse of _speck_round_128bytes().
*/
.macro _speck_unround_128bytes n
// y ^= x
veor TMP0, Y0, X0
veor TMP1, Y1, X1
veor TMP2, Y2, X2
veor TMP3, Y3, X3
// y = ror(y, 3)
vshr.u\n Y0, TMP0, #3
vshr.u\n Y1, TMP1, #3
vshr.u\n Y2, TMP2, #3
vshr.u\n Y3, TMP3, #3
vsli.u\n Y0, TMP0, #(\n - 3)
vsli.u\n Y1, TMP1, #(\n - 3)
vsli.u\n Y2, TMP2, #(\n - 3)
vsli.u\n Y3, TMP3, #(\n - 3)
// x ^= k
veor X0, ROUND_KEY
veor X1, ROUND_KEY
veor X2, ROUND_KEY
veor X3, ROUND_KEY
// x -= y
vsub.u\n X0, Y0
vsub.u\n X1, Y1
vsub.u\n X2, Y2
vsub.u\n X3, Y3
// x = rol(x, 8);
vtbl.8 X0_L, {X0_L}, ROTATE_TABLE
vtbl.8 X0_H, {X0_H}, ROTATE_TABLE
vtbl.8 X1_L, {X1_L}, ROTATE_TABLE
vtbl.8 X1_H, {X1_H}, ROTATE_TABLE
vtbl.8 X2_L, {X2_L}, ROTATE_TABLE
vtbl.8 X2_H, {X2_H}, ROTATE_TABLE
vtbl.8 X3_L, {X3_L}, ROTATE_TABLE
vtbl.8 X3_H, {X3_H}, ROTATE_TABLE
.endm
.macro _xts128_precrypt_one dst_reg, tweak_buf, tmp
// Load the next source block
vld1.8 {\dst_reg}, [SRC]!
// Save the current tweak in the tweak buffer
vst1.8 {TWEAKV}, [\tweak_buf:128]!
// XOR the next source block with the current tweak
veor \dst_reg, TWEAKV
/*
* Calculate the next tweak by multiplying the current one by x,
* modulo p(x) = x^128 + x^7 + x^2 + x + 1.
*/
vshr.u64 \tmp, TWEAKV, #63
vshl.u64 TWEAKV, #1
veor TWEAKV_H, \tmp\()_L
vtbl.8 \tmp\()_H, {GF128MUL_TABLE}, \tmp\()_H
veor TWEAKV_L, \tmp\()_H
.endm
.macro _xts64_precrypt_two dst_reg, tweak_buf, tmp
// Load the next two source blocks
vld1.8 {\dst_reg}, [SRC]!
// Save the current two tweaks in the tweak buffer
vst1.8 {TWEAKV}, [\tweak_buf:128]!
// XOR the next two source blocks with the current two tweaks
veor \dst_reg, TWEAKV
/*
* Calculate the next two tweaks by multiplying the current ones by x^2,
* modulo p(x) = x^64 + x^4 + x^3 + x + 1.
*/
vshr.u64 \tmp, TWEAKV, #62
vshl.u64 TWEAKV, #2
vtbl.8 \tmp\()_L, {GF64MUL_TABLE}, \tmp\()_L
vtbl.8 \tmp\()_H, {GF64MUL_TABLE}, \tmp\()_H
veor TWEAKV, \tmp
.endm
/*
* _speck_xts_crypt() - Speck-XTS encryption/decryption
*
* Encrypt or decrypt NBYTES bytes of data from the SRC buffer to the DST buffer
* using Speck-XTS, specifically the variant with a block size of '2n' and round
* count given by NROUNDS. The expanded round keys are given in ROUND_KEYS, and
* the current XTS tweak value is given in TWEAK. It's assumed that NBYTES is a
* nonzero multiple of 128.
*/
.macro _speck_xts_crypt n, decrypting
push {r4-r7}
mov r7, sp
/*
* The first four parameters were passed in registers r0-r3. Load the
* additional parameters, which were passed on the stack.
*/
ldr NBYTES, [sp, #16]
ldr TWEAK, [sp, #20]
/*
* If decrypting, modify the ROUND_KEYS parameter to point to the last
* round key rather than the first, since for decryption the round keys
* are used in reverse order.
*/
.if \decrypting
.if \n == 64
add ROUND_KEYS, ROUND_KEYS, NROUNDS, lsl #3
sub ROUND_KEYS, #8
.else
add ROUND_KEYS, ROUND_KEYS, NROUNDS, lsl #2
sub ROUND_KEYS, #4
.endif
.endif
// Load the index vector for vtbl-based 8-bit rotates
.if \decrypting
ldr r12, =.Lrol\n\()_8_table
.else
ldr r12, =.Lror\n\()_8_table
.endif
vld1.8 {ROTATE_TABLE}, [r12:64]
// One-time XTS preparation
/*
* Allocate stack space to store 128 bytes worth of tweaks. For
* performance, this space is aligned to a 16-byte boundary so that we
* can use the load/store instructions that declare 16-byte alignment.
*/
sub sp, #128
bic sp, #0xf
.if \n == 64
// Load first tweak
vld1.8 {TWEAKV}, [TWEAK]
// Load GF(2^128) multiplication table
ldr r12, =.Lgf128mul_table
vld1.8 {GF128MUL_TABLE}, [r12:64]
.else
// Load first tweak
vld1.8 {TWEAKV_L}, [TWEAK]
// Load GF(2^64) multiplication table
ldr r12, =.Lgf64mul_table
vld1.8 {GF64MUL_TABLE}, [r12:64]
// Calculate second tweak, packing it together with the first
vshr.u64 TMP0_L, TWEAKV_L, #63
vtbl.u8 TMP0_L, {GF64MUL_TABLE}, TMP0_L
vshl.u64 TWEAKV_H, TWEAKV_L, #1
veor TWEAKV_H, TMP0_L
.endif
.Lnext_128bytes_\@:
/*
* Load the source blocks into {X,Y}[0-3], XOR them with their XTS tweak
* values, and save the tweaks on the stack for later. Then
* de-interleave the 'x' and 'y' elements of each block, i.e. make it so
* that the X[0-3] registers contain only the second halves of blocks,
* and the Y[0-3] registers contain only the first halves of blocks.
* (Speck uses the order (y, x) rather than the more intuitive (x, y).)
*/
mov r12, sp
.if \n == 64
_xts128_precrypt_one X0, r12, TMP0
_xts128_precrypt_one Y0, r12, TMP0
_xts128_precrypt_one X1, r12, TMP0
_xts128_precrypt_one Y1, r12, TMP0
_xts128_precrypt_one X2, r12, TMP0
_xts128_precrypt_one Y2, r12, TMP0
_xts128_precrypt_one X3, r12, TMP0
_xts128_precrypt_one Y3, r12, TMP0
vswp X0_L, Y0_H
vswp X1_L, Y1_H
vswp X2_L, Y2_H
vswp X3_L, Y3_H
.else
_xts64_precrypt_two X0, r12, TMP0
_xts64_precrypt_two Y0, r12, TMP0
_xts64_precrypt_two X1, r12, TMP0
_xts64_precrypt_two Y1, r12, TMP0
_xts64_precrypt_two X2, r12, TMP0
_xts64_precrypt_two Y2, r12, TMP0
_xts64_precrypt_two X3, r12, TMP0
_xts64_precrypt_two Y3, r12, TMP0
vuzp.32 Y0, X0
vuzp.32 Y1, X1
vuzp.32 Y2, X2
vuzp.32 Y3, X3
.endif
// Do the cipher rounds
mov r12, ROUND_KEYS
mov r6, NROUNDS
.Lnext_round_\@:
.if \decrypting
.if \n == 64
vld1.64 ROUND_KEY_L, [r12]
sub r12, #8
vmov ROUND_KEY_H, ROUND_KEY_L
.else
vld1.32 {ROUND_KEY_L[],ROUND_KEY_H[]}, [r12]
sub r12, #4
.endif
_speck_unround_128bytes \n
.else
.if \n == 64
vld1.64 ROUND_KEY_L, [r12]!
vmov ROUND_KEY_H, ROUND_KEY_L
.else
vld1.32 {ROUND_KEY_L[],ROUND_KEY_H[]}, [r12]!
.endif
_speck_round_128bytes \n
.endif
subs r6, r6, #1
bne .Lnext_round_\@
// Re-interleave the 'x' and 'y' elements of each block
.if \n == 64
vswp X0_L, Y0_H
vswp X1_L, Y1_H
vswp X2_L, Y2_H
vswp X3_L, Y3_H
.else
vzip.32 Y0, X0
vzip.32 Y1, X1
vzip.32 Y2, X2
vzip.32 Y3, X3
.endif
// XOR the encrypted/decrypted blocks with the tweaks we saved earlier
mov r12, sp
vld1.8 {TMP0, TMP1}, [r12:128]!
vld1.8 {TMP2, TMP3}, [r12:128]!
veor X0, TMP0
veor Y0, TMP1
veor X1, TMP2
veor Y1, TMP3
vld1.8 {TMP0, TMP1}, [r12:128]!
vld1.8 {TMP2, TMP3}, [r12:128]!
veor X2, TMP0
veor Y2, TMP1
veor X3, TMP2
veor Y3, TMP3
// Store the ciphertext in the destination buffer
vst1.8 {X0, Y0}, [DST]!
vst1.8 {X1, Y1}, [DST]!
vst1.8 {X2, Y2}, [DST]!
vst1.8 {X3, Y3}, [DST]!
// Continue if there are more 128-byte chunks remaining, else return
subs NBYTES, #128
bne .Lnext_128bytes_\@
// Store the next tweak
.if \n == 64
vst1.8 {TWEAKV}, [TWEAK]
.else
vst1.8 {TWEAKV_L}, [TWEAK]
.endif
mov sp, r7
pop {r4-r7}
bx lr
.endm
ENTRY(speck128_xts_encrypt_neon)
_speck_xts_crypt n=64, decrypting=0
ENDPROC(speck128_xts_encrypt_neon)
ENTRY(speck128_xts_decrypt_neon)
_speck_xts_crypt n=64, decrypting=1
ENDPROC(speck128_xts_decrypt_neon)
ENTRY(speck64_xts_encrypt_neon)
_speck_xts_crypt n=32, decrypting=0
ENDPROC(speck64_xts_encrypt_neon)
ENTRY(speck64_xts_decrypt_neon)
_speck_xts_crypt n=32, decrypting=1
ENDPROC(speck64_xts_decrypt_neon)

View file

@ -0,0 +1,314 @@
// SPDX-License-Identifier: GPL-2.0
/*
* NEON-accelerated implementation of Speck128-XTS and Speck64-XTS
*
* Copyright (c) 2018 Google, Inc
*
* Note: the NIST recommendation for XTS only specifies a 128-bit block size,
* but a 64-bit version (needed for Speck64) is fairly straightforward; the math
* is just done in GF(2^64) instead of GF(2^128), with the reducing polynomial
* x^64 + x^4 + x^3 + x + 1 from the original XEX paper (Rogaway, 2004:
* "Efficient Instantiations of Tweakable Blockciphers and Refinements to Modes
* OCB and PMAC"), represented as 0x1B.
*/
#include <asm/hwcap.h>
#include <asm/neon.h>
#include <asm/simd.h>
#include <crypto/algapi.h>
#include <crypto/gf128mul.h>
#include <crypto/speck.h>
#include <crypto/xts.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* The assembly functions only handle multiples of 128 bytes */
#define SPECK_NEON_CHUNK_SIZE 128
/* Speck128 */
struct speck128_xts_tfm_ctx {
struct speck128_tfm_ctx main_key;
struct speck128_tfm_ctx tweak_key;
};
asmlinkage void speck128_xts_encrypt_neon(const u64 *round_keys, int nrounds,
void *dst, const void *src,
unsigned int nbytes, void *tweak);
asmlinkage void speck128_xts_decrypt_neon(const u64 *round_keys, int nrounds,
void *dst, const void *src,
unsigned int nbytes, void *tweak);
typedef void (*speck128_crypt_one_t)(const struct speck128_tfm_ctx *,
u8 *, const u8 *);
typedef void (*speck128_xts_crypt_many_t)(const u64 *, int, void *,
const void *, unsigned int, void *);
static __always_inline int
__speck128_xts_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
struct scatterlist *src, unsigned int nbytes,
speck128_crypt_one_t crypt_one,
speck128_xts_crypt_many_t crypt_many)
{
struct crypto_blkcipher *tfm = desc->tfm;
const struct speck128_xts_tfm_ctx *ctx = crypto_blkcipher_ctx(tfm);
struct blkcipher_walk walk;
le128 tweak;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt_block(desc, &walk, SPECK_NEON_CHUNK_SIZE);
crypto_speck128_encrypt(&ctx->tweak_key, (u8 *)&tweak, walk.iv);
while (walk.nbytes > 0) {
unsigned int nbytes = walk.nbytes;
u8 *dst = walk.dst.virt.addr;
const u8 *src = walk.src.virt.addr;
if (nbytes >= SPECK_NEON_CHUNK_SIZE && may_use_simd()) {
unsigned int count;
count = round_down(nbytes, SPECK_NEON_CHUNK_SIZE);
kernel_neon_begin();
(*crypt_many)(ctx->main_key.round_keys,
ctx->main_key.nrounds,
dst, src, count, &tweak);
kernel_neon_end();
dst += count;
src += count;
nbytes -= count;
}
/* Handle any remainder with generic code */
while (nbytes >= sizeof(tweak)) {
le128_xor((le128 *)dst, (const le128 *)src, &tweak);
(*crypt_one)(&ctx->main_key, dst, dst);
le128_xor((le128 *)dst, (const le128 *)dst, &tweak);
gf128mul_x_ble((be128 *)&tweak, (const be128 *)&tweak);
dst += sizeof(tweak);
src += sizeof(tweak);
nbytes -= sizeof(tweak);
}
err = blkcipher_walk_done(desc, &walk, nbytes);
}
return err;
}
static int speck128_xts_encrypt(struct blkcipher_desc *desc,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
return __speck128_xts_crypt(desc, dst, src, nbytes,
crypto_speck128_encrypt,
speck128_xts_encrypt_neon);
}
static int speck128_xts_decrypt(struct blkcipher_desc *desc,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes)
{
return __speck128_xts_crypt(desc, dst, src, nbytes,
crypto_speck128_decrypt,
speck128_xts_decrypt_neon);
}
static int speck128_xts_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen)
{
struct speck128_xts_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
int err;
if (keylen % 2)
return -EINVAL;
keylen /= 2;
err = crypto_speck128_setkey(&ctx->main_key, key, keylen);
if (err)
return err;
return crypto_speck128_setkey(&ctx->tweak_key, key + keylen, keylen);
}
/* Speck64 */
struct speck64_xts_tfm_ctx {
struct speck64_tfm_ctx main_key;
struct speck64_tfm_ctx tweak_key;
};
asmlinkage void speck64_xts_encrypt_neon(const u32 *round_keys, int nrounds,
void *dst, const void *src,
unsigned int nbytes, void *tweak);
asmlinkage void speck64_xts_decrypt_neon(const u32 *round_keys, int nrounds,
void *dst, const void *src,
unsigned int nbytes, void *tweak);
typedef void (*speck64_crypt_one_t)(const struct speck64_tfm_ctx *,
u8 *, const u8 *);
typedef void (*speck64_xts_crypt_many_t)(const u32 *, int, void *,
const void *, unsigned int, void *);
static __always_inline int
__speck64_xts_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
struct scatterlist *src, unsigned int nbytes,
speck64_crypt_one_t crypt_one,
speck64_xts_crypt_many_t crypt_many)
{
struct crypto_blkcipher *tfm = desc->tfm;
const struct speck64_xts_tfm_ctx *ctx = crypto_blkcipher_ctx(tfm);
struct blkcipher_walk walk;
__le64 tweak;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt_block(desc, &walk, SPECK_NEON_CHUNK_SIZE);
crypto_speck64_encrypt(&ctx->tweak_key, (u8 *)&tweak, walk.iv);
while (walk.nbytes > 0) {
unsigned int nbytes = walk.nbytes;
u8 *dst = walk.dst.virt.addr;
const u8 *src = walk.src.virt.addr;
if (nbytes >= SPECK_NEON_CHUNK_SIZE && may_use_simd()) {
unsigned int count;
count = round_down(nbytes, SPECK_NEON_CHUNK_SIZE);
kernel_neon_begin();
(*crypt_many)(ctx->main_key.round_keys,
ctx->main_key.nrounds,
dst, src, count, &tweak);
kernel_neon_end();
dst += count;
src += count;
nbytes -= count;
}
/* Handle any remainder with generic code */
while (nbytes >= sizeof(tweak)) {
*(__le64 *)dst = *(__le64 *)src ^ tweak;
(*crypt_one)(&ctx->main_key, dst, dst);
*(__le64 *)dst ^= tweak;
tweak = cpu_to_le64((le64_to_cpu(tweak) << 1) ^
((tweak & cpu_to_le64(1ULL << 63)) ?
0x1B : 0));
dst += sizeof(tweak);
src += sizeof(tweak);
nbytes -= sizeof(tweak);
}
err = blkcipher_walk_done(desc, &walk, nbytes);
}
return err;
}
static int speck64_xts_encrypt(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes)
{
return __speck64_xts_crypt(desc, dst, src, nbytes,
crypto_speck64_encrypt,
speck64_xts_encrypt_neon);
}
static int speck64_xts_decrypt(struct blkcipher_desc *desc,
struct scatterlist *dst, struct scatterlist *src,
unsigned int nbytes)
{
return __speck64_xts_crypt(desc, dst, src, nbytes,
crypto_speck64_decrypt,
speck64_xts_decrypt_neon);
}
static int speck64_xts_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen)
{
struct speck64_xts_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
int err;
if (keylen % 2)
return -EINVAL;
keylen /= 2;
err = crypto_speck64_setkey(&ctx->main_key, key, keylen);
if (err)
return err;
return crypto_speck64_setkey(&ctx->tweak_key, key + keylen, keylen);
}
static struct crypto_alg speck_algs[] = {
{
.cra_name = "xts(speck128)",
.cra_driver_name = "xts-speck128-neon",
.cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_blocksize = SPECK128_BLOCK_SIZE,
.cra_type = &crypto_blkcipher_type,
.cra_ctxsize = sizeof(struct speck128_xts_tfm_ctx),
.cra_alignmask = 7,
.cra_module = THIS_MODULE,
.cra_u = {
.blkcipher = {
.min_keysize = 2 * SPECK128_128_KEY_SIZE,
.max_keysize = 2 * SPECK128_256_KEY_SIZE,
.ivsize = SPECK128_BLOCK_SIZE,
.setkey = speck128_xts_setkey,
.encrypt = speck128_xts_encrypt,
.decrypt = speck128_xts_decrypt,
}
}
}, {
.cra_name = "xts(speck64)",
.cra_driver_name = "xts-speck64-neon",
.cra_priority = 300,
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_blocksize = SPECK64_BLOCK_SIZE,
.cra_type = &crypto_blkcipher_type,
.cra_ctxsize = sizeof(struct speck64_xts_tfm_ctx),
.cra_alignmask = 7,
.cra_module = THIS_MODULE,
.cra_u = {
.blkcipher = {
.min_keysize = 2 * SPECK64_96_KEY_SIZE,
.max_keysize = 2 * SPECK64_128_KEY_SIZE,
.ivsize = SPECK64_BLOCK_SIZE,
.setkey = speck64_xts_setkey,
.encrypt = speck64_xts_encrypt,
.decrypt = speck64_xts_decrypt,
}
}
}
};
static int __init speck_neon_module_init(void)
{
if (!(elf_hwcap & HWCAP_NEON))
return -ENODEV;
return crypto_register_algs(speck_algs, ARRAY_SIZE(speck_algs));
}
static void __exit speck_neon_module_exit(void)
{
crypto_unregister_algs(speck_algs, ARRAY_SIZE(speck_algs));
}
module_init(speck_neon_module_init);
module_exit(speck_neon_module_exit);
MODULE_DESCRIPTION("Speck block cipher (NEON-accelerated)");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
MODULE_ALIAS_CRYPTO("xts(speck128)");
MODULE_ALIAS_CRYPTO("xts-speck128-neon");
MODULE_ALIAS_CRYPTO("xts(speck64)");
MODULE_ALIAS_CRYPTO("xts-speck64-neon");

View file

@ -73,6 +73,25 @@ phys_addr_t omap_secure_ram_mempool_base(void)
return omap_secure_memblock_base; return omap_secure_memblock_base;
} }
u32 omap3_save_secure_ram(void __iomem *addr, int size)
{
u32 ret;
u32 param[5];
if (size != OMAP3_SAVE_SECURE_RAM_SZ)
return OMAP3_SAVE_SECURE_RAM_SZ;
param[0] = 4; /* Number of arguments */
param[1] = __pa(addr); /* Physical address for saving */
param[2] = 0;
param[3] = 1;
param[4] = 1;
ret = save_secure_ram_context(__pa(param));
return ret;
}
/** /**
* rx51_secure_dispatcher: Routine to dispatch secure PPA API calls * rx51_secure_dispatcher: Routine to dispatch secure PPA API calls
* @idx: The PPA API index * @idx: The PPA API index

View file

@ -31,6 +31,8 @@
/* Maximum Secure memory storage size */ /* Maximum Secure memory storage size */
#define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K) #define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K)
#define OMAP3_SAVE_SECURE_RAM_SZ 0x803F
/* Secure low power HAL API index */ /* Secure low power HAL API index */
#define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a #define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a
#define OMAP4_HAL_SAVEHW_INDEX 0x1b #define OMAP4_HAL_SAVEHW_INDEX 0x1b
@ -64,6 +66,8 @@ extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs); extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs);
extern phys_addr_t omap_secure_ram_mempool_base(void); extern phys_addr_t omap_secure_ram_mempool_base(void);
extern int omap_secure_ram_reserve_memblock(void); extern int omap_secure_ram_reserve_memblock(void);
extern u32 save_secure_ram_context(u32 args_pa);
extern u32 omap3_save_secure_ram(void __iomem *save_regs, int size);
extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs, extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
u32 arg1, u32 arg2, u32 arg3, u32 arg4); u32 arg1, u32 arg2, u32 arg3, u32 arg4);

View file

@ -81,10 +81,6 @@ extern unsigned int omap3_do_wfi_sz;
/* ... and its pointer from SRAM after copy */ /* ... and its pointer from SRAM after copy */
extern void (*omap3_do_wfi_sram)(void); extern void (*omap3_do_wfi_sram)(void);
/* save_secure_ram_context function pointer and size, for copy to SRAM */
extern int save_secure_ram_context(u32 *addr);
extern unsigned int save_secure_ram_context_sz;
extern void omap3_save_scratchpad_contents(void); extern void omap3_save_scratchpad_contents(void);
#define PM_RTA_ERRATUM_i608 (1 << 0) #define PM_RTA_ERRATUM_i608 (1 << 0)

View file

@ -48,6 +48,7 @@
#include "prm3xxx.h" #include "prm3xxx.h"
#include "pm.h" #include "pm.h"
#include "sdrc.h" #include "sdrc.h"
#include "omap-secure.h"
#include "sram.h" #include "sram.h"
#include "control.h" #include "control.h"
#include "vc.h" #include "vc.h"
@ -66,7 +67,6 @@ struct power_state {
static LIST_HEAD(pwrst_list); static LIST_HEAD(pwrst_list);
static int (*_omap_save_secure_sram)(u32 *addr);
void (*omap3_do_wfi_sram)(void); void (*omap3_do_wfi_sram)(void);
static struct powerdomain *mpu_pwrdm, *neon_pwrdm; static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
@ -121,8 +121,8 @@ static void omap3_save_secure_ram_context(void)
* will hang the system. * will hang the system.
*/ */
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
ret = _omap_save_secure_sram((u32 *)(unsigned long) ret = omap3_save_secure_ram(omap3_secure_ram_storage,
__pa(omap3_secure_ram_storage)); OMAP3_SAVE_SECURE_RAM_SZ);
pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state); pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state);
/* Following is for error tracking, it should not happen */ /* Following is for error tracking, it should not happen */
if (ret) { if (ret) {
@ -431,15 +431,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
* *
* The minimum set of functions is pushed to SRAM for execution: * The minimum set of functions is pushed to SRAM for execution:
* - omap3_do_wfi for erratum i581 WA, * - omap3_do_wfi for erratum i581 WA,
* - save_secure_ram_context for security extensions.
*/ */
void omap_push_sram_idle(void) void omap_push_sram_idle(void)
{ {
omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz); omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
if (omap_type() != OMAP2_DEVICE_TYPE_GP)
_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
save_secure_ram_context_sz);
} }
static void __init pm_errata_configure(void) static void __init pm_errata_configure(void)
@ -551,7 +546,7 @@ int __init omap3_pm_init(void)
clkdm_add_wkdep(neon_clkdm, mpu_clkdm); clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
if (omap_type() != OMAP2_DEVICE_TYPE_GP) { if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
omap3_secure_ram_storage = omap3_secure_ram_storage =
kmalloc(0x803F, GFP_KERNEL); kmalloc(OMAP3_SAVE_SECURE_RAM_SZ, GFP_KERNEL);
if (!omap3_secure_ram_storage) if (!omap3_secure_ram_storage)
pr_err("Memory allocation failed when allocating for secure sram context\n"); pr_err("Memory allocation failed when allocating for secure sram context\n");

View file

@ -176,17 +176,6 @@ static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
return v; return v;
} }
static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
{
u32 v;
v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs);
v &= AM33XX_LASTPOWERSTATEENTERED_MASK;
v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT;
return v;
}
static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
{ {
am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK, am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK,
@ -357,7 +346,6 @@ struct pwrdm_ops am33xx_pwrdm_operations = {
.pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
.pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
.pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst, .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst,
.pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst,
.pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst, .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst,
.pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst, .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst,
.pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst, .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst,

View file

@ -93,20 +93,13 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
ENDPROC(enable_omap3630_toggle_l2_on_restore) ENDPROC(enable_omap3630_toggle_l2_on_restore)
/* /*
* Function to call rom code to save secure ram context. This gets * Function to call rom code to save secure ram context.
* relocated to SRAM, so it can be all in .data section. Otherwise *
* we need to initialize api_params separately. * r0 = physical address of the parameters
*/ */
.data
.align 3
ENTRY(save_secure_ram_context) ENTRY(save_secure_ram_context)
stmfd sp!, {r4 - r11, lr} @ save registers on stack stmfd sp!, {r4 - r11, lr} @ save registers on stack
adr r3, api_params @ r3 points to parameters mov r3, r0 @ physical address of parameters
str r0, [r3,#0x4] @ r0 has sdram address
ldr r12, high_mask
and r3, r3, r12
ldr r12, sram_phy_addr_mask
orr r3, r3, r12
mov r0, #25 @ set service ID for PPA mov r0, #25 @ set service ID for PPA
mov r12, r0 @ copy secure service ID in r12 mov r12, r0 @ copy secure service ID in r12
mov r1, #0 @ set task id for ROM code in r1 mov r1, #0 @ set task id for ROM code in r1
@ -120,18 +113,7 @@ ENTRY(save_secure_ram_context)
nop nop
nop nop
ldmfd sp!, {r4 - r11, pc} ldmfd sp!, {r4 - r11, pc}
.align
sram_phy_addr_mask:
.word SRAM_BASE_P
high_mask:
.word 0xffff
api_params:
.word 0x4, 0x0, 0x0, 0x1, 0x1
ENDPROC(save_secure_ram_context) ENDPROC(save_secure_ram_context)
ENTRY(save_secure_ram_context_sz)
.word . - save_secure_ram_context
.text
/* /*
* ====================== * ======================

View file

@ -12,8 +12,6 @@ menuconfig ARCH_TEGRA
select ARCH_HAS_RESET_CONTROLLER select ARCH_HAS_RESET_CONTROLLER
select RESET_CONTROLLER select RESET_CONTROLLER
select SOC_BUS select SOC_BUS
select USB_ULPI if USB_PHY
select USB_ULPI_VIEWPORT if USB_PHY
help help
This enables support for NVIDIA Tegra based systems. This enables support for NVIDIA Tegra based systems.

View file

@ -1147,7 +1147,7 @@ source "fs/Kconfig.binfmt"
config COMPAT config COMPAT
bool "Kernel support for 32-bit EL0" bool "Kernel support for 32-bit EL0"
depends on ARM64_4K_PAGES || EXPERT depends on ARM64_4K_PAGES || EXPERT
select COMPAT_BINFMT_ELF select COMPAT_BINFMT_ELF if BINFMT_ELF
select HAVE_UID16 select HAVE_UID16
select OLD_SIGSUSPEND3 select OLD_SIGSUSPEND3
select COMPAT_OLD_SIGACTION select COMPAT_OLD_SIGACTION

View file

@ -146,8 +146,6 @@ config ARCH_TEGRA_132_SOC
bool "NVIDIA Tegra132 SoC" bool "NVIDIA Tegra132 SoC"
depends on ARCH_TEGRA depends on ARCH_TEGRA
select PINCTRL_TEGRA124 select PINCTRL_TEGRA124
select USB_ULPI if USB_PHY
select USB_ULPI_VIEWPORT if USB_PHY
help help
Enable support for NVIDIA Tegra132 SoC, based on the Denver Enable support for NVIDIA Tegra132 SoC, based on the Denver
ARMv8 CPU. The Tegra132 SoC is similar to the Tegra124 SoC, ARMv8 CPU. The Tegra132 SoC is similar to the Tegra124 SoC,

View file

@ -54,6 +54,7 @@
reg = <0x000>; reg = <0x000>;
enable-method = "psci"; enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0>; cpu-idle-states = <&CPU_SLEEP_0>;
#cooling-cells = <2>;
}; };
cpu1: cpu@1 { cpu1: cpu@1 {
@ -70,6 +71,7 @@
reg = <0x100>; reg = <0x100>;
enable-method = "psci"; enable-method = "psci";
cpu-idle-states = <&CPU_SLEEP_0>; cpu-idle-states = <&CPU_SLEEP_0>;
#cooling-cells = <2>;
}; };
cpu3: cpu@101 { cpu3: cpu@101 {

View file

@ -20,9 +20,6 @@
#include <asm/brk-imm.h> #include <asm/brk-imm.h>
#ifdef CONFIG_GENERIC_BUG
#define HAVE_ARCH_BUG
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line) #define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line)
#define __BUGVERBOSE_LOCATION(file, line) \ #define __BUGVERBOSE_LOCATION(file, line) \
@ -36,28 +33,36 @@
#define _BUGVERBOSE_LOCATION(file, line) #define _BUGVERBOSE_LOCATION(file, line)
#endif #endif
#define _BUG_FLAGS(flags) __BUG_FLAGS(flags) #ifdef CONFIG_GENERIC_BUG
#define __BUG_FLAGS(flags) asm volatile ( \ #define __BUG_ENTRY(flags) \
".pushsection __bug_table,\"a\"\n\t" \ ".pushsection __bug_table,\"a\"\n\t" \
".align 2\n\t" \ ".align 2\n\t" \
"0: .long 1f - 0b\n\t" \ "0: .long 1f - 0b\n\t" \
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ _BUGVERBOSE_LOCATION(__FILE__, __LINE__) \
".short " #flags "\n\t" \ ".short " #flags "\n\t" \
".popsection\n" \ ".popsection\n" \
\ "1: "
"1: brk %[imm]" \ #else
:: [imm] "i" (BUG_BRK_IMM) \ #define __BUG_ENTRY(flags) ""
) #endif
#define BUG() do { \ #define __BUG_FLAGS(flags) \
_BUG_FLAGS(0); \ asm volatile ( \
unreachable(); \ __BUG_ENTRY(flags) \
"brk %[imm]" :: [imm] "i" (BUG_BRK_IMM) \
);
#define BUG() do { \
__BUG_FLAGS(0); \
unreachable(); \
} while (0) } while (0)
#define __WARN_TAINT(taint) _BUG_FLAGS(BUGFLAG_TAINT(taint)) #define __WARN_TAINT(taint) \
__BUG_FLAGS(BUGFLAG_TAINT(taint))
#endif /* ! CONFIG_GENERIC_BUG */ #define HAVE_ARCH_BUG
#include <asm-generic/bug.h> #include <asm-generic/bug.h>

View file

@ -1381,7 +1381,7 @@ static int collect_events(struct perf_event *group, int max_count,
int n = 0; int n = 0;
struct perf_event *event; struct perf_event *event;
if (!is_software_event(group)) { if (group->pmu->task_ctx_nr == perf_hw_context) {
if (n >= max_count) if (n >= max_count)
return -1; return -1;
ctrs[n] = group; ctrs[n] = group;
@ -1389,7 +1389,7 @@ static int collect_events(struct perf_event *group, int max_count,
events[n++] = group->hw.config; events[n++] = group->hw.config;
} }
list_for_each_entry(event, &group->sibling_list, group_entry) { list_for_each_entry(event, &group->sibling_list, group_entry) {
if (!is_software_event(event) && if (event->pmu->task_ctx_nr == perf_hw_context &&
event->state != PERF_EVENT_STATE_OFF) { event->state != PERF_EVENT_STATE_OFF) {
if (n >= max_count) if (n >= max_count)
return -1; return -1;

View file

@ -1027,7 +1027,7 @@ config X86_MCE_THRESHOLD
def_bool y def_bool y
config X86_MCE_INJECT config X86_MCE_INJECT
depends on X86_MCE depends on X86_MCE && X86_LOCAL_APIC
tristate "Machine check injector support" tristate "Machine check injector support"
---help--- ---help---
Provide support for injecting machine checks for testing purposes. Provide support for injecting machine checks for testing purposes.

View file

@ -379,6 +379,7 @@ config X86_DEBUG_FPU
config PUNIT_ATOM_DEBUG config PUNIT_ATOM_DEBUG
tristate "ATOM Punit debug driver" tristate "ATOM Punit debug driver"
depends on PCI
select DEBUG_FS select DEBUG_FS
select IOSF_MBI select IOSF_MBI
---help--- ---help---

View file

@ -72,12 +72,13 @@ UBSAN_SANITIZE := n
$(obj)/bzImage: asflags-y := $(SVGA_MODE) $(obj)/bzImage: asflags-y := $(SVGA_MODE)
quiet_cmd_image = BUILD $@ quiet_cmd_image = BUILD $@
silent_redirect_image = >/dev/null
cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \ cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \
$(obj)/zoffset.h $@ $(obj)/zoffset.h $@ $($(quiet)redirect_image)
$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE $(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image) $(call if_changed,image)
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')' @$(kecho) 'Kernel: $@ is ready' ' (#'`cat .version`')'
OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note -R .comment -S OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note -R .comment -S
$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE

View file

@ -55,29 +55,31 @@
#define RAB1bl %bl #define RAB1bl %bl
#define RAB2bl %cl #define RAB2bl %cl
#define CD0 0x0(%rsp)
#define CD1 0x8(%rsp)
#define CD2 0x10(%rsp)
# used only before/after all rounds
#define RCD0 %r8 #define RCD0 %r8
#define RCD1 %r9 #define RCD1 %r9
#define RCD2 %r10 #define RCD2 %r10
#define RCD0d %r8d # used only during rounds
#define RCD1d %r9d #define RX0 %r8
#define RCD2d %r10d #define RX1 %r9
#define RX2 %r10
#define RX0 %rbp #define RX0d %r8d
#define RX1 %r11 #define RX1d %r9d
#define RX2 %r12 #define RX2d %r10d
#define RX0d %ebp #define RY0 %r11
#define RX1d %r11d #define RY1 %r12
#define RX2d %r12d #define RY2 %r13
#define RY0 %r13 #define RY0d %r11d
#define RY1 %r14 #define RY1d %r12d
#define RY2 %r15 #define RY2d %r13d
#define RY0d %r13d
#define RY1d %r14d
#define RY2d %r15d
#define RT0 %rdx #define RT0 %rdx
#define RT1 %rsi #define RT1 %rsi
@ -85,6 +87,8 @@
#define RT0d %edx #define RT0d %edx
#define RT1d %esi #define RT1d %esi
#define RT1bl %sil
#define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \ #define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \
movzbl ab ## bl, tmp2 ## d; \ movzbl ab ## bl, tmp2 ## d; \
movzbl ab ## bh, tmp1 ## d; \ movzbl ab ## bh, tmp1 ## d; \
@ -92,6 +96,11 @@
op1##l T0(CTX, tmp2, 4), dst ## d; \ op1##l T0(CTX, tmp2, 4), dst ## d; \
op2##l T1(CTX, tmp1, 4), dst ## d; op2##l T1(CTX, tmp1, 4), dst ## d;
#define swap_ab_with_cd(ab, cd, tmp) \
movq cd, tmp; \
movq ab, cd; \
movq tmp, ab;
/* /*
* Combined G1 & G2 function. Reordered with help of rotates to have moves * Combined G1 & G2 function. Reordered with help of rotates to have moves
* at begining. * at begining.
@ -110,15 +119,15 @@
/* G1,2 && G2,2 */ \ /* G1,2 && G2,2 */ \
do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \ do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \
do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \ do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \
xchgq cd ## 0, ab ## 0; \ swap_ab_with_cd(ab ## 0, cd ## 0, RT0); \
\ \
do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \ do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \
do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \ do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \
xchgq cd ## 1, ab ## 1; \ swap_ab_with_cd(ab ## 1, cd ## 1, RT0); \
\ \
do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \ do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \
do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \ do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \
xchgq cd ## 2, ab ## 2; swap_ab_with_cd(ab ## 2, cd ## 2, RT0);
#define enc_round_end(ab, x, y, n) \ #define enc_round_end(ab, x, y, n) \
addl y ## d, x ## d; \ addl y ## d, x ## d; \
@ -168,6 +177,16 @@
decrypt_round3(ba, dc, (n*2)+1); \ decrypt_round3(ba, dc, (n*2)+1); \
decrypt_round3(ba, dc, (n*2)); decrypt_round3(ba, dc, (n*2));
#define push_cd() \
pushq RCD2; \
pushq RCD1; \
pushq RCD0;
#define pop_cd() \
popq RCD0; \
popq RCD1; \
popq RCD2;
#define inpack3(in, n, xy, m) \ #define inpack3(in, n, xy, m) \
movq 4*(n)(in), xy ## 0; \ movq 4*(n)(in), xy ## 0; \
xorq w+4*m(CTX), xy ## 0; \ xorq w+4*m(CTX), xy ## 0; \
@ -223,11 +242,8 @@ ENTRY(__twofish_enc_blk_3way)
* %rdx: src, RIO * %rdx: src, RIO
* %rcx: bool, if true: xor output * %rcx: bool, if true: xor output
*/ */
pushq %r15;
pushq %r14;
pushq %r13; pushq %r13;
pushq %r12; pushq %r12;
pushq %rbp;
pushq %rbx; pushq %rbx;
pushq %rcx; /* bool xor */ pushq %rcx; /* bool xor */
@ -235,40 +251,36 @@ ENTRY(__twofish_enc_blk_3way)
inpack_enc3(); inpack_enc3();
encrypt_cycle3(RAB, RCD, 0); push_cd();
encrypt_cycle3(RAB, RCD, 1); encrypt_cycle3(RAB, CD, 0);
encrypt_cycle3(RAB, RCD, 2); encrypt_cycle3(RAB, CD, 1);
encrypt_cycle3(RAB, RCD, 3); encrypt_cycle3(RAB, CD, 2);
encrypt_cycle3(RAB, RCD, 4); encrypt_cycle3(RAB, CD, 3);
encrypt_cycle3(RAB, RCD, 5); encrypt_cycle3(RAB, CD, 4);
encrypt_cycle3(RAB, RCD, 6); encrypt_cycle3(RAB, CD, 5);
encrypt_cycle3(RAB, RCD, 7); encrypt_cycle3(RAB, CD, 6);
encrypt_cycle3(RAB, CD, 7);
pop_cd();
popq RIO; /* dst */ popq RIO; /* dst */
popq %rbp; /* bool xor */ popq RT1; /* bool xor */
testb %bpl, %bpl; testb RT1bl, RT1bl;
jnz .L__enc_xor3; jnz .L__enc_xor3;
outunpack_enc3(mov); outunpack_enc3(mov);
popq %rbx; popq %rbx;
popq %rbp;
popq %r12; popq %r12;
popq %r13; popq %r13;
popq %r14;
popq %r15;
ret; ret;
.L__enc_xor3: .L__enc_xor3:
outunpack_enc3(xor); outunpack_enc3(xor);
popq %rbx; popq %rbx;
popq %rbp;
popq %r12; popq %r12;
popq %r13; popq %r13;
popq %r14;
popq %r15;
ret; ret;
ENDPROC(__twofish_enc_blk_3way) ENDPROC(__twofish_enc_blk_3way)
@ -278,35 +290,31 @@ ENTRY(twofish_dec_blk_3way)
* %rsi: dst * %rsi: dst
* %rdx: src, RIO * %rdx: src, RIO
*/ */
pushq %r15;
pushq %r14;
pushq %r13; pushq %r13;
pushq %r12; pushq %r12;
pushq %rbp;
pushq %rbx; pushq %rbx;
pushq %rsi; /* dst */ pushq %rsi; /* dst */
inpack_dec3(); inpack_dec3();
decrypt_cycle3(RAB, RCD, 7); push_cd();
decrypt_cycle3(RAB, RCD, 6); decrypt_cycle3(RAB, CD, 7);
decrypt_cycle3(RAB, RCD, 5); decrypt_cycle3(RAB, CD, 6);
decrypt_cycle3(RAB, RCD, 4); decrypt_cycle3(RAB, CD, 5);
decrypt_cycle3(RAB, RCD, 3); decrypt_cycle3(RAB, CD, 4);
decrypt_cycle3(RAB, RCD, 2); decrypt_cycle3(RAB, CD, 3);
decrypt_cycle3(RAB, RCD, 1); decrypt_cycle3(RAB, CD, 2);
decrypt_cycle3(RAB, RCD, 0); decrypt_cycle3(RAB, CD, 1);
decrypt_cycle3(RAB, CD, 0);
pop_cd();
popq RIO; /* dst */ popq RIO; /* dst */
outunpack_dec3(); outunpack_dec3();
popq %rbx; popq %rbx;
popq %rbp;
popq %r12; popq %r12;
popq %r13; popq %r13;
popq %r14;
popq %r15;
ret; ret;
ENDPROC(twofish_dec_blk_3way) ENDPROC(twofish_dec_blk_3way)

View file

@ -20,6 +20,7 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/context_tracking.h> #include <linux/context_tracking.h>
#include <linux/user-return-notifier.h> #include <linux/user-return-notifier.h>
#include <linux/nospec.h>
#include <linux/uprobes.h> #include <linux/uprobes.h>
#include <asm/desc.h> #include <asm/desc.h>
@ -381,6 +382,7 @@ __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
} }
if (likely(nr < IA32_NR_syscalls)) { if (likely(nr < IA32_NR_syscalls)) {
nr = array_index_nospec(nr, IA32_NR_syscalls);
/* /*
* It's possible that a 32-bit syscall implementation * It's possible that a 32-bit syscall implementation
* takes a 64-bit parameter but nonetheless assumes that * takes a 64-bit parameter but nonetheless assumes that

View file

@ -37,5 +37,4 @@ INDIRECT_THUNK(dx)
INDIRECT_THUNK(si) INDIRECT_THUNK(si)
INDIRECT_THUNK(di) INDIRECT_THUNK(di)
INDIRECT_THUNK(bp) INDIRECT_THUNK(bp)
INDIRECT_THUNK(sp)
#endif /* CONFIG_RETPOLINE */ #endif /* CONFIG_RETPOLINE */

View file

@ -24,6 +24,34 @@
#define wmb() asm volatile("sfence" ::: "memory") #define wmb() asm volatile("sfence" ::: "memory")
#endif #endif
/**
* array_index_mask_nospec() - generate a mask that is ~0UL when the
* bounds check succeeds and 0 otherwise
* @index: array element index
* @size: number of elements in array
*
* Returns:
* 0 - (index < size)
*/
static inline unsigned long array_index_mask_nospec(unsigned long index,
unsigned long size)
{
unsigned long mask;
asm ("cmp %1,%2; sbb %0,%0;"
:"=r" (mask)
:"r"(size),"r" (index)
:"cc");
return mask;
}
/* Override the default implementation from linux/nospec.h. */
#define array_index_mask_nospec array_index_mask_nospec
/* Prevent speculative execution past this barrier. */
#define barrier_nospec() alternative_2("", "mfence", X86_FEATURE_MFENCE_RDTSC, \
"lfence", X86_FEATURE_LFENCE_RDTSC)
#ifdef CONFIG_X86_PPRO_FENCE #ifdef CONFIG_X86_PPRO_FENCE
#define dma_rmb() rmb() #define dma_rmb() rmb()
#else #else

View file

@ -59,7 +59,6 @@ static inline u16 find_equiv_id(struct equiv_cpu_entry *equiv_cpu_table,
extern int __apply_microcode_amd(struct microcode_amd *mc_amd); extern int __apply_microcode_amd(struct microcode_amd *mc_amd);
extern int apply_microcode_amd(int cpu); extern int apply_microcode_amd(int cpu);
extern enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size);
#define PATCH_MAX_SIZE PAGE_SIZE #define PATCH_MAX_SIZE PAGE_SIZE
extern u8 amd_ucode_patch[PATCH_MAX_SIZE]; extern u8 amd_ucode_patch[PATCH_MAX_SIZE];

View file

@ -147,8 +147,7 @@ static __always_inline unsigned long long rdtsc_ordered(void)
* that some other imaginary CPU is updating continuously with a * that some other imaginary CPU is updating continuously with a
* time stamp. * time stamp.
*/ */
alternative_2("", "mfence", X86_FEATURE_MFENCE_RDTSC, barrier_nospec();
"lfence", X86_FEATURE_LFENCE_RDTSC);
return rdtsc(); return rdtsc();
} }

View file

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#ifndef __NOSPEC_BRANCH_H__ #ifndef _ASM_X86_NOSPEC_BRANCH_H_
#define __NOSPEC_BRANCH_H__ #define _ASM_X86_NOSPEC_BRANCH_H_
#include <asm/alternative.h> #include <asm/alternative.h>
#include <asm/alternative-asm.h> #include <asm/alternative-asm.h>
@ -178,7 +178,7 @@ extern char __indirect_thunk_end[];
* On VMEXIT we must ensure that no RSB predictions learned in the guest * On VMEXIT we must ensure that no RSB predictions learned in the guest
* can be followed in the host, by overwriting the RSB completely. Both * can be followed in the host, by overwriting the RSB completely. Both
* retpoline and IBRS mitigations for Spectre v2 need this; only on future * retpoline and IBRS mitigations for Spectre v2 need this; only on future
* CPUs with IBRS_ATT *might* it be avoided. * CPUs with IBRS_ALL *might* it be avoided.
*/ */
static inline void vmexit_fill_RSB(void) static inline void vmexit_fill_RSB(void)
{ {
@ -195,4 +195,4 @@ static inline void vmexit_fill_RSB(void)
} }
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __NOSPEC_BRANCH_H__ */ #endif /* _ASM_X86_NOSPEC_BRANCH_H_ */

View file

@ -400,10 +400,11 @@ enum vmcs_field {
#define IDENTITY_PAGETABLE_PRIVATE_MEMSLOT (KVM_USER_MEM_SLOTS + 2) #define IDENTITY_PAGETABLE_PRIVATE_MEMSLOT (KVM_USER_MEM_SLOTS + 2)
#define VMX_NR_VPIDS (1 << 16) #define VMX_NR_VPIDS (1 << 16)
#define VMX_VPID_EXTENT_INDIVIDUAL_ADDR 0
#define VMX_VPID_EXTENT_SINGLE_CONTEXT 1 #define VMX_VPID_EXTENT_SINGLE_CONTEXT 1
#define VMX_VPID_EXTENT_ALL_CONTEXT 2 #define VMX_VPID_EXTENT_ALL_CONTEXT 2
#define VMX_VPID_EXTENT_SINGLE_NON_GLOBAL 3
#define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0
#define VMX_EPT_EXTENT_CONTEXT 1 #define VMX_EPT_EXTENT_CONTEXT 1
#define VMX_EPT_EXTENT_GLOBAL 2 #define VMX_EPT_EXTENT_GLOBAL 2
#define VMX_EPT_EXTENT_SHIFT 24 #define VMX_EPT_EXTENT_SHIFT 24
@ -420,8 +421,10 @@ enum vmcs_field {
#define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) #define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26)
#define VMX_VPID_INVVPID_BIT (1ull << 0) /* (32 - 32) */ #define VMX_VPID_INVVPID_BIT (1ull << 0) /* (32 - 32) */
#define VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT (1ull << 8) /* (40 - 32) */
#define VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT (1ull << 9) /* (41 - 32) */ #define VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT (1ull << 9) /* (41 - 32) */
#define VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT (1ull << 10) /* (42 - 32) */ #define VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT (1ull << 10) /* (42 - 32) */
#define VMX_VPID_EXTENT_SINGLE_NON_GLOBAL_BIT (1ull << 11) /* (43 - 32) */
#define VMX_EPT_DEFAULT_GAW 3 #define VMX_EPT_DEFAULT_GAW 3
#define VMX_EPT_MAX_GAW 0x4 #define VMX_EPT_MAX_GAW 0x4

View file

@ -45,17 +45,6 @@ static int __init setup_noreplace_smp(char *str)
} }
__setup("noreplace-smp", setup_noreplace_smp); __setup("noreplace-smp", setup_noreplace_smp);
#ifdef CONFIG_PARAVIRT
static int __initdata_or_module noreplace_paravirt = 0;
static int __init setup_noreplace_paravirt(char *str)
{
noreplace_paravirt = 1;
return 1;
}
__setup("noreplace-paravirt", setup_noreplace_paravirt);
#endif
#define DPRINTK(fmt, args...) \ #define DPRINTK(fmt, args...) \
do { \ do { \
if (debug_alternative) \ if (debug_alternative) \
@ -587,9 +576,6 @@ void __init_or_module apply_paravirt(struct paravirt_patch_site *start,
struct paravirt_patch_site *p; struct paravirt_patch_site *p;
char insnbuf[MAX_PATCH_LEN]; char insnbuf[MAX_PATCH_LEN];
if (noreplace_paravirt)
return;
for (p = start; p < end; p++) { for (p = start; p < end; p++) {
unsigned int used; unsigned int used;

View file

@ -10,6 +10,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/module.h>
#include <asm/nospec-branch.h> #include <asm/nospec-branch.h>
#include <asm/cmdline.h> #include <asm/cmdline.h>
@ -89,20 +90,42 @@ static const char *spectre_v2_strings[] = {
}; };
#undef pr_fmt #undef pr_fmt
#define pr_fmt(fmt) "Spectre V2 mitigation: " fmt #define pr_fmt(fmt) "Spectre V2 : " fmt
static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE; static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
#ifdef RETPOLINE
static bool spectre_v2_bad_module;
bool retpoline_module_ok(bool has_retpoline)
{
if (spectre_v2_enabled == SPECTRE_V2_NONE || has_retpoline)
return true;
pr_err("System may be vulnerable to spectre v2\n");
spectre_v2_bad_module = true;
return false;
}
static inline const char *spectre_v2_module_string(void)
{
return spectre_v2_bad_module ? " - vulnerable module loaded" : "";
}
#else
static inline const char *spectre_v2_module_string(void) { return ""; }
#endif
static void __init spec2_print_if_insecure(const char *reason) static void __init spec2_print_if_insecure(const char *reason)
{ {
if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
pr_info("%s\n", reason); pr_info("%s selected on command line.\n", reason);
} }
static void __init spec2_print_if_secure(const char *reason) static void __init spec2_print_if_secure(const char *reason)
{ {
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
pr_info("%s\n", reason); pr_info("%s selected on command line.\n", reason);
} }
static inline bool retp_compiler(void) static inline bool retp_compiler(void)
@ -117,42 +140,68 @@ static inline bool match_option(const char *arg, int arglen, const char *opt)
return len == arglen && !strncmp(arg, opt, len); return len == arglen && !strncmp(arg, opt, len);
} }
static const struct {
const char *option;
enum spectre_v2_mitigation_cmd cmd;
bool secure;
} mitigation_options[] = {
{ "off", SPECTRE_V2_CMD_NONE, false },
{ "on", SPECTRE_V2_CMD_FORCE, true },
{ "retpoline", SPECTRE_V2_CMD_RETPOLINE, false },
{ "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_AMD, false },
{ "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false },
{ "auto", SPECTRE_V2_CMD_AUTO, false },
};
static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
{ {
char arg[20]; char arg[20];
int ret; int ret, i;
enum spectre_v2_mitigation_cmd cmd = SPECTRE_V2_CMD_AUTO;
ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, if (cmdline_find_option_bool(boot_command_line, "nospectre_v2"))
sizeof(arg)); return SPECTRE_V2_CMD_NONE;
if (ret > 0) { else {
if (match_option(arg, ret, "off")) { ret = cmdline_find_option(boot_command_line, "spectre_v2", arg,
goto disable; sizeof(arg));
} else if (match_option(arg, ret, "on")) { if (ret < 0)
spec2_print_if_secure("force enabled on command line."); return SPECTRE_V2_CMD_AUTO;
return SPECTRE_V2_CMD_FORCE;
} else if (match_option(arg, ret, "retpoline")) { for (i = 0; i < ARRAY_SIZE(mitigation_options); i++) {
spec2_print_if_insecure("retpoline selected on command line."); if (!match_option(arg, ret, mitigation_options[i].option))
return SPECTRE_V2_CMD_RETPOLINE; continue;
} else if (match_option(arg, ret, "retpoline,amd")) { cmd = mitigation_options[i].cmd;
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) { break;
pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n"); }
return SPECTRE_V2_CMD_AUTO;
} if (i >= ARRAY_SIZE(mitigation_options)) {
spec2_print_if_insecure("AMD retpoline selected on command line."); pr_err("unknown option (%s). Switching to AUTO select\n",
return SPECTRE_V2_CMD_RETPOLINE_AMD; mitigation_options[i].option);
} else if (match_option(arg, ret, "retpoline,generic")) {
spec2_print_if_insecure("generic retpoline selected on command line.");
return SPECTRE_V2_CMD_RETPOLINE_GENERIC;
} else if (match_option(arg, ret, "auto")) {
return SPECTRE_V2_CMD_AUTO; return SPECTRE_V2_CMD_AUTO;
} }
} }
if (!cmdline_find_option_bool(boot_command_line, "nospectre_v2")) if ((cmd == SPECTRE_V2_CMD_RETPOLINE ||
cmd == SPECTRE_V2_CMD_RETPOLINE_AMD ||
cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) &&
!IS_ENABLED(CONFIG_RETPOLINE)) {
pr_err("%s selected but not compiled in. Switching to AUTO select\n",
mitigation_options[i].option);
return SPECTRE_V2_CMD_AUTO; return SPECTRE_V2_CMD_AUTO;
disable: }
spec2_print_if_insecure("disabled on command line.");
return SPECTRE_V2_CMD_NONE; if (cmd == SPECTRE_V2_CMD_RETPOLINE_AMD &&
boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n");
return SPECTRE_V2_CMD_AUTO;
}
if (mitigation_options[i].secure)
spec2_print_if_secure(mitigation_options[i].option);
else
spec2_print_if_insecure(mitigation_options[i].option);
return cmd;
} }
/* Check for Skylake-like CPUs (for RSB handling) */ /* Check for Skylake-like CPUs (for RSB handling) */
@ -190,10 +239,10 @@ static void __init spectre_v2_select_mitigation(void)
return; return;
case SPECTRE_V2_CMD_FORCE: case SPECTRE_V2_CMD_FORCE:
/* FALLTRHU */
case SPECTRE_V2_CMD_AUTO: case SPECTRE_V2_CMD_AUTO:
goto retpoline_auto; if (IS_ENABLED(CONFIG_RETPOLINE))
goto retpoline_auto;
break;
case SPECTRE_V2_CMD_RETPOLINE_AMD: case SPECTRE_V2_CMD_RETPOLINE_AMD:
if (IS_ENABLED(CONFIG_RETPOLINE)) if (IS_ENABLED(CONFIG_RETPOLINE))
goto retpoline_amd; goto retpoline_amd;
@ -268,7 +317,7 @@ ssize_t cpu_show_spectre_v1(struct device *dev,
{ {
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1)) if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1))
return sprintf(buf, "Not affected\n"); return sprintf(buf, "Not affected\n");
return sprintf(buf, "Vulnerable\n"); return sprintf(buf, "Mitigation: __user pointer sanitization\n");
} }
ssize_t cpu_show_spectre_v2(struct device *dev, ssize_t cpu_show_spectre_v2(struct device *dev,
@ -277,6 +326,7 @@ ssize_t cpu_show_spectre_v2(struct device *dev,
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
return sprintf(buf, "Not affected\n"); return sprintf(buf, "Not affected\n");
return sprintf(buf, "%s\n", spectre_v2_strings[spectre_v2_enabled]); return sprintf(buf, "%s%s\n", spectre_v2_strings[spectre_v2_enabled],
spectre_v2_module_string());
} }
#endif #endif

View file

@ -152,7 +152,6 @@ static void raise_mce(struct mce *m)
if (context == MCJ_CTX_RANDOM) if (context == MCJ_CTX_RANDOM)
return; return;
#ifdef CONFIG_X86_LOCAL_APIC
if (m->inject_flags & (MCJ_IRQ_BROADCAST | MCJ_NMI_BROADCAST)) { if (m->inject_flags & (MCJ_IRQ_BROADCAST | MCJ_NMI_BROADCAST)) {
unsigned long start; unsigned long start;
int cpu; int cpu;
@ -193,9 +192,7 @@ static void raise_mce(struct mce *m)
raise_local(); raise_local();
put_cpu(); put_cpu();
put_online_cpus(); put_online_cpus();
} else } else {
#endif
{
preempt_disable(); preempt_disable();
raise_local(); raise_local();
preempt_enable(); preempt_enable();

View file

@ -131,6 +131,9 @@ static size_t compute_container_size(u8 *data, u32 total_size)
return size; return size;
} }
static enum ucode_state
load_microcode_amd(bool save, u8 family, const u8 *data, size_t size);
/* /*
* Early load occurs before we can vmalloc(). So we look for the microcode * Early load occurs before we can vmalloc(). So we look for the microcode
* patch container file in initrd, traverse equivalent cpu table, look for a * patch container file in initrd, traverse equivalent cpu table, look for a
@ -438,7 +441,7 @@ int __init save_microcode_in_initrd_amd(void)
eax = cpuid_eax(0x00000001); eax = cpuid_eax(0x00000001);
eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
ret = load_microcode_amd(smp_processor_id(), eax, container, container_size); ret = load_microcode_amd(true, eax, container, container_size);
if (ret != UCODE_OK) if (ret != UCODE_OK)
retval = -EINVAL; retval = -EINVAL;
@ -854,7 +857,8 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
return UCODE_OK; return UCODE_OK;
} }
enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size) static enum ucode_state
load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
{ {
enum ucode_state ret; enum ucode_state ret;
@ -868,8 +872,8 @@ enum ucode_state load_microcode_amd(int cpu, u8 family, const u8 *data, size_t s
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
/* save BSP's matching patch for early load */ /* save BSP's matching patch for early load */
if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) { if (save) {
struct ucode_patch *p = find_patch(cpu); struct ucode_patch *p = find_patch(0);
if (p) { if (p) {
memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
@ -901,11 +905,12 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
{ {
char fw_name[36] = "amd-ucode/microcode_amd.bin"; char fw_name[36] = "amd-ucode/microcode_amd.bin";
struct cpuinfo_x86 *c = &cpu_data(cpu); struct cpuinfo_x86 *c = &cpu_data(cpu);
bool bsp = c->cpu_index == boot_cpu_data.cpu_index;
enum ucode_state ret = UCODE_NFOUND; enum ucode_state ret = UCODE_NFOUND;
const struct firmware *fw; const struct firmware *fw;
/* reload ucode container only on the boot cpu */ /* reload ucode container only on the boot cpu */
if (!refresh_fw || c->cpu_index != boot_cpu_data.cpu_index) if (!refresh_fw || !bsp)
return UCODE_OK; return UCODE_OK;
if (c->x86 >= 0x15) if (c->x86 >= 0x15)
@ -922,7 +927,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
goto fw_release; goto fw_release;
} }
ret = load_microcode_amd(cpu, c->x86, fw->data, fw->size); ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size);
fw_release: fw_release:
release_firmware(fw); release_firmware(fw);

View file

@ -188,8 +188,8 @@ static void release_pmc_hardware(void) {}
static bool check_hw_exists(void) static bool check_hw_exists(void)
{ {
u64 val, val_fail, val_new= ~0; u64 val, val_fail = -1, val_new= ~0;
int i, reg, reg_fail, ret = 0; int i, reg, reg_fail = -1, ret = 0;
int bios_fail = 0; int bios_fail = 0;
int reg_safe = -1; int reg_safe = -1;

View file

@ -669,14 +669,17 @@ __PAGE_ALIGNED_BSS
initial_pg_pmd: initial_pg_pmd:
.fill 1024*KPMDS,4,0 .fill 1024*KPMDS,4,0
#else #else
ENTRY(initial_page_table) .globl initial_page_table
initial_page_table:
.fill 1024,4,0 .fill 1024,4,0
#endif #endif
initial_pg_fixmap: initial_pg_fixmap:
.fill 1024,4,0 .fill 1024,4,0
ENTRY(empty_zero_page) .globl empty_zero_page
empty_zero_page:
.fill 4096,1,0 .fill 4096,1,0
ENTRY(swapper_pg_dir) .globl swapper_pg_dir
swapper_pg_dir:
.fill 1024,4,0 .fill 1024,4,0
/* /*

View file

@ -22,7 +22,8 @@ config KVM
depends on HAVE_KVM depends on HAVE_KVM
depends on HIGH_RES_TIMERS depends on HIGH_RES_TIMERS
# for TASKSTATS/TASK_DELAY_ACCT: # for TASKSTATS/TASK_DELAY_ACCT:
depends on NET depends on NET && MULTIUSER
depends on X86_LOCAL_APIC
select PREEMPT_NOTIFIERS select PREEMPT_NOTIFIERS
select MMU_NOTIFIER select MMU_NOTIFIER
select ANON_INODES select ANON_INODES

View file

@ -26,6 +26,7 @@
#include <asm/kvm_emulate.h> #include <asm/kvm_emulate.h>
#include <linux/stringify.h> #include <linux/stringify.h>
#include <asm/debugreg.h> #include <asm/debugreg.h>
#include <asm/nospec-branch.h>
#include "x86.h" #include "x86.h"
#include "tss.h" #include "tss.h"
@ -1000,8 +1001,8 @@ static u8 test_cc(unsigned int condition, unsigned long flags)
void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf); void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf);
flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF; flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF;
asm("push %[flags]; popf; call *%[fastop]" asm("push %[flags]; popf; " CALL_NOSPEC
: "=a"(rc) : [fastop]"r"(fop), [flags]"r"(flags)); : "=a"(rc) : [thunk_target]"r"(fop), [flags]"r"(flags));
return rc; return rc;
} }
@ -5297,9 +5298,9 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *))
ulong flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF; ulong flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF;
if (!(ctxt->d & ByteOp)) if (!(ctxt->d & ByteOp))
fop += __ffs(ctxt->dst.bytes) * FASTOP_SIZE; fop += __ffs(ctxt->dst.bytes) * FASTOP_SIZE;
asm("push %[flags]; popf; call *%[fastop]; pushf; pop %[flags]\n" asm("push %[flags]; popf; " CALL_NOSPEC "; pushf; pop %[flags]\n"
: "+a"(ctxt->dst.val), "+d"(ctxt->src.val), [flags]"+D"(flags), : "+a"(ctxt->dst.val), "+d"(ctxt->src.val), [flags]"+D"(flags),
[fastop]"+S"(fop) [thunk_target]"+S"(fop)
: "c"(ctxt->src2.val)); : "c"(ctxt->src2.val));
ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK); ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK);
if (!fop) /* exception is returned in fop variable */ if (!fop) /* exception is returned in fop variable */

View file

@ -32,6 +32,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/tboot.h> #include <linux/tboot.h>
#include <linux/hrtimer.h> #include <linux/hrtimer.h>
#include <linux/nospec.h>
#include "kvm_cache_regs.h" #include "kvm_cache_regs.h"
#include "x86.h" #include "x86.h"
@ -125,6 +126,12 @@ module_param_named(pml, enable_pml, bool, S_IRUGO);
#define VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE 5 #define VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE 5
#define VMX_VPID_EXTENT_SUPPORTED_MASK \
(VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT | \
VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT | \
VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT | \
VMX_VPID_EXTENT_SINGLE_NON_GLOBAL_BIT)
/* /*
* These 2 parameters are used to config the controls for Pause-Loop Exiting: * These 2 parameters are used to config the controls for Pause-Loop Exiting:
* ple_gap: upper bound on the amount of time between two successive * ple_gap: upper bound on the amount of time between two successive
@ -827,21 +834,18 @@ static const unsigned short vmcs_field_to_offset_table[] = {
static inline short vmcs_field_to_offset(unsigned long field) static inline short vmcs_field_to_offset(unsigned long field)
{ {
BUILD_BUG_ON(ARRAY_SIZE(vmcs_field_to_offset_table) > SHRT_MAX); const size_t size = ARRAY_SIZE(vmcs_field_to_offset_table);
unsigned short offset;
if (field >= ARRAY_SIZE(vmcs_field_to_offset_table)) BUILD_BUG_ON(size > SHRT_MAX);
if (field >= size)
return -ENOENT; return -ENOENT;
/* field = array_index_nospec(field, size);
* FIXME: Mitigation for CVE-2017-5753. To be replaced with a offset = vmcs_field_to_offset_table[field];
* generic mechanism. if (offset == 0)
*/
asm("lfence");
if (vmcs_field_to_offset_table[field] == 0)
return -ENOENT; return -ENOENT;
return offset;
return vmcs_field_to_offset_table[field];
} }
static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu) static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu)
@ -2659,8 +2663,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
*/ */
if (enable_vpid) if (enable_vpid)
vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT | vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT | VMX_VPID_EXTENT_SUPPORTED_MASK;
VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
else else
vmx->nested.nested_vmx_vpid_caps = 0; vmx->nested.nested_vmx_vpid_caps = 0;
@ -4514,7 +4517,7 @@ static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu)
return enable_apicv && lapic_in_kernel(vcpu); return enable_apicv && lapic_in_kernel(vcpu);
} }
static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
{ {
struct vcpu_vmx *vmx = to_vmx(vcpu); struct vcpu_vmx *vmx = to_vmx(vcpu);
int max_irr; int max_irr;
@ -4525,19 +4528,15 @@ static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
vmx->nested.pi_pending) { vmx->nested.pi_pending) {
vmx->nested.pi_pending = false; vmx->nested.pi_pending = false;
if (!pi_test_and_clear_on(vmx->nested.pi_desc)) if (!pi_test_and_clear_on(vmx->nested.pi_desc))
return 0; return;
max_irr = find_last_bit( max_irr = find_last_bit(
(unsigned long *)vmx->nested.pi_desc->pir, 256); (unsigned long *)vmx->nested.pi_desc->pir, 256);
if (max_irr == 256) if (max_irr == 256)
return 0; return;
vapic_page = kmap(vmx->nested.virtual_apic_page); vapic_page = kmap(vmx->nested.virtual_apic_page);
if (!vapic_page) {
WARN_ON(1);
return -ENOMEM;
}
__kvm_apic_update_irr(vmx->nested.pi_desc->pir, vapic_page); __kvm_apic_update_irr(vmx->nested.pi_desc->pir, vapic_page);
kunmap(vmx->nested.virtual_apic_page); kunmap(vmx->nested.virtual_apic_page);
@ -4548,7 +4547,6 @@ static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
vmcs_write16(GUEST_INTR_STATUS, status); vmcs_write16(GUEST_INTR_STATUS, status);
} }
} }
return 0;
} }
static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu) static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
@ -7368,7 +7366,7 @@ static int handle_invept(struct kvm_vcpu *vcpu)
types = (vmx->nested.nested_vmx_ept_caps >> VMX_EPT_EXTENT_SHIFT) & 6; types = (vmx->nested.nested_vmx_ept_caps >> VMX_EPT_EXTENT_SHIFT) & 6;
if (!(types & (1UL << type))) { if (type >= 32 || !(types & (1 << type))) {
nested_vmx_failValid(vcpu, nested_vmx_failValid(vcpu,
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
skip_emulated_instruction(vcpu); skip_emulated_instruction(vcpu);
@ -7425,9 +7423,10 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
type = kvm_register_readl(vcpu, (vmx_instruction_info >> 28) & 0xf); type = kvm_register_readl(vcpu, (vmx_instruction_info >> 28) & 0xf);
types = (vmx->nested.nested_vmx_vpid_caps >> 8) & 0x7; types = (vmx->nested.nested_vmx_vpid_caps &
VMX_VPID_EXTENT_SUPPORTED_MASK) >> 8;
if (!(types & (1UL << type))) { if (type >= 32 || !(types & (1 << type))) {
nested_vmx_failValid(vcpu, nested_vmx_failValid(vcpu,
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
skip_emulated_instruction(vcpu); skip_emulated_instruction(vcpu);
@ -7447,21 +7446,27 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
} }
switch (type) { switch (type) {
case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:
case VMX_VPID_EXTENT_SINGLE_CONTEXT: case VMX_VPID_EXTENT_SINGLE_CONTEXT:
/* case VMX_VPID_EXTENT_SINGLE_NON_GLOBAL:
* Old versions of KVM use the single-context version so we if (!vpid) {
* have to support it; just treat it the same as all-context. nested_vmx_failValid(vcpu,
*/ VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
skip_emulated_instruction(vcpu);
return 1;
}
break;
case VMX_VPID_EXTENT_ALL_CONTEXT: case VMX_VPID_EXTENT_ALL_CONTEXT:
__vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
nested_vmx_succeed(vcpu);
break; break;
default: default:
/* Trap individual address invalidation invvpid calls */ WARN_ON_ONCE(1);
BUG_ON(1); skip_emulated_instruction(vcpu);
break; return 1;
} }
__vmx_flush_tlb(vcpu, vmx->nested.vpid02);
nested_vmx_succeed(vcpu);
skip_emulated_instruction(vcpu); skip_emulated_instruction(vcpu);
return 1; return 1;
} }
@ -8377,13 +8382,13 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
"pushf\n\t" "pushf\n\t"
"orl $0x200, (%%" _ASM_SP ")\n\t" "orl $0x200, (%%" _ASM_SP ")\n\t"
__ASM_SIZE(push) " $%c[cs]\n\t" __ASM_SIZE(push) " $%c[cs]\n\t"
"call *%[entry]\n\t" CALL_NOSPEC
: :
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
[sp]"=&r"(tmp) [sp]"=&r"(tmp)
#endif #endif
: :
[entry]"r"(entry), THUNK_TARGET(entry),
[ss]"i"(__KERNEL_DS), [ss]"i"(__KERNEL_DS),
[cs]"i"(__KERNEL_CS) [cs]"i"(__KERNEL_CS)
); );
@ -9240,11 +9245,6 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
return false; return false;
} }
msr_bitmap = (unsigned long *)kmap(page); msr_bitmap = (unsigned long *)kmap(page);
if (!msr_bitmap) {
nested_release_page_clean(page);
WARN_ON(1);
return false;
}
if (nested_cpu_has_virt_x2apic_mode(vmcs12)) { if (nested_cpu_has_virt_x2apic_mode(vmcs12)) {
if (nested_cpu_has_apic_reg_virt(vmcs12)) if (nested_cpu_has_apic_reg_virt(vmcs12))
@ -10166,7 +10166,8 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
return 0; return 0;
} }
return vmx_complete_nested_posted_interrupt(vcpu); vmx_complete_nested_posted_interrupt(vcpu);
return 0;
} }
static u32 vmx_get_preemption_timer_value(struct kvm_vcpu *vcpu) static u32 vmx_get_preemption_timer_value(struct kvm_vcpu *vcpu)

View file

@ -2755,6 +2755,12 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_x86_ops->vcpu_put(vcpu); kvm_x86_ops->vcpu_put(vcpu);
kvm_put_guest_fpu(vcpu); kvm_put_guest_fpu(vcpu);
vcpu->arch.last_host_tsc = rdtsc(); vcpu->arch.last_host_tsc = rdtsc();
/*
* If userspace has set any breakpoints or watchpoints, dr6 is restored
* on every vmexit, but if not, we might have a stale dr6 from the
* guest. do_debug expects dr6 to be cleared after it runs, do the same.
*/
set_debugreg(0, 6);
} }
static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
@ -8204,6 +8210,13 @@ static int apf_put_user(struct kvm_vcpu *vcpu, u32 val)
sizeof(val)); sizeof(val));
} }
static int apf_get_user(struct kvm_vcpu *vcpu, u32 *val)
{
return kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.apf.data, val,
sizeof(u32));
}
void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
struct kvm_async_pf *work) struct kvm_async_pf *work)
{ {
@ -8230,6 +8243,7 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
struct kvm_async_pf *work) struct kvm_async_pf *work)
{ {
struct x86_exception fault; struct x86_exception fault;
u32 val;
if (work->wakeup_all) if (work->wakeup_all)
work->arch.token = ~0; /* broadcast wakeup */ work->arch.token = ~0; /* broadcast wakeup */
@ -8237,14 +8251,24 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
kvm_del_async_pf_gfn(vcpu, work->arch.gfn); kvm_del_async_pf_gfn(vcpu, work->arch.gfn);
trace_kvm_async_pf_ready(work->arch.token, work->gva); trace_kvm_async_pf_ready(work->arch.token, work->gva);
if ((vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) && if (vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED &&
!apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) { !apf_get_user(vcpu, &val)) {
fault.vector = PF_VECTOR; if (val == KVM_PV_REASON_PAGE_NOT_PRESENT &&
fault.error_code_valid = true; vcpu->arch.exception.pending &&
fault.error_code = 0; vcpu->arch.exception.nr == PF_VECTOR &&
fault.nested_page_fault = false; !apf_put_user(vcpu, 0)) {
fault.address = work->arch.token; vcpu->arch.exception.pending = false;
kvm_inject_page_fault(vcpu, &fault); vcpu->arch.exception.nr = 0;
vcpu->arch.exception.has_error_code = false;
vcpu->arch.exception.error_code = 0;
} else if (!apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) {
fault.vector = PF_VECTOR;
fault.error_code_valid = true;
fault.error_code = 0;
fault.nested_page_fault = false;
fault.address = work->arch.token;
kvm_inject_page_fault(vcpu, &fault);
}
} }
vcpu->arch.apf.halted = false; vcpu->arch.apf.halted = false;
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;

View file

@ -38,6 +38,8 @@ ENTRY(__get_user_1)
GET_THREAD_INFO(%_ASM_DX) GET_THREAD_INFO(%_ASM_DX)
cmp TI_addr_limit(%_ASM_DX),%_ASM_AX cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
jae bad_get_user jae bad_get_user
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
and %_ASM_DX, %_ASM_AX
ASM_STAC ASM_STAC
1: movzbl (%_ASM_AX),%edx 1: movzbl (%_ASM_AX),%edx
xor %eax,%eax xor %eax,%eax
@ -51,6 +53,8 @@ ENTRY(__get_user_2)
GET_THREAD_INFO(%_ASM_DX) GET_THREAD_INFO(%_ASM_DX)
cmp TI_addr_limit(%_ASM_DX),%_ASM_AX cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
jae bad_get_user jae bad_get_user
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
and %_ASM_DX, %_ASM_AX
ASM_STAC ASM_STAC
2: movzwl -1(%_ASM_AX),%edx 2: movzwl -1(%_ASM_AX),%edx
xor %eax,%eax xor %eax,%eax
@ -64,6 +68,8 @@ ENTRY(__get_user_4)
GET_THREAD_INFO(%_ASM_DX) GET_THREAD_INFO(%_ASM_DX)
cmp TI_addr_limit(%_ASM_DX),%_ASM_AX cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
jae bad_get_user jae bad_get_user
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
and %_ASM_DX, %_ASM_AX
ASM_STAC ASM_STAC
3: movl -3(%_ASM_AX),%edx 3: movl -3(%_ASM_AX),%edx
xor %eax,%eax xor %eax,%eax
@ -78,6 +84,8 @@ ENTRY(__get_user_8)
GET_THREAD_INFO(%_ASM_DX) GET_THREAD_INFO(%_ASM_DX)
cmp TI_addr_limit(%_ASM_DX),%_ASM_AX cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
jae bad_get_user jae bad_get_user
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
and %_ASM_DX, %_ASM_AX
ASM_STAC ASM_STAC
4: movq -7(%_ASM_AX),%rdx 4: movq -7(%_ASM_AX),%rdx
xor %eax,%eax xor %eax,%eax
@ -89,6 +97,8 @@ ENTRY(__get_user_8)
GET_THREAD_INFO(%_ASM_DX) GET_THREAD_INFO(%_ASM_DX)
cmp TI_addr_limit(%_ASM_DX),%_ASM_AX cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
jae bad_get_user_8 jae bad_get_user_8
sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */
and %_ASM_DX, %_ASM_AX
ASM_STAC ASM_STAC
4: movl -7(%_ASM_AX),%edx 4: movl -7(%_ASM_AX),%edx
5: movl -3(%_ASM_AX),%ecx 5: movl -3(%_ASM_AX),%ecx

View file

@ -36,7 +36,6 @@ GENERATE_THUNK(_ASM_DX)
GENERATE_THUNK(_ASM_SI) GENERATE_THUNK(_ASM_SI)
GENERATE_THUNK(_ASM_DI) GENERATE_THUNK(_ASM_DI)
GENERATE_THUNK(_ASM_BP) GENERATE_THUNK(_ASM_BP)
GENERATE_THUNK(_ASM_SP)
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
GENERATE_THUNK(r8) GENERATE_THUNK(r8)
GENERATE_THUNK(r9) GENERATE_THUNK(r9)

View file

@ -5,8 +5,8 @@
#DEBUG = -DDEBUGGING #DEBUG = -DDEBUGGING
DEBUG = DEBUG =
PARANOID = -DPARANOID PARANOID = -DPARANOID
EXTRA_CFLAGS := $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION) ccflags-y += $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION)
EXTRA_AFLAGS := $(PARANOID) asflags-y += $(PARANOID)
# From 'C' language sources: # From 'C' language sources:
C_OBJS =fpu_entry.o errors.o \ C_OBJS =fpu_entry.o errors.o \

View file

@ -168,7 +168,7 @@ static int compare(FPU_REG const *b, int tagb)
/* This function requires that st(0) is not empty */ /* This function requires that st(0) is not empty */
int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag) int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
{ {
int f = 0, c; int f, c;
c = compare(loaded_data, loaded_tag); c = compare(loaded_data, loaded_tag);
@ -189,12 +189,12 @@ int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
case COMP_No_Comp: case COMP_No_Comp:
f = SW_C3 | SW_C2 | SW_C0; f = SW_C3 | SW_C2 | SW_C0;
break; break;
#ifdef PARANOID
default: default:
#ifdef PARANOID
EXCEPTION(EX_INTERNAL | 0x121); EXCEPTION(EX_INTERNAL | 0x121);
#endif /* PARANOID */
f = SW_C3 | SW_C2 | SW_C0; f = SW_C3 | SW_C2 | SW_C0;
break; break;
#endif /* PARANOID */
} }
setcc(f); setcc(f);
if (c & COMP_Denormal) { if (c & COMP_Denormal) {
@ -205,7 +205,7 @@ int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
static int compare_st_st(int nr) static int compare_st_st(int nr)
{ {
int f = 0, c; int f, c;
FPU_REG *st_ptr; FPU_REG *st_ptr;
if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) { if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
@ -235,12 +235,12 @@ static int compare_st_st(int nr)
case COMP_No_Comp: case COMP_No_Comp:
f = SW_C3 | SW_C2 | SW_C0; f = SW_C3 | SW_C2 | SW_C0;
break; break;
#ifdef PARANOID
default: default:
#ifdef PARANOID
EXCEPTION(EX_INTERNAL | 0x122); EXCEPTION(EX_INTERNAL | 0x122);
#endif /* PARANOID */
f = SW_C3 | SW_C2 | SW_C0; f = SW_C3 | SW_C2 | SW_C0;
break; break;
#endif /* PARANOID */
} }
setcc(f); setcc(f);
if (c & COMP_Denormal) { if (c & COMP_Denormal) {
@ -283,12 +283,12 @@ static int compare_i_st_st(int nr)
case COMP_No_Comp: case COMP_No_Comp:
f = X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF; f = X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF;
break; break;
#ifdef PARANOID
default: default:
#ifdef PARANOID
EXCEPTION(EX_INTERNAL | 0x122); EXCEPTION(EX_INTERNAL | 0x122);
#endif /* PARANOID */
f = 0; f = 0;
break; break;
#endif /* PARANOID */
} }
FPU_EFLAGS = (FPU_EFLAGS & ~(X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF)) | f; FPU_EFLAGS = (FPU_EFLAGS & ~(X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF)) | f;
if (c & COMP_Denormal) { if (c & COMP_Denormal) {

View file

@ -348,11 +348,11 @@ void iounmap(volatile void __iomem *addr)
(void __force *)addr < phys_to_virt(ISA_END_ADDRESS)) (void __force *)addr < phys_to_virt(ISA_END_ADDRESS))
return; return;
mmiotrace_iounmap(addr);
addr = (volatile void __iomem *) addr = (volatile void __iomem *)
(PAGE_MASK & (unsigned long __force)addr); (PAGE_MASK & (unsigned long __force)addr);
mmiotrace_iounmap(addr);
/* Use the vm area unlocked, assuming the caller /* Use the vm area unlocked, assuming the caller
ensures there isn't another iounmap for the same address ensures there isn't another iounmap for the same address
in parallel. Reuse of the virtual address is prevented by in parallel. Reuse of the virtual address is prevented by

View file

@ -434,17 +434,18 @@ int register_kmmio_probe(struct kmmio_probe *p)
unsigned long flags; unsigned long flags;
int ret = 0; int ret = 0;
unsigned long size = 0; unsigned long size = 0;
unsigned long addr = p->addr & PAGE_MASK;
const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK);
unsigned int l; unsigned int l;
pte_t *pte; pte_t *pte;
spin_lock_irqsave(&kmmio_lock, flags); spin_lock_irqsave(&kmmio_lock, flags);
if (get_kmmio_probe(p->addr)) { if (get_kmmio_probe(addr)) {
ret = -EEXIST; ret = -EEXIST;
goto out; goto out;
} }
pte = lookup_address(p->addr, &l); pte = lookup_address(addr, &l);
if (!pte) { if (!pte) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
@ -453,7 +454,7 @@ int register_kmmio_probe(struct kmmio_probe *p)
kmmio_count++; kmmio_count++;
list_add_rcu(&p->list, &kmmio_probes); list_add_rcu(&p->list, &kmmio_probes);
while (size < size_lim) { while (size < size_lim) {
if (add_kmmio_fault_page(p->addr + size)) if (add_kmmio_fault_page(addr + size))
pr_err("Unable to set page fault.\n"); pr_err("Unable to set page fault.\n");
size += page_level_size(l); size += page_level_size(l);
} }
@ -527,19 +528,20 @@ void unregister_kmmio_probe(struct kmmio_probe *p)
{ {
unsigned long flags; unsigned long flags;
unsigned long size = 0; unsigned long size = 0;
unsigned long addr = p->addr & PAGE_MASK;
const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK);
struct kmmio_fault_page *release_list = NULL; struct kmmio_fault_page *release_list = NULL;
struct kmmio_delayed_release *drelease; struct kmmio_delayed_release *drelease;
unsigned int l; unsigned int l;
pte_t *pte; pte_t *pte;
pte = lookup_address(p->addr, &l); pte = lookup_address(addr, &l);
if (!pte) if (!pte)
return; return;
spin_lock_irqsave(&kmmio_lock, flags); spin_lock_irqsave(&kmmio_lock, flags);
while (size < size_lim) { while (size < size_lim) {
release_kmmio_fault_page(p->addr + size, &release_list); release_kmmio_fault_page(addr + size, &release_list);
size += page_level_size(l); size += page_level_size(l);
} }
list_del_rcu(&p->list); list_del_rcu(&p->list);

View file

@ -196,6 +196,7 @@ static int xo15_sci_remove(struct acpi_device *device)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP
static int xo15_sci_resume(struct device *dev) static int xo15_sci_resume(struct device *dev)
{ {
/* Enable all EC events */ /* Enable all EC events */
@ -207,6 +208,7 @@ static int xo15_sci_resume(struct device *dev)
return 0; return 0;
} }
#endif
static SIMPLE_DEV_PM_OPS(xo15_sci_pm, NULL, xo15_sci_resume); static SIMPLE_DEV_PM_OPS(xo15_sci_pm, NULL, xo15_sci_resume);

View file

@ -40,29 +40,34 @@ ifndef CONFIG_MODULE_SIG_HASH
$(error Could not determine digest type to use from kernel config) $(error Could not determine digest type to use from kernel config)
endif endif
redirect_openssl = 2>&1
quiet_redirect_openssl = 2>&1
silent_redirect_openssl = 2>/dev/null
# We do it this way rather than having a boolean option for enabling an # We do it this way rather than having a boolean option for enabling an
# external private key, because 'make randconfig' might enable such a # external private key, because 'make randconfig' might enable such a
# boolean option and we unfortunately can't make it depend on !RANDCONFIG. # boolean option and we unfortunately can't make it depend on !RANDCONFIG.
ifeq ($(CONFIG_MODULE_SIG_KEY),"certs/signing_key.pem") ifeq ($(CONFIG_MODULE_SIG_KEY),"certs/signing_key.pem")
$(obj)/signing_key.pem: $(obj)/x509.genkey $(obj)/signing_key.pem: $(obj)/x509.genkey
@echo "###" @$(kecho) "###"
@echo "### Now generating an X.509 key pair to be used for signing modules." @$(kecho) "### Now generating an X.509 key pair to be used for signing modules."
@echo "###" @$(kecho) "###"
@echo "### If this takes a long time, you might wish to run rngd in the" @$(kecho) "### If this takes a long time, you might wish to run rngd in the"
@echo "### background to keep the supply of entropy topped up. It" @$(kecho) "### background to keep the supply of entropy topped up. It"
@echo "### needs to be run as root, and uses a hardware random" @$(kecho) "### needs to be run as root, and uses a hardware random"
@echo "### number generator if one is available." @$(kecho) "### number generator if one is available."
@echo "###" @$(kecho) "###"
openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \ $(Q)openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \
-batch -x509 -config $(obj)/x509.genkey \ -batch -x509 -config $(obj)/x509.genkey \
-outform PEM -out $(obj)/signing_key.pem \ -outform PEM -out $(obj)/signing_key.pem \
-keyout $(obj)/signing_key.pem 2>&1 -keyout $(obj)/signing_key.pem \
@echo "###" $($(quiet)redirect_openssl)
@echo "### Key pair generated." @$(kecho) "###"
@echo "###" @$(kecho) "### Key pair generated."
@$(kecho) "###"
$(obj)/x509.genkey: $(obj)/x509.genkey:
@echo Generating X.509 key generation config @$(kecho) Generating X.509 key generation config
@echo >$@ "[ req ]" @echo >$@ "[ req ]"
@echo >>$@ "default_bits = 4096" @echo >>$@ "default_bits = 4096"
@echo >>$@ "distinguished_name = req_distinguished_name" @echo >>$@ "distinguished_name = req_distinguished_name"

View file

@ -1390,6 +1390,20 @@ config CRYPTO_SERPENT_AVX2_X86_64
See also: See also:
<http://www.cl.cam.ac.uk/~rja14/serpent.html> <http://www.cl.cam.ac.uk/~rja14/serpent.html>
config CRYPTO_SPECK
tristate "Speck cipher algorithm"
select CRYPTO_ALGAPI
help
Speck is a lightweight block cipher that is tuned for optimal
performance in software (rather than hardware).
Speck may not be as secure as AES, and should only be used on systems
where AES is not fast enough.
See also: <https://eprint.iacr.org/2013/404.pdf>
If unsure, say N.
config CRYPTO_TEA config CRYPTO_TEA
tristate "TEA, XTEA and XETA cipher algorithms" tristate "TEA, XTEA and XETA cipher algorithms"
select CRYPTO_ALGAPI select CRYPTO_ALGAPI

View file

@ -98,6 +98,7 @@ obj-$(CONFIG_CRYPTO_TEA) += tea.o
obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
obj-$(CONFIG_CRYPTO_SEED) += seed.o obj-$(CONFIG_CRYPTO_SEED) += seed.o
obj-$(CONFIG_CRYPTO_SPECK) += speck.o
obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
obj-$(CONFIG_CRYPTO_CHACHA20) += chacha20_generic.o obj-$(CONFIG_CRYPTO_CHACHA20) += chacha20_generic.o
obj-$(CONFIG_CRYPTO_POLY1305) += poly1305_generic.o obj-$(CONFIG_CRYPTO_POLY1305) += poly1305_generic.o

307
crypto/speck.c Normal file
View file

@ -0,0 +1,307 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Speck: a lightweight block cipher
*
* Copyright (c) 2018 Google, Inc
*
* Speck has 10 variants, including 5 block sizes. For now we only implement
* the variants Speck128/128, Speck128/192, Speck128/256, Speck64/96, and
* Speck64/128. Speck${B}/${K} denotes the variant with a block size of B bits
* and a key size of K bits. The Speck128 variants are believed to be the most
* secure variants, and they use the same block size and key sizes as AES. The
* Speck64 variants are less secure, but on 32-bit processors are usually
* faster. The remaining variants (Speck32, Speck48, and Speck96) are even less
* secure and/or not as well suited for implementation on either 32-bit or
* 64-bit processors, so are omitted.
*
* Reference: "The Simon and Speck Families of Lightweight Block Ciphers"
* https://eprint.iacr.org/2013/404.pdf
*
* In a correspondence, the Speck designers have also clarified that the words
* should be interpreted in little-endian format, and the words should be
* ordered such that the first word of each block is 'y' rather than 'x', and
* the first key word (rather than the last) becomes the first round key.
*/
#include <asm/unaligned.h>
#include <crypto/speck.h>
#include <linux/bitops.h>
#include <linux/crypto.h>
#include <linux/init.h>
#include <linux/module.h>
/* Speck128 */
static __always_inline void speck128_round(u64 *x, u64 *y, u64 k)
{
*x = ror64(*x, 8);
*x += *y;
*x ^= k;
*y = rol64(*y, 3);
*y ^= *x;
}
static __always_inline void speck128_unround(u64 *x, u64 *y, u64 k)
{
*y ^= *x;
*y = ror64(*y, 3);
*x ^= k;
*x -= *y;
*x = rol64(*x, 8);
}
void crypto_speck128_encrypt(const struct speck128_tfm_ctx *ctx,
u8 *out, const u8 *in)
{
u64 y = get_unaligned_le64(in);
u64 x = get_unaligned_le64(in + 8);
int i;
for (i = 0; i < ctx->nrounds; i++)
speck128_round(&x, &y, ctx->round_keys[i]);
put_unaligned_le64(y, out);
put_unaligned_le64(x, out + 8);
}
EXPORT_SYMBOL_GPL(crypto_speck128_encrypt);
static void speck128_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
crypto_speck128_encrypt(crypto_tfm_ctx(tfm), out, in);
}
void crypto_speck128_decrypt(const struct speck128_tfm_ctx *ctx,
u8 *out, const u8 *in)
{
u64 y = get_unaligned_le64(in);
u64 x = get_unaligned_le64(in + 8);
int i;
for (i = ctx->nrounds - 1; i >= 0; i--)
speck128_unround(&x, &y, ctx->round_keys[i]);
put_unaligned_le64(y, out);
put_unaligned_le64(x, out + 8);
}
EXPORT_SYMBOL_GPL(crypto_speck128_decrypt);
static void speck128_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
crypto_speck128_decrypt(crypto_tfm_ctx(tfm), out, in);
}
int crypto_speck128_setkey(struct speck128_tfm_ctx *ctx, const u8 *key,
unsigned int keylen)
{
u64 l[3];
u64 k;
int i;
switch (keylen) {
case SPECK128_128_KEY_SIZE:
k = get_unaligned_le64(key);
l[0] = get_unaligned_le64(key + 8);
ctx->nrounds = SPECK128_128_NROUNDS;
for (i = 0; i < ctx->nrounds; i++) {
ctx->round_keys[i] = k;
speck128_round(&l[0], &k, i);
}
break;
case SPECK128_192_KEY_SIZE:
k = get_unaligned_le64(key);
l[0] = get_unaligned_le64(key + 8);
l[1] = get_unaligned_le64(key + 16);
ctx->nrounds = SPECK128_192_NROUNDS;
for (i = 0; i < ctx->nrounds; i++) {
ctx->round_keys[i] = k;
speck128_round(&l[i % 2], &k, i);
}
break;
case SPECK128_256_KEY_SIZE:
k = get_unaligned_le64(key);
l[0] = get_unaligned_le64(key + 8);
l[1] = get_unaligned_le64(key + 16);
l[2] = get_unaligned_le64(key + 24);
ctx->nrounds = SPECK128_256_NROUNDS;
for (i = 0; i < ctx->nrounds; i++) {
ctx->round_keys[i] = k;
speck128_round(&l[i % 3], &k, i);
}
break;
default:
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL_GPL(crypto_speck128_setkey);
static int speck128_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen)
{
return crypto_speck128_setkey(crypto_tfm_ctx(tfm), key, keylen);
}
/* Speck64 */
static __always_inline void speck64_round(u32 *x, u32 *y, u32 k)
{
*x = ror32(*x, 8);
*x += *y;
*x ^= k;
*y = rol32(*y, 3);
*y ^= *x;
}
static __always_inline void speck64_unround(u32 *x, u32 *y, u32 k)
{
*y ^= *x;
*y = ror32(*y, 3);
*x ^= k;
*x -= *y;
*x = rol32(*x, 8);
}
void crypto_speck64_encrypt(const struct speck64_tfm_ctx *ctx,
u8 *out, const u8 *in)
{
u32 y = get_unaligned_le32(in);
u32 x = get_unaligned_le32(in + 4);
int i;
for (i = 0; i < ctx->nrounds; i++)
speck64_round(&x, &y, ctx->round_keys[i]);
put_unaligned_le32(y, out);
put_unaligned_le32(x, out + 4);
}
EXPORT_SYMBOL_GPL(crypto_speck64_encrypt);
static void speck64_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
crypto_speck64_encrypt(crypto_tfm_ctx(tfm), out, in);
}
void crypto_speck64_decrypt(const struct speck64_tfm_ctx *ctx,
u8 *out, const u8 *in)
{
u32 y = get_unaligned_le32(in);
u32 x = get_unaligned_le32(in + 4);
int i;
for (i = ctx->nrounds - 1; i >= 0; i--)
speck64_unround(&x, &y, ctx->round_keys[i]);
put_unaligned_le32(y, out);
put_unaligned_le32(x, out + 4);
}
EXPORT_SYMBOL_GPL(crypto_speck64_decrypt);
static void speck64_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
crypto_speck64_decrypt(crypto_tfm_ctx(tfm), out, in);
}
int crypto_speck64_setkey(struct speck64_tfm_ctx *ctx, const u8 *key,
unsigned int keylen)
{
u32 l[3];
u32 k;
int i;
switch (keylen) {
case SPECK64_96_KEY_SIZE:
k = get_unaligned_le32(key);
l[0] = get_unaligned_le32(key + 4);
l[1] = get_unaligned_le32(key + 8);
ctx->nrounds = SPECK64_96_NROUNDS;
for (i = 0; i < ctx->nrounds; i++) {
ctx->round_keys[i] = k;
speck64_round(&l[i % 2], &k, i);
}
break;
case SPECK64_128_KEY_SIZE:
k = get_unaligned_le32(key);
l[0] = get_unaligned_le32(key + 4);
l[1] = get_unaligned_le32(key + 8);
l[2] = get_unaligned_le32(key + 12);
ctx->nrounds = SPECK64_128_NROUNDS;
for (i = 0; i < ctx->nrounds; i++) {
ctx->round_keys[i] = k;
speck64_round(&l[i % 3], &k, i);
}
break;
default:
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL_GPL(crypto_speck64_setkey);
static int speck64_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen)
{
return crypto_speck64_setkey(crypto_tfm_ctx(tfm), key, keylen);
}
/* Algorithm definitions */
static struct crypto_alg speck_algs[] = {
{
.cra_name = "speck128",
.cra_driver_name = "speck128-generic",
.cra_priority = 100,
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = SPECK128_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct speck128_tfm_ctx),
.cra_module = THIS_MODULE,
.cra_u = {
.cipher = {
.cia_min_keysize = SPECK128_128_KEY_SIZE,
.cia_max_keysize = SPECK128_256_KEY_SIZE,
.cia_setkey = speck128_setkey,
.cia_encrypt = speck128_encrypt,
.cia_decrypt = speck128_decrypt
}
}
}, {
.cra_name = "speck64",
.cra_driver_name = "speck64-generic",
.cra_priority = 100,
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = SPECK64_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct speck64_tfm_ctx),
.cra_module = THIS_MODULE,
.cra_u = {
.cipher = {
.cia_min_keysize = SPECK64_96_KEY_SIZE,
.cia_max_keysize = SPECK64_128_KEY_SIZE,
.cia_setkey = speck64_setkey,
.cia_encrypt = speck64_encrypt,
.cia_decrypt = speck64_decrypt
}
}
}
};
static int __init speck_module_init(void)
{
return crypto_register_algs(speck_algs, ARRAY_SIZE(speck_algs));
}
static void __exit speck_module_exit(void)
{
crypto_unregister_algs(speck_algs, ARRAY_SIZE(speck_algs));
}
module_init(speck_module_init);
module_exit(speck_module_exit);
MODULE_DESCRIPTION("Speck block cipher (generic)");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
MODULE_ALIAS_CRYPTO("speck128");
MODULE_ALIAS_CRYPTO("speck128-generic");
MODULE_ALIAS_CRYPTO("speck64");
MODULE_ALIAS_CRYPTO("speck64-generic");

View file

@ -3113,6 +3113,36 @@ static const struct alg_test_desc alg_test_descs[] = {
} }
} }
} }
}, {
.alg = "ecb(speck128)",
.test = alg_test_skcipher,
.suite = {
.cipher = {
.enc = {
.vecs = speck128_enc_tv_template,
.count = ARRAY_SIZE(speck128_enc_tv_template)
},
.dec = {
.vecs = speck128_dec_tv_template,
.count = ARRAY_SIZE(speck128_dec_tv_template)
}
}
}
}, {
.alg = "ecb(speck64)",
.test = alg_test_skcipher,
.suite = {
.cipher = {
.enc = {
.vecs = speck64_enc_tv_template,
.count = ARRAY_SIZE(speck64_enc_tv_template)
},
.dec = {
.vecs = speck64_dec_tv_template,
.count = ARRAY_SIZE(speck64_dec_tv_template)
}
}
}
}, { }, {
.alg = "ecb(tea)", .alg = "ecb(tea)",
.test = alg_test_skcipher, .test = alg_test_skcipher,
@ -3858,6 +3888,36 @@ static const struct alg_test_desc alg_test_descs[] = {
} }
} }
} }
}, {
.alg = "xts(speck128)",
.test = alg_test_skcipher,
.suite = {
.cipher = {
.enc = {
.vecs = speck128_xts_enc_tv_template,
.count = ARRAY_SIZE(speck128_xts_enc_tv_template)
},
.dec = {
.vecs = speck128_xts_dec_tv_template,
.count = ARRAY_SIZE(speck128_xts_dec_tv_template)
}
}
}
}, {
.alg = "xts(speck64)",
.test = alg_test_skcipher,
.suite = {
.cipher = {
.enc = {
.vecs = speck64_xts_enc_tv_template,
.count = ARRAY_SIZE(speck64_xts_enc_tv_template)
},
.dec = {
.vecs = speck64_xts_dec_tv_template,
.count = ARRAY_SIZE(speck64_xts_dec_tv_template)
}
}
}
}, { }, {
.alg = "xts(twofish)", .alg = "xts(twofish)",
.test = alg_test_skcipher, .test = alg_test_skcipher,

File diff suppressed because it is too large Load diff

View file

@ -97,6 +97,7 @@ obj-$(CONFIG_TC) += tc/
obj-$(CONFIG_UWB) += uwb/ obj-$(CONFIG_UWB) += uwb/
obj-$(CONFIG_USB_PHY) += usb/ obj-$(CONFIG_USB_PHY) += usb/
obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_USB) += usb/
obj-$(CONFIG_USB_SUPPORT) += usb/
obj-$(CONFIG_PCI) += usb/ obj-$(CONFIG_PCI) += usb/
obj-$(CONFIG_USB_GADGET) += usb/ obj-$(CONFIG_USB_GADGET) += usb/
obj-$(CONFIG_OF) += usb/ obj-$(CONFIG_OF) += usb/

View file

@ -4550,6 +4550,15 @@ static int binder_thread_release(struct binder_proc *proc,
binder_inner_proc_unlock(thread->proc); binder_inner_proc_unlock(thread->proc);
/*
* This is needed to avoid races between wake_up_poll() above and
* and ep_remove_waitqueue() called for other reasons (eg the epoll file
* descriptor being closed); ep_remove_waitqueue() holds an RCU read
* lock, so we can be sure it's done after calling synchronize_rcu().
*/
if (thread->looper & BINDER_LOOPER_STATE_POLL)
synchronize_rcu();
if (send_reply) if (send_reply)
binder_send_failed_reply(send_reply, BR_DEAD_REPLY); binder_send_failed_reply(send_reply, BR_DEAD_REPLY);
binder_release_work(proc, &thread->todo); binder_release_work(proc, &thread->todo);
@ -4565,6 +4574,8 @@ static unsigned int binder_poll(struct file *filp,
bool wait_for_proc_work; bool wait_for_proc_work;
thread = binder_get_thread(proc); thread = binder_get_thread(proc);
if (!thread)
return POLLERR;
binder_inner_proc_lock(thread->proc); binder_inner_proc_lock(thread->proc);
thread->looper |= BINDER_LOOPER_STATE_POLL; thread->looper |= BINDER_LOOPER_STATE_POLL;

View file

@ -155,8 +155,7 @@ static int exynos_rng_probe(struct platform_device *pdev)
return ret; return ret;
} }
#ifdef CONFIG_PM static int __maybe_unused exynos_rng_runtime_suspend(struct device *dev)
static int exynos_rng_runtime_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct exynos_rng *exynos_rng = platform_get_drvdata(pdev); struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
@ -166,7 +165,7 @@ static int exynos_rng_runtime_suspend(struct device *dev)
return 0; return 0;
} }
static int exynos_rng_runtime_resume(struct device *dev) static int __maybe_unused exynos_rng_runtime_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct exynos_rng *exynos_rng = platform_get_drvdata(pdev); struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
@ -174,12 +173,12 @@ static int exynos_rng_runtime_resume(struct device *dev)
return clk_prepare_enable(exynos_rng->clk); return clk_prepare_enable(exynos_rng->clk);
} }
static int exynos_rng_suspend(struct device *dev) static int __maybe_unused exynos_rng_suspend(struct device *dev)
{ {
return pm_runtime_force_suspend(dev); return pm_runtime_force_suspend(dev);
} }
static int exynos_rng_resume(struct device *dev) static int __maybe_unused exynos_rng_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct exynos_rng *exynos_rng = platform_get_drvdata(pdev); struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
@ -191,7 +190,6 @@ static int exynos_rng_resume(struct device *dev)
return exynos_rng_configure(exynos_rng); return exynos_rng_configure(exynos_rng);
} }
#endif
static const struct dev_pm_ops exynos_rng_pm_ops = { static const struct dev_pm_ops exynos_rng_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(exynos_rng_suspend, exynos_rng_resume) SET_SYSTEM_SLEEP_PM_OPS(exynos_rng_suspend, exynos_rng_resume)

View file

@ -401,16 +401,21 @@ static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode)
uint32_t aes_control; uint32_t aes_control;
int err; int err;
unsigned long flags; unsigned long flags;
u8 *iv;
aes_control = SSS_AES_KEY_CHANGE_MODE; aes_control = SSS_AES_KEY_CHANGE_MODE;
if (mode & FLAGS_AES_DECRYPT) if (mode & FLAGS_AES_DECRYPT)
aes_control |= SSS_AES_MODE_DECRYPT; aes_control |= SSS_AES_MODE_DECRYPT;
if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC) if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC) {
aes_control |= SSS_AES_CHAIN_MODE_CBC; aes_control |= SSS_AES_CHAIN_MODE_CBC;
else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR) iv = req->info;
} else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR) {
aes_control |= SSS_AES_CHAIN_MODE_CTR; aes_control |= SSS_AES_CHAIN_MODE_CTR;
iv = req->info;
} else {
iv = NULL; /* AES_ECB */
}
if (dev->ctx->keylen == AES_KEYSIZE_192) if (dev->ctx->keylen == AES_KEYSIZE_192)
aes_control |= SSS_AES_KEY_SIZE_192; aes_control |= SSS_AES_KEY_SIZE_192;
else if (dev->ctx->keylen == AES_KEYSIZE_256) else if (dev->ctx->keylen == AES_KEYSIZE_256)
@ -440,7 +445,7 @@ static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode)
goto outdata_error; goto outdata_error;
SSS_AES_WRITE(dev, AES_CONTROL, aes_control); SSS_AES_WRITE(dev, AES_CONTROL, aes_control);
s5p_set_aes(dev, dev->ctx->aes_key, req->info, dev->ctx->keylen); s5p_set_aes(dev, dev->ctx->aes_key, iv, dev->ctx->keylen);
s5p_set_dma_indata(dev, req->src); s5p_set_dma_indata(dev, req->src);
s5p_set_dma_outdata(dev, req->dst); s5p_set_dma_outdata(dev, req->dst);

View file

@ -716,7 +716,7 @@ atc_prep_dma_interleaved(struct dma_chan *chan,
unsigned long flags) unsigned long flags)
{ {
struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma_chan *atchan = to_at_dma_chan(chan);
struct data_chunk *first = xt->sgl; struct data_chunk *first;
struct at_desc *desc = NULL; struct at_desc *desc = NULL;
size_t xfer_count; size_t xfer_count;
unsigned int dwidth; unsigned int dwidth;
@ -728,6 +728,8 @@ atc_prep_dma_interleaved(struct dma_chan *chan,
if (unlikely(!xt || xt->numf != 1 || !xt->frame_size)) if (unlikely(!xt || xt->numf != 1 || !xt->frame_size))
return NULL; return NULL;
first = xt->sgl;
dev_info(chan2dev(chan), dev_info(chan2dev(chan),
"%s: src=%pad, dest=%pad, numf=%d, frame_size=%d, flags=0x%lx\n", "%s: src=%pad, dest=%pad, numf=%d, frame_size=%d, flags=0x%lx\n",
__func__, &xt->src_start, &xt->dst_start, xt->numf, __func__, &xt->src_start, &xt->dst_start, xt->numf,

View file

@ -557,7 +557,7 @@ static int jz4740_dma_probe(struct platform_device *pdev)
ret = dma_async_device_register(dd); ret = dma_async_device_register(dd);
if (ret) if (ret)
return ret; goto err_clk;
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev); ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev);
@ -570,6 +570,8 @@ static int jz4740_dma_probe(struct platform_device *pdev)
err_unregister: err_unregister:
dma_async_device_unregister(dd); dma_async_device_unregister(dd);
err_clk:
clk_disable_unprepare(dmadev->clk);
return ret; return ret;
} }

View file

@ -395,7 +395,7 @@ static int ioat_dma_self_test(struct ioatdma_device *ioat_dma)
if (memcmp(src, dest, IOAT_TEST_SIZE)) { if (memcmp(src, dest, IOAT_TEST_SIZE)) {
dev_err(dev, "Self-test copy failed compare, disabling\n"); dev_err(dev, "Self-test copy failed compare, disabling\n");
err = -ENODEV; err = -ENODEV;
goto free_resources; goto unmap_dma;
} }
unmap_dma: unmap_dma:

View file

@ -26,7 +26,7 @@
#define DRIVER_NAME "zx-dma" #define DRIVER_NAME "zx-dma"
#define DMA_ALIGN 4 #define DMA_ALIGN 4
#define DMA_MAX_SIZE (0x10000 - PAGE_SIZE) #define DMA_MAX_SIZE (0x10000 - 512)
#define LLI_BLOCK_SIZE (4 * PAGE_SIZE) #define LLI_BLOCK_SIZE (4 * PAGE_SIZE)
#define REG_ZX_SRC_ADDR 0x00 #define REG_ZX_SRC_ADDR 0x00

View file

@ -326,7 +326,7 @@ static void intel_mid_irq_init_hw(struct intel_mid_gpio *priv)
} }
} }
static int intel_gpio_runtime_idle(struct device *dev) static int __maybe_unused intel_gpio_runtime_idle(struct device *dev)
{ {
int err = pm_schedule_suspend(dev, 500); int err = pm_schedule_suspend(dev, 500);
return err ?: -EBUSY; return err ?: -EBUSY;

View file

@ -42,9 +42,7 @@ struct xgene_gpio {
struct gpio_chip chip; struct gpio_chip chip;
void __iomem *base; void __iomem *base;
spinlock_t lock; spinlock_t lock;
#ifdef CONFIG_PM
u32 set_dr_val[XGENE_MAX_GPIO_BANKS]; u32 set_dr_val[XGENE_MAX_GPIO_BANKS];
#endif
}; };
static inline struct xgene_gpio *to_xgene_gpio(struct gpio_chip *chip) static inline struct xgene_gpio *to_xgene_gpio(struct gpio_chip *chip)
@ -132,8 +130,7 @@ static int xgene_gpio_dir_out(struct gpio_chip *gc,
return 0; return 0;
} }
#ifdef CONFIG_PM static __maybe_unused int xgene_gpio_suspend(struct device *dev)
static int xgene_gpio_suspend(struct device *dev)
{ {
struct xgene_gpio *gpio = dev_get_drvdata(dev); struct xgene_gpio *gpio = dev_get_drvdata(dev);
unsigned long bank_offset; unsigned long bank_offset;
@ -146,7 +143,7 @@ static int xgene_gpio_suspend(struct device *dev)
return 0; return 0;
} }
static int xgene_gpio_resume(struct device *dev) static __maybe_unused int xgene_gpio_resume(struct device *dev)
{ {
struct xgene_gpio *gpio = dev_get_drvdata(dev); struct xgene_gpio *gpio = dev_get_drvdata(dev);
unsigned long bank_offset; unsigned long bank_offset;
@ -160,10 +157,6 @@ static int xgene_gpio_resume(struct device *dev)
} }
static SIMPLE_DEV_PM_OPS(xgene_gpio_pm, xgene_gpio_suspend, xgene_gpio_resume); static SIMPLE_DEV_PM_OPS(xgene_gpio_pm, xgene_gpio_suspend, xgene_gpio_resume);
#define XGENE_GPIO_PM_OPS (&xgene_gpio_pm)
#else
#define XGENE_GPIO_PM_OPS NULL
#endif
static int xgene_gpio_probe(struct platform_device *pdev) static int xgene_gpio_probe(struct platform_device *pdev)
{ {
@ -230,7 +223,7 @@ static struct platform_driver xgene_gpio_driver = {
.driver = { .driver = {
.name = "xgene-gpio", .name = "xgene-gpio",
.of_match_table = xgene_gpio_of_match, .of_match_table = xgene_gpio_of_match,
.pm = XGENE_GPIO_PM_OPS, .pm = &xgene_gpio_pm,
}, },
.probe = xgene_gpio_probe, .probe = xgene_gpio_probe,
.remove = xgene_gpio_remove, .remove = xgene_gpio_remove,

View file

@ -1182,17 +1182,13 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc", ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc",
dcrtc); dcrtc);
if (ret < 0) { if (ret < 0)
kfree(dcrtc); goto err_crtc;
return ret;
}
if (dcrtc->variant->init) { if (dcrtc->variant->init) {
ret = dcrtc->variant->init(dcrtc, dev); ret = dcrtc->variant->init(dcrtc, dev);
if (ret) { if (ret)
kfree(dcrtc); goto err_crtc;
return ret;
}
} }
/* Ensure AXI pipeline is enabled */ /* Ensure AXI pipeline is enabled */
@ -1203,13 +1199,15 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
dcrtc->crtc.port = port; dcrtc->crtc.port = port;
primary = kzalloc(sizeof(*primary), GFP_KERNEL); primary = kzalloc(sizeof(*primary), GFP_KERNEL);
if (!primary) if (!primary) {
return -ENOMEM; ret = -ENOMEM;
goto err_crtc;
}
ret = armada_drm_plane_init(primary); ret = armada_drm_plane_init(primary);
if (ret) { if (ret) {
kfree(primary); kfree(primary);
return ret; goto err_crtc;
} }
ret = drm_universal_plane_init(drm, &primary->base, 0, ret = drm_universal_plane_init(drm, &primary->base, 0,
@ -1219,7 +1217,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
DRM_PLANE_TYPE_PRIMARY); DRM_PLANE_TYPE_PRIMARY);
if (ret) { if (ret) {
kfree(primary); kfree(primary);
return ret; goto err_crtc;
} }
ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, &primary->base, NULL, ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, &primary->base, NULL,
@ -1238,6 +1236,9 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
err_crtc_init: err_crtc_init:
primary->base.funcs->destroy(&primary->base); primary->base.funcs->destroy(&primary->base);
err_crtc:
kfree(dcrtc);
return ret; return ret;
} }

View file

@ -69,7 +69,7 @@ void drm_modeset_lock_all(struct drm_device *dev)
struct drm_modeset_acquire_ctx *ctx; struct drm_modeset_acquire_ctx *ctx;
int ret; int ret;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); ctx = kzalloc(sizeof(*ctx), GFP_KERNEL | __GFP_NOFAIL);
if (WARN_ON(!ctx)) if (WARN_ON(!ctx))
return; return;

View file

@ -821,14 +821,18 @@ void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
struct drm_device *dev = dsi_config->dev; struct drm_device *dev = dsi_config->dev;
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
u32 pipeconf_reg = PIPEACONF; u32 pipeconf_reg = PIPEACONF;
u32 dspcntr_reg = DSPACNTR; u32 dspcntr_reg = DSPACNTR;
u32 pipeconf, dspcntr;
u32 pipeconf = dev_priv->pipeconf[pipe];
u32 dspcntr = dev_priv->dspcntr[pipe];
u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
if (WARN_ON(pipe < 0))
return;
pipeconf = dev_priv->pipeconf[pipe];
dspcntr = dev_priv->dspcntr[pipe];
if (pipe) { if (pipe) {
pipeconf_reg = PIPECCONF; pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR; dspcntr_reg = DSPCCNTR;

View file

@ -382,16 +382,6 @@ static int mdfld_dsi_connector_mode_valid(struct drm_connector *connector,
return MODE_OK; return MODE_OK;
} }
static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode)
{
if (mode == connector->dpms)
return;
/*first, execute dpms*/
drm_helper_connector_dpms(connector, mode);
}
static struct drm_encoder *mdfld_dsi_connector_best_encoder( static struct drm_encoder *mdfld_dsi_connector_best_encoder(
struct drm_connector *connector) struct drm_connector *connector)
{ {
@ -404,7 +394,7 @@ static struct drm_encoder *mdfld_dsi_connector_best_encoder(
/*DSI connector funcs*/ /*DSI connector funcs*/
static const struct drm_connector_funcs mdfld_dsi_connector_funcs = { static const struct drm_connector_funcs mdfld_dsi_connector_funcs = {
.dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms, .dpms = drm_helper_connector_dpms,
.save = mdfld_dsi_connector_save, .save = mdfld_dsi_connector_save,
.restore = mdfld_dsi_connector_restore, .restore = mdfld_dsi_connector_restore,
.detect = mdfld_dsi_connector_detect, .detect = mdfld_dsi_connector_detect,

View file

@ -370,7 +370,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_cli *cli = nouveau_cli(file_priv);
struct drm_device *dev = chan->drm->dev; struct drm_device *dev = chan->drm->dev;
int trycnt = 0; int trycnt = 0;
int ret, i; int ret = -EINVAL, i;
struct nouveau_bo *res_bo = NULL; struct nouveau_bo *res_bo = NULL;
LIST_HEAD(gart_list); LIST_HEAD(gart_list);
LIST_HEAD(vram_list); LIST_HEAD(vram_list);

View file

@ -293,13 +293,10 @@ static int vmw_cmdbuf_header_submit(struct vmw_cmdbuf_header *header)
struct vmw_cmdbuf_man *man = header->man; struct vmw_cmdbuf_man *man = header->man;
u32 val; u32 val;
if (sizeof(header->handle) > 4) val = upper_32_bits(header->handle);
val = (header->handle >> 32);
else
val = 0;
vmw_write(man->dev_priv, SVGA_REG_COMMAND_HIGH, val); vmw_write(man->dev_priv, SVGA_REG_COMMAND_HIGH, val);
val = (header->handle & 0xFFFFFFFFULL); val = lower_32_bits(header->handle);
val |= header->cb_context & SVGA_CB_CONTEXT_MASK; val |= header->cb_context & SVGA_CB_CONTEXT_MASK;
vmw_write(man->dev_priv, SVGA_REG_COMMAND_LOW, val); vmw_write(man->dev_priv, SVGA_REG_COMMAND_LOW, val);

View file

@ -195,9 +195,7 @@ int hv_init(void)
{ {
int max_leaf; int max_leaf;
union hv_x64_msr_hypercall_contents hypercall_msr; union hv_x64_msr_hypercall_contents hypercall_msr;
union hv_x64_msr_hypercall_contents tsc_msr;
void *virtaddr = NULL; void *virtaddr = NULL;
void *va_tsc = NULL;
memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS); memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS);
memset(hv_context.synic_message_page, 0, memset(hv_context.synic_message_page, 0,
@ -243,6 +241,9 @@ int hv_init(void)
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) { if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
union hv_x64_msr_hypercall_contents tsc_msr;
void *va_tsc;
va_tsc = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL); va_tsc = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL);
if (!va_tsc) if (!va_tsc)
goto cleanup; goto cleanup;

View file

@ -56,9 +56,7 @@ EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num);
* The board info passed can safely be __initdata, but be careful of embedded * The board info passed can safely be __initdata, but be careful of embedded
* pointers (for platform_data, functions, etc) since that won't be copied. * pointers (for platform_data, functions, etc) since that won't be copied.
*/ */
int __init int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len)
i2c_register_board_info(int busnum,
struct i2c_board_info const *info, unsigned len)
{ {
int status; int status;

View file

@ -17,6 +17,7 @@ config I7300_IDLE_IOAT_CHANNEL
config I7300_IDLE config I7300_IDLE
tristate "Intel chipset idle memory power saving driver" tristate "Intel chipset idle memory power saving driver"
depends on PCI
select I7300_IDLE_IOAT_CHANNEL select I7300_IDLE_IOAT_CHANNEL
help help
Enable memory power savings when idle with certain Intel server Enable memory power savings when idle with certain Intel server

View file

@ -44,7 +44,7 @@ struct axp288_adc_info {
struct regmap *regmap; struct regmap *regmap;
}; };
static const struct iio_chan_spec const axp288_adc_channels[] = { static const struct iio_chan_spec axp288_adc_channels[] = {
{ {
.indexed = 1, .indexed = 1,
.type = IIO_TEMP, .type = IIO_TEMP,

View file

@ -626,6 +626,7 @@ struct rdma_cm_id *rdma_create_id(struct net *net,
INIT_LIST_HEAD(&id_priv->mc_list); INIT_LIST_HEAD(&id_priv->mc_list);
get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num); get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num);
id_priv->id.route.addr.dev_addr.net = get_net(net); id_priv->id.route.addr.dev_addr.net = get_net(net);
id_priv->seq_num &= 0x00ffffff;
return &id_priv->id; return &id_priv->id;
} }

View file

@ -809,10 +809,9 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
rdev->lldi.vr->qp.size, rdev->lldi.vr->qp.size,
rdev->lldi.vr->cq.start, rdev->lldi.vr->cq.start,
rdev->lldi.vr->cq.size); rdev->lldi.vr->cq.size);
PDBG("udb len 0x%x udb base %p db_reg %p gts_reg %p " PDBG("udb %pR db_reg %p gts_reg %p "
"qpmask 0x%x cqmask 0x%x\n", "qpmask 0x%x cqmask 0x%x\n",
(unsigned)pci_resource_len(rdev->lldi.pdev, 2), &rdev->lldi.pdev->resource[2],
(void *)pci_resource_start(rdev->lldi.pdev, 2),
rdev->lldi.db_reg, rdev->lldi.gts_reg, rdev->lldi.db_reg, rdev->lldi.gts_reg,
rdev->qpmask, rdev->cqmask); rdev->qpmask, rdev->cqmask);

View file

@ -164,11 +164,18 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
int error, col, row; int error, col, row;
u8 reg, state, code; u8 reg, state, code;
/* Initial read of the key event FIFO */ do {
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg); error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg);
if (error < 0) {
dev_err(&keypad_data->client->dev,
"unable to read REG_KEY_EVENT_A\n");
break;
}
/* Assume that key code 0 signifies empty FIFO */
if (reg <= 0)
break;
/* Assume that key code 0 signifies empty FIFO */
while (error >= 0 && reg > 0) {
state = reg & KEY_EVENT_VALUE; state = reg & KEY_EVENT_VALUE;
code = reg & KEY_EVENT_CODE; code = reg & KEY_EVENT_CODE;
@ -184,11 +191,7 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
/* Read for next loop */ /* Read for next loop */
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg); error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg);
} } while (1);
if (error < 0)
dev_err(&keypad_data->client->dev,
"unable to read REG_KEY_EVENT_A\n");
input_sync(input); input_sync(input);
} }

View file

@ -147,7 +147,7 @@ static word plci_remove_check(PLCI *);
static void listen_check(DIVA_CAPI_ADAPTER *); static void listen_check(DIVA_CAPI_ADAPTER *);
static byte AddInfo(byte **, byte **, byte *, byte *); static byte AddInfo(byte **, byte **, byte *, byte *);
static byte getChannel(API_PARSE *); static byte getChannel(API_PARSE *);
static void IndParse(PLCI *, word *, byte **, byte); static void IndParse(PLCI *, const word *, byte **, byte);
static byte ie_compare(byte *, byte *); static byte ie_compare(byte *, byte *);
static word find_cip(DIVA_CAPI_ADAPTER *, byte *, byte *); static word find_cip(DIVA_CAPI_ADAPTER *, byte *, byte *);
static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *, word); static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *, word);
@ -4860,7 +4860,7 @@ static void sig_ind(PLCI *plci)
/* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */ /* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */
/* SMSG is situated at the end because its 0 (for compatibility reasons */ /* SMSG is situated at the end because its 0 (for compatibility reasons */
/* (see Info_Mask Bit 4, first IE. then the message type) */ /* (see Info_Mask Bit 4, first IE. then the message type) */
word parms_id[] = static const word parms_id[] =
{MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA, {MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA,
UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW, UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW,
RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR, RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR,
@ -4868,12 +4868,12 @@ static void sig_ind(PLCI *plci)
/* 14 FTY repl by ESC_CHI */ /* 14 FTY repl by ESC_CHI */
/* 18 PI repl by ESC_LAW */ /* 18 PI repl by ESC_LAW */
/* removed OAD changed to 0xff for future use, OAD is multiIE now */ /* removed OAD changed to 0xff for future use, OAD is multiIE now */
word multi_fac_id[] = {1, FTY}; static const word multi_fac_id[] = {1, FTY};
word multi_pi_id[] = {1, PI}; static const word multi_pi_id[] = {1, PI};
word multi_CiPN_id[] = {1, OAD}; static const word multi_CiPN_id[] = {1, OAD};
word multi_ssext_id[] = {1, ESC_SSEXT}; static const word multi_ssext_id[] = {1, ESC_SSEXT};
word multi_vswitch_id[] = {1, ESC_VSWITCH}; static const word multi_vswitch_id[] = {1, ESC_VSWITCH};
byte *cau; byte *cau;
word ncci; word ncci;
@ -8926,7 +8926,7 @@ static void listen_check(DIVA_CAPI_ADAPTER *a)
/* functions for all parameters sent in INDs */ /* functions for all parameters sent in INDs */
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
static void IndParse(PLCI *plci, word *parms_id, byte **parms, byte multiIEsize) static void IndParse(PLCI *plci, const word *parms_id, byte **parms, byte multiIEsize)
{ {
word ploc; /* points to current location within packet */ word ploc; /* points to current location within packet */
byte w; byte w;

View file

@ -718,7 +718,7 @@ icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card *card)
return 0; return 0;
if (card->sndcount[channel] > ICN_MAX_SQUEUE) if (card->sndcount[channel] > ICN_MAX_SQUEUE)
return 0; return 0;
#warning TODO test headroom or use skb->nb to flag ACK /* TODO test headroom or use skb->nb to flag ACK */
nskb = skb_clone(skb, GFP_ATOMIC); nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) { if (nskb) {
/* Push ACK flag as one /* Push ACK flag as one

View file

@ -441,6 +441,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
RspMessage rcvmsg; RspMessage rcvmsg;
ReqMessage sndmsg; ReqMessage sndmsg;
HWConfig_pl hwci; HWConfig_pl hwci;
void __iomem *rambase_sig = (void __iomem *)rambase + SIG_OFFSET;
int x; int x;
pr_debug("Attempting to identify adapter @ 0x%lx io 0x%x\n", pr_debug("Attempting to identify adapter @ 0x%lx io 0x%x\n",
@ -481,7 +482,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
*/ */
outb(PRI_BASEPG_VAL, pgport); outb(PRI_BASEPG_VAL, pgport);
msleep_interruptible(1000); msleep_interruptible(1000);
sig = readl(rambase + SIG_OFFSET); sig = readl(rambase_sig);
pr_debug("Looking for a signature, got 0x%lx\n", sig); pr_debug("Looking for a signature, got 0x%lx\n", sig);
if (sig == SIGNATURE) if (sig == SIGNATURE)
return PRI_BOARD; return PRI_BOARD;
@ -491,7 +492,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
*/ */
outb(BRI_BASEPG_VAL, pgport); outb(BRI_BASEPG_VAL, pgport);
msleep_interruptible(1000); msleep_interruptible(1000);
sig = readl(rambase + SIG_OFFSET); sig = readl(rambase_sig);
pr_debug("Looking for a signature, got 0x%lx\n", sig); pr_debug("Looking for a signature, got 0x%lx\n", sig);
if (sig == SIGNATURE) if (sig == SIGNATURE)
return BRI_BOARD; return BRI_BOARD;
@ -501,7 +502,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
/* /*
* Try to spot a card * Try to spot a card
*/ */
sig = readl(rambase + SIG_OFFSET); sig = readl(rambase_sig);
pr_debug("Looking for a signature, got 0x%lx\n", sig); pr_debug("Looking for a signature, got 0x%lx\n", sig);
if (sig != SIGNATURE) if (sig != SIGNATURE)
return -1; return -1;

View file

@ -1028,8 +1028,9 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor
* (not needed for Linear and RAID0 as metadata doesn't * (not needed for Linear and RAID0 as metadata doesn't
* record this size) * record this size)
*/ */
if (rdev->sectors >= (2ULL << 32) && sb->level >= 1) if (IS_ENABLED(CONFIG_LBDAF) && (u64)rdev->sectors >= (2ULL << 32) &&
rdev->sectors = (2ULL << 32) - 2; sb->level >= 1)
rdev->sectors = (sector_t)(2ULL << 32) - 2;
if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1)
/* "this cannot possibly happen" ... */ /* "this cannot possibly happen" ... */
@ -1322,8 +1323,9 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors)
/* Limit to 4TB as metadata cannot record more than that. /* Limit to 4TB as metadata cannot record more than that.
* 4TB == 2^32 KB, or 2*2^32 sectors. * 4TB == 2^32 KB, or 2*2^32 sectors.
*/ */
if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) if (IS_ENABLED(CONFIG_LBDAF) && (u64)num_sectors >= (2ULL << 32) &&
num_sectors = (2ULL << 32) - 2; rdev->mddev->level >= 1)
num_sectors = (sector_t)(2ULL << 32) - 2;
md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
rdev->sb_page); rdev->sb_page);
md_super_wait(rdev->mddev); md_super_wait(rdev->mddev);

View file

@ -38,7 +38,7 @@ static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
#endif #endif
/* lnb control */ /* lnb control */
#if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299) #if (FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)) && FE_SUPPORTED(PLL)
static int flexcop_set_voltage(struct dvb_frontend *fe, static int flexcop_set_voltage(struct dvb_frontend *fe,
enum fe_sec_voltage voltage) enum fe_sec_voltage voltage)
{ {
@ -68,7 +68,7 @@ static int flexcop_set_voltage(struct dvb_frontend *fe,
#endif #endif
#if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312) #if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
static int flexcop_sleep(struct dvb_frontend* fe) static int __maybe_unused flexcop_sleep(struct dvb_frontend* fe)
{ {
struct flexcop_device *fc = fe->dvb->priv; struct flexcop_device *fc = fe->dvb->priv;
if (fc->fe_sleep) if (fc->fe_sleep)

View file

@ -421,6 +421,7 @@ static int s5k6aa_set_ahb_address(struct i2c_client *client)
/** /**
* s5k6aa_configure_pixel_clock - apply ISP main clock/PLL configuration * s5k6aa_configure_pixel_clock - apply ISP main clock/PLL configuration
* @s5k6aa: pointer to &struct s5k6aa describing the device
* *
* Configure the internal ISP PLL for the required output frequency. * Configure the internal ISP PLL for the required output frequency.
* Locking: called with s5k6aa.lock mutex held. * Locking: called with s5k6aa.lock mutex held.
@ -669,6 +670,7 @@ static int s5k6aa_set_input_params(struct s5k6aa *s5k6aa)
/** /**
* s5k6aa_configure_video_bus - configure the video output interface * s5k6aa_configure_video_bus - configure the video output interface
* @s5k6aa: pointer to &struct s5k6aa describing the device
* @bus_type: video bus type: parallel or MIPI-CSI * @bus_type: video bus type: parallel or MIPI-CSI
* @nlanes: number of MIPI lanes to be used (MIPI-CSI only) * @nlanes: number of MIPI lanes to be used (MIPI-CSI only)
* *
@ -724,6 +726,8 @@ static int s5k6aa_new_config_sync(struct i2c_client *client, int timeout,
/** /**
* s5k6aa_set_prev_config - write user preview register set * s5k6aa_set_prev_config - write user preview register set
* @s5k6aa: pointer to &struct s5k6aa describing the device
* @preset: s5kaa preset to be applied
* *
* Configure output resolution and color fromat, pixel clock * Configure output resolution and color fromat, pixel clock
* frequency range, device frame rate type and frame period range. * frequency range, device frame rate type and frame period range.
@ -777,6 +781,7 @@ static int s5k6aa_set_prev_config(struct s5k6aa *s5k6aa,
/** /**
* s5k6aa_initialize_isp - basic ISP MCU initialization * s5k6aa_initialize_isp - basic ISP MCU initialization
* @sd: pointer to V4L2 sub-device descriptor
* *
* Configure AHB addresses for registers read/write; configure PLLs for * Configure AHB addresses for registers read/write; configure PLLs for
* required output pixel clock. The ISP power supply needs to be already * required output pixel clock. The ISP power supply needs to be already

View file

@ -197,57 +197,61 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
} }
} }
static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)
{
__le32 val = 0;
i2c_rd(sd, reg, (u8 __force *)&val, n);
return le32_to_cpu(val);
}
static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n)
{
__le32 raw = cpu_to_le32(val);
i2c_wr(sd, reg, (u8 __force *)&raw, n);
}
static u8 i2c_rd8(struct v4l2_subdev *sd, u16 reg) static u8 i2c_rd8(struct v4l2_subdev *sd, u16 reg)
{ {
u8 val; return i2c_rdreg(sd, reg, 1);
i2c_rd(sd, reg, &val, 1);
return val;
} }
static void i2c_wr8(struct v4l2_subdev *sd, u16 reg, u8 val) static void i2c_wr8(struct v4l2_subdev *sd, u16 reg, u8 val)
{ {
i2c_wr(sd, reg, &val, 1); i2c_wrreg(sd, reg, val, 1);
} }
static void i2c_wr8_and_or(struct v4l2_subdev *sd, u16 reg, static void i2c_wr8_and_or(struct v4l2_subdev *sd, u16 reg,
u8 mask, u8 val) u8 mask, u8 val)
{ {
i2c_wr8(sd, reg, (i2c_rd8(sd, reg) & mask) | val); i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2);
} }
static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg) static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg)
{ {
u16 val; return i2c_rdreg(sd, reg, 2);
i2c_rd(sd, reg, (u8 *)&val, 2);
return val;
} }
static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val) static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val)
{ {
i2c_wr(sd, reg, (u8 *)&val, 2); i2c_wrreg(sd, reg, val, 2);
} }
static void i2c_wr16_and_or(struct v4l2_subdev *sd, u16 reg, u16 mask, u16 val) static void i2c_wr16_and_or(struct v4l2_subdev *sd, u16 reg, u16 mask, u16 val)
{ {
i2c_wr16(sd, reg, (i2c_rd16(sd, reg) & mask) | val); i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2);
} }
static u32 i2c_rd32(struct v4l2_subdev *sd, u16 reg) static u32 i2c_rd32(struct v4l2_subdev *sd, u16 reg)
{ {
u32 val; return i2c_rdreg(sd, reg, 4);
i2c_rd(sd, reg, (u8 *)&val, 4);
return val;
} }
static void i2c_wr32(struct v4l2_subdev *sd, u16 reg, u32 val) static void i2c_wr32(struct v4l2_subdev *sd, u16 reg, u32 val)
{ {
i2c_wr(sd, reg, (u8 *)&val, 4); i2c_wrreg(sd, reg, val, 4);
} }
/* --------------- STATUS --------------- */ /* --------------- STATUS --------------- */
@ -1240,7 +1244,7 @@ static int tc358743_g_register(struct v4l2_subdev *sd,
reg->size = tc358743_get_reg_size(reg->reg); reg->size = tc358743_get_reg_size(reg->reg);
i2c_rd(sd, reg->reg, (u8 *)&reg->val, reg->size); reg->val = i2c_rdreg(sd, reg->reg, reg->size);
return 0; return 0;
} }
@ -1266,7 +1270,7 @@ static int tc358743_s_register(struct v4l2_subdev *sd,
reg->reg == BCAPS) reg->reg == BCAPS)
return 0; return 0;
i2c_wr(sd, (u16)reg->reg, (u8 *)&reg->val, i2c_wrreg(sd, (u16)reg->reg, reg->val,
tc358743_get_reg_size(reg->reg)); tc358743_get_reg_size(reg->reg));
return 0; return 0;

View file

@ -11,7 +11,7 @@ config VIDEO_EM28XX_V4L2
select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT
select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT
select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT
---help--- ---help---
This is a video4linux driver for Empia 28xx based TV cards. This is a video4linux driver for Empia 28xx based TV cards.

View file

@ -11,7 +11,7 @@ config VIDEO_GO7007
select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT
select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT
select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT
select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT
select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT
---help--- ---help---
This is a video4linux driver for the WIS GO7007 MPEG This is a video4linux driver for the WIS GO7007 MPEG

View file

@ -273,7 +273,9 @@ static int hdpvr_probe(struct usb_interface *interface,
struct hdpvr_device *dev; struct hdpvr_device *dev;
struct usb_host_interface *iface_desc; struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
#if IS_ENABLED(CONFIG_I2C)
struct i2c_client *client; struct i2c_client *client;
#endif
size_t buffer_size; size_t buffer_size;
int i; int i;
int retval = -ENOMEM; int retval = -ENOMEM;

View file

@ -1119,8 +1119,10 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
return 0; return 0;
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
err_video_unreg: err_video_unreg:
video_unregister_device(&pdev->vdev); video_unregister_device(&pdev->vdev);
#endif
err_unregister_v4l2_dev: err_unregister_v4l2_dev:
v4l2_device_unregister(&pdev->v4l2_dev); v4l2_device_unregister(&pdev->v4l2_dev);
err_free_controls: err_free_controls:

View file

@ -37,7 +37,6 @@ config VIDEO_PCI_SKELETON
# Used by drivers that need tuner.ko # Used by drivers that need tuner.ko
config VIDEO_TUNER config VIDEO_TUNER
tristate tristate
depends on MEDIA_TUNER
# Used by drivers that need v4l2-mem2mem.ko # Used by drivers that need v4l2-mem2mem.ko
config V4L2_MEM2MEM_DEV config V4L2_MEM2MEM_DEV

View file

@ -6848,6 +6848,7 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh
*size = y; *size = y;
} }
#ifdef CONFIG_PROC_FS
static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan) static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
{ {
char expVer[32]; char expVer[32];
@ -6879,6 +6880,7 @@ static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int
seq_putc(m, '\n'); seq_putc(m, '\n');
} }
#endif
/** /**
* mpt_set_taskmgmt_in_progress_flag - set flags associated with task management * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management

View file

@ -67,6 +67,10 @@ endchoice
config MTD_CFI_GEOMETRY config MTD_CFI_GEOMETRY
bool "Specific CFI Flash geometry selection" bool "Specific CFI Flash geometry selection"
depends on MTD_CFI_ADV_OPTIONS depends on MTD_CFI_ADV_OPTIONS
select MTD_MAP_BANK_WIDTH_1 if !(MTD_MAP_BANK_WIDTH_2 || \
MTD_MAP_BANK_WIDTH_4 || MTD_MAP_BANK_WIDTH_8 || \
MTD_MAP_BANK_WIDTH_16 || MTD_MAP_BANK_WIDTH_32)
select MTD_CFI_I1 if !(MTD_CFI_I2 || MTD_CFI_I4 || MTD_CFI_I8)
help help
This option does not affect the code directly, but will enable This option does not affect the code directly, but will enable
some other configuration options which would allow you to reduce some other configuration options which would allow you to reduce

View file

@ -112,8 +112,8 @@ static void ck804xrom_cleanup(struct ck804xrom_window *window)
} }
static int ck804xrom_init_one(struct pci_dev *pdev, static int __init ck804xrom_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
u8 byte; u8 byte;

View file

@ -144,8 +144,8 @@ static void esb2rom_cleanup(struct esb2rom_window *window)
pci_dev_put(window->pdev); pci_dev_put(window->pdev);
} }
static int esb2rom_init_one(struct pci_dev *pdev, static int __init esb2rom_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
struct esb2rom_window *window = &esb2rom_window; struct esb2rom_window *window = &esb2rom_window;

View file

@ -57,10 +57,12 @@ static void ichxrom_cleanup(struct ichxrom_window *window)
{ {
struct ichxrom_map_info *map, *scratch; struct ichxrom_map_info *map, *scratch;
u16 word; u16 word;
int ret;
/* Disable writes through the rom window */ /* Disable writes through the rom window */
pci_read_config_word(window->pdev, BIOS_CNTL, &word); ret = pci_read_config_word(window->pdev, BIOS_CNTL, &word);
pci_write_config_word(window->pdev, BIOS_CNTL, word & ~1); if (!ret)
pci_write_config_word(window->pdev, BIOS_CNTL, word & ~1);
pci_dev_put(window->pdev); pci_dev_put(window->pdev);
/* Free all of the mtd devices */ /* Free all of the mtd devices */
@ -84,8 +86,8 @@ static void ichxrom_cleanup(struct ichxrom_window *window)
} }
static int ichxrom_init_one(struct pci_dev *pdev, static int __init ichxrom_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
struct ichxrom_window *window = &ichxrom_window; struct ichxrom_window *window = &ichxrom_window;

View file

@ -160,7 +160,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl)
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
cfg.direction = DMA_MEM_TO_DEV; cfg.direction = DMA_MEM_TO_DEV;
cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl); cfg.dst_addr = flctl->fifo;
cfg.src_addr = 0; cfg.src_addr = 0;
ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg); ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg);
if (ret < 0) if (ret < 0)
@ -176,7 +176,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl)
cfg.direction = DMA_DEV_TO_MEM; cfg.direction = DMA_DEV_TO_MEM;
cfg.dst_addr = 0; cfg.dst_addr = 0;
cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl); cfg.src_addr = flctl->fifo;
ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg); ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg);
if (ret < 0) if (ret < 0)
goto err; goto err;
@ -1096,6 +1096,7 @@ static int flctl_probe(struct platform_device *pdev)
flctl->reg = devm_ioremap_resource(&pdev->dev, res); flctl->reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(flctl->reg)) if (IS_ERR(flctl->reg))
return PTR_ERR(flctl->reg); return PTR_ERR(flctl->reg);
flctl->fifo = res->start + 0x24; /* FLDTFIFO */
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {

View file

@ -411,6 +411,9 @@ config XEN_NETDEV_BACKEND
config VMXNET3 config VMXNET3
tristate "VMware VMXNET3 ethernet driver" tristate "VMware VMXNET3 ethernet driver"
depends on PCI && INET depends on PCI && INET
depends on !(PAGE_SIZE_64KB || ARM64_64K_PAGES || \
IA64_PAGE_SIZE_64KB || MICROBLAZE_64K_PAGES || \
PARISC_PAGE_SIZE_64KB || PPC_64K_PAGES)
help help
This driver supports VMware's vmxnet3 virtual ethernet NIC. This driver supports VMware's vmxnet3 virtual ethernet NIC.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the

View file

@ -562,7 +562,7 @@ static void el3_common_remove (struct net_device *dev)
} }
#ifdef CONFIG_EISA #ifdef CONFIG_EISA
static int __init el3_eisa_probe (struct device *device) static int el3_eisa_probe(struct device *device)
{ {
short i; short i;
int ioaddr, irq, if_port; int ioaddr, irq, if_port;

View file

@ -907,7 +907,7 @@ static struct eisa_device_id vortex_eisa_ids[] = {
}; };
MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids); MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);
static int __init vortex_eisa_probe(struct device *device) static int vortex_eisa_probe(struct device *device)
{ {
void __iomem *ioaddr; void __iomem *ioaddr;
struct eisa_device *edev; struct eisa_device *edev;

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