Merge "Merge branch 'android11-5.4' into branch 'android11-5.4-lts'" into android11-5.4-lts

This commit is contained in:
Greg Kroah-Hartman 2024-02-15 13:27:31 +00:00
commit 5400c339e0
11 changed files with 82400 additions and 84924 deletions

14
OWNERS
View File

@ -1,2 +1,12 @@
# include OWNERS from the authoritative android-mainline branch
include kernel/common:android-mainline:/OWNERS
set noparent
# GKI Dr. No Enforcement is active on this branch. Approval of one of the Dr.
# No reviewers is required following a regular CodeReview+2 vote of a code
# reviewer.
#
# See the GKI release documentation (go/gki-dr-no) for further details.
#
# The expanded list of reviewers can be found at:
# https://android.googlesource.com/kernel/common/+/android-mainline/OWNERS_DrNo
include kernel/common:android-mainline:/OWNERS_DrNo

View File

@ -1,12 +0,0 @@
# If we ever add another OWNERS above this directory, it's likely to be
# more permissive, so don't inherit from it
set noparent
adelva@google.com
maennich@google.com
saravanak@google.com
sspatil@google.com
tkjos@google.com
willmcvicker@google.com
# Downstream boards maintained directly in this manifest branch
per-file abi_gki_aarch64_cuttlefish = adelva@google.com, rammuthiah@google.com
per-file abi_gki_aarch64_goldfish = rkir@google.com

File diff suppressed because it is too large Load Diff

View File

@ -2251,6 +2251,7 @@
snd_card_free_when_closed
snd_card_new
snd_card_register
snd_compr_use_pause_in_draining
snd_ctl_add
snd_ctl_boolean_mono_info
snd_ctl_enum_info

View File

@ -33,6 +33,7 @@
#define UINPUT_NAME "uinput"
#define UINPUT_BUFFER_SIZE 16
#define UINPUT_NUM_REQUESTS 16
#define UINPUT_TIMESTAMP_ALLOWED_OFFSET_SECS 10
enum uinput_state { UIST_NEW_DEVICE, UIST_SETUP_COMPLETE, UIST_CREATED };
@ -569,11 +570,40 @@ static int uinput_setup_device_legacy(struct uinput_device *udev,
return retval;
}
/*
* Returns true if the given timestamp is valid (i.e., if all the following
* conditions are satisfied), false otherwise.
* 1) given timestamp is positive
* 2) it's within the allowed offset before the current time
* 3) it's not in the future
*/
static bool is_valid_timestamp(const ktime_t timestamp)
{
ktime_t zero_time;
ktime_t current_time;
ktime_t min_time;
ktime_t offset;
zero_time = ktime_set(0, 0);
if (ktime_compare(zero_time, timestamp) >= 0)
return false;
current_time = ktime_get();
offset = ktime_set(UINPUT_TIMESTAMP_ALLOWED_OFFSET_SECS, 0);
min_time = ktime_sub(current_time, offset);
if (ktime_after(min_time, timestamp) || ktime_after(timestamp, current_time))
return false;
return true;
}
static ssize_t uinput_inject_events(struct uinput_device *udev,
const char __user *buffer, size_t count)
{
struct input_event ev;
size_t bytes = 0;
ktime_t timestamp;
if (count != 0 && count < input_event_size())
return -EINVAL;
@ -588,6 +618,10 @@ static ssize_t uinput_inject_events(struct uinput_device *udev,
if (input_event_from_user(buffer + bytes, &ev))
return -EFAULT;
timestamp = ktime_set(ev.input_event_sec, ev.input_event_usec * NSEC_PER_USEC);
if (is_valid_timestamp(timestamp))
input_set_timestamp(udev->dev, timestamp);
input_event(udev->dev, ev.type, ev.code, ev.value);
bytes += input_event_size();
cond_resched();

View File

@ -608,6 +608,9 @@ struct perf_event {
/* The cumulative AND of all event_caps for events in this group. */
int group_caps;
#ifndef __GENKSYMS__
unsigned int group_generation;
#endif
struct perf_event *group_leader;
struct pmu *pmu;
void *pmu_private;

View File

@ -198,4 +198,5 @@ static inline void snd_compr_set_runtime_buffer(
int snd_compr_stop_error(struct snd_compr_stream *stream,
snd_pcm_state_t state);
void snd_compr_use_pause_in_draining(struct snd_compr_stream *stream);
#endif

View File

@ -1711,28 +1711,31 @@ static inline void perf_event__state_init(struct perf_event *event)
PERF_EVENT_STATE_INACTIVE;
}
static void __perf_event_read_size(struct perf_event *event, int nr_siblings)
static int __perf_event_read_size(u64 read_format, int nr_siblings)
{
int entry = sizeof(u64); /* value */
int size = 0;
int nr = 1;
if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
size += sizeof(u64);
if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
size += sizeof(u64);
if (event->attr.read_format & PERF_FORMAT_ID)
if (read_format & PERF_FORMAT_ID)
entry += sizeof(u64);
if (event->attr.read_format & PERF_FORMAT_GROUP) {
if (read_format & PERF_FORMAT_GROUP) {
nr += nr_siblings;
size += sizeof(u64);
}
size += entry * nr;
event->read_size = size;
/*
* Since perf_event_validate_size() limits this to 16k and inhibits
* adding more siblings, this will never overflow.
*/
return size + nr * entry;
}
static void __perf_event_header_size(struct perf_event *event, u64 sample_type)
@ -1773,8 +1776,9 @@ static void __perf_event_header_size(struct perf_event *event, u64 sample_type)
*/
static void perf_event__header_size(struct perf_event *event)
{
__perf_event_read_size(event,
event->group_leader->nr_siblings);
event->read_size =
__perf_event_read_size(event->attr.read_format,
event->group_leader->nr_siblings);
__perf_event_header_size(event, event->attr.sample_type);
}
@ -1805,24 +1809,35 @@ static void perf_event__id_header_size(struct perf_event *event)
event->id_header_size = size;
}
/*
* Check that adding an event to the group does not result in anybody
* overflowing the 64k event limit imposed by the output buffer.
*
* Specifically, check that the read_size for the event does not exceed 16k,
* read_size being the one term that grows with groups size. Since read_size
* depends on per-event read_format, also (re)check the existing events.
*
* This leaves 48k for the constant size fields and things like callchains,
* branch stacks and register sets.
*/
static bool perf_event_validate_size(struct perf_event *event)
{
/*
* The values computed here will be over-written when we actually
* attach the event.
*/
__perf_event_read_size(event, event->group_leader->nr_siblings + 1);
__perf_event_header_size(event, event->attr.sample_type & ~PERF_SAMPLE_READ);
perf_event__id_header_size(event);
struct perf_event *sibling, *group_leader = event->group_leader;
/*
* Sum the lot; should not exceed the 64k limit we have on records.
* Conservative limit to allow for callchains and other variable fields.
*/
if (event->read_size + event->header_size +
event->id_header_size + sizeof(struct perf_event_header) >= 16*1024)
if (__perf_event_read_size(event->attr.read_format,
group_leader->nr_siblings + 1) > 16*1024)
return false;
if (__perf_event_read_size(group_leader->attr.read_format,
group_leader->nr_siblings + 1) > 16*1024)
return false;
for_each_sibling_event(sibling, group_leader) {
if (__perf_event_read_size(sibling->attr.read_format,
group_leader->nr_siblings + 1) > 16*1024)
return false;
}
return true;
}
@ -1849,6 +1864,7 @@ static void perf_group_attach(struct perf_event *event)
list_add_tail(&event->sibling_list, &group_leader->sibling_list);
group_leader->nr_siblings++;
group_leader->group_generation++;
perf_event__header_size(group_leader);
@ -2004,6 +2020,7 @@ static void perf_group_detach(struct perf_event *event)
if (event->group_leader != event) {
list_del_init(&event->sibling_list);
event->group_leader->nr_siblings--;
event->group_leader->group_generation++;
goto out;
}
@ -4857,7 +4874,7 @@ static int __perf_read_group_add(struct perf_event *leader,
u64 read_format, u64 *values)
{
struct perf_event_context *ctx = leader->ctx;
struct perf_event *sub;
struct perf_event *sub, *parent;
unsigned long flags;
int n = 1; /* skip @nr */
int ret;
@ -4867,6 +4884,33 @@ static int __perf_read_group_add(struct perf_event *leader,
return ret;
raw_spin_lock_irqsave(&ctx->lock, flags);
/*
* Verify the grouping between the parent and child (inherited)
* events is still in tact.
*
* Specifically:
* - leader->ctx->lock pins leader->sibling_list
* - parent->child_mutex pins parent->child_list
* - parent->ctx->mutex pins parent->sibling_list
*
* Because parent->ctx != leader->ctx (and child_list nests inside
* ctx->mutex), group destruction is not atomic between children, also
* see perf_event_release_kernel(). Additionally, parent can grow the
* group.
*
* Therefore it is possible to have parent and child groups in a
* different configuration and summing over such a beast makes no sense
* what so ever.
*
* Reject this.
*/
parent = leader->parent;
if (parent &&
(parent->group_generation != leader->group_generation ||
parent->nr_siblings != leader->nr_siblings)) {
ret = -ECHILD;
goto unlock;
}
/*
* Since we co-schedule groups, {enabled,running} times of siblings
@ -4896,8 +4940,9 @@ static int __perf_read_group_add(struct perf_event *leader,
values[n++] = primary_event_id(sub);
}
unlock:
raw_spin_unlock_irqrestore(&ctx->lock, flags);
return 0;
return ret;
}
static int perf_read_group(struct perf_event *event,
@ -4916,10 +4961,6 @@ static int perf_read_group(struct perf_event *event,
values[0] = 1 + leader->nr_siblings;
/*
* By locking the child_mutex of the leader we effectively
* lock the child list of all siblings.. XXX explain how.
*/
mutex_lock(&leader->child_mutex);
ret = __perf_read_group_add(leader, read_format, values);
@ -12024,6 +12065,7 @@ static int inherit_group(struct perf_event *parent_event,
!perf_get_aux_event(child_ctr, leader))
return -EINVAL;
}
leader->group_generation = parent_event->group_generation;
return 0;
}

View File

@ -7117,14 +7117,9 @@ struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
if (!trans)
return NULL;
trans->net = maybe_get_net(net);
if (!trans->net) {
kfree(trans);
return NULL;
}
refcount_inc(&set->refs);
trans->set = set;
trans->net = get_net(net);
trans->seq = gc_seq;
return trans;

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,8 @@ static DEFINE_MUTEX(device_mutex);
struct snd_compr_file {
unsigned long caps;
bool use_pause_in_draining;
bool pause_in_draining;
struct snd_compr_stream stream;
};
@ -115,6 +117,8 @@ static int snd_compr_open(struct inode *inode, struct file *f)
INIT_DELAYED_WORK(&data->stream.error_work, error_delayed_work);
data->use_pause_in_draining = false;
data->pause_in_draining = false;
data->stream.ops = compr->ops;
data->stream.direction = dirn;
data->stream.private_data = compr->private_data;
@ -662,27 +666,67 @@ snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg)
return ret;
}
/**
* snd_compr_use_pause_in_draining - Allow pause and resume in draining state
* @stream: compress substream to set
*
* Allow pause and resume in draining state.
* Only HW driver supports this transition can call this API.
*/
void snd_compr_use_pause_in_draining(struct snd_compr_stream *stream)
{
struct snd_compr_file *scf = container_of(stream, struct snd_compr_file, stream);
scf->use_pause_in_draining = true;
}
EXPORT_SYMBOL(snd_compr_use_pause_in_draining);
static int snd_compr_pause(struct snd_compr_stream *stream)
{
int retval;
struct snd_compr_file *scf = container_of(stream, struct snd_compr_file, stream);
if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
switch (stream->runtime->state) {
case SNDRV_PCM_STATE_RUNNING:
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
if (!retval)
stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
break;
case SNDRV_PCM_STATE_DRAINING:
if (!scf->use_pause_in_draining)
return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
if (!retval)
scf->pause_in_draining = true;
break;
default:
return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
if (!retval)
stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
}
return retval;
}
static int snd_compr_resume(struct snd_compr_stream *stream)
{
int retval;
struct snd_compr_file *scf = container_of(stream, struct snd_compr_file, stream);
if (stream->runtime->state != SNDRV_PCM_STATE_PAUSED)
switch (stream->runtime->state) {
case SNDRV_PCM_STATE_PAUSED:
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
if (!retval)
stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
break;
case SNDRV_PCM_STATE_DRAINING:
if (!scf->pause_in_draining)
return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
if (!retval)
scf->pause_in_draining = false;
break;
default:
return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
if (!retval)
stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
}
return retval;
}
@ -710,6 +754,7 @@ static int snd_compr_start(struct snd_compr_stream *stream)
static int snd_compr_stop(struct snd_compr_stream *stream)
{
int retval;
struct snd_compr_file *scf = container_of(stream, struct snd_compr_file, stream);
switch (stream->runtime->state) {
case SNDRV_PCM_STATE_OPEN:
@ -722,6 +767,7 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
if (!retval) {
scf->pause_in_draining = false;
snd_compr_drain_notify(stream);
stream->runtime->total_bytes_available = 0;
stream->runtime->total_bytes_transferred = 0;