Skip to content
Open
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
5 changes: 5 additions & 0 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -11477,6 +11477,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
}

if (dc_resource_is_dsc_encoding_supported(dc)) {
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
dm_new_crtc_state->mode_changed_independent_from_dsc = new_crtc_state->mode_changed;
}

for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
ret = add_affected_mst_dsc_crtcs(state, crtc);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@ struct dm_crtc_state {

bool freesync_vrr_info_changed;

bool mode_changed_independent_from_dsc;
bool dsc_force_changed;
bool vrr_supported;
struct mod_freesync_config freesync_config;
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
Original file line number Diff line number Diff line change
Expand Up @@ -1665,9 +1665,11 @@ int pre_validate_dsc(struct drm_atomic_state *state,
int ind = find_crtc_index_in_state_by_stream(state, stream);

if (ind >= 0) {
struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(state->crtcs[ind].new_state);

DRM_INFO_ONCE("%s:%d MST_DSC no mode changed for stream 0x%p\n",
__func__, __LINE__, stream);
state->crtcs[ind].new_state->mode_changed = 0;
dm_new_crtc_state->base.mode_changed = dm_new_crtc_state->mode_changed_independent_from_dsc;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/drm_gem_framebuffer_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
}

for (i = 0; i < info->num_planes; i++) {
unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
unsigned int width = drm_format_info_plane_width(info, mode_cmd->width, i);
unsigned int height = drm_format_info_plane_height(info, mode_cmd->height, i);
unsigned int min_size;

objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
Expand Down
3 changes: 2 additions & 1 deletion drivers/misc/vmw_vmci/vmci_resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ void vmci_resource_remove(struct vmci_resource *resource)
spin_lock(&vmci_resource_table.lock);

hlist_for_each_entry(r, &vmci_resource_table.entries[idx], node) {
if (vmci_handle_is_equal(r->handle, resource->handle)) {
if (vmci_handle_is_equal(r->handle, resource->handle) &&
resource->type == r->type) {
hlist_del_init_rcu(&r->node);
break;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/vt/vt.c
Original file line number Diff line number Diff line change
Expand Up @@ -4548,7 +4548,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
return -EINVAL;

if (op->data) {
font.data = kvmalloc(max_font_size, GFP_KERNEL);
font.data = kvzalloc(max_font_size, GFP_KERNEL);
if (!font.data)
return -ENOMEM;
} else
Expand Down
25 changes: 15 additions & 10 deletions fs/nfsd/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,16 +351,25 @@ static void export_stats_destroy(struct export_stats *stats)
EXP_STATS_COUNTERS_NUM);
}

static void svc_export_put(struct kref *ref)
static void svc_export_release(struct rcu_head *rcu_head)
{
struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
path_put(&exp->ex_path);
auth_domain_put(exp->ex_client);
struct svc_export *exp = container_of(rcu_head, struct svc_export,
ex_rcu);

nfsd4_fslocs_free(&exp->ex_fslocs);
export_stats_destroy(exp->ex_stats);
kfree(exp->ex_stats);
kfree(exp->ex_uuid);
kfree_rcu(exp, ex_rcu);
kfree(exp);
}

static void svc_export_put(struct kref *ref)
{
struct svc_export *exp = container_of(ref, struct svc_export, h.ref);

path_put(&exp->ex_path);
auth_domain_put(exp->ex_client);
call_rcu(&exp->ex_rcu, svc_export_release);
}

static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
Expand Down Expand Up @@ -1372,13 +1381,9 @@ static int e_show(struct seq_file *m, void *p)
return 0;
}

if (!cache_get_rcu(&exp->h))
return 0;

if (cache_check(cd, &exp->h, NULL))
if (cache_check_rcu(cd, &exp->h, NULL))
return 0;

exp_put(exp);
return svc_export_show(m, cd, cp);
}

Expand Down
20 changes: 12 additions & 8 deletions fs/smb/client/smb2file.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)
{
struct smb2_err_rsp *err = iov->iov_base;
struct smb2_symlink_err_rsp *sym = ERR_PTR(-EINVAL);
u8 *end = (u8 *)err + iov->iov_len;
u32 len;

if (err->ErrorContextCount) {
struct smb2_error_context_rsp *p, *end;
struct smb2_error_context_rsp *p;

len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp,
ErrorContextData) +
Expand All @@ -38,8 +39,7 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)
return ERR_PTR(-EINVAL);

p = (struct smb2_error_context_rsp *)err->ErrorData;
end = (struct smb2_error_context_rsp *)((u8 *)err + iov->iov_len);
do {
while ((u8 *)p + sizeof(*p) <= end) {
if (le32_to_cpu(p->ErrorId) == SMB2_ERROR_ID_DEFAULT) {
sym = (struct smb2_symlink_err_rsp *)p->ErrorContextData;
break;
Expand All @@ -49,14 +49,16 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)

len = ALIGN(le32_to_cpu(p->ErrorDataLength), 8);
p = (struct smb2_error_context_rsp *)(p->ErrorContextData + len);
} while (p < end);
}
} else if (le32_to_cpu(err->ByteCount) >= sizeof(*sym) &&
iov->iov_len >= SMB2_SYMLINK_STRUCT_SIZE) {
sym = (struct smb2_symlink_err_rsp *)err->ErrorData;
}

if (!IS_ERR(sym) && (le32_to_cpu(sym->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
le32_to_cpu(sym->ReparseTag) != IO_REPARSE_TAG_SYMLINK))
if (!IS_ERR(sym) &&
((u8 *)sym + sizeof(*sym) > end ||
le32_to_cpu(sym->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
le32_to_cpu(sym->ReparseTag) != IO_REPARSE_TAG_SYMLINK))
sym = ERR_PTR(-EINVAL);

return sym;
Expand Down Expand Up @@ -127,8 +129,10 @@ int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec
print_len = le16_to_cpu(sym->PrintNameLength);
print_offs = le16_to_cpu(sym->PrintNameOffset);

if (iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offs + sub_len ||
iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + print_offs + print_len)
if ((char *)sym->PathBuffer + sub_offs + sub_len >
(char *)iov->iov_base + iov->iov_len ||
(char *)sym->PathBuffer + print_offs + print_len >
(char *)iov->iov_base + iov->iov_len)
return -EINVAL;

return smb2_parse_native_symlink(path,
Expand Down
2 changes: 2 additions & 0 deletions include/linux/sunrpc/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ static inline bool cache_is_expired(struct cache_detail *detail, struct cache_he
return detail->flush_time >= h->last_refresh;
}

extern int cache_check_rcu(struct cache_detail *detail,
struct cache_head *h, struct cache_req *rqstp);
extern int cache_check(struct cache_detail *detail,
struct cache_head *h, struct cache_req *rqstp);
extern void cache_flush(void);
Expand Down
21 changes: 21 additions & 0 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,27 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
return NULL;
}

static inline struct hci_conn *hci_conn_hash_lookup_role(struct hci_dev *hdev,
__u8 type, __u8 role,
bdaddr_t *ba)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;

rcu_read_lock();

list_for_each_entry_rcu(c, &h->list, list) {
if (c->type == type && c->role == role && !bacmp(&c->dst, ba)) {
rcu_read_unlock();
return c;
}
}

rcu_read_unlock();

return NULL;
}

static inline struct hci_conn *hci_conn_hash_lookup_le(struct hci_dev *hdev,
bdaddr_t *ba,
__u8 ba_type)
Expand Down
26 changes: 23 additions & 3 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -3075,8 +3075,18 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,

hci_dev_lock(hdev);

/* Check for existing connection:
*
* 1. If it doesn't exist then it must be receiver/slave role.
* 2. If it does exist confirm that it is connecting/BT_CONNECT in case
* of initiator/master role since there could be a collision where
* either side is attempting to connect or something like a fuzzing
* testing is trying to play tricks to destroy the hcon object before
* it even attempts to connect (e.g. hcon->state == BT_OPEN).
*/
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
if (!conn) {
if (!conn ||
(conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) {
/* In case of error status and there is no connection pending
* just unlock as there is nothing to cleanup.
*/
Expand Down Expand Up @@ -5621,8 +5631,18 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
*/
hci_dev_clear_flag(hdev, HCI_LE_ADV);

conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
if (!conn) {
/* Check for existing connection:
*
* 1. If it doesn't exist then use the role to create a new object.
* 2. If it does exist confirm that it is connecting/BT_CONNECT in case
* of initiator/master role since there could be a collision where
* either side is attempting to connect or something like a fuzzing
* testing is trying to play tricks to destroy the hcon object before
* it even attempts to connect (e.g. hcon->state == BT_OPEN).
*/
conn = hci_conn_hash_lookup_role(hdev, LE_LINK, role, bdaddr);
if (!conn ||
(conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) {
/* In case of error status and there is no connection pending
* just unlock as there is nothing to cleanup.
*/
Expand Down
6 changes: 5 additions & 1 deletion net/sched/act_csum.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,12 @@ TC_INDIRECT_SCOPE int tcf_csum_act(struct sk_buff *skb,
protocol = skb->protocol;
orig_vlan_tag_present = true;
} else {
struct vlan_hdr *vlan = (struct vlan_hdr *)skb->data;
struct vlan_hdr *vlan;

if (!pskb_may_pull(skb, VLAN_HLEN))
goto drop;

vlan = (struct vlan_hdr *)skb->data;
protocol = vlan->h_vlan_encapsulated_proto;
skb_pull(skb, VLAN_HLEN);
skb_reset_network_header(skb);
Expand Down
53 changes: 29 additions & 24 deletions net/sunrpc/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,21 +281,7 @@ static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h
return rv;
}

/*
* This is the generic cache management routine for all
* the authentication caches.
* It checks the currency of a cache item and will (later)
* initiate an upcall to fill it if needed.
*
*
* Returns 0 if the cache_head can be used, or cache_puts it and returns
* -EAGAIN if upcall is pending and request has been queued
* -ETIMEDOUT if upcall failed or request could not be queue or
* upcall completed but item is still invalid (implying that
* the cache item has been replaced with a newer one).
* -ENOENT if cache entry was negative
*/
int cache_check(struct cache_detail *detail,
int cache_check_rcu(struct cache_detail *detail,
struct cache_head *h, struct cache_req *rqstp)
{
int rv;
Expand Down Expand Up @@ -336,6 +322,31 @@ int cache_check(struct cache_detail *detail,
rv = -ETIMEDOUT;
}
}

return rv;
}
EXPORT_SYMBOL_GPL(cache_check_rcu);

/*
* This is the generic cache management routine for all
* the authentication caches.
* It checks the currency of a cache item and will (later)
* initiate an upcall to fill it if needed.
*
*
* Returns 0 if the cache_head can be used, or cache_puts it and returns
* -EAGAIN if upcall is pending and request has been queued
* -ETIMEDOUT if upcall failed or request could not be queue or
* upcall completed but item is still invalid (implying that
* the cache item has been replaced with a newer one).
* -ENOENT if cache entry was negative
*/
int cache_check(struct cache_detail *detail,
struct cache_head *h, struct cache_req *rqstp)
{
int rv;

rv = cache_check_rcu(detail, h, rqstp);
if (rv)
cache_put(h, detail);
return rv;
Expand Down Expand Up @@ -1431,17 +1442,11 @@ static int c_show(struct seq_file *m, void *p)
seq_printf(m, "# expiry=%lld refcnt=%d flags=%lx\n",
convert_to_wallclock(cp->expiry_time),
kref_read(&cp->ref), cp->flags);
if (!cache_get_rcu(cp))
return 0;

if (cache_check(cd, cp, NULL))
/* cache_check does a cache_put on failure */
if (cache_check_rcu(cd, cp, NULL))
seq_puts(m, "# ");
else if (cache_is_expired(cd, cp))
seq_puts(m, "# ");
else {
if (cache_is_expired(cd, cp))
seq_puts(m, "# ");
cache_put(cp, cd);
}

return cd->cache_show(m, cd, cp);
}
Expand Down
Loading