# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_JUMP_LABEL=y
-CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
{ do_bad, SIGBUS, 0, "unknown 63" },
};
+#ifdef CONFIG_AMLOGIC_VMAP
+asmlinkage static void die_wrap(const struct fault_info *inf,
+ struct pt_regs *regs, unsigned int esr,
+ unsigned long addr)
+{
+ struct siginfo info;
+
+ info.si_signo = inf->sig;
+ info.si_errno = 0;
+ info.si_code = inf->code;
+ info.si_addr = (void __user *)addr;
+ arm64_notify_die("", regs, &info, esr);
+}
+#endif
/*
* Dispatch a data abort to the relevant handler.
*/
struct pt_regs *regs)
{
const struct fault_info *inf = esr_to_fault_info(esr);
+#ifndef CONFIG_AMLOGIC_VMAP
struct siginfo info;
+#endif
if (!inf->fn(addr, esr, regs))
return;
pr_alert("Unhandled fault: %s (0x%08x) at 0x%016lx\n",
inf->name, esr, addr);
+#ifndef CONFIG_AMLOGIC_VMAP
info.si_signo = inf->sig;
info.si_errno = 0;
info.si_code = inf->code;
info.si_addr = (void __user *)addr;
arm64_notify_die("", regs, &info, esr);
+#else
+ die_wrap(inf, regs, esr, addr);
+#endif
}
asmlinkage void __exception do_el0_irq_bp_hardening(void)
memcg_kmem_update_page_stat(first_page, MEMCG_KERNEL_STACK_KB,
account * (THREAD_SIZE / 1024));
if (time_after(jiffies, vmap_debug_jiff + HZ * 5)) {
+ int ratio, rem;
+
vmap_debug_jiff = jiffies;
- D("KERNEL_STACK:%ld KB, vmap stack:%d KB, cached:%d KB\n",
+ ratio = ((get_vmap_stack_size() << (PAGE_SHIFT - 10)) * 10000) /
+ global_page_state(NR_KERNEL_STACK_KB);
+ rem = ratio % 100;
+ D("STACK:%ld KB, vmap:%d KB, cached:%d KB, rate:%2d.%02d%%\n",
global_page_state(NR_KERNEL_STACK_KB),
get_vmap_stack_size() << (PAGE_SHIFT - 10),
- avmap->cached_pages << (PAGE_SHIFT - 10));
+ avmap->cached_pages << (PAGE_SHIFT - 10),
+ ratio / 100, rem);
}
}
}
#endif
+#ifdef CONFIG_AMLOGIC_VMAP
+noinline void trace_android_fs_datawrite_wrap(struct inode *inode,
+ loff_t pos, unsigned int len)
+{
+ if (trace_android_fs_datawrite_start_enabled()) {
+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+ path = android_fstrace_get_pathname(pathbuf,
+ MAX_TRACE_PATHBUF_LEN,
+ inode);
+ trace_android_fs_datawrite_start(inode, pos, len,
+ current->pid, path,
+ current->comm);
+ }
+}
+
+noinline void trace_android_fs_dataread_wrap(struct inode *inode,
+ loff_t pos, unsigned int len)
+{
+ if (trace_android_fs_dataread_start_enabled()) {
+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+ path = android_fstrace_get_pathname(pathbuf,
+ MAX_TRACE_PATHBUF_LEN,
+ inode);
+ trace_android_fs_dataread_start(inode, pos, len,
+ current->pid, path,
+ current->comm);
+ }
+}
+#endif
+
static int ext4_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
pgoff_t index;
unsigned from, to;
+#ifdef CONFIG_AMLOGIC_VMAP
+ trace_android_fs_datawrite_wrap(inode, pos, len);
+#else
if (trace_android_fs_datawrite_start_enabled()) {
char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
current->pid, path,
current->comm);
}
+#endif
trace_ext4_write_begin(inode, pos, len, flags);
/*
* Reserve one block more for addition to orphan list in case
len, flags, pagep, fsdata);
}
*fsdata = (void *)0;
+#ifdef CONFIG_AMLOGIC_VMAP
+ trace_android_fs_datawrite_wrap(inode, pos, len);
+#else
if (trace_android_fs_datawrite_start_enabled()) {
char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
current->pid,
path, current->comm);
}
+#endif
trace_ext4_da_write_begin(inode, pos, len, flags);
if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
if (ext4_has_inline_data(inode))
return 0;
+#ifdef CONFIG_AMLOGIC_VMAP
+ if (rw == READ)
+ trace_android_fs_dataread_wrap(inode, offset, count);
+ if (rw == WRITE)
+ trace_android_fs_datawrite_wrap(inode, offset, count);
+#else
if (trace_android_fs_dataread_start_enabled() &&
(rw == READ)) {
char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
current->pid, path,
current->comm);
}
+#endif
trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter));
if (iov_iter_rw(iter) == READ)
ret = ext4_direct_IO_read(iocb, iter);
struct page *first_page = bio->bi_io_vec[0].bv_page;
if (first_page != NULL) {
+ #ifdef CONFIG_AMLOGIC_VMAP
+ trace_android_fs_dataread_wrap(
+ first_page->mapping->host,
+ page_offset(first_page),
+ bio->bi_iter.bi_size);
+ #else
char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
path = android_fstrace_get_pathname(pathbuf,
current->pid,
path,
current->comm);
+ #endif
}
}
submit_bio(bio);
block_t blkaddr = NULL_ADDR;
int err = 0;
+#ifdef CONFIG_AMLOGIC_VMAP
+ trace_android_fs_datawrite_wrap(inode, pos, len);
+#else
if (trace_android_fs_datawrite_start_enabled()) {
char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
current->pid, path,
current->comm);
}
+#endif
trace_f2fs_write_begin(inode, pos, len, flags);
if (f2fs_is_atomic_file(inode) &&
trace_f2fs_direct_IO_enter(inode, offset, count, rw);
+#ifdef CONFIG_AMLOGIC_VMAP
+ if (rw == READ)
+ trace_android_fs_dataread_wrap(inode, offset, count);
+ if (rw == WRITE)
+ trace_android_fs_datawrite_wrap(inode, offset, count);
+#else
if (trace_android_fs_dataread_start_enabled() &&
(rw == READ)) {
char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
current->pid, path,
current->comm);
}
+#endif
if (rw == WRITE && whint_mode == WHINT_MODE_OFF)
iocb->ki_hint = WRITE_LIFE_NOT_SET;
{
struct page *ipage;
+#ifdef CONFIG_AMLOGIC_VMAP
+ trace_android_fs_dataread_wrap(inode, page_offset(page), PAGE_SIZE);
+#else
if (trace_android_fs_dataread_start_enabled()) {
char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
PAGE_SIZE, current->pid,
path, current->comm);
}
+#endif
ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
if (IS_ERR(ipage)) {
struct page *first_page = bio->bi_io_vec[0].bv_page;
if (first_page != NULL) {
+ #ifdef CONFIG_AMLOGIC_VMAP
+ trace_android_fs_dataread_wrap(
+ first_page->mapping->host,
+ page_offset(first_page),
+ bio->bi_iter.bi_size);
+ #else
char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
path = android_fstrace_get_pathname(pathbuf,
current->pid,
path,
current->comm);
+ #endif
}
}
bio->bi_end_io = mpage_end_io;
return -EINVAL;
}
+#ifdef CONFIG_AMLOGIC_VMAP
+/* a save stack version */
+static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct iattr *ia)
+{
+ int err;
+ struct dentry *lower_dentry;
+ struct vfsmount *lower_mnt;
+ struct inode *inode;
+ struct inode *lower_inode;
+ struct path lower_path;
+ struct iattr lower_ia;
+ struct dentry *parent;
+ struct inode *tmp;
+ struct dentry *tmp_d;
+ struct sdcardfs_inode_data *top;
+
+ const struct cred *saved_cred = NULL;
+
+ inode = d_inode(dentry);
+ top = top_data_get(SDCARDFS_I(inode));
+
+ if (!top)
+ return -EINVAL;
+
+ tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
+ if (!tmp)
+ return -ENOMEM;
+
+ tmp_d = kzalloc(sizeof(*tmp_d), GFP_KERNEL);
+ if (!tmp_d) {
+ kfree(tmp);
+ return -ENOMEM;
+ }
+ /*
+ * Permission check on sdcardfs inode.
+ * Calling process should have AID_SDCARD_RW permission
+ * Since generic_permission only needs i_mode, i_uid,
+ * i_gid, and i_sb, we can create a fake inode to pass
+ * this information down in.
+ *
+ * The underlying code may attempt to take locks in some
+ * cases for features we're not using, but if that changes,
+ * locks must be dealt with to avoid undefined behavior.
+ *
+ */
+ copy_attrs(tmp, inode);
+ tmp->i_uid = make_kuid(&init_user_ns, top->d_uid);
+ tmp->i_gid = make_kgid(&init_user_ns, get_gid(mnt, dentry->d_sb, top));
+ tmp->i_mode = (inode->i_mode & S_IFMT)
+ | get_mode(mnt, SDCARDFS_I(inode), top);
+ tmp->i_size = i_size_read(inode);
+ data_put(top);
+ tmp->i_sb = inode->i_sb;
+ tmp_d->d_inode = tmp;
+
+ /*
+ * Check if user has permission to change dentry. We don't check if
+ * this user can change the lower inode: that should happen when
+ * calling notify_change on the lower inode.
+ */
+ /* prepare our own lower struct iattr (with the lower file) */
+ memcpy(&lower_ia, ia, sizeof(lower_ia));
+ /* Allow touch updating timestamps. A previous permission check ensures
+ * we have write access. Changes to mode, owner, and group are ignored
+ */
+ ia->ia_valid |= ATTR_FORCE;
+ err = setattr_prepare(tmp_d, ia);
+
+ if (!err) {
+ /* check the Android group ID */
+ parent = dget_parent(dentry);
+ if (!check_caller_access_to_name(d_inode(parent),
+ &dentry->d_name))
+ err = -EACCES;
+ dput(parent);
+ }
+
+ if (err)
+ goto out_err;
+
+ /* save current_cred and override it */
+ OVERRIDE_CRED(SDCARDFS_SB(dentry->d_sb), saved_cred, SDCARDFS_I(inode));
+
+ sdcardfs_get_lower_path(dentry, &lower_path);
+ lower_dentry = lower_path.dentry;
+ lower_mnt = lower_path.mnt;
+ lower_inode = sdcardfs_lower_inode(inode);
+
+ if (ia->ia_valid & ATTR_FILE)
+ lower_ia.ia_file = sdcardfs_lower_file(ia->ia_file);
+
+ lower_ia.ia_valid &= ~(ATTR_UID | ATTR_GID | ATTR_MODE);
+
+ /*
+ * If shrinking, first truncate upper level to cancel writing dirty
+ * pages beyond the new eof; and also if its' maxbytes is more
+ * limiting (fail with -EFBIG before making any change to the lower
+ * level). There is no need to vmtruncate the upper level
+ * afterwards in the other cases: we fsstack_copy_inode_size from
+ * the lower level.
+ */
+ if (ia->ia_valid & ATTR_SIZE) {
+ err = inode_newsize_ok(tmp, ia->ia_size);
+ if (err)
+ goto out;
+ truncate_setsize(inode, ia->ia_size);
+ }
+
+ /*
+ * mode change is for clearing setuid/setgid bits. Allow lower fs
+ * to interpret this in its own way.
+ */
+ if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+ lower_ia.ia_valid &= ~ATTR_MODE;
+
+ /* notify the (possibly copied-up) lower inode */
+ /*
+ * Note: we use d_inode(lower_dentry), because lower_inode may be
+ * unlinked (no inode->i_sb and i_ino==0. This happens if someone
+ * tries to open(), unlink(), then ftruncate() a file.
+ */
+ inode_lock(d_inode(lower_dentry));
+ err = notify_change2(lower_mnt, lower_dentry, &lower_ia,
+ NULL);
+ inode_unlock(d_inode(lower_dentry));
+ if (err)
+ goto out;
+
+ /* get attributes from the lower inode and update derived permissions */
+ sdcardfs_copy_and_fix_attrs(inode, lower_inode);
+
+ /*
+ * Not running fsstack_copy_inode_size(inode, lower_inode), because
+ * VFS should update our inode size, and notify_change on
+ * lower_inode should update its size.
+ */
+
+out:
+ sdcardfs_put_lower_path(dentry, &lower_path);
+ REVERT_CRED(saved_cred);
+out_err:
+ kfree(tmp);
+ kfree(tmp_d);
+ return err;
+}
+#else
static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, struct iattr *ia)
{
int err;
out_err:
return err;
}
+#endif
static int sdcardfs_fillattr(struct vfsmount *mnt, struct inode *inode,
struct kstat *lower_stat, struct kstat *stat)
#define VMAP_PAGE_FLAG (__GFP_ZERO | __GFP_HIGH |\
__GFP_ATOMIC | __GFP_REPEAT)
-#define VMAP_CACHE_PAGE_ORDER 6
+#define VMAP_CACHE_PAGE_ORDER 5
#define VMAP_CACHE_PAGE (1 << VMAP_CACHE_PAGE_ORDER)
#define CACHE_MAINTAIN_DELAY (HZ)
return path;
}
#endif
+#ifdef CONFIG_AMLOGIC_VMAP
+extern void trace_android_fs_datawrite_wrap(struct inode *inode,
+ loff_t pos, unsigned int len);
+extern void trace_android_fs_dataread_wrap(struct inode *inode,
+ loff_t pos, unsigned int len);
+#endif