Merge branch 'android12-5.10' into android12-5.10-lts

Sync up with android12-5.10 for the following commits:

6c3417436a ANDROID: kernel: fix module info for debug_kinfo
774f1bd29c ANDROID: Disable CFI on restricted vendor hooks in TRACE_HEADER_MULTI_READ
90c60a51f5 UPSTREAM: f2fs: guarantee to write dirty data when enabling checkpoint back
8cf5bb6946 UPSTREAM: mm: memblock: fix section mismatch warning again
f00a543047 FROMLIST: usb: gadget: u_audio: EP-OUT bInterval in fback frequency
3f26745cae FROMLIST: usb: gadget: f_uac2: fixed EP-IN wMaxPacketSize
ab9ceb4334 FROMLIST: usb: gadget: f_uac2: Add missing companion descriptor for feedback EP
35afadf0da FROMLIST: thermal: Fix a NULL pointer dereference
3d371f087c UPSTREAM: usb: gadget: f_uac2: fixup feedback endpoint stop
406a51b486 UPSTREAM: usb: gadget: u_audio: add real feedback implementation
d33287acf3 UPSTREAM: usb: gadget: f_uac2: add adaptive sync support for capture
c71892dd9e UPSTREAM: usb: gadget: f_uac2/u_audio: add feedback endpoint support
a844dfbbcb UPSTREAM: usb: gadget: u_audio: convert to strscpy
955f917251 ANDROID: vendor_hooks: Add hook in try_to_unmap_one()
878e0caa77 ANDROID: vendor_hooks: Add hook in mmap_region()
b0778aaff4 ANDROID: vendor_hooks: export android_vh_kmalloc_slab
94fbab9d6c ANDROID: vendor_hooks: Add hook in kmalloc_slab()
73839b71c8 FROMGIT: usb: dwc3: Decouple USB 2.0 L1 & L2 events
2c68b9071d ANDROID: GKI: update xiaomi symbol list
8da32d526d ANDROID: cfi: explicitly clear diag in __cfi_slowpath

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I71c4d03d373d9cef0c467ceea52b62ada755e701
This commit is contained in:
Greg Kroah-Hartman
2021-09-13 18:11:33 +02:00
21 changed files with 505 additions and 23 deletions

View File

@@ -8,6 +8,8 @@ Description:
c_chmask capture channel mask c_chmask capture channel mask
c_srate capture sampling rate c_srate capture sampling rate
c_ssize capture sample size (bytes) c_ssize capture sample size (bytes)
c_sync capture synchronization type (async/adaptive)
fb_max maximum extra bandwidth in async mode
p_chmask playback channel mask p_chmask playback channel mask
p_srate playback sampling rate p_srate playback sampling rate
p_ssize playback sample size (bytes) p_ssize playback sample size (bytes)

View File

@@ -728,6 +728,8 @@ The uac2 function provides these attributes in its function directory:
c_chmask capture channel mask c_chmask capture channel mask
c_srate capture sampling rate c_srate capture sampling rate
c_ssize capture sample size (bytes) c_ssize capture sample size (bytes)
c_sync capture synchronization type (async/adaptive)
fb_max maximum extra bandwidth in async mode
p_chmask playback channel mask p_chmask playback channel mask
p_srate playback sampling rate p_srate playback sampling rate
p_ssize playback sample size (bytes) p_ssize playback sample size (bytes)

View File

@@ -142,6 +142,31 @@
free_uid free_uid
find_user find_user
#required by migt.ko
__traceiter_android_rvh_after_enqueue_task
__traceiter_android_rvh_after_dequeue_task
__traceiter_android_vh_map_util_freq
__tracepoint_android_rvh_after_enqueue_task
__tracepoint_android_rvh_after_dequeue_task
__tracepoint_android_vh_map_util_freq
#required by turbo.ko
__traceiter_android_rvh_set_cpus_allowed_comm
__traceiter_android_vh_sched_setaffinity_early
__traceiter_android_rvh_cpuset_fork
__tracepoint_android_rvh_set_cpus_allowed_comm
__tracepoint_android_vh_sched_setaffinity_early
__tracepoint_android_rvh_cpuset_fork
cpuset_cpus_allowed
#required by fas.ko
__traceiter_android_rvh_check_preempt_tick
__traceiter_android_rvh_dequeue_entity
__traceiter_android_rvh_enqueue_entity
__tracepoint_android_rvh_check_preempt_tick
__tracepoint_android_rvh_dequeue_entity
__tracepoint_android_rvh_enqueue_entity
#required by pm8941-pwrkey.ko module #required by pm8941-pwrkey.ko module
console_printk console_printk
@@ -157,3 +182,8 @@
__traceiter_android_vh_tune_swappiness __traceiter_android_vh_tune_swappiness
__tracepoint_android_vh_tune_swappiness __tracepoint_android_vh_tune_swappiness
#required by msm_drm.ko module
drm_get_connector_type_name
#required by mi_gamekey.ko module
gpio_request_array

View File

@@ -380,3 +380,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_udp_sendmsg);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_udp_recvmsg); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_udp_recvmsg);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_tcp_recvmsg_stat); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_tcp_recvmsg_stat);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_pci_d3_sleep); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_pci_d3_sleep);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kmalloc_slab);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmap_region);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_to_unmap_one);

View File

@@ -13,6 +13,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_reserved_mem.h> #include <linux/of_reserved_mem.h>
#include <linux/pgtable.h> #include <linux/pgtable.h>
#include <asm/module.h>
#include "debug_kinfo.h" #include "debug_kinfo.h"
/* /*
@@ -163,7 +164,10 @@ static int debug_kinfo_probe(struct platform_device *pdev)
info->mod_core_layout_offset = offsetof(struct module, core_layout); info->mod_core_layout_offset = offsetof(struct module, core_layout);
info->mod_init_layout_offset = offsetof(struct module, init_layout); info->mod_init_layout_offset = offsetof(struct module, init_layout);
info->mod_kallsyms_offset = offsetof(struct module, kallsyms); info->mod_kallsyms_offset = offsetof(struct module, kallsyms);
#if defined(CONFIG_MODULES) && defined(MODULES_VADDR) #if defined(CONFIG_RANDOMIZE_BASE) && defined(MODULES_VSIZE)
info->module_start_va = module_alloc_base;
info->module_end_va = info->module_start_va + MODULES_VSIZE;
#elif defined(CONFIG_MODULES) && defined(MODULES_VADDR)
info->module_start_va = MODULES_VADDR; info->module_start_va = MODULES_VADDR;
info->module_end_va = MODULES_END; info->module_end_va = MODULES_END;
#else #else

View File

@@ -89,7 +89,7 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz,
{ {
struct __thermal_zone *data = tz->devdata; struct __thermal_zone *data = tz->devdata;
if (!data->ops->get_temp) if (!data->ops || !data->ops->get_temp)
return -EINVAL; return -EINVAL;
return data->ops->get_temp(data->sensor_data, temp); return data->ops->get_temp(data->sensor_data, temp);
@@ -186,6 +186,9 @@ static int of_thermal_set_emul_temp(struct thermal_zone_device *tz,
{ {
struct __thermal_zone *data = tz->devdata; struct __thermal_zone *data = tz->devdata;
if (!data->ops || !data->ops->set_emul_temp)
return -EINVAL;
return data->ops->set_emul_temp(data->sensor_data, temp); return data->ops->set_emul_temp(data->sensor_data, temp);
} }
@@ -194,7 +197,7 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
{ {
struct __thermal_zone *data = tz->devdata; struct __thermal_zone *data = tz->devdata;
if (!data->ops->get_trend) if (!data->ops || !data->ops->get_trend)
return -EINVAL; return -EINVAL;
return data->ops->get_trend(data->sensor_data, trip, trend); return data->ops->get_trend(data->sensor_data, trip, trend);
@@ -301,7 +304,7 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
if (trip >= data->ntrips || trip < 0) if (trip >= data->ntrips || trip < 0)
return -EDOM; return -EDOM;
if (data->ops->set_trip_temp) { if (data->ops && data->ops->set_trip_temp) {
int ret; int ret;
ret = data->ops->set_trip_temp(data->sensor_data, trip, temp); ret = data->ops->set_trip_temp(data->sensor_data, trip, temp);

View File

@@ -1050,6 +1050,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
if (!DWC3_VER_IS_PRIOR(DWC3, 290A)) if (!DWC3_VER_IS_PRIOR(DWC3, 290A))
reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW; reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
/*
* Decouple USB 2.0 L1 & L2 events which will allow for
* gadget driver to only receive U3/L2 suspend & wakeup
* events and prevent the more frequent L1 LPM transitions
* from interrupting the driver.
*/
if (!DWC3_VER_IS_PRIOR(DWC3, 300A))
reg |= DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT;
if (dwc->dis_tx_ipgap_linecheck_quirk) if (dwc->dis_tx_ipgap_linecheck_quirk)
reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS; reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;

View File

@@ -257,9 +257,10 @@
#define DWC3_GUCTL_HSTINAUTORETRY BIT(14) #define DWC3_GUCTL_HSTINAUTORETRY BIT(14)
/* Global User Control 1 Register */ /* Global User Control 1 Register */
#define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17) #define DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT BIT(31)
#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28) #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
#define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24) #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24)
#define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17)
/* Global Status Register */ /* Global Status Register */
#define DWC3_GSTS_OTG_IP BIT(10) #define DWC3_GSTS_OTG_IP BIT(10)

View File

@@ -44,6 +44,7 @@
#define EPIN_EN(_opts) ((_opts)->p_chmask != 0) #define EPIN_EN(_opts) ((_opts)->p_chmask != 0)
#define EPOUT_EN(_opts) ((_opts)->c_chmask != 0) #define EPOUT_EN(_opts) ((_opts)->c_chmask != 0)
#define EPOUT_FBACK_IN_EN(_opts) ((_opts)->c_sync == USB_ENDPOINT_SYNC_ASYNC)
struct f_uac2 { struct f_uac2 {
struct g_audio g_audio; struct g_audio g_audio;
@@ -273,7 +274,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = {
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT, .bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, /* .bmAttributes = DYNAMIC */
/* .wMaxPacketSize = DYNAMIC */ /* .wMaxPacketSize = DYNAMIC */
.bInterval = 1, .bInterval = 1,
}; };
@@ -282,7 +283,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = {
.bLength = USB_DT_ENDPOINT_SIZE, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, /* .bmAttributes = DYNAMIC */
/* .wMaxPacketSize = DYNAMIC */ /* .wMaxPacketSize = DYNAMIC */
.bInterval = 4, .bInterval = 4,
}; };
@@ -292,7 +293,7 @@ static struct usb_endpoint_descriptor ss_epout_desc = {
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT, .bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, /* .bmAttributes = DYNAMIC */
/* .wMaxPacketSize = DYNAMIC */ /* .wMaxPacketSize = DYNAMIC */
.bInterval = 4, .bInterval = 4,
}; };
@@ -317,6 +318,37 @@ static struct uac2_iso_endpoint_descriptor as_iso_out_desc = {
.wLockDelay = 0, .wLockDelay = 0,
}; };
/* STD AS ISO IN Feedback Endpoint */
static struct usb_endpoint_descriptor fs_epin_fback_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_USAGE_FEEDBACK,
.wMaxPacketSize = cpu_to_le16(3),
.bInterval = 1,
};
static struct usb_endpoint_descriptor hs_epin_fback_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_USAGE_FEEDBACK,
.wMaxPacketSize = cpu_to_le16(4),
.bInterval = 4,
};
static struct usb_endpoint_descriptor ss_epin_fback_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_USAGE_FEEDBACK,
.wMaxPacketSize = cpu_to_le16(4),
.bInterval = 4,
};
/* Audio Streaming IN Interface - Alt0 */ /* Audio Streaming IN Interface - Alt0 */
static struct usb_interface_descriptor std_as_in_if0_desc = { static struct usb_interface_descriptor std_as_in_if0_desc = {
.bLength = sizeof std_as_in_if0_desc, .bLength = sizeof std_as_in_if0_desc,
@@ -431,6 +463,7 @@ static struct usb_descriptor_header *fs_audio_desc[] = {
(struct usb_descriptor_header *)&as_out_fmt1_desc, (struct usb_descriptor_header *)&as_out_fmt1_desc,
(struct usb_descriptor_header *)&fs_epout_desc, (struct usb_descriptor_header *)&fs_epout_desc,
(struct usb_descriptor_header *)&as_iso_out_desc, (struct usb_descriptor_header *)&as_iso_out_desc,
(struct usb_descriptor_header *)&fs_epin_fback_desc,
(struct usb_descriptor_header *)&std_as_in_if0_desc, (struct usb_descriptor_header *)&std_as_in_if0_desc,
(struct usb_descriptor_header *)&std_as_in_if1_desc, (struct usb_descriptor_header *)&std_as_in_if1_desc,
@@ -461,6 +494,7 @@ static struct usb_descriptor_header *hs_audio_desc[] = {
(struct usb_descriptor_header *)&as_out_fmt1_desc, (struct usb_descriptor_header *)&as_out_fmt1_desc,
(struct usb_descriptor_header *)&hs_epout_desc, (struct usb_descriptor_header *)&hs_epout_desc,
(struct usb_descriptor_header *)&as_iso_out_desc, (struct usb_descriptor_header *)&as_iso_out_desc,
(struct usb_descriptor_header *)&hs_epin_fback_desc,
(struct usb_descriptor_header *)&std_as_in_if0_desc, (struct usb_descriptor_header *)&std_as_in_if0_desc,
(struct usb_descriptor_header *)&std_as_in_if1_desc, (struct usb_descriptor_header *)&std_as_in_if1_desc,
@@ -492,6 +526,8 @@ static struct usb_descriptor_header *ss_audio_desc[] = {
(struct usb_descriptor_header *)&ss_epout_desc, (struct usb_descriptor_header *)&ss_epout_desc,
(struct usb_descriptor_header *)&ss_epout_desc_comp, (struct usb_descriptor_header *)&ss_epout_desc_comp,
(struct usb_descriptor_header *)&as_iso_out_desc, (struct usb_descriptor_header *)&as_iso_out_desc,
(struct usb_descriptor_header *)&ss_epin_fback_desc,
(struct usb_descriptor_header *)&ss_epin_desc_comp,
(struct usb_descriptor_header *)&std_as_in_if0_desc, (struct usb_descriptor_header *)&std_as_in_if0_desc,
(struct usb_descriptor_header *)&std_as_in_if1_desc, (struct usb_descriptor_header *)&std_as_in_if1_desc,
@@ -549,8 +585,17 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
ssize = uac2_opts->c_ssize; ssize = uac2_opts->c_ssize;
} }
max_size_bw = num_channels(chmask) * ssize * if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) {
((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1); // Win10 requires max packet size + 1 frame
srate = srate * (1000 + uac2_opts->fb_max) / 1000;
// updated srate is always bigger, therefore DIV_ROUND_UP always yields +1
max_size_bw = num_channels(chmask) * ssize *
(DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))));
} else {
// adding 1 frame provision for Win10
max_size_bw = num_channels(chmask) * ssize *
(DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))) + 1);
}
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw,
max_size_ep)); max_size_ep));
@@ -568,22 +613,26 @@ static void setup_headers(struct f_uac2_opts *opts,
struct usb_ss_ep_comp_descriptor *epin_desc_comp = NULL; struct usb_ss_ep_comp_descriptor *epin_desc_comp = NULL;
struct usb_endpoint_descriptor *epout_desc; struct usb_endpoint_descriptor *epout_desc;
struct usb_endpoint_descriptor *epin_desc; struct usb_endpoint_descriptor *epin_desc;
struct usb_endpoint_descriptor *epin_fback_desc;
int i; int i;
switch (speed) { switch (speed) {
case USB_SPEED_FULL: case USB_SPEED_FULL:
epout_desc = &fs_epout_desc; epout_desc = &fs_epout_desc;
epin_desc = &fs_epin_desc; epin_desc = &fs_epin_desc;
epin_fback_desc = &fs_epin_fback_desc;
break; break;
case USB_SPEED_HIGH: case USB_SPEED_HIGH:
epout_desc = &hs_epout_desc; epout_desc = &hs_epout_desc;
epin_desc = &hs_epin_desc; epin_desc = &hs_epin_desc;
epin_fback_desc = &hs_epin_fback_desc;
break; break;
default: default:
epout_desc = &ss_epout_desc; epout_desc = &ss_epout_desc;
epin_desc = &ss_epin_desc; epin_desc = &ss_epin_desc;
epout_desc_comp = &ss_epout_desc_comp; epout_desc_comp = &ss_epout_desc_comp;
epin_desc_comp = &ss_epin_desc_comp; epin_desc_comp = &ss_epin_desc_comp;
epin_fback_desc = &ss_epin_fback_desc;
} }
i = 0; i = 0;
@@ -611,6 +660,12 @@ static void setup_headers(struct f_uac2_opts *opts,
headers[i++] = USBDHDR(epout_desc_comp); headers[i++] = USBDHDR(epout_desc_comp);
headers[i++] = USBDHDR(&as_iso_out_desc); headers[i++] = USBDHDR(&as_iso_out_desc);
if (EPOUT_FBACK_IN_EN(opts)) {
headers[i++] = USBDHDR(epin_fback_desc);
if (epin_desc_comp)
headers[i++] = USBDHDR(epin_desc_comp);
}
} }
if (EPIN_EN(opts)) { if (EPIN_EN(opts)) {
headers[i++] = USBDHDR(&std_as_in_if0_desc); headers[i++] = USBDHDR(&std_as_in_if0_desc);
@@ -781,6 +836,23 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
std_as_out_if1_desc.bInterfaceNumber = ret; std_as_out_if1_desc.bInterfaceNumber = ret;
uac2->as_out_intf = ret; uac2->as_out_intf = ret;
uac2->as_out_alt = 0; uac2->as_out_alt = 0;
if (EPOUT_FBACK_IN_EN(uac2_opts)) {
fs_epout_desc.bmAttributes =
USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC;
hs_epout_desc.bmAttributes =
USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC;
ss_epout_desc.bmAttributes =
USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC;
std_as_out_if1_desc.bNumEndpoints++;
} else {
fs_epout_desc.bmAttributes =
USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE;
hs_epout_desc.bmAttributes =
USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE;
ss_epout_desc.bmAttributes =
USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE;
}
} }
if (EPIN_EN(uac2_opts)) { if (EPIN_EN(uac2_opts)) {
@@ -844,6 +916,15 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
return -ENODEV; return -ENODEV;
} }
if (EPOUT_FBACK_IN_EN(uac2_opts)) {
agdev->in_ep_fback = usb_ep_autoconfig(gadget,
&fs_epin_fback_desc);
if (!agdev->in_ep_fback) {
dev_err(dev, "%s:%d Error!\n",
__func__, __LINE__);
return -ENODEV;
}
}
} }
if (EPIN_EN(uac2_opts)) { if (EPIN_EN(uac2_opts)) {
@@ -867,8 +948,10 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
le16_to_cpu(ss_epout_desc.wMaxPacketSize)); le16_to_cpu(ss_epout_desc.wMaxPacketSize));
hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
hs_epin_fback_desc.bEndpointAddress = fs_epin_fback_desc.bEndpointAddress;
hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
ss_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; ss_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
ss_epin_fback_desc.bEndpointAddress = fs_epin_fback_desc.bEndpointAddress;
ss_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; ss_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
setup_descriptor(uac2_opts); setup_descriptor(uac2_opts);
@@ -887,6 +970,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
agdev->params.c_srate = uac2_opts->c_srate; agdev->params.c_srate = uac2_opts->c_srate;
agdev->params.c_ssize = uac2_opts->c_ssize; agdev->params.c_ssize = uac2_opts->c_ssize;
agdev->params.req_number = uac2_opts->req_number; agdev->params.req_number = uac2_opts->req_number;
agdev->params.fb_max = uac2_opts->fb_max;
ret = g_audio_setup(agdev, "UAC2 PCM", "UAC2_Gadget"); ret = g_audio_setup(agdev, "UAC2 PCM", "UAC2_Gadget");
if (ret) if (ret)
goto err_free_descs; goto err_free_descs;
@@ -1195,13 +1279,71 @@ end: \
\ \
CONFIGFS_ATTR(f_uac2_opts_, name) CONFIGFS_ATTR(f_uac2_opts_, name)
#define UAC2_ATTRIBUTE_SYNC(name) \
static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \
char *page) \
{ \
struct f_uac2_opts *opts = to_f_uac2_opts(item); \
int result; \
char *str; \
\
mutex_lock(&opts->lock); \
switch (opts->name) { \
case USB_ENDPOINT_SYNC_ASYNC: \
str = "async"; \
break; \
case USB_ENDPOINT_SYNC_ADAPTIVE: \
str = "adaptive"; \
break; \
default: \
str = "unknown"; \
break; \
} \
result = sprintf(page, "%s\n", str); \
mutex_unlock(&opts->lock); \
\
return result; \
} \
\
static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \
const char *page, size_t len) \
{ \
struct f_uac2_opts *opts = to_f_uac2_opts(item); \
int ret = 0; \
\
mutex_lock(&opts->lock); \
if (opts->refcnt) { \
ret = -EBUSY; \
goto end; \
} \
\
if (!strncmp(page, "async", 5)) \
opts->name = USB_ENDPOINT_SYNC_ASYNC; \
else if (!strncmp(page, "adaptive", 8)) \
opts->name = USB_ENDPOINT_SYNC_ADAPTIVE; \
else { \
ret = -EINVAL; \
goto end; \
} \
\
ret = len; \
\
end: \
mutex_unlock(&opts->lock); \
return ret; \
} \
\
CONFIGFS_ATTR(f_uac2_opts_, name)
UAC2_ATTRIBUTE(p_chmask); UAC2_ATTRIBUTE(p_chmask);
UAC2_ATTRIBUTE(p_srate); UAC2_ATTRIBUTE(p_srate);
UAC2_ATTRIBUTE(p_ssize); UAC2_ATTRIBUTE(p_ssize);
UAC2_ATTRIBUTE(c_chmask); UAC2_ATTRIBUTE(c_chmask);
UAC2_ATTRIBUTE(c_srate); UAC2_ATTRIBUTE(c_srate);
UAC2_ATTRIBUTE_SYNC(c_sync);
UAC2_ATTRIBUTE(c_ssize); UAC2_ATTRIBUTE(c_ssize);
UAC2_ATTRIBUTE(req_number); UAC2_ATTRIBUTE(req_number);
UAC2_ATTRIBUTE(fb_max);
static struct configfs_attribute *f_uac2_attrs[] = { static struct configfs_attribute *f_uac2_attrs[] = {
&f_uac2_opts_attr_p_chmask, &f_uac2_opts_attr_p_chmask,
@@ -1210,7 +1352,9 @@ static struct configfs_attribute *f_uac2_attrs[] = {
&f_uac2_opts_attr_c_chmask, &f_uac2_opts_attr_c_chmask,
&f_uac2_opts_attr_c_srate, &f_uac2_opts_attr_c_srate,
&f_uac2_opts_attr_c_ssize, &f_uac2_opts_attr_c_ssize,
&f_uac2_opts_attr_c_sync,
&f_uac2_opts_attr_req_number, &f_uac2_opts_attr_req_number,
&f_uac2_opts_attr_fb_max,
NULL, NULL,
}; };
@@ -1248,7 +1392,9 @@ static struct usb_function_instance *afunc_alloc_inst(void)
opts->c_chmask = UAC2_DEF_CCHMASK; opts->c_chmask = UAC2_DEF_CCHMASK;
opts->c_srate = UAC2_DEF_CSRATE; opts->c_srate = UAC2_DEF_CSRATE;
opts->c_ssize = UAC2_DEF_CSSIZE; opts->c_ssize = UAC2_DEF_CSSIZE;
opts->c_sync = UAC2_DEF_CSYNC;
opts->req_number = UAC2_DEF_REQ_NUM; opts->req_number = UAC2_DEF_REQ_NUM;
opts->fb_max = UAC2_DEF_FB_MAX;
return &opts->func_inst; return &opts->func_inst;
} }

View File

@@ -16,6 +16,7 @@
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/control.h>
#include "u_audio.h" #include "u_audio.h"
@@ -35,9 +36,13 @@ struct uac_rtd_params {
void *rbuf; void *rbuf;
unsigned int pitch; /* Stream pitch ratio to 1000000 */
unsigned int max_psize; /* MaxPacketSize of endpoint */ unsigned int max_psize; /* MaxPacketSize of endpoint */
struct usb_request **reqs; struct usb_request **reqs;
struct usb_request *req_fback; /* Feedback endpoint request */
bool fb_ep_enabled; /* if the ep is enabled */
}; };
struct snd_uac_chip { struct snd_uac_chip {
@@ -70,6 +75,55 @@ static const struct snd_pcm_hardware uac_pcm_hardware = {
.periods_min = MIN_PERIODS, .periods_min = MIN_PERIODS,
}; };
static void u_audio_set_fback_frequency(enum usb_device_speed speed,
struct usb_ep *out_ep,
unsigned long long freq,
unsigned int pitch,
void *buf)
{
u32 ff = 0;
const struct usb_endpoint_descriptor *ep_desc;
/*
* Because the pitch base is 1000000, the final divider here
* will be 1000 * 1000000 = 1953125 << 9
*
* Instead of dealing with big numbers lets fold this 9 left shift
*/
if (speed == USB_SPEED_FULL) {
/*
* Full-speed feedback endpoints report frequency
* in samples/frame
* Format is encoded in Q10.10 left-justified in the 24 bits,
* so that it has a Q10.14 format.
*
* ff = (freq << 14) / 1000
*/
freq <<= 5;
} else {
/*
* High-speed feedback endpoints report frequency
* in samples/microframe.
* Format is encoded in Q12.13 fitted into four bytes so that
* the binary point is located between the second and the third
* byte fromat (that is Q16.16)
*
* ff = (freq << 16) / 8000
*
* Win10 and OSX UAC2 drivers require number of samples per packet
* in order to honor the feedback value.
* Linux snd-usb-audio detects the applied bit-shift automatically.
*/
ep_desc = out_ep->desc;
freq <<= 4 + (ep_desc->bInterval - 1);
}
ff = DIV_ROUND_CLOSEST_ULL((freq * pitch), 1953125);
*(__le32 *)buf = cpu_to_le32(ff);
}
static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
{ {
unsigned int pending; unsigned int pending;
@@ -173,6 +227,41 @@ exit:
dev_err(uac->card->dev, "%d Error!\n", __LINE__); dev_err(uac->card->dev, "%d Error!\n", __LINE__);
} }
static void u_audio_iso_fback_complete(struct usb_ep *ep,
struct usb_request *req)
{
struct uac_rtd_params *prm = req->context;
struct snd_uac_chip *uac = prm->uac;
struct g_audio *audio_dev = uac->audio_dev;
struct uac_params *params = &audio_dev->params;
int status = req->status;
/* i/f shutting down */
if (!prm->fb_ep_enabled) {
kfree(req->buf);
usb_ep_free_request(ep, req);
return;
}
if (req->status == -ESHUTDOWN)
return;
/*
* We can't really do much about bad xfers.
* Afterall, the ISOCH xfers could fail legitimately.
*/
if (status)
pr_debug("%s: iso_complete status(%d) %d/%d\n",
__func__, status, req->actual, req->length);
u_audio_set_fback_frequency(audio_dev->gadget->speed, audio_dev->out_ep,
params->c_srate, prm->pitch,
req->buf);
if (usb_ep_queue(ep, req, GFP_ATOMIC))
dev_err(uac->card->dev, "%d Error!\n", __LINE__);
}
static int uac_pcm_trigger(struct snd_pcm_substream *substream, int cmd) static int uac_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{ {
struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
@@ -335,13 +424,34 @@ static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep)
dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__);
} }
static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep)
{
struct snd_uac_chip *uac = prm->uac;
if (!prm->fb_ep_enabled)
return;
prm->fb_ep_enabled = false;
if (prm->req_fback) {
if (usb_ep_dequeue(ep, prm->req_fback)) {
kfree(prm->req_fback->buf);
usb_ep_free_request(ep, prm->req_fback);
}
prm->req_fback = NULL;
}
if (usb_ep_disable(ep))
dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__);
}
int u_audio_start_capture(struct g_audio *audio_dev) int u_audio_start_capture(struct g_audio *audio_dev)
{ {
struct snd_uac_chip *uac = audio_dev->uac; struct snd_uac_chip *uac = audio_dev->uac;
struct usb_gadget *gadget = audio_dev->gadget; struct usb_gadget *gadget = audio_dev->gadget;
struct device *dev = &gadget->dev; struct device *dev = &gadget->dev;
struct usb_request *req; struct usb_request *req, *req_fback;
struct usb_ep *ep; struct usb_ep *ep, *ep_fback;
struct uac_rtd_params *prm; struct uac_rtd_params *prm;
struct uac_params *params = &audio_dev->params; struct uac_params *params = &audio_dev->params;
int req_len, i; int req_len, i;
@@ -373,6 +483,43 @@ int u_audio_start_capture(struct g_audio *audio_dev)
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
} }
ep_fback = audio_dev->in_ep_fback;
if (!ep_fback)
return 0;
/* Setup feedback endpoint */
config_ep_by_speed(gadget, &audio_dev->func, ep_fback);
prm->fb_ep_enabled = true;
usb_ep_enable(ep_fback);
req_len = ep_fback->maxpacket;
req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC);
if (req_fback == NULL)
return -ENOMEM;
prm->req_fback = req_fback;
req_fback->zero = 0;
req_fback->context = prm;
req_fback->length = req_len;
req_fback->complete = u_audio_iso_fback_complete;
req_fback->buf = kzalloc(req_len, GFP_ATOMIC);
if (!req_fback->buf)
return -ENOMEM;
/*
* Configure the feedback endpoint's reported frequency.
* Always start with original frequency since its deviation can't
* be meauserd at start of playback
*/
prm->pitch = 1000000;
u_audio_set_fback_frequency(audio_dev->gadget->speed, ep,
params->c_srate, prm->pitch,
req_fback->buf);
if (usb_ep_queue(ep_fback, req_fback, GFP_ATOMIC))
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(u_audio_start_capture); EXPORT_SYMBOL_GPL(u_audio_start_capture);
@@ -381,6 +528,8 @@ void u_audio_stop_capture(struct g_audio *audio_dev)
{ {
struct snd_uac_chip *uac = audio_dev->uac; struct snd_uac_chip *uac = audio_dev->uac;
if (audio_dev->in_ep_fback)
free_ep_fback(&uac->c_prm, audio_dev->in_ep_fback);
free_ep(&uac->c_prm, audio_dev->out_ep); free_ep(&uac->c_prm, audio_dev->out_ep);
} }
EXPORT_SYMBOL_GPL(u_audio_stop_capture); EXPORT_SYMBOL_GPL(u_audio_stop_capture);
@@ -462,12 +611,82 @@ void u_audio_stop_playback(struct g_audio *audio_dev)
} }
EXPORT_SYMBOL_GPL(u_audio_stop_playback); EXPORT_SYMBOL_GPL(u_audio_stop_playback);
static int u_audio_pitch_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol);
struct snd_uac_chip *uac = prm->uac;
struct g_audio *audio_dev = uac->audio_dev;
struct uac_params *params = &audio_dev->params;
unsigned int pitch_min, pitch_max;
pitch_min = (1000 - FBACK_SLOW_MAX) * 1000;
pitch_max = (1000 + params->fb_max) * 1000;
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
uinfo->value.integer.min = pitch_min;
uinfo->value.integer.max = pitch_max;
uinfo->value.integer.step = 1;
return 0;
}
static int u_audio_pitch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol);
ucontrol->value.integer.value[0] = prm->pitch;
return 0;
}
static int u_audio_pitch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol);
struct snd_uac_chip *uac = prm->uac;
struct g_audio *audio_dev = uac->audio_dev;
struct uac_params *params = &audio_dev->params;
unsigned int val;
unsigned int pitch_min, pitch_max;
int change = 0;
pitch_min = (1000 - FBACK_SLOW_MAX) * 1000;
pitch_max = (1000 + params->fb_max) * 1000;
val = ucontrol->value.integer.value[0];
if (val < pitch_min)
val = pitch_min;
if (val > pitch_max)
val = pitch_max;
if (prm->pitch != val) {
prm->pitch = val;
change = 1;
}
return change;
}
static const struct snd_kcontrol_new u_audio_controls[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "Capture Pitch 1000000",
.info = u_audio_pitch_info,
.get = u_audio_pitch_get,
.put = u_audio_pitch_put,
},
};
int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
const char *card_name) const char *card_name)
{ {
struct snd_uac_chip *uac; struct snd_uac_chip *uac;
struct snd_card *card; struct snd_card *card;
struct snd_pcm *pcm; struct snd_pcm *pcm;
struct snd_kcontrol *kctl;
struct uac_params *params; struct uac_params *params;
int p_chmask, c_chmask; int p_chmask, c_chmask;
int err; int err;
@@ -548,15 +767,32 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
if (err < 0) if (err < 0)
goto snd_fail; goto snd_fail;
strlcpy(pcm->name, pcm_name, sizeof(pcm->name)); strscpy(pcm->name, pcm_name, sizeof(pcm->name));
pcm->private_data = uac; pcm->private_data = uac;
uac->pcm = pcm; uac->pcm = pcm;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops);
strlcpy(card->driver, card_name, sizeof(card->driver)); if (c_chmask && g_audio->in_ep_fback) {
strlcpy(card->shortname, card_name, sizeof(card->shortname)); strscpy(card->mixername, card_name, sizeof(card->driver));
kctl = snd_ctl_new1(&u_audio_controls[0], &uac->c_prm);
if (!kctl) {
err = -ENOMEM;
goto snd_fail;
}
kctl->id.device = pcm->device;
kctl->id.subdevice = 0;
err = snd_ctl_add(card, kctl);
if (err < 0)
goto snd_fail;
}
strscpy(card->driver, card_name, sizeof(card->driver));
strscpy(card->shortname, card_name, sizeof(card->shortname));
sprintf(card->longname, "%s %i", card_name, card->dev->id); sprintf(card->longname, "%s %i", card_name, card->dev->id);
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,

View File

@@ -11,6 +11,14 @@
#include <linux/usb/composite.h> #include <linux/usb/composite.h>
/*
* Same maximum frequency deviation on the slower side as in
* sound/usb/endpoint.c. Value is expressed in per-mil deviation.
* The maximum deviation on the faster side will be provided as
* parameter, as it impacts the endpoint required bandwidth.
*/
#define FBACK_SLOW_MAX 250
struct uac_params { struct uac_params {
/* playback */ /* playback */
int p_chmask; /* channel mask */ int p_chmask; /* channel mask */
@@ -23,6 +31,7 @@ struct uac_params {
int c_ssize; /* sample size */ int c_ssize; /* sample size */
int req_number; /* number of preallocated requests */ int req_number; /* number of preallocated requests */
int fb_max; /* upper frequency drift feedback limit per-mil */
}; };
struct g_audio { struct g_audio {
@@ -30,7 +39,10 @@ struct g_audio {
struct usb_gadget *gadget; struct usb_gadget *gadget;
struct usb_ep *in_ep; struct usb_ep *in_ep;
struct usb_ep *out_ep; struct usb_ep *out_ep;
/* feedback IN endpoint corresponding to out_ep */
struct usb_ep *in_ep_fback;
/* Max packet size for all in_ep possible speeds */ /* Max packet size for all in_ep possible speeds */
unsigned int in_ep_maxpsize; unsigned int in_ep_maxpsize;

View File

@@ -21,7 +21,9 @@
#define UAC2_DEF_CCHMASK 0x3 #define UAC2_DEF_CCHMASK 0x3
#define UAC2_DEF_CSRATE 64000 #define UAC2_DEF_CSRATE 64000
#define UAC2_DEF_CSSIZE 2 #define UAC2_DEF_CSSIZE 2
#define UAC2_DEF_CSYNC USB_ENDPOINT_SYNC_ASYNC
#define UAC2_DEF_REQ_NUM 2 #define UAC2_DEF_REQ_NUM 2
#define UAC2_DEF_FB_MAX 5
struct f_uac2_opts { struct f_uac2_opts {
struct usb_function_instance func_inst; struct usb_function_instance func_inst;
@@ -31,7 +33,9 @@ struct f_uac2_opts {
int c_chmask; int c_chmask;
int c_srate; int c_srate;
int c_ssize; int c_ssize;
int c_sync;
int req_number; int req_number;
int fb_max;
bool bound; bool bound;
struct mutex lock; struct mutex lock;

View File

@@ -263,8 +263,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,
}; };
unsigned int seq_id = 0; unsigned int seq_id = 0;
if (unlikely(f2fs_readonly(inode->i_sb) || if (unlikely(f2fs_readonly(inode->i_sb)))
is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
return 0; return 0;
trace_f2fs_sync_file_enter(inode); trace_f2fs_sync_file_enter(inode);
@@ -278,7 +277,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,
ret = file_write_and_wait_range(file, start, end); ret = file_write_and_wait_range(file, start, end);
clear_inode_flag(inode, FI_NEED_IPU); clear_inode_flag(inode, FI_NEED_IPU);
if (ret) { if (ret || is_sbi_flag_set(sbi, SBI_CP_DISABLED)) {
trace_f2fs_sync_file_exit(inode, cp_reason, datasync, ret); trace_f2fs_sync_file_exit(inode, cp_reason, datasync, ret);
return ret; return ret;
} }

View File

@@ -1965,8 +1965,17 @@ restore_flag:
static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi)
{ {
int retry = DEFAULT_RETRY_IO_COUNT;
/* we should flush all the data to keep data consistency */ /* we should flush all the data to keep data consistency */
sync_inodes_sb(sbi->sb); do {
sync_inodes_sb(sbi->sb);
cond_resched();
congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT);
} while (get_pages(sbi, F2FS_DIRTY_DATA) && retry--);
if (unlikely(retry < 0))
f2fs_warn(sbi, "checkpoint=enable has some unwritten data.");
down_write(&sbi->gc_lock); down_write(&sbi->gc_lock);
f2fs_dirty_to_prefree(sbi); f2fs_dirty_to_prefree(sbi);

View File

@@ -460,7 +460,7 @@ static inline void memblock_free_late(phys_addr_t base, phys_addr_t size)
/* /*
* Set the allocation direction to bottom-up or top-down. * Set the allocation direction to bottom-up or top-down.
*/ */
static inline __init void memblock_set_bottom_up(bool enable) static inline __init_memblock void memblock_set_bottom_up(bool enable)
{ {
memblock.bottom_up = enable; memblock.bottom_up = enable;
} }
@@ -470,7 +470,7 @@ static inline __init void memblock_set_bottom_up(bool enable)
* if this is true, that said, memblock will allocate memory * if this is true, that said, memblock will allocate memory
* in bottom-up direction. * in bottom-up direction.
*/ */
static inline __init bool memblock_bottom_up(void) static inline __init_memblock bool memblock_bottom_up(void)
{ {
return memblock.bottom_up; return memblock.bottom_up;
} }

View File

@@ -117,6 +117,15 @@ DECLARE_HOOK(android_vh_mem_cgroup_css_online,
DECLARE_HOOK(android_vh_mem_cgroup_css_offline, DECLARE_HOOK(android_vh_mem_cgroup_css_offline,
TP_PROTO(struct cgroup_subsys_state *css, struct mem_cgroup *memcg), TP_PROTO(struct cgroup_subsys_state *css, struct mem_cgroup *memcg),
TP_ARGS(css, memcg)); TP_ARGS(css, memcg));
DECLARE_HOOK(android_vh_kmalloc_slab,
TP_PROTO(unsigned int index, gfp_t flags, struct kmem_cache **s),
TP_ARGS(index, flags, s));
DECLARE_HOOK(android_vh_mmap_region,
TP_PROTO(struct vm_area_struct *vma, unsigned long addr),
TP_ARGS(vma, addr));
DECLARE_HOOK(android_vh_try_to_unmap_one,
TP_PROTO(struct vm_area_struct *vma, struct page *page, unsigned long addr, bool ret),
TP_ARGS(vma, page, addr, ret));
/* macro versions of hooks are no longer required */ /* macro versions of hooks are no longer required */
#endif /* _TRACE_HOOK_MM_H */ #endif /* _TRACE_HOOK_MM_H */

View File

@@ -33,7 +33,7 @@ int android_rvh_probe_register(struct tracepoint *tp, void *probe, void *data);
.unregfunc = _unreg, \ .unregfunc = _unreg, \
.funcs = NULL }; \ .funcs = NULL }; \
__TRACEPOINT_ENTRY(_name); \ __TRACEPOINT_ENTRY(_name); \
int __traceiter_##_name(void *__data, proto) \ int __nocfi __traceiter_##_name(void *__data, proto) \
{ \ { \
struct tracepoint_func *it_func_ptr; \ struct tracepoint_func *it_func_ptr; \
void *it_func; \ void *it_func; \

View File

@@ -320,6 +320,9 @@ void cfi_slowpath_handler(uint64_t id, void *ptr, void *diag)
{ {
cfi_check_fn fn = find_check_fn((unsigned long)ptr); cfi_check_fn fn = find_check_fn((unsigned long)ptr);
if (!IS_ENABLED(CONFIG_CFI_PERMISSIVE))
diag = NULL;
if (likely(fn)) if (likely(fn))
fn(id, ptr, diag); fn(id, ptr, diag);
else /* Don't allow unchecked modules */ else /* Don't allow unchecked modules */

View File

@@ -1964,6 +1964,8 @@ out:
vma_set_page_prot(vma); vma_set_page_prot(vma);
vm_write_end(vma); vm_write_end(vma);
trace_android_vh_mmap_region(vma, addr);
return addr; return addr;
unmap_and_free_vma: unmap_and_free_vma:

View File

@@ -77,6 +77,8 @@
#include <trace/events/tlb.h> #include <trace/events/tlb.h>
#include <trace/hooks/mm.h>
#include "internal.h" #include "internal.h"
static struct kmem_cache *anon_vma_cachep; static struct kmem_cache *anon_vma_cachep;
@@ -1713,6 +1715,7 @@ discard:
} }
mmu_notifier_invalidate_range_end(&range); mmu_notifier_invalidate_range_end(&range);
trace_android_vh_try_to_unmap_one(vma, page, address, ret);
return ret; return ret;
} }

View File

@@ -640,6 +640,7 @@ static inline unsigned int size_index_elem(unsigned int bytes)
struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags) struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags)
{ {
unsigned int index; unsigned int index;
struct kmem_cache *s = NULL;
if (size <= 192) { if (size <= 192) {
if (!size) if (!size)
@@ -652,6 +653,10 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags)
index = fls(size - 1); index = fls(size - 1);
} }
trace_android_vh_kmalloc_slab(index, flags, &s);
if (s)
return s;
return kmalloc_caches[kmalloc_type(flags)][index]; return kmalloc_caches[kmalloc_type(flags)][index];
} }