Merge tag 'v5.1-rc1' into regulator-5.2
Linux 5.1-rc1
This commit is contained in:
@@ -400,12 +400,17 @@ extern bool acpi_osi_is_win8(void);
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
int acpi_map_pxm_to_online_node(int pxm);
|
||||
int acpi_map_pxm_to_node(int pxm);
|
||||
int acpi_get_node(acpi_handle handle);
|
||||
#else
|
||||
static inline int acpi_map_pxm_to_online_node(int pxm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int acpi_map_pxm_to_node(int pxm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int acpi_get_node(acpi_handle handle)
|
||||
{
|
||||
return 0;
|
||||
@@ -953,9 +958,6 @@ acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
|
||||
#if defined(CONFIG_ACPI) && defined(CONFIG_DYNAMIC_DEBUG)
|
||||
__printf(3, 4)
|
||||
void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const char *fmt, ...);
|
||||
#else
|
||||
#define __acpi_handle_debug(descriptor, handle, fmt, ...) \
|
||||
acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -985,12 +987,8 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
|
||||
#else
|
||||
#if defined(CONFIG_DYNAMIC_DEBUG)
|
||||
#define acpi_handle_debug(handle, fmt, ...) \
|
||||
do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \
|
||||
__acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
_dynamic_func_call(fmt, __acpi_handle_debug, \
|
||||
handle, pr_fmt(fmt), ##__VA_ARGS__)
|
||||
#else
|
||||
#define acpi_handle_debug(handle, fmt, ...) \
|
||||
({ \
|
||||
@@ -1014,6 +1012,13 @@ struct acpi_gpio_mapping {
|
||||
|
||||
/* Ignore IoRestriction field */
|
||||
#define ACPI_GPIO_QUIRK_NO_IO_RESTRICTION BIT(0)
|
||||
/*
|
||||
* When ACPI GPIO mapping table is in use the index parameter inside it
|
||||
* refers to the GPIO resource in _CRS method. That index has no
|
||||
* distinction of actual type of the resource. When consumer wants to
|
||||
* get GpioIo type explicitly, this quirk may be used.
|
||||
*/
|
||||
#define ACPI_GPIO_QUIRK_ONLY_GPIOIO BIT(1)
|
||||
|
||||
unsigned int quirks;
|
||||
};
|
||||
@@ -1061,17 +1066,6 @@ static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ACPI) && IS_ENABLED(CONFIG_I2C)
|
||||
bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
|
||||
struct acpi_resource_i2c_serialbus **i2c);
|
||||
#else
|
||||
static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
|
||||
struct acpi_resource_i2c_serialbus **i2c)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Device properties */
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
@@ -25,6 +25,43 @@
|
||||
#define AMBA_CID 0xb105f00d
|
||||
#define CORESIGHT_CID 0xb105900d
|
||||
|
||||
/*
|
||||
* CoreSight Architecture specification updates the ID specification
|
||||
* for components on the AMBA bus. (ARM IHI 0029E)
|
||||
*
|
||||
* Bits 15:12 of the CID are the device class.
|
||||
*
|
||||
* Class 0xF remains for PrimeCell and legacy components. (AMBA_CID above)
|
||||
* Class 0x9 defines the component as CoreSight (CORESIGHT_CID above)
|
||||
* Class 0x0, 0x1, 0xB, 0xE define components that do not have driver support
|
||||
* at present.
|
||||
* Class 0x2-0x8,0xA and 0xD-0xD are presently reserved.
|
||||
*
|
||||
* Remaining CID bits stay as 0xb105-00d
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class 0x9 components use additional values to form a Unique Component
|
||||
* Identifier (UCI), where peripheral ID values are identical for different
|
||||
* components. Passed to the amba bus code from the component driver via
|
||||
* the amba_id->data pointer.
|
||||
* @devarch : coresight devarch register value
|
||||
* @devarch_mask: mask bits used for matching. 0 indicates UCI not used.
|
||||
* @devtype : coresight device type value
|
||||
* @data : additional driver data. As we have usurped the original
|
||||
* pointer some devices may still need additional data
|
||||
*/
|
||||
struct amba_cs_uci_id {
|
||||
unsigned int devarch;
|
||||
unsigned int devarch_mask;
|
||||
unsigned int devtype;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* define offsets for registers used by UCI */
|
||||
#define UCI_REG_DEVTYPE_OFFSET 0xFCC
|
||||
#define UCI_REG_DEVARCH_OFFSET 0xFBC
|
||||
|
||||
struct clk;
|
||||
|
||||
struct amba_device {
|
||||
@@ -32,6 +69,8 @@ struct amba_device {
|
||||
struct resource res;
|
||||
struct clk *pclk;
|
||||
unsigned int periphid;
|
||||
unsigned int cid;
|
||||
struct amba_cs_uci_id uci;
|
||||
unsigned int irq[AMBA_NR_IRQS];
|
||||
char *driver_override;
|
||||
};
|
||||
|
@@ -11,7 +11,11 @@ enum sdei_conduit_types {
|
||||
CONDUIT_HVC,
|
||||
};
|
||||
|
||||
#include <acpi/ghes.h>
|
||||
|
||||
#ifdef CONFIG_ARM_SDE_INTERFACE
|
||||
#include <asm/sdei.h>
|
||||
#endif
|
||||
|
||||
/* Arch code should override this to set the entry point from firmware... */
|
||||
#ifndef sdei_arch_get_entry_point
|
||||
@@ -39,6 +43,11 @@ int sdei_event_unregister(u32 event_num);
|
||||
int sdei_event_enable(u32 event_num);
|
||||
int sdei_event_disable(u32 event_num);
|
||||
|
||||
/* GHES register/unregister helpers */
|
||||
int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb,
|
||||
sdei_event_callback *critical_cb);
|
||||
int sdei_unregister_ghes(struct ghes *ghes);
|
||||
|
||||
#ifdef CONFIG_ARM_SDE_INTERFACE
|
||||
/* For use by arch code when CPU hotplug notifiers are not appropriate. */
|
||||
int sdei_mask_local_cpu(void);
|
||||
|
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/numa.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
typedef u64 async_cookie_t;
|
||||
typedef void (*async_func_t) (void *data, async_cookie_t cookie);
|
||||
@@ -37,9 +39,83 @@ struct async_domain {
|
||||
struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \
|
||||
.registered = 0 }
|
||||
|
||||
extern async_cookie_t async_schedule(async_func_t func, void *data);
|
||||
extern async_cookie_t async_schedule_domain(async_func_t func, void *data,
|
||||
struct async_domain *domain);
|
||||
async_cookie_t async_schedule_node(async_func_t func, void *data,
|
||||
int node);
|
||||
async_cookie_t async_schedule_node_domain(async_func_t func, void *data,
|
||||
int node,
|
||||
struct async_domain *domain);
|
||||
|
||||
/**
|
||||
* async_schedule - schedule a function for asynchronous execution
|
||||
* @func: function to execute asynchronously
|
||||
* @data: data pointer to pass to the function
|
||||
*
|
||||
* Returns an async_cookie_t that may be used for checkpointing later.
|
||||
* Note: This function may be called from atomic or non-atomic contexts.
|
||||
*/
|
||||
static inline async_cookie_t async_schedule(async_func_t func, void *data)
|
||||
{
|
||||
return async_schedule_node(func, data, NUMA_NO_NODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* async_schedule_domain - schedule a function for asynchronous execution within a certain domain
|
||||
* @func: function to execute asynchronously
|
||||
* @data: data pointer to pass to the function
|
||||
* @domain: the domain
|
||||
*
|
||||
* Returns an async_cookie_t that may be used for checkpointing later.
|
||||
* @domain may be used in the async_synchronize_*_domain() functions to
|
||||
* wait within a certain synchronization domain rather than globally.
|
||||
* Note: This function may be called from atomic or non-atomic contexts.
|
||||
*/
|
||||
static inline async_cookie_t
|
||||
async_schedule_domain(async_func_t func, void *data,
|
||||
struct async_domain *domain)
|
||||
{
|
||||
return async_schedule_node_domain(func, data, NUMA_NO_NODE, domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* async_schedule_dev - A device specific version of async_schedule
|
||||
* @func: function to execute asynchronously
|
||||
* @dev: device argument to be passed to function
|
||||
*
|
||||
* Returns an async_cookie_t that may be used for checkpointing later.
|
||||
* @dev is used as both the argument for the function and to provide NUMA
|
||||
* context for where to run the function. By doing this we can try to
|
||||
* provide for the best possible outcome by operating on the device on the
|
||||
* CPUs closest to the device.
|
||||
* Note: This function may be called from atomic or non-atomic contexts.
|
||||
*/
|
||||
static inline async_cookie_t
|
||||
async_schedule_dev(async_func_t func, struct device *dev)
|
||||
{
|
||||
return async_schedule_node(func, dev, dev_to_node(dev));
|
||||
}
|
||||
|
||||
/**
|
||||
* async_schedule_dev_domain - A device specific version of async_schedule_domain
|
||||
* @func: function to execute asynchronously
|
||||
* @dev: device argument to be passed to function
|
||||
* @domain: the domain
|
||||
*
|
||||
* Returns an async_cookie_t that may be used for checkpointing later.
|
||||
* @dev is used as both the argument for the function and to provide NUMA
|
||||
* context for where to run the function. By doing this we can try to
|
||||
* provide for the best possible outcome by operating on the device on the
|
||||
* CPUs closest to the device.
|
||||
* @domain may be used in the async_synchronize_*_domain() functions to
|
||||
* wait within a certain synchronization domain rather than globally.
|
||||
* Note: This function may be called from atomic or non-atomic contexts.
|
||||
*/
|
||||
static inline async_cookie_t
|
||||
async_schedule_dev_domain(async_func_t func, struct device *dev,
|
||||
struct async_domain *domain)
|
||||
{
|
||||
return async_schedule_node_domain(func, dev, dev_to_node(dev), domain);
|
||||
}
|
||||
|
||||
void async_unregister_domain(struct async_domain *domain);
|
||||
extern void async_synchronize_full(void);
|
||||
extern void async_synchronize_full_domain(struct async_domain *domain);
|
||||
|
@@ -19,7 +19,8 @@ extern int __pata_platform_probe(struct device *dev,
|
||||
struct resource *irq_res,
|
||||
unsigned int ioport_shift,
|
||||
int __pio_mask,
|
||||
struct scsi_host_template *sht);
|
||||
struct scsi_host_template *sht,
|
||||
bool use16bit);
|
||||
|
||||
/*
|
||||
* Marvell SATA private data
|
||||
|
@@ -158,19 +158,29 @@ extern int sysctl_aarp_retransmit_limit;
|
||||
extern int sysctl_aarp_resolve_time;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
extern void atalk_register_sysctl(void);
|
||||
extern int atalk_register_sysctl(void);
|
||||
extern void atalk_unregister_sysctl(void);
|
||||
#else
|
||||
#define atalk_register_sysctl() do { } while(0)
|
||||
#define atalk_unregister_sysctl() do { } while(0)
|
||||
static inline int atalk_register_sysctl(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void atalk_unregister_sysctl(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
extern int atalk_proc_init(void);
|
||||
extern void atalk_proc_exit(void);
|
||||
#else
|
||||
#define atalk_proc_init() ({ 0; })
|
||||
#define atalk_proc_exit() do { } while(0)
|
||||
static inline int atalk_proc_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void atalk_proc_exit(void)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
#endif /* __LINUX_ATALK_H__ */
|
||||
|
2295
include/linux/atomic-fallback.h
Normal file
2295
include/linux/atomic-fallback.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/namei.h> /* LOOKUP_* */
|
||||
#include <uapi/linux/audit.h>
|
||||
|
||||
#define AUDIT_INO_UNSET ((unsigned long)-1)
|
||||
@@ -159,6 +160,18 @@ extern int audit_update_lsm_rules(void);
|
||||
extern int audit_rule_change(int type, int seq, void *data, size_t datasz);
|
||||
extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
|
||||
|
||||
extern int audit_set_loginuid(kuid_t loginuid);
|
||||
|
||||
static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
|
||||
{
|
||||
return tsk->loginuid;
|
||||
}
|
||||
|
||||
static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
|
||||
{
|
||||
return tsk->sessionid;
|
||||
}
|
||||
|
||||
extern u32 audit_enabled;
|
||||
#else /* CONFIG_AUDIT */
|
||||
static inline __printf(4, 5)
|
||||
@@ -201,6 +214,17 @@ static inline int audit_log_task_context(struct audit_buffer *ab)
|
||||
}
|
||||
static inline void audit_log_task_info(struct audit_buffer *ab)
|
||||
{ }
|
||||
|
||||
static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
|
||||
{
|
||||
return INVALID_UID;
|
||||
}
|
||||
|
||||
static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
|
||||
{
|
||||
return AUDIT_SID_UNSET;
|
||||
}
|
||||
|
||||
#define audit_enabled AUDIT_OFF
|
||||
#endif /* CONFIG_AUDIT */
|
||||
|
||||
@@ -225,6 +249,7 @@ extern void __audit_getname(struct filename *name);
|
||||
|
||||
#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */
|
||||
#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */
|
||||
#define AUDIT_INODE_NOEVAL 4 /* audit record incomplete */
|
||||
extern void __audit_inode(struct filename *name, const struct dentry *dentry,
|
||||
unsigned int flags);
|
||||
extern void __audit_file(const struct file *);
|
||||
@@ -285,12 +310,15 @@ static inline void audit_getname(struct filename *name)
|
||||
}
|
||||
static inline void audit_inode(struct filename *name,
|
||||
const struct dentry *dentry,
|
||||
unsigned int parent) {
|
||||
unsigned int flags) {
|
||||
if (unlikely(!audit_dummy_context())) {
|
||||
unsigned int flags = 0;
|
||||
if (parent)
|
||||
flags |= AUDIT_INODE_PARENT;
|
||||
__audit_inode(name, dentry, flags);
|
||||
unsigned int aflags = 0;
|
||||
|
||||
if (flags & LOOKUP_PARENT)
|
||||
aflags |= AUDIT_INODE_PARENT;
|
||||
if (flags & LOOKUP_NO_EVAL)
|
||||
aflags |= AUDIT_INODE_NOEVAL;
|
||||
__audit_inode(name, dentry, aflags);
|
||||
}
|
||||
}
|
||||
static inline void audit_file(struct file *file)
|
||||
@@ -320,21 +348,6 @@ static inline void audit_ptrace(struct task_struct *t)
|
||||
}
|
||||
|
||||
/* Private API (for audit.c only) */
|
||||
extern unsigned int audit_serial(void);
|
||||
extern int auditsc_get_stamp(struct audit_context *ctx,
|
||||
struct timespec64 *t, unsigned int *serial);
|
||||
extern int audit_set_loginuid(kuid_t loginuid);
|
||||
|
||||
static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
|
||||
{
|
||||
return tsk->loginuid;
|
||||
}
|
||||
|
||||
static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
|
||||
{
|
||||
return tsk->sessionid;
|
||||
}
|
||||
|
||||
extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
|
||||
extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode);
|
||||
extern void __audit_bprm(struct linux_binprm *bprm);
|
||||
@@ -514,19 +527,6 @@ static inline void audit_seccomp(unsigned long syscall, long signr, int code)
|
||||
static inline void audit_seccomp_actions_logged(const char *names,
|
||||
const char *old_names, int res)
|
||||
{ }
|
||||
static inline int auditsc_get_stamp(struct audit_context *ctx,
|
||||
struct timespec64 *t, unsigned int *serial)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
|
||||
{
|
||||
return INVALID_UID;
|
||||
}
|
||||
static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
|
||||
{
|
||||
return AUDIT_SID_UNSET;
|
||||
}
|
||||
static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
|
||||
{ }
|
||||
static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid,
|
||||
|
@@ -365,7 +365,7 @@ unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie)
|
||||
rcu_read_lock();
|
||||
|
||||
/*
|
||||
* Paired with store_release in inode_switch_wb_work_fn() and
|
||||
* Paired with store_release in inode_switch_wbs_work_fn() and
|
||||
* ensures that we see the new wb if we see cleared I_WB_SWITCH.
|
||||
*/
|
||||
cookie->locked = smp_load_acquire(&inode->i_state) & I_WB_SWITCH;
|
||||
|
@@ -4,15 +4,18 @@
|
||||
*
|
||||
* Common interface definitions for making balloon pages movable by compaction.
|
||||
*
|
||||
* Despite being perfectly possible to perform ballooned pages migration, they
|
||||
* make a special corner case to compaction scans because balloon pages are not
|
||||
* enlisted at any LRU list like the other pages we do compact / migrate.
|
||||
* Balloon page migration makes use of the general non-lru movable page
|
||||
* feature.
|
||||
*
|
||||
* page->private is used to reference the responsible balloon device.
|
||||
* page->mapping is used in context of non-lru page migration to reference
|
||||
* the address space operations for page isolation/migration/compaction.
|
||||
*
|
||||
* As the page isolation scanning step a compaction thread does is a lockless
|
||||
* procedure (from a page standpoint), it might bring some racy situations while
|
||||
* performing balloon page compaction. In order to sort out these racy scenarios
|
||||
* and safely perform balloon's page compaction and migration we must, always,
|
||||
* ensure following these three simple rules:
|
||||
* ensure following these simple rules:
|
||||
*
|
||||
* i. when updating a balloon's page ->mapping element, strictly do it under
|
||||
* the following lock order, independently of the far superior
|
||||
@@ -21,19 +24,8 @@
|
||||
* +--spin_lock_irq(&b_dev_info->pages_lock);
|
||||
* ... page->mapping updates here ...
|
||||
*
|
||||
* ii. before isolating or dequeueing a balloon page from the balloon device
|
||||
* pages list, the page reference counter must be raised by one and the
|
||||
* extra refcount must be dropped when the page is enqueued back into
|
||||
* the balloon device page list, thus a balloon page keeps its reference
|
||||
* counter raised only while it is under our special handling;
|
||||
*
|
||||
* iii. after the lockless scan step have selected a potential balloon page for
|
||||
* isolation, re-test the PageBalloon mark and the PagePrivate flag
|
||||
* under the proper page lock, to ensure isolating a valid balloon page
|
||||
* (not yet isolated, nor under release procedure)
|
||||
*
|
||||
* iv. isolation or dequeueing procedure must clear PagePrivate flag under
|
||||
* page lock together with removing page from balloon device page list.
|
||||
* ii. isolation or dequeueing procedure must remove the page from balloon
|
||||
* device page list under b_dev_info->pages_lock.
|
||||
*
|
||||
* The functions provided by this interface are placed to help on coping with
|
||||
* the aforementioned balloon page corner case, as well as to ensure the simple
|
||||
@@ -103,7 +95,7 @@ extern int balloon_page_migrate(struct address_space *mapping,
|
||||
static inline void balloon_page_insert(struct balloon_dev_info *balloon,
|
||||
struct page *page)
|
||||
{
|
||||
__SetPageBalloon(page);
|
||||
__SetPageOffline(page);
|
||||
__SetPageMovable(page, balloon->inode->i_mapping);
|
||||
set_page_private(page, (unsigned long)balloon);
|
||||
list_add(&page->lru, &balloon->pages);
|
||||
@@ -119,7 +111,7 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon,
|
||||
*/
|
||||
static inline void balloon_page_delete(struct page *page)
|
||||
{
|
||||
__ClearPageBalloon(page);
|
||||
__ClearPageOffline(page);
|
||||
__ClearPageMovable(page);
|
||||
set_page_private(page, 0);
|
||||
/*
|
||||
@@ -149,13 +141,13 @@ static inline gfp_t balloon_mapping_gfp_mask(void)
|
||||
static inline void balloon_page_insert(struct balloon_dev_info *balloon,
|
||||
struct page *page)
|
||||
{
|
||||
__SetPageBalloon(page);
|
||||
__SetPageOffline(page);
|
||||
list_add(&page->lru, &balloon->pages);
|
||||
}
|
||||
|
||||
static inline void balloon_page_delete(struct page *page)
|
||||
{
|
||||
__ClearPageBalloon(page);
|
||||
__ClearPageOffline(page);
|
||||
list_del(&page->lru);
|
||||
}
|
||||
|
||||
|
@@ -332,6 +332,8 @@ extern int bcma_arch_register_fallback_sprom(
|
||||
struct ssb_sprom *out));
|
||||
|
||||
struct bcma_bus {
|
||||
struct device *dev;
|
||||
|
||||
/* The MMIO area. */
|
||||
void __iomem *mmio;
|
||||
|
||||
@@ -339,14 +341,7 @@ struct bcma_bus {
|
||||
|
||||
enum bcma_hosttype hosttype;
|
||||
bool host_is_pcie2; /* Used for BCMA_HOSTTYPE_PCI only */
|
||||
union {
|
||||
/* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */
|
||||
struct pci_dev *host_pci;
|
||||
/* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
|
||||
struct sdio_func *host_sdio;
|
||||
/* Pointer to platform device (only for BCMA_HOSTTYPE_SOC) */
|
||||
struct platform_device *host_pdev;
|
||||
};
|
||||
struct pci_dev *host_pci; /* PCI bus pointer (BCMA_HOSTTYPE_PCI only) */
|
||||
|
||||
struct bcma_chipinfo chipinfo;
|
||||
|
||||
|
@@ -34,15 +34,7 @@
|
||||
#define BIO_BUG_ON
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THP_SWAP
|
||||
#if HPAGE_PMD_NR > 256
|
||||
#define BIO_MAX_PAGES HPAGE_PMD_NR
|
||||
#else
|
||||
#define BIO_MAX_PAGES 256
|
||||
#endif
|
||||
#else
|
||||
#define BIO_MAX_PAGES 256
|
||||
#endif
|
||||
|
||||
#define bio_prio(bio) (bio)->bi_ioprio
|
||||
#define bio_set_prio(bio, prio) ((bio)->bi_ioprio = prio)
|
||||
@@ -128,12 +120,19 @@ static inline bool bio_full(struct bio *bio)
|
||||
return bio->bi_vcnt >= bio->bi_max_vecs;
|
||||
}
|
||||
|
||||
#define mp_bvec_for_each_segment(bv, bvl, i, iter_all) \
|
||||
for (bv = bvec_init_iter_all(&iter_all); \
|
||||
(iter_all.done < (bvl)->bv_len) && \
|
||||
(mp_bvec_next_segment((bvl), &iter_all), 1); \
|
||||
iter_all.done += bv->bv_len, i += 1)
|
||||
|
||||
/*
|
||||
* drivers should _never_ use the all version - the bio may have been split
|
||||
* before it got to the driver and the driver won't own all of it
|
||||
*/
|
||||
#define bio_for_each_segment_all(bvl, bio, i) \
|
||||
for (i = 0, bvl = (bio)->bi_io_vec; i < (bio)->bi_vcnt; i++, bvl++)
|
||||
#define bio_for_each_segment_all(bvl, bio, i, iter_all) \
|
||||
for (i = 0, iter_all.idx = 0; iter_all.idx < (bio)->bi_vcnt; iter_all.idx++) \
|
||||
mp_bvec_for_each_segment(bvl, &((bio)->bi_io_vec[iter_all.idx]), i, iter_all)
|
||||
|
||||
static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
|
||||
unsigned bytes)
|
||||
@@ -156,6 +155,16 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
|
||||
#define bio_for_each_segment(bvl, bio, iter) \
|
||||
__bio_for_each_segment(bvl, bio, iter, (bio)->bi_iter)
|
||||
|
||||
#define __bio_for_each_bvec(bvl, bio, iter, start) \
|
||||
for (iter = (start); \
|
||||
(iter).bi_size && \
|
||||
((bvl = mp_bvec_iter_bvec((bio)->bi_io_vec, (iter))), 1); \
|
||||
bio_advance_iter((bio), &(iter), (bvl).bv_len))
|
||||
|
||||
/* iterate over multi-page bvec */
|
||||
#define bio_for_each_bvec(bvl, bio, iter) \
|
||||
__bio_for_each_bvec(bvl, bio, iter, (bio)->bi_iter)
|
||||
|
||||
#define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
|
||||
|
||||
static inline unsigned bio_segments(struct bio *bio)
|
||||
@@ -263,12 +272,6 @@ static inline void bio_get_last_bvec(struct bio *bio, struct bio_vec *bv)
|
||||
bv->bv_len = iter.bi_bvec_done;
|
||||
}
|
||||
|
||||
static inline unsigned bio_pages_all(struct bio *bio)
|
||||
{
|
||||
WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
|
||||
return bio->bi_vcnt;
|
||||
}
|
||||
|
||||
static inline struct bio_vec *bio_first_bvec_all(struct bio *bio)
|
||||
{
|
||||
WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
|
||||
@@ -430,7 +433,7 @@ extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
|
||||
extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
|
||||
unsigned int, unsigned int);
|
||||
bool __bio_try_merge_page(struct bio *bio, struct page *page,
|
||||
unsigned int len, unsigned int off);
|
||||
unsigned int len, unsigned int off, bool same_page);
|
||||
void __bio_add_page(struct bio *bio, struct page *page,
|
||||
unsigned int len, unsigned int off);
|
||||
int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter);
|
||||
@@ -823,5 +826,19 @@ static inline int bio_integrity_add_page(struct bio *bio, struct page *page,
|
||||
|
||||
#endif /* CONFIG_BLK_DEV_INTEGRITY */
|
||||
|
||||
/*
|
||||
* Mark a bio as polled. Note that for async polled IO, the caller must
|
||||
* expect -EWOULDBLOCK if we cannot allocate a request (or other resources).
|
||||
* We cannot block waiting for requests on polled IO, as those completions
|
||||
* must be found by the caller. This is different than IRQ driven IO, where
|
||||
* it's safe to wait for IO to complete.
|
||||
*/
|
||||
static inline void bio_set_polled(struct bio *bio, struct kiocb *kiocb)
|
||||
{
|
||||
bio->bi_opf |= REQ_HIPRI;
|
||||
if (!is_sync_kiocb(kiocb))
|
||||
bio->bi_opf |= REQ_NOWAIT;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BLOCK */
|
||||
#endif /* __LINUX_BIO_H */
|
||||
|
@@ -246,7 +246,7 @@ static __always_inline void __assign_bit(long nr, volatile unsigned long *addr,
|
||||
new__ = (old__ & ~mask__) | bits__; \
|
||||
} while (cmpxchg(ptr, old__, new__) != old__); \
|
||||
\
|
||||
new__; \
|
||||
old__; \
|
||||
})
|
||||
#endif
|
||||
|
||||
|
@@ -218,7 +218,6 @@ struct blk_mq_ops {
|
||||
enum {
|
||||
BLK_MQ_F_SHOULD_MERGE = 1 << 0,
|
||||
BLK_MQ_F_TAG_SHARED = 1 << 1,
|
||||
BLK_MQ_F_SG_MERGE = 1 << 2,
|
||||
BLK_MQ_F_BLOCKING = 1 << 5,
|
||||
BLK_MQ_F_NO_SCHED = 1 << 6,
|
||||
BLK_MQ_F_ALLOC_POLICY_START_BIT = 8,
|
||||
|
@@ -216,8 +216,6 @@ struct request {
|
||||
unsigned short write_hint;
|
||||
unsigned short ioprio;
|
||||
|
||||
void *special; /* opaque pointer available for LLD use */
|
||||
|
||||
unsigned int extra_len; /* length of alignment and padding */
|
||||
|
||||
enum mq_rq_state state;
|
||||
@@ -236,9 +234,6 @@ struct request {
|
||||
*/
|
||||
rq_end_io_fn *end_io;
|
||||
void *end_io_data;
|
||||
|
||||
/* for bidi */
|
||||
struct request *next_rq;
|
||||
};
|
||||
|
||||
static inline bool blk_op_is_scsi(unsigned int op)
|
||||
@@ -572,38 +567,31 @@ struct request_queue {
|
||||
u64 write_hints[BLK_MAX_WRITE_HINTS];
|
||||
};
|
||||
|
||||
#define QUEUE_FLAG_STOPPED 1 /* queue is stopped */
|
||||
#define QUEUE_FLAG_DYING 2 /* queue being torn down */
|
||||
#define QUEUE_FLAG_BIDI 4 /* queue supports bidi requests */
|
||||
#define QUEUE_FLAG_NOMERGES 5 /* disable merge attempts */
|
||||
#define QUEUE_FLAG_SAME_COMP 6 /* complete on same CPU-group */
|
||||
#define QUEUE_FLAG_FAIL_IO 7 /* fake timeout */
|
||||
#define QUEUE_FLAG_NONROT 9 /* non-rotational device (SSD) */
|
||||
#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */
|
||||
#define QUEUE_FLAG_IO_STAT 10 /* do disk/partitions IO accounting */
|
||||
#define QUEUE_FLAG_DISCARD 11 /* supports DISCARD */
|
||||
#define QUEUE_FLAG_NOXMERGES 12 /* No extended merges */
|
||||
#define QUEUE_FLAG_ADD_RANDOM 13 /* Contributes to random pool */
|
||||
#define QUEUE_FLAG_SECERASE 14 /* supports secure erase */
|
||||
#define QUEUE_FLAG_SAME_FORCE 15 /* force complete on same CPU */
|
||||
#define QUEUE_FLAG_DEAD 16 /* queue tear-down finished */
|
||||
#define QUEUE_FLAG_INIT_DONE 17 /* queue is initialized */
|
||||
#define QUEUE_FLAG_NO_SG_MERGE 18 /* don't attempt to merge SG segments*/
|
||||
#define QUEUE_FLAG_POLL 19 /* IO polling enabled if set */
|
||||
#define QUEUE_FLAG_WC 20 /* Write back caching */
|
||||
#define QUEUE_FLAG_FUA 21 /* device supports FUA writes */
|
||||
#define QUEUE_FLAG_FLUSH_NQ 22 /* flush not queueuable */
|
||||
#define QUEUE_FLAG_DAX 23 /* device supports DAX */
|
||||
#define QUEUE_FLAG_STATS 24 /* track IO start and completion times */
|
||||
#define QUEUE_FLAG_POLL_STATS 25 /* collecting stats for hybrid polling */
|
||||
#define QUEUE_FLAG_REGISTERED 26 /* queue has been registered to a disk */
|
||||
#define QUEUE_FLAG_SCSI_PASSTHROUGH 27 /* queue supports SCSI commands */
|
||||
#define QUEUE_FLAG_QUIESCED 28 /* queue has been quiesced */
|
||||
#define QUEUE_FLAG_PCI_P2PDMA 29 /* device supports PCI p2p requests */
|
||||
|
||||
#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
|
||||
(1 << QUEUE_FLAG_SAME_COMP) | \
|
||||
(1 << QUEUE_FLAG_ADD_RANDOM))
|
||||
#define QUEUE_FLAG_STOPPED 0 /* queue is stopped */
|
||||
#define QUEUE_FLAG_DYING 1 /* queue being torn down */
|
||||
#define QUEUE_FLAG_NOMERGES 3 /* disable merge attempts */
|
||||
#define QUEUE_FLAG_SAME_COMP 4 /* complete on same CPU-group */
|
||||
#define QUEUE_FLAG_FAIL_IO 5 /* fake timeout */
|
||||
#define QUEUE_FLAG_NONROT 6 /* non-rotational device (SSD) */
|
||||
#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */
|
||||
#define QUEUE_FLAG_IO_STAT 7 /* do disk/partitions IO accounting */
|
||||
#define QUEUE_FLAG_DISCARD 8 /* supports DISCARD */
|
||||
#define QUEUE_FLAG_NOXMERGES 9 /* No extended merges */
|
||||
#define QUEUE_FLAG_ADD_RANDOM 10 /* Contributes to random pool */
|
||||
#define QUEUE_FLAG_SECERASE 11 /* supports secure erase */
|
||||
#define QUEUE_FLAG_SAME_FORCE 12 /* force complete on same CPU */
|
||||
#define QUEUE_FLAG_DEAD 13 /* queue tear-down finished */
|
||||
#define QUEUE_FLAG_INIT_DONE 14 /* queue is initialized */
|
||||
#define QUEUE_FLAG_POLL 16 /* IO polling enabled if set */
|
||||
#define QUEUE_FLAG_WC 17 /* Write back caching */
|
||||
#define QUEUE_FLAG_FUA 18 /* device supports FUA writes */
|
||||
#define QUEUE_FLAG_DAX 19 /* device supports DAX */
|
||||
#define QUEUE_FLAG_STATS 20 /* track IO start and completion times */
|
||||
#define QUEUE_FLAG_POLL_STATS 21 /* collecting stats for hybrid polling */
|
||||
#define QUEUE_FLAG_REGISTERED 22 /* queue has been registered to a disk */
|
||||
#define QUEUE_FLAG_SCSI_PASSTHROUGH 23 /* queue supports SCSI commands */
|
||||
#define QUEUE_FLAG_QUIESCED 24 /* queue has been quiesced */
|
||||
#define QUEUE_FLAG_PCI_P2PDMA 25 /* device supports PCI p2p requests */
|
||||
|
||||
#define QUEUE_FLAG_MQ_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
|
||||
(1 << QUEUE_FLAG_SAME_COMP))
|
||||
@@ -646,8 +634,6 @@ static inline bool blk_account_rq(struct request *rq)
|
||||
return (rq->rq_flags & RQF_STARTED) && !blk_rq_is_passthrough(rq);
|
||||
}
|
||||
|
||||
#define blk_bidi_rq(rq) ((rq)->next_rq != NULL)
|
||||
|
||||
#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
|
||||
|
||||
#define rq_data_dir(rq) (op_is_write(req_op(rq)) ? WRITE : READ)
|
||||
@@ -797,6 +783,10 @@ struct req_iterator {
|
||||
__rq_for_each_bio(_iter.bio, _rq) \
|
||||
bio_for_each_segment(bvl, _iter.bio, _iter.iter)
|
||||
|
||||
#define rq_for_each_bvec(bvl, _rq, _iter) \
|
||||
__rq_for_each_bio(_iter.bio, _rq) \
|
||||
bio_for_each_bvec(bvl, _iter.bio, _iter.iter)
|
||||
|
||||
#define rq_iter_last(bvec, _iter) \
|
||||
(_iter.bio->bi_next == NULL && \
|
||||
bio_iter_last(bvec, _iter.iter))
|
||||
@@ -1069,7 +1059,6 @@ extern void blk_queue_virt_boundary(struct request_queue *, unsigned long);
|
||||
extern void blk_queue_dma_alignment(struct request_queue *, int);
|
||||
extern void blk_queue_update_dma_alignment(struct request_queue *, int);
|
||||
extern void blk_queue_rq_timeout(struct request_queue *, unsigned int);
|
||||
extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable);
|
||||
extern void blk_queue_write_cache(struct request_queue *q, bool enabled, bool fua);
|
||||
|
||||
/*
|
||||
@@ -1446,11 +1435,6 @@ static inline unsigned int block_size(struct block_device *bdev)
|
||||
return bdev->bd_block_size;
|
||||
}
|
||||
|
||||
static inline bool queue_flush_queueable(struct request_queue *q)
|
||||
{
|
||||
return !test_bit(QUEUE_FLAG_FLUSH_NQ, &q->queue_flags);
|
||||
}
|
||||
|
||||
typedef struct {struct page *v;} Sector;
|
||||
|
||||
unsigned char *read_dev_sector(struct block_device *, sector_t, Sector *);
|
||||
|
@@ -78,7 +78,7 @@ int cgroup_bpf_inherit(struct cgroup *cgrp);
|
||||
int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
|
||||
enum bpf_attach_type type, u32 flags);
|
||||
int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
|
||||
enum bpf_attach_type type, u32 flags);
|
||||
enum bpf_attach_type type);
|
||||
int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
|
||||
union bpf_attr __user *uattr);
|
||||
|
||||
@@ -292,7 +292,7 @@ static inline int bpf_cgroup_storage_assign(struct bpf_prog *prog,
|
||||
static inline void bpf_cgroup_storage_release(struct bpf_prog *prog,
|
||||
struct bpf_map *map) {}
|
||||
static inline struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(
|
||||
struct bpf_prog *prog, enum bpf_cgroup_storage_type stype) { return 0; }
|
||||
struct bpf_prog *prog, enum bpf_cgroup_storage_type stype) { return NULL; }
|
||||
static inline void bpf_cgroup_storage_free(
|
||||
struct bpf_cgroup_storage *storage) {}
|
||||
static inline int bpf_percpu_cgroup_storage_copy(struct bpf_map *map, void *key,
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include <linux/rbtree_latch.h>
|
||||
#include <linux/numa.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/u64_stats_sync.h>
|
||||
|
||||
struct bpf_verifier_env;
|
||||
struct perf_event;
|
||||
@@ -72,14 +73,15 @@ struct bpf_map {
|
||||
u32 value_size;
|
||||
u32 max_entries;
|
||||
u32 map_flags;
|
||||
u32 pages;
|
||||
int spin_lock_off; /* >=0 valid offset, <0 error */
|
||||
u32 id;
|
||||
int numa_node;
|
||||
u32 btf_key_type_id;
|
||||
u32 btf_value_type_id;
|
||||
struct btf *btf;
|
||||
u32 pages;
|
||||
bool unpriv_array;
|
||||
/* 55 bytes hole */
|
||||
/* 51 bytes hole */
|
||||
|
||||
/* The 3rd and 4th cacheline with misc members to avoid false sharing
|
||||
* particularly with refcounting.
|
||||
@@ -91,6 +93,36 @@ struct bpf_map {
|
||||
char name[BPF_OBJ_NAME_LEN];
|
||||
};
|
||||
|
||||
static inline bool map_value_has_spin_lock(const struct bpf_map *map)
|
||||
{
|
||||
return map->spin_lock_off >= 0;
|
||||
}
|
||||
|
||||
static inline void check_and_init_map_lock(struct bpf_map *map, void *dst)
|
||||
{
|
||||
if (likely(!map_value_has_spin_lock(map)))
|
||||
return;
|
||||
*(struct bpf_spin_lock *)(dst + map->spin_lock_off) =
|
||||
(struct bpf_spin_lock){};
|
||||
}
|
||||
|
||||
/* copy everything but bpf_spin_lock */
|
||||
static inline void copy_map_value(struct bpf_map *map, void *dst, void *src)
|
||||
{
|
||||
if (unlikely(map_value_has_spin_lock(map))) {
|
||||
u32 off = map->spin_lock_off;
|
||||
|
||||
memcpy(dst, src, off);
|
||||
memcpy(dst + off + sizeof(struct bpf_spin_lock),
|
||||
src + off + sizeof(struct bpf_spin_lock),
|
||||
map->value_size - off - sizeof(struct bpf_spin_lock));
|
||||
} else {
|
||||
memcpy(dst, src, map->value_size);
|
||||
}
|
||||
}
|
||||
void copy_map_value_locked(struct bpf_map *map, void *dst, void *src,
|
||||
bool lock_src);
|
||||
|
||||
struct bpf_offload_dev;
|
||||
struct bpf_offloaded_map;
|
||||
|
||||
@@ -162,6 +194,8 @@ enum bpf_arg_type {
|
||||
ARG_PTR_TO_CTX, /* pointer to context */
|
||||
ARG_ANYTHING, /* any (initialized) argument is ok */
|
||||
ARG_PTR_TO_SOCKET, /* pointer to bpf_sock */
|
||||
ARG_PTR_TO_SPIN_LOCK, /* pointer to bpf_spin_lock */
|
||||
ARG_PTR_TO_SOCK_COMMON, /* pointer to sock_common */
|
||||
};
|
||||
|
||||
/* type of values returned from helper functions */
|
||||
@@ -171,6 +205,7 @@ enum bpf_return_type {
|
||||
RET_PTR_TO_MAP_VALUE, /* returns a pointer to map elem value */
|
||||
RET_PTR_TO_MAP_VALUE_OR_NULL, /* returns a pointer to map elem value or NULL */
|
||||
RET_PTR_TO_SOCKET_OR_NULL, /* returns a pointer to a socket or NULL */
|
||||
RET_PTR_TO_TCP_SOCK_OR_NULL, /* returns a pointer to a tcp_sock or NULL */
|
||||
};
|
||||
|
||||
/* eBPF function prototype used by verifier to allow BPF_CALLs from eBPF programs
|
||||
@@ -224,6 +259,10 @@ enum bpf_reg_type {
|
||||
PTR_TO_FLOW_KEYS, /* reg points to bpf_flow_keys */
|
||||
PTR_TO_SOCKET, /* reg points to struct bpf_sock */
|
||||
PTR_TO_SOCKET_OR_NULL, /* reg points to struct bpf_sock or NULL */
|
||||
PTR_TO_SOCK_COMMON, /* reg points to sock_common */
|
||||
PTR_TO_SOCK_COMMON_OR_NULL, /* reg points to sock_common or NULL */
|
||||
PTR_TO_TCP_SOCK, /* reg points to struct tcp_sock */
|
||||
PTR_TO_TCP_SOCK_OR_NULL, /* reg points to struct tcp_sock or NULL */
|
||||
};
|
||||
|
||||
/* The information passed from prog-specific *_is_valid_access
|
||||
@@ -268,9 +307,15 @@ struct bpf_verifier_ops {
|
||||
};
|
||||
|
||||
struct bpf_prog_offload_ops {
|
||||
/* verifier basic callbacks */
|
||||
int (*insn_hook)(struct bpf_verifier_env *env,
|
||||
int insn_idx, int prev_insn_idx);
|
||||
int (*finalize)(struct bpf_verifier_env *env);
|
||||
/* verifier optimization callbacks (called after .finalize) */
|
||||
int (*replace_insn)(struct bpf_verifier_env *env, u32 off,
|
||||
struct bpf_insn *insn);
|
||||
int (*remove_insns)(struct bpf_verifier_env *env, u32 off, u32 cnt);
|
||||
/* program management callbacks */
|
||||
int (*prepare)(struct bpf_prog *prog);
|
||||
int (*translate)(struct bpf_prog *prog);
|
||||
void (*destroy)(struct bpf_prog *prog);
|
||||
@@ -283,6 +328,7 @@ struct bpf_prog_offload {
|
||||
void *dev_priv;
|
||||
struct list_head offloads;
|
||||
bool dev_state;
|
||||
bool opt_failed;
|
||||
void *jited_image;
|
||||
u32 jited_len;
|
||||
};
|
||||
@@ -295,6 +341,12 @@ enum bpf_cgroup_storage_type {
|
||||
|
||||
#define MAX_BPF_CGROUP_STORAGE_TYPE __BPF_CGROUP_STORAGE_MAX
|
||||
|
||||
struct bpf_prog_stats {
|
||||
u64 cnt;
|
||||
u64 nsecs;
|
||||
struct u64_stats_sync syncp;
|
||||
};
|
||||
|
||||
struct bpf_prog_aux {
|
||||
atomic_t refcnt;
|
||||
u32 used_map_cnt;
|
||||
@@ -344,6 +396,7 @@ struct bpf_prog_aux {
|
||||
* main prog always has linfo_idx == 0
|
||||
*/
|
||||
u32 linfo_idx;
|
||||
struct bpf_prog_stats __percpu *stats;
|
||||
union {
|
||||
struct work_struct work;
|
||||
struct rcu_head rcu;
|
||||
@@ -397,6 +450,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr);
|
||||
int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr);
|
||||
int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
|
||||
const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr);
|
||||
|
||||
/* an array of programs to be executed under rcu_lock.
|
||||
*
|
||||
@@ -511,6 +567,7 @@ void bpf_map_area_free(void *base);
|
||||
void bpf_map_init_from_attr(struct bpf_map *map, union bpf_attr *attr);
|
||||
|
||||
extern int sysctl_unprivileged_bpf_disabled;
|
||||
extern int sysctl_bpf_stats_enabled;
|
||||
|
||||
int bpf_map_new_fd(struct bpf_map *map, int flags);
|
||||
int bpf_prog_new_fd(struct bpf_prog *prog);
|
||||
@@ -725,8 +782,9 @@ int bpf_map_offload_get_next_key(struct bpf_map *map,
|
||||
bool bpf_offload_prog_map_match(struct bpf_prog *prog, struct bpf_map *map);
|
||||
|
||||
struct bpf_offload_dev *
|
||||
bpf_offload_dev_create(const struct bpf_prog_offload_ops *ops);
|
||||
bpf_offload_dev_create(const struct bpf_prog_offload_ops *ops, void *priv);
|
||||
void bpf_offload_dev_destroy(struct bpf_offload_dev *offdev);
|
||||
void *bpf_offload_dev_priv(struct bpf_offload_dev *offdev);
|
||||
int bpf_offload_dev_netdev_register(struct bpf_offload_dev *offdev,
|
||||
struct net_device *netdev);
|
||||
void bpf_offload_dev_netdev_unregister(struct bpf_offload_dev *offdev,
|
||||
@@ -869,7 +927,8 @@ extern const struct bpf_func_proto bpf_msg_redirect_hash_proto;
|
||||
extern const struct bpf_func_proto bpf_msg_redirect_map_proto;
|
||||
extern const struct bpf_func_proto bpf_sk_redirect_hash_proto;
|
||||
extern const struct bpf_func_proto bpf_sk_redirect_map_proto;
|
||||
|
||||
extern const struct bpf_func_proto bpf_spin_lock_proto;
|
||||
extern const struct bpf_func_proto bpf_spin_unlock_proto;
|
||||
extern const struct bpf_func_proto bpf_get_local_storage_proto;
|
||||
|
||||
/* Shared helpers among cBPF and eBPF. */
|
||||
@@ -877,6 +936,9 @@ void bpf_user_rnd_init_once(void);
|
||||
u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
|
||||
|
||||
#if defined(CONFIG_NET)
|
||||
bool bpf_sock_common_is_valid_access(int off, int size,
|
||||
enum bpf_access_type type,
|
||||
struct bpf_insn_access_aux *info);
|
||||
bool bpf_sock_is_valid_access(int off, int size, enum bpf_access_type type,
|
||||
struct bpf_insn_access_aux *info);
|
||||
u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
|
||||
@@ -885,6 +947,12 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
|
||||
struct bpf_prog *prog,
|
||||
u32 *target_size);
|
||||
#else
|
||||
static inline bool bpf_sock_common_is_valid_access(int off, int size,
|
||||
enum bpf_access_type type,
|
||||
struct bpf_insn_access_aux *info)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline bool bpf_sock_is_valid_access(int off, int size,
|
||||
enum bpf_access_type type,
|
||||
struct bpf_insn_access_aux *info)
|
||||
@@ -901,4 +969,31 @@ static inline u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_INET
|
||||
bool bpf_tcp_sock_is_valid_access(int off, int size, enum bpf_access_type type,
|
||||
struct bpf_insn_access_aux *info);
|
||||
|
||||
u32 bpf_tcp_sock_convert_ctx_access(enum bpf_access_type type,
|
||||
const struct bpf_insn *si,
|
||||
struct bpf_insn *insn_buf,
|
||||
struct bpf_prog *prog,
|
||||
u32 *target_size);
|
||||
#else
|
||||
static inline bool bpf_tcp_sock_is_valid_access(int off, int size,
|
||||
enum bpf_access_type type,
|
||||
struct bpf_insn_access_aux *info)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline u32 bpf_tcp_sock_convert_ctx_access(enum bpf_access_type type,
|
||||
const struct bpf_insn *si,
|
||||
struct bpf_insn *insn_buf,
|
||||
struct bpf_prog *prog,
|
||||
u32 *target_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_INET */
|
||||
|
||||
#endif /* _LINUX_BPF_H */
|
||||
|
@@ -6,9 +6,11 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_SOCKET_FILTER, sk_filter)
|
||||
BPF_PROG_TYPE(BPF_PROG_TYPE_SCHED_CLS, tc_cls_act)
|
||||
BPF_PROG_TYPE(BPF_PROG_TYPE_SCHED_ACT, tc_cls_act)
|
||||
BPF_PROG_TYPE(BPF_PROG_TYPE_XDP, xdp)
|
||||
#ifdef CONFIG_CGROUP_BPF
|
||||
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SKB, cg_skb)
|
||||
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SOCK, cg_sock)
|
||||
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, cg_sock_addr)
|
||||
#endif
|
||||
BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_IN, lwt_in)
|
||||
BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_OUT, lwt_out)
|
||||
BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_XMIT, lwt_xmit)
|
||||
|
@@ -148,6 +148,7 @@ struct bpf_verifier_state {
|
||||
/* call stack tracking */
|
||||
struct bpf_func_state *frame[MAX_CALL_FRAMES];
|
||||
u32 curframe;
|
||||
u32 active_spin_lock;
|
||||
bool speculative;
|
||||
};
|
||||
|
||||
@@ -187,6 +188,7 @@ struct bpf_insn_aux_data {
|
||||
int sanitize_stack_off; /* stack slot to be cleared */
|
||||
bool seen; /* this insn was processed by the verifier */
|
||||
u8 alu_state; /* used in combination with alu_limit */
|
||||
unsigned int orig_idx; /* original instruction index */
|
||||
};
|
||||
|
||||
#define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */
|
||||
@@ -265,5 +267,10 @@ int bpf_prog_offload_verifier_prep(struct bpf_prog *prog);
|
||||
int bpf_prog_offload_verify_insn(struct bpf_verifier_env *env,
|
||||
int insn_idx, int prev_insn_idx);
|
||||
int bpf_prog_offload_finalize(struct bpf_verifier_env *env);
|
||||
void
|
||||
bpf_prog_offload_replace_insn(struct bpf_verifier_env *env, u32 off,
|
||||
struct bpf_insn *insn);
|
||||
void
|
||||
bpf_prog_offload_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt);
|
||||
|
||||
#endif /* _LINUX_BPF_VERIFIER_H */
|
||||
|
@@ -69,6 +69,10 @@ struct bsg_job {
|
||||
int result;
|
||||
unsigned int reply_payload_rcv_len;
|
||||
|
||||
/* BIDI support */
|
||||
struct request *bidi_rq;
|
||||
struct bio *bidi_bio;
|
||||
|
||||
void *dd_data; /* Used for driver-specific storage */
|
||||
};
|
||||
|
||||
|
@@ -50,6 +50,7 @@ u32 btf_id(const struct btf *btf);
|
||||
bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
|
||||
const struct btf_member *m,
|
||||
u32 expected_offset, u32 expected_size);
|
||||
int btf_find_spin_lock(const struct btf *btf, const struct btf_type *t);
|
||||
|
||||
#ifdef CONFIG_BPF_SYSCALL
|
||||
const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id);
|
||||
|
@@ -58,4 +58,23 @@
|
||||
*/
|
||||
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
|
||||
|
||||
/**
|
||||
* static_assert - check integer constant expression at build time
|
||||
*
|
||||
* static_assert() is a wrapper for the C11 _Static_assert, with a
|
||||
* little macro magic to make the message optional (defaulting to the
|
||||
* stringification of the tested expression).
|
||||
*
|
||||
* Contrary to BUILD_BUG_ON(), static_assert() can be used at global
|
||||
* scope, but requires the expression to be an integer constant
|
||||
* expression (i.e., it is not enough that __builtin_constant_p() is
|
||||
* true for expr).
|
||||
*
|
||||
* Also note that BUILD_BUG_ON() fails the build if the condition is
|
||||
* true, while static_assert() fails the build if the expression is
|
||||
* false.
|
||||
*/
|
||||
#define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
|
||||
#define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
|
||||
|
||||
#endif /* _LINUX_BUILD_BUG_H */
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
/*
|
||||
* was unsigned short, but we might as well be ready for > 64kB I/O pages
|
||||
@@ -44,22 +45,56 @@ struct bvec_iter {
|
||||
current bvec */
|
||||
};
|
||||
|
||||
struct bvec_iter_all {
|
||||
struct bio_vec bv;
|
||||
int idx;
|
||||
unsigned done;
|
||||
};
|
||||
|
||||
static inline struct page *bvec_nth_page(struct page *page, int idx)
|
||||
{
|
||||
return idx == 0 ? page : nth_page(page, idx);
|
||||
}
|
||||
|
||||
/*
|
||||
* various member access, note that bio_data should of course not be used
|
||||
* on highmem page vectors
|
||||
*/
|
||||
#define __bvec_iter_bvec(bvec, iter) (&(bvec)[(iter).bi_idx])
|
||||
|
||||
#define bvec_iter_page(bvec, iter) \
|
||||
/* multi-page (mp_bvec) helpers */
|
||||
#define mp_bvec_iter_page(bvec, iter) \
|
||||
(__bvec_iter_bvec((bvec), (iter))->bv_page)
|
||||
|
||||
#define bvec_iter_len(bvec, iter) \
|
||||
#define mp_bvec_iter_len(bvec, iter) \
|
||||
min((iter).bi_size, \
|
||||
__bvec_iter_bvec((bvec), (iter))->bv_len - (iter).bi_bvec_done)
|
||||
|
||||
#define bvec_iter_offset(bvec, iter) \
|
||||
#define mp_bvec_iter_offset(bvec, iter) \
|
||||
(__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
|
||||
|
||||
#define mp_bvec_iter_page_idx(bvec, iter) \
|
||||
(mp_bvec_iter_offset((bvec), (iter)) / PAGE_SIZE)
|
||||
|
||||
#define mp_bvec_iter_bvec(bvec, iter) \
|
||||
((struct bio_vec) { \
|
||||
.bv_page = mp_bvec_iter_page((bvec), (iter)), \
|
||||
.bv_len = mp_bvec_iter_len((bvec), (iter)), \
|
||||
.bv_offset = mp_bvec_iter_offset((bvec), (iter)), \
|
||||
})
|
||||
|
||||
/* For building single-page bvec in flight */
|
||||
#define bvec_iter_offset(bvec, iter) \
|
||||
(mp_bvec_iter_offset((bvec), (iter)) % PAGE_SIZE)
|
||||
|
||||
#define bvec_iter_len(bvec, iter) \
|
||||
min_t(unsigned, mp_bvec_iter_len((bvec), (iter)), \
|
||||
PAGE_SIZE - bvec_iter_offset((bvec), (iter)))
|
||||
|
||||
#define bvec_iter_page(bvec, iter) \
|
||||
bvec_nth_page(mp_bvec_iter_page((bvec), (iter)), \
|
||||
mp_bvec_iter_page_idx((bvec), (iter)))
|
||||
|
||||
#define bvec_iter_bvec(bvec, iter) \
|
||||
((struct bio_vec) { \
|
||||
.bv_page = bvec_iter_page((bvec), (iter)), \
|
||||
@@ -77,14 +112,15 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv,
|
||||
}
|
||||
|
||||
while (bytes) {
|
||||
unsigned iter_len = bvec_iter_len(bv, *iter);
|
||||
unsigned len = min(bytes, iter_len);
|
||||
const struct bio_vec *cur = bv + iter->bi_idx;
|
||||
unsigned len = min3(bytes, iter->bi_size,
|
||||
cur->bv_len - iter->bi_bvec_done);
|
||||
|
||||
bytes -= len;
|
||||
iter->bi_size -= len;
|
||||
iter->bi_bvec_done += len;
|
||||
|
||||
if (iter->bi_bvec_done == __bvec_iter_bvec(bv, *iter)->bv_len) {
|
||||
if (iter->bi_bvec_done == cur->bv_len) {
|
||||
iter->bi_bvec_done = 0;
|
||||
iter->bi_idx++;
|
||||
}
|
||||
@@ -92,30 +128,6 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv,
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool bvec_iter_rewind(const struct bio_vec *bv,
|
||||
struct bvec_iter *iter,
|
||||
unsigned int bytes)
|
||||
{
|
||||
while (bytes) {
|
||||
unsigned len = min(bytes, iter->bi_bvec_done);
|
||||
|
||||
if (iter->bi_bvec_done == 0) {
|
||||
if (WARN_ONCE(iter->bi_idx == 0,
|
||||
"Attempted to rewind iter beyond "
|
||||
"bvec's boundaries\n")) {
|
||||
return false;
|
||||
}
|
||||
iter->bi_idx--;
|
||||
iter->bi_bvec_done = __bvec_iter_bvec(bv, *iter)->bv_len;
|
||||
continue;
|
||||
}
|
||||
bytes -= len;
|
||||
iter->bi_size += len;
|
||||
iter->bi_bvec_done -= len;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define for_each_bvec(bvl, bio_vec, iter, start) \
|
||||
for (iter = (start); \
|
||||
(iter).bi_size && \
|
||||
@@ -131,4 +143,55 @@ static inline bool bvec_iter_rewind(const struct bio_vec *bv,
|
||||
.bi_bvec_done = 0, \
|
||||
}
|
||||
|
||||
static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all)
|
||||
{
|
||||
iter_all->bv.bv_page = NULL;
|
||||
iter_all->done = 0;
|
||||
|
||||
return &iter_all->bv;
|
||||
}
|
||||
|
||||
static inline void mp_bvec_next_segment(const struct bio_vec *bvec,
|
||||
struct bvec_iter_all *iter_all)
|
||||
{
|
||||
struct bio_vec *bv = &iter_all->bv;
|
||||
|
||||
if (bv->bv_page) {
|
||||
bv->bv_page = nth_page(bv->bv_page, 1);
|
||||
bv->bv_offset = 0;
|
||||
} else {
|
||||
bv->bv_page = bvec->bv_page;
|
||||
bv->bv_offset = bvec->bv_offset;
|
||||
}
|
||||
bv->bv_len = min_t(unsigned int, PAGE_SIZE - bv->bv_offset,
|
||||
bvec->bv_len - iter_all->done);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the last single-page segment from the multi-page bvec and store it
|
||||
* in @seg
|
||||
*/
|
||||
static inline void mp_bvec_last_segment(const struct bio_vec *bvec,
|
||||
struct bio_vec *seg)
|
||||
{
|
||||
unsigned total = bvec->bv_offset + bvec->bv_len;
|
||||
unsigned last_page = (total - 1) / PAGE_SIZE;
|
||||
|
||||
seg->bv_page = bvec_nth_page(bvec->bv_page, last_page);
|
||||
|
||||
/* the whole segment is inside the last page */
|
||||
if (bvec->bv_offset >= last_page * PAGE_SIZE) {
|
||||
seg->bv_offset = bvec->bv_offset % PAGE_SIZE;
|
||||
seg->bv_len = bvec->bv_len;
|
||||
} else {
|
||||
seg->bv_offset = 0;
|
||||
seg->bv_len = total - last_page * PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
#define mp_bvec_for_each_page(pg, bv, i) \
|
||||
for (i = (bv)->bv_offset / PAGE_SIZE; \
|
||||
(i <= (((bv)->bv_offset + (bv)->bv_len - 1) / PAGE_SIZE)) && \
|
||||
(pg = bvec_nth_page((bv)->bv_page, i)); i += 1)
|
||||
|
||||
#endif /* __LINUX_BVEC_ITER_H */
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#define _LINUX_CAPABILITY_H
|
||||
|
||||
#include <uapi/linux/capability.h>
|
||||
|
||||
#include <linux/uidgid.h>
|
||||
|
||||
#define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3
|
||||
#define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3
|
||||
@@ -25,11 +25,12 @@ typedef struct kernel_cap_struct {
|
||||
__u32 cap[_KERNEL_CAPABILITY_U32S];
|
||||
} kernel_cap_t;
|
||||
|
||||
/* exact same as vfs_cap_data but in cpu endian and always filled completely */
|
||||
/* same as vfs_ns_cap_data but in cpu endian and always filled completely */
|
||||
struct cpu_vfs_cap_data {
|
||||
__u32 magic_etc;
|
||||
kernel_cap_t permitted;
|
||||
kernel_cap_t inheritable;
|
||||
kuid_t rootid;
|
||||
};
|
||||
|
||||
#define _USER_CAP_HEADER_SIZE (sizeof(struct __user_cap_header_struct))
|
||||
@@ -209,6 +210,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
|
||||
extern bool capable(int cap);
|
||||
extern bool ns_capable(struct user_namespace *ns, int cap);
|
||||
extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
|
||||
extern bool ns_capable_setid(struct user_namespace *ns, int cap);
|
||||
#else
|
||||
static inline bool has_capability(struct task_struct *t, int cap)
|
||||
{
|
||||
@@ -240,6 +242,10 @@ static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static inline bool ns_capable_setid(struct user_namespace *ns, int cap)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif /* CONFIG_MULTIUSER */
|
||||
extern bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode);
|
||||
extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
|
||||
|
@@ -24,6 +24,7 @@ struct ceph_vino {
|
||||
/* context for the caps reservation mechanism */
|
||||
struct ceph_cap_reservation {
|
||||
int count;
|
||||
int used;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -32,6 +32,7 @@ struct kernfs_node;
|
||||
struct kernfs_ops;
|
||||
struct kernfs_open_file;
|
||||
struct seq_file;
|
||||
struct poll_table_struct;
|
||||
|
||||
#define MAX_CGROUP_TYPE_NAMELEN 32
|
||||
#define MAX_CGROUP_ROOT_NAMELEN 64
|
||||
@@ -574,6 +575,9 @@ struct cftype {
|
||||
ssize_t (*write)(struct kernfs_open_file *of,
|
||||
char *buf, size_t nbytes, loff_t off);
|
||||
|
||||
__poll_t (*poll)(struct kernfs_open_file *of,
|
||||
struct poll_table_struct *pt);
|
||||
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
struct lock_class_key lockdep_key;
|
||||
#endif
|
||||
@@ -602,7 +606,7 @@ struct cgroup_subsys {
|
||||
void (*cancel_fork)(struct task_struct *task);
|
||||
void (*fork)(struct task_struct *task);
|
||||
void (*exit)(struct task_struct *task);
|
||||
void (*free)(struct task_struct *task);
|
||||
void (*release)(struct task_struct *task);
|
||||
void (*bind)(struct cgroup_subsys_state *root_css);
|
||||
|
||||
bool early_init:1;
|
||||
|
@@ -121,6 +121,7 @@ extern int cgroup_can_fork(struct task_struct *p);
|
||||
extern void cgroup_cancel_fork(struct task_struct *p);
|
||||
extern void cgroup_post_fork(struct task_struct *p);
|
||||
void cgroup_exit(struct task_struct *p);
|
||||
void cgroup_release(struct task_struct *p);
|
||||
void cgroup_free(struct task_struct *p);
|
||||
|
||||
int cgroup_init_early(void);
|
||||
@@ -697,6 +698,7 @@ static inline int cgroup_can_fork(struct task_struct *p) { return 0; }
|
||||
static inline void cgroup_cancel_fork(struct task_struct *p) {}
|
||||
static inline void cgroup_post_fork(struct task_struct *p) {}
|
||||
static inline void cgroup_exit(struct task_struct *p) {}
|
||||
static inline void cgroup_release(struct task_struct *p) {}
|
||||
static inline void cgroup_free(struct task_struct *p) {}
|
||||
|
||||
static inline int cgroup_init_early(void) { return 0; }
|
||||
|
@@ -39,7 +39,7 @@ struct rdmacg_device {
|
||||
* APIs for RDMA/IB stack to publish when a device wants to
|
||||
* participate in resource accounting
|
||||
*/
|
||||
int rdmacg_register_device(struct rdmacg_device *device);
|
||||
void rdmacg_register_device(struct rdmacg_device *device);
|
||||
void rdmacg_unregister_device(struct rdmacg_device *device);
|
||||
|
||||
/* APIs for RDMA/IB stack to charge/uncharge pool specific resources */
|
||||
|
@@ -792,6 +792,9 @@ unsigned int __clk_get_enable_count(struct clk *clk);
|
||||
unsigned long clk_hw_get_rate(const struct clk_hw *hw);
|
||||
unsigned long __clk_get_flags(struct clk *clk);
|
||||
unsigned long clk_hw_get_flags(const struct clk_hw *hw);
|
||||
#define clk_hw_can_set_rate_parent(hw) \
|
||||
(clk_hw_get_flags((hw)) & CLK_SET_RATE_PARENT)
|
||||
|
||||
bool clk_hw_is_prepared(const struct clk_hw *hw);
|
||||
bool clk_hw_rate_is_protected(const struct clk_hw *hw);
|
||||
bool clk_hw_is_enabled(const struct clk_hw *hw);
|
||||
|
@@ -383,6 +383,17 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
|
||||
*/
|
||||
struct clk *devm_clk_get(struct device *dev, const char *id);
|
||||
|
||||
/**
|
||||
* devm_clk_get_optional - lookup and obtain a managed reference to an optional
|
||||
* clock producer.
|
||||
* @dev: device for clock "consumer"
|
||||
* @id: clock consumer ID
|
||||
*
|
||||
* Behaves the same as devm_clk_get() except where there is no clock producer.
|
||||
* In this case, instead of returning -ENOENT, the function returns NULL.
|
||||
*/
|
||||
struct clk *devm_clk_get_optional(struct device *dev, const char *id);
|
||||
|
||||
/**
|
||||
* devm_get_clk_from_child - lookup and obtain a managed reference to a
|
||||
* clock producer from child node.
|
||||
@@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device *dev, const char *id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct clk *devm_clk_get_optional(struct device *dev,
|
||||
const char *id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
|
||||
struct clk_bulk_data *clks)
|
||||
{
|
||||
@@ -862,6 +879,25 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
|
||||
clk_bulk_unprepare(num_clks, clks);
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_get_optional - lookup and obtain a reference to an optional clock
|
||||
* producer.
|
||||
* @dev: device for clock "consumer"
|
||||
* @id: clock consumer ID
|
||||
*
|
||||
* Behaves the same as clk_get() except where there is no clock producer. In
|
||||
* this case, instead of returning -ENOENT, the function returns NULL.
|
||||
*/
|
||||
static inline struct clk *clk_get_optional(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk *clk = clk_get(dev, id);
|
||||
|
||||
if (clk == ERR_PTR(-ENOENT))
|
||||
return NULL;
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
|
||||
struct clk *of_clk_get(struct device_node *np, int index);
|
||||
struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
|
||||
|
@@ -160,6 +160,7 @@ struct clk_hw_omap {
|
||||
struct clockdomain *clkdm;
|
||||
const struct clk_hw_omap_ops *ops;
|
||||
u32 context;
|
||||
int autoidle_count;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -52,4 +52,8 @@ int clk_add_alias(const char *, const char *, const char *, struct device *);
|
||||
int clk_register_clkdev(struct clk *, const char *, const char *);
|
||||
int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *);
|
||||
|
||||
int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
|
||||
const char *con_id, const char *dev_id);
|
||||
void devm_clk_release_clkdev(struct device *dev, const char *con_id,
|
||||
const char *dev_id);
|
||||
#endif
|
||||
|
@@ -88,14 +88,13 @@ extern int sysctl_compact_memory;
|
||||
extern int sysctl_compaction_handler(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *length, loff_t *ppos);
|
||||
extern int sysctl_extfrag_threshold;
|
||||
extern int sysctl_extfrag_handler(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *length, loff_t *ppos);
|
||||
extern int sysctl_compact_unevictable_allowed;
|
||||
|
||||
extern int fragmentation_index(struct zone *zone, unsigned int order);
|
||||
extern enum compact_result try_to_compact_pages(gfp_t gfp_mask,
|
||||
unsigned int order, unsigned int alloc_flags,
|
||||
const struct alloc_context *ac, enum compact_priority prio);
|
||||
const struct alloc_context *ac, enum compact_priority prio,
|
||||
struct page **page);
|
||||
extern void reset_isolation_suitable(pg_data_t *pgdat);
|
||||
extern enum compact_result compaction_suitable(struct zone *zone, int order,
|
||||
unsigned int alloc_flags, int classzone_idx);
|
||||
@@ -227,8 +226,8 @@ static inline void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_i
|
||||
|
||||
#endif /* CONFIG_COMPACTION */
|
||||
|
||||
#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
|
||||
struct node;
|
||||
#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
|
||||
extern int compaction_register_node(struct node *node);
|
||||
extern void compaction_unregister_node(struct node *node);
|
||||
|
||||
|
@@ -132,37 +132,6 @@ struct compat_tms {
|
||||
compat_clock_t tms_cstime;
|
||||
};
|
||||
|
||||
struct compat_timex {
|
||||
compat_uint_t modes;
|
||||
compat_long_t offset;
|
||||
compat_long_t freq;
|
||||
compat_long_t maxerror;
|
||||
compat_long_t esterror;
|
||||
compat_int_t status;
|
||||
compat_long_t constant;
|
||||
compat_long_t precision;
|
||||
compat_long_t tolerance;
|
||||
struct old_timeval32 time;
|
||||
compat_long_t tick;
|
||||
compat_long_t ppsfreq;
|
||||
compat_long_t jitter;
|
||||
compat_int_t shift;
|
||||
compat_long_t stabil;
|
||||
compat_long_t jitcnt;
|
||||
compat_long_t calcnt;
|
||||
compat_long_t errcnt;
|
||||
compat_long_t stbcnt;
|
||||
compat_int_t tai;
|
||||
|
||||
compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
|
||||
compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
|
||||
compat_int_t:32; compat_int_t:32; compat_int_t:32;
|
||||
};
|
||||
|
||||
struct timex;
|
||||
int compat_get_timex(struct timex *, const struct compat_timex __user *);
|
||||
int compat_put_timex(struct compat_timex __user *, const struct timex *);
|
||||
|
||||
#define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW)
|
||||
|
||||
typedef struct {
|
||||
@@ -551,11 +520,6 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
|
||||
asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p);
|
||||
asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr,
|
||||
u32 __user *iocb);
|
||||
asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id,
|
||||
compat_long_t min_nr,
|
||||
compat_long_t nr,
|
||||
struct io_event __user *events,
|
||||
struct old_timespec32 __user *timeout);
|
||||
asmlinkage long compat_sys_io_pgetevents(compat_aio_context_t ctx_id,
|
||||
compat_long_t min_nr,
|
||||
compat_long_t nr,
|
||||
@@ -648,7 +612,7 @@ asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
|
||||
compat_loff_t __user *offset, compat_size_t count);
|
||||
|
||||
/* fs/select.c */
|
||||
asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp,
|
||||
asmlinkage long compat_sys_pselect6_time32(int n, compat_ulong_t __user *inp,
|
||||
compat_ulong_t __user *outp,
|
||||
compat_ulong_t __user *exp,
|
||||
struct old_timespec32 __user *tsp,
|
||||
@@ -658,7 +622,7 @@ asmlinkage long compat_sys_pselect6_time64(int n, compat_ulong_t __user *inp,
|
||||
compat_ulong_t __user *exp,
|
||||
struct __kernel_timespec __user *tsp,
|
||||
void __user *sig);
|
||||
asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
|
||||
asmlinkage long compat_sys_ppoll_time32(struct pollfd __user *ufds,
|
||||
unsigned int nfds,
|
||||
struct old_timespec32 __user *tsp,
|
||||
const compat_sigset_t __user *sigmask,
|
||||
@@ -688,19 +652,6 @@ asmlinkage long compat_sys_newfstat(unsigned int fd,
|
||||
|
||||
/* fs/sync.c: No generic prototype for sync_file_range and sync_file_range2 */
|
||||
|
||||
/* fs/timerfd.c */
|
||||
asmlinkage long compat_sys_timerfd_gettime(int ufd,
|
||||
struct old_itimerspec32 __user *otmr);
|
||||
asmlinkage long compat_sys_timerfd_settime(int ufd, int flags,
|
||||
const struct old_itimerspec32 __user *utmr,
|
||||
struct old_itimerspec32 __user *otmr);
|
||||
|
||||
/* fs/utimes.c */
|
||||
asmlinkage long compat_sys_utimensat(unsigned int dfd,
|
||||
const char __user *filename,
|
||||
struct old_timespec32 __user *t,
|
||||
int flags);
|
||||
|
||||
/* kernel/exit.c */
|
||||
asmlinkage long compat_sys_waitid(int, compat_pid_t,
|
||||
struct compat_siginfo __user *, int,
|
||||
@@ -709,9 +660,6 @@ asmlinkage long compat_sys_waitid(int, compat_pid_t,
|
||||
|
||||
|
||||
/* kernel/futex.c */
|
||||
asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
|
||||
struct old_timespec32 __user *utime, u32 __user *uaddr2,
|
||||
u32 val3);
|
||||
asmlinkage long
|
||||
compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
|
||||
compat_size_t len);
|
||||
@@ -719,10 +667,6 @@ asmlinkage long
|
||||
compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
|
||||
compat_size_t __user *len_ptr);
|
||||
|
||||
/* kernel/hrtimer.c */
|
||||
asmlinkage long compat_sys_nanosleep(struct old_timespec32 __user *rqtp,
|
||||
struct old_timespec32 __user *rmtp);
|
||||
|
||||
/* kernel/itimer.c */
|
||||
asmlinkage long compat_sys_getitimer(int which,
|
||||
struct compat_itimerval __user *it);
|
||||
@@ -740,20 +684,6 @@ asmlinkage long compat_sys_kexec_load(compat_ulong_t entry,
|
||||
asmlinkage long compat_sys_timer_create(clockid_t which_clock,
|
||||
struct compat_sigevent __user *timer_event_spec,
|
||||
timer_t __user *created_timer_id);
|
||||
asmlinkage long compat_sys_timer_gettime(timer_t timer_id,
|
||||
struct old_itimerspec32 __user *setting);
|
||||
asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags,
|
||||
struct old_itimerspec32 __user *new,
|
||||
struct old_itimerspec32 __user *old);
|
||||
asmlinkage long compat_sys_clock_settime(clockid_t which_clock,
|
||||
struct old_timespec32 __user *tp);
|
||||
asmlinkage long compat_sys_clock_gettime(clockid_t which_clock,
|
||||
struct old_timespec32 __user *tp);
|
||||
asmlinkage long compat_sys_clock_getres(clockid_t which_clock,
|
||||
struct old_timespec32 __user *tp);
|
||||
asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
|
||||
struct old_timespec32 __user *rqtp,
|
||||
struct old_timespec32 __user *rmtp);
|
||||
|
||||
/* kernel/ptrace.c */
|
||||
asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
|
||||
@@ -766,8 +696,6 @@ asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
|
||||
asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid,
|
||||
unsigned int len,
|
||||
compat_ulong_t __user *user_mask_ptr);
|
||||
asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
|
||||
struct old_timespec32 __user *interval);
|
||||
|
||||
/* kernel/signal.c */
|
||||
asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
|
||||
@@ -785,7 +713,7 @@ asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set,
|
||||
compat_size_t sigsetsize);
|
||||
asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset,
|
||||
compat_size_t sigsetsize);
|
||||
asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese,
|
||||
asmlinkage long compat_sys_rt_sigtimedwait_time32(compat_sigset_t __user *uthese,
|
||||
struct compat_siginfo __user *uinfo,
|
||||
struct old_timespec32 __user *uts, compat_size_t sigsetsize);
|
||||
asmlinkage long compat_sys_rt_sigtimedwait_time64(compat_sigset_t __user *uthese,
|
||||
@@ -808,7 +736,6 @@ asmlinkage long compat_sys_gettimeofday(struct old_timeval32 __user *tv,
|
||||
struct timezone __user *tz);
|
||||
asmlinkage long compat_sys_settimeofday(struct old_timeval32 __user *tv,
|
||||
struct timezone __user *tz);
|
||||
asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
|
||||
|
||||
/* kernel/timer.c */
|
||||
asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
|
||||
@@ -817,14 +744,6 @@ asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
|
||||
asmlinkage long compat_sys_mq_open(const char __user *u_name,
|
||||
int oflag, compat_mode_t mode,
|
||||
struct compat_mq_attr __user *u_attr);
|
||||
asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes,
|
||||
const char __user *u_msg_ptr,
|
||||
compat_size_t msg_len, unsigned int msg_prio,
|
||||
const struct old_timespec32 __user *u_abs_timeout);
|
||||
asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes,
|
||||
char __user *u_msg_ptr,
|
||||
compat_size_t msg_len, unsigned int __user *u_msg_prio,
|
||||
const struct old_timespec32 __user *u_abs_timeout);
|
||||
asmlinkage long compat_sys_mq_notify(mqd_t mqdes,
|
||||
const struct compat_sigevent __user *u_notification);
|
||||
asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes,
|
||||
@@ -840,8 +759,6 @@ asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp,
|
||||
|
||||
/* ipc/sem.c */
|
||||
asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
|
||||
asmlinkage long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
|
||||
unsigned nsems, const struct old_timespec32 __user *timeout);
|
||||
|
||||
/* ipc/shm.c */
|
||||
asmlinkage long compat_sys_shmctl(int first, int second, void __user *uptr);
|
||||
@@ -899,7 +816,7 @@ asmlinkage long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid,
|
||||
asmlinkage long compat_sys_recvmmsg_time64(int fd, struct compat_mmsghdr __user *mmsg,
|
||||
unsigned vlen, unsigned int flags,
|
||||
struct __kernel_timespec __user *timeout);
|
||||
asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
|
||||
asmlinkage long compat_sys_recvmmsg_time32(int fd, struct compat_mmsghdr __user *mmsg,
|
||||
unsigned vlen, unsigned int flags,
|
||||
struct old_timespec32 __user *timeout);
|
||||
asmlinkage long compat_sys_wait4(compat_pid_t pid,
|
||||
@@ -910,8 +827,6 @@ asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
|
||||
asmlinkage long compat_sys_open_by_handle_at(int mountdirfd,
|
||||
struct file_handle __user *handle,
|
||||
int flags);
|
||||
asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock,
|
||||
struct compat_timex __user *tp);
|
||||
asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
|
||||
unsigned vlen, unsigned int flags);
|
||||
asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid,
|
||||
@@ -952,8 +867,6 @@ asmlinkage long compat_sys_pwritev64v2(unsigned long fd,
|
||||
/* __ARCH_WANT_SYSCALL_NO_AT */
|
||||
asmlinkage long compat_sys_open(const char __user *filename, int flags,
|
||||
umode_t mode);
|
||||
asmlinkage long compat_sys_utimes(const char __user *filename,
|
||||
struct old_timeval32 __user *t);
|
||||
|
||||
/* __ARCH_WANT_SYSCALL_NO_FLAGS */
|
||||
asmlinkage long compat_sys_signalfd(int ufd,
|
||||
@@ -967,12 +880,6 @@ asmlinkage long compat_sys_newlstat(const char __user *filename,
|
||||
struct compat_stat __user *statbuf);
|
||||
|
||||
/* __ARCH_WANT_SYSCALL_DEPRECATED */
|
||||
asmlinkage long compat_sys_time(old_time32_t __user *tloc);
|
||||
asmlinkage long compat_sys_utime(const char __user *filename,
|
||||
struct old_utimbuf32 __user *t);
|
||||
asmlinkage long compat_sys_futimesat(unsigned int dfd,
|
||||
const char __user *filename,
|
||||
struct old_timeval32 __user *t);
|
||||
asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
|
||||
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
|
||||
struct old_timeval32 __user *tvp);
|
||||
@@ -1007,9 +914,6 @@ asmlinkage long compat_sys_sigaction(int sig,
|
||||
struct compat_old_sigaction __user *oact);
|
||||
#endif
|
||||
|
||||
/* obsolete: kernel/time/time.c */
|
||||
asmlinkage long compat_sys_stime(old_time32_t __user *tptr);
|
||||
|
||||
/* obsolete: net/socket.c */
|
||||
asmlinkage long compat_sys_socketcall(int call, u32 __user *args);
|
||||
|
||||
|
@@ -4,16 +4,38 @@
|
||||
|
||||
#include <linux/stddef.h>
|
||||
|
||||
|
||||
struct device;
|
||||
|
||||
/**
|
||||
* struct component_ops - callbacks for component drivers
|
||||
*
|
||||
* Components are registered with component_add() and unregistered with
|
||||
* component_del().
|
||||
*/
|
||||
struct component_ops {
|
||||
/**
|
||||
* @bind:
|
||||
*
|
||||
* Called through component_bind_all() when the aggregate driver is
|
||||
* ready to bind the overall driver.
|
||||
*/
|
||||
int (*bind)(struct device *comp, struct device *master,
|
||||
void *master_data);
|
||||
/**
|
||||
* @unbind:
|
||||
*
|
||||
* Called through component_unbind_all() when the aggregate driver is
|
||||
* ready to bind the overall driver, or when component_bind_all() fails
|
||||
* part-ways through and needs to unbind some already bound components.
|
||||
*/
|
||||
void (*unbind)(struct device *comp, struct device *master,
|
||||
void *master_data);
|
||||
};
|
||||
|
||||
int component_add(struct device *, const struct component_ops *);
|
||||
int component_add_typed(struct device *dev, const struct component_ops *ops,
|
||||
int subcomponent);
|
||||
void component_del(struct device *, const struct component_ops *);
|
||||
|
||||
int component_bind_all(struct device *master, void *master_data);
|
||||
@@ -21,8 +43,42 @@ void component_unbind_all(struct device *master, void *master_data);
|
||||
|
||||
struct master;
|
||||
|
||||
/**
|
||||
* struct component_master_ops - callback for the aggregate driver
|
||||
*
|
||||
* Aggregate drivers are registered with component_master_add_with_match() and
|
||||
* unregistered with component_master_del().
|
||||
*/
|
||||
struct component_master_ops {
|
||||
/**
|
||||
* @bind:
|
||||
*
|
||||
* Called when all components or the aggregate driver, as specified in
|
||||
* the match list passed to component_master_add_with_match(), are
|
||||
* ready. Usually there are 3 steps to bind an aggregate driver:
|
||||
*
|
||||
* 1. Allocate a structure for the aggregate driver.
|
||||
*
|
||||
* 2. Bind all components to the aggregate driver by calling
|
||||
* component_bind_all() with the aggregate driver structure as opaque
|
||||
* pointer data.
|
||||
*
|
||||
* 3. Register the aggregate driver with the subsystem to publish its
|
||||
* interfaces.
|
||||
*
|
||||
* Note that the lifetime of the aggregate driver does not align with
|
||||
* any of the underlying &struct device instances. Therefore devm cannot
|
||||
* be used and all resources acquired or allocated in this callback must
|
||||
* be explicitly released in the @unbind callback.
|
||||
*/
|
||||
int (*bind)(struct device *master);
|
||||
/**
|
||||
* @unbind:
|
||||
*
|
||||
* Called when either the aggregate driver, using
|
||||
* component_master_del(), or one of its components, using
|
||||
* component_del(), is unregistered.
|
||||
*/
|
||||
void (*unbind)(struct device *master);
|
||||
};
|
||||
|
||||
@@ -37,7 +93,27 @@ void component_match_add_release(struct device *master,
|
||||
struct component_match **matchptr,
|
||||
void (*release)(struct device *, void *),
|
||||
int (*compare)(struct device *, void *), void *compare_data);
|
||||
void component_match_add_typed(struct device *master,
|
||||
struct component_match **matchptr,
|
||||
int (*compare_typed)(struct device *, int, void *), void *compare_data);
|
||||
|
||||
/**
|
||||
* component_match_add - add a component match entry
|
||||
* @master: device with the aggregate driver
|
||||
* @matchptr: pointer to the list of component matches
|
||||
* @compare: compare function to match against all components
|
||||
* @compare_data: opaque pointer passed to the @compare function
|
||||
*
|
||||
* Adds a new component match to the list stored in @matchptr, which the @master
|
||||
* aggregate driver needs to function. The list of component matches pointed to
|
||||
* by @matchptr must be initialized to NULL before adding the first match. This
|
||||
* only matches against components added with component_add().
|
||||
*
|
||||
* The allocated match list in @matchptr is automatically released using devm
|
||||
* actions.
|
||||
*
|
||||
* See also component_match_add_release() and component_match_add_typed().
|
||||
*/
|
||||
static inline void component_match_add(struct device *master,
|
||||
struct component_match **matchptr,
|
||||
int (*compare)(struct device *, void *), void *compare_data)
|
||||
|
@@ -119,7 +119,7 @@ struct vc_data {
|
||||
unsigned int vc_s_blink : 1;
|
||||
unsigned int vc_s_reverse : 1;
|
||||
/* misc */
|
||||
unsigned int vc_ques : 1;
|
||||
unsigned int vc_priv : 3;
|
||||
unsigned int vc_need_wrap : 1;
|
||||
unsigned int vc_can_do_color : 1;
|
||||
unsigned int vc_report_mouse : 2;
|
||||
|
@@ -154,8 +154,9 @@ struct coresight_connection {
|
||||
* @orphan: true if the component has connections that haven't been linked.
|
||||
* @enable: 'true' if component is currently part of an active path.
|
||||
* @activated: 'true' only if a _sink_ has been activated. A sink can be
|
||||
activated but not yet enabled. Enabling for a _sink_
|
||||
happens when a source has been selected for that it.
|
||||
* activated but not yet enabled. Enabling for a _sink_
|
||||
* appens when a source has been selected for that it.
|
||||
* @ea: Device attribute for sink representation under PMU directory.
|
||||
*/
|
||||
struct coresight_device {
|
||||
struct coresight_connection *conns;
|
||||
@@ -168,7 +169,9 @@ struct coresight_device {
|
||||
atomic_t *refcnt;
|
||||
bool orphan;
|
||||
bool enable; /* true only if configured as part of a path */
|
||||
/* sink specific fields */
|
||||
bool activated; /* true only if a sink is part of a path */
|
||||
struct dev_ext_attribute *ea;
|
||||
};
|
||||
|
||||
#define to_coresight_device(d) container_of(d, struct coresight_device, dev)
|
||||
|
@@ -151,6 +151,9 @@ struct cpufreq_policy {
|
||||
|
||||
/* For cpufreq driver's internal use */
|
||||
void *driver_data;
|
||||
|
||||
/* Pointer to the cooling device if used for thermal mitigation */
|
||||
struct thermal_cooling_device *cdev;
|
||||
};
|
||||
|
||||
/* Only for ACPI */
|
||||
@@ -254,20 +257,12 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
|
||||
static struct freq_attr _name = \
|
||||
__ATTR(_name, 0200, NULL, store_##_name)
|
||||
|
||||
struct global_attr {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct kobject *kobj,
|
||||
struct attribute *attr, char *buf);
|
||||
ssize_t (*store)(struct kobject *a, struct attribute *b,
|
||||
const char *c, size_t count);
|
||||
};
|
||||
|
||||
#define define_one_global_ro(_name) \
|
||||
static struct global_attr _name = \
|
||||
static struct kobj_attribute _name = \
|
||||
__ATTR(_name, 0444, show_##_name, NULL)
|
||||
|
||||
#define define_one_global_rw(_name) \
|
||||
static struct global_attr _name = \
|
||||
static struct kobj_attribute _name = \
|
||||
__ATTR(_name, 0644, show_##_name, store_##_name)
|
||||
|
||||
|
||||
@@ -330,6 +325,8 @@ struct cpufreq_driver {
|
||||
/* optional */
|
||||
int (*bios_limit)(int cpu, unsigned int *limit);
|
||||
|
||||
int (*online)(struct cpufreq_policy *policy);
|
||||
int (*offline)(struct cpufreq_policy *policy);
|
||||
int (*exit)(struct cpufreq_policy *policy);
|
||||
void (*stop_cpu)(struct cpufreq_policy *policy);
|
||||
int (*suspend)(struct cpufreq_policy *policy);
|
||||
@@ -346,14 +343,15 @@ struct cpufreq_driver {
|
||||
};
|
||||
|
||||
/* flags */
|
||||
#define CPUFREQ_STICKY (1 << 0) /* driver isn't removed even if
|
||||
all ->init() calls failed */
|
||||
#define CPUFREQ_CONST_LOOPS (1 << 1) /* loops_per_jiffy or other
|
||||
kernel "constants" aren't
|
||||
affected by frequency
|
||||
transitions */
|
||||
#define CPUFREQ_PM_NO_WARN (1 << 2) /* don't warn on suspend/resume
|
||||
speed mismatches */
|
||||
|
||||
/* driver isn't removed even if all ->init() calls failed */
|
||||
#define CPUFREQ_STICKY BIT(0)
|
||||
|
||||
/* loops_per_jiffy or other kernel "constants" aren't affected by frequency transitions */
|
||||
#define CPUFREQ_CONST_LOOPS BIT(1)
|
||||
|
||||
/* don't warn on suspend/resume speed mismatches */
|
||||
#define CPUFREQ_PM_NO_WARN BIT(2)
|
||||
|
||||
/*
|
||||
* This should be set by platforms having multiple clock-domains, i.e.
|
||||
@@ -361,14 +359,14 @@ struct cpufreq_driver {
|
||||
* be created in cpu/cpu<num>/cpufreq/ directory and so they can use the same
|
||||
* governor with different tunables for different clusters.
|
||||
*/
|
||||
#define CPUFREQ_HAVE_GOVERNOR_PER_POLICY (1 << 3)
|
||||
#define CPUFREQ_HAVE_GOVERNOR_PER_POLICY BIT(3)
|
||||
|
||||
/*
|
||||
* Driver will do POSTCHANGE notifications from outside of their ->target()
|
||||
* routine and so must set cpufreq_driver->flags with this flag, so that core
|
||||
* can handle them specially.
|
||||
*/
|
||||
#define CPUFREQ_ASYNC_NOTIFICATION (1 << 4)
|
||||
#define CPUFREQ_ASYNC_NOTIFICATION BIT(4)
|
||||
|
||||
/*
|
||||
* Set by drivers which want cpufreq core to check if CPU is running at a
|
||||
@@ -377,13 +375,19 @@ struct cpufreq_driver {
|
||||
* from the table. And if that fails, we will stop further boot process by
|
||||
* issuing a BUG_ON().
|
||||
*/
|
||||
#define CPUFREQ_NEED_INITIAL_FREQ_CHECK (1 << 5)
|
||||
#define CPUFREQ_NEED_INITIAL_FREQ_CHECK BIT(5)
|
||||
|
||||
/*
|
||||
* Set by drivers to disallow use of governors with "dynamic_switching" flag
|
||||
* set.
|
||||
*/
|
||||
#define CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING (1 << 6)
|
||||
#define CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING BIT(6)
|
||||
|
||||
/*
|
||||
* Set by drivers that want the core to automatically register the cpufreq
|
||||
* driver as a thermal cooling device.
|
||||
*/
|
||||
#define CPUFREQ_IS_COOLING_DEV BIT(7)
|
||||
|
||||
int cpufreq_register_driver(struct cpufreq_driver *driver_data);
|
||||
int cpufreq_unregister_driver(struct cpufreq_driver *driver_data);
|
||||
|
@@ -121,6 +121,7 @@ enum cpuhp_state {
|
||||
CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING,
|
||||
CPUHP_AP_ARM_TWD_STARTING,
|
||||
CPUHP_AP_QCOM_TIMER_STARTING,
|
||||
CPUHP_AP_TEGRA_TIMER_STARTING,
|
||||
CPUHP_AP_ARMADA_TIMER_STARTING,
|
||||
CPUHP_AP_MARCO_TIMER_STARTING,
|
||||
CPUHP_AP_MIPS_GIC_TIMER_STARTING,
|
||||
|
@@ -69,11 +69,9 @@ struct cpuidle_state {
|
||||
|
||||
/* Idle State Flags */
|
||||
#define CPUIDLE_FLAG_NONE (0x00)
|
||||
#define CPUIDLE_FLAG_POLLING (0x01) /* polling state */
|
||||
#define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */
|
||||
#define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */
|
||||
|
||||
#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
|
||||
#define CPUIDLE_FLAG_POLLING BIT(0) /* polling state */
|
||||
#define CPUIDLE_FLAG_COUPLED BIT(1) /* state applies to multiple cpus */
|
||||
#define CPUIDLE_FLAG_TIMER_STOP BIT(2) /* timer is stopped on this state */
|
||||
|
||||
struct cpuidle_device_kobj;
|
||||
struct cpuidle_state_kobj;
|
||||
|
@@ -15,7 +15,6 @@
|
||||
#include <linux/capability.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/key.h>
|
||||
#include <linux/selinux.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/uidgid.h>
|
||||
#include <linux/sched.h>
|
||||
|
@@ -118,7 +118,7 @@
|
||||
#define CRYPTO_TFM_REQ_MASK 0x000fff00
|
||||
#define CRYPTO_TFM_RES_MASK 0xfff00000
|
||||
|
||||
#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
|
||||
#define CRYPTO_TFM_REQ_FORBID_WEAK_KEYS 0x00000100
|
||||
#define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200
|
||||
#define CRYPTO_TFM_REQ_MAY_BACKLOG 0x00000400
|
||||
#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
|
||||
@@ -188,14 +188,6 @@ struct blkcipher_desc {
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct cipher_desc {
|
||||
struct crypto_tfm *tfm;
|
||||
void (*crfn)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
|
||||
unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst,
|
||||
const u8 *src, unsigned int nbytes);
|
||||
void *info;
|
||||
};
|
||||
|
||||
/**
|
||||
* DOC: Block Cipher Algorithm Definitions
|
||||
*
|
||||
|
@@ -46,5 +46,4 @@ enum {
|
||||
EMAC_VERSION_2, /* DM646x */
|
||||
};
|
||||
|
||||
void davinci_get_mac_addr(struct nvmem_device *nvmem, void *context);
|
||||
#endif
|
||||
|
@@ -55,6 +55,7 @@ static inline void ndelay(unsigned long x)
|
||||
|
||||
extern unsigned long lpj_fine;
|
||||
void calibrate_delay(void);
|
||||
void __attribute__((weak)) calibration_delay_done(void);
|
||||
void msleep(unsigned int msecs);
|
||||
unsigned long msleep_interruptible(unsigned int msecs);
|
||||
void usleep_range(unsigned long min, unsigned long max);
|
||||
|
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <linux/bio.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/dm-ioctl.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/ratelimit.h>
|
||||
|
||||
@@ -315,12 +316,6 @@ struct dm_target {
|
||||
* whether or not its underlying devices have support.
|
||||
*/
|
||||
bool discards_supported:1;
|
||||
|
||||
/*
|
||||
* Set if the target required discard bios to be split
|
||||
* on max_io_len boundary.
|
||||
*/
|
||||
bool split_discard_bios:1;
|
||||
};
|
||||
|
||||
/* Each target can link one of these into the table */
|
||||
@@ -431,6 +426,14 @@ void dm_remap_zone_report(struct dm_target *ti, sector_t start,
|
||||
struct blk_zone *zones, unsigned int *nr_zones);
|
||||
union map_info *dm_get_rq_mapinfo(struct request *rq);
|
||||
|
||||
/*
|
||||
* Device mapper functions to parse and create devices specified by the
|
||||
* parameter "dm-mod.create="
|
||||
*/
|
||||
int __init dm_early_create(struct dm_ioctl *dmi,
|
||||
struct dm_target_spec **spec_array,
|
||||
char **target_params_array);
|
||||
|
||||
struct queue_limits *dm_get_queue_limits(struct mapped_device *md);
|
||||
|
||||
/*
|
||||
@@ -609,7 +612,7 @@ do { \
|
||||
*/
|
||||
#define dm_target_offset(ti, sector) ((sector) - (ti)->begin)
|
||||
|
||||
static inline sector_t to_sector(unsigned long n)
|
||||
static inline sector_t to_sector(unsigned long long n)
|
||||
{
|
||||
return (n >> SECTOR_SHIFT);
|
||||
}
|
||||
|
@@ -341,6 +341,7 @@ struct device *driver_find_device(struct device_driver *drv,
|
||||
struct device *start, void *data,
|
||||
int (*match)(struct device *dev, void *data));
|
||||
|
||||
void driver_deferred_probe_add(struct device *dev);
|
||||
int driver_deferred_probe_check_state(struct device *dev);
|
||||
|
||||
/**
|
||||
@@ -757,11 +758,17 @@ struct device_dma_parameters {
|
||||
|
||||
/**
|
||||
* struct device_connection - Device Connection Descriptor
|
||||
* @fwnode: The device node of the connected device
|
||||
* @endpoint: The names of the two devices connected together
|
||||
* @id: Unique identifier for the connection
|
||||
* @list: List head, private, for internal use only
|
||||
*
|
||||
* NOTE: @fwnode is not used together with @endpoint. @fwnode is used when
|
||||
* platform firmware defines the connection. When the connection is registered
|
||||
* with device_connection_add() @endpoint is used instead.
|
||||
*/
|
||||
struct device_connection {
|
||||
struct fwnode_handle *fwnode;
|
||||
const char *endpoint[2];
|
||||
const char *id;
|
||||
struct list_head list;
|
||||
@@ -827,12 +834,14 @@ enum device_link_state {
|
||||
* PM_RUNTIME: If set, the runtime PM framework will use this link.
|
||||
* RPM_ACTIVE: Run pm_runtime_get_sync() on the supplier during link creation.
|
||||
* AUTOREMOVE_SUPPLIER: Remove the link automatically on supplier driver unbind.
|
||||
* AUTOPROBE_CONSUMER: Probe consumer driver automatically after supplier binds.
|
||||
*/
|
||||
#define DL_FLAG_STATELESS BIT(0)
|
||||
#define DL_FLAG_AUTOREMOVE_CONSUMER BIT(1)
|
||||
#define DL_FLAG_PM_RUNTIME BIT(2)
|
||||
#define DL_FLAG_RPM_ACTIVE BIT(3)
|
||||
#define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4)
|
||||
#define DL_FLAG_AUTOPROBE_CONSUMER BIT(5)
|
||||
|
||||
/**
|
||||
* struct device_link - Device link representation.
|
||||
@@ -845,6 +854,7 @@ enum device_link_state {
|
||||
* @rpm_active: Whether or not the consumer device is runtime-PM-active.
|
||||
* @kref: Count repeated addition of the same link.
|
||||
* @rcu_head: An RCU head to use for deferred execution of SRCU callbacks.
|
||||
* @supplier_preactivated: Supplier has been made active before consumer probe.
|
||||
*/
|
||||
struct device_link {
|
||||
struct device *supplier;
|
||||
@@ -853,11 +863,12 @@ struct device_link {
|
||||
struct list_head c_node;
|
||||
enum device_link_state status;
|
||||
u32 flags;
|
||||
bool rpm_active;
|
||||
refcount_t rpm_active;
|
||||
struct kref kref;
|
||||
#ifdef CONFIG_SRCU
|
||||
struct rcu_head rcu_head;
|
||||
#endif
|
||||
bool supplier_preactivated; /* Owned by consumer probe. */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -985,7 +996,7 @@ struct device {
|
||||
void *platform_data; /* Platform specific data, device
|
||||
core doesn't touch it */
|
||||
void *driver_data; /* Driver data, set and get with
|
||||
dev_set/get_drvdata */
|
||||
dev_set_drvdata/dev_get_drvdata */
|
||||
struct dev_links_info links;
|
||||
struct dev_pm_info power;
|
||||
struct dev_pm_domain *pm_domain;
|
||||
@@ -1017,8 +1028,10 @@ struct device {
|
||||
|
||||
struct list_head dma_pools; /* dma pools (if dma'ble) */
|
||||
|
||||
#ifdef CONFIG_DMA_DECLARE_COHERENT
|
||||
struct dma_coherent_mem *dma_mem; /* internal for coherent mem
|
||||
override */
|
||||
#endif
|
||||
#ifdef CONFIG_DMA_CMA
|
||||
struct cma *cma_area; /* contiguous memory area for dma
|
||||
allocations */
|
||||
@@ -1035,7 +1048,6 @@ struct device {
|
||||
spinlock_t devres_lock;
|
||||
struct list_head devres_head;
|
||||
|
||||
struct klist_node knode_class;
|
||||
struct class *class;
|
||||
const struct attribute_group **groups; /* optional groups */
|
||||
|
||||
@@ -1095,7 +1107,7 @@ static inline void set_dev_node(struct device *dev, int node)
|
||||
#else
|
||||
static inline int dev_to_node(struct device *dev)
|
||||
{
|
||||
return -1;
|
||||
return NUMA_NO_NODE;
|
||||
}
|
||||
static inline void set_dev_node(struct device *dev, int node)
|
||||
{
|
||||
@@ -1165,6 +1177,16 @@ static inline bool device_async_suspend_enabled(struct device *dev)
|
||||
return !!dev->power.async_suspend;
|
||||
}
|
||||
|
||||
static inline bool device_pm_not_required(struct device *dev)
|
||||
{
|
||||
return dev->power.no_pm;
|
||||
}
|
||||
|
||||
static inline void device_set_pm_not_required(struct device *dev)
|
||||
{
|
||||
dev->power.no_pm = true;
|
||||
}
|
||||
|
||||
static inline void dev_pm_syscore_device(struct device *dev, bool val)
|
||||
{
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -1382,28 +1404,28 @@ void device_link_remove(void *consumer, struct device *supplier);
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
|
||||
__printf(3, 0)
|
||||
__printf(3, 0) __cold
|
||||
int dev_vprintk_emit(int level, const struct device *dev,
|
||||
const char *fmt, va_list args);
|
||||
__printf(3, 4)
|
||||
__printf(3, 4) __cold
|
||||
int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
|
||||
|
||||
__printf(3, 4)
|
||||
__printf(3, 4) __cold
|
||||
void dev_printk(const char *level, const struct device *dev,
|
||||
const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
__printf(2, 3) __cold
|
||||
void _dev_emerg(const struct device *dev, const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
__printf(2, 3) __cold
|
||||
void _dev_alert(const struct device *dev, const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
__printf(2, 3) __cold
|
||||
void _dev_crit(const struct device *dev, const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
__printf(2, 3) __cold
|
||||
void _dev_err(const struct device *dev, const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
__printf(2, 3) __cold
|
||||
void _dev_warn(const struct device *dev, const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
__printf(2, 3) __cold
|
||||
void _dev_notice(const struct device *dev, const char *fmt, ...);
|
||||
__printf(2, 3)
|
||||
__printf(2, 3) __cold
|
||||
void _dev_info(const struct device *dev, const char *fmt, ...);
|
||||
|
||||
#else
|
||||
@@ -1548,7 +1570,7 @@ do { \
|
||||
DEFAULT_RATELIMIT_INTERVAL, \
|
||||
DEFAULT_RATELIMIT_BURST); \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \
|
||||
if (DYNAMIC_DEBUG_BRANCH(descriptor) && \
|
||||
__ratelimit(&_rs)) \
|
||||
__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \
|
||||
##__VA_ARGS__); \
|
||||
|
@@ -40,6 +40,7 @@ struct dma_fence_array_cb {
|
||||
* @num_fences: number of fences in the array
|
||||
* @num_pending: fences in the array still pending
|
||||
* @fences: array of the fences
|
||||
* @work: internal irq_work function
|
||||
*/
|
||||
struct dma_fence_array {
|
||||
struct dma_fence base;
|
||||
|
@@ -77,7 +77,7 @@ struct dma_fence {
|
||||
struct list_head cb_list;
|
||||
spinlock_t *lock;
|
||||
u64 context;
|
||||
unsigned seqno;
|
||||
u64 seqno;
|
||||
unsigned long flags;
|
||||
ktime_t timestamp;
|
||||
int error;
|
||||
@@ -244,7 +244,7 @@ struct dma_fence_ops {
|
||||
};
|
||||
|
||||
void dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
|
||||
spinlock_t *lock, u64 context, unsigned seqno);
|
||||
spinlock_t *lock, u64 context, u64 seqno);
|
||||
|
||||
void dma_fence_release(struct kref *kref);
|
||||
void dma_fence_free(struct dma_fence *fence);
|
||||
@@ -414,9 +414,17 @@ dma_fence_is_signaled(struct dma_fence *fence)
|
||||
* Returns true if f1 is chronologically later than f2. Both fences must be
|
||||
* from the same context, since a seqno is not common across contexts.
|
||||
*/
|
||||
static inline bool __dma_fence_is_later(u32 f1, u32 f2)
|
||||
static inline bool __dma_fence_is_later(u64 f1, u64 f2)
|
||||
{
|
||||
return (int)(f1 - f2) > 0;
|
||||
/* This is for backward compatibility with drivers which can only handle
|
||||
* 32bit sequence numbers. Use a 64bit compare when any of the higher
|
||||
* bits are none zero, otherwise use a 32bit compare with wrap around
|
||||
* handling.
|
||||
*/
|
||||
if (upper_32_bits(f1) || upper_32_bits(f2))
|
||||
return f1 > f2;
|
||||
|
||||
return (int)(lower_32_bits(f1) - lower_32_bits(f2)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -548,21 +556,21 @@ u64 dma_fence_context_alloc(unsigned num);
|
||||
do { \
|
||||
struct dma_fence *__ff = (f); \
|
||||
if (IS_ENABLED(CONFIG_DMA_FENCE_TRACE)) \
|
||||
pr_info("f %llu#%u: " fmt, \
|
||||
pr_info("f %llu#%llu: " fmt, \
|
||||
__ff->context, __ff->seqno, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define DMA_FENCE_WARN(f, fmt, args...) \
|
||||
do { \
|
||||
struct dma_fence *__ff = (f); \
|
||||
pr_warn("f %llu#%u: " fmt, __ff->context, __ff->seqno, \
|
||||
pr_warn("f %llu#%llu: " fmt, __ff->context, __ff->seqno,\
|
||||
##args); \
|
||||
} while (0)
|
||||
|
||||
#define DMA_FENCE_ERR(f, fmt, args...) \
|
||||
do { \
|
||||
struct dma_fence *__ff = (f); \
|
||||
pr_err("f %llu#%u: " fmt, __ff->context, __ff->seqno, \
|
||||
pr_err("f %llu#%llu: " fmt, __ff->context, __ff->seqno, \
|
||||
##args); \
|
||||
} while (0)
|
||||
|
||||
|
@@ -130,6 +130,7 @@ struct dma_map_ops {
|
||||
enum dma_data_direction direction);
|
||||
int (*dma_supported)(struct device *dev, u64 mask);
|
||||
u64 (*get_required_mask)(struct device *dev);
|
||||
size_t (*max_mapping_size)(struct device *dev);
|
||||
};
|
||||
|
||||
#define DMA_MAPPING_ERROR (~(dma_addr_t)0)
|
||||
@@ -153,7 +154,7 @@ static inline int is_device_dma_capable(struct device *dev)
|
||||
return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
|
||||
#ifdef CONFIG_DMA_DECLARE_COHERENT
|
||||
/*
|
||||
* These three functions are only for dma allocator.
|
||||
* Don't use them in device drivers.
|
||||
@@ -192,7 +193,7 @@ static inline int dma_mmap_from_global_coherent(struct vm_area_struct *vma,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
|
||||
#endif /* CONFIG_DMA_DECLARE_COHERENT */
|
||||
|
||||
static inline bool dma_is_direct(const struct dma_map_ops *ops)
|
||||
{
|
||||
@@ -208,6 +209,8 @@ dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
|
||||
unsigned long attrs);
|
||||
int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
|
||||
enum dma_data_direction dir, unsigned long attrs);
|
||||
dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr,
|
||||
size_t size, enum dma_data_direction dir, unsigned long attrs);
|
||||
|
||||
#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
|
||||
defined(CONFIG_SWIOTLB)
|
||||
@@ -257,6 +260,8 @@ static inline void dma_direct_sync_sg_for_cpu(struct device *dev,
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t dma_direct_max_mapping_size(struct device *dev);
|
||||
|
||||
#ifdef CONFIG_HAS_DMA
|
||||
#include <asm/dma-mapping.h>
|
||||
|
||||
@@ -346,19 +351,20 @@ static inline dma_addr_t dma_map_resource(struct device *dev,
|
||||
unsigned long attrs)
|
||||
{
|
||||
const struct dma_map_ops *ops = get_dma_ops(dev);
|
||||
dma_addr_t addr;
|
||||
dma_addr_t addr = DMA_MAPPING_ERROR;
|
||||
|
||||
BUG_ON(!valid_dma_direction(dir));
|
||||
|
||||
/* Don't allow RAM to be mapped */
|
||||
BUG_ON(pfn_valid(PHYS_PFN(phys_addr)));
|
||||
if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
|
||||
return DMA_MAPPING_ERROR;
|
||||
|
||||
addr = phys_addr;
|
||||
if (ops && ops->map_resource)
|
||||
if (dma_is_direct(ops))
|
||||
addr = dma_direct_map_resource(dev, phys_addr, size, dir, attrs);
|
||||
else if (ops->map_resource)
|
||||
addr = ops->map_resource(dev, phys_addr, size, dir, attrs);
|
||||
|
||||
debug_dma_map_resource(dev, phys_addr, size, dir, addr);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -369,7 +375,7 @@ static inline void dma_unmap_resource(struct device *dev, dma_addr_t addr,
|
||||
const struct dma_map_ops *ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!valid_dma_direction(dir));
|
||||
if (ops && ops->unmap_resource)
|
||||
if (!dma_is_direct(ops) && ops->unmap_resource)
|
||||
ops->unmap_resource(dev, addr, size, dir, attrs);
|
||||
debug_dma_unmap_resource(dev, addr, size, dir);
|
||||
}
|
||||
@@ -460,6 +466,7 @@ int dma_supported(struct device *dev, u64 mask);
|
||||
int dma_set_mask(struct device *dev, u64 mask);
|
||||
int dma_set_coherent_mask(struct device *dev, u64 mask);
|
||||
u64 dma_get_required_mask(struct device *dev);
|
||||
size_t dma_max_mapping_size(struct device *dev);
|
||||
#else /* CONFIG_HAS_DMA */
|
||||
static inline dma_addr_t dma_map_page_attrs(struct device *dev,
|
||||
struct page *page, size_t offset, size_t size,
|
||||
@@ -561,6 +568,10 @@ static inline u64 dma_get_required_mask(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline size_t dma_max_mapping_size(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_HAS_DMA */
|
||||
|
||||
static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
|
||||
@@ -668,15 +679,23 @@ static inline int dma_coerce_mask_and_coherent(struct device *dev, u64 mask)
|
||||
return dma_set_mask_and_coherent(dev, mask);
|
||||
}
|
||||
|
||||
#ifndef arch_setup_dma_ops
|
||||
#ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
|
||||
void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
|
||||
const struct iommu_ops *iommu, bool coherent);
|
||||
#else
|
||||
static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
|
||||
u64 size, const struct iommu_ops *iommu,
|
||||
bool coherent) { }
|
||||
#endif
|
||||
u64 size, const struct iommu_ops *iommu, bool coherent)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
|
||||
|
||||
#ifndef arch_teardown_dma_ops
|
||||
static inline void arch_teardown_dma_ops(struct device *dev) { }
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS
|
||||
void arch_teardown_dma_ops(struct device *dev);
|
||||
#else
|
||||
static inline void arch_teardown_dma_ops(struct device *dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS */
|
||||
|
||||
static inline unsigned int dma_get_max_seg_size(struct device *dev)
|
||||
{
|
||||
@@ -725,19 +744,14 @@ static inline int dma_get_cache_alignment(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags for the coherent memory api */
|
||||
#define DMA_MEMORY_EXCLUSIVE 0x01
|
||||
|
||||
#ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
|
||||
#ifdef CONFIG_DMA_DECLARE_COHERENT
|
||||
int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
|
||||
dma_addr_t device_addr, size_t size, int flags);
|
||||
dma_addr_t device_addr, size_t size);
|
||||
void dma_release_declared_memory(struct device *dev);
|
||||
void *dma_mark_declared_memory_occupied(struct device *dev,
|
||||
dma_addr_t device_addr, size_t size);
|
||||
#else
|
||||
static inline int
|
||||
dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
|
||||
dma_addr_t device_addr, size_t size, int flags)
|
||||
dma_addr_t device_addr, size_t size)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -746,14 +760,7 @@ static inline void
|
||||
dma_release_declared_memory(struct device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void *
|
||||
dma_mark_declared_memory_occupied(struct device *dev,
|
||||
dma_addr_t device_addr, size_t size)
|
||||
{
|
||||
return ERR_PTR(-EBUSY);
|
||||
}
|
||||
#endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
|
||||
#endif /* CONFIG_DMA_DECLARE_COHERENT */
|
||||
|
||||
static inline void *dmam_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t gfp)
|
||||
|
@@ -1,13 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Driver for the Synopsys DesignWare DMA Controller
|
||||
*
|
||||
* Copyright (C) 2007 Atmel Corporation
|
||||
* Copyright (C) 2010-2011 ST Microelectronics
|
||||
* Copyright (C) 2014 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _DMA_DW_H
|
||||
#define _DMA_DW_H
|
||||
@@ -45,9 +42,13 @@ struct dw_dma_chip {
|
||||
#if IS_ENABLED(CONFIG_DW_DMAC_CORE)
|
||||
int dw_dma_probe(struct dw_dma_chip *chip);
|
||||
int dw_dma_remove(struct dw_dma_chip *chip);
|
||||
int idma32_dma_probe(struct dw_dma_chip *chip);
|
||||
int idma32_dma_remove(struct dw_dma_chip *chip);
|
||||
#else
|
||||
static inline int dw_dma_probe(struct dw_dma_chip *chip) { return -ENODEV; }
|
||||
static inline int dw_dma_remove(struct dw_dma_chip *chip) { return 0; }
|
||||
static inline int idma32_dma_probe(struct dw_dma_chip *chip) { return -ENODEV; }
|
||||
static inline int idma32_dma_remove(struct dw_dma_chip *chip) { return 0; }
|
||||
#endif /* CONFIG_DW_DMAC_CORE */
|
||||
|
||||
#endif /* _DMA_DW_H */
|
||||
|
@@ -47,10 +47,10 @@ struct _ddebug {
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
|
||||
int ddebug_add_module(struct _ddebug *tab, unsigned int n,
|
||||
const char *modname);
|
||||
|
||||
#if defined(CONFIG_DYNAMIC_DEBUG)
|
||||
int ddebug_add_module(struct _ddebug *tab, unsigned int n,
|
||||
const char *modname);
|
||||
extern int ddebug_remove_module(const char *mod_name);
|
||||
extern __printf(2, 3)
|
||||
void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
|
||||
@@ -71,7 +71,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
|
||||
const struct net_device *dev,
|
||||
const char *fmt, ...);
|
||||
|
||||
#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init) \
|
||||
#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
|
||||
static struct _ddebug __aligned(8) \
|
||||
__attribute__((section("__verbose"))) name = { \
|
||||
.modname = KBUILD_MODNAME, \
|
||||
@@ -80,35 +80,27 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
|
||||
.format = (fmt), \
|
||||
.lineno = __LINE__, \
|
||||
.flags = _DPRINTK_FLAGS_DEFAULT, \
|
||||
dd_key_init(key, init) \
|
||||
_DPRINTK_KEY_INIT \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_JUMP_LABEL
|
||||
|
||||
#define dd_key_init(key, init) key = (init)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_true, \
|
||||
(STATIC_KEY_TRUE_INIT))
|
||||
|
||||
#define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)
|
||||
|
||||
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
|
||||
static_branch_likely(&descriptor.key.dd_key_true)
|
||||
#else
|
||||
#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \
|
||||
(STATIC_KEY_FALSE_INIT))
|
||||
#define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)
|
||||
|
||||
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
|
||||
static_branch_unlikely(&descriptor.key.dd_key_false)
|
||||
#endif
|
||||
|
||||
#else
|
||||
#else /* !HAVE_JUMP_LABEL */
|
||||
|
||||
#define dd_key_init(key, init)
|
||||
|
||||
#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0)
|
||||
#define _DPRINTK_KEY_INIT
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DYNAMIC_DEBUG_BRANCH(descriptor) \
|
||||
@@ -120,46 +112,66 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
|
||||
|
||||
#endif
|
||||
|
||||
#define dynamic_pr_debug(fmt, ...) \
|
||||
do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
|
||||
__dynamic_pr_debug(&descriptor, pr_fmt(fmt), \
|
||||
##__VA_ARGS__); \
|
||||
#define __dynamic_func_call(id, fmt, func, ...) do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
|
||||
if (DYNAMIC_DEBUG_BRANCH(id)) \
|
||||
func(&id, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define __dynamic_func_call_no_desc(id, fmt, func, ...) do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
|
||||
if (DYNAMIC_DEBUG_BRANCH(id)) \
|
||||
func(__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* "Factory macro" for generating a call to func, guarded by a
|
||||
* DYNAMIC_DEBUG_BRANCH. The dynamic debug decriptor will be
|
||||
* initialized using the fmt argument. The function will be called with
|
||||
* the address of the descriptor as first argument, followed by all
|
||||
* the varargs. Note that fmt is repeated in invocations of this
|
||||
* macro.
|
||||
*/
|
||||
#define _dynamic_func_call(fmt, func, ...) \
|
||||
__dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
|
||||
/*
|
||||
* A variant that does the same, except that the descriptor is not
|
||||
* passed as the first argument to the function; it is only called
|
||||
* with precisely the macro's varargs.
|
||||
*/
|
||||
#define _dynamic_func_call_no_desc(fmt, func, ...) \
|
||||
__dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
|
||||
|
||||
#define dynamic_pr_debug(fmt, ...) \
|
||||
_dynamic_func_call(fmt, __dynamic_pr_debug, \
|
||||
pr_fmt(fmt), ##__VA_ARGS__)
|
||||
|
||||
#define dynamic_dev_dbg(dev, fmt, ...) \
|
||||
do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
|
||||
__dynamic_dev_dbg(&descriptor, dev, fmt, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
_dynamic_func_call(fmt,__dynamic_dev_dbg, \
|
||||
dev, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define dynamic_netdev_dbg(dev, fmt, ...) \
|
||||
do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
|
||||
__dynamic_netdev_dbg(&descriptor, dev, fmt, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
_dynamic_func_call(fmt, __dynamic_netdev_dbg, \
|
||||
dev, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii) \
|
||||
do { \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \
|
||||
__builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\
|
||||
if (DYNAMIC_DEBUG_BRANCH(descriptor)) \
|
||||
print_hex_dump(KERN_DEBUG, prefix_str, \
|
||||
prefix_type, rowsize, groupsize, \
|
||||
buf, len, ascii); \
|
||||
} while (0)
|
||||
#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii) \
|
||||
_dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
|
||||
print_hex_dump, \
|
||||
KERN_DEBUG, prefix_str, prefix_type, \
|
||||
rowsize, groupsize, buf, len, ascii)
|
||||
|
||||
#else
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
static inline int ddebug_add_module(struct _ddebug *tab, unsigned int n,
|
||||
const char *modname)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ddebug_remove_module(const char *mod)
|
||||
{
|
||||
return 0;
|
||||
|
@@ -48,7 +48,20 @@ typedef u16 efi_char16_t; /* UNICODE character */
|
||||
typedef u64 efi_physical_addr_t;
|
||||
typedef void *efi_handle_t;
|
||||
|
||||
typedef guid_t efi_guid_t;
|
||||
/*
|
||||
* The UEFI spec and EDK2 reference implementation both define EFI_GUID as
|
||||
* struct { u32 a; u16; b; u16 c; u8 d[8]; }; and so the implied alignment
|
||||
* is 32 bits not 8 bits like our guid_t. In some cases (i.e., on 32-bit ARM),
|
||||
* this means that firmware services invoked by the kernel may assume that
|
||||
* efi_guid_t* arguments are 32-bit aligned, and use memory accessors that
|
||||
* do not tolerate misalignment. So let's set the minimum alignment to 32 bits.
|
||||
*
|
||||
* Note that the UEFI spec as well as some comments in the EDK2 code base
|
||||
* suggest that EFI_GUID should be 64-bit aligned, but this appears to be
|
||||
* a mistake, given that no code seems to exist that actually enforces that
|
||||
* or relies on it.
|
||||
*/
|
||||
typedef guid_t efi_guid_t __aligned(__alignof__(u32));
|
||||
|
||||
#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
|
||||
GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7)
|
||||
@@ -1600,6 +1613,7 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
|
||||
|
||||
bool efi_runtime_disabled(void);
|
||||
extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
|
||||
extern unsigned long efi_call_virt_save_flags(void);
|
||||
|
||||
enum efi_secureboot_mode {
|
||||
efi_secureboot_mode_unset,
|
||||
@@ -1645,7 +1659,7 @@ void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table);
|
||||
\
|
||||
arch_efi_call_virt_setup(); \
|
||||
\
|
||||
local_save_flags(__flags); \
|
||||
__flags = efi_call_virt_save_flags(); \
|
||||
__s = arch_efi_call_virt(p, f, args); \
|
||||
efi_call_virt_check_flags(__flags, __stringify(f)); \
|
||||
\
|
||||
@@ -1660,7 +1674,7 @@ void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table);
|
||||
\
|
||||
arch_efi_call_virt_setup(); \
|
||||
\
|
||||
local_save_flags(__flags); \
|
||||
__flags = efi_call_virt_save_flags(); \
|
||||
arch_efi_call_virt(p, f, args); \
|
||||
efi_call_virt_check_flags(__flags, __stringify(f)); \
|
||||
\
|
||||
@@ -1699,19 +1713,19 @@ extern int efi_tpm_eventlog_init(void);
|
||||
* fault happened while executing an efi runtime service.
|
||||
*/
|
||||
enum efi_rts_ids {
|
||||
NONE,
|
||||
GET_TIME,
|
||||
SET_TIME,
|
||||
GET_WAKEUP_TIME,
|
||||
SET_WAKEUP_TIME,
|
||||
GET_VARIABLE,
|
||||
GET_NEXT_VARIABLE,
|
||||
SET_VARIABLE,
|
||||
QUERY_VARIABLE_INFO,
|
||||
GET_NEXT_HIGH_MONO_COUNT,
|
||||
RESET_SYSTEM,
|
||||
UPDATE_CAPSULE,
|
||||
QUERY_CAPSULE_CAPS,
|
||||
EFI_NONE,
|
||||
EFI_GET_TIME,
|
||||
EFI_SET_TIME,
|
||||
EFI_GET_WAKEUP_TIME,
|
||||
EFI_SET_WAKEUP_TIME,
|
||||
EFI_GET_VARIABLE,
|
||||
EFI_GET_NEXT_VARIABLE,
|
||||
EFI_SET_VARIABLE,
|
||||
EFI_QUERY_VARIABLE_INFO,
|
||||
EFI_GET_NEXT_HIGH_MONO_COUNT,
|
||||
EFI_RESET_SYSTEM,
|
||||
EFI_UPDATE_CAPSULE,
|
||||
EFI_QUERY_CAPSULE_CAPS,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
|
||||
#define EPROBE_DEFER 517 /* Driver requests probe retry */
|
||||
#define EOPENSTALE 518 /* open found a stale dentry */
|
||||
#define ENOPARAM 519 /* Parameter not supported */
|
||||
|
||||
/* Defined for the NFSv3 protocol */
|
||||
#define EBADHANDLE 521 /* Illegal NFS file handle */
|
||||
|
@@ -44,6 +44,7 @@ int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh,
|
||||
__be16 type);
|
||||
void eth_header_cache_update(struct hh_cache *hh, const struct net_device *dev,
|
||||
const unsigned char *haddr);
|
||||
__be16 eth_header_parse_protocol(const struct sk_buff *skb);
|
||||
int eth_prepare_mac_addr_change(struct net_device *dev, void *p);
|
||||
void eth_commit_mac_addr_change(struct net_device *dev, void *p);
|
||||
int eth_mac_addr(struct net_device *dev, void *p);
|
||||
|
@@ -98,10 +98,6 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings)
|
||||
return index % n_rx_rings;
|
||||
}
|
||||
|
||||
/* number of link mode bits/ulongs handled internally by kernel */
|
||||
#define __ETHTOOL_LINK_MODE_MASK_NBITS \
|
||||
(__ETHTOOL_LINK_MODE_LAST + 1)
|
||||
|
||||
/* declare a link mode bitmap */
|
||||
#define __ETHTOOL_DECLARE_LINK_MODE_MASK(name) \
|
||||
DECLARE_BITMAP(name, __ETHTOOL_LINK_MODE_MASK_NBITS)
|
||||
@@ -400,4 +396,19 @@ struct ethtool_ops {
|
||||
void (*get_ethtool_phy_stats)(struct net_device *,
|
||||
struct ethtool_stats *, u64 *);
|
||||
};
|
||||
|
||||
struct ethtool_rx_flow_rule {
|
||||
struct flow_rule *rule;
|
||||
unsigned long priv[0];
|
||||
};
|
||||
|
||||
struct ethtool_rx_flow_spec_input {
|
||||
const struct ethtool_rx_flow_spec *fs;
|
||||
u32 rss_ctx;
|
||||
};
|
||||
|
||||
struct ethtool_rx_flow_rule *
|
||||
ethtool_rx_flow_rule_create(const struct ethtool_rx_flow_spec_input *input);
|
||||
void ethtool_rx_flow_rule_destroy(struct ethtool_rx_flow_rule *rule);
|
||||
|
||||
#endif /* _LINUX_ETHTOOL_H */
|
||||
|
@@ -116,6 +116,7 @@ struct f2fs_super_block {
|
||||
/*
|
||||
* For checkpoint
|
||||
*/
|
||||
#define CP_DISABLED_QUICK_FLAG 0x00002000
|
||||
#define CP_DISABLED_FLAG 0x00001000
|
||||
#define CP_QUOTA_NEED_FSCK_FLAG 0x00000800
|
||||
#define CP_LARGE_NAT_BITMAP_FLAG 0x00000400
|
||||
@@ -186,7 +187,7 @@ struct f2fs_orphan_block {
|
||||
struct f2fs_extent {
|
||||
__le32 fofs; /* start file offset of the extent */
|
||||
__le32 blk; /* start block address of the extent */
|
||||
__le32 len; /* lengh of the extent */
|
||||
__le32 len; /* length of the extent */
|
||||
} __packed;
|
||||
|
||||
#define F2FS_NAME_LEN 255
|
||||
@@ -284,7 +285,7 @@ enum {
|
||||
|
||||
struct node_footer {
|
||||
__le32 nid; /* node id */
|
||||
__le32 ino; /* inode nunmber */
|
||||
__le32 ino; /* inode number */
|
||||
__le32 flag; /* include cold/fsync/dentry marks and offset */
|
||||
__le64 cp_ver; /* checkpoint version */
|
||||
__le32 next_blkaddr; /* next node page block address */
|
||||
@@ -489,12 +490,12 @@ typedef __le32 f2fs_hash_t;
|
||||
|
||||
/*
|
||||
* space utilization of regular dentry and inline dentry (w/o extra reservation)
|
||||
* regular dentry inline dentry
|
||||
* bitmap 1 * 27 = 27 1 * 23 = 23
|
||||
* reserved 1 * 3 = 3 1 * 7 = 7
|
||||
* dentry 11 * 214 = 2354 11 * 182 = 2002
|
||||
* filename 8 * 214 = 1712 8 * 182 = 1456
|
||||
* total 4096 3488
|
||||
* regular dentry inline dentry (def) inline dentry (min)
|
||||
* bitmap 1 * 27 = 27 1 * 23 = 23 1 * 1 = 1
|
||||
* reserved 1 * 3 = 3 1 * 7 = 7 1 * 1 = 1
|
||||
* dentry 11 * 214 = 2354 11 * 182 = 2002 11 * 2 = 22
|
||||
* filename 8 * 214 = 1712 8 * 182 = 1456 8 * 2 = 16
|
||||
* total 4096 3488 40
|
||||
*
|
||||
* Note: there are more reserved space in inline dentry than in regular
|
||||
* dentry, when converting inline dentry we should handle this carefully.
|
||||
@@ -506,12 +507,13 @@ typedef __le32 f2fs_hash_t;
|
||||
#define SIZE_OF_RESERVED (PAGE_SIZE - ((SIZE_OF_DIR_ENTRY + \
|
||||
F2FS_SLOT_LEN) * \
|
||||
NR_DENTRY_IN_BLOCK + SIZE_OF_DENTRY_BITMAP))
|
||||
#define MIN_INLINE_DENTRY_SIZE 40 /* just include '.' and '..' entries */
|
||||
|
||||
/* One directory entry slot representing F2FS_SLOT_LEN-sized file name */
|
||||
struct f2fs_dir_entry {
|
||||
__le32 hash_code; /* hash code of file name */
|
||||
__le32 ino; /* inode number */
|
||||
__le16 name_len; /* lengh of file name */
|
||||
__le16 name_len; /* length of file name */
|
||||
__u8 file_type; /* file type */
|
||||
} __packed;
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
FAN_CLASS_PRE_CONTENT)
|
||||
|
||||
#define FANOTIFY_INIT_FLAGS (FANOTIFY_CLASS_BITS | \
|
||||
FAN_REPORT_TID | \
|
||||
FAN_REPORT_TID | FAN_REPORT_FID | \
|
||||
FAN_CLOEXEC | FAN_NONBLOCK | \
|
||||
FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
|
||||
|
||||
@@ -35,10 +35,28 @@
|
||||
FAN_MARK_IGNORED_SURV_MODIFY | \
|
||||
FAN_MARK_FLUSH)
|
||||
|
||||
/* Events that user can request to be notified on */
|
||||
#define FANOTIFY_EVENTS (FAN_ACCESS | FAN_MODIFY | \
|
||||
/*
|
||||
* Events that can be reported with data type FSNOTIFY_EVENT_PATH.
|
||||
* Note that FAN_MODIFY can also be reported with data type
|
||||
* FSNOTIFY_EVENT_INODE.
|
||||
*/
|
||||
#define FANOTIFY_PATH_EVENTS (FAN_ACCESS | FAN_MODIFY | \
|
||||
FAN_CLOSE | FAN_OPEN | FAN_OPEN_EXEC)
|
||||
|
||||
/*
|
||||
* Directory entry modification events - reported only to directory
|
||||
* where entry is modified and not to a watching parent.
|
||||
*/
|
||||
#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE)
|
||||
|
||||
/* Events that can only be reported with data type FSNOTIFY_EVENT_INODE */
|
||||
#define FANOTIFY_INODE_EVENTS (FANOTIFY_DIRENT_EVENTS | \
|
||||
FAN_ATTRIB | FAN_MOVE_SELF | FAN_DELETE_SELF)
|
||||
|
||||
/* Events that user can request to be notified on */
|
||||
#define FANOTIFY_EVENTS (FANOTIFY_PATH_EVENTS | \
|
||||
FANOTIFY_INODE_EVENTS)
|
||||
|
||||
/* Events that require a permission response from user */
|
||||
#define FANOTIFY_PERM_EVENTS (FAN_OPEN_PERM | FAN_ACCESS_PERM | \
|
||||
FAN_OPEN_EXEC_PERM)
|
||||
@@ -49,7 +67,7 @@
|
||||
/* Events that may be reported to user */
|
||||
#define FANOTIFY_OUTGOING_EVENTS (FANOTIFY_EVENTS | \
|
||||
FANOTIFY_PERM_EVENTS | \
|
||||
FAN_Q_OVERFLOW)
|
||||
FAN_Q_OVERFLOW | FAN_ONDIR)
|
||||
|
||||
#define ALL_FANOTIFY_EVENT_BITS (FANOTIFY_OUTGOING_EVENTS | \
|
||||
FANOTIFY_EVENT_FLAGS)
|
||||
|
@@ -12,7 +12,7 @@
|
||||
O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
|
||||
|
||||
#ifndef force_o_largefile
|
||||
#define force_o_largefile() (BITS_PER_LONG != 32)
|
||||
#define force_o_largefile() (!IS_ENABLED(CONFIG_ARCH_32BIT_OFF_T))
|
||||
#endif
|
||||
|
||||
#if BITS_PER_LONG == 32
|
||||
|
@@ -13,6 +13,7 @@
|
||||
struct file;
|
||||
|
||||
extern void fput(struct file *);
|
||||
extern void fput_many(struct file *, unsigned int);
|
||||
|
||||
struct file_operations;
|
||||
struct vfsmount;
|
||||
@@ -44,6 +45,7 @@ static inline void fdput(struct fd fd)
|
||||
}
|
||||
|
||||
extern struct file *fget(unsigned int fd);
|
||||
extern struct file *fget_many(unsigned int fd, unsigned int refs);
|
||||
extern struct file *fget_raw(unsigned int fd);
|
||||
extern unsigned long __fdget(unsigned int fd);
|
||||
extern unsigned long __fdget_raw(unsigned int fd);
|
||||
|
@@ -277,6 +277,26 @@ struct sock_reuseport;
|
||||
.off = OFF, \
|
||||
.imm = IMM })
|
||||
|
||||
/* Like BPF_JMP_REG, but with 32-bit wide operands for comparison. */
|
||||
|
||||
#define BPF_JMP32_REG(OP, DST, SRC, OFF) \
|
||||
((struct bpf_insn) { \
|
||||
.code = BPF_JMP32 | BPF_OP(OP) | BPF_X, \
|
||||
.dst_reg = DST, \
|
||||
.src_reg = SRC, \
|
||||
.off = OFF, \
|
||||
.imm = 0 })
|
||||
|
||||
/* Like BPF_JMP_IMM, but with 32-bit wide operands for comparison. */
|
||||
|
||||
#define BPF_JMP32_IMM(OP, DST, IMM, OFF) \
|
||||
((struct bpf_insn) { \
|
||||
.code = BPF_JMP32 | BPF_OP(OP) | BPF_K, \
|
||||
.dst_reg = DST, \
|
||||
.src_reg = 0, \
|
||||
.off = OFF, \
|
||||
.imm = IMM })
|
||||
|
||||
/* Unconditional jumps, goto pc + off16 */
|
||||
|
||||
#define BPF_JMP_A(OFF) \
|
||||
@@ -513,7 +533,24 @@ struct sk_filter {
|
||||
struct bpf_prog *prog;
|
||||
};
|
||||
|
||||
#define BPF_PROG_RUN(filter, ctx) (*(filter)->bpf_func)(ctx, (filter)->insnsi)
|
||||
DECLARE_STATIC_KEY_FALSE(bpf_stats_enabled_key);
|
||||
|
||||
#define BPF_PROG_RUN(prog, ctx) ({ \
|
||||
u32 ret; \
|
||||
cant_sleep(); \
|
||||
if (static_branch_unlikely(&bpf_stats_enabled_key)) { \
|
||||
struct bpf_prog_stats *stats; \
|
||||
u64 start = sched_clock(); \
|
||||
ret = (*(prog)->bpf_func)(ctx, (prog)->insnsi); \
|
||||
stats = this_cpu_ptr(prog->aux->stats); \
|
||||
u64_stats_update_begin(&stats->syncp); \
|
||||
stats->cnt++; \
|
||||
stats->nsecs += sched_clock() - start; \
|
||||
u64_stats_update_end(&stats->syncp); \
|
||||
} else { \
|
||||
ret = (*(prog)->bpf_func)(ctx, (prog)->insnsi); \
|
||||
} \
|
||||
ret; })
|
||||
|
||||
#define BPF_SKB_CB_LEN QDISC_CB_PRIV_LEN
|
||||
|
||||
@@ -744,6 +781,7 @@ void bpf_prog_free_jited_linfo(struct bpf_prog *prog);
|
||||
void bpf_prog_free_unused_jited_linfo(struct bpf_prog *prog);
|
||||
|
||||
struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags);
|
||||
struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flags);
|
||||
struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,
|
||||
gfp_t gfp_extra_flags);
|
||||
void __bpf_prog_free(struct bpf_prog *fp);
|
||||
@@ -793,6 +831,7 @@ static inline bool bpf_dump_raw_ok(void)
|
||||
|
||||
struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
|
||||
const struct bpf_insn *patch, u32 len);
|
||||
int bpf_remove_insns(struct bpf_prog *prog, u32 off, u32 cnt);
|
||||
|
||||
void bpf_clear_redirect_map(struct bpf_map *map);
|
||||
|
||||
@@ -874,7 +913,9 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
|
||||
unsigned int alignment,
|
||||
bpf_jit_fill_hole_t bpf_fill_ill_insns);
|
||||
void bpf_jit_binary_free(struct bpf_binary_header *hdr);
|
||||
|
||||
u64 bpf_jit_alloc_exec_limit(void);
|
||||
void *bpf_jit_alloc_exec(unsigned long size);
|
||||
void bpf_jit_free_exec(void *addr);
|
||||
void bpf_jit_free(struct bpf_prog *fp);
|
||||
|
||||
int bpf_jit_get_func_addr(const struct bpf_prog *prog,
|
||||
@@ -966,6 +1007,7 @@ bpf_address_lookup(unsigned long addr, unsigned long *size,
|
||||
|
||||
void bpf_prog_kallsyms_add(struct bpf_prog *fp);
|
||||
void bpf_prog_kallsyms_del(struct bpf_prog *fp);
|
||||
void bpf_get_prog_name(const struct bpf_prog *prog, char *sym);
|
||||
|
||||
#else /* CONFIG_BPF_JIT */
|
||||
|
||||
@@ -1021,6 +1063,12 @@ static inline void bpf_prog_kallsyms_add(struct bpf_prog *fp)
|
||||
static inline void bpf_prog_kallsyms_del(struct bpf_prog *fp)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void bpf_get_prog_name(const struct bpf_prog *prog, char *sym)
|
||||
{
|
||||
sym[0] = '\0';
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BPF_JIT */
|
||||
|
||||
void bpf_prog_kallsyms_del_subprogs(struct bpf_prog *fp);
|
||||
|
@@ -52,4 +52,7 @@ int imx_sc_misc_set_control(struct imx_sc_ipc *ipc, u32 resource,
|
||||
int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 resource,
|
||||
u8 ctrl, u32 *val);
|
||||
|
||||
int imx_sc_pm_cpu_start(struct imx_sc_ipc *ipc, u32 resource,
|
||||
bool enable, u64 phys_addr);
|
||||
|
||||
#endif /* _SC_MISC_API_H */
|
||||
|
@@ -28,12 +28,35 @@
|
||||
/* SMC SIP service Call Function Identifier Prefix */
|
||||
#define PM_SIP_SVC 0xC2000000
|
||||
#define PM_GET_TRUSTZONE_VERSION 0xa03
|
||||
#define PM_SET_SUSPEND_MODE 0xa02
|
||||
#define GET_CALLBACK_DATA 0xa01
|
||||
|
||||
/* Number of 32bits values in payload */
|
||||
#define PAYLOAD_ARG_CNT 4U
|
||||
|
||||
/* Number of arguments for a callback */
|
||||
#define CB_ARG_CNT 4
|
||||
|
||||
/* Payload size (consists of callback API ID + arguments) */
|
||||
#define CB_PAYLOAD_SIZE (CB_ARG_CNT + 1)
|
||||
|
||||
#define ZYNQMP_PM_MAX_QOS 100U
|
||||
|
||||
/* Node capabilities */
|
||||
#define ZYNQMP_PM_CAPABILITY_ACCESS 0x1U
|
||||
#define ZYNQMP_PM_CAPABILITY_CONTEXT 0x2U
|
||||
#define ZYNQMP_PM_CAPABILITY_WAKEUP 0x4U
|
||||
#define ZYNQMP_PM_CAPABILITY_POWER 0x8U
|
||||
|
||||
enum pm_api_id {
|
||||
PM_GET_API_VERSION = 1,
|
||||
PM_REQUEST_NODE = 13,
|
||||
PM_RELEASE_NODE,
|
||||
PM_SET_REQUIREMENT,
|
||||
PM_RESET_ASSERT = 17,
|
||||
PM_RESET_GET_STATUS,
|
||||
PM_PM_INIT_FINALIZE = 21,
|
||||
PM_GET_CHIPID = 24,
|
||||
PM_IOCTL = 34,
|
||||
PM_QUERY_DATA,
|
||||
PM_CLOCK_ENABLE,
|
||||
@@ -75,6 +98,149 @@ enum pm_query_id {
|
||||
PM_QID_CLOCK_GET_NUM_CLOCKS = 12,
|
||||
};
|
||||
|
||||
enum zynqmp_pm_reset_action {
|
||||
PM_RESET_ACTION_RELEASE,
|
||||
PM_RESET_ACTION_ASSERT,
|
||||
PM_RESET_ACTION_PULSE,
|
||||
};
|
||||
|
||||
enum zynqmp_pm_reset {
|
||||
ZYNQMP_PM_RESET_START = 1000,
|
||||
ZYNQMP_PM_RESET_PCIE_CFG = ZYNQMP_PM_RESET_START,
|
||||
ZYNQMP_PM_RESET_PCIE_BRIDGE,
|
||||
ZYNQMP_PM_RESET_PCIE_CTRL,
|
||||
ZYNQMP_PM_RESET_DP,
|
||||
ZYNQMP_PM_RESET_SWDT_CRF,
|
||||
ZYNQMP_PM_RESET_AFI_FM5,
|
||||
ZYNQMP_PM_RESET_AFI_FM4,
|
||||
ZYNQMP_PM_RESET_AFI_FM3,
|
||||
ZYNQMP_PM_RESET_AFI_FM2,
|
||||
ZYNQMP_PM_RESET_AFI_FM1,
|
||||
ZYNQMP_PM_RESET_AFI_FM0,
|
||||
ZYNQMP_PM_RESET_GDMA,
|
||||
ZYNQMP_PM_RESET_GPU_PP1,
|
||||
ZYNQMP_PM_RESET_GPU_PP0,
|
||||
ZYNQMP_PM_RESET_GPU,
|
||||
ZYNQMP_PM_RESET_GT,
|
||||
ZYNQMP_PM_RESET_SATA,
|
||||
ZYNQMP_PM_RESET_ACPU3_PWRON,
|
||||
ZYNQMP_PM_RESET_ACPU2_PWRON,
|
||||
ZYNQMP_PM_RESET_ACPU1_PWRON,
|
||||
ZYNQMP_PM_RESET_ACPU0_PWRON,
|
||||
ZYNQMP_PM_RESET_APU_L2,
|
||||
ZYNQMP_PM_RESET_ACPU3,
|
||||
ZYNQMP_PM_RESET_ACPU2,
|
||||
ZYNQMP_PM_RESET_ACPU1,
|
||||
ZYNQMP_PM_RESET_ACPU0,
|
||||
ZYNQMP_PM_RESET_DDR,
|
||||
ZYNQMP_PM_RESET_APM_FPD,
|
||||
ZYNQMP_PM_RESET_SOFT,
|
||||
ZYNQMP_PM_RESET_GEM0,
|
||||
ZYNQMP_PM_RESET_GEM1,
|
||||
ZYNQMP_PM_RESET_GEM2,
|
||||
ZYNQMP_PM_RESET_GEM3,
|
||||
ZYNQMP_PM_RESET_QSPI,
|
||||
ZYNQMP_PM_RESET_UART0,
|
||||
ZYNQMP_PM_RESET_UART1,
|
||||
ZYNQMP_PM_RESET_SPI0,
|
||||
ZYNQMP_PM_RESET_SPI1,
|
||||
ZYNQMP_PM_RESET_SDIO0,
|
||||
ZYNQMP_PM_RESET_SDIO1,
|
||||
ZYNQMP_PM_RESET_CAN0,
|
||||
ZYNQMP_PM_RESET_CAN1,
|
||||
ZYNQMP_PM_RESET_I2C0,
|
||||
ZYNQMP_PM_RESET_I2C1,
|
||||
ZYNQMP_PM_RESET_TTC0,
|
||||
ZYNQMP_PM_RESET_TTC1,
|
||||
ZYNQMP_PM_RESET_TTC2,
|
||||
ZYNQMP_PM_RESET_TTC3,
|
||||
ZYNQMP_PM_RESET_SWDT_CRL,
|
||||
ZYNQMP_PM_RESET_NAND,
|
||||
ZYNQMP_PM_RESET_ADMA,
|
||||
ZYNQMP_PM_RESET_GPIO,
|
||||
ZYNQMP_PM_RESET_IOU_CC,
|
||||
ZYNQMP_PM_RESET_TIMESTAMP,
|
||||
ZYNQMP_PM_RESET_RPU_R50,
|
||||
ZYNQMP_PM_RESET_RPU_R51,
|
||||
ZYNQMP_PM_RESET_RPU_AMBA,
|
||||
ZYNQMP_PM_RESET_OCM,
|
||||
ZYNQMP_PM_RESET_RPU_PGE,
|
||||
ZYNQMP_PM_RESET_USB0_CORERESET,
|
||||
ZYNQMP_PM_RESET_USB1_CORERESET,
|
||||
ZYNQMP_PM_RESET_USB0_HIBERRESET,
|
||||
ZYNQMP_PM_RESET_USB1_HIBERRESET,
|
||||
ZYNQMP_PM_RESET_USB0_APB,
|
||||
ZYNQMP_PM_RESET_USB1_APB,
|
||||
ZYNQMP_PM_RESET_IPI,
|
||||
ZYNQMP_PM_RESET_APM_LPD,
|
||||
ZYNQMP_PM_RESET_RTC,
|
||||
ZYNQMP_PM_RESET_SYSMON,
|
||||
ZYNQMP_PM_RESET_AFI_FM6,
|
||||
ZYNQMP_PM_RESET_LPD_SWDT,
|
||||
ZYNQMP_PM_RESET_FPD,
|
||||
ZYNQMP_PM_RESET_RPU_DBG1,
|
||||
ZYNQMP_PM_RESET_RPU_DBG0,
|
||||
ZYNQMP_PM_RESET_DBG_LPD,
|
||||
ZYNQMP_PM_RESET_DBG_FPD,
|
||||
ZYNQMP_PM_RESET_APLL,
|
||||
ZYNQMP_PM_RESET_DPLL,
|
||||
ZYNQMP_PM_RESET_VPLL,
|
||||
ZYNQMP_PM_RESET_IOPLL,
|
||||
ZYNQMP_PM_RESET_RPLL,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_0,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_1,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_2,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_3,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_4,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_5,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_6,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_7,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_8,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_9,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_10,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_11,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_12,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_13,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_14,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_15,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_16,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_17,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_18,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_19,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_20,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_21,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_22,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_23,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_24,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_25,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_26,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_27,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_28,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_29,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_30,
|
||||
ZYNQMP_PM_RESET_GPO3_PL_31,
|
||||
ZYNQMP_PM_RESET_RPU_LS,
|
||||
ZYNQMP_PM_RESET_PS_ONLY,
|
||||
ZYNQMP_PM_RESET_PL,
|
||||
ZYNQMP_PM_RESET_PS_PL0,
|
||||
ZYNQMP_PM_RESET_PS_PL1,
|
||||
ZYNQMP_PM_RESET_PS_PL2,
|
||||
ZYNQMP_PM_RESET_PS_PL3,
|
||||
ZYNQMP_PM_RESET_END = ZYNQMP_PM_RESET_PS_PL3
|
||||
};
|
||||
|
||||
enum zynqmp_pm_suspend_reason {
|
||||
SUSPEND_POWER_REQUEST = 201,
|
||||
SUSPEND_ALERT,
|
||||
SUSPEND_SYSTEM_SHUTDOWN,
|
||||
};
|
||||
|
||||
enum zynqmp_pm_request_ack {
|
||||
ZYNQMP_PM_REQUEST_ACK_NO = 1,
|
||||
ZYNQMP_PM_REQUEST_ACK_BLOCKING,
|
||||
ZYNQMP_PM_REQUEST_ACK_NON_BLOCKING,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct zynqmp_pm_query_data - PM query data
|
||||
* @qid: query ID
|
||||
@@ -91,6 +257,7 @@ struct zynqmp_pm_query_data {
|
||||
|
||||
struct zynqmp_eemi_ops {
|
||||
int (*get_api_version)(u32 *version);
|
||||
int (*get_chipid)(u32 *idcode, u32 *version);
|
||||
int (*query_data)(struct zynqmp_pm_query_data qdata, u32 *out);
|
||||
int (*clock_enable)(u32 clock_id);
|
||||
int (*clock_disable)(u32 clock_id);
|
||||
@@ -102,8 +269,25 @@ struct zynqmp_eemi_ops {
|
||||
int (*clock_setparent)(u32 clock_id, u32 parent_id);
|
||||
int (*clock_getparent)(u32 clock_id, u32 *parent_id);
|
||||
int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *out);
|
||||
int (*reset_assert)(const enum zynqmp_pm_reset reset,
|
||||
const enum zynqmp_pm_reset_action assert_flag);
|
||||
int (*reset_get_status)(const enum zynqmp_pm_reset reset, u32 *status);
|
||||
int (*init_finalize)(void);
|
||||
int (*set_suspend_mode)(u32 mode);
|
||||
int (*request_node)(const u32 node,
|
||||
const u32 capabilities,
|
||||
const u32 qos,
|
||||
const enum zynqmp_pm_request_ack ack);
|
||||
int (*release_node)(const u32 node);
|
||||
int (*set_requirement)(const u32 node,
|
||||
const u32 capabilities,
|
||||
const u32 qos,
|
||||
const enum zynqmp_pm_request_ack ack);
|
||||
};
|
||||
|
||||
int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
|
||||
u32 arg2, u32 arg3, u32 *ret_payload);
|
||||
|
||||
#if IS_REACHABLE(CONFIG_ARCH_ZYNQMP)
|
||||
const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void);
|
||||
#else
|
||||
|
@@ -1,149 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _FLEX_ARRAY_H
|
||||
#define _FLEX_ARRAY_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/reciprocal_div.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#define FLEX_ARRAY_PART_SIZE PAGE_SIZE
|
||||
#define FLEX_ARRAY_BASE_SIZE PAGE_SIZE
|
||||
|
||||
struct flex_array_part;
|
||||
|
||||
/*
|
||||
* This is meant to replace cases where an array-like
|
||||
* structure has gotten too big to fit into kmalloc()
|
||||
* and the developer is getting tempted to use
|
||||
* vmalloc().
|
||||
*/
|
||||
|
||||
struct flex_array {
|
||||
union {
|
||||
struct {
|
||||
int element_size;
|
||||
int total_nr_elements;
|
||||
int elems_per_part;
|
||||
struct reciprocal_value reciprocal_elems;
|
||||
struct flex_array_part *parts[];
|
||||
};
|
||||
/*
|
||||
* This little trick makes sure that
|
||||
* sizeof(flex_array) == PAGE_SIZE
|
||||
*/
|
||||
char padding[FLEX_ARRAY_BASE_SIZE];
|
||||
};
|
||||
};
|
||||
|
||||
/* Number of bytes left in base struct flex_array, excluding metadata */
|
||||
#define FLEX_ARRAY_BASE_BYTES_LEFT \
|
||||
(FLEX_ARRAY_BASE_SIZE - offsetof(struct flex_array, parts))
|
||||
|
||||
/* Number of pointers in base to struct flex_array_part pages */
|
||||
#define FLEX_ARRAY_NR_BASE_PTRS \
|
||||
(FLEX_ARRAY_BASE_BYTES_LEFT / sizeof(struct flex_array_part *))
|
||||
|
||||
/* Number of elements of size that fit in struct flex_array_part */
|
||||
#define FLEX_ARRAY_ELEMENTS_PER_PART(size) \
|
||||
(FLEX_ARRAY_PART_SIZE / size)
|
||||
|
||||
/*
|
||||
* Defines a statically allocated flex array and ensures its parameters are
|
||||
* valid.
|
||||
*/
|
||||
#define DEFINE_FLEX_ARRAY(__arrayname, __element_size, __total) \
|
||||
struct flex_array __arrayname = { { { \
|
||||
.element_size = (__element_size), \
|
||||
.total_nr_elements = (__total), \
|
||||
} } }; \
|
||||
static inline void __arrayname##_invalid_parameter(void) \
|
||||
{ \
|
||||
BUILD_BUG_ON((__total) > FLEX_ARRAY_NR_BASE_PTRS * \
|
||||
FLEX_ARRAY_ELEMENTS_PER_PART(__element_size)); \
|
||||
}
|
||||
|
||||
/**
|
||||
* flex_array_alloc() - Creates a flexible array.
|
||||
* @element_size: individual object size.
|
||||
* @total: maximum number of objects which can be stored.
|
||||
* @flags: GFP flags
|
||||
*
|
||||
* Return: Returns an object of structure flex_array.
|
||||
*/
|
||||
struct flex_array *flex_array_alloc(int element_size, unsigned int total,
|
||||
gfp_t flags);
|
||||
|
||||
/**
|
||||
* flex_array_prealloc() - Ensures that memory for the elements indexed in the
|
||||
* range defined by start and nr_elements has been allocated.
|
||||
* @fa: array to allocate memory to.
|
||||
* @start: start address
|
||||
* @nr_elements: number of elements to be allocated.
|
||||
* @flags: GFP flags
|
||||
*
|
||||
*/
|
||||
int flex_array_prealloc(struct flex_array *fa, unsigned int start,
|
||||
unsigned int nr_elements, gfp_t flags);
|
||||
|
||||
/**
|
||||
* flex_array_free() - Removes all elements of a flexible array.
|
||||
* @fa: array to be freed.
|
||||
*/
|
||||
void flex_array_free(struct flex_array *fa);
|
||||
|
||||
/**
|
||||
* flex_array_free_parts() - Removes all elements of a flexible array, but
|
||||
* leaves the array itself in place.
|
||||
* @fa: array to be emptied.
|
||||
*/
|
||||
void flex_array_free_parts(struct flex_array *fa);
|
||||
|
||||
/**
|
||||
* flex_array_put() - Stores data into a flexible array.
|
||||
* @fa: array where element is to be stored.
|
||||
* @element_nr: position to copy, must be less than the maximum specified when
|
||||
* the array was created.
|
||||
* @src: data source to be copied into the array.
|
||||
* @flags: GFP flags
|
||||
*
|
||||
* Return: Returns zero on success, a negative error code otherwise.
|
||||
*/
|
||||
int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
|
||||
gfp_t flags);
|
||||
|
||||
/**
|
||||
* flex_array_clear() - Clears an individual element in the array, sets the
|
||||
* given element to FLEX_ARRAY_FREE.
|
||||
* @element_nr: element position to clear.
|
||||
* @fa: array to which element to be cleared belongs.
|
||||
*
|
||||
* Return: Returns zero on success, -EINVAL otherwise.
|
||||
*/
|
||||
int flex_array_clear(struct flex_array *fa, unsigned int element_nr);
|
||||
|
||||
/**
|
||||
* flex_array_get() - Retrieves data into a flexible array.
|
||||
*
|
||||
* @element_nr: Element position to retrieve data from.
|
||||
* @fa: array from which data is to be retrieved.
|
||||
*
|
||||
* Return: Returns a pointer to the data element, or NULL if that
|
||||
* particular element has never been allocated.
|
||||
*/
|
||||
void *flex_array_get(struct flex_array *fa, unsigned int element_nr);
|
||||
|
||||
/**
|
||||
* flex_array_shrink() - Reduces the allocated size of an array.
|
||||
* @fa: array to shrink.
|
||||
*
|
||||
* Return: Returns number of pages of memory actually freed.
|
||||
*
|
||||
*/
|
||||
int flex_array_shrink(struct flex_array *fa);
|
||||
|
||||
#define flex_array_put_ptr(fa, nr, src, gfp) \
|
||||
flex_array_put(fa, nr, (void *)&(src), gfp)
|
||||
|
||||
void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr);
|
||||
|
||||
#endif /* _FLEX_ARRAY_H */
|
@@ -7,6 +7,13 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
/*
|
||||
* Return code to denote that requested number of
|
||||
* frontswap pages are unused(moved to page cache).
|
||||
* Used in in shmem_unuse and try_to_unuse.
|
||||
*/
|
||||
#define FRONTSWAP_PAGES_UNUSED 2
|
||||
|
||||
struct frontswap_ops {
|
||||
void (*init)(unsigned); /* this swap type was just swapon'ed */
|
||||
int (*store)(unsigned, pgoff_t, struct page *); /* store a page */
|
||||
|
@@ -37,6 +37,9 @@
|
||||
#include <linux/uuid.h>
|
||||
#include <linux/errseq.h>
|
||||
#include <linux/ioprio.h>
|
||||
#include <linux/fs_types.h>
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/stddef.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <uapi/linux/fs.h>
|
||||
@@ -61,6 +64,8 @@ struct workqueue_struct;
|
||||
struct iov_iter;
|
||||
struct fscrypt_info;
|
||||
struct fscrypt_operations;
|
||||
struct fs_context;
|
||||
struct fs_parameter_description;
|
||||
|
||||
extern void __init inode_init(void);
|
||||
extern void __init inode_init_early(void);
|
||||
@@ -304,13 +309,20 @@ enum rw_hint {
|
||||
|
||||
struct kiocb {
|
||||
struct file *ki_filp;
|
||||
|
||||
/* The 'ki_filp' pointer is shared in a union for aio */
|
||||
randomized_struct_fields_start
|
||||
|
||||
loff_t ki_pos;
|
||||
void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
|
||||
void *private;
|
||||
int ki_flags;
|
||||
u16 ki_hint;
|
||||
u16 ki_ioprio; /* See linux/ioprio.h */
|
||||
} __randomize_layout;
|
||||
unsigned int ki_cookie; /* for ->iopoll */
|
||||
|
||||
randomized_struct_fields_end
|
||||
};
|
||||
|
||||
static inline bool is_sync_kiocb(struct kiocb *kiocb)
|
||||
{
|
||||
@@ -698,7 +710,7 @@ struct inode {
|
||||
struct fsnotify_mark_connector __rcu *i_fsnotify_marks;
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
struct fscrypt_info *i_crypt_info;
|
||||
#endif
|
||||
|
||||
@@ -951,7 +963,9 @@ static inline struct file *get_file(struct file *f)
|
||||
atomic_long_inc(&f->f_count);
|
||||
return f;
|
||||
}
|
||||
#define get_file_rcu(x) atomic_long_inc_not_zero(&(x)->f_count)
|
||||
#define get_file_rcu_many(x, cnt) \
|
||||
atomic_long_add_unless(&(x)->f_count, (cnt), 0)
|
||||
#define get_file_rcu(x) get_file_rcu_many((x), 1)
|
||||
#define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1)
|
||||
#define file_count(x) atomic_long_read(&(x)->f_count)
|
||||
|
||||
@@ -1337,6 +1351,7 @@ extern int send_sigurg(struct fown_struct *fown);
|
||||
|
||||
/* These sb flags are internal to the kernel */
|
||||
#define SB_SUBMOUNT (1<<26)
|
||||
#define SB_FORCE (1<<27)
|
||||
#define SB_NOSEC (1<<28)
|
||||
#define SB_BORN (1<<29)
|
||||
#define SB_ACTIVE (1<<30)
|
||||
@@ -1403,7 +1418,7 @@ struct super_block {
|
||||
void *s_security;
|
||||
#endif
|
||||
const struct xattr_handler **s_xattr;
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
const struct fscrypt_operations *s_cop;
|
||||
#endif
|
||||
struct hlist_bl_head s_roots; /* alternate root dentries for NFS */
|
||||
@@ -1447,7 +1462,7 @@ struct super_block {
|
||||
* Filesystem subtype. If non-empty the filesystem type field
|
||||
* in /proc/mounts will be "type.subtype"
|
||||
*/
|
||||
char *s_subtype;
|
||||
const char *s_subtype;
|
||||
|
||||
const struct dentry_operations *s_d_op; /* default d_op for dentries */
|
||||
|
||||
@@ -1700,22 +1715,6 @@ int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
|
||||
u64 phys, u64 len, u32 flags);
|
||||
int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
|
||||
|
||||
/*
|
||||
* File types
|
||||
*
|
||||
* NOTE! These match bits 12..15 of stat.st_mode
|
||||
* (ie "(i_mode >> 12) & 15").
|
||||
*/
|
||||
#define DT_UNKNOWN 0
|
||||
#define DT_FIFO 1
|
||||
#define DT_CHR 2
|
||||
#define DT_DIR 4
|
||||
#define DT_BLK 6
|
||||
#define DT_REG 8
|
||||
#define DT_LNK 10
|
||||
#define DT_SOCK 12
|
||||
#define DT_WHT 14
|
||||
|
||||
/*
|
||||
* This is the "filldir" function type, used by readdir() to let
|
||||
* the kernel specify what kind of dirent layout it wants to have.
|
||||
@@ -1787,6 +1786,7 @@ struct file_operations {
|
||||
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
|
||||
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
|
||||
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
|
||||
int (*iopoll)(struct kiocb *kiocb, bool spin);
|
||||
int (*iterate) (struct file *, struct dir_context *);
|
||||
int (*iterate_shared) (struct file *, struct dir_context *);
|
||||
__poll_t (*poll) (struct file *, struct poll_table_struct *);
|
||||
@@ -2085,7 +2085,7 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
|
||||
* I_WB_SWITCH Cgroup bdi_writeback switching in progress. Used to
|
||||
* synchronize competing switching instances and to tell
|
||||
* wb stat updates to grab the i_pages lock. See
|
||||
* inode_switch_wb_work_fn() for details.
|
||||
* inode_switch_wbs_work_fn() for details.
|
||||
*
|
||||
* I_OVL_INUSE Used by overlayfs to get exclusive ownership on upper
|
||||
* and work dirs among overlayfs mounts.
|
||||
@@ -2173,6 +2173,8 @@ struct file_system_type {
|
||||
#define FS_HAS_SUBTYPE 4
|
||||
#define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */
|
||||
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
|
||||
int (*init_fs_context)(struct fs_context *);
|
||||
const struct fs_parameter_description *parameters;
|
||||
struct dentry *(*mount) (struct file_system_type *, int,
|
||||
const char *, void *);
|
||||
void (*kill_sb) (struct super_block *);
|
||||
@@ -2228,8 +2230,12 @@ void kill_litter_super(struct super_block *sb);
|
||||
void deactivate_super(struct super_block *sb);
|
||||
void deactivate_locked_super(struct super_block *sb);
|
||||
int set_anon_super(struct super_block *s, void *data);
|
||||
int set_anon_super_fc(struct super_block *s, struct fs_context *fc);
|
||||
int get_anon_bdev(dev_t *);
|
||||
void free_anon_bdev(dev_t);
|
||||
struct super_block *sget_fc(struct fs_context *fc,
|
||||
int (*test)(struct super_block *, struct fs_context *),
|
||||
int (*set)(struct super_block *, struct fs_context *));
|
||||
struct super_block *sget_userns(struct file_system_type *type,
|
||||
int (*test)(struct super_block *,void *),
|
||||
int (*set)(struct super_block *,void *),
|
||||
@@ -2272,8 +2278,7 @@ mount_pseudo(struct file_system_type *fs_type, char *name,
|
||||
|
||||
extern int register_filesystem(struct file_system_type *);
|
||||
extern int unregister_filesystem(struct file_system_type *);
|
||||
extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
|
||||
#define kern_mount(type) kern_mount_data(type, NULL)
|
||||
extern struct vfsmount *kern_mount(struct file_system_type *);
|
||||
extern void kern_unmount(struct vfsmount *mnt);
|
||||
extern int may_umount_tree(struct vfsmount *);
|
||||
extern int may_umount(struct vfsmount *);
|
||||
@@ -2487,6 +2492,7 @@ struct filename {
|
||||
struct audit_names *aname;
|
||||
const char iname[];
|
||||
};
|
||||
static_assert(offsetof(struct filename, iname) % sizeof(long) == 0);
|
||||
|
||||
extern long vfs_truncate(const struct path *, loff_t);
|
||||
extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
|
||||
@@ -3515,4 +3521,13 @@ extern void inode_nohighmem(struct inode *inode);
|
||||
extern int vfs_fadvise(struct file *file, loff_t offset, loff_t len,
|
||||
int advice);
|
||||
|
||||
#if defined(CONFIG_IO_URING)
|
||||
extern struct sock *io_uring_get_socket(struct file *file);
|
||||
#else
|
||||
static inline struct sock *io_uring_get_socket(struct file *file)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LINUX_FS_H */
|
||||
|
188
include/linux/fs_context.h
Normal file
188
include/linux/fs_context.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/* Filesystem superblock creation and reconfiguration context.
|
||||
*
|
||||
* Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FS_CONTEXT_H
|
||||
#define _LINUX_FS_CONTEXT_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/security.h>
|
||||
|
||||
struct cred;
|
||||
struct dentry;
|
||||
struct file_operations;
|
||||
struct file_system_type;
|
||||
struct mnt_namespace;
|
||||
struct net;
|
||||
struct pid_namespace;
|
||||
struct super_block;
|
||||
struct user_namespace;
|
||||
struct vfsmount;
|
||||
struct path;
|
||||
|
||||
enum fs_context_purpose {
|
||||
FS_CONTEXT_FOR_MOUNT, /* New superblock for explicit mount */
|
||||
FS_CONTEXT_FOR_SUBMOUNT, /* New superblock for automatic submount */
|
||||
FS_CONTEXT_FOR_RECONFIGURE, /* Superblock reconfiguration (remount) */
|
||||
};
|
||||
|
||||
/*
|
||||
* Type of parameter value.
|
||||
*/
|
||||
enum fs_value_type {
|
||||
fs_value_is_undefined,
|
||||
fs_value_is_flag, /* Value not given a value */
|
||||
fs_value_is_string, /* Value is a string */
|
||||
fs_value_is_blob, /* Value is a binary blob */
|
||||
fs_value_is_filename, /* Value is a filename* + dirfd */
|
||||
fs_value_is_filename_empty, /* Value is a filename* + dirfd + AT_EMPTY_PATH */
|
||||
fs_value_is_file, /* Value is a file* */
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration parameter.
|
||||
*/
|
||||
struct fs_parameter {
|
||||
const char *key; /* Parameter name */
|
||||
enum fs_value_type type:8; /* The type of value here */
|
||||
union {
|
||||
char *string;
|
||||
void *blob;
|
||||
struct filename *name;
|
||||
struct file *file;
|
||||
};
|
||||
size_t size;
|
||||
int dirfd;
|
||||
};
|
||||
|
||||
/*
|
||||
* Filesystem context for holding the parameters used in the creation or
|
||||
* reconfiguration of a superblock.
|
||||
*
|
||||
* Superblock creation fills in ->root whereas reconfiguration begins with this
|
||||
* already set.
|
||||
*
|
||||
* See Documentation/filesystems/mounting.txt
|
||||
*/
|
||||
struct fs_context {
|
||||
const struct fs_context_operations *ops;
|
||||
struct file_system_type *fs_type;
|
||||
void *fs_private; /* The filesystem's context */
|
||||
struct dentry *root; /* The root and superblock */
|
||||
struct user_namespace *user_ns; /* The user namespace for this mount */
|
||||
struct net *net_ns; /* The network namespace for this mount */
|
||||
const struct cred *cred; /* The mounter's credentials */
|
||||
const char *source; /* The source name (eg. dev path) */
|
||||
const char *subtype; /* The subtype to set on the superblock */
|
||||
void *security; /* Linux S&M options */
|
||||
void *s_fs_info; /* Proposed s_fs_info */
|
||||
unsigned int sb_flags; /* Proposed superblock flags (SB_*) */
|
||||
unsigned int sb_flags_mask; /* Superblock flags that were changed */
|
||||
unsigned int lsm_flags; /* Information flags from the fs to the LSM */
|
||||
enum fs_context_purpose purpose:8;
|
||||
bool need_free:1; /* Need to call ops->free() */
|
||||
bool global:1; /* Goes into &init_user_ns */
|
||||
};
|
||||
|
||||
struct fs_context_operations {
|
||||
void (*free)(struct fs_context *fc);
|
||||
int (*dup)(struct fs_context *fc, struct fs_context *src_fc);
|
||||
int (*parse_param)(struct fs_context *fc, struct fs_parameter *param);
|
||||
int (*parse_monolithic)(struct fs_context *fc, void *data);
|
||||
int (*get_tree)(struct fs_context *fc);
|
||||
int (*reconfigure)(struct fs_context *fc);
|
||||
};
|
||||
|
||||
/*
|
||||
* fs_context manipulation functions.
|
||||
*/
|
||||
extern struct fs_context *fs_context_for_mount(struct file_system_type *fs_type,
|
||||
unsigned int sb_flags);
|
||||
extern struct fs_context *fs_context_for_reconfigure(struct dentry *dentry,
|
||||
unsigned int sb_flags,
|
||||
unsigned int sb_flags_mask);
|
||||
extern struct fs_context *fs_context_for_submount(struct file_system_type *fs_type,
|
||||
struct dentry *reference);
|
||||
|
||||
extern struct fs_context *vfs_dup_fs_context(struct fs_context *fc);
|
||||
extern int vfs_parse_fs_param(struct fs_context *fc, struct fs_parameter *param);
|
||||
extern int vfs_parse_fs_string(struct fs_context *fc, const char *key,
|
||||
const char *value, size_t v_size);
|
||||
extern int generic_parse_monolithic(struct fs_context *fc, void *data);
|
||||
extern int vfs_get_tree(struct fs_context *fc);
|
||||
extern void put_fs_context(struct fs_context *fc);
|
||||
|
||||
/*
|
||||
* sget() wrapper to be called from the ->get_tree() op.
|
||||
*/
|
||||
enum vfs_get_super_keying {
|
||||
vfs_get_single_super, /* Only one such superblock may exist */
|
||||
vfs_get_keyed_super, /* Superblocks with different s_fs_info keys may exist */
|
||||
vfs_get_independent_super, /* Multiple independent superblocks may exist */
|
||||
};
|
||||
extern int vfs_get_super(struct fs_context *fc,
|
||||
enum vfs_get_super_keying keying,
|
||||
int (*fill_super)(struct super_block *sb,
|
||||
struct fs_context *fc));
|
||||
|
||||
extern const struct file_operations fscontext_fops;
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
extern __attribute__((format(printf, 2, 3)))
|
||||
void logfc(struct fs_context *fc, const char *fmt, ...);
|
||||
#else
|
||||
static inline __attribute__((format(printf, 2, 3)))
|
||||
void logfc(struct fs_context *fc, const char *fmt, ...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* infof - Store supplementary informational message
|
||||
* @fc: The context in which to log the informational message
|
||||
* @fmt: The format string
|
||||
*
|
||||
* Store the supplementary informational message for the process if the process
|
||||
* has enabled the facility.
|
||||
*/
|
||||
#define infof(fc, fmt, ...) ({ logfc(fc, "i "fmt, ## __VA_ARGS__); })
|
||||
|
||||
/**
|
||||
* warnf - Store supplementary warning message
|
||||
* @fc: The context in which to log the error message
|
||||
* @fmt: The format string
|
||||
*
|
||||
* Store the supplementary warning message for the process if the process has
|
||||
* enabled the facility.
|
||||
*/
|
||||
#define warnf(fc, fmt, ...) ({ logfc(fc, "w "fmt, ## __VA_ARGS__); })
|
||||
|
||||
/**
|
||||
* errorf - Store supplementary error message
|
||||
* @fc: The context in which to log the error message
|
||||
* @fmt: The format string
|
||||
*
|
||||
* Store the supplementary error message for the process if the process has
|
||||
* enabled the facility.
|
||||
*/
|
||||
#define errorf(fc, fmt, ...) ({ logfc(fc, "e "fmt, ## __VA_ARGS__); })
|
||||
|
||||
/**
|
||||
* invalf - Store supplementary invalid argument error message
|
||||
* @fc: The context in which to log the error message
|
||||
* @fmt: The format string
|
||||
*
|
||||
* Store the supplementary error message for the process if the process has
|
||||
* enabled the facility and return -EINVAL.
|
||||
*/
|
||||
#define invalf(fc, fmt, ...) ({ errorf(fc, fmt, ## __VA_ARGS__); -EINVAL; })
|
||||
|
||||
#endif /* _LINUX_FS_CONTEXT_H */
|
151
include/linux/fs_parser.h
Normal file
151
include/linux/fs_parser.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/* Filesystem parameter description and parser
|
||||
*
|
||||
* Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FS_PARSER_H
|
||||
#define _LINUX_FS_PARSER_H
|
||||
|
||||
#include <linux/fs_context.h>
|
||||
|
||||
struct path;
|
||||
|
||||
struct constant_table {
|
||||
const char *name;
|
||||
int value;
|
||||
};
|
||||
|
||||
/*
|
||||
* The type of parameter expected.
|
||||
*/
|
||||
enum fs_parameter_type {
|
||||
__fs_param_wasnt_defined,
|
||||
fs_param_is_flag,
|
||||
fs_param_is_bool,
|
||||
fs_param_is_u32,
|
||||
fs_param_is_u32_octal,
|
||||
fs_param_is_u32_hex,
|
||||
fs_param_is_s32,
|
||||
fs_param_is_u64,
|
||||
fs_param_is_enum,
|
||||
fs_param_is_string,
|
||||
fs_param_is_blob,
|
||||
fs_param_is_blockdev,
|
||||
fs_param_is_path,
|
||||
fs_param_is_fd,
|
||||
nr__fs_parameter_type,
|
||||
};
|
||||
|
||||
/*
|
||||
* Specification of the type of value a parameter wants.
|
||||
*
|
||||
* Note that the fsparam_flag(), fsparam_string(), fsparam_u32(), ... macros
|
||||
* should be used to generate elements of this type.
|
||||
*/
|
||||
struct fs_parameter_spec {
|
||||
const char *name;
|
||||
u8 opt; /* Option number (returned by fs_parse()) */
|
||||
enum fs_parameter_type type:8; /* The desired parameter type */
|
||||
unsigned short flags;
|
||||
#define fs_param_v_optional 0x0001 /* The value is optional */
|
||||
#define fs_param_neg_with_no 0x0002 /* "noxxx" is negative param */
|
||||
#define fs_param_neg_with_empty 0x0004 /* "xxx=" is negative param */
|
||||
#define fs_param_deprecated 0x0008 /* The param is deprecated */
|
||||
};
|
||||
|
||||
struct fs_parameter_enum {
|
||||
u8 opt; /* Option number (as fs_parameter_spec::opt) */
|
||||
char name[14];
|
||||
u8 value;
|
||||
};
|
||||
|
||||
struct fs_parameter_description {
|
||||
const char name[16]; /* Name for logging purposes */
|
||||
const struct fs_parameter_spec *specs; /* List of param specifications */
|
||||
const struct fs_parameter_enum *enums; /* Enum values */
|
||||
};
|
||||
|
||||
/*
|
||||
* Result of parse.
|
||||
*/
|
||||
struct fs_parse_result {
|
||||
bool negated; /* T if param was "noxxx" */
|
||||
bool has_value; /* T if value supplied to param */
|
||||
union {
|
||||
bool boolean; /* For spec_bool */
|
||||
int int_32; /* For spec_s32/spec_enum */
|
||||
unsigned int uint_32; /* For spec_u32{,_octal,_hex}/spec_enum */
|
||||
u64 uint_64; /* For spec_u64 */
|
||||
};
|
||||
};
|
||||
|
||||
extern int fs_parse(struct fs_context *fc,
|
||||
const struct fs_parameter_description *desc,
|
||||
struct fs_parameter *value,
|
||||
struct fs_parse_result *result);
|
||||
extern int fs_lookup_param(struct fs_context *fc,
|
||||
struct fs_parameter *param,
|
||||
bool want_bdev,
|
||||
struct path *_path);
|
||||
|
||||
extern int __lookup_constant(const struct constant_table tbl[], size_t tbl_size,
|
||||
const char *name, int not_found);
|
||||
#define lookup_constant(t, n, nf) __lookup_constant(t, ARRAY_SIZE(t), (n), (nf))
|
||||
|
||||
#ifdef CONFIG_VALIDATE_FS_PARSER
|
||||
extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
|
||||
int low, int high, int special);
|
||||
extern bool fs_validate_description(const struct fs_parameter_description *desc);
|
||||
#else
|
||||
static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
|
||||
int low, int high, int special)
|
||||
{ return true; }
|
||||
static inline bool fs_validate_description(const struct fs_parameter_description *desc)
|
||||
{ return true; }
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Parameter type, name, index and flags element constructors. Use as:
|
||||
*
|
||||
* fsparam_xxxx("foo", Opt_foo)
|
||||
*
|
||||
* If existing helpers are not enough, direct use of __fsparam() would
|
||||
* work, but any such case is probably a sign that new helper is needed.
|
||||
* Helpers will remain stable; low-level implementation may change.
|
||||
*/
|
||||
#define __fsparam(TYPE, NAME, OPT, FLAGS) \
|
||||
{ \
|
||||
.name = NAME, \
|
||||
.opt = OPT, \
|
||||
.type = TYPE, \
|
||||
.flags = FLAGS \
|
||||
}
|
||||
|
||||
#define fsparam_flag(NAME, OPT) __fsparam(fs_param_is_flag, NAME, OPT, 0)
|
||||
#define fsparam_flag_no(NAME, OPT) \
|
||||
__fsparam(fs_param_is_flag, NAME, OPT, \
|
||||
fs_param_neg_with_no)
|
||||
#define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0)
|
||||
#define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0)
|
||||
#define fsparam_u32oct(NAME, OPT) \
|
||||
__fsparam(fs_param_is_u32_octal, NAME, OPT, 0)
|
||||
#define fsparam_u32hex(NAME, OPT) \
|
||||
__fsparam(fs_param_is_u32_hex, NAME, OPT, 0)
|
||||
#define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0)
|
||||
#define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0)
|
||||
#define fsparam_enum(NAME, OPT) __fsparam(fs_param_is_enum, NAME, OPT, 0)
|
||||
#define fsparam_string(NAME, OPT) \
|
||||
__fsparam(fs_param_is_string, NAME, OPT, 0)
|
||||
#define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0)
|
||||
#define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0)
|
||||
#define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0)
|
||||
#define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0)
|
||||
|
||||
|
||||
#endif /* _LINUX_FS_PARSER_H */
|
75
include/linux/fs_types.h
Normal file
75
include/linux/fs_types.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LINUX_FS_TYPES_H
|
||||
#define _LINUX_FS_TYPES_H
|
||||
|
||||
/*
|
||||
* This is a header for the common implementation of dirent
|
||||
* to fs on-disk file type conversion. Although the fs on-disk
|
||||
* bits are specific to every file system, in practice, many
|
||||
* file systems use the exact same on-disk format to describe
|
||||
* the lower 3 file type bits that represent the 7 POSIX file
|
||||
* types.
|
||||
*
|
||||
* It is important to note that the definitions in this
|
||||
* header MUST NOT change. This would break both the
|
||||
* userspace ABI and the on-disk format of filesystems
|
||||
* using this code.
|
||||
*
|
||||
* All those file systems can use this generic code for the
|
||||
* conversions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* struct dirent file types
|
||||
* exposed to user via getdents(2), readdir(3)
|
||||
*
|
||||
* These match bits 12..15 of stat.st_mode
|
||||
* (ie "(i_mode >> 12) & 15").
|
||||
*/
|
||||
#define S_DT_SHIFT 12
|
||||
#define S_DT(mode) (((mode) & S_IFMT) >> S_DT_SHIFT)
|
||||
#define S_DT_MASK (S_IFMT >> S_DT_SHIFT)
|
||||
|
||||
/* these are defined by POSIX and also present in glibc's dirent.h */
|
||||
#define DT_UNKNOWN 0
|
||||
#define DT_FIFO 1
|
||||
#define DT_CHR 2
|
||||
#define DT_DIR 4
|
||||
#define DT_BLK 6
|
||||
#define DT_REG 8
|
||||
#define DT_LNK 10
|
||||
#define DT_SOCK 12
|
||||
#define DT_WHT 14
|
||||
|
||||
#define DT_MAX (S_DT_MASK + 1) /* 16 */
|
||||
|
||||
/*
|
||||
* fs on-disk file types.
|
||||
* Only the low 3 bits are used for the POSIX file types.
|
||||
* Other bits are reserved for fs private use.
|
||||
* These definitions are shared and used by multiple filesystems,
|
||||
* and MUST NOT change under any circumstances.
|
||||
*
|
||||
* Note that no fs currently stores the whiteout type on-disk,
|
||||
* so whiteout dirents are exposed to user as DT_CHR.
|
||||
*/
|
||||
#define FT_UNKNOWN 0
|
||||
#define FT_REG_FILE 1
|
||||
#define FT_DIR 2
|
||||
#define FT_CHRDEV 3
|
||||
#define FT_BLKDEV 4
|
||||
#define FT_FIFO 5
|
||||
#define FT_SOCK 6
|
||||
#define FT_SYMLINK 7
|
||||
|
||||
#define FT_MAX 8
|
||||
|
||||
/*
|
||||
* declarations for helper functions, accompanying implementation
|
||||
* is in fs/fs_types.c
|
||||
*/
|
||||
extern unsigned char fs_ftype_to_dtype(unsigned int filetype);
|
||||
extern unsigned char fs_umode_to_ftype(umode_t mode);
|
||||
extern unsigned char fs_umode_to_dtype(umode_t mode);
|
||||
|
||||
#endif
|
@@ -2,9 +2,8 @@
|
||||
/*
|
||||
* fscrypt.h: declarations for per-file encryption
|
||||
*
|
||||
* Filesystems that implement per-file encryption include this header
|
||||
* file with the __FS_HAS_ENCRYPTION set according to whether that filesystem
|
||||
* is being built with encryption support or not.
|
||||
* Filesystems that implement per-file encryption must include this header
|
||||
* file.
|
||||
*
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
*
|
||||
@@ -15,6 +14,8 @@
|
||||
#define _LINUX_FSCRYPT_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define FS_CRYPTO_BLOCK_SIZE 16
|
||||
|
||||
@@ -42,11 +43,410 @@ struct fscrypt_name {
|
||||
/* Maximum value for the third parameter of fscrypt_operations.set_context(). */
|
||||
#define FSCRYPT_SET_CONTEXT_MAX_SIZE 28
|
||||
|
||||
#if __FS_HAS_ENCRYPTION
|
||||
#include <linux/fscrypt_supp.h>
|
||||
#else
|
||||
#include <linux/fscrypt_notsupp.h>
|
||||
#endif
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
/*
|
||||
* fscrypt superblock flags
|
||||
*/
|
||||
#define FS_CFLG_OWN_PAGES (1U << 1)
|
||||
|
||||
/*
|
||||
* crypto operations for filesystems
|
||||
*/
|
||||
struct fscrypt_operations {
|
||||
unsigned int flags;
|
||||
const char *key_prefix;
|
||||
int (*get_context)(struct inode *, void *, size_t);
|
||||
int (*set_context)(struct inode *, const void *, size_t, void *);
|
||||
bool (*dummy_context)(struct inode *);
|
||||
bool (*empty_dir)(struct inode *);
|
||||
unsigned int max_namelen;
|
||||
};
|
||||
|
||||
struct fscrypt_ctx {
|
||||
union {
|
||||
struct {
|
||||
struct page *bounce_page; /* Ciphertext page */
|
||||
struct page *control_page; /* Original page */
|
||||
} w;
|
||||
struct {
|
||||
struct bio *bio;
|
||||
struct work_struct work;
|
||||
} r;
|
||||
struct list_head free_list; /* Free list */
|
||||
};
|
||||
u8 flags; /* Flags */
|
||||
};
|
||||
|
||||
static inline bool fscrypt_has_encryption_key(const struct inode *inode)
|
||||
{
|
||||
return (inode->i_crypt_info != NULL);
|
||||
}
|
||||
|
||||
static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
return inode->i_sb->s_cop->dummy_context &&
|
||||
inode->i_sb->s_cop->dummy_context(inode);
|
||||
}
|
||||
|
||||
/* crypto.c */
|
||||
extern void fscrypt_enqueue_decrypt_work(struct work_struct *);
|
||||
extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
|
||||
extern void fscrypt_release_ctx(struct fscrypt_ctx *);
|
||||
extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
|
||||
unsigned int, unsigned int,
|
||||
u64, gfp_t);
|
||||
extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int,
|
||||
unsigned int, u64);
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
|
||||
}
|
||||
|
||||
extern void fscrypt_restore_control_page(struct page *);
|
||||
|
||||
/* policy.c */
|
||||
extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
|
||||
extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
|
||||
extern int fscrypt_has_permitted_context(struct inode *, struct inode *);
|
||||
extern int fscrypt_inherit_context(struct inode *, struct inode *,
|
||||
void *, bool);
|
||||
/* keyinfo.c */
|
||||
extern int fscrypt_get_encryption_info(struct inode *);
|
||||
extern void fscrypt_put_encryption_info(struct inode *);
|
||||
|
||||
/* fname.c */
|
||||
extern int fscrypt_setup_filename(struct inode *, const struct qstr *,
|
||||
int lookup, struct fscrypt_name *);
|
||||
|
||||
static inline void fscrypt_free_filename(struct fscrypt_name *fname)
|
||||
{
|
||||
kfree(fname->crypto_buf.name);
|
||||
}
|
||||
|
||||
extern int fscrypt_fname_alloc_buffer(const struct inode *, u32,
|
||||
struct fscrypt_str *);
|
||||
extern void fscrypt_fname_free_buffer(struct fscrypt_str *);
|
||||
extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32,
|
||||
const struct fscrypt_str *, struct fscrypt_str *);
|
||||
|
||||
#define FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE 32
|
||||
|
||||
/* Extracts the second-to-last ciphertext block; see explanation below */
|
||||
#define FSCRYPT_FNAME_DIGEST(name, len) \
|
||||
((name) + round_down((len) - FS_CRYPTO_BLOCK_SIZE - 1, \
|
||||
FS_CRYPTO_BLOCK_SIZE))
|
||||
|
||||
#define FSCRYPT_FNAME_DIGEST_SIZE FS_CRYPTO_BLOCK_SIZE
|
||||
|
||||
/**
|
||||
* fscrypt_digested_name - alternate identifier for an on-disk filename
|
||||
*
|
||||
* When userspace lists an encrypted directory without access to the key,
|
||||
* filenames whose ciphertext is longer than FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE
|
||||
* bytes are shown in this abbreviated form (base64-encoded) rather than as the
|
||||
* full ciphertext (base64-encoded). This is necessary to allow supporting
|
||||
* filenames up to NAME_MAX bytes, since base64 encoding expands the length.
|
||||
*
|
||||
* To make it possible for filesystems to still find the correct directory entry
|
||||
* despite not knowing the full on-disk name, we encode any filesystem-specific
|
||||
* 'hash' and/or 'minor_hash' which the filesystem may need for its lookups,
|
||||
* followed by the second-to-last ciphertext block of the filename. Due to the
|
||||
* use of the CBC-CTS encryption mode, the second-to-last ciphertext block
|
||||
* depends on the full plaintext. (Note that ciphertext stealing causes the
|
||||
* last two blocks to appear "flipped".) This makes accidental collisions very
|
||||
* unlikely: just a 1 in 2^128 chance for two filenames to collide even if they
|
||||
* share the same filesystem-specific hashes.
|
||||
*
|
||||
* However, this scheme isn't immune to intentional collisions, which can be
|
||||
* created by anyone able to create arbitrary plaintext filenames and view them
|
||||
* without the key. Making the "digest" be a real cryptographic hash like
|
||||
* SHA-256 over the full ciphertext would prevent this, although it would be
|
||||
* less efficient and harder to implement, especially since the filesystem would
|
||||
* need to calculate it for each directory entry examined during a search.
|
||||
*/
|
||||
struct fscrypt_digested_name {
|
||||
u32 hash;
|
||||
u32 minor_hash;
|
||||
u8 digest[FSCRYPT_FNAME_DIGEST_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* fscrypt_match_name() - test whether the given name matches a directory entry
|
||||
* @fname: the name being searched for
|
||||
* @de_name: the name from the directory entry
|
||||
* @de_name_len: the length of @de_name in bytes
|
||||
*
|
||||
* Normally @fname->disk_name will be set, and in that case we simply compare
|
||||
* that to the name stored in the directory entry. The only exception is that
|
||||
* if we don't have the key for an encrypted directory and a filename in it is
|
||||
* very long, then we won't have the full disk_name and we'll instead need to
|
||||
* match against the fscrypt_digested_name.
|
||||
*
|
||||
* Return: %true if the name matches, otherwise %false.
|
||||
*/
|
||||
static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
|
||||
const u8 *de_name, u32 de_name_len)
|
||||
{
|
||||
if (unlikely(!fname->disk_name.name)) {
|
||||
const struct fscrypt_digested_name *n =
|
||||
(const void *)fname->crypto_buf.name;
|
||||
if (WARN_ON_ONCE(fname->usr_fname->name[0] != '_'))
|
||||
return false;
|
||||
if (de_name_len <= FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE)
|
||||
return false;
|
||||
return !memcmp(FSCRYPT_FNAME_DIGEST(de_name, de_name_len),
|
||||
n->digest, FSCRYPT_FNAME_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
if (de_name_len != fname->disk_name.len)
|
||||
return false;
|
||||
return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
|
||||
}
|
||||
|
||||
/* bio.c */
|
||||
extern void fscrypt_decrypt_bio(struct bio *);
|
||||
extern void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
|
||||
struct bio *bio);
|
||||
extern void fscrypt_pullback_bio_page(struct page **, bool);
|
||||
extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t,
|
||||
unsigned int);
|
||||
|
||||
/* hooks.c */
|
||||
extern int fscrypt_file_open(struct inode *inode, struct file *filp);
|
||||
extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir);
|
||||
extern int __fscrypt_prepare_rename(struct inode *old_dir,
|
||||
struct dentry *old_dentry,
|
||||
struct inode *new_dir,
|
||||
struct dentry *new_dentry,
|
||||
unsigned int flags);
|
||||
extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry);
|
||||
extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link);
|
||||
extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
|
||||
unsigned int len,
|
||||
struct fscrypt_str *disk_link);
|
||||
extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
|
||||
unsigned int max_size,
|
||||
struct delayed_call *done);
|
||||
#else /* !CONFIG_FS_ENCRYPTION */
|
||||
|
||||
static inline bool fscrypt_has_encryption_key(const struct inode *inode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* crypto.c */
|
||||
static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline void fscrypt_release_ctx(struct fscrypt_ctx *ctx)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_encrypt_page(const struct inode *inode,
|
||||
struct page *page,
|
||||
unsigned int len,
|
||||
unsigned int offs,
|
||||
u64 lblk_num, gfp_t gfp_flags)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline int fscrypt_decrypt_page(const struct inode *inode,
|
||||
struct page *page,
|
||||
unsigned int len, unsigned int offs,
|
||||
u64 lblk_num)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
WARN_ON_ONCE(1);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static inline void fscrypt_restore_control_page(struct page *page)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* policy.c */
|
||||
static inline int fscrypt_ioctl_set_policy(struct file *filp,
|
||||
const void __user *arg)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_has_permitted_context(struct inode *parent,
|
||||
struct inode *child)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fscrypt_inherit_context(struct inode *parent,
|
||||
struct inode *child,
|
||||
void *fs_data, bool preload)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* keyinfo.c */
|
||||
static inline int fscrypt_get_encryption_info(struct inode *inode)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_put_encryption_info(struct inode *inode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* fname.c */
|
||||
static inline int fscrypt_setup_filename(struct inode *dir,
|
||||
const struct qstr *iname,
|
||||
int lookup, struct fscrypt_name *fname)
|
||||
{
|
||||
if (IS_ENCRYPTED(dir))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memset(fname, 0, sizeof(struct fscrypt_name));
|
||||
fname->usr_fname = iname;
|
||||
fname->disk_name.name = (unsigned char *)iname->name;
|
||||
fname->disk_name.len = iname->len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fscrypt_free_filename(struct fscrypt_name *fname)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_fname_alloc_buffer(const struct inode *inode,
|
||||
u32 max_encrypted_len,
|
||||
struct fscrypt_str *crypto_str)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_fname_disk_to_usr(struct inode *inode,
|
||||
u32 hash, u32 minor_hash,
|
||||
const struct fscrypt_str *iname,
|
||||
struct fscrypt_str *oname)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
|
||||
const u8 *de_name, u32 de_name_len)
|
||||
{
|
||||
/* Encryption support disabled; use standard comparison */
|
||||
if (de_name_len != fname->disk_name.len)
|
||||
return false;
|
||||
return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
|
||||
}
|
||||
|
||||
/* bio.c */
|
||||
static inline void fscrypt_decrypt_bio(struct bio *bio)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
|
||||
struct bio *bio)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void fscrypt_pullback_bio_page(struct page **page, bool restore)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
|
||||
sector_t pblk, unsigned int len)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* hooks.c */
|
||||
|
||||
static inline int fscrypt_file_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
if (IS_ENCRYPTED(inode))
|
||||
return -EOPNOTSUPP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_prepare_link(struct inode *inode,
|
||||
struct inode *dir)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_prepare_rename(struct inode *old_dir,
|
||||
struct dentry *old_dentry,
|
||||
struct inode *new_dir,
|
||||
struct dentry *new_dentry,
|
||||
unsigned int flags)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_prepare_lookup(struct inode *dir,
|
||||
struct dentry *dentry)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_prepare_symlink(struct inode *dir,
|
||||
unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
static inline int __fscrypt_encrypt_symlink(struct inode *inode,
|
||||
const char *target,
|
||||
unsigned int len,
|
||||
struct fscrypt_str *disk_link)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline const char *fscrypt_get_symlink(struct inode *inode,
|
||||
const void *caddr,
|
||||
unsigned int max_size,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
#endif /* !CONFIG_FS_ENCRYPTION */
|
||||
|
||||
/**
|
||||
* fscrypt_require_key - require an inode's encryption key
|
||||
@@ -89,7 +489,7 @@ static inline int fscrypt_require_key(struct inode *inode)
|
||||
* in an encrypted directory tree use the same encryption policy.
|
||||
*
|
||||
* Return: 0 on success, -ENOKEY if the directory's encryption key is missing,
|
||||
* -EPERM if the link would result in an inconsistent encryption policy, or
|
||||
* -EXDEV if the link would result in an inconsistent encryption policy, or
|
||||
* another -errno code.
|
||||
*/
|
||||
static inline int fscrypt_prepare_link(struct dentry *old_dentry,
|
||||
@@ -119,7 +519,7 @@ static inline int fscrypt_prepare_link(struct dentry *old_dentry,
|
||||
* We also verify that the rename will not violate the constraint that all files
|
||||
* in an encrypted directory tree use the same encryption policy.
|
||||
*
|
||||
* Return: 0 on success, -ENOKEY if an encryption key is missing, -EPERM if the
|
||||
* Return: 0 on success, -ENOKEY if an encryption key is missing, -EXDEV if the
|
||||
* rename would cause inconsistent encryption policies, or another -errno code.
|
||||
*/
|
||||
static inline int fscrypt_prepare_rename(struct inode *old_dir,
|
||||
|
@@ -1,231 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* fscrypt_notsupp.h
|
||||
*
|
||||
* This stubs out the fscrypt functions for filesystems configured without
|
||||
* encryption support.
|
||||
*
|
||||
* Do not include this file directly. Use fscrypt.h instead!
|
||||
*/
|
||||
#ifndef _LINUX_FSCRYPT_H
|
||||
#error "Incorrect include of linux/fscrypt_notsupp.h!"
|
||||
#endif
|
||||
|
||||
#ifndef _LINUX_FSCRYPT_NOTSUPP_H
|
||||
#define _LINUX_FSCRYPT_NOTSUPP_H
|
||||
|
||||
static inline bool fscrypt_has_encryption_key(const struct inode *inode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* crypto.c */
|
||||
static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline void fscrypt_release_ctx(struct fscrypt_ctx *ctx)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_encrypt_page(const struct inode *inode,
|
||||
struct page *page,
|
||||
unsigned int len,
|
||||
unsigned int offs,
|
||||
u64 lblk_num, gfp_t gfp_flags)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline int fscrypt_decrypt_page(const struct inode *inode,
|
||||
struct page *page,
|
||||
unsigned int len, unsigned int offs,
|
||||
u64 lblk_num)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
WARN_ON_ONCE(1);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static inline void fscrypt_restore_control_page(struct page *page)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* policy.c */
|
||||
static inline int fscrypt_ioctl_set_policy(struct file *filp,
|
||||
const void __user *arg)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_has_permitted_context(struct inode *parent,
|
||||
struct inode *child)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fscrypt_inherit_context(struct inode *parent,
|
||||
struct inode *child,
|
||||
void *fs_data, bool preload)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* keyinfo.c */
|
||||
static inline int fscrypt_get_encryption_info(struct inode *inode)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_put_encryption_info(struct inode *inode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* fname.c */
|
||||
static inline int fscrypt_setup_filename(struct inode *dir,
|
||||
const struct qstr *iname,
|
||||
int lookup, struct fscrypt_name *fname)
|
||||
{
|
||||
if (IS_ENCRYPTED(dir))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memset(fname, 0, sizeof(struct fscrypt_name));
|
||||
fname->usr_fname = iname;
|
||||
fname->disk_name.name = (unsigned char *)iname->name;
|
||||
fname->disk_name.len = iname->len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fscrypt_free_filename(struct fscrypt_name *fname)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_fname_alloc_buffer(const struct inode *inode,
|
||||
u32 max_encrypted_len,
|
||||
struct fscrypt_str *crypto_str)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_fname_disk_to_usr(struct inode *inode,
|
||||
u32 hash, u32 minor_hash,
|
||||
const struct fscrypt_str *iname,
|
||||
struct fscrypt_str *oname)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
|
||||
const u8 *de_name, u32 de_name_len)
|
||||
{
|
||||
/* Encryption support disabled; use standard comparison */
|
||||
if (de_name_len != fname->disk_name.len)
|
||||
return false;
|
||||
return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
|
||||
}
|
||||
|
||||
/* bio.c */
|
||||
static inline void fscrypt_decrypt_bio(struct bio *bio)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
|
||||
struct bio *bio)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void fscrypt_pullback_bio_page(struct page **page, bool restore)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
|
||||
sector_t pblk, unsigned int len)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* hooks.c */
|
||||
|
||||
static inline int fscrypt_file_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
if (IS_ENCRYPTED(inode))
|
||||
return -EOPNOTSUPP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_prepare_link(struct inode *inode,
|
||||
struct inode *dir)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_prepare_rename(struct inode *old_dir,
|
||||
struct dentry *old_dentry,
|
||||
struct inode *new_dir,
|
||||
struct dentry *new_dentry,
|
||||
unsigned int flags)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_prepare_lookup(struct inode *dir,
|
||||
struct dentry *dentry)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_prepare_symlink(struct inode *dir,
|
||||
unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_encrypt_symlink(struct inode *inode,
|
||||
const char *target,
|
||||
unsigned int len,
|
||||
struct fscrypt_str *disk_link)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline const char *fscrypt_get_symlink(struct inode *inode,
|
||||
const void *caddr,
|
||||
unsigned int max_size,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
#endif /* _LINUX_FSCRYPT_NOTSUPP_H */
|
@@ -1,204 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* fscrypt_supp.h
|
||||
*
|
||||
* Do not include this file directly. Use fscrypt.h instead!
|
||||
*/
|
||||
#ifndef _LINUX_FSCRYPT_H
|
||||
#error "Incorrect include of linux/fscrypt_supp.h!"
|
||||
#endif
|
||||
|
||||
#ifndef _LINUX_FSCRYPT_SUPP_H
|
||||
#define _LINUX_FSCRYPT_SUPP_H
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/*
|
||||
* fscrypt superblock flags
|
||||
*/
|
||||
#define FS_CFLG_OWN_PAGES (1U << 1)
|
||||
|
||||
/*
|
||||
* crypto operations for filesystems
|
||||
*/
|
||||
struct fscrypt_operations {
|
||||
unsigned int flags;
|
||||
const char *key_prefix;
|
||||
int (*get_context)(struct inode *, void *, size_t);
|
||||
int (*set_context)(struct inode *, const void *, size_t, void *);
|
||||
bool (*dummy_context)(struct inode *);
|
||||
bool (*empty_dir)(struct inode *);
|
||||
unsigned int max_namelen;
|
||||
};
|
||||
|
||||
struct fscrypt_ctx {
|
||||
union {
|
||||
struct {
|
||||
struct page *bounce_page; /* Ciphertext page */
|
||||
struct page *control_page; /* Original page */
|
||||
} w;
|
||||
struct {
|
||||
struct bio *bio;
|
||||
struct work_struct work;
|
||||
} r;
|
||||
struct list_head free_list; /* Free list */
|
||||
};
|
||||
u8 flags; /* Flags */
|
||||
};
|
||||
|
||||
static inline bool fscrypt_has_encryption_key(const struct inode *inode)
|
||||
{
|
||||
return (inode->i_crypt_info != NULL);
|
||||
}
|
||||
|
||||
static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
return inode->i_sb->s_cop->dummy_context &&
|
||||
inode->i_sb->s_cop->dummy_context(inode);
|
||||
}
|
||||
|
||||
/* crypto.c */
|
||||
extern void fscrypt_enqueue_decrypt_work(struct work_struct *);
|
||||
extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
|
||||
extern void fscrypt_release_ctx(struct fscrypt_ctx *);
|
||||
extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
|
||||
unsigned int, unsigned int,
|
||||
u64, gfp_t);
|
||||
extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int,
|
||||
unsigned int, u64);
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
|
||||
}
|
||||
|
||||
extern void fscrypt_restore_control_page(struct page *);
|
||||
|
||||
/* policy.c */
|
||||
extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
|
||||
extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
|
||||
extern int fscrypt_has_permitted_context(struct inode *, struct inode *);
|
||||
extern int fscrypt_inherit_context(struct inode *, struct inode *,
|
||||
void *, bool);
|
||||
/* keyinfo.c */
|
||||
extern int fscrypt_get_encryption_info(struct inode *);
|
||||
extern void fscrypt_put_encryption_info(struct inode *);
|
||||
|
||||
/* fname.c */
|
||||
extern int fscrypt_setup_filename(struct inode *, const struct qstr *,
|
||||
int lookup, struct fscrypt_name *);
|
||||
|
||||
static inline void fscrypt_free_filename(struct fscrypt_name *fname)
|
||||
{
|
||||
kfree(fname->crypto_buf.name);
|
||||
}
|
||||
|
||||
extern int fscrypt_fname_alloc_buffer(const struct inode *, u32,
|
||||
struct fscrypt_str *);
|
||||
extern void fscrypt_fname_free_buffer(struct fscrypt_str *);
|
||||
extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32,
|
||||
const struct fscrypt_str *, struct fscrypt_str *);
|
||||
|
||||
#define FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE 32
|
||||
|
||||
/* Extracts the second-to-last ciphertext block; see explanation below */
|
||||
#define FSCRYPT_FNAME_DIGEST(name, len) \
|
||||
((name) + round_down((len) - FS_CRYPTO_BLOCK_SIZE - 1, \
|
||||
FS_CRYPTO_BLOCK_SIZE))
|
||||
|
||||
#define FSCRYPT_FNAME_DIGEST_SIZE FS_CRYPTO_BLOCK_SIZE
|
||||
|
||||
/**
|
||||
* fscrypt_digested_name - alternate identifier for an on-disk filename
|
||||
*
|
||||
* When userspace lists an encrypted directory without access to the key,
|
||||
* filenames whose ciphertext is longer than FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE
|
||||
* bytes are shown in this abbreviated form (base64-encoded) rather than as the
|
||||
* full ciphertext (base64-encoded). This is necessary to allow supporting
|
||||
* filenames up to NAME_MAX bytes, since base64 encoding expands the length.
|
||||
*
|
||||
* To make it possible for filesystems to still find the correct directory entry
|
||||
* despite not knowing the full on-disk name, we encode any filesystem-specific
|
||||
* 'hash' and/or 'minor_hash' which the filesystem may need for its lookups,
|
||||
* followed by the second-to-last ciphertext block of the filename. Due to the
|
||||
* use of the CBC-CTS encryption mode, the second-to-last ciphertext block
|
||||
* depends on the full plaintext. (Note that ciphertext stealing causes the
|
||||
* last two blocks to appear "flipped".) This makes accidental collisions very
|
||||
* unlikely: just a 1 in 2^128 chance for two filenames to collide even if they
|
||||
* share the same filesystem-specific hashes.
|
||||
*
|
||||
* However, this scheme isn't immune to intentional collisions, which can be
|
||||
* created by anyone able to create arbitrary plaintext filenames and view them
|
||||
* without the key. Making the "digest" be a real cryptographic hash like
|
||||
* SHA-256 over the full ciphertext would prevent this, although it would be
|
||||
* less efficient and harder to implement, especially since the filesystem would
|
||||
* need to calculate it for each directory entry examined during a search.
|
||||
*/
|
||||
struct fscrypt_digested_name {
|
||||
u32 hash;
|
||||
u32 minor_hash;
|
||||
u8 digest[FSCRYPT_FNAME_DIGEST_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* fscrypt_match_name() - test whether the given name matches a directory entry
|
||||
* @fname: the name being searched for
|
||||
* @de_name: the name from the directory entry
|
||||
* @de_name_len: the length of @de_name in bytes
|
||||
*
|
||||
* Normally @fname->disk_name will be set, and in that case we simply compare
|
||||
* that to the name stored in the directory entry. The only exception is that
|
||||
* if we don't have the key for an encrypted directory and a filename in it is
|
||||
* very long, then we won't have the full disk_name and we'll instead need to
|
||||
* match against the fscrypt_digested_name.
|
||||
*
|
||||
* Return: %true if the name matches, otherwise %false.
|
||||
*/
|
||||
static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
|
||||
const u8 *de_name, u32 de_name_len)
|
||||
{
|
||||
if (unlikely(!fname->disk_name.name)) {
|
||||
const struct fscrypt_digested_name *n =
|
||||
(const void *)fname->crypto_buf.name;
|
||||
if (WARN_ON_ONCE(fname->usr_fname->name[0] != '_'))
|
||||
return false;
|
||||
if (de_name_len <= FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE)
|
||||
return false;
|
||||
return !memcmp(FSCRYPT_FNAME_DIGEST(de_name, de_name_len),
|
||||
n->digest, FSCRYPT_FNAME_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
if (de_name_len != fname->disk_name.len)
|
||||
return false;
|
||||
return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
|
||||
}
|
||||
|
||||
/* bio.c */
|
||||
extern void fscrypt_decrypt_bio(struct bio *);
|
||||
extern void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
|
||||
struct bio *bio);
|
||||
extern void fscrypt_pullback_bio_page(struct page **, bool);
|
||||
extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t,
|
||||
unsigned int);
|
||||
|
||||
/* hooks.c */
|
||||
extern int fscrypt_file_open(struct inode *inode, struct file *filp);
|
||||
extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir);
|
||||
extern int __fscrypt_prepare_rename(struct inode *old_dir,
|
||||
struct dentry *old_dentry,
|
||||
struct inode *new_dir,
|
||||
struct dentry *new_dentry,
|
||||
unsigned int flags);
|
||||
extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry);
|
||||
extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link);
|
||||
extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
|
||||
unsigned int len,
|
||||
struct fscrypt_str *disk_link);
|
||||
extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
|
||||
unsigned int max_size,
|
||||
struct delayed_call *done);
|
||||
|
||||
#endif /* _LINUX_FSCRYPT_SUPP_H */
|
@@ -135,8 +135,6 @@ struct ccsr_guts {
|
||||
u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
u32 fsl_guts_get_svr(void);
|
||||
|
||||
/* Alternate function signal multiplex control */
|
||||
#define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))
|
||||
|
||||
|
@@ -193,6 +193,7 @@ struct fsl_mc_device {
|
||||
struct resource *regions;
|
||||
struct fsl_mc_device_irq **irqs;
|
||||
struct fsl_mc_resource *resource;
|
||||
struct device_link *consumer_link;
|
||||
};
|
||||
|
||||
#define to_fsl_mc_device(_dev) \
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#define __PTP_QORIQ_H__
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ptp_clock_kernel.h>
|
||||
|
||||
/*
|
||||
@@ -49,7 +50,7 @@ struct etts_regs {
|
||||
u32 tmr_etts2_l; /* Timestamp of general purpose external trigger */
|
||||
};
|
||||
|
||||
struct qoriq_ptp_registers {
|
||||
struct ptp_qoriq_registers {
|
||||
struct ctrl_regs __iomem *ctrl_regs;
|
||||
struct alarm_regs __iomem *alarm_regs;
|
||||
struct fiper_regs __iomem *fiper_regs;
|
||||
@@ -57,15 +58,15 @@ struct qoriq_ptp_registers {
|
||||
};
|
||||
|
||||
/* Offset definitions for the four register groups */
|
||||
#define CTRL_REGS_OFFSET 0x0
|
||||
#define ALARM_REGS_OFFSET 0x40
|
||||
#define FIPER_REGS_OFFSET 0x80
|
||||
#define ETTS_REGS_OFFSET 0xa0
|
||||
#define ETSEC_CTRL_REGS_OFFSET 0x0
|
||||
#define ETSEC_ALARM_REGS_OFFSET 0x40
|
||||
#define ETSEC_FIPER_REGS_OFFSET 0x80
|
||||
#define ETSEC_ETTS_REGS_OFFSET 0xa0
|
||||
|
||||
#define FMAN_CTRL_REGS_OFFSET 0x80
|
||||
#define FMAN_ALARM_REGS_OFFSET 0xb8
|
||||
#define FMAN_FIPER_REGS_OFFSET 0xd0
|
||||
#define FMAN_ETTS_REGS_OFFSET 0xe0
|
||||
#define CTRL_REGS_OFFSET 0x80
|
||||
#define ALARM_REGS_OFFSET 0xb8
|
||||
#define FIPER_REGS_OFFSET 0xd0
|
||||
#define ETTS_REGS_OFFSET 0xe0
|
||||
|
||||
|
||||
/* Bit definitions for the TMR_CTRL register */
|
||||
@@ -120,6 +121,8 @@ struct qoriq_ptp_registers {
|
||||
/* Bit definitions for the TMR_STAT register */
|
||||
#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */
|
||||
#define STAT_VEC_MASK (0x3f)
|
||||
#define ETS1_VLD (1<<24)
|
||||
#define ETS2_VLD (1<<25)
|
||||
|
||||
/* Bit definitions for the TMR_PRSC register */
|
||||
#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */
|
||||
@@ -134,13 +137,16 @@ struct qoriq_ptp_registers {
|
||||
#define DEFAULT_FIPER1_PERIOD 1000000000
|
||||
#define DEFAULT_FIPER2_PERIOD 100000
|
||||
|
||||
struct qoriq_ptp {
|
||||
struct ptp_qoriq {
|
||||
void __iomem *base;
|
||||
struct qoriq_ptp_registers regs;
|
||||
struct ptp_qoriq_registers regs;
|
||||
spinlock_t lock; /* protects regs */
|
||||
struct ptp_clock *clock;
|
||||
struct ptp_clock_info caps;
|
||||
struct resource *rsrc;
|
||||
struct dentry *debugfs_root;
|
||||
struct device *dev;
|
||||
bool extts_fifo_support;
|
||||
int irq;
|
||||
int phc_index;
|
||||
u64 alarm_interval; /* for periodic alarm */
|
||||
@@ -151,19 +157,49 @@ struct qoriq_ptp {
|
||||
u32 cksel;
|
||||
u32 tmr_fiper1;
|
||||
u32 tmr_fiper2;
|
||||
u32 (*read)(unsigned __iomem *addr);
|
||||
void (*write)(unsigned __iomem *addr, u32 val);
|
||||
};
|
||||
|
||||
static inline u32 qoriq_read(unsigned __iomem *addr)
|
||||
static inline u32 qoriq_read_be(unsigned __iomem *addr)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = ioread32be(addr);
|
||||
return val;
|
||||
return ioread32be(addr);
|
||||
}
|
||||
|
||||
static inline void qoriq_write(unsigned __iomem *addr, u32 val)
|
||||
static inline void qoriq_write_be(unsigned __iomem *addr, u32 val)
|
||||
{
|
||||
iowrite32be(val, addr);
|
||||
}
|
||||
|
||||
static inline u32 qoriq_read_le(unsigned __iomem *addr)
|
||||
{
|
||||
return ioread32(addr);
|
||||
}
|
||||
|
||||
static inline void qoriq_write_le(unsigned __iomem *addr, u32 val)
|
||||
{
|
||||
iowrite32(val, addr);
|
||||
}
|
||||
|
||||
irqreturn_t ptp_qoriq_isr(int irq, void *priv);
|
||||
int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base,
|
||||
const struct ptp_clock_info *caps);
|
||||
void ptp_qoriq_free(struct ptp_qoriq *ptp_qoriq);
|
||||
int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm);
|
||||
int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta);
|
||||
int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts);
|
||||
int ptp_qoriq_settime(struct ptp_clock_info *ptp,
|
||||
const struct timespec64 *ts);
|
||||
int ptp_qoriq_enable(struct ptp_clock_info *ptp,
|
||||
struct ptp_clock_request *rq, int on);
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void ptp_qoriq_create_debugfs(struct ptp_qoriq *ptp_qoriq);
|
||||
void ptp_qoriq_remove_debugfs(struct ptp_qoriq *ptp_qoriq);
|
||||
#else
|
||||
static inline void ptp_qoriq_create_debugfs(struct ptp_qoriq *ptp_qoriq)
|
||||
{ }
|
||||
static inline void ptp_qoriq_remove_debugfs(struct ptp_qoriq *ptp_qoriq)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -98,10 +98,11 @@ struct fsl_usb2_platform_data {
|
||||
|
||||
unsigned suspended:1;
|
||||
unsigned already_suspended:1;
|
||||
unsigned has_fsl_erratum_a007792:1;
|
||||
unsigned has_fsl_erratum_a005275:1;
|
||||
unsigned has_fsl_erratum_a007792:1;
|
||||
unsigned has_fsl_erratum_14:1;
|
||||
unsigned has_fsl_erratum_a005275:1;
|
||||
unsigned has_fsl_erratum_a005697:1;
|
||||
unsigned check_phy_clk_valid:1;
|
||||
unsigned check_phy_clk_valid:1;
|
||||
|
||||
/* register save area for suspend/resume */
|
||||
u32 pm_command;
|
||||
|
@@ -17,8 +17,22 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bug.h>
|
||||
|
||||
/*
|
||||
* Notify this @dir inode about a change in the directory entry @dentry.
|
||||
*
|
||||
* Unlike fsnotify_parent(), the event will be reported regardless of the
|
||||
* FS_EVENT_ON_CHILD mask on the parent inode.
|
||||
*/
|
||||
static inline int fsnotify_dirent(struct inode *dir, struct dentry *dentry,
|
||||
__u32 mask)
|
||||
{
|
||||
return fsnotify(dir, mask, d_inode(dentry), FSNOTIFY_EVENT_INODE,
|
||||
dentry->d_name.name, 0);
|
||||
}
|
||||
|
||||
/* Notify this dentry's parent about a child's events. */
|
||||
static inline int fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask)
|
||||
static inline int fsnotify_parent(const struct path *path,
|
||||
struct dentry *dentry, __u32 mask)
|
||||
{
|
||||
if (!dentry)
|
||||
dentry = path->dentry;
|
||||
@@ -65,6 +79,9 @@ static inline int fsnotify_perm(struct file *file, int mask)
|
||||
fsnotify_mask = FS_ACCESS_PERM;
|
||||
}
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
fsnotify_mask |= FS_ISDIR;
|
||||
|
||||
return fsnotify_path(inode, path, fsnotify_mask);
|
||||
}
|
||||
|
||||
@@ -73,7 +90,12 @@ static inline int fsnotify_perm(struct file *file, int mask)
|
||||
*/
|
||||
static inline void fsnotify_link_count(struct inode *inode)
|
||||
{
|
||||
fsnotify(inode, FS_ATTRIB, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
|
||||
__u32 mask = FS_ATTRIB;
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
mask |= FS_ISDIR;
|
||||
|
||||
fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,12 +103,14 @@ static inline void fsnotify_link_count(struct inode *inode)
|
||||
*/
|
||||
static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
|
||||
const unsigned char *old_name,
|
||||
int isdir, struct inode *target, struct dentry *moved)
|
||||
int isdir, struct inode *target,
|
||||
struct dentry *moved)
|
||||
{
|
||||
struct inode *source = moved->d_inode;
|
||||
u32 fs_cookie = fsnotify_get_cookie();
|
||||
__u32 old_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_FROM);
|
||||
__u32 new_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_TO);
|
||||
__u32 old_dir_mask = FS_MOVED_FROM;
|
||||
__u32 new_dir_mask = FS_MOVED_TO;
|
||||
__u32 mask = FS_MOVE_SELF;
|
||||
const unsigned char *new_name = moved->d_name.name;
|
||||
|
||||
if (old_dir == new_dir)
|
||||
@@ -95,6 +119,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
|
||||
if (isdir) {
|
||||
old_dir_mask |= FS_ISDIR;
|
||||
new_dir_mask |= FS_ISDIR;
|
||||
mask |= FS_ISDIR;
|
||||
}
|
||||
|
||||
fsnotify(old_dir, old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_name,
|
||||
@@ -106,7 +131,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
|
||||
fsnotify_link_count(target);
|
||||
|
||||
if (source)
|
||||
fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0);
|
||||
fsnotify(source, mask, source, FSNOTIFY_EVENT_INODE, NULL, 0);
|
||||
audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE);
|
||||
}
|
||||
|
||||
@@ -128,15 +153,35 @@ static inline void fsnotify_vfsmount_delete(struct vfsmount *mnt)
|
||||
|
||||
/*
|
||||
* fsnotify_nameremove - a filename was removed from a directory
|
||||
*
|
||||
* This is mostly called under parent vfs inode lock so name and
|
||||
* dentry->d_parent should be stable. However there are some corner cases where
|
||||
* inode lock is not held. So to be on the safe side and be reselient to future
|
||||
* callers and out of tree users of d_delete(), we do not assume that d_parent
|
||||
* and d_name are stable and we use dget_parent() and
|
||||
* take_dentry_name_snapshot() to grab stable references.
|
||||
*/
|
||||
static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
|
||||
{
|
||||
struct dentry *parent;
|
||||
struct name_snapshot name;
|
||||
__u32 mask = FS_DELETE;
|
||||
|
||||
/* d_delete() of pseudo inode? (e.g. __ns_get_path() playing tricks) */
|
||||
if (IS_ROOT(dentry))
|
||||
return;
|
||||
|
||||
if (isdir)
|
||||
mask |= FS_ISDIR;
|
||||
|
||||
fsnotify_parent(NULL, dentry, mask);
|
||||
parent = dget_parent(dentry);
|
||||
take_dentry_name_snapshot(&name, dentry);
|
||||
|
||||
fsnotify(d_inode(parent), mask, d_inode(dentry), FSNOTIFY_EVENT_INODE,
|
||||
name.name, 0);
|
||||
|
||||
release_dentry_name_snapshot(&name);
|
||||
dput(parent);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -144,7 +189,12 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
|
||||
*/
|
||||
static inline void fsnotify_inoderemove(struct inode *inode)
|
||||
{
|
||||
fsnotify(inode, FS_DELETE_SELF, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
|
||||
__u32 mask = FS_DELETE_SELF;
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
mask |= FS_ISDIR;
|
||||
|
||||
fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
|
||||
__fsnotify_inode_delete(inode);
|
||||
}
|
||||
|
||||
@@ -155,7 +205,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
|
||||
{
|
||||
audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
|
||||
|
||||
fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
|
||||
fsnotify_dirent(inode, dentry, FS_CREATE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -176,12 +226,9 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct
|
||||
*/
|
||||
static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
|
||||
{
|
||||
__u32 mask = (FS_CREATE | FS_ISDIR);
|
||||
struct inode *d_inode = dentry->d_inode;
|
||||
|
||||
audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
|
||||
|
||||
fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
|
||||
fsnotify_dirent(inode, dentry, FS_CREATE | FS_ISDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -59,27 +59,33 @@
|
||||
* dnotify and inotify. */
|
||||
#define FS_EVENT_ON_CHILD 0x08000000
|
||||
|
||||
/* This is a list of all events that may get sent to a parernt based on fs event
|
||||
* happening to inodes inside that directory */
|
||||
#define FS_EVENTS_POSS_ON_CHILD (FS_ACCESS | FS_MODIFY | FS_ATTRIB |\
|
||||
FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN |\
|
||||
FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE |\
|
||||
FS_DELETE | FS_OPEN_PERM | FS_ACCESS_PERM | \
|
||||
FS_OPEN_EXEC | FS_OPEN_EXEC_PERM)
|
||||
|
||||
#define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO)
|
||||
|
||||
/*
|
||||
* Directory entry modification events - reported only to directory
|
||||
* where entry is modified and not to a watching parent.
|
||||
* The watching parent may get an FS_ATTRIB|FS_EVENT_ON_CHILD event
|
||||
* when a directory entry inside a child subdir changes.
|
||||
*/
|
||||
#define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE)
|
||||
|
||||
#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM | \
|
||||
FS_OPEN_EXEC_PERM)
|
||||
|
||||
/*
|
||||
* This is a list of all events that may get sent to a parent based on fs event
|
||||
* happening to inodes inside that directory.
|
||||
*/
|
||||
#define FS_EVENTS_POSS_ON_CHILD (ALL_FSNOTIFY_PERM_EVENTS | \
|
||||
FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
|
||||
FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | \
|
||||
FS_OPEN | FS_OPEN_EXEC)
|
||||
|
||||
/* Events that can be reported to backends */
|
||||
#define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
|
||||
FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
|
||||
FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
|
||||
FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \
|
||||
FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
|
||||
FS_OPEN_PERM | FS_ACCESS_PERM | FS_DN_RENAME | \
|
||||
FS_OPEN_EXEC | FS_OPEN_EXEC_PERM)
|
||||
#define ALL_FSNOTIFY_EVENTS (ALL_FSNOTIFY_DIRENT_EVENTS | \
|
||||
FS_EVENTS_POSS_ON_CHILD | \
|
||||
FS_DELETE_SELF | FS_MOVE_SELF | FS_DN_RENAME | \
|
||||
FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED)
|
||||
|
||||
/* Extra flags that may be reported with event or control handling of events */
|
||||
#define ALL_FSNOTIFY_FLAGS (FS_EXCL_UNLINK | FS_ISDIR | FS_IN_ONESHOT | \
|
||||
@@ -129,7 +135,6 @@ struct fsnotify_event {
|
||||
struct list_head list;
|
||||
/* inode may ONLY be dereferenced during handle_event(). */
|
||||
struct inode *inode; /* either the inode the event happened to or its parent */
|
||||
u32 mask; /* the type of access, bitwise OR for FS_* event types */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -288,6 +293,7 @@ typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t;
|
||||
struct fsnotify_mark_connector {
|
||||
spinlock_t lock;
|
||||
unsigned int type; /* Type of object [lock] */
|
||||
__kernel_fsid_t fsid; /* fsid of filesystem containing object */
|
||||
union {
|
||||
/* Object pointer [lock] */
|
||||
fsnotify_connp_t *obj;
|
||||
@@ -416,6 +422,9 @@ extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group);
|
||||
extern struct fsnotify_event *fsnotify_peek_first_event(struct fsnotify_group *group);
|
||||
/* return AND dequeue the first event on the notification queue */
|
||||
extern struct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group *group);
|
||||
/* Remove event queued in the notification list */
|
||||
extern void fsnotify_remove_queued_event(struct fsnotify_group *group,
|
||||
struct fsnotify_event *event);
|
||||
|
||||
/* functions used to manipulate the marks attached to inodes */
|
||||
|
||||
@@ -428,28 +437,35 @@ extern void fsnotify_init_mark(struct fsnotify_mark *mark,
|
||||
/* Find mark belonging to given group in the list of marks */
|
||||
extern struct fsnotify_mark *fsnotify_find_mark(fsnotify_connp_t *connp,
|
||||
struct fsnotify_group *group);
|
||||
/* Get cached fsid of filesystem containing object */
|
||||
extern int fsnotify_get_conn_fsid(const struct fsnotify_mark_connector *conn,
|
||||
__kernel_fsid_t *fsid);
|
||||
/* attach the mark to the object */
|
||||
extern int fsnotify_add_mark(struct fsnotify_mark *mark,
|
||||
fsnotify_connp_t *connp, unsigned int type,
|
||||
int allow_dups);
|
||||
int allow_dups, __kernel_fsid_t *fsid);
|
||||
extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
|
||||
fsnotify_connp_t *connp, unsigned int type,
|
||||
int allow_dups);
|
||||
fsnotify_connp_t *connp,
|
||||
unsigned int type, int allow_dups,
|
||||
__kernel_fsid_t *fsid);
|
||||
|
||||
/* attach the mark to the inode */
|
||||
static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
|
||||
struct inode *inode,
|
||||
int allow_dups)
|
||||
{
|
||||
return fsnotify_add_mark(mark, &inode->i_fsnotify_marks,
|
||||
FSNOTIFY_OBJ_TYPE_INODE, allow_dups);
|
||||
FSNOTIFY_OBJ_TYPE_INODE, allow_dups, NULL);
|
||||
}
|
||||
static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark,
|
||||
struct inode *inode,
|
||||
int allow_dups)
|
||||
{
|
||||
return fsnotify_add_mark_locked(mark, &inode->i_fsnotify_marks,
|
||||
FSNOTIFY_OBJ_TYPE_INODE, allow_dups);
|
||||
FSNOTIFY_OBJ_TYPE_INODE, allow_dups,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* given a group and a mark, flag mark to be freed when all references are dropped */
|
||||
extern void fsnotify_destroy_mark(struct fsnotify_mark *mark,
|
||||
struct fsnotify_group *group);
|
||||
@@ -479,9 +495,12 @@ extern void fsnotify_put_mark(struct fsnotify_mark *mark);
|
||||
extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info);
|
||||
extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);
|
||||
|
||||
/* put here because inotify does some weird stuff when destroying watches */
|
||||
extern void fsnotify_init_event(struct fsnotify_event *event,
|
||||
struct inode *to_tell, u32 mask);
|
||||
static inline void fsnotify_init_event(struct fsnotify_event *event,
|
||||
struct inode *inode)
|
||||
{
|
||||
INIT_LIST_HEAD(&event->list);
|
||||
event->inode = inode;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
231
include/linux/generic-radix-tree.h
Normal file
231
include/linux/generic-radix-tree.h
Normal file
@@ -0,0 +1,231 @@
|
||||
#ifndef _LINUX_GENERIC_RADIX_TREE_H
|
||||
#define _LINUX_GENERIC_RADIX_TREE_H
|
||||
|
||||
/**
|
||||
* DOC: Generic radix trees/sparse arrays:
|
||||
*
|
||||
* Very simple and minimalistic, supporting arbitrary size entries up to
|
||||
* PAGE_SIZE.
|
||||
*
|
||||
* A genradix is defined with the type it will store, like so:
|
||||
*
|
||||
* static GENRADIX(struct foo) foo_genradix;
|
||||
*
|
||||
* The main operations are:
|
||||
*
|
||||
* - genradix_init(radix) - initialize an empty genradix
|
||||
*
|
||||
* - genradix_free(radix) - free all memory owned by the genradix and
|
||||
* reinitialize it
|
||||
*
|
||||
* - genradix_ptr(radix, idx) - gets a pointer to the entry at idx, returning
|
||||
* NULL if that entry does not exist
|
||||
*
|
||||
* - genradix_ptr_alloc(radix, idx, gfp) - gets a pointer to an entry,
|
||||
* allocating it if necessary
|
||||
*
|
||||
* - genradix_for_each(radix, iter, p) - iterate over each entry in a genradix
|
||||
*
|
||||
* The radix tree allocates one page of entries at a time, so entries may exist
|
||||
* that were never explicitly allocated - they will be initialized to all
|
||||
* zeroes.
|
||||
*
|
||||
* Internally, a genradix is just a radix tree of pages, and indexing works in
|
||||
* terms of byte offsets. The wrappers in this header file use sizeof on the
|
||||
* type the radix contains to calculate a byte offset from the index - see
|
||||
* __idx_to_offset.
|
||||
*/
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/log2.h>
|
||||
|
||||
struct genradix_root;
|
||||
|
||||
struct __genradix {
|
||||
struct genradix_root __rcu *root;
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: currently, sizeof(_type) must not be larger than PAGE_SIZE:
|
||||
*/
|
||||
|
||||
#define __GENRADIX_INITIALIZER \
|
||||
{ \
|
||||
.tree = { \
|
||||
.root = NULL, \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* We use a 0 size array to stash the type we're storing without taking any
|
||||
* space at runtime - then the various accessor macros can use typeof() to get
|
||||
* to it for casts/sizeof - we also force the alignment so that storing a type
|
||||
* with a ridiculous alignment doesn't blow up the alignment or size of the
|
||||
* genradix.
|
||||
*/
|
||||
|
||||
#define GENRADIX(_type) \
|
||||
struct { \
|
||||
struct __genradix tree; \
|
||||
_type type[0] __aligned(1); \
|
||||
}
|
||||
|
||||
#define DEFINE_GENRADIX(_name, _type) \
|
||||
GENRADIX(_type) _name = __GENRADIX_INITIALIZER
|
||||
|
||||
/**
|
||||
* genradix_init - initialize a genradix
|
||||
* @_radix: genradix to initialize
|
||||
*
|
||||
* Does not fail
|
||||
*/
|
||||
#define genradix_init(_radix) \
|
||||
do { \
|
||||
*(_radix) = (typeof(*_radix)) __GENRADIX_INITIALIZER; \
|
||||
} while (0)
|
||||
|
||||
void __genradix_free(struct __genradix *);
|
||||
|
||||
/**
|
||||
* genradix_free: free all memory owned by a genradix
|
||||
* @_radix: the genradix to free
|
||||
*
|
||||
* After freeing, @_radix will be reinitialized and empty
|
||||
*/
|
||||
#define genradix_free(_radix) __genradix_free(&(_radix)->tree)
|
||||
|
||||
static inline size_t __idx_to_offset(size_t idx, size_t obj_size)
|
||||
{
|
||||
if (__builtin_constant_p(obj_size))
|
||||
BUILD_BUG_ON(obj_size > PAGE_SIZE);
|
||||
else
|
||||
BUG_ON(obj_size > PAGE_SIZE);
|
||||
|
||||
if (!is_power_of_2(obj_size)) {
|
||||
size_t objs_per_page = PAGE_SIZE / obj_size;
|
||||
|
||||
return (idx / objs_per_page) * PAGE_SIZE +
|
||||
(idx % objs_per_page) * obj_size;
|
||||
} else {
|
||||
return idx * obj_size;
|
||||
}
|
||||
}
|
||||
|
||||
#define __genradix_cast(_radix) (typeof((_radix)->type[0]) *)
|
||||
#define __genradix_obj_size(_radix) sizeof((_radix)->type[0])
|
||||
#define __genradix_idx_to_offset(_radix, _idx) \
|
||||
__idx_to_offset(_idx, __genradix_obj_size(_radix))
|
||||
|
||||
void *__genradix_ptr(struct __genradix *, size_t);
|
||||
|
||||
/**
|
||||
* genradix_ptr - get a pointer to a genradix entry
|
||||
* @_radix: genradix to access
|
||||
* @_idx: index to fetch
|
||||
*
|
||||
* Returns a pointer to entry at @_idx, or NULL if that entry does not exist.
|
||||
*/
|
||||
#define genradix_ptr(_radix, _idx) \
|
||||
(__genradix_cast(_radix) \
|
||||
__genradix_ptr(&(_radix)->tree, \
|
||||
__genradix_idx_to_offset(_radix, _idx)))
|
||||
|
||||
void *__genradix_ptr_alloc(struct __genradix *, size_t, gfp_t);
|
||||
|
||||
/**
|
||||
* genradix_ptr_alloc - get a pointer to a genradix entry, allocating it
|
||||
* if necessary
|
||||
* @_radix: genradix to access
|
||||
* @_idx: index to fetch
|
||||
* @_gfp: gfp mask
|
||||
*
|
||||
* Returns a pointer to entry at @_idx, or NULL on allocation failure
|
||||
*/
|
||||
#define genradix_ptr_alloc(_radix, _idx, _gfp) \
|
||||
(__genradix_cast(_radix) \
|
||||
__genradix_ptr_alloc(&(_radix)->tree, \
|
||||
__genradix_idx_to_offset(_radix, _idx), \
|
||||
_gfp))
|
||||
|
||||
struct genradix_iter {
|
||||
size_t offset;
|
||||
size_t pos;
|
||||
};
|
||||
|
||||
/**
|
||||
* genradix_iter_init - initialize a genradix_iter
|
||||
* @_radix: genradix that will be iterated over
|
||||
* @_idx: index to start iterating from
|
||||
*/
|
||||
#define genradix_iter_init(_radix, _idx) \
|
||||
((struct genradix_iter) { \
|
||||
.pos = (_idx), \
|
||||
.offset = __genradix_idx_to_offset((_radix), (_idx)),\
|
||||
})
|
||||
|
||||
void *__genradix_iter_peek(struct genradix_iter *, struct __genradix *, size_t);
|
||||
|
||||
/**
|
||||
* genradix_iter_peek - get first entry at or above iterator's current
|
||||
* position
|
||||
* @_iter: a genradix_iter
|
||||
* @_radix: genradix being iterated over
|
||||
*
|
||||
* If no more entries exist at or above @_iter's current position, returns NULL
|
||||
*/
|
||||
#define genradix_iter_peek(_iter, _radix) \
|
||||
(__genradix_cast(_radix) \
|
||||
__genradix_iter_peek(_iter, &(_radix)->tree, \
|
||||
PAGE_SIZE / __genradix_obj_size(_radix)))
|
||||
|
||||
static inline void __genradix_iter_advance(struct genradix_iter *iter,
|
||||
size_t obj_size)
|
||||
{
|
||||
iter->offset += obj_size;
|
||||
|
||||
if (!is_power_of_2(obj_size) &&
|
||||
(iter->offset & (PAGE_SIZE - 1)) + obj_size > PAGE_SIZE)
|
||||
iter->offset = round_up(iter->offset, PAGE_SIZE);
|
||||
|
||||
iter->pos++;
|
||||
}
|
||||
|
||||
#define genradix_iter_advance(_iter, _radix) \
|
||||
__genradix_iter_advance(_iter, __genradix_obj_size(_radix))
|
||||
|
||||
#define genradix_for_each_from(_radix, _iter, _p, _start) \
|
||||
for (_iter = genradix_iter_init(_radix, _start); \
|
||||
(_p = genradix_iter_peek(&_iter, _radix)) != NULL; \
|
||||
genradix_iter_advance(&_iter, _radix))
|
||||
|
||||
/**
|
||||
* genradix_for_each - iterate over entry in a genradix
|
||||
* @_radix: genradix to iterate over
|
||||
* @_iter: a genradix_iter to track current position
|
||||
* @_p: pointer to genradix entry type
|
||||
*
|
||||
* On every iteration, @_p will point to the current entry, and @_iter.pos
|
||||
* will be the current entry's index.
|
||||
*/
|
||||
#define genradix_for_each(_radix, _iter, _p) \
|
||||
genradix_for_each_from(_radix, _iter, _p, 0)
|
||||
|
||||
int __genradix_prealloc(struct __genradix *, size_t, gfp_t);
|
||||
|
||||
/**
|
||||
* genradix_prealloc - preallocate entries in a generic radix tree
|
||||
* @_radix: genradix to preallocate
|
||||
* @_nr: number of entries to preallocate
|
||||
* @_gfp: gfp mask
|
||||
*
|
||||
* Returns 0 on success, -ENOMEM on failure
|
||||
*/
|
||||
#define genradix_prealloc(_radix, _nr, _gfp) \
|
||||
__genradix_prealloc(&(_radix)->tree, \
|
||||
__genradix_idx_to_offset(_radix, _nr + 1),\
|
||||
_gfp)
|
||||
|
||||
|
||||
#endif /* _LINUX_GENERIC_RADIX_TREE_H */
|
@@ -24,21 +24,21 @@ struct vm_area_struct;
|
||||
#define ___GFP_HIGH 0x20u
|
||||
#define ___GFP_IO 0x40u
|
||||
#define ___GFP_FS 0x80u
|
||||
#define ___GFP_WRITE 0x100u
|
||||
#define ___GFP_NOWARN 0x200u
|
||||
#define ___GFP_RETRY_MAYFAIL 0x400u
|
||||
#define ___GFP_NOFAIL 0x800u
|
||||
#define ___GFP_NORETRY 0x1000u
|
||||
#define ___GFP_MEMALLOC 0x2000u
|
||||
#define ___GFP_COMP 0x4000u
|
||||
#define ___GFP_ZERO 0x8000u
|
||||
#define ___GFP_NOMEMALLOC 0x10000u
|
||||
#define ___GFP_HARDWALL 0x20000u
|
||||
#define ___GFP_THISNODE 0x40000u
|
||||
#define ___GFP_ATOMIC 0x80000u
|
||||
#define ___GFP_ACCOUNT 0x100000u
|
||||
#define ___GFP_DIRECT_RECLAIM 0x200000u
|
||||
#define ___GFP_KSWAPD_RECLAIM 0x400000u
|
||||
#define ___GFP_ZERO 0x100u
|
||||
#define ___GFP_ATOMIC 0x200u
|
||||
#define ___GFP_DIRECT_RECLAIM 0x400u
|
||||
#define ___GFP_KSWAPD_RECLAIM 0x800u
|
||||
#define ___GFP_WRITE 0x1000u
|
||||
#define ___GFP_NOWARN 0x2000u
|
||||
#define ___GFP_RETRY_MAYFAIL 0x4000u
|
||||
#define ___GFP_NOFAIL 0x8000u
|
||||
#define ___GFP_NORETRY 0x10000u
|
||||
#define ___GFP_MEMALLOC 0x20000u
|
||||
#define ___GFP_COMP 0x40000u
|
||||
#define ___GFP_NOMEMALLOC 0x80000u
|
||||
#define ___GFP_HARDWALL 0x100000u
|
||||
#define ___GFP_THISNODE 0x200000u
|
||||
#define ___GFP_ACCOUNT 0x400000u
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
#define ___GFP_NOLOCKDEP 0x800000u
|
||||
#else
|
||||
|
@@ -22,6 +22,7 @@ enum gnss_type {
|
||||
GNSS_TYPE_NMEA = 0,
|
||||
GNSS_TYPE_SIRF,
|
||||
GNSS_TYPE_UBX,
|
||||
GNSS_TYPE_MTK,
|
||||
|
||||
GNSS_TYPE_COUNT
|
||||
};
|
||||
|
@@ -472,6 +472,11 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
|
||||
irq_hw_number_t hwirq);
|
||||
void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq);
|
||||
|
||||
int gpiochip_irq_domain_activate(struct irq_domain *domain,
|
||||
struct irq_data *data, bool reserve);
|
||||
void gpiochip_irq_domain_deactivate(struct irq_domain *domain,
|
||||
struct irq_data *data);
|
||||
|
||||
void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
|
||||
struct irq_chip *irqchip,
|
||||
unsigned int parent_irq,
|
||||
|
@@ -12,6 +12,8 @@ enum gpio_lookup_flags {
|
||||
GPIO_OPEN_SOURCE = (1 << 2),
|
||||
GPIO_PERSISTENT = (0 << 3),
|
||||
GPIO_TRANSITORY = (1 << 3),
|
||||
GPIO_PULL_UP = (1 << 4),
|
||||
GPIO_PULL_DOWN = (1 << 5),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -60,8 +60,14 @@ extern void irq_enter(void);
|
||||
*/
|
||||
extern void irq_exit(void);
|
||||
|
||||
#ifndef arch_nmi_enter
|
||||
#define arch_nmi_enter() do { } while (0)
|
||||
#define arch_nmi_exit() do { } while (0)
|
||||
#endif
|
||||
|
||||
#define nmi_enter() \
|
||||
do { \
|
||||
arch_nmi_enter(); \
|
||||
printk_nmi_enter(); \
|
||||
lockdep_off(); \
|
||||
ftrace_nmi_enter(); \
|
||||
@@ -80,6 +86,7 @@ extern void irq_exit(void);
|
||||
ftrace_nmi_exit(); \
|
||||
lockdep_on(); \
|
||||
printk_nmi_exit(); \
|
||||
arch_nmi_exit(); \
|
||||
} while (0)
|
||||
|
||||
#endif /* LINUX_HARDIRQ_H */
|
||||
|
@@ -27,6 +27,21 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
enum hdmi_packet_type {
|
||||
HDMI_PACKET_TYPE_NULL = 0x00,
|
||||
HDMI_PACKET_TYPE_AUDIO_CLOCK_REGEN = 0x01,
|
||||
HDMI_PACKET_TYPE_AUDIO_SAMPLE = 0x02,
|
||||
HDMI_PACKET_TYPE_GENERAL_CONTROL = 0x03,
|
||||
HDMI_PACKET_TYPE_ACP = 0x04,
|
||||
HDMI_PACKET_TYPE_ISRC1 = 0x05,
|
||||
HDMI_PACKET_TYPE_ISRC2 = 0x06,
|
||||
HDMI_PACKET_TYPE_ONE_BIT_AUDIO_SAMPLE = 0x07,
|
||||
HDMI_PACKET_TYPE_DST_AUDIO = 0x08,
|
||||
HDMI_PACKET_TYPE_HBR_AUDIO_STREAM = 0x09,
|
||||
HDMI_PACKET_TYPE_GAMUT_METADATA = 0x0a,
|
||||
/* + enum hdmi_infoframe_type */
|
||||
};
|
||||
|
||||
enum hdmi_infoframe_type {
|
||||
HDMI_INFOFRAME_TYPE_VENDOR = 0x81,
|
||||
HDMI_INFOFRAME_TYPE_AVI = 0x82,
|
||||
|
@@ -468,7 +468,7 @@ struct hmm_devmem_ops {
|
||||
* Note that mmap semaphore is held in read mode at least when this
|
||||
* callback occurs, hence the vma is valid upon callback entry.
|
||||
*/
|
||||
int (*fault)(struct hmm_devmem *devmem,
|
||||
vm_fault_t (*fault)(struct hmm_devmem *devmem,
|
||||
struct vm_area_struct *vma,
|
||||
unsigned long addr,
|
||||
const struct page *page,
|
||||
@@ -511,7 +511,7 @@ struct hmm_devmem_ops {
|
||||
* chunk, as an optimization. It must, however, prioritize the faulting address
|
||||
* over all the others.
|
||||
*/
|
||||
typedef int (*dev_page_fault_t)(struct vm_area_struct *vma,
|
||||
typedef vm_fault_t (*dev_page_fault_t)(struct vm_area_struct *vma,
|
||||
unsigned long addr,
|
||||
const struct page *page,
|
||||
unsigned int flags,
|
||||
|
@@ -371,6 +371,8 @@ struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid,
|
||||
nodemask_t *nmask);
|
||||
struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma,
|
||||
unsigned long address);
|
||||
struct page *alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
|
||||
int nid, nodemask_t *nmask);
|
||||
int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
|
||||
pgoff_t idx);
|
||||
|
||||
@@ -493,17 +495,54 @@ static inline pgoff_t basepage_index(struct page *page)
|
||||
extern int dissolve_free_huge_page(struct page *page);
|
||||
extern int dissolve_free_huge_pages(unsigned long start_pfn,
|
||||
unsigned long end_pfn);
|
||||
static inline bool hugepage_migration_supported(struct hstate *h)
|
||||
{
|
||||
|
||||
#ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
|
||||
#ifndef arch_hugetlb_migration_supported
|
||||
static inline bool arch_hugetlb_migration_supported(struct hstate *h)
|
||||
{
|
||||
if ((huge_page_shift(h) == PMD_SHIFT) ||
|
||||
(huge_page_shift(h) == PGDIR_SHIFT))
|
||||
(huge_page_shift(h) == PUD_SHIFT) ||
|
||||
(huge_page_shift(h) == PGDIR_SHIFT))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
static inline bool arch_hugetlb_migration_supported(struct hstate *h)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool hugepage_migration_supported(struct hstate *h)
|
||||
{
|
||||
return arch_hugetlb_migration_supported(h);
|
||||
}
|
||||
|
||||
/*
|
||||
* Movability check is different as compared to migration check.
|
||||
* It determines whether or not a huge page should be placed on
|
||||
* movable zone or not. Movability of any huge page should be
|
||||
* required only if huge page size is supported for migration.
|
||||
* There wont be any reason for the huge page to be movable if
|
||||
* it is not migratable to start with. Also the size of the huge
|
||||
* page should be large enough to be placed under a movable zone
|
||||
* and still feasible enough to be migratable. Just the presence
|
||||
* in movable zone does not make the migration feasible.
|
||||
*
|
||||
* So even though large huge page sizes like the gigantic ones
|
||||
* are migratable they should not be movable because its not
|
||||
* feasible to migrate them from movable zone.
|
||||
*/
|
||||
static inline bool hugepage_movable_supported(struct hstate *h)
|
||||
{
|
||||
if (!hugepage_migration_supported(h))
|
||||
return false;
|
||||
|
||||
if (hstate_is_gigantic(h))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
|
||||
@@ -543,6 +582,26 @@ static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr
|
||||
set_huge_pte_at(mm, addr, ptep, pte);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef huge_ptep_modify_prot_start
|
||||
#define huge_ptep_modify_prot_start huge_ptep_modify_prot_start
|
||||
static inline pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
return huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef huge_ptep_modify_prot_commit
|
||||
#define huge_ptep_modify_prot_commit huge_ptep_modify_prot_commit
|
||||
static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
pte_t old_pte, pte_t pte)
|
||||
{
|
||||
set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_HUGETLB_PAGE */
|
||||
struct hstate {};
|
||||
#define alloc_huge_page(v, a, r) NULL
|
||||
@@ -602,6 +661,11 @@ static inline bool hugepage_migration_supported(struct hstate *h)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool hugepage_movable_supported(struct hstate *h)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
|
||||
struct mm_struct *mm, pte_t *pte)
|
||||
{
|
||||
|
@@ -222,8 +222,8 @@ static inline u32 hv_get_avail_to_write_percent(
|
||||
* struct contains the fundamental information about an offer.
|
||||
*/
|
||||
struct vmbus_channel_offer {
|
||||
uuid_le if_type;
|
||||
uuid_le if_instance;
|
||||
guid_t if_type;
|
||||
guid_t if_instance;
|
||||
|
||||
/*
|
||||
* These two fields are not currently used.
|
||||
@@ -614,8 +614,8 @@ struct vmbus_channel_initiate_contact {
|
||||
/* Hyper-V socket: guest's connect()-ing to host */
|
||||
struct vmbus_channel_tl_connect_request {
|
||||
struct vmbus_channel_message_header header;
|
||||
uuid_le guest_endpoint_id;
|
||||
uuid_le host_service_id;
|
||||
guid_t guest_endpoint_id;
|
||||
guid_t host_service_id;
|
||||
} __packed;
|
||||
|
||||
struct vmbus_channel_version_response {
|
||||
@@ -714,7 +714,7 @@ enum vmbus_device_type {
|
||||
|
||||
struct vmbus_device {
|
||||
u16 dev_type;
|
||||
uuid_le guid;
|
||||
guid_t guid;
|
||||
bool perf_device;
|
||||
};
|
||||
|
||||
@@ -751,6 +751,19 @@ struct vmbus_channel {
|
||||
u64 interrupts; /* Host to Guest interrupts */
|
||||
u64 sig_events; /* Guest to Host events */
|
||||
|
||||
/*
|
||||
* Guest to host interrupts caused by the outbound ring buffer changing
|
||||
* from empty to not empty.
|
||||
*/
|
||||
u64 intr_out_empty;
|
||||
|
||||
/*
|
||||
* Indicates that a full outbound ring buffer was encountered. The flag
|
||||
* is set to true when a full outbound ring buffer is encountered and
|
||||
* set to false when a write to the outbound ring buffer is completed.
|
||||
*/
|
||||
bool out_full_flag;
|
||||
|
||||
/* Channel callback's invoked in softirq context */
|
||||
struct tasklet_struct callback_event;
|
||||
void (*onchannel_callback)(void *context);
|
||||
@@ -903,6 +916,24 @@ struct vmbus_channel {
|
||||
* vmbus_connection.work_queue and hang: see vmbus_process_offer().
|
||||
*/
|
||||
struct work_struct add_channel_work;
|
||||
|
||||
/*
|
||||
* Guest to host interrupts caused by the inbound ring buffer changing
|
||||
* from full to not full while a packet is waiting.
|
||||
*/
|
||||
u64 intr_in_full;
|
||||
|
||||
/*
|
||||
* The total number of write operations that encountered a full
|
||||
* outbound ring buffer.
|
||||
*/
|
||||
u64 out_full_total;
|
||||
|
||||
/*
|
||||
* The number of write operations that were the first to encounter a
|
||||
* full outbound ring buffer.
|
||||
*/
|
||||
u64 out_full_first;
|
||||
};
|
||||
|
||||
static inline bool is_hvsock_channel(const struct vmbus_channel *c)
|
||||
@@ -936,6 +967,21 @@ static inline void *get_per_channel_state(struct vmbus_channel *c)
|
||||
static inline void set_channel_pending_send_size(struct vmbus_channel *c,
|
||||
u32 size)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (size) {
|
||||
spin_lock_irqsave(&c->outbound.ring_lock, flags);
|
||||
++c->out_full_total;
|
||||
|
||||
if (!c->out_full_flag) {
|
||||
++c->out_full_first;
|
||||
c->out_full_flag = true;
|
||||
}
|
||||
spin_unlock_irqrestore(&c->outbound.ring_lock, flags);
|
||||
} else {
|
||||
c->out_full_flag = false;
|
||||
}
|
||||
|
||||
c->outbound.ring_buffer->pending_send_sz = size;
|
||||
}
|
||||
|
||||
@@ -1096,7 +1142,7 @@ struct hv_driver {
|
||||
bool hvsock;
|
||||
|
||||
/* the device type supported by this driver */
|
||||
uuid_le dev_type;
|
||||
guid_t dev_type;
|
||||
const struct hv_vmbus_device_id *id_table;
|
||||
|
||||
struct device_driver driver;
|
||||
@@ -1116,10 +1162,10 @@ struct hv_driver {
|
||||
/* Base device object */
|
||||
struct hv_device {
|
||||
/* the device type id of this device */
|
||||
uuid_le dev_type;
|
||||
guid_t dev_type;
|
||||
|
||||
/* the device instance id of this device */
|
||||
uuid_le dev_instance;
|
||||
guid_t dev_instance;
|
||||
u16 vendor_id;
|
||||
u16 device_id;
|
||||
|
||||
@@ -1188,102 +1234,102 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size);
|
||||
* {f8615163-df3e-46c5-913f-f2d2f965ed0e}
|
||||
*/
|
||||
#define HV_NIC_GUID \
|
||||
.guid = UUID_LE(0xf8615163, 0xdf3e, 0x46c5, 0x91, 0x3f, \
|
||||
0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e)
|
||||
.guid = GUID_INIT(0xf8615163, 0xdf3e, 0x46c5, 0x91, 0x3f, \
|
||||
0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e)
|
||||
|
||||
/*
|
||||
* IDE GUID
|
||||
* {32412632-86cb-44a2-9b5c-50d1417354f5}
|
||||
*/
|
||||
#define HV_IDE_GUID \
|
||||
.guid = UUID_LE(0x32412632, 0x86cb, 0x44a2, 0x9b, 0x5c, \
|
||||
0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5)
|
||||
.guid = GUID_INIT(0x32412632, 0x86cb, 0x44a2, 0x9b, 0x5c, \
|
||||
0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5)
|
||||
|
||||
/*
|
||||
* SCSI GUID
|
||||
* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}
|
||||
*/
|
||||
#define HV_SCSI_GUID \
|
||||
.guid = UUID_LE(0xba6163d9, 0x04a1, 0x4d29, 0xb6, 0x05, \
|
||||
0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f)
|
||||
.guid = GUID_INIT(0xba6163d9, 0x04a1, 0x4d29, 0xb6, 0x05, \
|
||||
0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f)
|
||||
|
||||
/*
|
||||
* Shutdown GUID
|
||||
* {0e0b6031-5213-4934-818b-38d90ced39db}
|
||||
*/
|
||||
#define HV_SHUTDOWN_GUID \
|
||||
.guid = UUID_LE(0x0e0b6031, 0x5213, 0x4934, 0x81, 0x8b, \
|
||||
0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb)
|
||||
.guid = GUID_INIT(0x0e0b6031, 0x5213, 0x4934, 0x81, 0x8b, \
|
||||
0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb)
|
||||
|
||||
/*
|
||||
* Time Synch GUID
|
||||
* {9527E630-D0AE-497b-ADCE-E80AB0175CAF}
|
||||
*/
|
||||
#define HV_TS_GUID \
|
||||
.guid = UUID_LE(0x9527e630, 0xd0ae, 0x497b, 0xad, 0xce, \
|
||||
0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
|
||||
.guid = GUID_INIT(0x9527e630, 0xd0ae, 0x497b, 0xad, 0xce, \
|
||||
0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
|
||||
|
||||
/*
|
||||
* Heartbeat GUID
|
||||
* {57164f39-9115-4e78-ab55-382f3bd5422d}
|
||||
*/
|
||||
#define HV_HEART_BEAT_GUID \
|
||||
.guid = UUID_LE(0x57164f39, 0x9115, 0x4e78, 0xab, 0x55, \
|
||||
0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
|
||||
.guid = GUID_INIT(0x57164f39, 0x9115, 0x4e78, 0xab, 0x55, \
|
||||
0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
|
||||
|
||||
/*
|
||||
* KVP GUID
|
||||
* {a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}
|
||||
*/
|
||||
#define HV_KVP_GUID \
|
||||
.guid = UUID_LE(0xa9a0f4e7, 0x5a45, 0x4d96, 0xb8, 0x27, \
|
||||
0x8a, 0x84, 0x1e, 0x8c, 0x03, 0xe6)
|
||||
.guid = GUID_INIT(0xa9a0f4e7, 0x5a45, 0x4d96, 0xb8, 0x27, \
|
||||
0x8a, 0x84, 0x1e, 0x8c, 0x03, 0xe6)
|
||||
|
||||
/*
|
||||
* Dynamic memory GUID
|
||||
* {525074dc-8985-46e2-8057-a307dc18a502}
|
||||
*/
|
||||
#define HV_DM_GUID \
|
||||
.guid = UUID_LE(0x525074dc, 0x8985, 0x46e2, 0x80, 0x57, \
|
||||
0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02)
|
||||
.guid = GUID_INIT(0x525074dc, 0x8985, 0x46e2, 0x80, 0x57, \
|
||||
0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02)
|
||||
|
||||
/*
|
||||
* Mouse GUID
|
||||
* {cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}
|
||||
*/
|
||||
#define HV_MOUSE_GUID \
|
||||
.guid = UUID_LE(0xcfa8b69e, 0x5b4a, 0x4cc0, 0xb9, 0x8b, \
|
||||
0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a)
|
||||
.guid = GUID_INIT(0xcfa8b69e, 0x5b4a, 0x4cc0, 0xb9, 0x8b, \
|
||||
0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a)
|
||||
|
||||
/*
|
||||
* Keyboard GUID
|
||||
* {f912ad6d-2b17-48ea-bd65-f927a61c7684}
|
||||
*/
|
||||
#define HV_KBD_GUID \
|
||||
.guid = UUID_LE(0xf912ad6d, 0x2b17, 0x48ea, 0xbd, 0x65, \
|
||||
0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84)
|
||||
.guid = GUID_INIT(0xf912ad6d, 0x2b17, 0x48ea, 0xbd, 0x65, \
|
||||
0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84)
|
||||
|
||||
/*
|
||||
* VSS (Backup/Restore) GUID
|
||||
*/
|
||||
#define HV_VSS_GUID \
|
||||
.guid = UUID_LE(0x35fa2e29, 0xea23, 0x4236, 0x96, 0xae, \
|
||||
0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40)
|
||||
.guid = GUID_INIT(0x35fa2e29, 0xea23, 0x4236, 0x96, 0xae, \
|
||||
0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40)
|
||||
/*
|
||||
* Synthetic Video GUID
|
||||
* {DA0A7802-E377-4aac-8E77-0558EB1073F8}
|
||||
*/
|
||||
#define HV_SYNTHVID_GUID \
|
||||
.guid = UUID_LE(0xda0a7802, 0xe377, 0x4aac, 0x8e, 0x77, \
|
||||
0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8)
|
||||
.guid = GUID_INIT(0xda0a7802, 0xe377, 0x4aac, 0x8e, 0x77, \
|
||||
0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8)
|
||||
|
||||
/*
|
||||
* Synthetic FC GUID
|
||||
* {2f9bcc4a-0069-4af3-b76b-6fd0be528cda}
|
||||
*/
|
||||
#define HV_SYNTHFC_GUID \
|
||||
.guid = UUID_LE(0x2f9bcc4a, 0x0069, 0x4af3, 0xb7, 0x6b, \
|
||||
0x6f, 0xd0, 0xbe, 0x52, 0x8c, 0xda)
|
||||
.guid = GUID_INIT(0x2f9bcc4a, 0x0069, 0x4af3, 0xb7, 0x6b, \
|
||||
0x6f, 0xd0, 0xbe, 0x52, 0x8c, 0xda)
|
||||
|
||||
/*
|
||||
* Guest File Copy Service
|
||||
@@ -1291,16 +1337,16 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size);
|
||||
*/
|
||||
|
||||
#define HV_FCOPY_GUID \
|
||||
.guid = UUID_LE(0x34d14be3, 0xdee4, 0x41c8, 0x9a, 0xe7, \
|
||||
0x6b, 0x17, 0x49, 0x77, 0xc1, 0x92)
|
||||
.guid = GUID_INIT(0x34d14be3, 0xdee4, 0x41c8, 0x9a, 0xe7, \
|
||||
0x6b, 0x17, 0x49, 0x77, 0xc1, 0x92)
|
||||
|
||||
/*
|
||||
* NetworkDirect. This is the guest RDMA service.
|
||||
* {8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}
|
||||
*/
|
||||
#define HV_ND_GUID \
|
||||
.guid = UUID_LE(0x8c2eaf3d, 0x32a7, 0x4b09, 0xab, 0x99, \
|
||||
0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01)
|
||||
.guid = GUID_INIT(0x8c2eaf3d, 0x32a7, 0x4b09, 0xab, 0x99, \
|
||||
0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01)
|
||||
|
||||
/*
|
||||
* PCI Express Pass Through
|
||||
@@ -1308,8 +1354,8 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size);
|
||||
*/
|
||||
|
||||
#define HV_PCIE_GUID \
|
||||
.guid = UUID_LE(0x44c4f61d, 0x4444, 0x4400, 0x9d, 0x52, \
|
||||
0x80, 0x2e, 0x27, 0xed, 0xe1, 0x9f)
|
||||
.guid = GUID_INIT(0x44c4f61d, 0x4444, 0x4400, 0x9d, 0x52, \
|
||||
0x80, 0x2e, 0x27, 0xed, 0xe1, 0x9f)
|
||||
|
||||
/*
|
||||
* Linux doesn't support the 3 devices: the first two are for
|
||||
@@ -1321,16 +1367,16 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size);
|
||||
*/
|
||||
|
||||
#define HV_AVMA1_GUID \
|
||||
.guid = UUID_LE(0xf8e65716, 0x3cb3, 0x4a06, 0x9a, 0x60, \
|
||||
0x18, 0x89, 0xc5, 0xcc, 0xca, 0xb5)
|
||||
.guid = GUID_INIT(0xf8e65716, 0x3cb3, 0x4a06, 0x9a, 0x60, \
|
||||
0x18, 0x89, 0xc5, 0xcc, 0xca, 0xb5)
|
||||
|
||||
#define HV_AVMA2_GUID \
|
||||
.guid = UUID_LE(0x3375baf4, 0x9e15, 0x4b30, 0xb7, 0x65, \
|
||||
0x67, 0xac, 0xb1, 0x0d, 0x60, 0x7b)
|
||||
.guid = GUID_INIT(0x3375baf4, 0x9e15, 0x4b30, 0xb7, 0x65, \
|
||||
0x67, 0xac, 0xb1, 0x0d, 0x60, 0x7b)
|
||||
|
||||
#define HV_RDV_GUID \
|
||||
.guid = UUID_LE(0x276aacf4, 0xac15, 0x426c, 0x98, 0xdd, \
|
||||
0x75, 0x21, 0xad, 0x3f, 0x01, 0xfe)
|
||||
.guid = GUID_INIT(0x276aacf4, 0xac15, 0x426c, 0x98, 0xdd, \
|
||||
0x75, 0x21, 0xad, 0x3f, 0x01, 0xfe)
|
||||
|
||||
/*
|
||||
* Common header for Hyper-V ICs
|
||||
@@ -1432,7 +1478,7 @@ struct ictimesync_ref_data {
|
||||
struct hyperv_service_callback {
|
||||
u8 msg_type;
|
||||
char *log_msg;
|
||||
uuid_le data;
|
||||
guid_t data;
|
||||
struct vmbus_channel *channel;
|
||||
void (*callback)(void *context);
|
||||
};
|
||||
@@ -1452,8 +1498,8 @@ void vmbus_setevent(struct vmbus_channel *channel);
|
||||
|
||||
extern __u32 vmbus_proto_version;
|
||||
|
||||
int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
|
||||
const uuid_le *shv_host_servie_id);
|
||||
int vmbus_send_tl_connect_request(const guid_t *shv_guest_servie_id,
|
||||
const guid_t *shv_host_servie_id);
|
||||
void vmbus_set_event(struct vmbus_channel *channel);
|
||||
|
||||
/* Get the start of the ring buffer. */
|
||||
|
@@ -1,30 +1,17 @@
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* i2c-algo-bit.h i2c driver algorithms for bit-shift adapters */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Copyright (C) 1995-99 Simon G. Vogl
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301 USA. */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
|
||||
Frodo Looijaard <frodol@dds.nl> */
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* i2c-algo-bit.h: i2c driver algorithms for bit-shift adapters
|
||||
*
|
||||
* Copyright (C) 1995-99 Simon G. Vogl
|
||||
* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
|
||||
* Frodo Looijaard <frodol@dds.nl>
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_I2C_ALGO_BIT_H
|
||||
#define _LINUX_I2C_ALGO_BIT_H
|
||||
|
||||
#include <linux/i2c.h>
|
||||
|
||||
/* --- Defines for bit-adapters --------------------------------------- */
|
||||
/*
|
||||
* This struct contains the hw-dependent functions of bit-style adapters to
|
||||
|
@@ -333,6 +333,7 @@ struct i2c_client {
|
||||
char name[I2C_NAME_SIZE];
|
||||
struct i2c_adapter *adapter; /* the adapter we sit on */
|
||||
struct device dev; /* the device structure */
|
||||
int init_irq; /* irq set at initialization */
|
||||
int irq; /* irq issued by device */
|
||||
struct list_head detected;
|
||||
#if IS_ENABLED(CONFIG_I2C_SLAVE)
|
||||
@@ -680,6 +681,8 @@ struct i2c_adapter {
|
||||
int timeout; /* in jiffies */
|
||||
int retries;
|
||||
struct device dev; /* the adapter device */
|
||||
unsigned long locked_flags; /* owned by the I2C core */
|
||||
#define I2C_ALF_IS_SUSPENDED 0
|
||||
|
||||
int nr;
|
||||
char name[48];
|
||||
@@ -762,6 +765,38 @@ i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags)
|
||||
adapter->lock_ops->unlock_bus(adapter, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* i2c_mark_adapter_suspended - Report suspended state of the adapter to the core
|
||||
* @adap: Adapter to mark as suspended
|
||||
*
|
||||
* When using this helper to mark an adapter as suspended, the core will reject
|
||||
* further transfers to this adapter. The usage of this helper is optional but
|
||||
* recommended for devices having distinct handlers for system suspend and
|
||||
* runtime suspend. More complex devices are free to implement custom solutions
|
||||
* to reject transfers when suspended.
|
||||
*/
|
||||
static inline void i2c_mark_adapter_suspended(struct i2c_adapter *adap)
|
||||
{
|
||||
i2c_lock_bus(adap, I2C_LOCK_ROOT_ADAPTER);
|
||||
set_bit(I2C_ALF_IS_SUSPENDED, &adap->locked_flags);
|
||||
i2c_unlock_bus(adap, I2C_LOCK_ROOT_ADAPTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* i2c_mark_adapter_resumed - Report resumed state of the adapter to the core
|
||||
* @adap: Adapter to mark as resumed
|
||||
*
|
||||
* When using this helper to mark an adapter as resumed, the core will allow
|
||||
* further transfers to this adapter. See also further notes to
|
||||
* @i2c_mark_adapter_suspended().
|
||||
*/
|
||||
static inline void i2c_mark_adapter_resumed(struct i2c_adapter *adap)
|
||||
{
|
||||
i2c_lock_bus(adap, I2C_LOCK_ROOT_ADAPTER);
|
||||
clear_bit(I2C_ALF_IS_SUSPENDED, &adap->locked_flags);
|
||||
i2c_unlock_bus(adap, I2C_LOCK_ROOT_ADAPTER);
|
||||
}
|
||||
|
||||
/*flags for the client struct: */
|
||||
#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */
|
||||
#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
|
||||
@@ -933,11 +968,21 @@ static inline int of_i2c_get_board_info(struct device *dev,
|
||||
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
struct acpi_resource;
|
||||
struct acpi_resource_i2c_serialbus;
|
||||
|
||||
#if IS_ENABLED(CONFIG_ACPI)
|
||||
bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
|
||||
struct acpi_resource_i2c_serialbus **i2c);
|
||||
u32 i2c_acpi_find_bus_speed(struct device *dev);
|
||||
struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
|
||||
struct i2c_board_info *info);
|
||||
#else
|
||||
static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
|
||||
struct acpi_resource_i2c_serialbus **i2c)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline u32 i2c_acpi_find_bus_speed(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
|
@@ -8,7 +8,7 @@
|
||||
* Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright (c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (c) 2018 Intel Corporation
|
||||
* Copyright (c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -1803,6 +1803,9 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
|
||||
#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION 0x04
|
||||
#define IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU 0x08
|
||||
#define IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX 0x10
|
||||
#define IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS 0x20
|
||||
#define IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING 0x40
|
||||
#define IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX 0x80
|
||||
|
||||
/* 802.11ax HE PHY capabilities */
|
||||
#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G 0x02
|
||||
@@ -1926,11 +1929,11 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
|
||||
#define IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU 0x08
|
||||
#define IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI 0x10
|
||||
#define IEEE80211_HE_PHY_CAP8_MIDAMBLE_RX_TX_2X_AND_1XLTF 0x20
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_20MHZ 0x00
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_40MHZ 0x40
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_80MHZ 0x80
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_160_OR_80P80_MHZ 0xc0
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_MASK 0xc0
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_242 0x00
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_484 0x40
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_996 0x80
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_2x996 0xc0
|
||||
#define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_MASK 0xc0
|
||||
|
||||
#define IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM 0x01
|
||||
#define IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK 0x02
|
||||
@@ -1938,6 +1941,11 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
|
||||
#define IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU 0x08
|
||||
#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB 0x10
|
||||
#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB 0x20
|
||||
#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_0US 0x00
|
||||
#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_8US 0x40
|
||||
#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US 0x80
|
||||
#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_RESERVED 0xc0
|
||||
#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_MASK 0xc0
|
||||
|
||||
/* 802.11ax HE TX/RX MCS NSS Support */
|
||||
#define IEEE80211_TX_RX_MCS_NSS_SUPP_HIGHEST_MCS_POS (3)
|
||||
@@ -2016,7 +2024,7 @@ ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info)
|
||||
#define IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK 0x00003ff0
|
||||
#define IEEE80211_HE_OPERATION_RTS_THRESHOLD_OFFSET 4
|
||||
#define IEEE80211_HE_OPERATION_VHT_OPER_INFO 0x00004000
|
||||
#define IEEE80211_HE_OPERATION_CO_LOCATED_BSS 0x00008000
|
||||
#define IEEE80211_HE_OPERATION_CO_HOSTED_BSS 0x00008000
|
||||
#define IEEE80211_HE_OPERATION_ER_SU_DISABLE 0x00010000
|
||||
#define IEEE80211_HE_OPERATION_BSS_COLOR_MASK 0x3f000000
|
||||
#define IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET 24
|
||||
@@ -2046,7 +2054,7 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
|
||||
he_oper_params = le32_to_cpu(he_oper->he_oper_params);
|
||||
if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO)
|
||||
oper_len += 3;
|
||||
if (he_oper_params & IEEE80211_HE_OPERATION_CO_LOCATED_BSS)
|
||||
if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS)
|
||||
oper_len++;
|
||||
|
||||
/* Add the first byte (extension ID) to the total length */
|
||||
@@ -2118,6 +2126,8 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
|
||||
#define IEEE80211_SPCT_MSR_RPRT_TYPE_BASIC 0
|
||||
#define IEEE80211_SPCT_MSR_RPRT_TYPE_CCA 1
|
||||
#define IEEE80211_SPCT_MSR_RPRT_TYPE_RPI 2
|
||||
#define IEEE80211_SPCT_MSR_RPRT_TYPE_LCI 8
|
||||
#define IEEE80211_SPCT_MSR_RPRT_TYPE_CIVIC 11
|
||||
|
||||
/* 802.11g ERP information element */
|
||||
#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
|
||||
@@ -2475,6 +2485,8 @@ enum ieee80211_eid_ext {
|
||||
WLAN_EID_EXT_HE_OPERATION = 36,
|
||||
WLAN_EID_EXT_UORA = 37,
|
||||
WLAN_EID_EXT_HE_MU_EDCA = 38,
|
||||
WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME = 52,
|
||||
WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55,
|
||||
};
|
||||
|
||||
/* Action category code */
|
||||
@@ -2656,6 +2668,11 @@ enum ieee80211_tdls_actioncode {
|
||||
*/
|
||||
#define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2)
|
||||
|
||||
/* Multiple BSSID capability is set in the 6th bit of 3rd byte of the
|
||||
* @WLAN_EID_EXT_CAPABILITY information element
|
||||
*/
|
||||
#define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT BIT(6)
|
||||
|
||||
/* TDLS capabilities in the the 4th byte of @WLAN_EID_EXT_CAPABILITY */
|
||||
#define WLAN_EXT_CAPA4_TDLS_BUFFER_STA BIT(4)
|
||||
#define WLAN_EXT_CAPA4_TDLS_PEER_PSM BIT(5)
|
||||
@@ -2691,6 +2708,9 @@ enum ieee80211_tdls_actioncode {
|
||||
#define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT BIT(5)
|
||||
#define WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT BIT(6)
|
||||
|
||||
/* Defines support for enhanced multi-bssid advertisement*/
|
||||
#define WLAN_EXT_CAPA11_EMA_SUPPORT BIT(1)
|
||||
|
||||
/* TDLS specific payload type in the LLC/SNAP header */
|
||||
#define WLAN_TDLS_SNAP_RFTYPE 0x2
|
||||
|
||||
@@ -2882,6 +2902,34 @@ enum ieee80211_sa_query_action {
|
||||
WLAN_ACTION_SA_QUERY_RESPONSE = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_bssid_index
|
||||
*
|
||||
* This structure refers to "Multiple BSSID-index element"
|
||||
*
|
||||
* @bssid_index: BSSID index
|
||||
* @dtim_period: optional, overrides transmitted BSS dtim period
|
||||
* @dtim_count: optional, overrides transmitted BSS dtim count
|
||||
*/
|
||||
struct ieee80211_bssid_index {
|
||||
u8 bssid_index;
|
||||
u8 dtim_period;
|
||||
u8 dtim_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_multiple_bssid_configuration
|
||||
*
|
||||
* This structure refers to "Multiple BSSID Configuration element"
|
||||
*
|
||||
* @bssid_count: total number of active BSSIDs in the set
|
||||
* @profile_periodicity: the least number of beacon frames need to be received
|
||||
* in order to discover all the nontransmitted BSSIDs in the set.
|
||||
*/
|
||||
struct ieee80211_multiple_bssid_configuration {
|
||||
u8 bssid_count;
|
||||
u8 profile_periodicity;
|
||||
};
|
||||
|
||||
#define SUITE(oui, id) (((oui) << 8) | (id))
|
||||
|
||||
@@ -3243,4 +3291,57 @@ static inline bool ieee80211_action_contains_tpc(struct sk_buff *skb)
|
||||
return true;
|
||||
}
|
||||
|
||||
struct element {
|
||||
u8 id;
|
||||
u8 datalen;
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
/* element iteration helpers */
|
||||
#define for_each_element(_elem, _data, _datalen) \
|
||||
for (_elem = (const struct element *)(_data); \
|
||||
(const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \
|
||||
(int)sizeof(*_elem) && \
|
||||
(const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \
|
||||
(int)sizeof(*_elem) + _elem->datalen; \
|
||||
_elem = (const struct element *)(_elem->data + _elem->datalen))
|
||||
|
||||
#define for_each_element_id(element, _id, data, datalen) \
|
||||
for_each_element(element, data, datalen) \
|
||||
if (element->id == (_id))
|
||||
|
||||
#define for_each_element_extid(element, extid, _data, _datalen) \
|
||||
for_each_element(element, _data, _datalen) \
|
||||
if (element->id == WLAN_EID_EXTENSION && \
|
||||
element->datalen > 0 && \
|
||||
element->data[0] == (extid))
|
||||
|
||||
#define for_each_subelement(sub, element) \
|
||||
for_each_element(sub, (element)->data, (element)->datalen)
|
||||
|
||||
#define for_each_subelement_id(sub, id, element) \
|
||||
for_each_element_id(sub, id, (element)->data, (element)->datalen)
|
||||
|
||||
#define for_each_subelement_extid(sub, extid, element) \
|
||||
for_each_element_extid(sub, extid, (element)->data, (element)->datalen)
|
||||
|
||||
/**
|
||||
* for_each_element_completed - determine if element parsing consumed all data
|
||||
* @element: element pointer after for_each_element() or friends
|
||||
* @data: same data pointer as passed to for_each_element() or friends
|
||||
* @datalen: same data length as passed to for_each_element() or friends
|
||||
*
|
||||
* This function returns %true if all the data was parsed or considered
|
||||
* while walking the elements. Only use this if your for_each_element()
|
||||
* loop cannot be broken out of, otherwise it always returns %false.
|
||||
*
|
||||
* If some data was malformed, this returns %false since the last parsed
|
||||
* element will not fill the whole remaining data.
|
||||
*/
|
||||
static inline bool for_each_element_completed(const struct element *element,
|
||||
const void *data, size_t datalen)
|
||||
{
|
||||
return (const u8 *)element == (const u8 *)data + datalen;
|
||||
}
|
||||
|
||||
#endif /* LINUX_IEEE80211_H */
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <uapi/linux/igmp.h>
|
||||
|
||||
@@ -106,6 +107,14 @@ struct ip_mc_list {
|
||||
#define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value)
|
||||
#define IGMPV3_MRC(value) IGMPV3_EXP(0x80, 4, 3, value)
|
||||
|
||||
static inline int ip_mc_may_pull(struct sk_buff *skb, unsigned int len)
|
||||
{
|
||||
if (skb_transport_offset(skb) + ip_transport_len(skb) < len)
|
||||
return 0;
|
||||
|
||||
return pskb_may_pull(skb, len);
|
||||
}
|
||||
|
||||
extern int ip_check_mc_rcu(struct in_device *dev, __be32 mc_addr, __be32 src_addr, u8 proto);
|
||||
extern int igmp_rcv(struct sk_buff *);
|
||||
extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
|
||||
@@ -128,8 +137,14 @@ extern void ip_mc_up(struct in_device *);
|
||||
extern void ip_mc_down(struct in_device *);
|
||||
extern void ip_mc_unmap(struct in_device *);
|
||||
extern void ip_mc_remap(struct in_device *);
|
||||
extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr);
|
||||
extern void __ip_mc_dec_group(struct in_device *in_dev, __be32 addr, gfp_t gfp);
|
||||
static inline void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
|
||||
{
|
||||
return __ip_mc_dec_group(in_dev, addr, GFP_KERNEL);
|
||||
}
|
||||
extern void __ip_mc_inc_group(struct in_device *in_dev, __be32 addr,
|
||||
gfp_t gfp);
|
||||
extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
|
||||
int ip_mc_check_igmp(struct sk_buff *skb, struct sk_buff **skb_trimmed);
|
||||
int ip_mc_check_igmp(struct sk_buff *skb);
|
||||
|
||||
#endif
|
||||
|
@@ -21,12 +21,24 @@ struct ihex_binrec {
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
static inline uint16_t ihex_binrec_size(const struct ihex_binrec *p)
|
||||
{
|
||||
return be16_to_cpu(p->len) + sizeof(*p);
|
||||
}
|
||||
|
||||
/* Find the next record, taking into account the 4-byte alignment */
|
||||
static inline const struct ihex_binrec *
|
||||
__ihex_next_binrec(const struct ihex_binrec *rec)
|
||||
{
|
||||
const void *p = rec;
|
||||
|
||||
return p + ALIGN(ihex_binrec_size(rec), 4);
|
||||
}
|
||||
|
||||
static inline const struct ihex_binrec *
|
||||
ihex_next_binrec(const struct ihex_binrec *rec)
|
||||
{
|
||||
int next = ((be16_to_cpu(rec->len) + 5) & ~3) - 2;
|
||||
rec = (void *)&rec->data[next];
|
||||
rec = __ihex_next_binrec(rec);
|
||||
|
||||
return be16_to_cpu(rec->len) ? rec : NULL;
|
||||
}
|
||||
@@ -34,18 +46,15 @@ ihex_next_binrec(const struct ihex_binrec *rec)
|
||||
/* Check that ihex_next_binrec() won't take us off the end of the image... */
|
||||
static inline int ihex_validate_fw(const struct firmware *fw)
|
||||
{
|
||||
const struct ihex_binrec *rec;
|
||||
size_t ofs = 0;
|
||||
const struct ihex_binrec *end, *rec;
|
||||
|
||||
while (ofs <= fw->size - sizeof(*rec)) {
|
||||
rec = (void *)&fw->data[ofs];
|
||||
rec = (const void *)fw->data;
|
||||
end = (const void *)&fw->data[fw->size - sizeof(*end)];
|
||||
|
||||
for (; rec <= end; rec = __ihex_next_binrec(rec)) {
|
||||
/* Zero length marks end of records */
|
||||
if (!be16_to_cpu(rec->len))
|
||||
if (rec == end && !be16_to_cpu(rec->len))
|
||||
return 0;
|
||||
|
||||
/* Point to next record... */
|
||||
ofs += (sizeof(*rec) + be16_to_cpu(rec->len) + 3) & ~3;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@@ -260,6 +260,7 @@ struct st_sensor_settings {
|
||||
struct st_sensor_data {
|
||||
struct device *dev;
|
||||
struct iio_trigger *trig;
|
||||
struct iio_mount_matrix *mount_matrix;
|
||||
struct st_sensor_settings *sensor_settings;
|
||||
struct st_sensor_fullscale_avl *current_fullscale;
|
||||
struct regulator *vdd;
|
||||
|
@@ -18,6 +18,7 @@ struct linux_binprm;
|
||||
#ifdef CONFIG_IMA
|
||||
extern int ima_bprm_check(struct linux_binprm *bprm);
|
||||
extern int ima_file_check(struct file *file, int mask);
|
||||
extern void ima_post_create_tmpfile(struct inode *inode);
|
||||
extern void ima_file_free(struct file *file);
|
||||
extern int ima_file_mmap(struct file *file, unsigned long prot);
|
||||
extern int ima_load_data(enum kernel_load_data_id id);
|
||||
@@ -56,6 +57,10 @@ static inline int ima_file_check(struct file *file, int mask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ima_post_create_tmpfile(struct inode *inode)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ima_file_free(struct file *file)
|
||||
{
|
||||
return;
|
||||
|
@@ -60,6 +60,11 @@ static inline bool ipv4_is_lbcast(__be32 addr)
|
||||
return addr == htonl(INADDR_BROADCAST);
|
||||
}
|
||||
|
||||
static inline bool ipv4_is_all_snoopers(__be32 addr)
|
||||
{
|
||||
return addr == htonl(INADDR_ALLSNOOPERS_GROUP);
|
||||
}
|
||||
|
||||
static inline bool ipv4_is_zeronet(__be32 addr)
|
||||
{
|
||||
return (addr & htonl(0xff000000)) == htonl(0x00000000);
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include <linux/securebits.h>
|
||||
#include <linux/seqlock.h>
|
||||
#include <linux/rbtree.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <linux/sched/autogroup.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <linux/sched/rt.h>
|
||||
|
@@ -25,3 +25,6 @@ extern phys_addr_t phys_initrd_start;
|
||||
extern unsigned long phys_initrd_size;
|
||||
|
||||
extern unsigned int real_root_dev;
|
||||
|
||||
extern char __initramfs_start[];
|
||||
extern unsigned long __initramfs_size;
|
||||
|
@@ -1,11 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ILI210X_H
|
||||
#define _ILI210X_H
|
||||
|
||||
struct ili210x_platform_data {
|
||||
unsigned long irq_flags;
|
||||
unsigned int poll_period;
|
||||
bool (*get_pendown_state)(void);
|
||||
};
|
||||
|
||||
#endif
|
@@ -374,20 +374,17 @@ enum {
|
||||
#define QI_DEV_EIOTLB_PFSID(pfsid) (((u64)(pfsid & 0xf) << 12) | ((u64)(pfsid & 0xfff) << 52))
|
||||
#define QI_DEV_EIOTLB_MAX_INVS 32
|
||||
|
||||
#define QI_PGRP_IDX(idx) (((u64)(idx)) << 55)
|
||||
#define QI_PGRP_PRIV(priv) (((u64)(priv)) << 32)
|
||||
#define QI_PGRP_RESP_CODE(res) ((u64)(res))
|
||||
#define QI_PGRP_PASID(pasid) (((u64)(pasid)) << 32)
|
||||
#define QI_PGRP_DID(did) (((u64)(did)) << 16)
|
||||
/* Page group response descriptor QW0 */
|
||||
#define QI_PGRP_PASID_P(p) (((u64)(p)) << 4)
|
||||
#define QI_PGRP_PDP(p) (((u64)(p)) << 5)
|
||||
#define QI_PGRP_RESP_CODE(res) (((u64)(res)) << 12)
|
||||
#define QI_PGRP_DID(rid) (((u64)(rid)) << 16)
|
||||
#define QI_PGRP_PASID(pasid) (((u64)(pasid)) << 32)
|
||||
|
||||
/* Page group response descriptor QW1 */
|
||||
#define QI_PGRP_LPIG(x) (((u64)(x)) << 2)
|
||||
#define QI_PGRP_IDX(idx) (((u64)(idx)) << 3)
|
||||
|
||||
#define QI_PSTRM_ADDR(addr) (((u64)(addr)) & VTD_PAGE_MASK)
|
||||
#define QI_PSTRM_DEVFN(devfn) (((u64)(devfn)) << 4)
|
||||
#define QI_PSTRM_RESP_CODE(res) ((u64)(res))
|
||||
#define QI_PSTRM_IDX(idx) (((u64)(idx)) << 55)
|
||||
#define QI_PSTRM_PRIV(priv) (((u64)(priv)) << 32)
|
||||
#define QI_PSTRM_BUS(bus) (((u64)(bus)) << 24)
|
||||
#define QI_PSTRM_PASID(pasid) (((u64)(pasid)) << 4)
|
||||
|
||||
#define QI_RESP_SUCCESS 0x0
|
||||
#define QI_RESP_INVALID 0x1
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user