diff --git a/Makefile b/Makefile
index 73e93e596e50..d2baacc1b0f6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 4
 PATCHLEVEL = 14
-SUBLEVEL = 178
+SUBLEVEL = 179
 EXTRAVERSION =
 NAME = Petit Gorille
 
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index fc300ce3ae8e..afb1bc104a6f 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -227,13 +227,13 @@ int acpi_device_set_power(struct acpi_device *device, int 
state)
  end:
        if (result) {
                dev_warn(&device->dev, "Failed to change power state to %s\n",
-                        acpi_power_state_string(state));
+                        acpi_power_state_string(target_state));
        } else {
                device->power.state = target_state;
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Device [%s] transitioned to %s\n",
                                  device->pnp.bus_id,
-                                 acpi_power_state_string(state)));
+                                 acpi_power_state_string(target_state)));
        }
 
        return result;
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index e39336127741..d19a602beebd 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -552,8 +552,8 @@ static int dmatest_func(void *data)
        flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
 
        ktime = ktime_get();
-       while (!kthread_should_stop()
-              && !(params->iterations && total_tests >= params->iterations)) {
+       while (!(kthread_should_stop() ||
+              (params->iterations && total_tests >= params->iterations))) {
                struct dma_async_tx_descriptor *tx = NULL;
                struct dmaengine_unmap_data *um;
                dma_addr_t srcs[src_cnt];
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index dfdc7d3147fb..51276dd0d864 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4502,7 +4502,7 @@ static struct drm_display_mode 
*drm_mode_displayid_detailed(struct drm_device *d
        struct drm_display_mode *mode;
        unsigned pixel_clock = (timings->pixel_clock[0] |
                                (timings->pixel_clock[1] << 8) |
-                               (timings->pixel_clock[2] << 16));
+                               (timings->pixel_clock[2] << 16)) + 1;
        unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1;
        unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1;
        unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) 
+ 1;
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index 3eb920851141..8334afa70b94 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -504,9 +504,10 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev,
                return ret;
 
        ret = qxl_release_reserve_list(release, true);
-       if (ret)
+       if (ret) {
+               qxl_release_free(qdev, release);
                return ret;
-
+       }
        cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release);
        cmd->type = QXL_SURFACE_CMD_CREATE;
        cmd->flags = QXL_SURF_FLAG_KEEP_DATA;
@@ -532,8 +533,8 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev,
        /* no need to add a release to the fence for this surface bo,
           since it is only released when we ask to destroy the surface
           and it would never signal otherwise */
-       qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
        qxl_release_fence_buffer_objects(release);
+       qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
 
        surf->hw_surf_alloc = true;
        spin_lock(&qdev->surf_id_idr_lock);
@@ -575,9 +576,8 @@ int qxl_hw_surface_dealloc(struct qxl_device *qdev,
        cmd->surface_id = id;
        qxl_release_unmap(qdev, release, &cmd->release_info);
 
-       qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
-
        qxl_release_fence_buffer_objects(release);
+       qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
 
        return 0;
 }
diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 573bab222123..b209a25e307d 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -533,8 +533,8 @@ static int qxl_primary_apply_cursor(struct drm_plane *plane)
        cmd->u.set.visible = 1;
        qxl_release_unmap(qdev, release, &cmd->release_info);
 
-       qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
        qxl_release_fence_buffer_objects(release);
+       qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 
        return ret;
 
@@ -701,8 +701,8 @@ static void qxl_cursor_atomic_update(struct drm_plane 
*plane,
        cmd->u.position.y = plane->state->crtc_y + fb->hot_y;
 
        qxl_release_unmap(qdev, release, &cmd->release_info);
-       qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
        qxl_release_fence_buffer_objects(release);
+       qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 
        if (old_cursor_bo)
                qxl_bo_unref(&old_cursor_bo);
@@ -747,8 +747,8 @@ static void qxl_cursor_atomic_disable(struct drm_plane 
*plane,
        cmd->type = QXL_CURSOR_HIDE;
        qxl_release_unmap(qdev, release, &cmd->release_info);
 
-       qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
        qxl_release_fence_buffer_objects(release);
+       qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 }
 
 static int qxl_plane_prepare_fb(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/qxl/qxl_draw.c b/drivers/gpu/drm/qxl/qxl_draw.c
index 4d8681e84e68..d009f2bc28e9 100644
--- a/drivers/gpu/drm/qxl/qxl_draw.c
+++ b/drivers/gpu/drm/qxl/qxl_draw.c
@@ -241,8 +241,8 @@ void qxl_draw_opaque_fb(const struct qxl_fb_image 
*qxl_fb_image,
                qxl_bo_physical_address(qdev, dimage->bo, 0);
        qxl_release_unmap(qdev, release, &drawable->release_info);
 
-       qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
        qxl_release_fence_buffer_objects(release);
+       qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 
 out_free_palette:
        if (palette_bo)
@@ -348,9 +348,10 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
                goto out_release_backoff;
 
        rects = drawable_set_clipping(qdev, num_clips, clips_bo);
-       if (!rects)
+       if (!rects) {
+               ret = -EINVAL;
                goto out_release_backoff;
-
+       }
        drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
 
        drawable->clip.type = SPICE_CLIP_TYPE_RECTS;
@@ -381,8 +382,8 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
        }
        qxl_bo_kunmap(clips_bo);
 
-       qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
        qxl_release_fence_buffer_objects(release);
+       qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 
 out_release_backoff:
        if (ret)
@@ -432,8 +433,8 @@ void qxl_draw_copyarea(struct qxl_device *qdev,
        drawable->u.copy_bits.src_pos.y = sy;
        qxl_release_unmap(qdev, release, &drawable->release_info);
 
-       qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
        qxl_release_fence_buffer_objects(release);
+       qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 
 out_free_release:
        if (ret)
@@ -476,8 +477,8 @@ void qxl_draw_fill(struct qxl_draw_fill *qxl_draw_fill_rec)
 
        qxl_release_unmap(qdev, release, &drawable->release_info);
 
-       qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
        qxl_release_fence_buffer_objects(release);
+       qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 
 out_free_release:
        if (ret)
diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index 31effed4a3c8..cede17585525 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -257,11 +257,8 @@ static int qxl_process_single_command(struct qxl_device 
*qdev,
                        apply_surf_reloc(qdev, &reloc_info[i]);
        }
 
+       qxl_release_fence_buffer_objects(release);
        ret = qxl_push_command_ring_release(qdev, release, cmd->type, true);
-       if (ret)
-               qxl_release_backoff_reserve_list(release);
-       else
-               qxl_release_fence_buffer_objects(release);
 
 out_free_bos:
 out_free_release:
diff --git a/drivers/infiniband/hw/mlx4/main.c 
b/drivers/infiniband/hw/mlx4/main.c
index 7e73a1a6cb67..3f8511104c5b 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -1614,8 +1614,9 @@ static int __mlx4_ib_create_default_rules(
        int i;
 
        for (i = 0; i < ARRAY_SIZE(pdefault_rules->rules_create_list); i++) {
+               union ib_flow_spec ib_spec = {};
                int ret;
-               union ib_flow_spec ib_spec;
+
                switch (pdefault_rules->rules_create_list[i]) {
                case 0:
                        /* no rule */
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 0cb60072c82f..d835ef2ce23c 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -4362,7 +4362,9 @@ static void to_rdma_ah_attr(struct mlx5_ib_dev *ibdev,
        rdma_ah_set_path_bits(ah_attr, path->grh_mlid & 0x7f);
        rdma_ah_set_static_rate(ah_attr,
                                path->static_rate ? path->static_rate - 5 : 0);
-       if (path->grh_mlid & (1 << 7)) {
+
+       if (path->grh_mlid & (1 << 7) ||
+           ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) {
                u32 tc_fl = be32_to_cpu(path->tclass_flowlabel);
 
                rdma_ah_set_grh(ah_attr, NULL,
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 4d2920988d60..6c228144b3da 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2809,7 +2809,7 @@ static int __init parse_amd_iommu_intr(char *str)
 {
        for (; *str; ++str) {
                if (strncmp(str, "legacy", 6) == 0) {
-                       amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
+                       amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA;
                        break;
                }
                if (strncmp(str, "vapic", 5) == 0) {
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
index b08002851e06..920a5df319bc 100644
--- a/drivers/iommu/qcom_iommu.c
+++ b/drivers/iommu/qcom_iommu.c
@@ -775,8 +775,11 @@ static int qcom_iommu_device_probe(struct platform_device 
*pdev)
        qcom_iommu->dev = dev;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res)
+       if (res) {
                qcom_iommu->local_base = devm_ioremap_resource(dev, res);
+               if (IS_ERR(qcom_iommu->local_base))
+                       return PTR_ERR(qcom_iommu->local_base);
+       }
 
        qcom_iommu->iface_clk = devm_clk_get(dev, "iface");
        if (IS_ERR(qcom_iommu->iface_clk)) {
diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
index 285148100cde..0fe6cc3007f5 100644
--- a/drivers/md/dm-verity-fec.c
+++ b/drivers/md/dm-verity-fec.c
@@ -436,7 +436,7 @@ int verity_fec_decode(struct dm_verity *v, struct 
dm_verity_io *io,
        fio->level++;
 
        if (type == DM_VERITY_BLOCK_TYPE_METADATA)
-               block += v->data_blocks;
+               block = block - v->hash_start + v->data_blocks;
 
        /*
         * For RS(M, N), the continuous FEC data is divided into blocks of N
diff --git a/drivers/mmc/host/sdhci-pci-core.c 
b/drivers/mmc/host/sdhci-pci-core.c
index 0e386f5cc836..4bc89551229b 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -490,6 +490,9 @@ static int intel_select_drive_strength(struct mmc_card 
*card,
        struct sdhci_pci_slot *slot = sdhci_priv(host);
        struct intel_host *intel_host = sdhci_pci_priv(slot);
 
+       if (!(mmc_driver_type_mask(intel_host->drv_strength) & card_drv))
+               return 0;
+
        return intel_host->drv_strength;
 }
 
diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c
index a0b5089b3274..fafb02644efd 100644
--- a/drivers/mmc/host/sdhci-xenon.c
+++ b/drivers/mmc/host/sdhci-xenon.c
@@ -238,6 +238,16 @@ static void xenon_voltage_switch(struct sdhci_host *host)
 {
        /* Wait for 5ms after set 1.8V signal enable bit */
        usleep_range(5000, 5500);
+
+       /*
+        * For some reason the controller's Host Control2 register reports
+        * the bit representing 1.8V signaling as 0 when read after it was
+        * written as 1. Subsequent read reports 1.
+        *
+        * Since this may cause some issues, do an empty read of the Host
+        * Control2 register here to circumvent this.
+        */
+       sdhci_readw(host, SDHCI_HOST_CONTROL2);
 }
 
 static const struct sdhci_ops sdhci_xenon_ops = {
diff --git a/drivers/target/target_core_iblock.c 
b/drivers/target/target_core_iblock.c
index 60429011292a..2a9e023f5429 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -447,7 +447,7 @@ iblock_execute_zero_out(struct block_device *bdev, struct 
se_cmd *cmd)
                                target_to_linux_sector(dev, cmd->t_task_lba),
                                target_to_linux_sector(dev,
                                        sbc_get_write_same_sectors(cmd)),
-                               GFP_KERNEL, false);
+                               GFP_KERNEL, BLKDEV_ZERO_NOUNMAP);
        if (ret)
                return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index f77a9b3370b5..35a3750a6ddd 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -378,8 +378,8 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
long vaddr,
        vma = find_vma_intersection(mm, vaddr, vaddr + 1);
 
        if (vma && vma->vm_flags & VM_PFNMAP) {
-               *pfn = ((vaddr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
-               if (is_invalid_reserved_pfn(*pfn))
+               if (!follow_pfn(vma, vaddr, pfn) &&
+                   is_invalid_reserved_pfn(*pfn))
                        ret = 0;
        }
 
@@ -591,7 +591,7 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data,
                        continue;
                }
 
-               remote_vaddr = dma->vaddr + iova - dma->iova;
+               remote_vaddr = dma->vaddr + (iova - dma->iova);
                ret = vfio_pin_page_external(dma, remote_vaddr, &phys_pfn[i],
                                             do_accounting);
                if (ret)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index fd15f396b3a0..51e26f90f0bb 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -10554,7 +10554,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle 
*trans,
        path = btrfs_alloc_path();
        if (!path) {
                ret = -ENOMEM;
-               goto out;
+               goto out_put_group;
        }
 
        /*
@@ -10591,7 +10591,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle 
*trans,
                ret = btrfs_orphan_add(trans, BTRFS_I(inode));
                if (ret) {
                        btrfs_add_delayed_iput(inode);
-                       goto out;
+                       goto out_put_group;
                }
                clear_nlink(inode);
                /* One for the block groups ref */
@@ -10614,13 +10614,13 @@ int btrfs_remove_block_group(struct 
btrfs_trans_handle *trans,
 
        ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
        if (ret < 0)
-               goto out;
+               goto out_put_group;
        if (ret > 0)
                btrfs_release_path(path);
        if (ret == 0) {
                ret = btrfs_del_item(trans, tree_root, path);
                if (ret)
-                       goto out;
+                       goto out_put_group;
                btrfs_release_path(path);
        }
 
@@ -10778,9 +10778,9 @@ int btrfs_remove_block_group(struct btrfs_trans_handle 
*trans,
 
        ret = remove_block_group_free_space(trans, fs_info, block_group);
        if (ret)
-               goto out;
+               goto out_put_group;
 
-       btrfs_put_block_group(block_group);
+       /* Once for the block groups rbtree */
        btrfs_put_block_group(block_group);
 
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
@@ -10790,6 +10790,10 @@ int btrfs_remove_block_group(struct btrfs_trans_handle 
*trans,
                goto out;
 
        ret = btrfs_del_item(trans, root, path);
+
+out_put_group:
+       /* Once for the lookup reference */
+       btrfs_put_block_group(block_group);
 out:
        btrfs_free_path(path);
        return ret;
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 0b62c8080af0..bcfb7a772c8e 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4155,6 +4155,9 @@ static int btrfs_log_prealloc_extents(struct 
btrfs_trans_handle *trans,
        const u64 ino = btrfs_ino(inode);
        struct btrfs_path *dst_path = NULL;
        bool dropped_extents = false;
+       u64 truncate_offset = i_size;
+       struct extent_buffer *leaf;
+       int slot;
        int ins_nr = 0;
        int start_slot;
        int ret;
@@ -4169,9 +4172,43 @@ static int btrfs_log_prealloc_extents(struct 
btrfs_trans_handle *trans,
        if (ret < 0)
                goto out;
 
+       /*
+        * We must check if there is a prealloc extent that starts before the
+        * i_size and crosses the i_size boundary. This is to ensure later we
+        * truncate down to the end of that extent and not to the i_size, as
+        * otherwise we end up losing part of the prealloc extent after a log
+        * replay and with an implicit hole if there is another prealloc extent
+        * that starts at an offset beyond i_size.
+        */
+       ret = btrfs_previous_item(root, path, ino, BTRFS_EXTENT_DATA_KEY);
+       if (ret < 0)
+               goto out;
+
+       if (ret == 0) {
+               struct btrfs_file_extent_item *ei;
+
+               leaf = path->nodes[0];
+               slot = path->slots[0];
+               ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
+
+               if (btrfs_file_extent_type(leaf, ei) ==
+                   BTRFS_FILE_EXTENT_PREALLOC) {
+                       u64 extent_end;
+
+                       btrfs_item_key_to_cpu(leaf, &key, slot);
+                       extent_end = key.offset +
+                               btrfs_file_extent_num_bytes(leaf, ei);
+
+                       if (extent_end > i_size)
+                               truncate_offset = extent_end;
+               }
+       } else {
+               ret = 0;
+       }
+
        while (true) {
-               struct extent_buffer *leaf = path->nodes[0];
-               int slot = path->slots[0];
+               leaf = path->nodes[0];
+               slot = path->slots[0];
 
                if (slot >= btrfs_header_nritems(leaf)) {
                        if (ins_nr > 0) {
@@ -4209,7 +4246,7 @@ static int btrfs_log_prealloc_extents(struct 
btrfs_trans_handle *trans,
                                ret = btrfs_truncate_inode_items(trans,
                                                         root->log_root,
                                                         &inode->vfs_inode,
-                                                        i_size,
+                                                        truncate_offset,
                                                         BTRFS_EXTENT_DATA_KEY);
                        } while (ret == -EAGAIN);
                        if (ret)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 1bc0037c50aa..5f03a4fabeaa 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4715,7 +4715,7 @@ struct inode *__ext4_iget(struct super_block *sb, 
unsigned long ino,
        gid_t i_gid;
        projid_t i_projid;
 
-       if (((flags & EXT4_IGET_NORMAL) &&
+       if ((!(flags & EXT4_IGET_SPECIAL) &&
             (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) ||
            (ino < EXT4_ROOT_INO) ||
            (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) {
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index 7173a4ee862c..5e9f9c70fe70 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -253,37 +253,45 @@ int nfs3_proc_setacls(struct inode *inode, struct 
posix_acl *acl,
 
 int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
-       struct posix_acl *alloc = NULL, *dfacl = NULL;
+       struct posix_acl *orig = acl, *dfacl = NULL, *alloc;
        int status;
 
        if (S_ISDIR(inode->i_mode)) {
                switch(type) {
                case ACL_TYPE_ACCESS:
-                       alloc = dfacl = get_acl(inode, ACL_TYPE_DEFAULT);
+                       alloc = get_acl(inode, ACL_TYPE_DEFAULT);
                        if (IS_ERR(alloc))
                                goto fail;
+                       dfacl = alloc;
                        break;
 
                case ACL_TYPE_DEFAULT:
-                       dfacl = acl;
-                       alloc = acl = get_acl(inode, ACL_TYPE_ACCESS);
+                       alloc = get_acl(inode, ACL_TYPE_ACCESS);
                        if (IS_ERR(alloc))
                                goto fail;
+                       dfacl = acl;
+                       acl = alloc;
                        break;
                }
        }
 
        if (acl == NULL) {
-               alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
+               alloc = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
                if (IS_ERR(alloc))
                        goto fail;
+               acl = alloc;
        }
        status = __nfs3_proc_setacls(inode, acl, dfacl);
-       posix_acl_release(alloc);
+out:
+       if (acl != orig)
+               posix_acl_release(acl);
+       if (dfacl != orig)
+               posix_acl_release(dfacl);
        return status;
 
 fail:
-       return PTR_ERR(alloc);
+       status = PTR_ERR(alloc);
+       goto out;
 }
 
 const struct xattr_handler *nfs3_xattr_handlers[] = {
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 2d6d14ad7b4f..2e65aacfa116 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -892,6 +892,13 @@ static int software_resume(void)
        error = freeze_processes();
        if (error)
                goto Close_Finish;
+
+       error = freeze_kernel_threads();
+       if (error) {
+               thaw_processes();
+               goto Close_Finish;
+       }
+
        error = load_image_and_restore();
        thaw_processes();
  Finish:
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5f7bfc65c446..5def19ec1179 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5121,39 +5121,59 @@ static int selinux_tun_dev_open(void *security)
 
 static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
 {
-       int err = 0;
-       u32 perm;
+       int rc = 0;
+       unsigned int msg_len;
+       unsigned int data_len = skb->len;
+       unsigned char *data = skb->data;
        struct nlmsghdr *nlh;
        struct sk_security_struct *sksec = sk->sk_security;
+       u16 sclass = sksec->sclass;
+       u32 perm;
 
-       if (skb->len < NLMSG_HDRLEN) {
-               err = -EINVAL;
-               goto out;
-       }
-       nlh = nlmsg_hdr(skb);
+       while (data_len >= nlmsg_total_size(0)) {
+               nlh = (struct nlmsghdr *)data;
 
-       err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
-       if (err) {
-               if (err == -EINVAL) {
+               /* NOTE: the nlmsg_len field isn't reliably set by some netlink
+                *       users which means we can't reject skb's with bogus
+                *       length fields; our solution is to follow what
+                *       netlink_rcv_skb() does and simply skip processing at
+                *       messages with length fields that are clearly junk
+                */
+               if (nlh->nlmsg_len < NLMSG_HDRLEN || nlh->nlmsg_len > data_len)
+                       return 0;
+
+               rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm);
+               if (rc == 0) {
+                       rc = sock_has_perm(sk, perm);
+                       if (rc)
+                               return rc;
+               } else if (rc == -EINVAL) {
+                       /* -EINVAL is a missing msg/perm mapping */
                        pr_warn_ratelimited("SELinux: unrecognized netlink"
-                              " message: protocol=%hu nlmsg_type=%hu sclass=%s"
-                              " pig=%d comm=%s\n",
-                              sk->sk_protocol, nlh->nlmsg_type,
-                              secclass_map[sksec->sclass - 1].name,
-                              task_pid_nr(current), current->comm);
-                       if (!selinux_enforcing || security_get_allow_unknown())
-                               err = 0;
+                               " message: protocol=%hu nlmsg_type=%hu 
sclass=%s"
+                               " pid=%d comm=%s\n",
+                               sk->sk_protocol, nlh->nlmsg_type,
+                               secclass_map[sclass - 1].name,
+                               task_pid_nr(current), current->comm);
+                       if (selinux_enforcing && !security_get_allow_unknown())
+                               return rc;
+                       rc = 0;
+               } else if (rc == -ENOENT) {
+                       /* -ENOENT is a missing socket/class mapping, ignore */
+                       rc = 0;
+               } else {
+                       return rc;
                }
 
-               /* Ignore */
-               if (err == -ENOENT)
-                       err = 0;
-               goto out;
+               /* move to the next message after applying netlink padding */
+               msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
+               if (msg_len >= data_len)
+                       return 0;
+               data_len -= msg_len;
+               data += msg_len;
        }
 
-       err = sock_has_perm(sk, perm);
-out:
-       return err;
+       return rc;
 }
 
 #ifdef CONFIG_NETFILTER
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 3ecc070738e8..c1315ce98b54 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -211,21 +211,23 @@ static snd_pcm_sframes_t plug_client_size(struct 
snd_pcm_substream *plug,
        if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
                plugin = snd_pcm_plug_last(plug);
                while (plugin && drv_frames > 0) {
-                       if (check_size && drv_frames > plugin->buf_frames)
-                               drv_frames = plugin->buf_frames;
                        plugin_prev = plugin->prev;
                        if (plugin->src_frames)
                                drv_frames = plugin->src_frames(plugin, 
drv_frames);
+                       if (check_size && plugin->buf_frames &&
+                           drv_frames > plugin->buf_frames)
+                               drv_frames = plugin->buf_frames;
                        plugin = plugin_prev;
                }
        } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
                plugin = snd_pcm_plug_first(plug);
                while (plugin && drv_frames > 0) {
                        plugin_next = plugin->next;
+                       if (check_size && plugin->buf_frames &&
+                           drv_frames > plugin->buf_frames)
+                               drv_frames = plugin->buf_frames;
                        if (plugin->dst_frames)
                                drv_frames = plugin->dst_frames(plugin, 
drv_frames);
-                       if (check_size && drv_frames > plugin->buf_frames)
-                               drv_frames = plugin->buf_frames;
                        plugin = plugin_next;
                }
        } else
@@ -251,26 +253,28 @@ static snd_pcm_sframes_t plug_slave_size(struct 
snd_pcm_substream *plug,
                plugin = snd_pcm_plug_first(plug);
                while (plugin && frames > 0) {
                        plugin_next = plugin->next;
+                       if (check_size && plugin->buf_frames &&
+                           frames > plugin->buf_frames)
+                               frames = plugin->buf_frames;
                        if (plugin->dst_frames) {
                                frames = plugin->dst_frames(plugin, frames);
                                if (frames < 0)
                                        return frames;
                        }
-                       if (check_size && frames > plugin->buf_frames)
-                               frames = plugin->buf_frames;
                        plugin = plugin_next;
                }
        } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
                plugin = snd_pcm_plug_last(plug);
                while (plugin) {
-                       if (check_size && frames > plugin->buf_frames)
-                               frames = plugin->buf_frames;
                        plugin_prev = plugin->prev;
                        if (plugin->src_frames) {
                                frames = plugin->src_frames(plugin, frames);
                                if (frames < 0)
                                        return frames;
                        }
+                       if (check_size && plugin->buf_frames &&
+                           frames > plugin->buf_frames)
+                               frames = plugin->buf_frames;
                        plugin = plugin_prev;
                }
        } else
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 8894c7c18ad6..d92c3c6b6051 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -875,10 +875,13 @@ static void snd_miro_write(struct snd_miro *chip, 
unsigned char reg,
        spin_unlock_irqrestore(&chip->lock, flags);
 }
 
+static inline void snd_miro_write_mask(struct snd_miro *chip,
+               unsigned char reg, unsigned char value, unsigned char mask)
+{
+       unsigned char oldval = snd_miro_read(chip, reg);
 
-#define snd_miro_write_mask(chip, reg, value, mask)    \
-       snd_miro_write(chip, reg,                       \
-               (snd_miro_read(chip, reg) & ~(mask)) | ((value) & (mask)))
+       snd_miro_write(chip, reg, (oldval & ~mask) | (value & mask));
+}
 
 /*
  *  Proc Interface
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c 
b/sound/isa/opti9xx/opti92x-ad1848.c
index 505cd81e19fa..4ef3caaf4354 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -327,10 +327,13 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, 
unsigned char reg,
 }
 
 
-#define snd_opti9xx_write_mask(chip, reg, value, mask) \
-       snd_opti9xx_write(chip, reg,                    \
-               (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
+static inline void snd_opti9xx_write_mask(struct snd_opti9xx *chip,
+               unsigned char reg, unsigned char value, unsigned char mask)
+{
+       unsigned char oldval = snd_opti9xx_read(chip, reg);
 
+       snd_opti9xx_write(chip, reg, (oldval & ~mask) | (value & mask));
+}
 
 static int snd_opti9xx_configure(struct snd_opti9xx *chip,
                                           long port,
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 12913368c231..435c0efb9bf2 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1849,8 +1849,10 @@ static bool check_non_pcm_per_cvt(struct hda_codec 
*codec, hda_nid_t cvt_nid)
        /* Add sanity check to pass klockwork check.
         * This should never happen.
         */
-       if (WARN_ON(spdif == NULL))
+       if (WARN_ON(spdif == NULL)) {
+               mutex_unlock(&codec->spdif_mutex);
                return true;
+       }
        non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
        mutex_unlock(&codec->spdif_mutex);
        return non_pcm;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 288ea05dfa3c..b2aec97414fb 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -6590,6 +6590,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", 
ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", 
ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", 
ALC233_FIXUP_LENOVO_MULTI_CODECS),
+       SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", 
ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", 
ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", 
ALC269_FIXUP_SKU_IGNORE),

Reply via email to