mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
Merge branch 'android-4.4' of https://android.googlesource.com/kernel/common
* android-4.4: (284 commits) ANDROID: fix binder change in merge of 4.4.183 Linux 4.4.189 x86/speculation/swapgs: Exclude ATOMs from speculation through SWAPGS x86/entry/64: Use JMP instead of JMPQ x86/speculation: Enable Spectre v1 swapgs mitigations x86/speculation: Prepare entry code for Spectre v1 swapgs mitigations x86/entry/64: Fix context tracking state warning when load_gs_index fails x86: cpufeatures: Sort feature word 7 spi: bcm2835: Fix 3-wire mode if DMA is enabled block: blk_init_allocated_queue() set q->fq as NULL in the fail case compat_ioctl: pppoe: fix PPPOEIOCSFWD handling bnx2x: Disable multi-cos feature. net/mlx5: Use reversed order when unregister devices net: sched: Fix a possible null-pointer dereference in dequeue_func() tipc: compat: allow tipc commands without arguments net: fix ifindex collision during namespace removal net: bridge: delete local fdb on device init failure atm: iphase: Fix Spectre v1 vulnerability tcp: be more careful in tcp_fragment() HID: Add quirk for HP X1200 PIXART OEM mouse ... Change-Id: Iff9f57338c67e76e96a88dfe5b19bb476c6ddda6
This commit is contained in:
@@ -243,3 +243,11 @@ Description:
|
||||
- Del: echo '[h/c]!extension' > /sys/fs/f2fs/<disk>/extension_list
|
||||
- [h] means add/del hot file extension
|
||||
- [c] means add/del cold file extension
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/unusable
|
||||
Date April 2019
|
||||
Contact: "Daniel Rosenberg" <drosen@google.com>
|
||||
Description:
|
||||
If checkpoint=disable, it displays the number of blocks that are unusable.
|
||||
If checkpoint=enable it displays the enumber of blocks that would be unusable
|
||||
if checkpoint=disable were to be set.
|
||||
|
||||
@@ -4,6 +4,7 @@ Required properties:
|
||||
- compatible: Should be one of the following:
|
||||
- "microchip,mcp2510" for MCP2510.
|
||||
- "microchip,mcp2515" for MCP2515.
|
||||
- "microchip,mcp25625" for MCP25625.
|
||||
- reg: SPI chip select.
|
||||
- clocks: The clock feeding the CAN controller.
|
||||
- interrupt-parent: The parent interrupt controller.
|
||||
|
||||
@@ -214,11 +214,22 @@ fsync_mode=%s Control the policy of fsync. Currently supports "posix",
|
||||
non-atomic files likewise "nobarrier" mount option.
|
||||
test_dummy_encryption Enable dummy encryption, which provides a fake fscrypt
|
||||
context. The fake fscrypt context is used by xfstests.
|
||||
checkpoint=%s Set to "disable" to turn off checkpointing. Set to "enable"
|
||||
checkpoint=%s[:%u[%]] Set to "disable" to turn off checkpointing. Set to "enable"
|
||||
to reenable checkpointing. Is enabled by default. While
|
||||
disabled, any unmounting or unexpected shutdowns will cause
|
||||
the filesystem contents to appear as they did when the
|
||||
filesystem was mounted with that option.
|
||||
While mounting with checkpoint=disabled, the filesystem must
|
||||
run garbage collection to ensure that all available space can
|
||||
be used. If this takes too much time, the mount may return
|
||||
EAGAIN. You may optionally add a value to indicate how much
|
||||
of the disk you would be willing to temporarily give up to
|
||||
avoid additional garbage collection. This can be given as a
|
||||
number of blocks, or as a percent. For instance, mounting
|
||||
with checkpoint=disable:100% would always succeed, but it may
|
||||
hide up to all remaining free space. The actual space that
|
||||
would be unusable can be viewed at /sys/fs/f2fs/<disk>/unusable
|
||||
This space is reclaimed once checkpoint=enable.
|
||||
|
||||
================================================================================
|
||||
DEBUGFS ENTRIES
|
||||
@@ -246,11 +257,14 @@ Files in /sys/fs/f2fs/<devname>
|
||||
..............................................................................
|
||||
File Content
|
||||
|
||||
gc_max_sleep_time This tuning parameter controls the maximum sleep
|
||||
gc_urgent_sleep_time This parameter controls sleep time for gc_urgent.
|
||||
500 ms is set by default. See above gc_urgent.
|
||||
|
||||
gc_min_sleep_time This tuning parameter controls the minimum sleep
|
||||
time for the garbage collection thread. Time is
|
||||
in milliseconds.
|
||||
|
||||
gc_min_sleep_time This tuning parameter controls the minimum sleep
|
||||
gc_max_sleep_time This tuning parameter controls the maximum sleep
|
||||
time for the garbage collection thread. Time is
|
||||
in milliseconds.
|
||||
|
||||
@@ -270,9 +284,6 @@ Files in /sys/fs/f2fs/<devname>
|
||||
to 1, background thread starts to do GC by given
|
||||
gc_urgent_sleep_time interval.
|
||||
|
||||
gc_urgent_sleep_time This parameter controls sleep time for gc_urgent.
|
||||
500 ms is set by default. See above gc_urgent.
|
||||
|
||||
reclaim_segments This parameter controls the number of prefree
|
||||
segments to be reclaimed. If the number of prefree
|
||||
segments is larger than the number of segments
|
||||
@@ -287,7 +298,16 @@ Files in /sys/fs/f2fs/<devname>
|
||||
checkpoint is triggered, and issued during the
|
||||
checkpoint. By default, it is disabled with 0.
|
||||
|
||||
trim_sections This parameter controls the number of sections
|
||||
discard_granularity This parameter controls the granularity of discard
|
||||
command size. It will issue discard commands iif
|
||||
the size is larger than given granularity. Its
|
||||
unit size is 4KB, and 4 (=16KB) is set by default.
|
||||
The maximum value is 128 (=512KB).
|
||||
|
||||
reserved_blocks This parameter indicates the number of blocks that
|
||||
f2fs reserves internally for root.
|
||||
|
||||
batched_trim_sections This parameter controls the number of sections
|
||||
to be trimmed out in batch mode when FITRIM
|
||||
conducts. 32 sections is set by default.
|
||||
|
||||
@@ -309,11 +329,35 @@ Files in /sys/fs/f2fs/<devname>
|
||||
the number is less than this value, it triggers
|
||||
in-place-updates.
|
||||
|
||||
min_seq_blocks This parameter controls the threshold to serialize
|
||||
write IOs issued by multiple threads in parallel.
|
||||
|
||||
min_hot_blocks This parameter controls the threshold to allocate
|
||||
a hot data log for pending data blocks to write.
|
||||
|
||||
min_ssr_sections This parameter adds the threshold when deciding
|
||||
SSR block allocation. If this is large, SSR mode
|
||||
will be enabled early.
|
||||
|
||||
ram_thresh This parameter controls the memory footprint used
|
||||
by free nids and cached nat entries. By default,
|
||||
10 is set, which indicates 10 MB / 1 GB RAM.
|
||||
|
||||
ra_nid_pages When building free nids, F2FS reads NAT blocks
|
||||
ahead for speed up. Default is 0.
|
||||
|
||||
dirty_nats_ratio Given dirty ratio of cached nat entries, F2FS
|
||||
determines flushing them in background.
|
||||
|
||||
max_victim_search This parameter controls the number of trials to
|
||||
find a victim segment when conducting SSR and
|
||||
cleaning operations. The default value is 4096
|
||||
which covers 8GB block address range.
|
||||
|
||||
migration_granularity For large-sized sections, F2FS can stop GC given
|
||||
this granularity instead of reclaiming entire
|
||||
section.
|
||||
|
||||
dir_level This parameter controls the directory level to
|
||||
support large directory. If a directory has a
|
||||
number of files, it can reduce the file lookup
|
||||
@@ -321,9 +365,53 @@ Files in /sys/fs/f2fs/<devname>
|
||||
Otherwise, it needs to decrease this value to
|
||||
reduce the space overhead. The default value is 0.
|
||||
|
||||
ram_thresh This parameter controls the memory footprint used
|
||||
by free nids and cached nat entries. By default,
|
||||
10 is set, which indicates 10 MB / 1 GB RAM.
|
||||
cp_interval F2FS tries to do checkpoint periodically, 60 secs
|
||||
by default.
|
||||
|
||||
idle_interval F2FS detects system is idle, if there's no F2FS
|
||||
operations during given interval, 5 secs by
|
||||
default.
|
||||
|
||||
discard_idle_interval F2FS detects the discard thread is idle, given
|
||||
time interval. Default is 5 secs.
|
||||
|
||||
gc_idle_interval F2FS detects the GC thread is idle, given time
|
||||
interval. Default is 5 secs.
|
||||
|
||||
umount_discard_timeout When unmounting the disk, F2FS waits for finishing
|
||||
queued discard commands which can take huge time.
|
||||
This gives time out for it, 5 secs by default.
|
||||
|
||||
iostat_enable This controls to enable/disable iostat in F2FS.
|
||||
|
||||
readdir_ra This enables/disabled readahead of inode blocks
|
||||
in readdir, and default is enabled.
|
||||
|
||||
gc_pin_file_thresh This indicates how many GC can be failed for the
|
||||
pinned file. If it exceeds this, F2FS doesn't
|
||||
guarantee its pinning state. 2048 trials is set
|
||||
by default.
|
||||
|
||||
extension_list This enables to change extension_list for hot/cold
|
||||
files in runtime.
|
||||
|
||||
inject_rate This controls injection rate of arbitrary faults.
|
||||
|
||||
inject_type This controls injection type of arbitrary faults.
|
||||
|
||||
dirty_segments This shows # of dirty segments.
|
||||
|
||||
lifetime_write_kbytes This shows # of data written to the disk.
|
||||
|
||||
features This shows current features enabled on F2FS.
|
||||
|
||||
current_reserved_blocks This shows # of blocks currently reserved.
|
||||
|
||||
unusable If checkpoint=disable, this shows the number of
|
||||
blocks that are unusable.
|
||||
If checkpoint=enable it shows the number of blocks
|
||||
that would be unusable if checkpoint=disable were
|
||||
to be set.
|
||||
|
||||
================================================================================
|
||||
USAGE
|
||||
@@ -656,3 +744,28 @@ algorithm.
|
||||
In order to identify whether the data in the victim segment are valid or not,
|
||||
F2FS manages a bitmap. Each bit represents the validity of a block, and the
|
||||
bitmap is composed of a bit stream covering whole blocks in main area.
|
||||
|
||||
Fallocate(2) Policy
|
||||
-------------------
|
||||
|
||||
The default policy follows the below posix rule.
|
||||
|
||||
Allocating disk space
|
||||
The default operation (i.e., mode is zero) of fallocate() allocates
|
||||
the disk space within the range specified by offset and len. The
|
||||
file size (as reported by stat(2)) will be changed if offset+len is
|
||||
greater than the file size. Any subregion within the range specified
|
||||
by offset and len that did not contain data before the call will be
|
||||
initialized to zero. This default behavior closely resembles the
|
||||
behavior of the posix_fallocate(3) library function, and is intended
|
||||
as a method of optimally implementing that function.
|
||||
|
||||
However, once F2FS receives ioctl(fd, F2FS_IOC_SET_PIN_FILE) in prior to
|
||||
fallocate(fd, DEFAULT_MODE), it allocates on-disk blocks addressess having
|
||||
zero or random data, which is useful to the below scenario where:
|
||||
1. create(fd)
|
||||
2. ioctl(fd, F2FS_IOC_SET_PIN_FILE)
|
||||
3. fallocate(fd, 0, 0, size)
|
||||
4. address = fibmap(fd, offset)
|
||||
5. open(blkdev)
|
||||
6. write(blkdev, address)
|
||||
|
||||
@@ -2225,6 +2225,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
improves system performance, but it may also
|
||||
expose users to several CPU vulnerabilities.
|
||||
Equivalent to: nopti [X86]
|
||||
nospectre_v1 [X86]
|
||||
nospectre_v2 [X86]
|
||||
spectre_v2_user=off [X86]
|
||||
spec_store_bypass_disable=off [X86]
|
||||
@@ -2558,9 +2559,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
|
||||
nohugeiomap [KNL,x86] Disable kernel huge I/O mappings.
|
||||
|
||||
nospectre_v1 [PPC] Disable mitigations for Spectre Variant 1 (bounds
|
||||
check bypass). With this option data leaks are possible
|
||||
in the system.
|
||||
nospectre_v1 [X86,PPC] Disable mitigations for Spectre Variant 1
|
||||
(bounds check bypass). With this option data leaks are
|
||||
possible in the system.
|
||||
|
||||
nospectre_v2 [X86,PPC_FSL_BOOK3E] Disable all mitigations for the Spectre variant 2
|
||||
(indirect branch prediction) vulnerability. System may
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 185
|
||||
SUBLEVEL = 189
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
|
||||
@@ -183,11 +183,6 @@ static void *__init unw_hdr_alloc_early(unsigned long sz)
|
||||
MAX_DMA_ADDRESS);
|
||||
}
|
||||
|
||||
static void *unw_hdr_alloc(unsigned long sz)
|
||||
{
|
||||
return kmalloc(sz, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void init_unwind_table(struct unwind_table *table, const char *name,
|
||||
const void *core_start, unsigned long core_size,
|
||||
const void *init_start, unsigned long init_size,
|
||||
@@ -368,6 +363,10 @@ ret_err:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
static void *unw_hdr_alloc(unsigned long sz)
|
||||
{
|
||||
return kmalloc(sz, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static struct unwind_table *last_table;
|
||||
|
||||
|
||||
@@ -344,6 +344,7 @@
|
||||
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
clock-frequency = <24000000>;
|
||||
arm,no-tick-in-suspend;
|
||||
};
|
||||
|
||||
display-subsystem {
|
||||
|
||||
@@ -1479,6 +1479,8 @@ static __init void da850_evm_init(void)
|
||||
if (ret)
|
||||
pr_warn("%s: dsp/rproc registration failed: %d\n",
|
||||
__func__, ret);
|
||||
|
||||
regulator_has_full_constraints();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||||
|
||||
@@ -660,6 +660,9 @@ static struct platform_device da8xx_lcdc_device = {
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(da8xx_lcdc_resources),
|
||||
.resource = da8xx_lcdc_resources,
|
||||
.dev = {
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
}
|
||||
};
|
||||
|
||||
int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata)
|
||||
|
||||
@@ -430,7 +430,7 @@ static void omap3_prm_reconfigure_io_chain(void)
|
||||
* registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
|
||||
* No return value.
|
||||
*/
|
||||
static void __init omap3xxx_prm_enable_io_wakeup(void)
|
||||
static void omap3xxx_prm_enable_io_wakeup(void)
|
||||
{
|
||||
if (prm_features & PRM_HAS_IO_WAKEUP)
|
||||
omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
|
||||
|
||||
@@ -131,7 +131,7 @@ static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
|
||||
} while (1);
|
||||
|
||||
idma->state = ~DMA_ST_AB;
|
||||
disable_irq(irq);
|
||||
disable_irq_nosync(irq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -174,6 +174,9 @@ static void iomd_enable_dma(unsigned int chan, dma_t *dma)
|
||||
DMA_FROM_DEVICE : DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
idma->dma_addr = idma->dma.sg->dma_address;
|
||||
idma->dma_len = idma->dma.sg->length;
|
||||
|
||||
iomd_writeb(DMA_CR_C, dma_base + CR);
|
||||
idma->state = DMA_ST_AB;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ static int sha1_ce_finup(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len, u8 *out)
|
||||
{
|
||||
struct sha1_ce_state *sctx = shash_desc_ctx(desc);
|
||||
bool finalize = !sctx->sst.count && !(len % SHA1_BLOCK_SIZE);
|
||||
bool finalize = !sctx->sst.count && !(len % SHA1_BLOCK_SIZE) && len;
|
||||
|
||||
/*
|
||||
* Allow the asm code to perform the finalization if there is no
|
||||
|
||||
@@ -52,7 +52,7 @@ static int sha256_ce_finup(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len, u8 *out)
|
||||
{
|
||||
struct sha256_ce_state *sctx = shash_desc_ctx(desc);
|
||||
bool finalize = !sctx->sst.count && !(len % SHA256_BLOCK_SIZE);
|
||||
bool finalize = !sctx->sst.count && !(len % SHA256_BLOCK_SIZE) && len;
|
||||
|
||||
/*
|
||||
* Allow the asm code to perform the finalization if there is no
|
||||
|
||||
@@ -46,9 +46,10 @@
|
||||
|
||||
/* CPU feature register tracking */
|
||||
enum ftr_type {
|
||||
FTR_EXACT, /* Use a predefined safe value */
|
||||
FTR_LOWER_SAFE, /* Smaller value is safe */
|
||||
FTR_HIGHER_SAFE,/* Bigger value is safe */
|
||||
FTR_EXACT, /* Use a predefined safe value */
|
||||
FTR_LOWER_SAFE, /* Smaller value is safe */
|
||||
FTR_HIGHER_SAFE, /* Bigger value is safe */
|
||||
FTR_HIGHER_OR_ZERO_SAFE, /* Bigger value is safe, but 0 is biggest */
|
||||
};
|
||||
|
||||
#define FTR_STRICT true /* SANITY check strict matching required */
|
||||
|
||||
@@ -141,10 +141,14 @@ static int __init acpi_fadt_sanity_check(void)
|
||||
*/
|
||||
if (table->revision < 5 ||
|
||||
(table->revision == 5 && fadt->minor_revision < 1)) {
|
||||
pr_err("Unsupported FADT revision %d.%d, should be 5.1+\n",
|
||||
pr_err(FW_BUG "Unsupported FADT revision %d.%d, should be 5.1+\n",
|
||||
table->revision, fadt->minor_revision);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
||||
if (!fadt->arm_boot_flags) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
pr_err("FADT has ARM boot flags set, assuming 5.1\n");
|
||||
}
|
||||
|
||||
if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {
|
||||
|
||||
@@ -138,10 +138,12 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
|
||||
};
|
||||
|
||||
static struct arm64_ftr_bits ftr_ctr[] = {
|
||||
U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RAO */
|
||||
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 3, 0),
|
||||
U_ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0), /* CWG */
|
||||
U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), /* ERG */
|
||||
U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RES1 */
|
||||
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 30, 1, 0),
|
||||
U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 29, 1, 1), /* DIC */
|
||||
U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 28, 1, 1), /* IDC */
|
||||
U_ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_OR_ZERO_SAFE, 24, 4, 0), /* CWG */
|
||||
U_ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_OR_ZERO_SAFE, 20, 4, 0), /* ERG */
|
||||
U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */
|
||||
/*
|
||||
* Linux can handle differing I-cache policies. Userspace JITs will
|
||||
@@ -352,6 +354,10 @@ static s64 arm64_ftr_safe_value(struct arm64_ftr_bits *ftrp, s64 new, s64 cur)
|
||||
case FTR_LOWER_SAFE:
|
||||
ret = new < cur ? new : cur;
|
||||
break;
|
||||
case FTR_HIGHER_OR_ZERO_SAFE:
|
||||
if (!cur || !new)
|
||||
break;
|
||||
/* Fallthrough */
|
||||
case FTR_HIGHER_SAFE:
|
||||
ret = new > cur ? new : cur;
|
||||
break;
|
||||
|
||||
@@ -66,6 +66,8 @@ OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \
|
||||
$(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
HOSTCFLAGS_calc_vmlinuz_load_addr.o += $(LINUXINCLUDE)
|
||||
|
||||
# Calculate the load address of the compressed kernel image
|
||||
hostprogs-y := calc_vmlinuz_load_addr
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../../../include/linux/sizes.h"
|
||||
#include <linux/sizes.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#define AR933X_UART_CS_PARITY_S 0
|
||||
#define AR933X_UART_CS_PARITY_M 0x3
|
||||
#define AR933X_UART_CS_PARITY_NONE 0
|
||||
#define AR933X_UART_CS_PARITY_ODD 1
|
||||
#define AR933X_UART_CS_PARITY_EVEN 2
|
||||
#define AR933X_UART_CS_PARITY_ODD 2
|
||||
#define AR933X_UART_CS_PARITY_EVEN 3
|
||||
#define AR933X_UART_CS_IF_MODE_S 2
|
||||
#define AR933X_UART_CS_IF_MODE_M 0x3
|
||||
#define AR933X_UART_CS_IF_MODE_NONE 0
|
||||
|
||||
@@ -10,14 +10,6 @@
|
||||
#ifndef __ASM_SGIDEFS_H
|
||||
#define __ASM_SGIDEFS_H
|
||||
|
||||
/*
|
||||
* Using a Linux compiler for building Linux seems logic but not to
|
||||
* everybody.
|
||||
*/
|
||||
#ifndef __linux__
|
||||
#error Use a Linux compiler or give up.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definitions for the ISA levels
|
||||
*
|
||||
|
||||
@@ -160,8 +160,9 @@ static int ltq_eiu_settype(struct irq_data *d, unsigned int type)
|
||||
if (edge)
|
||||
irq_set_handler(d->hwirq, handle_edge_irq);
|
||||
|
||||
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
|
||||
(val << (i * 4)), LTQ_EIU_EXIN_C);
|
||||
ltq_eiu_w32((ltq_eiu_r32(LTQ_EIU_EXIN_C) &
|
||||
(~(7 << (i * 4)))) | (val << (i * 4)),
|
||||
LTQ_EIU_EXIN_C);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +156,9 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
if ((addr & (sizeof(unsigned long)-1)) ||
|
||||
addr >= sizeof(struct pt_regs))
|
||||
break;
|
||||
if (addr == PT_IAOQ0 || addr == PT_IAOQ1) {
|
||||
data |= 3; /* ensure userspace privilege */
|
||||
}
|
||||
if ((addr >= PT_GR1 && addr <= PT_GR31) ||
|
||||
addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
|
||||
(addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
|
||||
@@ -189,16 +192,18 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
|
||||
static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
|
||||
{
|
||||
if (offset < 0)
|
||||
return sizeof(struct pt_regs);
|
||||
else if (offset <= 32*4) /* gr[0..31] */
|
||||
return offset * 2 + 4;
|
||||
else if (offset <= 32*4+32*8) /* gr[0..31] + fr[0..31] */
|
||||
return offset + 32*4;
|
||||
else if (offset < sizeof(struct pt_regs)/2 + 32*4)
|
||||
return offset * 2 + 4 - 32*8;
|
||||
compat_ulong_t pos;
|
||||
|
||||
if (offset < 32*4) /* gr[0..31] */
|
||||
pos = offset * 2 + 4;
|
||||
else if (offset < 32*4+32*8) /* fr[0] ... fr[31] */
|
||||
pos = (offset - 32*4) + PT_FR0;
|
||||
else if (offset < sizeof(struct pt_regs)/2 + 32*4) /* sr[0] ... ipsw */
|
||||
pos = (offset - 32*4 - 32*8) * 2 + PT_SR0 + 4;
|
||||
else
|
||||
return sizeof(struct pt_regs);
|
||||
pos = sizeof(struct pt_regs);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
@@ -242,9 +247,12 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
addr = translate_usr_offset(addr);
|
||||
if (addr >= sizeof(struct pt_regs))
|
||||
break;
|
||||
if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) {
|
||||
data |= 3; /* ensure userspace privilege */
|
||||
}
|
||||
if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
|
||||
/* Special case, fp regs are 64 bits anyway */
|
||||
*(__u64 *) ((char *) task_regs(child) + addr) = data;
|
||||
*(__u32 *) ((char *) task_regs(child) + addr) = data;
|
||||
ret = 0;
|
||||
}
|
||||
else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
|
||||
|
||||
@@ -363,10 +363,19 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
|
||||
NULL, &hugepage_shift);
|
||||
if (!ptep)
|
||||
return token;
|
||||
WARN_ON(hugepage_shift);
|
||||
pa = pte_pfn(*ptep) << PAGE_SHIFT;
|
||||
|
||||
return pa | (token & (PAGE_SIZE-1));
|
||||
pa = pte_pfn(*ptep);
|
||||
|
||||
/* On radix we can do hugepage mappings for io, so handle that */
|
||||
if (hugepage_shift) {
|
||||
pa <<= hugepage_shift;
|
||||
pa |= token & ((1ul << hugepage_shift) - 1);
|
||||
} else {
|
||||
pa <<= PAGE_SHIFT;
|
||||
pa |= token & (PAGE_SIZE - 1);
|
||||
}
|
||||
|
||||
return pa;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1719,7 +1719,7 @@ handle_page_fault:
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_page_fault
|
||||
cmpdi r3,0
|
||||
beq+ 12f
|
||||
beq+ ret_from_except_lite
|
||||
bl save_nvgprs
|
||||
mr r5,r3
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
@@ -1734,7 +1734,12 @@ handle_dabr_fault:
|
||||
ld r5,_DSISR(r1)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl do_break
|
||||
12: b ret_from_except_lite
|
||||
/*
|
||||
* do_break() may have changed the NV GPRS while handling a breakpoint.
|
||||
* If so, we need to restore them with their updated values. Don't use
|
||||
* ret_from_except_lite here.
|
||||
*/
|
||||
b ret_from_except
|
||||
|
||||
|
||||
/* We have a page fault that hash_page could handle but HV refused
|
||||
|
||||
@@ -45,6 +45,8 @@ static unsigned int pci_parse_of_flags(u32 addr0, int bridge)
|
||||
if (addr0 & 0x02000000) {
|
||||
flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
|
||||
flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
|
||||
if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
|
||||
flags |= IORESOURCE_MEM_64;
|
||||
flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
|
||||
if (addr0 & 0x40000000)
|
||||
flags |= IORESOURCE_PREFETCH
|
||||
|
||||
@@ -1261,6 +1261,9 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
|
||||
goto bad;
|
||||
|
||||
if (MSR_TM_ACTIVE(msr_hi<<32)) {
|
||||
/* Trying to start TM on non TM system */
|
||||
if (!cpu_has_feature(CPU_FTR_TM))
|
||||
goto bad;
|
||||
/* We only recheckpoint on return if we're
|
||||
* transaction.
|
||||
*/
|
||||
|
||||
@@ -695,6 +695,11 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
|
||||
if (MSR_TM_ACTIVE(msr)) {
|
||||
/* We recheckpoint on return. */
|
||||
struct ucontext __user *uc_transact;
|
||||
|
||||
/* Trying to start TM on non TM system */
|
||||
if (!cpu_has_feature(CPU_FTR_TM))
|
||||
goto badframe;
|
||||
|
||||
if (__get_user(uc_transact, &uc->uc_link))
|
||||
goto badframe;
|
||||
if (restore_tm_sigcontexts(regs, &uc->uc_mcontext,
|
||||
|
||||
@@ -23,11 +23,19 @@
|
||||
#define SL_IBAT2 0x48
|
||||
#define SL_DBAT3 0x50
|
||||
#define SL_IBAT3 0x58
|
||||
#define SL_TB 0x60
|
||||
#define SL_R2 0x68
|
||||
#define SL_CR 0x6c
|
||||
#define SL_LR 0x70
|
||||
#define SL_R12 0x74 /* r12 to r31 */
|
||||
#define SL_DBAT4 0x60
|
||||
#define SL_IBAT4 0x68
|
||||
#define SL_DBAT5 0x70
|
||||
#define SL_IBAT5 0x78
|
||||
#define SL_DBAT6 0x80
|
||||
#define SL_IBAT6 0x88
|
||||
#define SL_DBAT7 0x90
|
||||
#define SL_IBAT7 0x98
|
||||
#define SL_TB 0xa0
|
||||
#define SL_R2 0xa8
|
||||
#define SL_CR 0xac
|
||||
#define SL_LR 0xb0
|
||||
#define SL_R12 0xb4 /* r12 to r31 */
|
||||
#define SL_SIZE (SL_R12 + 80)
|
||||
|
||||
.section .data
|
||||
@@ -112,6 +120,41 @@ _GLOBAL(swsusp_arch_suspend)
|
||||
mfibatl r4,3
|
||||
stw r4,SL_IBAT3+4(r11)
|
||||
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
mfspr r4,SPRN_DBAT4U
|
||||
stw r4,SL_DBAT4(r11)
|
||||
mfspr r4,SPRN_DBAT4L
|
||||
stw r4,SL_DBAT4+4(r11)
|
||||
mfspr r4,SPRN_DBAT5U
|
||||
stw r4,SL_DBAT5(r11)
|
||||
mfspr r4,SPRN_DBAT5L
|
||||
stw r4,SL_DBAT5+4(r11)
|
||||
mfspr r4,SPRN_DBAT6U
|
||||
stw r4,SL_DBAT6(r11)
|
||||
mfspr r4,SPRN_DBAT6L
|
||||
stw r4,SL_DBAT6+4(r11)
|
||||
mfspr r4,SPRN_DBAT7U
|
||||
stw r4,SL_DBAT7(r11)
|
||||
mfspr r4,SPRN_DBAT7L
|
||||
stw r4,SL_DBAT7+4(r11)
|
||||
mfspr r4,SPRN_IBAT4U
|
||||
stw r4,SL_IBAT4(r11)
|
||||
mfspr r4,SPRN_IBAT4L
|
||||
stw r4,SL_IBAT4+4(r11)
|
||||
mfspr r4,SPRN_IBAT5U
|
||||
stw r4,SL_IBAT5(r11)
|
||||
mfspr r4,SPRN_IBAT5L
|
||||
stw r4,SL_IBAT5+4(r11)
|
||||
mfspr r4,SPRN_IBAT6U
|
||||
stw r4,SL_IBAT6(r11)
|
||||
mfspr r4,SPRN_IBAT6L
|
||||
stw r4,SL_IBAT6+4(r11)
|
||||
mfspr r4,SPRN_IBAT7U
|
||||
stw r4,SL_IBAT7(r11)
|
||||
mfspr r4,SPRN_IBAT7L
|
||||
stw r4,SL_IBAT7+4(r11)
|
||||
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
|
||||
|
||||
#if 0
|
||||
/* Backup various CPU config stuffs */
|
||||
bl __save_cpu_setup
|
||||
@@ -277,27 +320,41 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
||||
mtibatu 3,r4
|
||||
lwz r4,SL_IBAT3+4(r11)
|
||||
mtibatl 3,r4
|
||||
#endif
|
||||
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
li r4,0
|
||||
lwz r4,SL_DBAT4(r11)
|
||||
mtspr SPRN_DBAT4U,r4
|
||||
lwz r4,SL_DBAT4+4(r11)
|
||||
mtspr SPRN_DBAT4L,r4
|
||||
lwz r4,SL_DBAT5(r11)
|
||||
mtspr SPRN_DBAT5U,r4
|
||||
lwz r4,SL_DBAT5+4(r11)
|
||||
mtspr SPRN_DBAT5L,r4
|
||||
lwz r4,SL_DBAT6(r11)
|
||||
mtspr SPRN_DBAT6U,r4
|
||||
lwz r4,SL_DBAT6+4(r11)
|
||||
mtspr SPRN_DBAT6L,r4
|
||||
lwz r4,SL_DBAT7(r11)
|
||||
mtspr SPRN_DBAT7U,r4
|
||||
lwz r4,SL_DBAT7+4(r11)
|
||||
mtspr SPRN_DBAT7L,r4
|
||||
lwz r4,SL_IBAT4(r11)
|
||||
mtspr SPRN_IBAT4U,r4
|
||||
lwz r4,SL_IBAT4+4(r11)
|
||||
mtspr SPRN_IBAT4L,r4
|
||||
lwz r4,SL_IBAT5(r11)
|
||||
mtspr SPRN_IBAT5U,r4
|
||||
lwz r4,SL_IBAT5+4(r11)
|
||||
mtspr SPRN_IBAT5L,r4
|
||||
lwz r4,SL_IBAT6(r11)
|
||||
mtspr SPRN_IBAT6U,r4
|
||||
lwz r4,SL_IBAT6+4(r11)
|
||||
mtspr SPRN_IBAT6L,r4
|
||||
lwz r4,SL_IBAT7(r11)
|
||||
mtspr SPRN_IBAT7U,r4
|
||||
lwz r4,SL_IBAT7+4(r11)
|
||||
mtspr SPRN_IBAT7L,r4
|
||||
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
|
||||
#endif
|
||||
|
||||
/* Flush all TLBs */
|
||||
lis r4,0x1000
|
||||
|
||||
@@ -37,10 +37,18 @@
|
||||
#define SL_IBAT2 0x48
|
||||
#define SL_DBAT3 0x50
|
||||
#define SL_IBAT3 0x58
|
||||
#define SL_TB 0x60
|
||||
#define SL_R2 0x68
|
||||
#define SL_CR 0x6c
|
||||
#define SL_R12 0x70 /* r12 to r31 */
|
||||
#define SL_DBAT4 0x60
|
||||
#define SL_IBAT4 0x68
|
||||
#define SL_DBAT5 0x70
|
||||
#define SL_IBAT5 0x78
|
||||
#define SL_DBAT6 0x80
|
||||
#define SL_IBAT6 0x88
|
||||
#define SL_DBAT7 0x90
|
||||
#define SL_IBAT7 0x98
|
||||
#define SL_TB 0xa0
|
||||
#define SL_R2 0xa8
|
||||
#define SL_CR 0xac
|
||||
#define SL_R12 0xb0 /* r12 to r31 */
|
||||
#define SL_SIZE (SL_R12 + 80)
|
||||
|
||||
.section .text
|
||||
@@ -125,6 +133,41 @@ _GLOBAL(low_sleep_handler)
|
||||
mfibatl r4,3
|
||||
stw r4,SL_IBAT3+4(r1)
|
||||
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
mfspr r4,SPRN_DBAT4U
|
||||
stw r4,SL_DBAT4(r1)
|
||||
mfspr r4,SPRN_DBAT4L
|
||||
stw r4,SL_DBAT4+4(r1)
|
||||
mfspr r4,SPRN_DBAT5U
|
||||
stw r4,SL_DBAT5(r1)
|
||||
mfspr r4,SPRN_DBAT5L
|
||||
stw r4,SL_DBAT5+4(r1)
|
||||
mfspr r4,SPRN_DBAT6U
|
||||
stw r4,SL_DBAT6(r1)
|
||||
mfspr r4,SPRN_DBAT6L
|
||||
stw r4,SL_DBAT6+4(r1)
|
||||
mfspr r4,SPRN_DBAT7U
|
||||
stw r4,SL_DBAT7(r1)
|
||||
mfspr r4,SPRN_DBAT7L
|
||||
stw r4,SL_DBAT7+4(r1)
|
||||
mfspr r4,SPRN_IBAT4U
|
||||
stw r4,SL_IBAT4(r1)
|
||||
mfspr r4,SPRN_IBAT4L
|
||||
stw r4,SL_IBAT4+4(r1)
|
||||
mfspr r4,SPRN_IBAT5U
|
||||
stw r4,SL_IBAT5(r1)
|
||||
mfspr r4,SPRN_IBAT5L
|
||||
stw r4,SL_IBAT5+4(r1)
|
||||
mfspr r4,SPRN_IBAT6U
|
||||
stw r4,SL_IBAT6(r1)
|
||||
mfspr r4,SPRN_IBAT6L
|
||||
stw r4,SL_IBAT6+4(r1)
|
||||
mfspr r4,SPRN_IBAT7U
|
||||
stw r4,SL_IBAT7(r1)
|
||||
mfspr r4,SPRN_IBAT7L
|
||||
stw r4,SL_IBAT7+4(r1)
|
||||
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
|
||||
|
||||
/* Backup various CPU config stuffs */
|
||||
bl __save_cpu_setup
|
||||
|
||||
@@ -325,22 +368,37 @@ grackle_wake_up:
|
||||
mtibatl 3,r4
|
||||
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
li r4,0
|
||||
lwz r4,SL_DBAT4(r1)
|
||||
mtspr SPRN_DBAT4U,r4
|
||||
lwz r4,SL_DBAT4+4(r1)
|
||||
mtspr SPRN_DBAT4L,r4
|
||||
lwz r4,SL_DBAT5(r1)
|
||||
mtspr SPRN_DBAT5U,r4
|
||||
lwz r4,SL_DBAT5+4(r1)
|
||||
mtspr SPRN_DBAT5L,r4
|
||||
lwz r4,SL_DBAT6(r1)
|
||||
mtspr SPRN_DBAT6U,r4
|
||||
lwz r4,SL_DBAT6+4(r1)
|
||||
mtspr SPRN_DBAT6L,r4
|
||||
lwz r4,SL_DBAT7(r1)
|
||||
mtspr SPRN_DBAT7U,r4
|
||||
lwz r4,SL_DBAT7+4(r1)
|
||||
mtspr SPRN_DBAT7L,r4
|
||||
lwz r4,SL_IBAT4(r1)
|
||||
mtspr SPRN_IBAT4U,r4
|
||||
lwz r4,SL_IBAT4+4(r1)
|
||||
mtspr SPRN_IBAT4L,r4
|
||||
lwz r4,SL_IBAT5(r1)
|
||||
mtspr SPRN_IBAT5U,r4
|
||||
lwz r4,SL_IBAT5+4(r1)
|
||||
mtspr SPRN_IBAT5L,r4
|
||||
lwz r4,SL_IBAT6(r1)
|
||||
mtspr SPRN_IBAT6U,r4
|
||||
lwz r4,SL_IBAT6+4(r1)
|
||||
mtspr SPRN_IBAT6L,r4
|
||||
lwz r4,SL_IBAT7(r1)
|
||||
mtspr SPRN_IBAT7U,r4
|
||||
lwz r4,SL_IBAT7+4(r1)
|
||||
mtspr SPRN_IBAT7L,r4
|
||||
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)
|
||||
|
||||
mtdcr(uic->dcrbase + UIC_PR, pr);
|
||||
mtdcr(uic->dcrbase + UIC_TR, tr);
|
||||
mtdcr(uic->dcrbase + UIC_SR, ~mask);
|
||||
|
||||
raw_spin_unlock_irqrestore(&uic->lock, flags);
|
||||
|
||||
|
||||
@@ -51,6 +51,18 @@ static inline int test_facility(unsigned long nr)
|
||||
return __test_facility(nr, &S390_lowcore.stfle_fac_list);
|
||||
}
|
||||
|
||||
static inline unsigned long __stfle_asm(u64 *stfle_fac_list, int size)
|
||||
{
|
||||
register unsigned long reg0 asm("0") = size - 1;
|
||||
|
||||
asm volatile(
|
||||
".insn s,0xb2b00000,0(%1)" /* stfle */
|
||||
: "+d" (reg0)
|
||||
: "a" (stfle_fac_list)
|
||||
: "memory", "cc");
|
||||
return reg0;
|
||||
}
|
||||
|
||||
/**
|
||||
* stfle - Store facility list extended
|
||||
* @stfle_fac_list: array where facility list can be stored
|
||||
@@ -70,13 +82,8 @@ static inline void stfle(u64 *stfle_fac_list, int size)
|
||||
memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
|
||||
if (S390_lowcore.stfl_fac_list & 0x01000000) {
|
||||
/* More facility bits available with stfle */
|
||||
register unsigned long reg0 asm("0") = size - 1;
|
||||
|
||||
asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */
|
||||
: "+d" (reg0)
|
||||
: "a" (stfle_fac_list)
|
||||
: "memory", "cc");
|
||||
nr = (reg0 + 1) * 8; /* # bytes stored by stfle */
|
||||
nr = __stfle_asm(stfle_fac_list, size);
|
||||
nr = min_t(unsigned long, (nr + 1) * 8, size * 8);
|
||||
}
|
||||
memset((char *) stfle_fac_list + nr, 0, size * 8 - nr);
|
||||
preempt_enable();
|
||||
|
||||
@@ -370,7 +370,11 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
|
||||
|
||||
#define ioremap_nocache ioremap
|
||||
#define ioremap_uc ioremap
|
||||
#define iounmap __iounmap
|
||||
|
||||
static inline void iounmap(void __iomem *addr)
|
||||
{
|
||||
__iounmap(addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
|
||||
|
||||
@@ -42,7 +42,7 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
|
||||
* when the new ->mm is used for the first time.
|
||||
*/
|
||||
__switch_mm(&new->context.id);
|
||||
down_write(&new->mmap_sem);
|
||||
down_write_nested(&new->mmap_sem, 1);
|
||||
uml_setup_stubs(new);
|
||||
up_write(&new->mmap_sem);
|
||||
}
|
||||
|
||||
@@ -382,6 +382,7 @@ CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
|
||||
CONFIG_USB_CONFIGFS_UEVENT=y
|
||||
CONFIG_USB_CONFIGFS_F_MIDI=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_TEST=y
|
||||
CONFIG_VIRTIO_PCI=y
|
||||
CONFIG_VIRTIO_BALLOON=y
|
||||
CONFIG_VIRTIO_INPUT=y
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <asm/cpufeatures.h>
|
||||
|
||||
/*
|
||||
|
||||
x86 function call convention, 64-bit:
|
||||
@@ -199,6 +201,23 @@ For 32-bit we have the following conventions - kernel is built with
|
||||
.byte 0xf1
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Mitigate Spectre v1 for conditional swapgs code paths.
|
||||
*
|
||||
* FENCE_SWAPGS_USER_ENTRY is used in the user entry swapgs code path, to
|
||||
* prevent a speculative swapgs when coming from kernel space.
|
||||
*
|
||||
* FENCE_SWAPGS_KERNEL_ENTRY is used in the kernel entry non-swapgs code path,
|
||||
* to prevent the swapgs from getting speculatively skipped when coming from
|
||||
* user space.
|
||||
*/
|
||||
.macro FENCE_SWAPGS_USER_ENTRY
|
||||
ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_USER
|
||||
.endm
|
||||
.macro FENCE_SWAPGS_KERNEL_ENTRY
|
||||
ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_KERNEL
|
||||
.endm
|
||||
|
||||
#else /* CONFIG_X86_64 */
|
||||
|
||||
/*
|
||||
|
||||
@@ -578,6 +578,7 @@ END(irq_entries_start)
|
||||
* tracking that we're in kernel mode.
|
||||
*/
|
||||
SWAPGS
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
SWITCH_KERNEL_CR3
|
||||
|
||||
/*
|
||||
@@ -593,8 +594,10 @@ END(irq_entries_start)
|
||||
#ifdef CONFIG_CONTEXT_TRACKING
|
||||
call enter_from_user_mode
|
||||
#endif
|
||||
|
||||
jmp 2f
|
||||
1:
|
||||
FENCE_SWAPGS_KERNEL_ENTRY
|
||||
2:
|
||||
/*
|
||||
* Save previous stack pointer, optionally switch to interrupt stack.
|
||||
* irq_count is used to check if a CPU is already on an interrupt stack
|
||||
@@ -1110,6 +1113,13 @@ ENTRY(paranoid_entry)
|
||||
movq %rax, %cr3
|
||||
2:
|
||||
#endif
|
||||
/*
|
||||
* The above doesn't do an unconditional CR3 write, even in the PTI
|
||||
* case. So do an lfence to prevent GS speculation, regardless of
|
||||
* whether PTI is enabled.
|
||||
*/
|
||||
FENCE_SWAPGS_KERNEL_ENTRY
|
||||
|
||||
ret
|
||||
END(paranoid_entry)
|
||||
|
||||
@@ -1166,12 +1176,12 @@ ENTRY(error_entry)
|
||||
testb $3, CS+8(%rsp)
|
||||
jz .Lerror_kernelspace
|
||||
|
||||
.Lerror_entry_from_usermode_swapgs:
|
||||
/*
|
||||
* We entered from user mode or we're pretending to have entered
|
||||
* from user mode due to an IRET fault.
|
||||
*/
|
||||
SWAPGS
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
|
||||
.Lerror_entry_from_usermode_after_swapgs:
|
||||
/*
|
||||
@@ -1185,6 +1195,8 @@ ENTRY(error_entry)
|
||||
#endif
|
||||
ret
|
||||
|
||||
.Lerror_entry_done_lfence:
|
||||
FENCE_SWAPGS_KERNEL_ENTRY
|
||||
.Lerror_entry_done:
|
||||
TRACE_IRQS_OFF
|
||||
ret
|
||||
@@ -1203,14 +1215,16 @@ ENTRY(error_entry)
|
||||
cmpq %rax, RIP+8(%rsp)
|
||||
je .Lbstep_iret
|
||||
cmpq $gs_change, RIP+8(%rsp)
|
||||
jne .Lerror_entry_done
|
||||
jne .Lerror_entry_done_lfence
|
||||
|
||||
/*
|
||||
* hack: gs_change can fail with user gsbase. If this happens, fix up
|
||||
* gsbase and proceed. We'll fix up the exception and land in
|
||||
* gs_change's error handler with kernel gsbase.
|
||||
*/
|
||||
jmp .Lerror_entry_from_usermode_swapgs
|
||||
SWAPGS
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
jmp .Lerror_entry_done
|
||||
|
||||
.Lbstep_iret:
|
||||
/* Fix truncated RIP */
|
||||
@@ -1223,6 +1237,7 @@ ENTRY(error_entry)
|
||||
* Switch to kernel gsbase:
|
||||
*/
|
||||
SWAPGS
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
|
||||
/*
|
||||
* Pretend that the exception came from user mode: set up pt_regs
|
||||
@@ -1319,6 +1334,7 @@ ENTRY(nmi)
|
||||
* to switch CR3 here.
|
||||
*/
|
||||
cld
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
movq %rsp, %rdx
|
||||
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
|
||||
pushq 5*8(%rdx) /* pt_regs->ss */
|
||||
@@ -1607,6 +1623,7 @@ end_repeat_nmi:
|
||||
movq %rax, %cr3
|
||||
2:
|
||||
#endif
|
||||
FENCE_SWAPGS_KERNEL_ENTRY
|
||||
|
||||
/* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
|
||||
call do_nmi
|
||||
|
||||
@@ -44,7 +44,7 @@ static inline void generic_apic_probe(void)
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
|
||||
extern unsigned int apic_verbosity;
|
||||
extern int apic_verbosity;
|
||||
extern int local_apic_timer_c2_ok;
|
||||
|
||||
extern int disable_apic;
|
||||
|
||||
@@ -192,17 +192,17 @@
|
||||
#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
|
||||
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
|
||||
|
||||
#define X86_FEATURE_FENCE_SWAPGS_USER ( 7*32+10) /* "" LFENCE in user entry SWAPGS path */
|
||||
#define X86_FEATURE_FENCE_SWAPGS_KERNEL ( 7*32+11) /* "" LFENCE in kernel entry SWAPGS path */
|
||||
|
||||
#define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
|
||||
#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
|
||||
|
||||
#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
|
||||
#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
|
||||
|
||||
#define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
|
||||
#define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */
|
||||
|
||||
/* Because the ALTERNATIVE scheme is for members of the X86_FEATURE club... */
|
||||
#define X86_FEATURE_KAISER ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o nokaiser */
|
||||
#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
|
||||
|
||||
#define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled*/
|
||||
#define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
|
||||
@@ -215,6 +215,7 @@
|
||||
#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
|
||||
#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
|
||||
#define X86_FEATURE_IBRS_ENHANCED ( 7*32+30) /* Enhanced IBRS */
|
||||
#define X86_FEATURE_KAISER ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o nokaiser */
|
||||
|
||||
/* Virtualization flags: Linux defined, word 8 */
|
||||
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
|
||||
@@ -338,5 +339,6 @@
|
||||
#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
|
||||
#define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */
|
||||
#define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */
|
||||
#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
|
||||
|
||||
#endif /* _ASM_X86_CPUFEATURES_H */
|
||||
|
||||
@@ -1184,25 +1184,29 @@ enum {
|
||||
#define kvm_arch_vcpu_memslots_id(vcpu) ((vcpu)->arch.hflags & HF_SMM_MASK ? 1 : 0)
|
||||
#define kvm_memslots_for_spte_role(kvm, role) __kvm_memslots(kvm, (role).smm)
|
||||
|
||||
asmlinkage void __noreturn kvm_spurious_fault(void);
|
||||
|
||||
/*
|
||||
* Hardware virtualization extension instructions may fault if a
|
||||
* reboot turns off virtualization while processes are running.
|
||||
* Trap the fault and ignore the instruction if that happens.
|
||||
* Usually after catching the fault we just panic; during reboot
|
||||
* instead the instruction is ignored.
|
||||
*/
|
||||
asmlinkage void kvm_spurious_fault(void);
|
||||
|
||||
#define ____kvm_handle_fault_on_reboot(insn, cleanup_insn) \
|
||||
"666: " insn "\n\t" \
|
||||
"668: \n\t" \
|
||||
".pushsection .fixup, \"ax\" \n" \
|
||||
"667: \n\t" \
|
||||
cleanup_insn "\n\t" \
|
||||
"cmpb $0, kvm_rebooting \n\t" \
|
||||
"jne 668b \n\t" \
|
||||
__ASM_SIZE(push) " $666b \n\t" \
|
||||
"jmp kvm_spurious_fault \n\t" \
|
||||
".popsection \n\t" \
|
||||
_ASM_EXTABLE(666b, 667b)
|
||||
#define ____kvm_handle_fault_on_reboot(insn, cleanup_insn) \
|
||||
"666: \n\t" \
|
||||
insn "\n\t" \
|
||||
"jmp 668f \n\t" \
|
||||
"667: \n\t" \
|
||||
"call kvm_spurious_fault \n\t" \
|
||||
"668: \n\t" \
|
||||
".pushsection .fixup, \"ax\" \n\t" \
|
||||
"700: \n\t" \
|
||||
cleanup_insn "\n\t" \
|
||||
"cmpb $0, kvm_rebooting\n\t" \
|
||||
"je 667b \n\t" \
|
||||
"jmp 668b \n\t" \
|
||||
".popsection \n\t" \
|
||||
_ASM_EXTABLE(666b, 700b)
|
||||
|
||||
#define __kvm_handle_fault_on_reboot(insn) \
|
||||
____kvm_handle_fault_on_reboot(insn, "")
|
||||
|
||||
@@ -171,7 +171,7 @@ int first_system_vector = FIRST_SYSTEM_VECTOR;
|
||||
/*
|
||||
* Debug level, exported for io_apic.c
|
||||
*/
|
||||
unsigned int apic_verbosity;
|
||||
int apic_verbosity;
|
||||
|
||||
int pic_mode;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/e820.h>
|
||||
|
||||
static void __init spectre_v1_select_mitigation(void);
|
||||
static void __init spectre_v2_select_mitigation(void);
|
||||
static void __init ssb_select_mitigation(void);
|
||||
static void __init l1tf_select_mitigation(void);
|
||||
@@ -87,17 +88,11 @@ void __init check_bugs(void)
|
||||
if (boot_cpu_has(X86_FEATURE_STIBP))
|
||||
x86_spec_ctrl_mask |= SPEC_CTRL_STIBP;
|
||||
|
||||
/* Select the proper spectre mitigation before patching alternatives */
|
||||
/* Select the proper CPU mitigations before patching alternatives: */
|
||||
spectre_v1_select_mitigation();
|
||||
spectre_v2_select_mitigation();
|
||||
|
||||
/*
|
||||
* Select proper mitigation for any exposure to the Speculative Store
|
||||
* Bypass vulnerability.
|
||||
*/
|
||||
ssb_select_mitigation();
|
||||
|
||||
l1tf_select_mitigation();
|
||||
|
||||
mds_select_mitigation();
|
||||
|
||||
arch_smt_update();
|
||||
@@ -251,6 +246,98 @@ static int __init mds_cmdline(char *str)
|
||||
}
|
||||
early_param("mds", mds_cmdline);
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "Spectre V1 : " fmt
|
||||
|
||||
enum spectre_v1_mitigation {
|
||||
SPECTRE_V1_MITIGATION_NONE,
|
||||
SPECTRE_V1_MITIGATION_AUTO,
|
||||
};
|
||||
|
||||
static enum spectre_v1_mitigation spectre_v1_mitigation =
|
||||
SPECTRE_V1_MITIGATION_AUTO;
|
||||
|
||||
static const char * const spectre_v1_strings[] = {
|
||||
[SPECTRE_V1_MITIGATION_NONE] = "Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers",
|
||||
[SPECTRE_V1_MITIGATION_AUTO] = "Mitigation: usercopy/swapgs barriers and __user pointer sanitization",
|
||||
};
|
||||
|
||||
/*
|
||||
* Does SMAP provide full mitigation against speculative kernel access to
|
||||
* userspace?
|
||||
*/
|
||||
static bool smap_works_speculatively(void)
|
||||
{
|
||||
if (!boot_cpu_has(X86_FEATURE_SMAP))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* On CPUs which are vulnerable to Meltdown, SMAP does not
|
||||
* prevent speculative access to user data in the L1 cache.
|
||||
* Consider SMAP to be non-functional as a mitigation on these
|
||||
* CPUs.
|
||||
*/
|
||||
if (boot_cpu_has(X86_BUG_CPU_MELTDOWN))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __init spectre_v1_select_mitigation(void)
|
||||
{
|
||||
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1) || cpu_mitigations_off()) {
|
||||
spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (spectre_v1_mitigation == SPECTRE_V1_MITIGATION_AUTO) {
|
||||
/*
|
||||
* With Spectre v1, a user can speculatively control either
|
||||
* path of a conditional swapgs with a user-controlled GS
|
||||
* value. The mitigation is to add lfences to both code paths.
|
||||
*
|
||||
* If FSGSBASE is enabled, the user can put a kernel address in
|
||||
* GS, in which case SMAP provides no protection.
|
||||
*
|
||||
* [ NOTE: Don't check for X86_FEATURE_FSGSBASE until the
|
||||
* FSGSBASE enablement patches have been merged. ]
|
||||
*
|
||||
* If FSGSBASE is disabled, the user can only put a user space
|
||||
* address in GS. That makes an attack harder, but still
|
||||
* possible if there's no SMAP protection.
|
||||
*/
|
||||
if (!smap_works_speculatively()) {
|
||||
/*
|
||||
* Mitigation can be provided from SWAPGS itself or
|
||||
* PTI as the CR3 write in the Meltdown mitigation
|
||||
* is serializing.
|
||||
*
|
||||
* If neither is there, mitigate with an LFENCE to
|
||||
* stop speculation through swapgs.
|
||||
*/
|
||||
if (boot_cpu_has_bug(X86_BUG_SWAPGS) &&
|
||||
!boot_cpu_has(X86_FEATURE_KAISER))
|
||||
setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_USER);
|
||||
|
||||
/*
|
||||
* Enable lfences in the kernel entry (non-swapgs)
|
||||
* paths, to prevent user entry from speculatively
|
||||
* skipping swapgs.
|
||||
*/
|
||||
setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
pr_info("%s\n", spectre_v1_strings[spectre_v1_mitigation]);
|
||||
}
|
||||
|
||||
static int __init nospectre_v1_cmdline(char *str)
|
||||
{
|
||||
spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE;
|
||||
return 0;
|
||||
}
|
||||
early_param("nospectre_v1", nospectre_v1_cmdline);
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "Spectre V2 : " fmt
|
||||
|
||||
@@ -1094,7 +1181,7 @@ static void __init l1tf_select_mitigation(void)
|
||||
static ssize_t mds_show_state(char *buf)
|
||||
{
|
||||
#ifdef CONFIG_HYPERVISOR_GUEST
|
||||
if (x86_hyper) {
|
||||
if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
|
||||
return sprintf(buf, "%s; SMT Host state unknown\n",
|
||||
mds_strings[mds_mitigation]);
|
||||
}
|
||||
@@ -1154,7 +1241,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
|
||||
break;
|
||||
|
||||
case X86_BUG_SPECTRE_V1:
|
||||
return sprintf(buf, "Mitigation: __user pointer sanitization\n");
|
||||
return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
|
||||
|
||||
case X86_BUG_SPECTRE_V2:
|
||||
return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
|
||||
|
||||
@@ -853,6 +853,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
|
||||
#define NO_L1TF BIT(3)
|
||||
#define NO_MDS BIT(4)
|
||||
#define MSBDS_ONLY BIT(5)
|
||||
#define NO_SWAPGS BIT(6)
|
||||
|
||||
#define VULNWL(_vendor, _family, _model, _whitelist) \
|
||||
{ X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }
|
||||
@@ -876,29 +877,37 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
|
||||
VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION),
|
||||
VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION),
|
||||
|
||||
VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
|
||||
VULNWL_INTEL(CORE_YONAH, NO_SSB),
|
||||
|
||||
VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY),
|
||||
VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
|
||||
|
||||
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF | NO_SWAPGS),
|
||||
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS),
|
||||
|
||||
/*
|
||||
* Technically, swapgs isn't serializing on AMD (despite it previously
|
||||
* being documented as such in the APM). But according to AMD, %gs is
|
||||
* updated non-speculatively, and the issuing of %gs-relative memory
|
||||
* operands will be blocked until the %gs update completes, which is
|
||||
* good enough for our purposes.
|
||||
*/
|
||||
|
||||
/* AMD Family 0xf - 0x12 */
|
||||
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
|
||||
/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
|
||||
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
|
||||
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS),
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -935,6 +944,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
||||
setup_force_cpu_bug(X86_BUG_MSBDS_ONLY);
|
||||
}
|
||||
|
||||
if (!cpu_matches(NO_SWAPGS))
|
||||
setup_force_cpu_bug(X86_BUG_SWAPGS);
|
||||
|
||||
if (cpu_matches(NO_MELTDOWN))
|
||||
return;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeatures.h
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
IN=$1
|
||||
OUT=$2
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/context_tracking.h>
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
@@ -697,9 +698,11 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
|
||||
{
|
||||
struct thread_struct *thread = &tsk->thread;
|
||||
unsigned long val = 0;
|
||||
int index = n;
|
||||
|
||||
if (n < HBP_NUM) {
|
||||
struct perf_event *bp = thread->ptrace_bps[n];
|
||||
struct perf_event *bp = thread->ptrace_bps[index];
|
||||
index = array_index_nospec(index, HBP_NUM);
|
||||
|
||||
if (bp)
|
||||
val = bp->hw.info.address;
|
||||
|
||||
@@ -216,9 +216,55 @@ static const struct dmi_system_id efifb_dmi_system_table[] __initconst = {
|
||||
{},
|
||||
};
|
||||
|
||||
/*
|
||||
* Some devices have a portrait LCD but advertise a landscape resolution (and
|
||||
* pitch). We simply swap width and height for these devices so that we can
|
||||
* correctly deal with some of them coming with multiple resolutions.
|
||||
*/
|
||||
static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = {
|
||||
{
|
||||
/*
|
||||
* Lenovo MIIX310-10ICR, only some batches have the troublesome
|
||||
* 800x1280 portrait screen. Luckily the portrait version has
|
||||
* its own BIOS version, so we match on that.
|
||||
*/
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"),
|
||||
DMI_EXACT_MATCH(DMI_BIOS_VERSION, "1HCN44WW"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Lenovo MIIX 320-10ICR with 800x1280 portrait screen */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION,
|
||||
"Lenovo MIIX 320-10ICR"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Lenovo D330 with 800x1280 or 1200x1920 portrait screen */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION,
|
||||
"Lenovo ideapad D330-10IGM"),
|
||||
},
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
__init void sysfb_apply_efi_quirks(void)
|
||||
{
|
||||
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI ||
|
||||
!(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS))
|
||||
dmi_check_system(efifb_dmi_system_table);
|
||||
|
||||
if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI &&
|
||||
dmi_check_system(efifb_dmi_swap_width_height)) {
|
||||
u16 temp = screen_info.lfb_width;
|
||||
|
||||
screen_info.lfb_width = screen_info.lfb_height;
|
||||
screen_info.lfb_height = temp;
|
||||
screen_info.lfb_linelength = 4 * screen_info.lfb_width;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <linux/user.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/desc.h>
|
||||
@@ -177,6 +178,7 @@ int do_get_thread_area(struct task_struct *p, int idx,
|
||||
struct user_desc __user *u_info)
|
||||
{
|
||||
struct user_desc info;
|
||||
int index;
|
||||
|
||||
if (idx == -1 && get_user(idx, &u_info->entry_number))
|
||||
return -EFAULT;
|
||||
@@ -184,8 +186,11 @@ int do_get_thread_area(struct task_struct *p, int idx,
|
||||
if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
fill_user_desc(&info, idx,
|
||||
&p->thread.tls_array[idx - GDT_ENTRY_TLS_MIN]);
|
||||
index = idx - GDT_ENTRY_TLS_MIN;
|
||||
index = array_index_nospec(index,
|
||||
GDT_ENTRY_TLS_MAX - GDT_ENTRY_TLS_MIN + 1);
|
||||
|
||||
fill_user_desc(&info, idx, &p->thread.tls_array[index]);
|
||||
|
||||
if (copy_to_user(u_info, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -678,7 +678,6 @@ static const struct kvm_io_device_ops speaker_dev_ops = {
|
||||
.write = speaker_ioport_write,
|
||||
};
|
||||
|
||||
/* Caller must hold slots_lock */
|
||||
struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
|
||||
{
|
||||
struct kvm_pit *pit;
|
||||
@@ -733,6 +732,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
|
||||
pit->mask_notifier.func = pit_mask_notifer;
|
||||
kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
|
||||
|
||||
mutex_lock(&kvm->slots_lock);
|
||||
kvm_iodevice_init(&pit->dev, &pit_dev_ops);
|
||||
ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, KVM_PIT_BASE_ADDRESS,
|
||||
KVM_PIT_MEM_LENGTH, &pit->dev);
|
||||
@@ -747,13 +747,14 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
|
||||
if (ret < 0)
|
||||
goto fail_unregister;
|
||||
}
|
||||
mutex_unlock(&kvm->slots_lock);
|
||||
|
||||
return pit;
|
||||
|
||||
fail_unregister:
|
||||
kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev);
|
||||
|
||||
fail:
|
||||
mutex_unlock(&kvm->slots_lock);
|
||||
kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
|
||||
kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
|
||||
kvm_free_irq_source_id(kvm, pit->irq_source_id);
|
||||
|
||||
@@ -124,8 +124,8 @@ static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type,
|
||||
intr ? kvm_perf_overflow_intr :
|
||||
kvm_perf_overflow, pmc);
|
||||
if (IS_ERR(event)) {
|
||||
printk_once("kvm_pmu: event creation failed %ld\n",
|
||||
PTR_ERR(event));
|
||||
pr_debug_ratelimited("kvm_pmu: event creation failed %ld for pmc->idx = %d\n",
|
||||
PTR_ERR(event), pmc->idx);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3867,7 +3867,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
|
||||
sizeof(struct kvm_pit_config)))
|
||||
goto out;
|
||||
create_pit:
|
||||
mutex_lock(&kvm->slots_lock);
|
||||
mutex_lock(&kvm->lock);
|
||||
r = -EEXIST;
|
||||
if (kvm->arch.vpit)
|
||||
goto create_pit_unlock;
|
||||
@@ -3876,7 +3876,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
|
||||
if (kvm->arch.vpit)
|
||||
r = 0;
|
||||
create_pit_unlock:
|
||||
mutex_unlock(&kvm->slots_lock);
|
||||
mutex_unlock(&kvm->lock);
|
||||
break;
|
||||
case KVM_GET_IRQCHIP: {
|
||||
/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
|
||||
@@ -7799,7 +7799,7 @@ int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
|
||||
|
||||
slot = id_to_memslot(slots, id);
|
||||
if (size) {
|
||||
if (WARN_ON(slot->npages))
|
||||
if (slot->npages)
|
||||
return -EEXIST;
|
||||
|
||||
/*
|
||||
|
||||
@@ -176,7 +176,7 @@ static inline void reg_copy(FPU_REG const *x, FPU_REG *y)
|
||||
#define setexponentpos(x,y) { (*(short *)&((x)->exp)) = \
|
||||
((y) + EXTENDED_Ebias) & 0x7fff; }
|
||||
#define exponent16(x) (*(short *)&((x)->exp))
|
||||
#define setexponent16(x,y) { (*(short *)&((x)->exp)) = (y); }
|
||||
#define setexponent16(x,y) { (*(short *)&((x)->exp)) = (u16)(y); }
|
||||
#define addexponent(x,y) { (*(short *)&((x)->exp)) += (y); }
|
||||
#define stdexp(x) { (*(short *)&((x)->exp)) += EXTENDED_Ebias; }
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "control_w.h"
|
||||
|
||||
#define MAKE_REG(s, e, l, h) { l, h, \
|
||||
((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) }
|
||||
(u16)((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) }
|
||||
|
||||
FPU_REG const CONST_1 = MAKE_REG(POS, 0, 0x00000000, 0x80000000);
|
||||
#if 0
|
||||
|
||||
@@ -872,6 +872,7 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
|
||||
|
||||
fail:
|
||||
blk_free_flush_queue(q->fq);
|
||||
q->fq = NULL;
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_init_allocated_queue);
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <linux/cdrom.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/elevator.h>
|
||||
#include <linux/fd.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/syscalls.h>
|
||||
@@ -209,318 +208,6 @@ static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
#define BLKBSZSET_32 _IOW(0x12, 113, int)
|
||||
#define BLKGETSIZE64_32 _IOR(0x12, 114, int)
|
||||
|
||||
struct compat_floppy_drive_params {
|
||||
char cmos;
|
||||
compat_ulong_t max_dtr;
|
||||
compat_ulong_t hlt;
|
||||
compat_ulong_t hut;
|
||||
compat_ulong_t srt;
|
||||
compat_ulong_t spinup;
|
||||
compat_ulong_t spindown;
|
||||
unsigned char spindown_offset;
|
||||
unsigned char select_delay;
|
||||
unsigned char rps;
|
||||
unsigned char tracks;
|
||||
compat_ulong_t timeout;
|
||||
unsigned char interleave_sect;
|
||||
struct floppy_max_errors max_errors;
|
||||
char flags;
|
||||
char read_track;
|
||||
short autodetect[8];
|
||||
compat_int_t checkfreq;
|
||||
compat_int_t native_format;
|
||||
};
|
||||
|
||||
struct compat_floppy_drive_struct {
|
||||
signed char flags;
|
||||
compat_ulong_t spinup_date;
|
||||
compat_ulong_t select_date;
|
||||
compat_ulong_t first_read_date;
|
||||
short probed_format;
|
||||
short track;
|
||||
short maxblock;
|
||||
short maxtrack;
|
||||
compat_int_t generation;
|
||||
compat_int_t keep_data;
|
||||
compat_int_t fd_ref;
|
||||
compat_int_t fd_device;
|
||||
compat_int_t last_checked;
|
||||
compat_caddr_t dmabuf;
|
||||
compat_int_t bufblocks;
|
||||
};
|
||||
|
||||
struct compat_floppy_fdc_state {
|
||||
compat_int_t spec1;
|
||||
compat_int_t spec2;
|
||||
compat_int_t dtr;
|
||||
unsigned char version;
|
||||
unsigned char dor;
|
||||
compat_ulong_t address;
|
||||
unsigned int rawcmd:2;
|
||||
unsigned int reset:1;
|
||||
unsigned int need_configure:1;
|
||||
unsigned int perp_mode:2;
|
||||
unsigned int has_fifo:1;
|
||||
unsigned int driver_version;
|
||||
unsigned char track[4];
|
||||
};
|
||||
|
||||
struct compat_floppy_write_errors {
|
||||
unsigned int write_errors;
|
||||
compat_ulong_t first_error_sector;
|
||||
compat_int_t first_error_generation;
|
||||
compat_ulong_t last_error_sector;
|
||||
compat_int_t last_error_generation;
|
||||
compat_uint_t badness;
|
||||
};
|
||||
|
||||
#define FDSETPRM32 _IOW(2, 0x42, struct compat_floppy_struct)
|
||||
#define FDDEFPRM32 _IOW(2, 0x43, struct compat_floppy_struct)
|
||||
#define FDSETDRVPRM32 _IOW(2, 0x90, struct compat_floppy_drive_params)
|
||||
#define FDGETDRVPRM32 _IOR(2, 0x11, struct compat_floppy_drive_params)
|
||||
#define FDGETDRVSTAT32 _IOR(2, 0x12, struct compat_floppy_drive_struct)
|
||||
#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct compat_floppy_drive_struct)
|
||||
#define FDGETFDCSTAT32 _IOR(2, 0x15, struct compat_floppy_fdc_state)
|
||||
#define FDWERRORGET32 _IOR(2, 0x17, struct compat_floppy_write_errors)
|
||||
|
||||
static struct {
|
||||
unsigned int cmd32;
|
||||
unsigned int cmd;
|
||||
} fd_ioctl_trans_table[] = {
|
||||
{ FDSETPRM32, FDSETPRM },
|
||||
{ FDDEFPRM32, FDDEFPRM },
|
||||
{ FDGETPRM32, FDGETPRM },
|
||||
{ FDSETDRVPRM32, FDSETDRVPRM },
|
||||
{ FDGETDRVPRM32, FDGETDRVPRM },
|
||||
{ FDGETDRVSTAT32, FDGETDRVSTAT },
|
||||
{ FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
|
||||
{ FDGETFDCSTAT32, FDGETFDCSTAT },
|
||||
{ FDWERRORGET32, FDWERRORGET }
|
||||
};
|
||||
|
||||
#define NR_FD_IOCTL_TRANS ARRAY_SIZE(fd_ioctl_trans_table)
|
||||
|
||||
static int compat_fd_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
mm_segment_t old_fs = get_fs();
|
||||
void *karg = NULL;
|
||||
unsigned int kcmd = 0;
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
|
||||
if (cmd == fd_ioctl_trans_table[i].cmd32) {
|
||||
kcmd = fd_ioctl_trans_table[i].cmd;
|
||||
break;
|
||||
}
|
||||
if (!kcmd)
|
||||
return -EINVAL;
|
||||
|
||||
switch (cmd) {
|
||||
case FDSETPRM32:
|
||||
case FDDEFPRM32:
|
||||
case FDGETPRM32:
|
||||
{
|
||||
compat_uptr_t name;
|
||||
struct compat_floppy_struct __user *uf;
|
||||
struct floppy_struct *f;
|
||||
|
||||
uf = compat_ptr(arg);
|
||||
f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
|
||||
if (!karg)
|
||||
return -ENOMEM;
|
||||
if (cmd == FDGETPRM32)
|
||||
break;
|
||||
err = __get_user(f->size, &uf->size);
|
||||
err |= __get_user(f->sect, &uf->sect);
|
||||
err |= __get_user(f->head, &uf->head);
|
||||
err |= __get_user(f->track, &uf->track);
|
||||
err |= __get_user(f->stretch, &uf->stretch);
|
||||
err |= __get_user(f->gap, &uf->gap);
|
||||
err |= __get_user(f->rate, &uf->rate);
|
||||
err |= __get_user(f->spec1, &uf->spec1);
|
||||
err |= __get_user(f->fmt_gap, &uf->fmt_gap);
|
||||
err |= __get_user(name, &uf->name);
|
||||
f->name = compat_ptr(name);
|
||||
if (err) {
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FDSETDRVPRM32:
|
||||
case FDGETDRVPRM32:
|
||||
{
|
||||
struct compat_floppy_drive_params __user *uf;
|
||||
struct floppy_drive_params *f;
|
||||
|
||||
uf = compat_ptr(arg);
|
||||
f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
|
||||
if (!karg)
|
||||
return -ENOMEM;
|
||||
if (cmd == FDGETDRVPRM32)
|
||||
break;
|
||||
err = __get_user(f->cmos, &uf->cmos);
|
||||
err |= __get_user(f->max_dtr, &uf->max_dtr);
|
||||
err |= __get_user(f->hlt, &uf->hlt);
|
||||
err |= __get_user(f->hut, &uf->hut);
|
||||
err |= __get_user(f->srt, &uf->srt);
|
||||
err |= __get_user(f->spinup, &uf->spinup);
|
||||
err |= __get_user(f->spindown, &uf->spindown);
|
||||
err |= __get_user(f->spindown_offset, &uf->spindown_offset);
|
||||
err |= __get_user(f->select_delay, &uf->select_delay);
|
||||
err |= __get_user(f->rps, &uf->rps);
|
||||
err |= __get_user(f->tracks, &uf->tracks);
|
||||
err |= __get_user(f->timeout, &uf->timeout);
|
||||
err |= __get_user(f->interleave_sect, &uf->interleave_sect);
|
||||
err |= __copy_from_user(&f->max_errors, &uf->max_errors, sizeof(f->max_errors));
|
||||
err |= __get_user(f->flags, &uf->flags);
|
||||
err |= __get_user(f->read_track, &uf->read_track);
|
||||
err |= __copy_from_user(f->autodetect, uf->autodetect, sizeof(f->autodetect));
|
||||
err |= __get_user(f->checkfreq, &uf->checkfreq);
|
||||
err |= __get_user(f->native_format, &uf->native_format);
|
||||
if (err) {
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FDGETDRVSTAT32:
|
||||
case FDPOLLDRVSTAT32:
|
||||
karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
|
||||
if (!karg)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
case FDGETFDCSTAT32:
|
||||
karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
|
||||
if (!karg)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
case FDWERRORGET32:
|
||||
karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
|
||||
if (!karg)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
set_fs(KERNEL_DS);
|
||||
err = __blkdev_driver_ioctl(bdev, mode, kcmd, (unsigned long)karg);
|
||||
set_fs(old_fs);
|
||||
if (err)
|
||||
goto out;
|
||||
switch (cmd) {
|
||||
case FDGETPRM32:
|
||||
{
|
||||
struct floppy_struct *f = karg;
|
||||
struct compat_floppy_struct __user *uf = compat_ptr(arg);
|
||||
|
||||
err = __put_user(f->size, &uf->size);
|
||||
err |= __put_user(f->sect, &uf->sect);
|
||||
err |= __put_user(f->head, &uf->head);
|
||||
err |= __put_user(f->track, &uf->track);
|
||||
err |= __put_user(f->stretch, &uf->stretch);
|
||||
err |= __put_user(f->gap, &uf->gap);
|
||||
err |= __put_user(f->rate, &uf->rate);
|
||||
err |= __put_user(f->spec1, &uf->spec1);
|
||||
err |= __put_user(f->fmt_gap, &uf->fmt_gap);
|
||||
err |= __put_user((u64)f->name, (compat_caddr_t __user *)&uf->name);
|
||||
break;
|
||||
}
|
||||
case FDGETDRVPRM32:
|
||||
{
|
||||
struct compat_floppy_drive_params __user *uf;
|
||||
struct floppy_drive_params *f = karg;
|
||||
|
||||
uf = compat_ptr(arg);
|
||||
err = __put_user(f->cmos, &uf->cmos);
|
||||
err |= __put_user(f->max_dtr, &uf->max_dtr);
|
||||
err |= __put_user(f->hlt, &uf->hlt);
|
||||
err |= __put_user(f->hut, &uf->hut);
|
||||
err |= __put_user(f->srt, &uf->srt);
|
||||
err |= __put_user(f->spinup, &uf->spinup);
|
||||
err |= __put_user(f->spindown, &uf->spindown);
|
||||
err |= __put_user(f->spindown_offset, &uf->spindown_offset);
|
||||
err |= __put_user(f->select_delay, &uf->select_delay);
|
||||
err |= __put_user(f->rps, &uf->rps);
|
||||
err |= __put_user(f->tracks, &uf->tracks);
|
||||
err |= __put_user(f->timeout, &uf->timeout);
|
||||
err |= __put_user(f->interleave_sect, &uf->interleave_sect);
|
||||
err |= __copy_to_user(&uf->max_errors, &f->max_errors, sizeof(f->max_errors));
|
||||
err |= __put_user(f->flags, &uf->flags);
|
||||
err |= __put_user(f->read_track, &uf->read_track);
|
||||
err |= __copy_to_user(uf->autodetect, f->autodetect, sizeof(f->autodetect));
|
||||
err |= __put_user(f->checkfreq, &uf->checkfreq);
|
||||
err |= __put_user(f->native_format, &uf->native_format);
|
||||
break;
|
||||
}
|
||||
case FDGETDRVSTAT32:
|
||||
case FDPOLLDRVSTAT32:
|
||||
{
|
||||
struct compat_floppy_drive_struct __user *uf;
|
||||
struct floppy_drive_struct *f = karg;
|
||||
|
||||
uf = compat_ptr(arg);
|
||||
err = __put_user(f->flags, &uf->flags);
|
||||
err |= __put_user(f->spinup_date, &uf->spinup_date);
|
||||
err |= __put_user(f->select_date, &uf->select_date);
|
||||
err |= __put_user(f->first_read_date, &uf->first_read_date);
|
||||
err |= __put_user(f->probed_format, &uf->probed_format);
|
||||
err |= __put_user(f->track, &uf->track);
|
||||
err |= __put_user(f->maxblock, &uf->maxblock);
|
||||
err |= __put_user(f->maxtrack, &uf->maxtrack);
|
||||
err |= __put_user(f->generation, &uf->generation);
|
||||
err |= __put_user(f->keep_data, &uf->keep_data);
|
||||
err |= __put_user(f->fd_ref, &uf->fd_ref);
|
||||
err |= __put_user(f->fd_device, &uf->fd_device);
|
||||
err |= __put_user(f->last_checked, &uf->last_checked);
|
||||
err |= __put_user((u64)f->dmabuf, &uf->dmabuf);
|
||||
err |= __put_user((u64)f->bufblocks, &uf->bufblocks);
|
||||
break;
|
||||
}
|
||||
case FDGETFDCSTAT32:
|
||||
{
|
||||
struct compat_floppy_fdc_state __user *uf;
|
||||
struct floppy_fdc_state *f = karg;
|
||||
|
||||
uf = compat_ptr(arg);
|
||||
err = __put_user(f->spec1, &uf->spec1);
|
||||
err |= __put_user(f->spec2, &uf->spec2);
|
||||
err |= __put_user(f->dtr, &uf->dtr);
|
||||
err |= __put_user(f->version, &uf->version);
|
||||
err |= __put_user(f->dor, &uf->dor);
|
||||
err |= __put_user(f->address, &uf->address);
|
||||
err |= __copy_to_user((char __user *)&uf->address + sizeof(uf->address),
|
||||
(char *)&f->address + sizeof(f->address), sizeof(int));
|
||||
err |= __put_user(f->driver_version, &uf->driver_version);
|
||||
err |= __copy_to_user(uf->track, f->track, sizeof(f->track));
|
||||
break;
|
||||
}
|
||||
case FDWERRORGET32:
|
||||
{
|
||||
struct compat_floppy_write_errors __user *uf;
|
||||
struct floppy_write_errors *f = karg;
|
||||
|
||||
uf = compat_ptr(arg);
|
||||
err = __put_user(f->write_errors, &uf->write_errors);
|
||||
err |= __put_user(f->first_error_sector, &uf->first_error_sector);
|
||||
err |= __put_user(f->first_error_generation, &uf->first_error_generation);
|
||||
err |= __put_user(f->last_error_sector, &uf->last_error_sector);
|
||||
err |= __put_user(f->last_error_generation, &uf->last_error_generation);
|
||||
err |= __put_user(f->badness, &uf->badness);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (err)
|
||||
err = -EFAULT;
|
||||
|
||||
out:
|
||||
kfree(karg);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
unsigned cmd, unsigned long arg)
|
||||
{
|
||||
@@ -537,16 +224,6 @@ static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
case HDIO_GET_ADDRESS:
|
||||
case HDIO_GET_BUSSTATE:
|
||||
return compat_hdio_ioctl(bdev, mode, cmd, arg);
|
||||
case FDSETPRM32:
|
||||
case FDDEFPRM32:
|
||||
case FDGETPRM32:
|
||||
case FDSETDRVPRM32:
|
||||
case FDGETDRVPRM32:
|
||||
case FDGETDRVSTAT32:
|
||||
case FDPOLLDRVSTAT32:
|
||||
case FDGETFDCSTAT32:
|
||||
case FDWERRORGET32:
|
||||
return compat_fd_ioctl(bdev, mode, cmd, arg);
|
||||
case CDROMREADAUDIO:
|
||||
return compat_cdrom_read_audio(bdev, mode, cmd, arg);
|
||||
case CDROM_SEND_PACKET:
|
||||
@@ -566,23 +243,6 @@ static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
case HDIO_DRIVE_CMD:
|
||||
/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
|
||||
case 0x330:
|
||||
/* 0x02 -- Floppy ioctls */
|
||||
case FDMSGON:
|
||||
case FDMSGOFF:
|
||||
case FDSETEMSGTRESH:
|
||||
case FDFLUSH:
|
||||
case FDWERRORCLR:
|
||||
case FDSETMAXERRS:
|
||||
case FDGETMAXERRS:
|
||||
case FDGETDRVTYP:
|
||||
case FDEJECT:
|
||||
case FDCLRPRM:
|
||||
case FDFMTBEG:
|
||||
case FDFMTEND:
|
||||
case FDRESET:
|
||||
case FDTWADDLE:
|
||||
case FDFMTTRK:
|
||||
case FDRAWCMD:
|
||||
/* CDROM stuff */
|
||||
case CDROMPAUSE:
|
||||
case CDROMRESUME:
|
||||
|
||||
@@ -34,6 +34,7 @@ static int ghash_setkey(struct crypto_shash *tfm,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
|
||||
be128 k;
|
||||
|
||||
if (keylen != GHASH_BLOCK_SIZE) {
|
||||
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
@@ -42,7 +43,12 @@ static int ghash_setkey(struct crypto_shash *tfm,
|
||||
|
||||
if (ctx->gf128)
|
||||
gf128mul_free_4k(ctx->gf128);
|
||||
ctx->gf128 = gf128mul_init_4k_lle((be128 *)key);
|
||||
|
||||
BUILD_BUG_ON(sizeof(k) != GHASH_BLOCK_SIZE);
|
||||
memcpy(&k, key, GHASH_BLOCK_SIZE); /* avoid violating alignment rules */
|
||||
ctx->gf128 = gf128mul_init_4k_lle(&k);
|
||||
memzero_explicit(&k, GHASH_BLOCK_SIZE);
|
||||
|
||||
if (!ctx->gf128)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -3229,7 +3229,8 @@ static void binder_transaction(struct binder_proc *proc,
|
||||
}
|
||||
off_end = (void *)off_start + tr->offsets_size;
|
||||
sg_bufp = (u8 *)(PTR_ALIGN(off_end, sizeof(void *)));
|
||||
sg_buf_end = sg_bufp + extra_buffers_size;
|
||||
sg_buf_end = sg_bufp + extra_buffers_size -
|
||||
ALIGN(secctx_sz, sizeof(u64));
|
||||
off_min = 0;
|
||||
for (; offp < off_end; offp++) {
|
||||
struct binder_object_header *hdr;
|
||||
|
||||
@@ -219,6 +219,11 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
|
||||
|
||||
if (mm) {
|
||||
down_read(&mm->mmap_sem);
|
||||
if (!mmget_still_valid(mm)) {
|
||||
if (allocate == 0)
|
||||
goto free_range;
|
||||
goto err_no_vma;
|
||||
}
|
||||
vma = alloc->vma;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/nospec.h>
|
||||
#include "iphase.h"
|
||||
#include "suni.h"
|
||||
#define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
|
||||
@@ -2755,8 +2756,11 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
|
||||
}
|
||||
if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT;
|
||||
board = ia_cmds.status;
|
||||
if ((board < 0) || (board > iadev_count))
|
||||
board = 0;
|
||||
|
||||
if ((board < 0) || (board > iadev_count))
|
||||
board = 0;
|
||||
board = array_index_nospec(board, iadev_count + 1);
|
||||
|
||||
iadev = ia_dev[board];
|
||||
switch (ia_cmds.cmd) {
|
||||
case MEMDUMP:
|
||||
|
||||
@@ -1358,6 +1358,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
|
||||
map->format.reg_bytes +
|
||||
map->format.pad_bytes,
|
||||
val, val_len);
|
||||
else
|
||||
ret = -ENOTSUPP;
|
||||
|
||||
/* If that didn't work fall back on linearising by hand. */
|
||||
if (ret == -ENOTSUPP) {
|
||||
|
||||
@@ -192,6 +192,7 @@ static int print_unex = 1;
|
||||
#include <linux/io.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/async.h>
|
||||
#include <linux/compat.h>
|
||||
|
||||
/*
|
||||
* PS/2 floppies have much slower step rates than regular floppies.
|
||||
@@ -2113,6 +2114,9 @@ static void setup_format_params(int track)
|
||||
raw_cmd->kernel_data = floppy_track_buffer;
|
||||
raw_cmd->length = 4 * F_SECT_PER_TRACK;
|
||||
|
||||
if (!F_SECT_PER_TRACK)
|
||||
return;
|
||||
|
||||
/* allow for about 30ms for data transport per track */
|
||||
head_shift = (F_SECT_PER_TRACK + 5) / 6;
|
||||
|
||||
@@ -3233,8 +3237,12 @@ static int set_geometry(unsigned int cmd, struct floppy_struct *g,
|
||||
int cnt;
|
||||
|
||||
/* sanity checking for parameters. */
|
||||
if (g->sect <= 0 ||
|
||||
g->head <= 0 ||
|
||||
if ((int)g->sect <= 0 ||
|
||||
(int)g->head <= 0 ||
|
||||
/* check for overflow in max_sector */
|
||||
(int)(g->sect * g->head) <= 0 ||
|
||||
/* check for zero in F_SECT_PER_TRACK */
|
||||
(unsigned char)((g->sect << 2) >> FD_SIZECODE(g)) == 0 ||
|
||||
g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) ||
|
||||
/* check if reserved bits are set */
|
||||
(g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_SECTBASEMASK)) != 0)
|
||||
@@ -3378,6 +3386,24 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool valid_floppy_drive_params(const short autodetect[8],
|
||||
int native_format)
|
||||
{
|
||||
size_t floppy_type_size = ARRAY_SIZE(floppy_type);
|
||||
size_t i = 0;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
if (autodetect[i] < 0 ||
|
||||
autodetect[i] >= floppy_type_size)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (native_format < 0 || native_format >= floppy_type_size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
|
||||
unsigned long param)
|
||||
{
|
||||
@@ -3504,6 +3530,9 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
|
||||
SUPBOUND(size, strlen((const char *)outparam) + 1);
|
||||
break;
|
||||
case FDSETDRVPRM:
|
||||
if (!valid_floppy_drive_params(inparam.dp.autodetect,
|
||||
inparam.dp.native_format))
|
||||
return -EINVAL;
|
||||
*UDP = inparam.dp;
|
||||
break;
|
||||
case FDGETDRVPRM:
|
||||
@@ -3569,6 +3598,332 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
struct compat_floppy_drive_params {
|
||||
char cmos;
|
||||
compat_ulong_t max_dtr;
|
||||
compat_ulong_t hlt;
|
||||
compat_ulong_t hut;
|
||||
compat_ulong_t srt;
|
||||
compat_ulong_t spinup;
|
||||
compat_ulong_t spindown;
|
||||
unsigned char spindown_offset;
|
||||
unsigned char select_delay;
|
||||
unsigned char rps;
|
||||
unsigned char tracks;
|
||||
compat_ulong_t timeout;
|
||||
unsigned char interleave_sect;
|
||||
struct floppy_max_errors max_errors;
|
||||
char flags;
|
||||
char read_track;
|
||||
short autodetect[8];
|
||||
compat_int_t checkfreq;
|
||||
compat_int_t native_format;
|
||||
};
|
||||
|
||||
struct compat_floppy_drive_struct {
|
||||
signed char flags;
|
||||
compat_ulong_t spinup_date;
|
||||
compat_ulong_t select_date;
|
||||
compat_ulong_t first_read_date;
|
||||
short probed_format;
|
||||
short track;
|
||||
short maxblock;
|
||||
short maxtrack;
|
||||
compat_int_t generation;
|
||||
compat_int_t keep_data;
|
||||
compat_int_t fd_ref;
|
||||
compat_int_t fd_device;
|
||||
compat_int_t last_checked;
|
||||
compat_caddr_t dmabuf;
|
||||
compat_int_t bufblocks;
|
||||
};
|
||||
|
||||
struct compat_floppy_fdc_state {
|
||||
compat_int_t spec1;
|
||||
compat_int_t spec2;
|
||||
compat_int_t dtr;
|
||||
unsigned char version;
|
||||
unsigned char dor;
|
||||
compat_ulong_t address;
|
||||
unsigned int rawcmd:2;
|
||||
unsigned int reset:1;
|
||||
unsigned int need_configure:1;
|
||||
unsigned int perp_mode:2;
|
||||
unsigned int has_fifo:1;
|
||||
unsigned int driver_version;
|
||||
unsigned char track[4];
|
||||
};
|
||||
|
||||
struct compat_floppy_write_errors {
|
||||
unsigned int write_errors;
|
||||
compat_ulong_t first_error_sector;
|
||||
compat_int_t first_error_generation;
|
||||
compat_ulong_t last_error_sector;
|
||||
compat_int_t last_error_generation;
|
||||
compat_uint_t badness;
|
||||
};
|
||||
|
||||
#define FDSETPRM32 _IOW(2, 0x42, struct compat_floppy_struct)
|
||||
#define FDDEFPRM32 _IOW(2, 0x43, struct compat_floppy_struct)
|
||||
#define FDSETDRVPRM32 _IOW(2, 0x90, struct compat_floppy_drive_params)
|
||||
#define FDGETDRVPRM32 _IOR(2, 0x11, struct compat_floppy_drive_params)
|
||||
#define FDGETDRVSTAT32 _IOR(2, 0x12, struct compat_floppy_drive_struct)
|
||||
#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct compat_floppy_drive_struct)
|
||||
#define FDGETFDCSTAT32 _IOR(2, 0x15, struct compat_floppy_fdc_state)
|
||||
#define FDWERRORGET32 _IOR(2, 0x17, struct compat_floppy_write_errors)
|
||||
|
||||
static int compat_set_geometry(struct block_device *bdev, fmode_t mode, unsigned int cmd,
|
||||
struct compat_floppy_struct __user *arg)
|
||||
{
|
||||
struct floppy_struct v;
|
||||
int drive, type;
|
||||
int err;
|
||||
|
||||
BUILD_BUG_ON(offsetof(struct floppy_struct, name) !=
|
||||
offsetof(struct compat_floppy_struct, name));
|
||||
|
||||
if (!(mode & (FMODE_WRITE | FMODE_WRITE_IOCTL)))
|
||||
return -EPERM;
|
||||
|
||||
memset(&v, 0, sizeof(struct floppy_struct));
|
||||
if (copy_from_user(&v, arg, offsetof(struct floppy_struct, name)))
|
||||
return -EFAULT;
|
||||
|
||||
mutex_lock(&floppy_mutex);
|
||||
drive = (long)bdev->bd_disk->private_data;
|
||||
type = ITYPE(UDRS->fd_device);
|
||||
err = set_geometry(cmd == FDSETPRM32 ? FDSETPRM : FDDEFPRM,
|
||||
&v, drive, type, bdev);
|
||||
mutex_unlock(&floppy_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_prm(int drive,
|
||||
struct compat_floppy_struct __user *arg)
|
||||
{
|
||||
struct compat_floppy_struct v;
|
||||
struct floppy_struct *p;
|
||||
int err;
|
||||
|
||||
memset(&v, 0, sizeof(v));
|
||||
mutex_lock(&floppy_mutex);
|
||||
err = get_floppy_geometry(drive, ITYPE(UDRS->fd_device), &p);
|
||||
if (err) {
|
||||
mutex_unlock(&floppy_mutex);
|
||||
return err;
|
||||
}
|
||||
memcpy(&v, p, offsetof(struct floppy_struct, name));
|
||||
mutex_unlock(&floppy_mutex);
|
||||
if (copy_to_user(arg, &v, sizeof(struct compat_floppy_struct)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compat_setdrvprm(int drive,
|
||||
struct compat_floppy_drive_params __user *arg)
|
||||
{
|
||||
struct compat_floppy_drive_params v;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
if (copy_from_user(&v, arg, sizeof(struct compat_floppy_drive_params)))
|
||||
return -EFAULT;
|
||||
if (!valid_floppy_drive_params(v.autodetect, v.native_format))
|
||||
return -EINVAL;
|
||||
mutex_lock(&floppy_mutex);
|
||||
UDP->cmos = v.cmos;
|
||||
UDP->max_dtr = v.max_dtr;
|
||||
UDP->hlt = v.hlt;
|
||||
UDP->hut = v.hut;
|
||||
UDP->srt = v.srt;
|
||||
UDP->spinup = v.spinup;
|
||||
UDP->spindown = v.spindown;
|
||||
UDP->spindown_offset = v.spindown_offset;
|
||||
UDP->select_delay = v.select_delay;
|
||||
UDP->rps = v.rps;
|
||||
UDP->tracks = v.tracks;
|
||||
UDP->timeout = v.timeout;
|
||||
UDP->interleave_sect = v.interleave_sect;
|
||||
UDP->max_errors = v.max_errors;
|
||||
UDP->flags = v.flags;
|
||||
UDP->read_track = v.read_track;
|
||||
memcpy(UDP->autodetect, v.autodetect, sizeof(v.autodetect));
|
||||
UDP->checkfreq = v.checkfreq;
|
||||
UDP->native_format = v.native_format;
|
||||
mutex_unlock(&floppy_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compat_getdrvprm(int drive,
|
||||
struct compat_floppy_drive_params __user *arg)
|
||||
{
|
||||
struct compat_floppy_drive_params v;
|
||||
|
||||
memset(&v, 0, sizeof(struct compat_floppy_drive_params));
|
||||
mutex_lock(&floppy_mutex);
|
||||
v.cmos = UDP->cmos;
|
||||
v.max_dtr = UDP->max_dtr;
|
||||
v.hlt = UDP->hlt;
|
||||
v.hut = UDP->hut;
|
||||
v.srt = UDP->srt;
|
||||
v.spinup = UDP->spinup;
|
||||
v.spindown = UDP->spindown;
|
||||
v.spindown_offset = UDP->spindown_offset;
|
||||
v.select_delay = UDP->select_delay;
|
||||
v.rps = UDP->rps;
|
||||
v.tracks = UDP->tracks;
|
||||
v.timeout = UDP->timeout;
|
||||
v.interleave_sect = UDP->interleave_sect;
|
||||
v.max_errors = UDP->max_errors;
|
||||
v.flags = UDP->flags;
|
||||
v.read_track = UDP->read_track;
|
||||
memcpy(v.autodetect, UDP->autodetect, sizeof(v.autodetect));
|
||||
v.checkfreq = UDP->checkfreq;
|
||||
v.native_format = UDP->native_format;
|
||||
mutex_unlock(&floppy_mutex);
|
||||
|
||||
if (copy_from_user(arg, &v, sizeof(struct compat_floppy_drive_params)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compat_getdrvstat(int drive, bool poll,
|
||||
struct compat_floppy_drive_struct __user *arg)
|
||||
{
|
||||
struct compat_floppy_drive_struct v;
|
||||
|
||||
memset(&v, 0, sizeof(struct compat_floppy_drive_struct));
|
||||
mutex_lock(&floppy_mutex);
|
||||
|
||||
if (poll) {
|
||||
if (lock_fdc(drive, true))
|
||||
goto Eintr;
|
||||
if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
|
||||
goto Eintr;
|
||||
process_fd_request();
|
||||
}
|
||||
v.spinup_date = UDRS->spinup_date;
|
||||
v.select_date = UDRS->select_date;
|
||||
v.first_read_date = UDRS->first_read_date;
|
||||
v.probed_format = UDRS->probed_format;
|
||||
v.track = UDRS->track;
|
||||
v.maxblock = UDRS->maxblock;
|
||||
v.maxtrack = UDRS->maxtrack;
|
||||
v.generation = UDRS->generation;
|
||||
v.keep_data = UDRS->keep_data;
|
||||
v.fd_ref = UDRS->fd_ref;
|
||||
v.fd_device = UDRS->fd_device;
|
||||
v.last_checked = UDRS->last_checked;
|
||||
v.dmabuf = (uintptr_t)UDRS->dmabuf;
|
||||
v.bufblocks = UDRS->bufblocks;
|
||||
mutex_unlock(&floppy_mutex);
|
||||
|
||||
if (copy_from_user(arg, &v, sizeof(struct compat_floppy_drive_struct)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
Eintr:
|
||||
mutex_unlock(&floppy_mutex);
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
static int compat_getfdcstat(int drive,
|
||||
struct compat_floppy_fdc_state __user *arg)
|
||||
{
|
||||
struct compat_floppy_fdc_state v32;
|
||||
struct floppy_fdc_state v;
|
||||
|
||||
mutex_lock(&floppy_mutex);
|
||||
v = *UFDCS;
|
||||
mutex_unlock(&floppy_mutex);
|
||||
|
||||
memset(&v32, 0, sizeof(struct compat_floppy_fdc_state));
|
||||
v32.spec1 = v.spec1;
|
||||
v32.spec2 = v.spec2;
|
||||
v32.dtr = v.dtr;
|
||||
v32.version = v.version;
|
||||
v32.dor = v.dor;
|
||||
v32.address = v.address;
|
||||
v32.rawcmd = v.rawcmd;
|
||||
v32.reset = v.reset;
|
||||
v32.need_configure = v.need_configure;
|
||||
v32.perp_mode = v.perp_mode;
|
||||
v32.has_fifo = v.has_fifo;
|
||||
v32.driver_version = v.driver_version;
|
||||
memcpy(v32.track, v.track, 4);
|
||||
if (copy_to_user(arg, &v32, sizeof(struct compat_floppy_fdc_state)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compat_werrorget(int drive,
|
||||
struct compat_floppy_write_errors __user *arg)
|
||||
{
|
||||
struct compat_floppy_write_errors v32;
|
||||
struct floppy_write_errors v;
|
||||
|
||||
memset(&v32, 0, sizeof(struct compat_floppy_write_errors));
|
||||
mutex_lock(&floppy_mutex);
|
||||
v = *UDRWE;
|
||||
mutex_unlock(&floppy_mutex);
|
||||
v32.write_errors = v.write_errors;
|
||||
v32.first_error_sector = v.first_error_sector;
|
||||
v32.first_error_generation = v.first_error_generation;
|
||||
v32.last_error_sector = v.last_error_sector;
|
||||
v32.last_error_generation = v.last_error_generation;
|
||||
v32.badness = v.badness;
|
||||
if (copy_to_user(arg, &v32, sizeof(struct compat_floppy_write_errors)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fd_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
|
||||
unsigned long param)
|
||||
{
|
||||
int drive = (long)bdev->bd_disk->private_data;
|
||||
switch (cmd) {
|
||||
case FDMSGON:
|
||||
case FDMSGOFF:
|
||||
case FDSETEMSGTRESH:
|
||||
case FDFLUSH:
|
||||
case FDWERRORCLR:
|
||||
case FDEJECT:
|
||||
case FDCLRPRM:
|
||||
case FDFMTBEG:
|
||||
case FDRESET:
|
||||
case FDTWADDLE:
|
||||
return fd_ioctl(bdev, mode, cmd, param);
|
||||
case FDSETMAXERRS:
|
||||
case FDGETMAXERRS:
|
||||
case FDGETDRVTYP:
|
||||
case FDFMTEND:
|
||||
case FDFMTTRK:
|
||||
case FDRAWCMD:
|
||||
return fd_ioctl(bdev, mode, cmd,
|
||||
(unsigned long)compat_ptr(param));
|
||||
case FDSETPRM32:
|
||||
case FDDEFPRM32:
|
||||
return compat_set_geometry(bdev, mode, cmd, compat_ptr(param));
|
||||
case FDGETPRM32:
|
||||
return compat_get_prm(drive, compat_ptr(param));
|
||||
case FDSETDRVPRM32:
|
||||
return compat_setdrvprm(drive, compat_ptr(param));
|
||||
case FDGETDRVPRM32:
|
||||
return compat_getdrvprm(drive, compat_ptr(param));
|
||||
case FDPOLLDRVSTAT32:
|
||||
return compat_getdrvstat(drive, true, compat_ptr(param));
|
||||
case FDGETDRVSTAT32:
|
||||
return compat_getdrvstat(drive, false, compat_ptr(param));
|
||||
case FDGETFDCSTAT32:
|
||||
return compat_getfdcstat(drive, compat_ptr(param));
|
||||
case FDWERRORGET32:
|
||||
return compat_werrorget(drive, compat_ptr(param));
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __init config_types(void)
|
||||
{
|
||||
bool has_drive = false;
|
||||
@@ -3885,6 +4240,9 @@ static const struct block_device_operations floppy_fops = {
|
||||
.getgeo = fd_getgeo,
|
||||
.check_events = floppy_check_events,
|
||||
.revalidate_disk = floppy_revalidate,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = fd_compat_ioctl,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -101,6 +101,9 @@ static int ath_open(struct hci_uart *hu)
|
||||
|
||||
BT_DBG("hu %p", hu);
|
||||
|
||||
if (!hci_uart_has_flow_control(hu))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ath = kzalloc(sizeof(*ath), GFP_KERNEL);
|
||||
if (!ath)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -279,6 +279,9 @@ static int bcm_open(struct hci_uart *hu)
|
||||
|
||||
bt_dev_dbg(hu->hdev, "hu %p", hu);
|
||||
|
||||
if (!hci_uart_has_flow_control(hu))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
bcm = kzalloc(sizeof(*bcm), GFP_KERNEL);
|
||||
if (!bcm)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -729,6 +729,11 @@ static int bcsp_close(struct hci_uart *hu)
|
||||
skb_queue_purge(&bcsp->rel);
|
||||
skb_queue_purge(&bcsp->unrel);
|
||||
|
||||
if (bcsp->rx_skb) {
|
||||
kfree_skb(bcsp->rx_skb);
|
||||
bcsp->rx_skb = NULL;
|
||||
}
|
||||
|
||||
kfree(bcsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -407,6 +407,9 @@ static int intel_open(struct hci_uart *hu)
|
||||
|
||||
BT_DBG("hu %p", hu);
|
||||
|
||||
if (!hci_uart_has_flow_control(hu))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
intel = kzalloc(sizeof(*intel), GFP_KERNEL);
|
||||
if (!intel)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -265,6 +265,15 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the underlying device or tty has flow control support */
|
||||
bool hci_uart_has_flow_control(struct hci_uart *hu)
|
||||
{
|
||||
if (hu->tty->driver->ops->tiocmget && hu->tty->driver->ops->tiocmset)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Flow control or un-flow control the device */
|
||||
void hci_uart_set_flow_control(struct hci_uart *hu, bool enable)
|
||||
{
|
||||
|
||||
@@ -106,6 +106,7 @@ int hci_uart_tx_wakeup(struct hci_uart *hu);
|
||||
int hci_uart_init_ready(struct hci_uart *hu);
|
||||
void hci_uart_init_tty(struct hci_uart *hu);
|
||||
void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed);
|
||||
bool hci_uart_has_flow_control(struct hci_uart *hu);
|
||||
void hci_uart_set_flow_control(struct hci_uart *hu, bool enable);
|
||||
void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed,
|
||||
unsigned int oper_speed);
|
||||
|
||||
@@ -569,8 +569,7 @@ static inline unsigned long hpet_time_div(struct hpets *hpets,
|
||||
unsigned long long m;
|
||||
|
||||
m = hpets->hp_tick_freq + (dis >> 1);
|
||||
do_div(m, dis);
|
||||
return (unsigned long)m;
|
||||
return div64_ul(m, dis);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -1446,11 +1446,15 @@ static void ablkcipher_done(struct device *dev,
|
||||
int err)
|
||||
{
|
||||
struct ablkcipher_request *areq = context;
|
||||
struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
|
||||
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
|
||||
unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
|
||||
struct talitos_edesc *edesc;
|
||||
|
||||
edesc = container_of(desc, struct talitos_edesc, desc);
|
||||
|
||||
common_nonsnoop_unmap(dev, edesc, areq);
|
||||
memcpy(areq->info, ctx->iv, ivsize);
|
||||
|
||||
kfree(edesc);
|
||||
|
||||
|
||||
@@ -1786,27 +1786,6 @@ static int sdma_probe(struct platform_device *pdev)
|
||||
if (pdata && pdata->script_addrs)
|
||||
sdma_add_scripts(sdma, pdata->script_addrs);
|
||||
|
||||
if (pdata) {
|
||||
ret = sdma_get_firmware(sdma, pdata->fw_name);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev, "failed to get firmware from platform data\n");
|
||||
} else {
|
||||
/*
|
||||
* Because that device tree does not encode ROM script address,
|
||||
* the RAM script in firmware is mandatory for device tree
|
||||
* probe, otherwise it fails.
|
||||
*/
|
||||
ret = of_property_read_string(np, "fsl,sdma-ram-script-name",
|
||||
&fw_name);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev, "failed to get firmware name\n");
|
||||
else {
|
||||
ret = sdma_get_firmware(sdma, fw_name);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev, "failed to get firmware from device tree\n");
|
||||
}
|
||||
}
|
||||
|
||||
sdma->dma_device.dev = &pdev->dev;
|
||||
|
||||
sdma->dma_device.device_alloc_chan_resources = sdma_alloc_chan_resources;
|
||||
@@ -1848,6 +1827,33 @@ static int sdma_probe(struct platform_device *pdev)
|
||||
of_node_put(spba_bus);
|
||||
}
|
||||
|
||||
/*
|
||||
* Kick off firmware loading as the very last step:
|
||||
* attempt to load firmware only if we're not on the error path, because
|
||||
* the firmware callback requires a fully functional and allocated sdma
|
||||
* instance.
|
||||
*/
|
||||
if (pdata) {
|
||||
ret = sdma_get_firmware(sdma, pdata->fw_name);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev, "failed to get firmware from platform data\n");
|
||||
} else {
|
||||
/*
|
||||
* Because that device tree does not encode ROM script address,
|
||||
* the RAM script in firmware is mandatory for device tree
|
||||
* probe, otherwise it fails.
|
||||
*/
|
||||
ret = of_property_read_string(np, "fsl,sdma-ram-script-name",
|
||||
&fw_name);
|
||||
if (ret) {
|
||||
dev_warn(&pdev->dev, "failed to get firmware name\n");
|
||||
} else {
|
||||
ret = sdma_get_firmware(sdma, fw_name);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev, "failed to get firmware from device tree\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_register:
|
||||
|
||||
@@ -1030,7 +1030,7 @@ rcar_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
dma_addr_t dev_addr;
|
||||
|
||||
/* Someone calling slave DMA on a generic channel? */
|
||||
if (rchan->mid_rid < 0 || !sg_len) {
|
||||
if (rchan->mid_rid < 0 || !sg_len || !sg_dma_len(sgl)) {
|
||||
dev_warn(chan->device->dev,
|
||||
"%s: bad parameter: len=%d, id=%d\n",
|
||||
__func__, sg_len, rchan->mid_rid);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
static int edac_mc_log_ue = 1;
|
||||
static int edac_mc_log_ce = 1;
|
||||
static int edac_mc_panic_on_ue;
|
||||
static int edac_mc_poll_msec = 1000;
|
||||
static unsigned int edac_mc_poll_msec = 1000;
|
||||
|
||||
/* Getter functions for above */
|
||||
int edac_mc_get_log_ue(void)
|
||||
@@ -45,30 +45,30 @@ int edac_mc_get_panic_on_ue(void)
|
||||
}
|
||||
|
||||
/* this is temporary */
|
||||
int edac_mc_get_poll_msec(void)
|
||||
unsigned int edac_mc_get_poll_msec(void)
|
||||
{
|
||||
return edac_mc_poll_msec;
|
||||
}
|
||||
|
||||
static int edac_set_poll_msec(const char *val, struct kernel_param *kp)
|
||||
{
|
||||
unsigned long l;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
ret = kstrtoul(val, 0, &l);
|
||||
ret = kstrtouint(val, 0, &i);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (l < 1000)
|
||||
if (i < 1000)
|
||||
return -EINVAL;
|
||||
|
||||
*((unsigned long *)kp->arg) = l;
|
||||
*((unsigned int *)kp->arg) = i;
|
||||
|
||||
/* notify edac_mc engine to reset the poll period */
|
||||
edac_mc_reset_delay_period(l);
|
||||
edac_mc_reset_delay_period(i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -82,7 +82,7 @@ MODULE_PARM_DESC(edac_mc_log_ue,
|
||||
module_param(edac_mc_log_ce, int, 0644);
|
||||
MODULE_PARM_DESC(edac_mc_log_ce,
|
||||
"Log correctable error to console: 0=off 1=on");
|
||||
module_param_call(edac_mc_poll_msec, edac_set_poll_msec, param_get_int,
|
||||
module_param_call(edac_mc_poll_msec, edac_set_poll_msec, param_get_uint,
|
||||
&edac_mc_poll_msec, 0644);
|
||||
MODULE_PARM_DESC(edac_mc_poll_msec, "Polling period in milliseconds");
|
||||
|
||||
@@ -426,6 +426,8 @@ static inline int nr_pages_per_csrow(struct csrow_info *csrow)
|
||||
static int edac_create_csrow_object(struct mem_ctl_info *mci,
|
||||
struct csrow_info *csrow, int index)
|
||||
{
|
||||
int err;
|
||||
|
||||
csrow->dev.type = &csrow_attr_type;
|
||||
csrow->dev.bus = mci->bus;
|
||||
csrow->dev.groups = csrow_dev_groups;
|
||||
@@ -438,7 +440,11 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
|
||||
edac_dbg(0, "creating (virtual) csrow node %s\n",
|
||||
dev_name(&csrow->dev));
|
||||
|
||||
return device_add(&csrow->dev);
|
||||
err = device_add(&csrow->dev);
|
||||
if (err)
|
||||
put_device(&csrow->dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Create a CSROW object under specifed edac_mc_device */
|
||||
|
||||
@@ -33,7 +33,7 @@ extern int edac_mc_get_log_ue(void);
|
||||
extern int edac_mc_get_log_ce(void);
|
||||
extern int edac_mc_get_panic_on_ue(void);
|
||||
extern int edac_get_poll_msec(void);
|
||||
extern int edac_mc_get_poll_msec(void);
|
||||
extern unsigned int edac_mc_get_poll_msec(void);
|
||||
|
||||
unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
|
||||
unsigned len);
|
||||
|
||||
@@ -821,9 +821,9 @@ static void omap_gpio_irq_shutdown(struct irq_data *d)
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
bank->irq_usage &= ~(BIT(offset));
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
if (!LINE_USED(bank->mod_usage, offset))
|
||||
omap_clear_gpio_debounce(bank, offset);
|
||||
omap_disable_gpio_module(bank, offset);
|
||||
@@ -865,8 +865,8 @@ static void omap_gpio_mask_irq(struct irq_data *d)
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
}
|
||||
|
||||
@@ -878,9 +878,6 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
if (trigger)
|
||||
omap_set_gpio_triggering(bank, offset, trigger);
|
||||
|
||||
omap_set_gpio_irqenable(bank, offset, 1);
|
||||
|
||||
/*
|
||||
@@ -888,9 +885,13 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
|
||||
* is cleared, thus after the handler has run. OMAP4 needs this done
|
||||
* after enabing the interrupt to clear the wakeup status.
|
||||
*/
|
||||
if (bank->level_mask & BIT(offset))
|
||||
if (bank->regs->leveldetect0 && bank->regs->wkup_en &&
|
||||
trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
|
||||
if (trigger)
|
||||
omap_set_gpio_triggering(bank, offset, trigger);
|
||||
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
}
|
||||
|
||||
@@ -1611,6 +1612,8 @@ static struct omap_gpio_reg_offs omap4_gpio_regs = {
|
||||
.clr_dataout = OMAP4_GPIO_CLEARDATAOUT,
|
||||
.irqstatus = OMAP4_GPIO_IRQSTATUS0,
|
||||
.irqstatus2 = OMAP4_GPIO_IRQSTATUS1,
|
||||
.irqstatus_raw0 = OMAP4_GPIO_IRQSTATUSRAW0,
|
||||
.irqstatus_raw1 = OMAP4_GPIO_IRQSTATUSRAW1,
|
||||
.irqenable = OMAP4_GPIO_IRQSTATUSSET0,
|
||||
.irqenable2 = OMAP4_GPIO_IRQSTATUSSET1,
|
||||
.set_irqenable = OMAP4_GPIO_IRQSTATUSSET0,
|
||||
|
||||
@@ -184,6 +184,25 @@ nvkm_i2c_fini(struct nvkm_subdev *subdev, bool suspend)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_i2c_preinit(struct nvkm_subdev *subdev)
|
||||
{
|
||||
struct nvkm_i2c *i2c = nvkm_i2c(subdev);
|
||||
struct nvkm_i2c_bus *bus;
|
||||
struct nvkm_i2c_pad *pad;
|
||||
|
||||
/*
|
||||
* We init our i2c busses as early as possible, since they may be
|
||||
* needed by the vbios init scripts on some cards
|
||||
*/
|
||||
list_for_each_entry(pad, &i2c->pad, head)
|
||||
nvkm_i2c_pad_init(pad);
|
||||
list_for_each_entry(bus, &i2c->bus, head)
|
||||
nvkm_i2c_bus_init(bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_i2c_init(struct nvkm_subdev *subdev)
|
||||
{
|
||||
@@ -238,6 +257,7 @@ nvkm_i2c_dtor(struct nvkm_subdev *subdev)
|
||||
static const struct nvkm_subdev_func
|
||||
nvkm_i2c = {
|
||||
.dtor = nvkm_i2c_dtor,
|
||||
.preinit = nvkm_i2c_preinit,
|
||||
.init = nvkm_i2c_init,
|
||||
.fini = nvkm_i2c_fini,
|
||||
.intr = nvkm_i2c_intr,
|
||||
|
||||
@@ -2466,7 +2466,14 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
|
||||
if (!of_property_read_u32(dev->of_node, "dsi,lanes", &val))
|
||||
dsi->lanes = val;
|
||||
|
||||
return mipi_dsi_attach(dsi);
|
||||
err = mipi_dsi_attach(dsi);
|
||||
if (err) {
|
||||
struct panel_simple *panel = dev_get_drvdata(&dsi->dev);
|
||||
|
||||
drm_panel_remove(&panel->base);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int panel_simple_dsi_remove(struct mipi_dsi_device *dsi)
|
||||
|
||||
@@ -535,6 +535,9 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
|
||||
ret = wait_event_timeout(vgdev->resp_wq,
|
||||
atomic_read(&cache_ent->is_valid), 5 * HZ);
|
||||
|
||||
/* is_valid check must proceed before copy of the cache entry. */
|
||||
smp_rmb();
|
||||
|
||||
ptr = cache_ent->caps_cache;
|
||||
|
||||
copy_exit:
|
||||
|
||||
@@ -618,6 +618,8 @@ static void virtio_gpu_cmd_capset_cb(struct virtio_gpu_device *vgdev,
|
||||
cache_ent->id == le32_to_cpu(cmd->capset_id)) {
|
||||
memcpy(cache_ent->caps_cache, resp->capset_data,
|
||||
cache_ent->size);
|
||||
/* Copy must occur before is_valid is signalled. */
|
||||
smp_wmb();
|
||||
atomic_set(&cache_ent->is_valid, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ static int init_csc(struct ipu_ic *ic,
|
||||
writel(param, base++);
|
||||
|
||||
param = ((a[0] & 0x1fe0) >> 5) | (params->scale << 8) |
|
||||
(params->sat << 9);
|
||||
(params->sat << 10);
|
||||
writel(param, base++);
|
||||
|
||||
param = ((a[1] & 0x1f) << 27) | ((c[0][1] & 0x1ff) << 18) |
|
||||
|
||||
@@ -475,6 +475,7 @@
|
||||
#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a
|
||||
#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a
|
||||
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a
|
||||
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641 0x0641
|
||||
|
||||
#define USB_VENDOR_ID_HUION 0x256c
|
||||
#define USB_DEVICE_ID_HUION_TABLET 0x006e
|
||||
|
||||
@@ -82,6 +82,7 @@ static const struct hid_blacklist {
|
||||
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, HID_QUIRK_ALWAYS_POLL },
|
||||
|
||||
@@ -625,7 +625,7 @@ static int msc_buffer_contig_alloc(struct msc *msc, unsigned long size)
|
||||
goto err_out;
|
||||
|
||||
ret = -ENOMEM;
|
||||
page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
|
||||
page = alloc_pages(GFP_KERNEL | __GFP_ZERO | GFP_DMA32, order);
|
||||
if (!page)
|
||||
goto err_free_sgt;
|
||||
|
||||
|
||||
@@ -530,11 +530,12 @@ static int imx_keypad_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused imx_kbd_suspend(struct device *dev)
|
||||
static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct imx_keypad *kbd = platform_get_drvdata(pdev);
|
||||
struct input_dev *input_dev = kbd->input_dev;
|
||||
unsigned short reg_val = readw(kbd->mmio_base + KPSR);
|
||||
|
||||
/* imx kbd can wake up system even clock is disabled */
|
||||
mutex_lock(&input_dev->mutex);
|
||||
@@ -544,13 +545,20 @@ static int __maybe_unused imx_kbd_suspend(struct device *dev)
|
||||
|
||||
mutex_unlock(&input_dev->mutex);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
if (device_may_wakeup(&pdev->dev)) {
|
||||
if (reg_val & KBD_STAT_KPKD)
|
||||
reg_val |= KBD_STAT_KRIE;
|
||||
if (reg_val & KBD_STAT_KPKR)
|
||||
reg_val |= KBD_STAT_KDIE;
|
||||
writew(reg_val, kbd->mmio_base + KPSR);
|
||||
|
||||
enable_irq_wake(kbd->irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused imx_kbd_resume(struct device *dev)
|
||||
static int __maybe_unused imx_kbd_noirq_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct imx_keypad *kbd = platform_get_drvdata(pdev);
|
||||
@@ -574,7 +582,9 @@ err_clk:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume);
|
||||
static const struct dev_pm_ops imx_kbd_pm_ops = {
|
||||
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_kbd_noirq_suspend, imx_kbd_noirq_resume)
|
||||
};
|
||||
|
||||
static struct platform_driver imx_keypad_driver = {
|
||||
.driver = {
|
||||
|
||||
@@ -1191,6 +1191,8 @@ static const char * const middle_button_pnp_ids[] = {
|
||||
"LEN2132", /* ThinkPad P52 */
|
||||
"LEN2133", /* ThinkPad P72 w/ NFC */
|
||||
"LEN2134", /* ThinkPad P72 */
|
||||
"LEN0407",
|
||||
"LEN0408",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ Scott Hill shill@gtcocalcomp.com
|
||||
|
||||
/* Max size of a single report */
|
||||
#define REPORT_MAX_SIZE 10
|
||||
#define MAX_COLLECTION_LEVELS 10
|
||||
|
||||
|
||||
/* Bitmask whether pen is in range */
|
||||
@@ -224,8 +225,7 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
|
||||
char maintype = 'x';
|
||||
char globtype[12];
|
||||
int indent = 0;
|
||||
char indentstr[10] = "";
|
||||
|
||||
char indentstr[MAX_COLLECTION_LEVELS + 1] = { 0 };
|
||||
|
||||
dev_dbg(ddev, "======>>>>>>PARSE<<<<<<======\n");
|
||||
|
||||
@@ -351,6 +351,13 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
|
||||
case TAG_MAIN_COL_START:
|
||||
maintype = 'S';
|
||||
|
||||
if (indent == MAX_COLLECTION_LEVELS) {
|
||||
dev_err(ddev, "Collection level %d would exceed limit of %d\n",
|
||||
indent + 1,
|
||||
MAX_COLLECTION_LEVELS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == 0) {
|
||||
dev_dbg(ddev, "======>>>>>> Physical\n");
|
||||
strcpy(globtype, "Physical");
|
||||
@@ -370,8 +377,15 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
|
||||
break;
|
||||
|
||||
case TAG_MAIN_COL_END:
|
||||
dev_dbg(ddev, "<<<<<<======\n");
|
||||
maintype = 'E';
|
||||
|
||||
if (indent == 0) {
|
||||
dev_err(ddev, "Collection level already at zero\n");
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(ddev, "<<<<<<======\n");
|
||||
|
||||
indent--;
|
||||
for (x = 0; x < indent; x++)
|
||||
indentstr[x] = '-';
|
||||
|
||||
@@ -1963,6 +1963,9 @@ hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
|
||||
/* get endpoint base */
|
||||
idx = ((ep_addr & 0x7f) - 1) * 2;
|
||||
if (idx > 15)
|
||||
return -EIO;
|
||||
|
||||
if (ep_addr & 0x80)
|
||||
idx++;
|
||||
attr = ep->desc.bmAttributes;
|
||||
|
||||
@@ -389,11 +389,13 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
|
||||
|
||||
of_property_for_each_string(np, "mbox-names", prop, mbox_name) {
|
||||
if (!strncmp(name, mbox_name, strlen(name)))
|
||||
break;
|
||||
return mbox_request_channel(cl, index);
|
||||
index++;
|
||||
}
|
||||
|
||||
return mbox_request_channel(cl, index);
|
||||
dev_err(cl->dev, "%s() could not locate channel named \"%s\"\n",
|
||||
__func__, name);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
|
||||
|
||||
|
||||
@@ -1403,7 +1403,7 @@ static void cache_set_flush(struct closure *cl)
|
||||
kobject_put(&c->internal);
|
||||
kobject_del(&c->kobj);
|
||||
|
||||
if (c->gc_thread)
|
||||
if (!IS_ERR_OR_NULL(c->gc_thread))
|
||||
kthread_stop(c->gc_thread);
|
||||
|
||||
if (!IS_ERR_OR_NULL(c->root))
|
||||
|
||||
@@ -1561,9 +1561,7 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
|
||||
unsigned long freed;
|
||||
|
||||
c = container_of(shrink, struct dm_bufio_client, shrinker);
|
||||
if (sc->gfp_mask & __GFP_FS)
|
||||
dm_bufio_lock(c);
|
||||
else if (!dm_bufio_trylock(c))
|
||||
if (!dm_bufio_trylock(c))
|
||||
return SHRINK_STOP;
|
||||
|
||||
freed = __scan(c, sc->nr_to_scan, sc->gfp_mask);
|
||||
|
||||
@@ -220,8 +220,8 @@ static int verity_handle_err(struct dm_verity *v, enum verity_block_type type,
|
||||
BUG();
|
||||
}
|
||||
|
||||
DMERR("%s: %s block %llu is corrupted", v->data_dev->name, type_str,
|
||||
block);
|
||||
DMERR_LIMIT("%s: %s block %llu is corrupted", v->data_dev->name,
|
||||
type_str, block);
|
||||
|
||||
if (v->corrupted_errs == DM_VERITY_MAX_CORRUPTED_ERRS)
|
||||
DMERR("%s: reached maximum errors", v->data_dev->name);
|
||||
|
||||
@@ -7226,9 +7226,9 @@ static void status_unused(struct seq_file *seq)
|
||||
static int status_resync(struct seq_file *seq, struct mddev *mddev)
|
||||
{
|
||||
sector_t max_sectors, resync, res;
|
||||
unsigned long dt, db;
|
||||
sector_t rt;
|
||||
int scale;
|
||||
unsigned long dt, db = 0;
|
||||
sector_t rt, curr_mark_cnt, resync_mark_cnt;
|
||||
int scale, recovery_active;
|
||||
unsigned int per_milli;
|
||||
|
||||
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ||
|
||||
@@ -7298,22 +7298,30 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
|
||||
* db: blocks written from mark until now
|
||||
* rt: remaining time
|
||||
*
|
||||
* rt is a sector_t, so could be 32bit or 64bit.
|
||||
* So we divide before multiply in case it is 32bit and close
|
||||
* to the limit.
|
||||
* We scale the divisor (db) by 32 to avoid losing precision
|
||||
* near the end of resync when the number of remaining sectors
|
||||
* is close to 'db'.
|
||||
* We then divide rt by 32 after multiplying by db to compensate.
|
||||
* The '+1' avoids division by zero if db is very small.
|
||||
* rt is a sector_t, which is always 64bit now. We are keeping
|
||||
* the original algorithm, but it is not really necessary.
|
||||
*
|
||||
* Original algorithm:
|
||||
* So we divide before multiply in case it is 32bit and close
|
||||
* to the limit.
|
||||
* We scale the divisor (db) by 32 to avoid losing precision
|
||||
* near the end of resync when the number of remaining sectors
|
||||
* is close to 'db'.
|
||||
* We then divide rt by 32 after multiplying by db to compensate.
|
||||
* The '+1' avoids division by zero if db is very small.
|
||||
*/
|
||||
dt = ((jiffies - mddev->resync_mark) / HZ);
|
||||
if (!dt) dt++;
|
||||
db = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active))
|
||||
- mddev->resync_mark_cnt;
|
||||
|
||||
curr_mark_cnt = mddev->curr_mark_cnt;
|
||||
recovery_active = atomic_read(&mddev->recovery_active);
|
||||
resync_mark_cnt = mddev->resync_mark_cnt;
|
||||
|
||||
if (curr_mark_cnt >= (recovery_active + resync_mark_cnt))
|
||||
db = curr_mark_cnt - (recovery_active + resync_mark_cnt);
|
||||
|
||||
rt = max_sectors - resync; /* number of remaining sectors */
|
||||
sector_div(rt, db/32+1);
|
||||
rt = div64_u64(rt, db/32+1);
|
||||
rt *= dt;
|
||||
rt >>= 5;
|
||||
|
||||
|
||||
@@ -80,8 +80,8 @@ static int tua6100_set_params(struct dvb_frontend *fe)
|
||||
struct i2c_msg msg1 = { .addr = priv->i2c_address, .flags = 0, .buf = reg1, .len = 4 };
|
||||
struct i2c_msg msg2 = { .addr = priv->i2c_address, .flags = 0, .buf = reg2, .len = 3 };
|
||||
|
||||
#define _R 4
|
||||
#define _P 32
|
||||
#define _R_VAL 4
|
||||
#define _P_VAL 32
|
||||
#define _ri 4000000
|
||||
|
||||
// setup register 0
|
||||
@@ -96,14 +96,14 @@ static int tua6100_set_params(struct dvb_frontend *fe)
|
||||
else
|
||||
reg1[1] = 0x0c;
|
||||
|
||||
if (_P == 64)
|
||||
if (_P_VAL == 64)
|
||||
reg1[1] |= 0x40;
|
||||
if (c->frequency >= 1525000)
|
||||
reg1[1] |= 0x80;
|
||||
|
||||
// register 2
|
||||
reg2[1] = (_R >> 8) & 0x03;
|
||||
reg2[2] = _R;
|
||||
reg2[1] = (_R_VAL >> 8) & 0x03;
|
||||
reg2[2] = _R_VAL;
|
||||
if (c->frequency < 1455000)
|
||||
reg2[1] |= 0x1c;
|
||||
else if (c->frequency < 1630000)
|
||||
@@ -115,18 +115,18 @@ static int tua6100_set_params(struct dvb_frontend *fe)
|
||||
* The N divisor ratio (note: c->frequency is in kHz, but we
|
||||
* need it in Hz)
|
||||
*/
|
||||
prediv = (c->frequency * _R) / (_ri / 1000);
|
||||
div = prediv / _P;
|
||||
prediv = (c->frequency * _R_VAL) / (_ri / 1000);
|
||||
div = prediv / _P_VAL;
|
||||
reg1[1] |= (div >> 9) & 0x03;
|
||||
reg1[2] = div >> 1;
|
||||
reg1[3] = (div << 7);
|
||||
priv->frequency = ((div * _P) * (_ri / 1000)) / _R;
|
||||
priv->frequency = ((div * _P_VAL) * (_ri / 1000)) / _R_VAL;
|
||||
|
||||
// Finally, calculate and store the value for A
|
||||
reg1[3] |= (prediv - (div*_P)) & 0x7f;
|
||||
reg1[3] |= (prediv - (div*_P_VAL)) & 0x7f;
|
||||
|
||||
#undef _R
|
||||
#undef _P
|
||||
#undef _R_VAL
|
||||
#undef _P_VAL
|
||||
#undef _ri
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
|
||||
@@ -30,7 +30,7 @@ obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o
|
||||
obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o
|
||||
obj-$(CONFIG_VIDEO_ADV7842) += adv7842.o
|
||||
obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o
|
||||
obj-$(CONFIG_VIDEO_ADV7511) += adv7511.o
|
||||
obj-$(CONFIG_VIDEO_ADV7511) += adv7511-v4l2.o
|
||||
obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
|
||||
obj-$(CONFIG_VIDEO_VS6624) += vs6624.o
|
||||
obj-$(CONFIG_VIDEO_BT819) += bt819.o
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is named adv7511-v4l2.c so it doesn't conflict with the Analog
|
||||
* Device ADV7511 (config fragment CONFIG_DRM_I2C_ADV7511).
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
@@ -1581,6 +1581,7 @@ static int __coda_start_decoding(struct coda_ctx *ctx)
|
||||
coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
ctx->sequence_offset = ~0U;
|
||||
ctx->initialized = 1;
|
||||
|
||||
/* Update kfifo out pointer from coda bitstream read pointer */
|
||||
@@ -1966,12 +1967,17 @@ static void coda_finish_decode(struct coda_ctx *ctx)
|
||||
else if (ctx->display_idx < 0)
|
||||
ctx->hold = true;
|
||||
} else if (decoded_idx == -2) {
|
||||
if (ctx->display_idx >= 0 &&
|
||||
ctx->display_idx < ctx->num_internal_frames)
|
||||
ctx->sequence_offset++;
|
||||
/* no frame was decoded, we still return remaining buffers */
|
||||
} else if (decoded_idx < 0 || decoded_idx >= ctx->num_internal_frames) {
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"decoded frame index out of range: %d\n", decoded_idx);
|
||||
} else {
|
||||
val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1;
|
||||
val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM);
|
||||
if (ctx->sequence_offset == -1)
|
||||
ctx->sequence_offset = val;
|
||||
val -= ctx->sequence_offset;
|
||||
spin_lock_irqsave(&ctx->buffer_meta_lock, flags);
|
||||
if (!list_empty(&ctx->buffer_meta_list)) {
|
||||
@@ -2101,7 +2107,6 @@ irqreturn_t coda_irq_handler(int irq, void *data)
|
||||
if (ctx == NULL) {
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"Instance released before the end of transaction\n");
|
||||
mutex_unlock(&dev->coda_mutex);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
@@ -523,6 +523,11 @@ static int __init vpss_init(void)
|
||||
return -EBUSY;
|
||||
|
||||
oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4);
|
||||
if (unlikely(!oper_cfg.vpss_regs_base2)) {
|
||||
release_mem_region(VPSS_CLK_CTRL, 4);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
writel(VPSS_CLK_CTRL_VENCCLKEN |
|
||||
VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2);
|
||||
|
||||
|
||||
@@ -209,7 +209,6 @@ struct mcam_vb_buffer {
|
||||
struct list_head queue;
|
||||
struct mcam_dma_desc *dma_desc; /* Descriptor virtual address */
|
||||
dma_addr_t dma_desc_pa; /* Descriptor physical address */
|
||||
int dma_desc_nent; /* Number of mapped descriptors */
|
||||
};
|
||||
|
||||
static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_v4l2_buffer *vb)
|
||||
@@ -616,9 +615,11 @@ static void mcam_dma_contig_done(struct mcam_camera *cam, int frame)
|
||||
static void mcam_sg_next_buffer(struct mcam_camera *cam)
|
||||
{
|
||||
struct mcam_vb_buffer *buf;
|
||||
struct sg_table *sg_table;
|
||||
|
||||
buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue);
|
||||
list_del_init(&buf->queue);
|
||||
sg_table = vb2_dma_sg_plane_desc(&buf->vb_buf.vb2_buf, 0);
|
||||
/*
|
||||
* Very Bad Not Good Things happen if you don't clear
|
||||
* C1_DESC_ENA before making any descriptor changes.
|
||||
@@ -626,7 +627,7 @@ static void mcam_sg_next_buffer(struct mcam_camera *cam)
|
||||
mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA);
|
||||
mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa);
|
||||
mcam_reg_write(cam, REG_DESC_LEN_Y,
|
||||
buf->dma_desc_nent*sizeof(struct mcam_dma_desc));
|
||||
sg_table->nents * sizeof(struct mcam_dma_desc));
|
||||
mcam_reg_write(cam, REG_DESC_LEN_U, 0);
|
||||
mcam_reg_write(cam, REG_DESC_LEN_V, 0);
|
||||
mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
|
||||
|
||||
@@ -283,6 +283,14 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void raremono_device_release(struct v4l2_device *v4l2_dev)
|
||||
{
|
||||
struct raremono_device *radio = to_raremono_dev(v4l2_dev);
|
||||
|
||||
kfree(radio->buffer);
|
||||
kfree(radio);
|
||||
}
|
||||
|
||||
/* File system interface */
|
||||
static const struct v4l2_file_operations usb_raremono_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
@@ -307,12 +315,14 @@ static int usb_raremono_probe(struct usb_interface *intf,
|
||||
struct raremono_device *radio;
|
||||
int retval = 0;
|
||||
|
||||
radio = devm_kzalloc(&intf->dev, sizeof(struct raremono_device), GFP_KERNEL);
|
||||
if (radio)
|
||||
radio->buffer = devm_kmalloc(&intf->dev, BUFFER_LENGTH, GFP_KERNEL);
|
||||
|
||||
if (!radio || !radio->buffer)
|
||||
radio = kzalloc(sizeof(*radio), GFP_KERNEL);
|
||||
if (!radio)
|
||||
return -ENOMEM;
|
||||
radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
|
||||
if (!radio->buffer) {
|
||||
kfree(radio);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
radio->usbdev = interface_to_usbdev(intf);
|
||||
radio->intf = intf;
|
||||
@@ -336,7 +346,8 @@ static int usb_raremono_probe(struct usb_interface *intf,
|
||||
if (retval != 3 ||
|
||||
(get_unaligned_be16(&radio->buffer[1]) & 0xfff) == 0x0242) {
|
||||
dev_info(&intf->dev, "this is not Thanko's Raremono.\n");
|
||||
return -ENODEV;
|
||||
retval = -ENODEV;
|
||||
goto free_mem;
|
||||
}
|
||||
|
||||
dev_info(&intf->dev, "Thanko's Raremono connected: (%04X:%04X)\n",
|
||||
@@ -345,7 +356,7 @@ static int usb_raremono_probe(struct usb_interface *intf,
|
||||
retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
|
||||
if (retval < 0) {
|
||||
dev_err(&intf->dev, "couldn't register v4l2_device\n");
|
||||
return retval;
|
||||
goto free_mem;
|
||||
}
|
||||
|
||||
mutex_init(&radio->lock);
|
||||
@@ -357,6 +368,7 @@ static int usb_raremono_probe(struct usb_interface *intf,
|
||||
radio->vdev.ioctl_ops = &usb_raremono_ioctl_ops;
|
||||
radio->vdev.lock = &radio->lock;
|
||||
radio->vdev.release = video_device_release_empty;
|
||||
radio->v4l2_dev.release = raremono_device_release;
|
||||
|
||||
usb_set_intfdata(intf, &radio->v4l2_dev);
|
||||
|
||||
@@ -372,6 +384,10 @@ static int usb_raremono_probe(struct usb_interface *intf,
|
||||
}
|
||||
dev_err(&intf->dev, "could not register video device\n");
|
||||
v4l2_device_unregister(&radio->v4l2_dev);
|
||||
|
||||
free_mem:
|
||||
kfree(radio->buffer);
|
||||
kfree(radio);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -553,6 +553,7 @@ int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
|
||||
|
||||
/* Register with V4L2 subsystem as RADIO device */
|
||||
if (video_register_device(&gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
|
||||
v4l2_device_unregister(&fmdev->v4l2_dev);
|
||||
fmerr("Could not register video device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -566,6 +567,8 @@ int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
|
||||
if (ret < 0) {
|
||||
fmerr("(fmdev): Can't init ctrl handler\n");
|
||||
v4l2_ctrl_handler_free(&fmdev->ctrl_handler);
|
||||
video_unregister_device(fmdev->radio_dev);
|
||||
v4l2_device_unregister(&fmdev->v4l2_dev);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
||||
@@ -884,7 +884,6 @@ static void cpia2_usb_disconnect(struct usb_interface *intf)
|
||||
cpia2_unregister_camera(cam);
|
||||
v4l2_device_disconnect(&cam->v4l2_dev);
|
||||
mutex_unlock(&cam->v4l2_lock);
|
||||
v4l2_device_put(&cam->v4l2_dev);
|
||||
|
||||
if(cam->buffers) {
|
||||
DBG("Wakeup waiting processes\n");
|
||||
@@ -897,6 +896,8 @@ static void cpia2_usb_disconnect(struct usb_interface *intf)
|
||||
DBG("Releasing interface\n");
|
||||
usb_driver_release_interface(&cpia2_driver, intf);
|
||||
|
||||
v4l2_device_put(&cam->v4l2_dev);
|
||||
|
||||
LOG("CPiA2 camera disconnected.\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -286,12 +286,15 @@ EXPORT_SYMBOL(dvb_usb_device_init);
|
||||
void dvb_usb_device_exit(struct usb_interface *intf)
|
||||
{
|
||||
struct dvb_usb_device *d = usb_get_intfdata(intf);
|
||||
const char *name = "generic DVB-USB module";
|
||||
const char *default_name = "generic DVB-USB module";
|
||||
char name[40];
|
||||
|
||||
usb_set_intfdata(intf, NULL);
|
||||
if (d != NULL && d->desc != NULL) {
|
||||
name = d->desc->name;
|
||||
strscpy(name, d->desc->name, sizeof(name));
|
||||
dvb_usb_exit(d);
|
||||
} else {
|
||||
strscpy(name, default_name, sizeof(name));
|
||||
}
|
||||
info("%s successfully deinitialized and disconnected.", name);
|
||||
|
||||
|
||||
@@ -2189,16 +2189,15 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
|
||||
v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step,
|
||||
&def, &flags);
|
||||
|
||||
is_menu = (cfg->type == V4L2_CTRL_TYPE_MENU ||
|
||||
cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU);
|
||||
is_menu = (type == V4L2_CTRL_TYPE_MENU ||
|
||||
type == V4L2_CTRL_TYPE_INTEGER_MENU);
|
||||
if (is_menu)
|
||||
WARN_ON(step);
|
||||
else
|
||||
WARN_ON(cfg->menu_skip_mask);
|
||||
if (cfg->type == V4L2_CTRL_TYPE_MENU && qmenu == NULL)
|
||||
if (type == V4L2_CTRL_TYPE_MENU && !qmenu) {
|
||||
qmenu = v4l2_ctrl_get_menu(cfg->id);
|
||||
else if (cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU &&
|
||||
qmenu_int == NULL) {
|
||||
} else if (type == V4L2_CTRL_TYPE_INTEGER_MENU && !qmenu_int) {
|
||||
handler_set_err(hdl, -EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user