Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .container_build_image
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lts-9.4-kernel-builder
11 changes: 11 additions & 0 deletions .github/workflows/kernel-build-and-test-x86_64.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Automated kernel build and test (x86_64)

on:
push:
branches:
- '*_ciqlts9_6'

jobs:
build:
uses: ctrliq/kernel-src-tree/.github/workflows/kernel-build-and-test-x86_64.yml@{jmaple}_main
secrets: inherit
6 changes: 5 additions & 1 deletion arch/arm64/kvm/arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
if (err)
return err;

return kvm_share_hyp(vcpu, vcpu + 1);
err = kvm_share_hyp(vcpu, vcpu + 1);
if (err)
kvm_vgic_vcpu_destroy(vcpu);

return err;
}

void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3679,6 +3679,11 @@ static int vmw_cmd_check(struct vmw_private *dev_priv,


cmd_id = header->id;
if (header->size > SVGA_CMD_MAX_DATASIZE) {
VMW_DEBUG_USER("SVGA3D command: %d is too big.\n",
cmd_id + SVGA_3D_CMD_BASE);
return -E2BIG;
}
*size = header->size + sizeof(SVGA3dCmdHeader);

cmd_id -= SVGA_3D_CMD_BASE;
Expand Down
12 changes: 10 additions & 2 deletions drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,13 @@ int xe_gt_tlb_invalidation_ggtt(struct xe_gt *gt)
return 0;
}

/*
* Ensure that roundup_pow_of_two(length) doesn't overflow.
* Note that roundup_pow_of_two() operates on unsigned long,
* not on u64.
*/
#define MAX_RANGE_TLB_INVALIDATION_LENGTH (rounddown_pow_of_two(ULONG_MAX))

/**
* xe_gt_tlb_invalidation_range - Issue a TLB invalidation on this GT for an
* address range
Expand All @@ -334,6 +341,7 @@ int xe_gt_tlb_invalidation_range(struct xe_gt *gt,
struct xe_device *xe = gt_to_xe(gt);
#define MAX_TLB_INVALIDATION_LEN 7
u32 action[MAX_TLB_INVALIDATION_LEN];
u64 length = end - start;
int len = 0;

xe_gt_assert(gt, fence);
Expand All @@ -346,11 +354,11 @@ int xe_gt_tlb_invalidation_range(struct xe_gt *gt,

action[len++] = XE_GUC_ACTION_TLB_INVALIDATION;
action[len++] = 0; /* seqno, replaced in send_tlb_invalidation */
if (!xe->info.has_range_tlb_invalidation) {
if (!xe->info.has_range_tlb_invalidation ||
length > MAX_RANGE_TLB_INVALIDATION_LENGTH) {
action[len++] = MAKE_INVAL_OP(XE_GUC_TLB_INVAL_FULL);
} else {
u64 orig_start = start;
u64 length = end - start;
u64 align;

if (length < SZ_4K)
Expand Down
14 changes: 14 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,13 @@ static int i40e_config_vsi_tx_queue(struct i40e_vf *vf, u16 vsi_id,

/* only set the required fields */
tx_ctx.base = info->dma_ring_addr / 128;

/* ring_len has to be multiple of 8 */
if (!IS_ALIGNED(info->ring_len, 8) ||
info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) {
ret = -EINVAL;
goto error_context;
}
tx_ctx.qlen = info->ring_len;
tx_ctx.rdylist = le16_to_cpu(vsi->info.qs_handle[0]);
tx_ctx.rdylist_act = 0;
Expand Down Expand Up @@ -716,6 +723,13 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id,

/* only set the required fields */
rx_ctx.base = info->dma_ring_addr / 128;

/* ring_len has to be multiple of 32 */
if (!IS_ALIGNED(info->ring_len, 32) ||
info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) {
ret = -EINVAL;
goto error_param;
}
rx_ctx.qlen = info->ring_len;

if (info->splithdr_enabled) {
Expand Down
32 changes: 17 additions & 15 deletions drivers/scsi/lpfc/lpfc_hbadisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
struct lpfc_hba *phba;
struct lpfc_work_evt *evtp;
unsigned long iflags;
bool nvme_reg = false;
bool drop_initial_node_ref = false;

ndlp = ((struct lpfc_rport_data *)rport->dd_data)->pnode;
if (!ndlp)
Expand All @@ -188,8 +188,13 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
spin_lock_irqsave(&ndlp->lock, iflags);
ndlp->rport = NULL;

if (ndlp->fc4_xpt_flags & NVME_XPT_REGD)
nvme_reg = true;
/* Only 1 thread can drop the initial node reference.
* If not registered for NVME and NLP_DROPPED flag is
* clear, remove the initial reference.
*/
if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD))
if (!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
drop_initial_node_ref = true;

/* The scsi_transport is done with the rport so lpfc cannot
* call to unregister.
Expand All @@ -200,28 +205,25 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
/* If NLP_XPT_REGD was cleared in lpfc_nlp_unreg_node,
* unregister calls were made to the scsi and nvme
* transports and refcnt was already decremented. Clear
* the NLP_XPT_REGD flag only if the NVME Rport is
* the NLP_XPT_REGD flag only if the NVME nrport is
* confirmed unregistered.
*/
if (!nvme_reg && ndlp->fc4_xpt_flags & NLP_XPT_REGD) {
ndlp->fc4_xpt_flags &= ~NLP_XPT_REGD;
if (ndlp->fc4_xpt_flags & NLP_XPT_REGD) {
if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD))
ndlp->fc4_xpt_flags &= ~NLP_XPT_REGD;
spin_unlock_irqrestore(&ndlp->lock, iflags);
lpfc_nlp_put(ndlp); /* may free ndlp */

/* Release scsi transport reference */
lpfc_nlp_put(ndlp);
} else {
spin_unlock_irqrestore(&ndlp->lock, iflags);
}
} else {
spin_unlock_irqrestore(&ndlp->lock, iflags);
}

/* Only 1 thread can drop the initial node reference. If
* another thread has set NLP_DROPPED, this thread is done.
*/
if (nvme_reg || test_bit(NLP_DROPPED, &ndlp->nlp_flag))
return;

set_bit(NLP_DROPPED, &ndlp->nlp_flag);
lpfc_nlp_put(ndlp);
if (drop_initial_node_ref)
lpfc_nlp_put(ndlp);
return;
}

Expand Down
9 changes: 5 additions & 4 deletions fs/nfs/pagelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,14 @@ nfs_page_group_unlock(struct nfs_page *req)
nfs_page_clear_headlock(req);
}

/*
* nfs_page_group_sync_on_bit_locked
/**
* nfs_page_group_sync_on_bit_locked - Test if all requests have @bit set
* @req: request in page group
* @bit: PG_* bit that is used to sync page group
*
* must be called with page group lock held
*/
static bool
nfs_page_group_sync_on_bit_locked(struct nfs_page *req, unsigned int bit)
bool nfs_page_group_sync_on_bit_locked(struct nfs_page *req, unsigned int bit)
{
struct nfs_page *head = req->wb_head;
struct nfs_page *tmp;
Expand Down
29 changes: 10 additions & 19 deletions fs/nfs/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,20 +152,10 @@ nfs_page_set_inode_ref(struct nfs_page *req, struct inode *inode)
}
}

static int
nfs_cancel_remove_inode(struct nfs_page *req, struct inode *inode)
static void nfs_cancel_remove_inode(struct nfs_page *req, struct inode *inode)
{
int ret;

if (!test_bit(PG_REMOVE, &req->wb_flags))
return 0;
ret = nfs_page_group_lock(req);
if (ret)
return ret;
if (test_and_clear_bit(PG_REMOVE, &req->wb_flags))
nfs_page_set_inode_ref(req, inode);
nfs_page_group_unlock(req);
return 0;
}

/**
Expand Down Expand Up @@ -583,19 +573,18 @@ static struct nfs_page *nfs_lock_and_join_requests(struct folio *folio)
return ERR_PTR(ret);
}

ret = nfs_page_group_lock(head);
if (ret < 0)
goto out_unlock;

/* Ensure that nobody removed the request before we locked it */
if (head != folio->private) {
nfs_page_group_unlock(head);
nfs_unlock_and_release_request(head);
goto retry;
}

ret = nfs_cancel_remove_inode(head, inode);
if (ret < 0)
goto out_unlock;

ret = nfs_page_group_lock(head);
if (ret < 0)
goto out_unlock;
nfs_cancel_remove_inode(head, inode);

/* lock each request in the page group */
for (subreq = head->wb_this_page;
Expand Down Expand Up @@ -800,7 +789,8 @@ static void nfs_inode_remove_request(struct nfs_page *req)
{
struct nfs_inode *nfsi = NFS_I(nfs_page_to_inode(req));

if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) {
nfs_page_group_lock(req);
if (nfs_page_group_sync_on_bit_locked(req, PG_REMOVE)) {
struct folio *folio = nfs_page_to_folio(req->wb_head);
struct address_space *mapping = folio->mapping;

Expand All @@ -812,6 +802,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
}
spin_unlock(&mapping->private_lock);
}
nfs_page_group_unlock(req);

if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) {
atomic_long_dec(&nfsi->nrequests);
Expand Down
1 change: 1 addition & 0 deletions include/linux/nfs_page.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ extern void nfs_join_page_group(struct nfs_page *head,
extern int nfs_page_group_lock(struct nfs_page *);
extern void nfs_page_group_unlock(struct nfs_page *);
extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
extern bool nfs_page_group_sync_on_bit_locked(struct nfs_page *, unsigned int);
extern int nfs_page_set_headlock(struct nfs_page *req);
extern void nfs_page_clear_headlock(struct nfs_page *req);
extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);
Expand Down
2 changes: 1 addition & 1 deletion include/sound/ump_convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct ump_cvt_to_ump_bank {
/* context for converting from MIDI1 byte stream to UMP packet */
struct ump_cvt_to_ump {
/* MIDI1 intermediate buffer */
unsigned char buf[4];
unsigned char buf[6]; /* up to 6 bytes for SysEx */
int len;
int cmd_bytes;

Expand Down
12 changes: 9 additions & 3 deletions net/bluetooth/hci_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -863,11 +863,17 @@ bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev,
{
struct hci_cmd_sync_work_entry *entry;

entry = hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
if (!entry)
mutex_lock(&hdev->cmd_sync_work_lock);

entry = _hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
if (!entry) {
mutex_unlock(&hdev->cmd_sync_work_lock);
return false;
}

hci_cmd_sync_cancel_entry(hdev, entry);
_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);

mutex_unlock(&hdev->cmd_sync_work_lock);

return true;
}
Expand Down
7 changes: 7 additions & 0 deletions net/bluetooth/iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,13 @@ static void iso_sock_kill(struct sock *sk)

BT_DBG("sk %p state %d", sk, sk->sk_state);

/* Sock is dead, so set conn->sk to NULL to avoid possible UAF */
if (iso_pi(sk)->conn) {
iso_conn_lock(iso_pi(sk)->conn);
iso_pi(sk)->conn->sk = NULL;
iso_conn_unlock(iso_pi(sk)->conn);
}

/* Kill poor orphan */
bt_sock_unlink(&iso_sk_list, sk);
sock_set_flag(sk, SOCK_DEAD);
Expand Down
4 changes: 3 additions & 1 deletion net/devlink/rate.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,13 +701,15 @@ void devl_rate_nodes_destroy(struct devlink *devlink)
if (!devlink_rate->parent)
continue;

refcount_dec(&devlink_rate->parent->refcnt);
if (devlink_rate_is_leaf(devlink_rate))
ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
NULL, NULL);
else if (devlink_rate_is_node(devlink_rate))
ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
NULL, NULL);

refcount_dec(&devlink_rate->parent->refcnt);
devlink_rate->parent = NULL;
}
list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
if (devlink_rate_is_node(devlink_rate)) {
Expand Down
19 changes: 12 additions & 7 deletions net/mptcp/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -936,14 +936,19 @@ static void mptcp_reset_rtx_timer(struct sock *sk)

bool mptcp_schedule_work(struct sock *sk)
{
if (inet_sk_state_load(sk) != TCP_CLOSE &&
schedule_work(&mptcp_sk(sk)->work)) {
/* each subflow already holds a reference to the sk, and the
* workqueue is invoked by a subflow, so sk can't go away here.
*/
sock_hold(sk);
if (inet_sk_state_load(sk) == TCP_CLOSE)
return false;

/* Get a reference on this socket, mptcp_worker() will release it.
* As mptcp_worker() might complete before us, we can not avoid
* a sock_hold()/sock_put() if schedule_work() returns false.
*/
sock_hold(sk);

if (schedule_work(&mptcp_sk(sk)->work))
return true;
}

sock_put(sk);
return false;
}

Expand Down
7 changes: 5 additions & 2 deletions sound/soc/intel/boards/bytcr_rt5640.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ enum {
BYT_RT5640_OVCD_SF_1P5 = (RT5640_OVCD_SF_1P5 << 13),
};

#define BYT_RT5640_MAP(quirk) ((quirk) & GENMASK(3, 0))
#define BYT_RT5640_MAP_MASK GENMASK(3, 0)
#define BYT_RT5640_MAP(quirk) ((quirk) & BYT_RT5640_MAP_MASK)
#define BYT_RT5640_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4)
#define BYT_RT5640_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8)
#define BYT_RT5640_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13)
Expand Down Expand Up @@ -140,7 +141,9 @@ static void log_quirks(struct device *dev)
dev_info(dev, "quirk NO_INTERNAL_MIC_MAP enabled\n");
break;
default:
dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to DMIC1_MAP\n", map);
byt_rt5640_quirk &= ~BYT_RT5640_MAP_MASK;
byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
break;
}
if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1)
Expand Down
Loading