Merge 4.9.67 into android-4.9
Changes in 4.9.67 ARM: dts: LogicPD Torpedo: Fix camera pin mux ARM: dts: omap3: logicpd-torpedo-37xx-devkit: Fix MMC1 cd-gpio mm, thp: Do not make page table dirty unconditionally in touch_p[mu]d() mm/cma: fix alloc_contig_range ret code/potential leak mm, hugetlbfs: introduce ->split() to vm_operations_struct mm/madvise.c: fix madvise() infinite loop under special circumstances btrfs: clear space cache inode generation always nfsd: Fix stateid races between OPEN and CLOSE nfsd: Fix another OPEN stateid race nfsd: fix panic in posix_unblock_lock called from nfs4_laundromat mfd: twl4030-power: Fix pmic for boards that need vmmc1 on reboot ARM: OMAP2+: Fix WL1283 Bluetooth Baud Rate KVM: x86: pvclock: Handle first-time write to pvclock-page contains random junk KVM: x86: Exit to user-mode on #UD intercept when emulator requires KVM: x86: inject exceptions produced by x86_decode_insn KVM: lapic: Split out x2apic ldr calculation KVM: lapic: Fixup LDR on load in x2apic mmc: core: Do not leave the block driver in a suspended state mmc: core: prepend 0x to OCR entry in sysfs eeprom: at24: fix reading from 24MAC402/24MAC602 eeprom: at24: correctly set the size for at24mac402 eeprom: at24: check at24_read/write arguments i2c: i801: Fix Failed to allocate irq -2147483648 error bcache: Fix building error on MIPS hwmon: (jc42) optionally try to disable the SMBUS timeout nvme-pci: add quirk for delay before CHK RDY for WDC SN200 Revert "drm/radeon: dont switch vt on suspend" drm/amdgpu: potential uninitialized variable in amdgpu_vce_ring_parse_cs() drm/amdgpu: Potential uninitialized variable in amdgpu_vm_update_directories() drm/radeon: fix atombios on big endian drm/panel: simple: Add missing panel_simple_unprepare() calls drm/hisilicon: Ensure LDI regs are properly configured. drm/ttm: once more fix ttm_buffer_object_transfer drm/amd/pp: fix typecast error in powerplay. Revert "x86/entry/64: Add missing irqflags tracing to native_load_gs_index()" NFS: revalidate "." etc correctly on "open". drm/i915: Don't try indexed reads to alternate slave addresses drm/i915: Prevent zero length "index" write Linux 4.9.67 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -34,6 +34,10 @@ Required properties:
|
||||
|
||||
- reg: I2C address
|
||||
|
||||
Optional properties:
|
||||
- smbus-timeout-disable: When set, the smbus timeout function will be disabled.
|
||||
This is not supported on all chips.
|
||||
|
||||
Example:
|
||||
|
||||
temp-sensor@1a {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 66
|
||||
SUBLEVEL = 67
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc1_pins &mmc1_cd>;
|
||||
cd-gpios = <&gpio4 31 IRQ_TYPE_LEVEL_LOW>; /* gpio127 */
|
||||
cd-gpios = <&gpio4 31 GPIO_ACTIVE_LOW>; /* gpio127 */
|
||||
vmmc-supply = <&vmmc1>;
|
||||
bus-width = <4>;
|
||||
cap-power-off-card;
|
||||
@@ -249,9 +249,9 @@
|
||||
OMAP3_CORE1_IOPAD(0x2110, PIN_INPUT | MUX_MODE0) /* cam_xclka.cam_xclka */
|
||||
OMAP3_CORE1_IOPAD(0x2112, PIN_INPUT | MUX_MODE0) /* cam_pclk.cam_pclk */
|
||||
|
||||
OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE0) /* cam_d0.cam_d0 */
|
||||
OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0) /* cam_d1.cam_d1 */
|
||||
OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0) /* cam_d2.cam_d2 */
|
||||
OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0) /* cam_d0.cam_d0 */
|
||||
OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0) /* cam_d1.cam_d1 */
|
||||
OMAP3_CORE1_IOPAD(0x211a, PIN_INPUT | MUX_MODE0) /* cam_d2.cam_d2 */
|
||||
OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT | MUX_MODE0) /* cam_d3.cam_d3 */
|
||||
OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT | MUX_MODE0) /* cam_d4.cam_d4 */
|
||||
OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT | MUX_MODE0) /* cam_d5.cam_d5 */
|
||||
|
||||
@@ -162,7 +162,7 @@ static struct ti_st_plat_data wilink7_pdata = {
|
||||
.nshutdown_gpio = 162,
|
||||
.dev_name = "/dev/ttyO1",
|
||||
.flow_cntrl = 1,
|
||||
.baud_rate = 300000,
|
||||
.baud_rate = 3000000,
|
||||
};
|
||||
|
||||
static struct platform_device wl128x_device = {
|
||||
|
||||
@@ -54,19 +54,15 @@ ENTRY(native_usergs_sysret64)
|
||||
ENDPROC(native_usergs_sysret64)
|
||||
#endif /* CONFIG_PARAVIRT */
|
||||
|
||||
.macro TRACE_IRQS_FLAGS flags:req
|
||||
.macro TRACE_IRQS_IRETQ
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
bt $9, \flags /* interrupts off? */
|
||||
bt $9, EFLAGS(%rsp) /* interrupts off? */
|
||||
jnc 1f
|
||||
TRACE_IRQS_ON
|
||||
1:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro TRACE_IRQS_IRETQ
|
||||
TRACE_IRQS_FLAGS EFLAGS(%rsp)
|
||||
.endm
|
||||
|
||||
/*
|
||||
* When dynamic function tracer is enabled it will add a breakpoint
|
||||
* to all locations that it is about to modify, sync CPUs, update
|
||||
@@ -872,13 +868,11 @@ idtentry simd_coprocessor_error do_simd_coprocessor_error has_error_code=0
|
||||
ENTRY(native_load_gs_index)
|
||||
pushfq
|
||||
DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI)
|
||||
TRACE_IRQS_OFF
|
||||
SWAPGS
|
||||
.Lgs_change:
|
||||
movl %edi, %gs
|
||||
2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE
|
||||
SWAPGS
|
||||
TRACE_IRQS_FLAGS (%rsp)
|
||||
popfq
|
||||
ret
|
||||
END(native_load_gs_index)
|
||||
|
||||
+11
-1
@@ -246,9 +246,14 @@ static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id)
|
||||
recalculate_apic_map(apic->vcpu->kvm);
|
||||
}
|
||||
|
||||
static inline u32 kvm_apic_calc_x2apic_ldr(u32 id)
|
||||
{
|
||||
return ((id >> 4) << 16) | (1 << (id & 0xf));
|
||||
}
|
||||
|
||||
static inline void kvm_apic_set_x2apic_id(struct kvm_lapic *apic, u32 id)
|
||||
{
|
||||
u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
|
||||
u32 ldr = kvm_apic_calc_x2apic_ldr(id);
|
||||
|
||||
kvm_lapic_set_reg(apic, APIC_ID, id);
|
||||
kvm_lapic_set_reg(apic, APIC_LDR, ldr);
|
||||
@@ -2029,6 +2034,7 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
if (apic_x2apic_mode(vcpu->arch.apic)) {
|
||||
u32 *id = (u32 *)(s->regs + APIC_ID);
|
||||
u32 *ldr = (u32 *)(s->regs + APIC_LDR);
|
||||
|
||||
if (vcpu->kvm->arch.x2apic_format) {
|
||||
if (*id != vcpu->vcpu_id)
|
||||
@@ -2039,6 +2045,10 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
|
||||
else
|
||||
*id <<= 24;
|
||||
}
|
||||
|
||||
/* In x2APIC mode, the LDR is fixed and based on the id */
|
||||
if (set)
|
||||
*ldr = kvm_apic_calc_x2apic_ldr(*id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -2149,6 +2149,8 @@ static int ud_interception(struct vcpu_svm *svm)
|
||||
int er;
|
||||
|
||||
er = emulate_instruction(&svm->vcpu, EMULTYPE_TRAP_UD);
|
||||
if (er == EMULATE_USER_EXIT)
|
||||
return 0;
|
||||
if (er != EMULATE_DONE)
|
||||
kvm_queue_exception(&svm->vcpu, UD_VECTOR);
|
||||
return 1;
|
||||
|
||||
@@ -5502,6 +5502,8 @@ static int handle_exception(struct kvm_vcpu *vcpu)
|
||||
return 1;
|
||||
}
|
||||
er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD);
|
||||
if (er == EMULATE_USER_EXIT)
|
||||
return 0;
|
||||
if (er != EMULATE_DONE)
|
||||
kvm_queue_exception(vcpu, UD_VECTOR);
|
||||
return 1;
|
||||
|
||||
@@ -1797,6 +1797,9 @@ static void kvm_setup_pvclock_page(struct kvm_vcpu *v)
|
||||
*/
|
||||
BUILD_BUG_ON(offsetof(struct pvclock_vcpu_time_info, version) != 0);
|
||||
|
||||
if (guest_hv_clock.version & 1)
|
||||
++guest_hv_clock.version; /* first time write, random junk */
|
||||
|
||||
vcpu->hv_clock.version = guest_hv_clock.version + 1;
|
||||
kvm_write_guest_cached(v->kvm, &vcpu->pv_time,
|
||||
&vcpu->hv_clock,
|
||||
@@ -5576,6 +5579,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
|
||||
if (reexecute_instruction(vcpu, cr2, write_fault_to_spt,
|
||||
emulation_type))
|
||||
return EMULATE_DONE;
|
||||
if (ctxt->have_exception && inject_emulated_exception(vcpu))
|
||||
return EMULATE_DONE;
|
||||
if (emulation_type & EMULTYPE_SKIP)
|
||||
return EMULATE_FAIL;
|
||||
return handle_emulation_failure(vcpu);
|
||||
|
||||
@@ -1788,34 +1788,32 @@ void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev)
|
||||
WREG32(mmBIOS_SCRATCH_0 + i, adev->bios_scratch[i]);
|
||||
}
|
||||
|
||||
/* Atom needs data in little endian format
|
||||
* so swap as appropriate when copying data to
|
||||
* or from atom. Note that atom operates on
|
||||
* dw units.
|
||||
/* Atom needs data in little endian format so swap as appropriate when copying
|
||||
* data to or from atom. Note that atom operates on dw units.
|
||||
*
|
||||
* Use to_le=true when sending data to atom and provide at least
|
||||
* ALIGN(num_bytes,4) bytes in the dst buffer.
|
||||
*
|
||||
* Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
|
||||
* byes in the src buffer.
|
||||
*/
|
||||
void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */
|
||||
u32 *dst32, *src32;
|
||||
u32 src_tmp[5], dst_tmp[5];
|
||||
int i;
|
||||
u8 align_num_bytes = ALIGN(num_bytes, 4);
|
||||
|
||||
memcpy(src_tmp, src, num_bytes);
|
||||
src32 = (u32 *)src_tmp;
|
||||
dst32 = (u32 *)dst_tmp;
|
||||
if (to_le) {
|
||||
for (i = 0; i < ((num_bytes + 3) / 4); i++)
|
||||
dst32[i] = cpu_to_le32(src32[i]);
|
||||
memcpy(dst, dst_tmp, num_bytes);
|
||||
memcpy(src_tmp, src, num_bytes);
|
||||
for (i = 0; i < align_num_bytes / 4; i++)
|
||||
dst_tmp[i] = cpu_to_le32(src_tmp[i]);
|
||||
memcpy(dst, dst_tmp, align_num_bytes);
|
||||
} else {
|
||||
u8 dws = num_bytes & ~3;
|
||||
for (i = 0; i < ((num_bytes + 3) / 4); i++)
|
||||
dst32[i] = le32_to_cpu(src32[i]);
|
||||
memcpy(dst, dst_tmp, dws);
|
||||
if (num_bytes % 4) {
|
||||
for (i = 0; i < (num_bytes % 4); i++)
|
||||
dst[dws+i] = dst_tmp[dws+i];
|
||||
}
|
||||
memcpy(src_tmp, src, align_num_bytes);
|
||||
for (i = 0; i < align_num_bytes / 4; i++)
|
||||
dst_tmp[i] = le32_to_cpu(src_tmp[i]);
|
||||
memcpy(dst, dst_tmp, num_bytes);
|
||||
}
|
||||
#else
|
||||
memcpy(dst, src, num_bytes);
|
||||
|
||||
@@ -648,7 +648,7 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
|
||||
uint32_t allocated = 0;
|
||||
uint32_t tmp, handle = 0;
|
||||
uint32_t *size = &tmp;
|
||||
int i, r, idx = 0;
|
||||
int i, r = 0, idx = 0;
|
||||
|
||||
r = amdgpu_cs_sysvm_access_required(p);
|
||||
if (r)
|
||||
|
||||
@@ -744,7 +744,7 @@ error_free:
|
||||
int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm)
|
||||
{
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
r = amdgpu_vm_update_pd_or_shadow(adev, vm, true);
|
||||
if (r)
|
||||
|
||||
@@ -850,9 +850,9 @@ static int init_over_drive_limits(
|
||||
const ATOM_Tonga_POWERPLAYTABLE *powerplay_table)
|
||||
{
|
||||
hwmgr->platform_descriptor.overdriveLimit.engineClock =
|
||||
le16_to_cpu(powerplay_table->ulMaxODEngineClock);
|
||||
le32_to_cpu(powerplay_table->ulMaxODEngineClock);
|
||||
hwmgr->platform_descriptor.overdriveLimit.memoryClock =
|
||||
le16_to_cpu(powerplay_table->ulMaxODMemoryClock);
|
||||
le32_to_cpu(powerplay_table->ulMaxODMemoryClock);
|
||||
|
||||
hwmgr->platform_descriptor.minOverdriveVDDC = 0;
|
||||
hwmgr->platform_descriptor.maxOverdriveVDDC = 0;
|
||||
|
||||
@@ -521,9 +521,12 @@ static void ade_crtc_atomic_begin(struct drm_crtc *crtc,
|
||||
{
|
||||
struct ade_crtc *acrtc = to_ade_crtc(crtc);
|
||||
struct ade_hw_ctx *ctx = acrtc->ctx;
|
||||
struct drm_display_mode *mode = &crtc->state->mode;
|
||||
struct drm_display_mode *adj_mode = &crtc->state->adjusted_mode;
|
||||
|
||||
if (!ctx->power_on)
|
||||
(void)ade_power_up(ctx);
|
||||
ade_ldi_set_mode(acrtc, mode, adj_mode);
|
||||
}
|
||||
|
||||
static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
|
||||
@@ -430,7 +430,9 @@ static bool
|
||||
gmbus_is_index_read(struct i2c_msg *msgs, int i, int num)
|
||||
{
|
||||
return (i + 1 < num &&
|
||||
!(msgs[i].flags & I2C_M_RD) && msgs[i].len <= 2 &&
|
||||
msgs[i].addr == msgs[i + 1].addr &&
|
||||
!(msgs[i].flags & I2C_M_RD) &&
|
||||
(msgs[i].len == 1 || msgs[i].len == 2) &&
|
||||
(msgs[i + 1].flags & I2C_M_RD));
|
||||
}
|
||||
|
||||
|
||||
@@ -369,6 +369,7 @@ static int panel_simple_remove(struct device *dev)
|
||||
drm_panel_remove(&panel->base);
|
||||
|
||||
panel_simple_disable(&panel->base);
|
||||
panel_simple_unprepare(&panel->base);
|
||||
|
||||
if (panel->ddc)
|
||||
put_device(&panel->ddc->dev);
|
||||
@@ -384,6 +385,7 @@ static void panel_simple_shutdown(struct device *dev)
|
||||
struct panel_simple *panel = dev_get_drvdata(dev);
|
||||
|
||||
panel_simple_disable(&panel->base);
|
||||
panel_simple_unprepare(&panel->base);
|
||||
}
|
||||
|
||||
static const struct drm_display_mode ampire_am800480r3tmqwa1h_mode = {
|
||||
|
||||
@@ -45,34 +45,32 @@ static char *pre_emph_names[] = {
|
||||
|
||||
/***** radeon AUX functions *****/
|
||||
|
||||
/* Atom needs data in little endian format
|
||||
* so swap as appropriate when copying data to
|
||||
* or from atom. Note that atom operates on
|
||||
* dw units.
|
||||
/* Atom needs data in little endian format so swap as appropriate when copying
|
||||
* data to or from atom. Note that atom operates on dw units.
|
||||
*
|
||||
* Use to_le=true when sending data to atom and provide at least
|
||||
* ALIGN(num_bytes,4) bytes in the dst buffer.
|
||||
*
|
||||
* Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
|
||||
* byes in the src buffer.
|
||||
*/
|
||||
void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */
|
||||
u32 *dst32, *src32;
|
||||
u32 src_tmp[5], dst_tmp[5];
|
||||
int i;
|
||||
u8 align_num_bytes = ALIGN(num_bytes, 4);
|
||||
|
||||
memcpy(src_tmp, src, num_bytes);
|
||||
src32 = (u32 *)src_tmp;
|
||||
dst32 = (u32 *)dst_tmp;
|
||||
if (to_le) {
|
||||
for (i = 0; i < ((num_bytes + 3) / 4); i++)
|
||||
dst32[i] = cpu_to_le32(src32[i]);
|
||||
memcpy(dst, dst_tmp, num_bytes);
|
||||
memcpy(src_tmp, src, num_bytes);
|
||||
for (i = 0; i < align_num_bytes / 4; i++)
|
||||
dst_tmp[i] = cpu_to_le32(src_tmp[i]);
|
||||
memcpy(dst, dst_tmp, align_num_bytes);
|
||||
} else {
|
||||
u8 dws = num_bytes & ~3;
|
||||
for (i = 0; i < ((num_bytes + 3) / 4); i++)
|
||||
dst32[i] = le32_to_cpu(src32[i]);
|
||||
memcpy(dst, dst_tmp, dws);
|
||||
if (num_bytes % 4) {
|
||||
for (i = 0; i < (num_bytes % 4); i++)
|
||||
dst[dws+i] = dst_tmp[dws+i];
|
||||
}
|
||||
memcpy(src_tmp, src, align_num_bytes);
|
||||
for (i = 0; i < align_num_bytes / 4; i++)
|
||||
dst_tmp[i] = le32_to_cpu(src_tmp[i]);
|
||||
memcpy(dst, dst_tmp, num_bytes);
|
||||
}
|
||||
#else
|
||||
memcpy(dst, src, num_bytes);
|
||||
|
||||
@@ -252,7 +252,6 @@ static int radeonfb_create(struct drm_fb_helper *helper,
|
||||
}
|
||||
|
||||
info->par = rfbdev;
|
||||
info->skip_vt_switch = true;
|
||||
|
||||
ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
|
||||
if (ret) {
|
||||
|
||||
@@ -473,6 +473,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
|
||||
INIT_LIST_HEAD(&fbo->lru);
|
||||
INIT_LIST_HEAD(&fbo->swap);
|
||||
INIT_LIST_HEAD(&fbo->io_reserve_lru);
|
||||
mutex_init(&fbo->wu_mutex);
|
||||
fbo->moving = NULL;
|
||||
drm_vma_node_reset(&fbo->vma_node);
|
||||
atomic_set(&fbo->cpu_writers, 0);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -45,6 +46,7 @@ static const unsigned short normal_i2c[] = {
|
||||
#define JC42_REG_TEMP 0x05
|
||||
#define JC42_REG_MANID 0x06
|
||||
#define JC42_REG_DEVICEID 0x07
|
||||
#define JC42_REG_SMBUS 0x22 /* NXP and Atmel, possibly others? */
|
||||
|
||||
/* Status bits in temperature register */
|
||||
#define JC42_ALARM_CRIT_BIT 15
|
||||
@@ -73,6 +75,9 @@ static const unsigned short normal_i2c[] = {
|
||||
#define ONS_MANID 0x1b09 /* ON Semiconductor */
|
||||
#define STM_MANID 0x104a /* ST Microelectronics */
|
||||
|
||||
/* SMBUS register */
|
||||
#define SMBUS_STMOUT BIT(7) /* SMBus time-out, active low */
|
||||
|
||||
/* Supported chips */
|
||||
|
||||
/* Analog Devices */
|
||||
@@ -476,6 +481,22 @@ static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
|
||||
data->extended = !!(cap & JC42_CAP_RANGE);
|
||||
|
||||
if (device_property_read_bool(dev, "smbus-timeout-disable")) {
|
||||
int smbus;
|
||||
|
||||
/*
|
||||
* Not all chips support this register, but from a
|
||||
* quick read of various datasheets no chip appears
|
||||
* incompatible with the below attempt to disable
|
||||
* the timeout. And the whole thing is opt-in...
|
||||
*/
|
||||
smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS);
|
||||
if (smbus < 0)
|
||||
return smbus;
|
||||
i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS,
|
||||
smbus | SMBUS_STMOUT);
|
||||
}
|
||||
|
||||
config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG);
|
||||
if (config < 0)
|
||||
return config;
|
||||
|
||||
@@ -1592,6 +1592,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
/* Default timeout in interrupt mode: 200 ms */
|
||||
priv->adapter.timeout = HZ / 5;
|
||||
|
||||
if (dev->irq == IRQ_NOTCONNECTED)
|
||||
priv->features &= ~FEATURE_IRQ;
|
||||
|
||||
if (priv->features & FEATURE_IRQ) {
|
||||
u16 pcictl, pcists;
|
||||
|
||||
|
||||
@@ -477,7 +477,7 @@ int __bch_bucket_alloc_set(struct cache_set *c, unsigned reserve,
|
||||
if (b == -1)
|
||||
goto err;
|
||||
|
||||
k->ptr[i] = PTR(ca->buckets[b].gen,
|
||||
k->ptr[i] = MAKE_PTR(ca->buckets[b].gen,
|
||||
bucket_to_sector(c, b),
|
||||
ca->sb.nr_this_dev);
|
||||
|
||||
|
||||
@@ -584,7 +584,7 @@ static bool bch_extent_merge(struct btree_keys *bk, struct bkey *l, struct bkey
|
||||
return false;
|
||||
|
||||
for (i = 0; i < KEY_PTRS(l); i++)
|
||||
if (l->ptr[i] + PTR(0, KEY_SIZE(l), 0) != r->ptr[i] ||
|
||||
if (l->ptr[i] + MAKE_PTR(0, KEY_SIZE(l), 0) != r->ptr[i] ||
|
||||
PTR_BUCKET_NR(b->c, l, i) != PTR_BUCKET_NR(b->c, r, i))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -508,7 +508,7 @@ static void journal_reclaim(struct cache_set *c)
|
||||
continue;
|
||||
|
||||
ja->cur_idx = next;
|
||||
k->ptr[n++] = PTR(0,
|
||||
k->ptr[n++] = MAKE_PTR(0,
|
||||
bucket_to_sector(c, ca->sb.d[ja->cur_idx]),
|
||||
ca->sb.nr_this_dev);
|
||||
}
|
||||
|
||||
@@ -701,6 +701,7 @@ static struct twl4030_ins omap3_wrst_seq[] = {
|
||||
TWL_RESOURCE_RESET(RES_MAIN_REF),
|
||||
TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2),
|
||||
TWL_RESOURCE_RESET(RES_VUSB_3V1),
|
||||
TWL_RESOURCE_RESET(RES_VMMC1),
|
||||
TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1),
|
||||
TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0),
|
||||
TWL_RESOURCE_ON(RES_RESET),
|
||||
|
||||
@@ -365,7 +365,8 @@ static ssize_t at24_eeprom_read_mac(struct at24_data *at24, char *buf,
|
||||
memset(msg, 0, sizeof(msg));
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].buf = addrbuf;
|
||||
addrbuf[0] = 0x90 + offset;
|
||||
/* EUI-48 starts from 0x9a, EUI-64 from 0x98 */
|
||||
addrbuf[0] = 0xa0 - at24->chip.byte_len + offset;
|
||||
msg[0].len = 1;
|
||||
msg[1].addr = client->addr;
|
||||
msg[1].flags = I2C_M_RD;
|
||||
@@ -506,6 +507,9 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count)
|
||||
if (unlikely(!count))
|
||||
return count;
|
||||
|
||||
if (off + count > at24->chip.byte_len)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Read data from chip, protecting against concurrent updates
|
||||
* from this host, but not from other I2C masters.
|
||||
@@ -538,6 +542,9 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)
|
||||
if (unlikely(!count))
|
||||
return -EINVAL;
|
||||
|
||||
if (off + count > at24->chip.byte_len)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Write data to chip, protecting against concurrent updates
|
||||
* from this host, but not from other I2C masters.
|
||||
@@ -638,6 +645,16 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
dev_warn(&client->dev,
|
||||
"page_size looks suspicious (no power of 2)!\n");
|
||||
|
||||
/*
|
||||
* REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while
|
||||
* the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4.
|
||||
*
|
||||
* Eventually we'll get rid of the magic values altoghether in favor of
|
||||
* real structs, but for now just manually set the right size.
|
||||
*/
|
||||
if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4)
|
||||
chip.byte_len = 6;
|
||||
|
||||
/* Use I2C operations unless we're stuck with SMBus extensions. */
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
if (chip.flags & AT24_FLAG_ADDR16)
|
||||
|
||||
@@ -155,6 +155,9 @@ static int mmc_bus_suspend(struct device *dev)
|
||||
return ret;
|
||||
|
||||
ret = host->bus_ops->suspend(host);
|
||||
if (ret)
|
||||
pm_generic_resume(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -763,7 +763,7 @@ MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",
|
||||
MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
|
||||
MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
|
||||
MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
|
||||
MMC_DEV_ATTR(ocr, "%08x\n", card->ocr);
|
||||
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
|
||||
|
||||
static ssize_t mmc_fwrev_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
|
||||
@@ -683,7 +683,7 @@ MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
|
||||
MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
|
||||
MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
|
||||
MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
|
||||
MMC_DEV_ATTR(ocr, "%08x\n", card->ocr);
|
||||
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
|
||||
|
||||
|
||||
static ssize_t mmc_dsr_show(struct device *dev,
|
||||
|
||||
@@ -84,7 +84,7 @@ enum nvme_quirks {
|
||||
* NVME_QUIRK_DELAY_BEFORE_CHK_RDY quirk enabled. The value (in ms) was
|
||||
* found empirically.
|
||||
*/
|
||||
#define NVME_QUIRK_DELAY_AMOUNT 2000
|
||||
#define NVME_QUIRK_DELAY_AMOUNT 2300
|
||||
|
||||
enum nvme_ctrl_state {
|
||||
NVME_CTRL_NEW,
|
||||
|
||||
@@ -2109,6 +2109,8 @@ static const struct pci_device_id nvme_id_table[] = {
|
||||
.driver_data = NVME_QUIRK_IDENTIFY_CNS, },
|
||||
{ PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE(0x1c58, 0x0023), /* WDC SN200 adapter */
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE(0x1c5f, 0x0540), /* Memblaze Pblaze4 adapter */
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
|
||||
|
||||
@@ -3397,13 +3397,6 @@ again:
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* We've already setup this transaction, go ahead and exit */
|
||||
if (block_group->cache_generation == trans->transid &&
|
||||
i_size_read(inode)) {
|
||||
dcs = BTRFS_DC_SETUP;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
/*
|
||||
* We want to set the generation to 0, that way if anything goes wrong
|
||||
* from here on out we know not to trust this cache when we load up next
|
||||
@@ -3427,6 +3420,13 @@ again:
|
||||
}
|
||||
WARN_ON(ret);
|
||||
|
||||
/* We've already setup this transaction, go ahead and exit */
|
||||
if (block_group->cache_generation == trans->transid &&
|
||||
i_size_read(inode)) {
|
||||
dcs = BTRFS_DC_SETUP;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
if (i_size_read(inode) > 0) {
|
||||
ret = btrfs_check_trunc_cache_free_space(root,
|
||||
&root->fs_info->global_block_rsv);
|
||||
|
||||
+2
-1
@@ -1292,7 +1292,7 @@ static int nfs_weak_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
error = nfs_revalidate_inode(NFS_SERVER(inode), inode);
|
||||
error = nfs_lookup_verify_inode(inode, flags);
|
||||
dfprintk(LOOKUPCACHE, "NFS: %s: inode %lu is %s\n",
|
||||
__func__, inode->i_ino, error ? "invalid" : "valid");
|
||||
return !error;
|
||||
@@ -1443,6 +1443,7 @@ static int nfs4_lookup_revalidate(struct dentry *, unsigned int);
|
||||
|
||||
const struct dentry_operations nfs4_dentry_operations = {
|
||||
.d_revalidate = nfs4_lookup_revalidate,
|
||||
.d_weak_revalidate = nfs_weak_revalidate,
|
||||
.d_delete = nfs_dentry_delete,
|
||||
.d_iput = nfs_dentry_iput,
|
||||
.d_automount = nfs_d_automount,
|
||||
|
||||
+74
-25
@@ -3513,7 +3513,9 @@ nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
|
||||
/* ignore lock owners */
|
||||
if (local->st_stateowner->so_is_open_owner == 0)
|
||||
continue;
|
||||
if (local->st_stateowner == &oo->oo_owner) {
|
||||
if (local->st_stateowner != &oo->oo_owner)
|
||||
continue;
|
||||
if (local->st_stid.sc_type == NFS4_OPEN_STID) {
|
||||
ret = local;
|
||||
atomic_inc(&ret->st_stid.sc_count);
|
||||
break;
|
||||
@@ -3522,6 +3524,52 @@ nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_verify_open_stid(struct nfs4_stid *s)
|
||||
{
|
||||
__be32 ret = nfs_ok;
|
||||
|
||||
switch (s->sc_type) {
|
||||
default:
|
||||
break;
|
||||
case NFS4_CLOSED_STID:
|
||||
case NFS4_CLOSED_DELEG_STID:
|
||||
ret = nfserr_bad_stateid;
|
||||
break;
|
||||
case NFS4_REVOKED_DELEG_STID:
|
||||
ret = nfserr_deleg_revoked;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Lock the stateid st_mutex, and deal with races with CLOSE */
|
||||
static __be32
|
||||
nfsd4_lock_ol_stateid(struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
__be32 ret;
|
||||
|
||||
mutex_lock(&stp->st_mutex);
|
||||
ret = nfsd4_verify_open_stid(&stp->st_stid);
|
||||
if (ret != nfs_ok)
|
||||
mutex_unlock(&stp->st_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct nfs4_ol_stateid *
|
||||
nfsd4_find_and_lock_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
|
||||
{
|
||||
struct nfs4_ol_stateid *stp;
|
||||
for (;;) {
|
||||
spin_lock(&fp->fi_lock);
|
||||
stp = nfsd4_find_existing_open(fp, open);
|
||||
spin_unlock(&fp->fi_lock);
|
||||
if (!stp || nfsd4_lock_ol_stateid(stp) == nfs_ok)
|
||||
break;
|
||||
nfs4_put_stid(&stp->st_stid);
|
||||
}
|
||||
return stp;
|
||||
}
|
||||
|
||||
static struct nfs4_openowner *
|
||||
alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
|
||||
struct nfsd4_compound_state *cstate)
|
||||
@@ -3566,6 +3614,7 @@ init_open_stateid(struct nfs4_file *fp, struct nfsd4_open *open)
|
||||
mutex_init(&stp->st_mutex);
|
||||
mutex_lock(&stp->st_mutex);
|
||||
|
||||
retry:
|
||||
spin_lock(&oo->oo_owner.so_client->cl_lock);
|
||||
spin_lock(&fp->fi_lock);
|
||||
|
||||
@@ -3590,7 +3639,11 @@ out_unlock:
|
||||
spin_unlock(&fp->fi_lock);
|
||||
spin_unlock(&oo->oo_owner.so_client->cl_lock);
|
||||
if (retstp) {
|
||||
mutex_lock(&retstp->st_mutex);
|
||||
/* Handle races with CLOSE */
|
||||
if (nfsd4_lock_ol_stateid(retstp) != nfs_ok) {
|
||||
nfs4_put_stid(&retstp->st_stid);
|
||||
goto retry;
|
||||
}
|
||||
/* To keep mutex tracking happy */
|
||||
mutex_unlock(&stp->st_mutex);
|
||||
stp = retstp;
|
||||
@@ -4400,6 +4453,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
||||
struct nfs4_ol_stateid *stp = NULL;
|
||||
struct nfs4_delegation *dp = NULL;
|
||||
__be32 status;
|
||||
bool new_stp = false;
|
||||
|
||||
/*
|
||||
* Lookup file; if found, lookup stateid and check open request,
|
||||
@@ -4411,9 +4465,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
||||
status = nfs4_check_deleg(cl, open, &dp);
|
||||
if (status)
|
||||
goto out;
|
||||
spin_lock(&fp->fi_lock);
|
||||
stp = nfsd4_find_existing_open(fp, open);
|
||||
spin_unlock(&fp->fi_lock);
|
||||
stp = nfsd4_find_and_lock_existing_open(fp, open);
|
||||
} else {
|
||||
open->op_file = NULL;
|
||||
status = nfserr_bad_stateid;
|
||||
@@ -4421,35 +4473,31 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!stp) {
|
||||
stp = init_open_stateid(fp, open);
|
||||
if (!open->op_stp)
|
||||
new_stp = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* OPEN the file, or upgrade an existing OPEN.
|
||||
* If truncate fails, the OPEN fails.
|
||||
*
|
||||
* stp is already locked.
|
||||
*/
|
||||
if (stp) {
|
||||
if (!new_stp) {
|
||||
/* Stateid was found, this is an OPEN upgrade */
|
||||
mutex_lock(&stp->st_mutex);
|
||||
status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
|
||||
if (status) {
|
||||
mutex_unlock(&stp->st_mutex);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* stp is returned locked. */
|
||||
stp = init_open_stateid(fp, open);
|
||||
/* See if we lost the race to some other thread */
|
||||
if (stp->st_access_bmap != 0) {
|
||||
status = nfs4_upgrade_open(rqstp, fp, current_fh,
|
||||
stp, open);
|
||||
if (status) {
|
||||
mutex_unlock(&stp->st_mutex);
|
||||
goto out;
|
||||
}
|
||||
goto upgrade_out;
|
||||
}
|
||||
status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
|
||||
if (status) {
|
||||
mutex_unlock(&stp->st_mutex);
|
||||
stp->st_stid.sc_type = NFS4_CLOSED_STID;
|
||||
release_open_stateid(stp);
|
||||
mutex_unlock(&stp->st_mutex);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -4458,7 +4506,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
||||
if (stp->st_clnt_odstate == open->op_odstate)
|
||||
open->op_odstate = NULL;
|
||||
}
|
||||
upgrade_out:
|
||||
|
||||
nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid);
|
||||
mutex_unlock(&stp->st_mutex);
|
||||
|
||||
@@ -4684,7 +4732,7 @@ nfs4_laundromat(struct nfsd_net *nn)
|
||||
spin_unlock(&nn->blocked_locks_lock);
|
||||
|
||||
while (!list_empty(&reaplist)) {
|
||||
nbl = list_first_entry(&nn->blocked_locks_lru,
|
||||
nbl = list_first_entry(&reaplist,
|
||||
struct nfsd4_blocked_lock, nbl_lru);
|
||||
list_del_init(&nbl->nbl_lru);
|
||||
posix_unblock_lock(&nbl->nbl_lock);
|
||||
@@ -5314,7 +5362,6 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
|
||||
bool unhashed;
|
||||
LIST_HEAD(reaplist);
|
||||
|
||||
s->st_stid.sc_type = NFS4_CLOSED_STID;
|
||||
spin_lock(&clp->cl_lock);
|
||||
unhashed = unhash_open_stateid(s, &reaplist);
|
||||
|
||||
@@ -5353,10 +5400,12 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
nfsd4_bump_seqid(cstate, status);
|
||||
if (status)
|
||||
goto out;
|
||||
|
||||
stp->st_stid.sc_type = NFS4_CLOSED_STID;
|
||||
nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
|
||||
mutex_unlock(&stp->st_mutex);
|
||||
|
||||
nfsd4_close_open_stateid(stp);
|
||||
mutex_unlock(&stp->st_mutex);
|
||||
|
||||
/* put reference from nfs4_preprocess_seqid_op */
|
||||
nfs4_put_stid(&stp->st_stid);
|
||||
@@ -7094,7 +7143,7 @@ nfs4_state_shutdown_net(struct net *net)
|
||||
spin_unlock(&nn->blocked_locks_lock);
|
||||
|
||||
while (!list_empty(&reaplist)) {
|
||||
nbl = list_first_entry(&nn->blocked_locks_lru,
|
||||
nbl = list_first_entry(&reaplist,
|
||||
struct nfsd4_blocked_lock, nbl_lru);
|
||||
list_del_init(&nbl->nbl_lru);
|
||||
posix_unblock_lock(&nbl->nbl_lock);
|
||||
|
||||
@@ -351,6 +351,7 @@ struct fault_env {
|
||||
struct vm_operations_struct {
|
||||
void (*open)(struct vm_area_struct * area);
|
||||
void (*close)(struct vm_area_struct * area);
|
||||
int (*split)(struct vm_area_struct * area, unsigned long addr);
|
||||
int (*mremap)(struct vm_area_struct * area);
|
||||
int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
|
||||
int (*pmd_fault)(struct vm_area_struct *, unsigned long address,
|
||||
|
||||
@@ -90,7 +90,7 @@ PTR_FIELD(PTR_GEN, 0, 8)
|
||||
|
||||
#define PTR_CHECK_DEV ((1 << PTR_DEV_BITS) - 1)
|
||||
|
||||
#define PTR(gen, offset, dev) \
|
||||
#define MAKE_PTR(gen, offset, dev) \
|
||||
((((__u64) dev) << 51) | ((__u64) offset) << 8 | gen)
|
||||
|
||||
/* Bkey utility code */
|
||||
|
||||
+7
-12
@@ -745,20 +745,15 @@ int vmf_insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
|
||||
EXPORT_SYMBOL_GPL(vmf_insert_pfn_pmd);
|
||||
|
||||
static void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
|
||||
pmd_t *pmd)
|
||||
pmd_t *pmd, int flags)
|
||||
{
|
||||
pmd_t _pmd;
|
||||
|
||||
/*
|
||||
* We should set the dirty bit only for FOLL_WRITE but for now
|
||||
* the dirty bit in the pmd is meaningless. And if the dirty
|
||||
* bit will become meaningful and we'll only set it with
|
||||
* FOLL_WRITE, an atomic set_bit will be required on the pmd to
|
||||
* set the young bit, instead of the current set_pmd_at.
|
||||
*/
|
||||
_pmd = pmd_mkyoung(pmd_mkdirty(*pmd));
|
||||
_pmd = pmd_mkyoung(*pmd);
|
||||
if (flags & FOLL_WRITE)
|
||||
_pmd = pmd_mkdirty(_pmd);
|
||||
if (pmdp_set_access_flags(vma, addr & HPAGE_PMD_MASK,
|
||||
pmd, _pmd, 1))
|
||||
pmd, _pmd, flags & FOLL_WRITE))
|
||||
update_mmu_cache_pmd(vma, addr, pmd);
|
||||
}
|
||||
|
||||
@@ -787,7 +782,7 @@ struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr,
|
||||
return NULL;
|
||||
|
||||
if (flags & FOLL_TOUCH)
|
||||
touch_pmd(vma, addr, pmd);
|
||||
touch_pmd(vma, addr, pmd, flags);
|
||||
|
||||
/*
|
||||
* device mapped pages can only be returned if the
|
||||
@@ -1158,7 +1153,7 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
|
||||
page = pmd_page(*pmd);
|
||||
VM_BUG_ON_PAGE(!PageHead(page) && !is_zone_device_page(page), page);
|
||||
if (flags & FOLL_TOUCH)
|
||||
touch_pmd(vma, addr, pmd);
|
||||
touch_pmd(vma, addr, pmd, flags);
|
||||
if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) {
|
||||
/*
|
||||
* We don't mlock() pte-mapped THPs. This way we can avoid
|
||||
|
||||
@@ -3135,6 +3135,13 @@ static void hugetlb_vm_op_close(struct vm_area_struct *vma)
|
||||
}
|
||||
}
|
||||
|
||||
static int hugetlb_vm_op_split(struct vm_area_struct *vma, unsigned long addr)
|
||||
{
|
||||
if (addr & ~(huge_page_mask(hstate_vma(vma))))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot handle pagefaults against hugetlb pages at all. They cause
|
||||
* handle_mm_fault() to try to instantiate regular-sized pages in the
|
||||
@@ -3151,6 +3158,7 @@ const struct vm_operations_struct hugetlb_vm_ops = {
|
||||
.fault = hugetlb_vm_op_fault,
|
||||
.open = hugetlb_vm_op_open,
|
||||
.close = hugetlb_vm_op_close,
|
||||
.split = hugetlb_vm_op_split,
|
||||
};
|
||||
|
||||
static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page,
|
||||
|
||||
+1
-3
@@ -228,15 +228,14 @@ static long madvise_willneed(struct vm_area_struct *vma,
|
||||
{
|
||||
struct file *file = vma->vm_file;
|
||||
|
||||
*prev = vma;
|
||||
#ifdef CONFIG_SWAP
|
||||
if (!file) {
|
||||
*prev = vma;
|
||||
force_swapin_readahead(vma, start, end);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (shmem_mapping(file->f_mapping)) {
|
||||
*prev = vma;
|
||||
force_shm_swapin_readahead(vma, start, end,
|
||||
file->f_mapping);
|
||||
return 0;
|
||||
@@ -251,7 +250,6 @@ static long madvise_willneed(struct vm_area_struct *vma,
|
||||
return 0;
|
||||
}
|
||||
|
||||
*prev = vma;
|
||||
start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
|
||||
if (end > vma->vm_end)
|
||||
end = vma->vm_end;
|
||||
|
||||
@@ -2547,9 +2547,11 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
|
||||
struct vm_area_struct *new;
|
||||
int err;
|
||||
|
||||
if (is_vm_hugetlb_page(vma) && (addr &
|
||||
~(huge_page_mask(hstate_vma(vma)))))
|
||||
return -EINVAL;
|
||||
if (vma->vm_ops && vma->vm_ops->split) {
|
||||
err = vma->vm_ops->split(vma, addr);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
|
||||
if (!new)
|
||||
|
||||
+8
-1
@@ -7309,11 +7309,18 @@ int alloc_contig_range(unsigned long start, unsigned long end,
|
||||
|
||||
/*
|
||||
* In case of -EBUSY, we'd like to know which page causes problem.
|
||||
* So, just fall through. We will check it in test_pages_isolated().
|
||||
* So, just fall through. test_pages_isolated() has a tracepoint
|
||||
* which will report the busy page.
|
||||
*
|
||||
* It is possible that busy pages could become available before
|
||||
* the call to test_pages_isolated, and the range will actually be
|
||||
* allocated. So, if we fall through be sure to clear ret so that
|
||||
* -EBUSY is not accidentally used or returned to caller.
|
||||
*/
|
||||
ret = __alloc_contig_migrate_range(&cc, start, end);
|
||||
if (ret && ret != -EBUSY)
|
||||
goto done;
|
||||
ret =0;
|
||||
|
||||
/*
|
||||
* Pages from [start, end) are within a MAX_ORDER_NR_PAGES
|
||||
|
||||
Reference in New Issue
Block a user