Re: [PATCH v5 08/14] platform/x86: dell-smbios: Add a sysfs interface for SMBIOS tokens
On Fri, Oct 06, 2017 at 11:59:52PM -0500, Mario Limonciello wrote: > Currently userspace tools can access system tokens via the dcdbas > kernel module and a SMI call that will cause the platform to execute > SMM code. > > With a goal in mind of deprecating the dcdbas kernel module a different > method for accessing these tokens from userspace needs to be created. > > This is intentionally marked to only be readable as root as it can > contain sensitive information about the platform's configuration. > > MAINTAINERS was missing for this driver. Add myself and Pali to > maintainers list for it. > > Signed-off-by: Mario Limonciello > --- > .../ABI/testing/sysfs-platform-dell-smbios | 16 ++ > MAINTAINERS| 7 +++ > drivers/platform/x86/dell-smbios.c | 64 > ++ > 3 files changed, 87 insertions(+) > create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-smbios > > diff --git a/Documentation/ABI/testing/sysfs-platform-dell-smbios > b/Documentation/ABI/testing/sysfs-platform-dell-smbios > new file mode 100644 > index ..d97f4bd5bd91 > --- /dev/null > +++ b/Documentation/ABI/testing/sysfs-platform-dell-smbios > @@ -0,0 +1,16 @@ > +What:/sys/devices/platform//tokens > +Date:November 2017 > +KernelVersion: 4.15 > +Contact: "Mario Limonciello" > +Description: > + A read-only description of Dell platform tokens > + available on the machine. > + > + The tokens will be displayed in the following > + machine readable format with each token on a > + new line: > + > + ID Locationvalue > + > + For example token: > + 5 5 3 That's more than "one value per file" which is what sysfs requires, so this isn't acceptable, sorry. > +static ssize_t tokens_show(struct device *dev, > +struct device_attribute *attr, char *buf) > +{ > + size_t off = 0; > + int to_print; > + int i; > + > + to_print = min(da_num_tokens, (int)(PAGE_SIZE - 1) / 15); > + for (i = 0; i < to_print; i++) { > + off += scnprintf(buf+off, PAGE_SIZE-off, "%04x\t%04x\t%04x\n", > + da_tokens[i].tokenID, da_tokens[i].location, > + da_tokens[i].value); Huge hint, if you are checking for the max size of the buffer for sysfs, something is really wrong, and you need to redo your design. thanks, greg k-h
5f82e71a00 ("Merge branch 'locking-core-for-linus' of .."): watchdog: BUG: soft lockup - CPU#0 stuck for 21s! [swapper:1]
Greetings, 0day kernel testing robot got the below dmesg and the first bad commit is https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master commit 5f82e71a001d14824a7728ad9e49f6aea420f161 Merge: 6c51e67b64d16 edc2988c548db Author: Linus Torvalds AuthorDate: Mon Sep 4 11:52:29 2017 -0700 Commit: Linus Torvalds CommitDate: Mon Sep 4 11:52:29 2017 -0700 Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull locking updates from Ingo Molnar: - Add 'cross-release' support to lockdep, which allows APIs like completions, where it's not the 'owner' who releases the lock, to be tracked. It's all activated automatically under CONFIG_PROVE_LOCKING=y. - Clean up (restructure) the x86 atomics op implementation to be more readable, in preparation of KASAN annotations. (Dmitry Vyukov) - Fix static keys (Paolo Bonzini) - Add killable versions of down_read() et al (Kirill Tkhai) - Rework and fix jump_label locking (Marc Zyngier, Paolo Bonzini) - Rework (and fix) tlb_flush_pending() barriers (Peter Zijlstra) - Remove smp_mb__before_spinlock() and convert its usages, introduce smp_mb__after_spinlock() (Peter Zijlstra) * 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (56 commits) locking/lockdep/selftests: Fix mixed read-write ABBA tests sched/completion: Avoid unnecessary stack allocation for COMPLETION_INITIALIZER_ONSTACK() acpi/nfit: Fix COMPLETION_INITIALIZER_ONSTACK() abuse locking/pvqspinlock: Relax cmpxchg's to improve performance on some architectures smp: Avoid using two cache lines for struct call_single_data locking/lockdep: Untangle xhlock history save/restore from task independence locking/refcounts, x86/asm: Disable CONFIG_ARCH_HAS_REFCOUNT for the time being futex: Remove duplicated code and fix undefined behaviour Documentation/locking/atomic: Finish the document... locking/lockdep: Fix workqueue crossrelease annotation workqueue/lockdep: 'Fix' flush_work() annotation locking/lockdep/selftests: Add mixed read-write ABBA tests mm, locking/barriers: Clarify tlb_flush_pending() barriers locking/lockdep: Make CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS truly non-interactive locking/lockdep: Explicitly initialize wq_barrier::done::map locking/lockdep: Rename CONFIG_LOCKDEP_COMPLETE to CONFIG_LOCKDEP_COMPLETIONS locking/lockdep: Reword title of LOCKDEP_CROSSRELEASE config locking/lockdep: Make CONFIG_LOCKDEP_CROSSRELEASE part of CONFIG_PROVE_LOCKING locking/refcounts, x86/asm: Implement fast refcount overflow protection locking/lockdep: Fix the rollback and overwrite detection logic in crossrelease ... 6c51e67b64 Merge branch 'x86-syscall-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip edc2988c54 Merge branch 'linus' into locking/core, to fix up conflicts 5f82e71a00 Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 1c86f2e4c8 Merge tag 'hwmon-for-linus-v4.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging 1418b85217 Add linux-next specific files for 20170929 ++++++---+ || 6c51e67b64 | edc2988c54 | 5f82e71a00 | 1c86f2e4c8 | next-20170929 | ++++++---+ | boot_successes | 104| 106| 20 | 26 | 3 | | boot_failures | 0 | 0 | 19 | 17 | 32| | BUG:soft_lockup-CPU##stuck_for#s | 0 | 0 | 19 | 15 | 32| | Kernel_panic-not_syncing:softlockup:hung_tasks | 0 | 0 | 19 | 15 | 32| | BUG:workqueue_lockup-pool | 0 | 0 | 0 | 2 | | ++++++---+ [ 34.173316] ACPI: Power Button [PWRF] [ 36.514313] ACPI: PCI Interrupt Link [LNKD] enabled at IRQ 11 [ 43.543992] ACPI: PCI Interrupt Link [LNKA] enabled at IRQ 10 [ 50.552444] ACPI: PCI Interrupt Link [LNKB] enabled at IRQ 10 [ 57.519736] ACPI: PCI Interrupt Link [LNKC] enabled at IRQ 11 [ 80.054918] watchdog: BUG: soft lockup - CPU#0 stuck for 21s! [swapper:1] [ 80.054918] Modules linked in: [ 80.054918] irq event stamp: 26612068 [ 80.054918] hardirqs last enabled at (26612067): [] _raw_spin_unlock_
Re: [Patch v6 2/7] slimbus: Add messaging APIs to slimbus framework
Hi, On Fri, Oct 06, 2017 at 05:51:31PM +0200, srinivas.kandaga...@linaro.org wrote: > From: Sagar Dharia > > Slimbus devices use value-element, and information elements to > control device parameters (e.g. value element is used to represent > gain for codec, information element is used to represent interrupt > status for codec when codec interrupt fires). > Messaging APIs are used to set/get these value and information > elements. Slimbus specification uses 8-bit "transaction IDs" for > messages where a read-value is anticipated. Framework uses a table > of pointers to store those TIDs and responds back to the caller in > O(1). > Caller can opt to do synchronous, or asynchronous reads/writes. For > asynchronous operations, the callback will be called from atomic > context. > TX and RX circular rings are used to allow queuing of multiple > transfers per controller. Controller can choose size of these rings > based of controller HW implementation. The buffers are coerently s/based of/based on/ s/coerently/coherently/ > mapped so that controller can utilize DMA operations for the > transactions without remapping every transaction buffer. > Statically allocated rings help to improve performance by avoiding > overhead of dynamically allocating transactions on need basis. > > Signed-off-by: Sagar Dharia > Tested-by: Naveen Kaje > Signed-off-by: Srinivas Kandagatla > --- [...] > +static u16 slim_slicecodefromsize(u16 req) > +{ > + static const u8 codetosize[8] = {1, 2, 3, 4, 6, 8, 12, 16}; > + > + if (req >= ARRAY_SIZE(codetosize)) > + return 0; > + else > + return codetosize[req]; > +} > + > +static u16 slim_slicesize(int code) > +{ > + static const u8 sizetocode[16] = { > + 0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7 > + }; > + > + clamp(code, 1, (int)ARRAY_SIZE(sizetocode)); > + return sizetocode[code - 1]; > +} > + > +int slim_xfer_msg(struct slim_controller *ctrl, > + struct slim_device *sbdev, struct slim_val_inf *msg, > + u8 mc) > +{ > + DEFINE_SLIM_LDEST_TXN(txn_stack, mc, 6, sbdev->laddr, msg); > + struct slim_msg_txn *txn = &txn_stack; > + int ret; > + u16 sl, cur; > + > + ret = slim_val_inf_sanity(ctrl, msg, mc); > + if (ret) > + return ret; > + > + sl = slim_slicesize(msg->num_bytes); > + > + dev_dbg(&ctrl->dev, "SB xfer msg:os:%x, len:%d, MC:%x, sl:%x\n", > + msg->start_offset, msg->num_bytes, mc, sl); > + > + cur = slim_slicecodefromsize(sl); > + txn->ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4)); Shouldn't this be (cur | (1 << 3)? (Also, what does cur mean? Cursor? Current?) > + > + switch (mc) { > + case SLIM_MSG_MC_REQUEST_CHANGE_VALUE: > + case SLIM_MSG_MC_CHANGE_VALUE: > + case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION: > + case SLIM_MSG_MC_CLEAR_INFORMATION: > + txn->rl += msg->num_bytes; > + default: > + break; > + } > + > + if (slim_tid_txn(txn->mt, txn->mc)) > + txn->rl++; > + > + return slim_processtxn(ctrl, txn); > +} > +EXPORT_SYMBOL_GPL(slim_xfer_msg); [...] > +/* > + * slim_request_val_element: change and request a given value element > + * @sb: client handle requesting elemental message reads, writes. > + * @msg: Input structure for start-offset, number of bytes to write. > + * context: can sleep > + * Returns: > + * -EINVAL: Invalid parameters > + * -ETIMEDOUT: If transmission of this message timed out (e.g. due to bus > lines > + * not being clocked or driven by controller) > + * -ENOTCONN: If the transmitted message was not ACKed by destination device. Does rbuf contain the old value after this function finishes? > + */ > +int slim_request_change_val_element(struct slim_device *sb, > + struct slim_val_inf *msg) > +{ > + struct slim_controller *ctrl = sb->ctrl; > + > + if (!ctrl) > + return -EINVAL; > + > + return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_CHANGE_VALUE); > +} > +EXPORT_SYMBOL_GPL(slim_request_change_val_element); [...] > +/** > + * struct slim_pending: context of pending transfers > + * @cb: callback for this transfer > + * @ctx: contex for the callback function s/contex/context/ > + * @need_tid: True if this transfer need Transaction ID > + */ > +struct slim_pending { > + void (*cb)(void *ctx, int err); > + void *ctx; > + bool need_tid; > +}; Thanks, Jonathan Neuschäfer signature.asc Description: PGP signature
Re: [for-next][PATCH 15/16] ftrace: Add freeing algorithm to free ftrace_mod_maps
Hi Steve, On Fri, Oct 6, 2017 at 11:07 AM, Steven Rostedt wrote: > From: "Steven Rostedt (VMware)" > > The ftrace_mod_map is a descriptor to save module init function names in > case they were traced, and the trace output needs to reference the function > name from the function address. But after the function is unloaded, it > the maps should be freed, as the rest of the function names are as well. Just checking for my understanding of this patch - wouldn't this also mean that if there were any look ups of the init functions that may be needed at trace output time, then those look ups wont be possible any more after module is unloaded? I guess having a reference somehow on the ftrace_mod_map descriptor if there are any entries in the trace buffer that need it can help prevent that but it could be too expensive for not much return since most likely the user wouldn't unload modules before trace collection in normal usage. thanks, - Joel
Re: [RFC PATCH -tip 0/5] kprobes: Abolish jprobe APIs
Hello, Nice read, see some comments below On Fri, Oct 06, 2017 at 11:34:30AM -0400, Steven Rostedt wrote: > On Fri, 6 Oct 2017 13:49:59 +0900 > Masami Hiramatsu wrote: > > > Steve, could you write a documentation how to use ftrace callback? > > I think I should update the Documentation/kprobes.txt so that jprobe > > user can easily migrate on that. > > I decided to do this now. Here's a first draft. What do you think? > > -- Steve > > Using ftrace to hook to functions > = > > Copyright 2017 VMware Inc. >Author: Steven Rostedt > License: The GNU Free Documentation License, Version 1.2 >(dual licensed under the GPL v2) > > Written for: 4.14 > > Introduction > > > The ftrace infrastructure was originially created to attach hooks to the > beginning of functions in order to record and trace the flow of the kernel. > But hooks to the start of a function can have other use cases. Either > for live kernel patching, or for security monitoring. This document describes > how to use ftrace to implement your own function hooks. > > > The ftrace context > == > > WARNING: The ability to add a callback to almost any function within the > kernel comes with risks. A callback can be called from any context > (normal, softirq, irq, and NMI). Callbacks can also be called just before > going to idle, during CPU bring up and takedown, or going to user space. > This requires extra care to what can be done inside a callback. A callback > can be called outside the protective scope of RCU. > > The ftrace infrastructure has some protections agains recursions and RCU > but one must still be very careful how they use the callbacks. > > > The ftrace_ops structure > > > To register a function callback, a ftrace_ops is required. This structure > is used to tell ftrace what function should be called as the callback > as well as what protections the callback will perform and not require > ftrace to handle. > > There are only two fields that are needed to be set when registering > an ftrace_ops with ftrace. The rest should be NULL. > > struct ftrace_ops ops = { >.func = my_callback_func, >.flags = MY_FTRACE_FLAGS >.private = any_private_data_structure, > }; > > Both .flags and .private are optional. Only .func is required. > > To enable tracing call: > > register_ftrace_function(&ops); Maybe it would help to have a small section on 'The register function' below to answer? Is it possible to make changes to the filter after calling register_ftrace_function()? Or do you need to call register_ftrace_function() again? > To disable tracing call: > > unregister_ftrace_function(@ops); > > > The callback function > = > > The prototype of the callback function is as follows (as of v4.14): > > void callback_func(unsigned long ip, unsigned long parent_ip, > struct ftrace_ops *op, struct pt_regs *regs); > > @ip - This is the instruction pointer of the function that is being traced. > (where the fentry or mcount is within the function) > > @parent_ip - This is the instruction pointer of the function that called the > the function being traced (where the call of the function occurred). > > @op - This is a pointer to ftrace_ops that was used to register the callback. > This can be used to pass data to the callback via the private pointer. > > @regs - If the FTRACE_OPS_FL_SAVE_REGS or FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED > flags are set in the ftrace_ops structure, then this will be pointing > to the pt_regs structure like it would be if an breakpoint was placed > at the start of the function where ftrace was tracing. Otherwise it > either contains garbage, or NULL. > > > The ftrace FLAGS > > > The ftrace_ops flags are all defined and documented in include/linux/ftrace.h. > Some of the flags are used for internal infrastructure of ftrace, but the > ones that users should be aware of are the following: > > (All of these are prefixed with FTRACE_OPS_FL_) > > PER_CPU - When set, the callback can be enabled or disabled per cpu with the > following functions: > > void ftrace_function_local_enable(struct ftrace_ops *ops); > void ftrace_function_local_disable(struct ftrace_ops *ops); > > These two functions must be called with preemption disabled. > > SAVE_REGS - If the callback requires reading or modifying the pt_regs > passed to the callback, then it must set this flag. Registering > a ftrace_ops with this flag set on an architecture that does not > support passing of pt_regs to the callback, will fail. > > SAVE_REGS_IF_SUPPORTED - Similar to SAVE_REGS but the registering of a > ftrace_ops on an architecture that does not support passing of regs > w
Re: [PATCH] mwifiex: Use put_unaligned_le32
Hi Himanshu, [auto build test ERROR on wireless-drivers-next/master] [also build test ERROR on v4.14-rc3 next-20170929] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Himanshu-Jha/mwifiex-Use-put_unaligned_le32/20171007-095017 base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master config: openrisc-allyesconfig (attached as .config) compiler: or1k-linux-gcc (GCC) 5.4.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=openrisc All errors (new ones prefixed by >>): In file included from arch/openrisc/include/asm/unaligned.h:42:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_memmove.h:6:19: error: redefinition of >> 'get_unaligned_be16' static inline u16 get_unaligned_be16(const void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:22:28: note: previous definition of 'get_unaligned_be16' was here static __always_inline u16 get_unaligned_be16(const void *p) ^ In file included from arch/openrisc/include/asm/unaligned.h:42:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_memmove.h:11:19: error: redefinition of >> 'get_unaligned_be32' static inline u32 get_unaligned_be32(const void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:27:28: note: previous definition of 'get_unaligned_be32' was here static __always_inline u32 get_unaligned_be32(const void *p) ^ In file included from arch/openrisc/include/asm/unaligned.h:42:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_memmove.h:16:19: error: redefinition of >> 'get_unaligned_be64' static inline u64 get_unaligned_be64(const void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:32:28: note: previous definition of 'get_unaligned_be64' was here static __always_inline u64 get_unaligned_be64(const void *p) ^ In file included from arch/openrisc/include/asm/unaligned.h:42:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_memmove.h:21:20: error: redefinition of >> 'put_unaligned_be16' static inline void put_unaligned_be16(u16 val, void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:52:29: note: previous definition of 'put_unaligned_be16' was here static __always_inline void put_unaligned_be16(u16 val, void *p) ^ In file included from arch/openrisc/include/asm/unaligned.h:42:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_memmove.h:26:20: error: redefinition of >> 'put_unaligned_be32' static inline void put_unaligned_be32(u32 val, void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:57:29: note: previous definition of 'put_unaligned_be32' was here static __always_inline void put_unaligned_be32(u32 val, void *p) ^ In file included from arch/openrisc/include/asm/unaligned.h:42:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwi
Re: [PATCH] MAINTAINERS: Update the UV architecture to current addresses
On Fri, 2017-10-06 at 15:36 -0500, Nathan Zimmer wrote: > After the buyout/merger our @sgi.com address are slowing being less useful. > So make sure we are can be contacted properly. This seems more like a new entry so the commit message seems wrong. > Signed-off-by: Nathan Zimmer > Signed-off-by: Mike Travis > --- > MAINTAINERS | 10 ++ > 1 file changed, 10 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index cc42c83..8581e18 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -14161,6 +14161,16 @@ F: include/linux/uuid.h > F: include/uapi/linux/uuid.h > S: Maintained > > +UV PLATFORM > +M: Mike Travis > +M: Nathan Zimmer > +M: uv_ker...@groups.ext.hpe.com > +S: Supported > +F: arch/x86/kernel/apic/x2apic_uv_x.c > +F: arch/x86/platform/uv/* > +F: arch/x86/include/asm/uv/* And Most likmely, these 2 should not have the * > +F: drivers/char/uv_mmtimer.c > + > UVESAFB DRIVER > M: Michal Januszewski > L: linux-fb...@vger.kernel.org
[PATCH] irqchip/gicv3-its: Add missing changes to support 52bit physical address
The current ITS driver works fine as long as normal memory and GICR regions are located within the lower 48bit (>=0 && <2^48) physical address space. Some of the registers GICR_PEND/PROP, GICR_VPEND/VPROP and GITS_CBASER are handled properly but not all when configuring the hardware with 52bit physical address. This patch does the following changes to support 52bit PA. -Handle 52bit PA in GITS_BASERn. -Fix ITT_addr width to 52bits, bits[51:8]. -Fix RDbase width to 52bits, bits[51:16]. -Fix VPT_addr width to 52bits, bits[51:16]. Definition of the GITS_BASERn register when ITS PageSize is 64KB: -Bits[47:16] of the register provide bits[47:16] of the table PA. -Bits[15:12] of the register provide bits[51:48] of the table PA. -Bits[15:00] of the base physical address are 0. Signed-off-by: Shanker Donthineni --- drivers/irqchip/irq-gic-v3-its.c | 24 +++- include/linux/irqchip/arm-gic-v3.h | 3 +++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e8d8934..e52c0da 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -308,7 +308,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size) static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) { - its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8); + its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8); } static void its_encode_valid(struct its_cmd_block *cmd, int valid) @@ -318,7 +318,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid) static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) { - its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16); + its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16); } static void its_encode_collection(struct its_cmd_block *cmd, u16 col) @@ -358,7 +358,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list) static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa) { - its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16); + its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16); } static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size) @@ -1478,9 +1478,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, u64 val = its_read_baser(its, baser); u64 esz = GITS_BASER_ENTRY_SIZE(val); u64 type = GITS_BASER_TYPE(val); + u64 baser_phys, tmp; u32 alloc_pages; void *base; - u64 tmp; retry_alloc_baser: alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); @@ -1496,8 +1496,22 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, if (!base) return -ENOMEM; + baser_phys = virt_to_phys(base); + + /* Check if the physical address of the memory is above 48bits */ + if (baser_phys & (~GITS_BASER_PHYS_MASK)) { + /* 52bit PA is supported only when PageSize=64K */ + if (psz != SZ_64K) { + free_pages((unsigned long)base, order); + return -EFAULT; + } + + /* Convert 52bit PA to 48bit field */ + baser_phys = GITS_BASER_64K_PHYS(baser_phys); + } + retry_baser: - val = (virt_to_phys(base)| + val = (baser_phys| (type << GITS_BASER_TYPE_SHIFT) | ((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | ((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT)| diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index b8b5998..4e82f73 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -373,6 +373,9 @@ #define GITS_BASER_ENTRY_SIZE_SHIFT(48) #define GITS_BASER_ENTRY_SIZE(r) r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1) #define GITS_BASER_ENTRY_SIZE_MASK GENMASK_ULL(52, 48) +#define GITS_BASER_PHYS_MASK GENMASK_ULL(47, 12) +#define GITS_BASER_64K_PHYS(phys) \ + (((phys) | phys) >> 48) & 0xF) << 12)) & GITS_BASER_PHYS_MASK) #define GITS_BASER_SHAREABILITY_SHIFT (10) #define GITS_BASER_InnerShareable \ GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable) -- Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [Patch v6 6/7] regmap: add SLIMBUS support
Hi, On Fri, Oct 06, 2017 at 05:51:35PM +0200, srinivas.kandaga...@linaro.org wrote: > From: Srinivas Kandagatla > > This patch adds support to read/write slimbus value elements. > Currently it only supports byte read/write. Adding this support in > regmap would give codec drivers more flexibility when there are more > than 2 control interfaces like slimbus, i2c. > > Without this patch each codec driver has to directly call slimbus value > element apis, and this could would get messy once we want to add i2c > interface to it. > > Signed-off-by: Srinivas Kandagatla > --- [...] > +static int regmap_slimbus_byte_reg_read(void *context, unsigned int reg, > + unsigned int *val) > +{ > + struct slim_device *slim = context; > + struct slim_val_inf msg = {0,}; > + > + msg.start_offset = reg; > + msg.num_bytes = 1; > + msg.rbuf = (void *)val; > + > + return slim_request_val_element(slim, &msg); > +} This looks like it won't work on big-endian systems. I know big endian is pretty uncommon in devices that will likely have SLIMBus, but it's better to be endian-independent. > +static int regmap_slimbus_byte_reg_write(void *context, unsigned int reg, > + unsigned int val) > +{ > + struct slim_device *slim = context; > + struct slim_val_inf msg = {0,}; > + > + msg.start_offset = reg; > + msg.num_bytes = 1; > + msg.wbuf = (void *)&val; > + > + return slim_change_val_element(slim, &msg); > +} dito > +static struct regmap_bus regmap_slimbus_bus = { > + .reg_write = regmap_slimbus_byte_reg_write, > + .reg_read = regmap_slimbus_byte_reg_read, > +}; Thanks, Jonathan Neuschäfer signature.asc Description: PGP signature
[PATCH v5 02/14] platform/x86: dell-wmi: increase severity of some failures
There is a lot of error checking in place for the format of the WMI descriptor buffer, but some of the potentially raised issues should be considered critical failures. If the buffer size or header don't match, this is a good indication that the buffer format changed in a way that the rest of the data should not be relied upon. For the remaining data set vectors, continue to notate a warning in undefined results, but as those are fields that the descriptor intended to refer to other applications, don't fail if they're new values. Signed-off-by: Mario Limonciello --- drivers/platform/x86/dell-wmi.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 1fbef560ca67..2cfaaa8faf0a 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -657,17 +657,18 @@ static int dell_wmi_check_descriptor_buffer(struct wmi_device *wdev) dev_err(&wdev->dev, "Dell descriptor buffer has invalid length (%d)\n", obj->buffer.length); - if (obj->buffer.length < 16) { - ret = -EINVAL; - goto out; - } + ret = -EINVAL; + goto out; } buffer = (u32 *)obj->buffer.pointer; - if (buffer[0] != 0x4C4C4544 && buffer[1] != 0x494D5720) - dev_warn(&wdev->dev, "Dell descriptor buffer has invalid signature (%*ph)\n", + if (buffer[0] != 0x4C4C4544 && buffer[1] != 0x494D5720) { + dev_err(&wdev->dev, "Dell descriptor buffer has invalid signature (%*ph)\n", 8, buffer); + ret = -EINVAL; + goto out; + } if (buffer[2] != 0 && buffer[2] != 1) dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%d)\n", -- 2.14.1
[PATCH v5 01/14] platform/x86: wmi: Add new method wmidev_evaluate_method
Drivers properly using the wmibus can pass their wmi_device pointer rather than the GUID back to the WMI bus to evaluate the proper methods. Any "new" drivers added that use the WMI bus should use this rather than the old wmi_evaluate_method that would take the GUID. Signed-off-by: Mario Limonciello --- drivers/platform/x86/wmi.c | 28 include/linux/wmi.h| 6 ++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 7a05843aff19..4d73a87c2ddf 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -200,6 +200,28 @@ static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable) */ acpi_status wmi_evaluate_method(const char *guid_string, u8 instance, u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) +{ + struct wmi_block *wblock = NULL; + + if (!find_guid(guid_string, &wblock)) + return AE_ERROR; + return wmidev_evaluate_method(&wblock->dev, instance, method_id, + in, out); +} +EXPORT_SYMBOL_GPL(wmi_evaluate_method); + +/** + * wmidev_evaluate_method - Evaluate a WMI method + * @wdev: A wmi bus device from a driver + * @instance: Instance index + * @method_id: Method ID to call + * &in: Buffer containing input for the method call + * &out: Empty buffer to return the method results + * + * Call an ACPI-WMI method + */ +acpi_status wmidev_evaluate_method(struct wmi_device *wdev, u8 instance, + u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) { struct guid_block *block = NULL; struct wmi_block *wblock = NULL; @@ -209,9 +231,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) union acpi_object params[3]; char method[5] = "WM"; - if (!find_guid(guid_string, &wblock)) - return AE_ERROR; - + wblock = container_of(wdev, struct wmi_block, dev); block = &wblock->gblock; handle = wblock->acpi_device->handle; @@ -246,7 +266,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) return status; } -EXPORT_SYMBOL_GPL(wmi_evaluate_method); +EXPORT_SYMBOL_GPL(wmidev_evaluate_method); static acpi_status __query_block(struct wmi_block *wblock, u8 instance, struct acpi_buffer *out) diff --git a/include/linux/wmi.h b/include/linux/wmi.h index cd0d7734dc49..2cd10c3b89e9 100644 --- a/include/linux/wmi.h +++ b/include/linux/wmi.h @@ -26,6 +26,12 @@ struct wmi_device { bool setable; }; +/* evaluate the ACPI method associated with this device */ +extern acpi_status wmidev_evaluate_method(struct wmi_device *wdev, + u8 instance, u32 method_id, + const struct acpi_buffer *in, + struct acpi_buffer *out); + /* Caller must kfree the result. */ extern union acpi_object *wmidev_block_query(struct wmi_device *wdev, u8 instance); -- 2.14.1
[PATCH v5 03/14] platform/x86: dell-wmi: clean up wmi descriptor check
Some cases the wrong type was used for errors and checks can be done more cleanly. Signed-off-by: Mario Limonciello Reviewed-by: Edward O'Callaghan Suggested-by: Andy Shevchenko --- drivers/platform/x86/dell-wmi.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 2cfaaa8faf0a..ece2fe341f01 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -663,19 +663,19 @@ static int dell_wmi_check_descriptor_buffer(struct wmi_device *wdev) buffer = (u32 *)obj->buffer.pointer; - if (buffer[0] != 0x4C4C4544 && buffer[1] != 0x494D5720) { - dev_err(&wdev->dev, "Dell descriptor buffer has invalid signature (%*ph)\n", - 8, buffer); + if (strncmp(obj->string.pointer, "DELL WMI", 8) != 0) { + dev_err(&wdev->dev, "Dell descriptor buffer has invalid signature (%8ph)\n", + buffer); ret = -EINVAL; goto out; } if (buffer[2] != 0 && buffer[2] != 1) - dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%d)\n", + dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%u)\n", buffer[2]); if (buffer[3] != 4096) - dev_warn(&wdev->dev, "Dell descriptor buffer has invalid buffer length (%d)\n", + dev_warn(&wdev->dev, "Dell descriptor buffer has invalid buffer length (%u)\n", buffer[3]); priv->interface_version = buffer[2]; -- 2.14.1
[PATCH v5 07/14] platform/x86: dell-smbios: only run if proper oem string is detected
The proper way to indicate that a system is a 'supported' Dell System is by the presence of this string in OEM strings. Allowing the driver to load on non-Dell systems will have undefined results. Signed-off-by: Mario Limonciello --- drivers/platform/x86/dell-smbios.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios.c index e9b1ca07c872..873d1c3f7641 100644 --- a/drivers/platform/x86/dell-smbios.c +++ b/drivers/platform/x86/dell-smbios.c @@ -172,8 +172,15 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy) static int __init dell_smbios_init(void) { + const struct dmi_device *valid; int ret; + valid = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL); + if (!valid) { + pr_info("Unable to run on non-Dell system\n"); + return -ENODEV; + } + dmi_walk(find_tokens, NULL); if (!da_tokens) { -- 2.14.1
[PATCH v5 08/14] platform/x86: dell-smbios: Add a sysfs interface for SMBIOS tokens
Currently userspace tools can access system tokens via the dcdbas kernel module and a SMI call that will cause the platform to execute SMM code. With a goal in mind of deprecating the dcdbas kernel module a different method for accessing these tokens from userspace needs to be created. This is intentionally marked to only be readable as root as it can contain sensitive information about the platform's configuration. MAINTAINERS was missing for this driver. Add myself and Pali to maintainers list for it. Signed-off-by: Mario Limonciello --- .../ABI/testing/sysfs-platform-dell-smbios | 16 ++ MAINTAINERS| 7 +++ drivers/platform/x86/dell-smbios.c | 64 ++ 3 files changed, 87 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-smbios diff --git a/Documentation/ABI/testing/sysfs-platform-dell-smbios b/Documentation/ABI/testing/sysfs-platform-dell-smbios new file mode 100644 index ..d97f4bd5bd91 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-smbios @@ -0,0 +1,16 @@ +What: /sys/devices/platform//tokens +Date: November 2017 +KernelVersion: 4.15 +Contact: "Mario Limonciello" +Description: + A read-only description of Dell platform tokens + available on the machine. + + The tokens will be displayed in the following + machine readable format with each token on a + new line: + + ID Locationvalue + + For example token: + 5 5 3 diff --git a/MAINTAINERS b/MAINTAINERS index 659dbeec4191..2e3f2aea0370 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3967,6 +3967,13 @@ M: "Maciej W. Rozycki" S: Maintained F: drivers/net/fddi/defxx.* +DELL SMBIOS DRIVER +M: Pali Rohár +M: Mario Limonciello +L: platform-driver-...@vger.kernel.org +S: Maintained +F: drivers/platform/x86/dell-smbios.* + DELL LAPTOP DRIVER M: Matthew Garrett M: Pali Rohár diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios.c index 873d1c3f7641..7275d1d48190 100644 --- a/drivers/platform/x86/dell-smbios.c +++ b/drivers/platform/x86/dell-smbios.c @@ -23,6 +23,7 @@ #include #include #include "../../firmware/dcdbas.h" +#include #include "dell-smbios.h" struct calling_interface_structure { @@ -39,6 +40,7 @@ static DEFINE_MUTEX(buffer_mutex); static int da_command_address; static int da_command_code; static int da_num_tokens; +static struct platform_device *platform_device; static struct calling_interface_token *da_tokens; int dell_smbios_error(int value) @@ -170,6 +172,40 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy) } } +static ssize_t tokens_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + size_t off = 0; + int to_print; + int i; + + to_print = min(da_num_tokens, (int)(PAGE_SIZE - 1) / 15); + for (i = 0; i < to_print; i++) { + off += scnprintf(buf+off, PAGE_SIZE-off, "%04x\t%04x\t%04x\n", + da_tokens[i].tokenID, da_tokens[i].location, + da_tokens[i].value); + } + + return off; +} + +DEVICE_ATTR(tokens, 0400, tokens_show, NULL); + +static struct attribute *smbios_attrs[] = { + &dev_attr_tokens.attr, + NULL +}; + +static const struct attribute_group smbios_attribute_group = { + .attrs = smbios_attrs, +}; + +static struct platform_driver platform_driver = { + .driver = { + .name = "dell-smbios", + }, +}; + static int __init dell_smbios_init(void) { const struct dmi_device *valid; @@ -197,9 +233,37 @@ static int __init dell_smbios_init(void) ret = -ENOMEM; goto fail_buffer; } + ret = platform_driver_register(&platform_driver); + if (ret) + goto fail_platform_driver; + + platform_device = platform_device_alloc("dell-smbios", 0); + if (!platform_device) { + ret = -ENOMEM; + goto fail_platform_device_alloc; + } + ret = platform_device_add(platform_device); + if (ret) + goto fail_platform_device_add; + ret = sysfs_create_group(&platform_device->dev.kobj, +&smbios_attribute_group); + if (ret) + goto fail_create_group; return 0; +fail_create_group: + platform_device_del(platform_device); + +fail_platform_device_add: + platform_device_put(platform_device); + +fail_platform_device_alloc: + platform_driver_unregister(&platform_driver); + +fail_platform_driver: + free_page((unsigned long)buffer); + fail_buffer: kfree(da_tokens); return ret; -- 2.14.1
[PATCH v5 04/14] platform/x86: dell-wmi: allow 32k return size in the descriptor
Some platforms this year will be adopting 32k WMI buffer, so don't complain when encountering those. Signed-off-by: Mario Limonciello --- drivers/platform/x86/dell-wmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index ece2fe341f01..c8c7f4f9326c 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -624,7 +624,7 @@ static void dell_wmi_input_destroy(struct wmi_device *wdev) * Vendor Signature 0 4"DELL" * Object Signature 4 4" WMI" * WMI Interface Version 8 4 - * WMI buffer length12 44096 + * WMI buffer length12 44096 or 32768 */ static int dell_wmi_check_descriptor_buffer(struct wmi_device *wdev) { @@ -674,7 +674,7 @@ static int dell_wmi_check_descriptor_buffer(struct wmi_device *wdev) dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%u)\n", buffer[2]); - if (buffer[3] != 4096) + if (desc_buffer[3] != 4096 && desc_buffer[3] != 32768) dev_warn(&wdev->dev, "Dell descriptor buffer has invalid buffer length (%u)\n", buffer[3]); -- 2.14.1
[PATCH v5 09/14] platform/x86: dell-smbios: Introduce dispatcher for SMM calls
This splits up the dell-smbios driver into two drivers: * dell-smbios * dell-smbios-smm dell-smbios can operate with multiple different dispatcher drivers to perform SMBIOS operations. Also modify the interface that dell-laptop and dell-wmi use align to this model more closely. Rather than a single global buffer being allocated for all drivers, each driver will allocate and be responsible for it's own buffer. The pointer will be passed to the calling function and each dispatcher driver will then internally copy it to the proper location to perform it's call. Signed-off-by: Mario Limonciello --- MAINTAINERS| 6 + drivers/platform/x86/Kconfig | 16 ++- drivers/platform/x86/Makefile | 1 + drivers/platform/x86/dell-laptop.c | 255 - drivers/platform/x86/dell-smbios-smm.c | 136 ++ drivers/platform/x86/dell-smbios.c | 123 ++-- drivers/platform/x86/dell-smbios.h | 13 +- drivers/platform/x86/dell-wmi.c| 11 +- 8 files changed, 338 insertions(+), 223 deletions(-) create mode 100644 drivers/platform/x86/dell-smbios-smm.c diff --git a/MAINTAINERS b/MAINTAINERS index 2e3f2aea0370..8faf08ebcfee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3974,6 +3974,12 @@ L: platform-driver-...@vger.kernel.org S: Maintained F: drivers/platform/x86/dell-smbios.* +DELL SMBIOS SMM DRIVER +M: Mario Limonciello +L: platform-driver-...@vger.kernel.org +S: Maintained +F: drivers/platform/x86/dell-smbios-smm.c + DELL LAPTOP DRIVER M: Matthew Garrett M: Pali Rohár diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 7722923c968c..7cc91519bec8 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -93,12 +93,20 @@ config ASUS_LAPTOP config DELL_SMBIOS tristate - select DCDBAS + depends on DELL_SMBIOS_SMM + +config DELL_SMBIOS_SMM + tristate "Dell SMBIOS calling interface (SMM implementation)" + depends on DCDBAS + default DCDBAS + select DELL_SMBIOS ---help--- - This module provides common functions for kernel modules using - Dell SMBIOS. + This provides an implementation for the Dell SMBIOS calling interface + communicated over SMI/SMM. - If you have a Dell laptop, say Y or M here. + If you have a Dell computer from <=2017 you should say Y or M here. + If you aren't sure and this module doesn't work for your computer + it just won't load. config DELL_LAPTOP tristate "Dell Laptop Extras" diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 8636f5d3424f..e743615241f8 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_ACPI_CMPC)+= classmate-laptop.o obj-$(CONFIG_COMPAL_LAPTOP)+= compal-laptop.o obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o +obj-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_DELL_WMI) += dell-wmi.o obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index f42159fd2031..2f65f5c15d53 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -85,6 +85,7 @@ static struct platform_driver platform_driver = { } }; +static struct calling_interface_buffer *buffer; static struct platform_device *platform_device; static struct backlight_device *dell_backlight_device; static struct rfkill *wifi_rfkill; @@ -283,6 +284,23 @@ static const struct dmi_system_id dell_quirks[] __initconst = { { } }; +int dell_send_request(u16 class, u16 select, u32 arg0, u32 arg1, u32 arg2, + u32 arg3) +{ + int ret; + + buffer->class = class; + buffer->select = select; + buffer->input[0] = arg0; + buffer->input[1] = arg1; + buffer->input[2] = arg2; + buffer->input[3] = arg3; + ret = dell_smbios_call(buffer); + if (ret != 0) + return ret; + return dell_smbios_error(buffer->output[0]); +} + /* * Derived from information in smbios-wireless-ctl: * @@ -405,7 +423,6 @@ static const struct dmi_system_id dell_quirks[] __initconst = { static int dell_rfkill_set(void *data, bool blocked) { - struct calling_interface_buffer *buffer; int disable = blocked ? 1 : 0; unsigned long radio = (unsigned long)data; int hwswitch_bit = (unsigned long)data - 1; @@ -413,20 +430,14 @@ static int dell_rfkill_set(void *data, bool blocked) int status; int ret; - buffer = dell_smbios_get_buffer(); - - dell_smbios_send_request(17, 11); - ret = buffer->output[0]; + ret = dell_send_requ
[PATCH v5 05/14] platform/x86: dell-wmi-descriptor: split WMI descriptor into it's own driver
All communication on individual GUIDs should occur in separate drivers. Allowing a driver to communicate with the bus to another GUID is just a hack that discourages drivers to adopt the bus model. The information found from the WMI descriptor driver is now exported for use by other drivers. Signed-off-by: Mario Limonciello --- MAINTAINERS| 5 + drivers/platform/x86/Kconfig | 5 + drivers/platform/x86/Makefile | 1 + drivers/platform/x86/dell-wmi-descriptor.c | 162 + drivers/platform/x86/dell-wmi-descriptor.h | 18 drivers/platform/x86/dell-wmi.c| 89 ++-- 6 files changed, 198 insertions(+), 82 deletions(-) create mode 100644 drivers/platform/x86/dell-wmi-descriptor.c create mode 100644 drivers/platform/x86/dell-wmi-descriptor.h diff --git a/MAINTAINERS b/MAINTAINERS index 08b96f77f618..659dbeec4191 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4002,6 +4002,11 @@ M: Pali Rohár S: Maintained F: drivers/platform/x86/dell-wmi.c +DELL WMI DESCRIPTOR DRIVER +M: Mario Limonciello +S: Maintained +F: drivers/platform/x86/dell-wmi-descriptor.c + DELTA ST MEDIA DRIVER M: Hugues Fruchet L: linux-me...@vger.kernel.org diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 1f7959ff055c..7722923c968c 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -121,6 +121,7 @@ config DELL_WMI depends on DMI depends on INPUT depends on ACPI_VIDEO || ACPI_VIDEO = n + select DELL_WMI_DESCRIPTOR select DELL_SMBIOS select INPUT_SPARSEKMAP ---help--- @@ -129,6 +130,10 @@ config DELL_WMI To compile this driver as a module, choose M here: the module will be called dell-wmi. +config DELL_WMI_DESCRIPTOR + tristate + depends on ACPI_WMI + config DELL_WMI_AIO tristate "WMI Hotkeys for Dell All-In-One series" depends on ACPI_WMI diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 2b315d0df3b7..8636f5d3424f 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_DELL_WMI) += dell-wmi.o +obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o diff --git a/drivers/platform/x86/dell-wmi-descriptor.c b/drivers/platform/x86/dell-wmi-descriptor.c new file mode 100644 index ..72e317cf0365 --- /dev/null +++ b/drivers/platform/x86/dell-wmi-descriptor.c @@ -0,0 +1,162 @@ +/* + * Dell WMI descriptor driver + * + * Copyright (C) 2017 Dell Inc. All Rights Reserved. + * + * 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. + * + * 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. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include "dell-wmi-descriptor.h" + +#define DELL_WMI_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492" + +struct descriptor_priv { + struct list_head list; + u32 interface_version; + u32 size; +}; +static LIST_HEAD(wmi_list); + +bool dell_wmi_get_interface_version(u32 *version) +{ + struct descriptor_priv *priv; + + priv = list_first_entry_or_null(&wmi_list, + struct descriptor_priv, + list); + if (!priv) + return false; + *version = priv->interface_version; + return true; +} +EXPORT_SYMBOL_GPL(dell_wmi_get_interface_version); + +bool dell_wmi_get_size(u32 *size) +{ + struct descriptor_priv *priv; + + priv = list_first_entry_or_null(&wmi_list, + struct descriptor_priv, + list); + if (!priv) + return false; + *size = priv->size; + return true; +} +EXPORT_SYMBOL_GPL(dell_wmi_get_size); + +/* + * Descriptor buffer is 128 byte long and contains: + * + * Name Offset Length Value + * Vendor Signature 0 4"DELL" + * Object Signature 4 4" WMI" + * WMI Interface Version 8 4 + * WMI buffer length12 44096 or 32768 + */ +static int dell_wmi_descriptor_probe(struct wmi_device *wdev) +{ +
[PATCH v5 00/14] Introduce support for Dell SMBIOS over WMI
The existing way that the dell-smbios helper module and associated other drivers (dell-laptop, dell-wmi) communicate with the platform really isn't secure. It requires creating a buffer in physical DMA32 memory space and passing that to the platform via SMM. Since the platform got a physical memory pointer, you've just got to trust that the platform has only modified (and accessed) memory within that buffer. Dell Platform designers recognize this security risk and offer a safer way to communicate with the platform over ACPI. This is in turn exposed via a WMI interface to the OS. When communicating over WMI-ACPI the communication doesn't occur with physical memory pointers. When the ASL is invoked, the fixed length ACPI buffer is copied to a small operating region. The ASL will invoke the SMI, and SMM will only have access to this operating region. When the ASL returns the buffer is copied back for the OS to process. This method of communication should also deprecate the usage of the dcdbas kernel module and software dependent upon it's interface. Instead offer a character device interface for communicating with this ASL method to allow userspace to use instead. To faciliate that this patch series introduces a generic way for WMI drivers to be able to create discoverable character devices with a predictable IOCTL interface through the WMI bus when desired. Requiring WMI drivers to explicitly ask for this functionality will act as an effective vendor whitelist to character device creation. Some of this work is the basis for what will be a proper interpreter of MOF in the kernel and controls for what drivers will be able to do with that MOF. NOTE: This patch series is intended to go on top of platform-drivers-x86 linux-next. For convenience the entire series including those is also available here: https://github.com/superm1/linux/tree/wmi-smbios changes between v4 and v5: * Remove Andy's S suggested by in sysfs tokens patch * Make some output in dell-wmi-descriptor debug only * Adjust various Kconfig dependencies as recommended by Darren * Drop patch to set dell-smbios to default on ACPI_WMI, it's not needed after the Kconfig dependencies rework * Move WSMT check patch to after WMI driver is introduced. * Make common smbios call return value int as there could be errors now with drivers not being loaded. * Make SMBIOS call methods for all drivers return status * Reorder patches 2 and 4. * Don't export symbols for calling functions on dispatchers * wmi patch: - use sprintf instead of strcpy - remove needless bool for tracking found - adjust logic to look for instance_count - 1, it's zero based not 1 based. - Pass a callback to unlocked_ioctl instead of full file operations object - ioctl: Don't fail on no bound WMI driver - Add missing header for uapi - Make helper macros include data types - add compat ioctl * dell-smbios: - Add filtering functionality for SMBIOS calling interface - Use dev_dbg rather than pr_debug where possible * dell-smbios-wmi: - test for handle on b1 table - correct misc flags comment - drop access checks - use dev_dbg instead of pr_* calls - use filtering functionality - add mutexes around list add/remove - switch from get_first_device to get_first_priv and inline - add mutex locking to prevent unloading mid-call. - update to new ioctl passing - fix userspace uapi to use __u32 instead of u32 - Don't use a header file for internal only use - make sure it works with compat ioctl * dell-laptop: make dell_smbios_send_request local function for boilerplate calls. * ioctl patch - Change API to have a simpler structure to pass back and forth - Rename header file - Export to sysfs properly - Add the size of the length variable into the requested buffersize to sysfs, do math in the driver when copying data around. changes between v3 and v4: * Make Dell WMI notifications driver fail notifications fail when WMI descriptor driver is unavailable. * Add a patch to check for Dell OEM string to stop dell-smbios module from being loaded in unsupported systems manually. * Split Dell WMI descriptor into it's own driver for others to query. * Test the misc BIOS flags table to decide whether to run in WMI or SMI mode. * s/dell-wmi-smbios/dell-smbios/ in a few patch titles * Add missing Suggested-by to a patch from v2 (Sorry Andy S!) * Adjust cleanup order of wmi character device. * Fix a remaining reference to /dev/wmi-$driver * Use get_order to get size for pages * Split up dell-smbios into 3 drivers: dell-smbios -> dell-smbios-smm -> dell-smbios-wmi If either of the two dispatcher drivers is unloaded but the other still works, gracefully fall back to that driver * Remove unneded open and release on file operations in WMI driver * Switch to misc character device in WMI bus. * Query the size of the calling interface buffer from
[PATCH v5 11/14] platform/x86: dell-smbios-wmi: Add new WMI dispatcher driver
The dell-smbios stack only currently uses an SMI interface which grants direct access to physical memory to the firmware SMM methods via a pointer. This dispatcher driver adds a WMI-ACPI interface that is detected by WMI probe and preferred over the SMI interface in dell-smbios. Changing this to operate over WMI-ACPI will use an ACPI OperationRegion for a buffer of data storage when SMM calls are performed. This is a safer approach to use in kernel drivers as the SMM will only have access to that OperationRegion. Signed-off-by: Mario Limonciello --- MAINTAINERS| 6 + drivers/platform/x86/Kconfig | 16 ++- drivers/platform/x86/Makefile | 1 + drivers/platform/x86/dell-smbios-wmi.c | 229 + 4 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 drivers/platform/x86/dell-smbios-wmi.c diff --git a/MAINTAINERS b/MAINTAINERS index 8faf08ebcfee..e7514b616e13 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3980,6 +3980,12 @@ L: platform-driver-...@vger.kernel.org S: Maintained F: drivers/platform/x86/dell-smbios-smm.c +DELL SMBIOS WMI DRIVER +M: Mario Limonciello +L: platform-driver-...@vger.kernel.org +S: Maintained +F: drivers/platform/x86/dell-smbios-wmi.c + DELL LAPTOP DRIVER M: Matthew Garrett M: Pali Rohár diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 7cc91519bec8..7b0b8379 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -93,7 +93,21 @@ config ASUS_LAPTOP config DELL_SMBIOS tristate - depends on DELL_SMBIOS_SMM + depends on DELL_SMBIOS_WMI || DELL_SMBIOS_SMM + +config DELL_SMBIOS_WMI + tristate "Dell SMBIOS calling interface (WMI implementation)" + depends on ACPI_WMI + select DELL_WMI_DESCRIPTOR + default ACPI_WMI + select DELL_SMBIOS + ---help--- + This provides an implementation for the Dell SMBIOS calling interface + communicated over ACPI-WMI. + + If you have a Dell computer from >2007 you should say Y or M here. + If you aren't sure and this module doesn't work for your computer + it just won't load. config DELL_SMBIOS_SMM tristate "Dell SMBIOS calling interface (SMM implementation)" diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index e743615241f8..1c4234861de0 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_ACPI_CMPC)+= classmate-laptop.o obj-$(CONFIG_COMPAL_LAPTOP)+= compal-laptop.o obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o +obj-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o obj-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_DELL_WMI) += dell-wmi.o diff --git a/drivers/platform/x86/dell-smbios-wmi.c b/drivers/platform/x86/dell-smbios-wmi.c new file mode 100644 index ..3de8abea38f8 --- /dev/null +++ b/drivers/platform/x86/dell-smbios-wmi.c @@ -0,0 +1,229 @@ +/* + * WMI methods for use with dell-smbios + * + * Copyright (c) 2017 Dell Inc. + * + * 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. + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include "dell-smbios.h" +#include "dell-wmi-descriptor.h" +static DEFINE_MUTEX(call_mutex); +static DEFINE_MUTEX(list_mutex); +static int wmi_supported; + +struct misc_bios_flags_structure { + struct dmi_header header; + u16 flags0; +} __packed; +#define FLAG_HAS_ACPI_WMI 0x02 + +#define DELL_WMI_SMBIOS_GUID "A80593CE-A997-11DA-B012-B622A1EF5492" + +struct wmi_extensions { + __u32 argattrib; + __u32 blength; + __u8 data[]; +} __packed; + +struct wmi_smbios_buffer { + struct calling_interface_buffer std; + struct wmi_extensions ext; +} __packed; + +struct wmi_smbios_priv { + struct wmi_smbios_buffer *buf; + struct list_head list; + struct wmi_device *wdev; + struct device *child; + u32 buffer_size; +}; +static LIST_HEAD(wmi_list); + +static inline struct wmi_smbios_priv *get_first_smbios_priv(void) +{ + return list_first_entry_or_null(&wmi_list, + struct wmi_smbios_priv, + list); +} + +static int run_smbios_call(struct wmi_device *wdev) +{ + struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; + struct wmi_smbios_priv *priv; + struct acpi_buffer input; + union acpi_object *obj; + acpi_status status; + + priv = dev_get_drvdata(&wdev->dev); + input.length = priv->buffer_size; + input.pointer
[PATCH v5 10/14] platform/x86: dell-smbios: add filtering capability for requests
There are some categories of tokens and SMBIOS calls that it makes sense to protect userspace from accessing. These are calls that may write to one time use fields or activate hardware debugging capabilities. They are not intended for general purpose use. This same functionality may be be later extended to also intercept calls that may cause kernel functionality to get out of sync if the same functions are used by other drivers. Signed-off-by: Mario Limonciello --- drivers/platform/x86/dell-smbios.c | 76 ++ drivers/platform/x86/dell-smbios.h | 2 + 2 files changed, 78 insertions(+) diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios.c index 2f90ba5346bc..d1908f159be3 100644 --- a/drivers/platform/x86/dell-smbios.c +++ b/drivers/platform/x86/dell-smbios.c @@ -32,6 +32,7 @@ struct calling_interface_structure { struct calling_interface_token tokens[]; } __packed; +static u32 da_supported_commands; static int da_command_address; static int da_command_code; static int da_num_tokens; @@ -45,6 +46,14 @@ struct smbios_device { int (*call_fn)(struct calling_interface_buffer *); }; +static u32 token_black[] = { + 0x0175, 0x0176, 0x0195, 0x0196, 0x0197, 0x01DC, 0x01DD, 0x027D, 0x027E, + 0x027F, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x02E3, 0x02FF, 0x0300, + 0x0301, 0x0302, 0x0325, 0x0326, 0x0332, 0x0333, 0x0334, 0x0335, 0x0350, + 0x0363, 0x0368, 0x03F6, 0x03F7, 0x049E, 0x049F, 0x04A0, 0x04A1, 0x04A2, + 0x04A3, 0x04E6, 0x04E7, 0x9000, 0x9001 +}; + static LIST_HEAD(smbios_device_list); void dell_smbios_get_smm_address(int *address, int *code) @@ -104,6 +113,65 @@ void dell_smbios_unregister_device(struct device *d) } EXPORT_SYMBOL_GPL(dell_smbios_unregister_device); +int dell_smbios_call_filter(struct device *d, + struct calling_interface_buffer *buffer) +{ + int i; + int j; + u32 t; + + /* can't make calls over 30 */ + if (buffer->class > 30) { + dev_dbg(d, "buffer->class too big: %d\n", buffer->class); + return -EINVAL; + } + + /* supported calls on the particular system */ + if (!(da_supported_commands & (1 << buffer->class))) { + dev_dbg(d, "invalid command, supported commands: 0x%8x\n", + da_supported_commands); + return -EINVAL; + } + + /* diagonstics, debugging information or write once */ + if ((buffer->class == 01 && buffer->select == 07) || + (buffer->class == 06 && buffer->select == 05) || + (buffer->class == 11 && buffer->select == 03) || + (buffer->class == 11 && buffer->select == 07) || + (buffer->class == 11 && buffer->select == 11) || +buffer->class == 19) { + dev_dbg(d, "blacklisted command: %d/%d\n", + buffer->class, buffer->select); + return -EINVAL; + } + + /* reading/writing tokens*/ + if ((buffer->class == 0 && buffer->select < 3) || + (buffer->class == 1 && buffer->select < 3)) { + for (i = 0; i < da_num_tokens; i++) { + if (da_tokens[i].location != buffer->input[0]) + continue; + /*blacklist reading and writing these */ + t = da_tokens[i].tokenID; + if ((t >= 0x4000 && t <= 0x7FFF) || + (t >= 0xA000 && t <= 0xBFFF) || + (t >= 0xEFF0 && t <= 0xEFFF)) + return -EINVAL; + for (j = 0; j < ARRAY_SIZE(token_black); j++) + if (t == token_black[j]) + return -EINVAL; + /* token exists and is OK */ + return 0; + } + /* token didn't exist */ + dev_dbg(d, "token at location %u doesn't exist\n", + buffer->input[0]); + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL_GPL(dell_smbios_call_filter); + int dell_smbios_call(struct calling_interface_buffer *buffer) { int (*call_fn)(struct calling_interface_buffer *) = NULL; @@ -127,6 +195,13 @@ int dell_smbios_call(struct calling_interface_buffer *buffer) goto out_smbios_call; } + if (dell_smbios_call_filter(selected_dev, buffer)) { + ret = -EINVAL; + dev_err(selected_dev, "Invalid call %d/%d:%8x\n", + buffer->class, buffer->select, buffer->input[0]); + goto out_smbios_call; + } + ret = call_fn(buffer); out_smbios_call: @@ -184,6 +259,7 @@ static void __init parse_da_table(const struct dmi_header *dm) da_command_address = table->cmdIOAddress; da_command_code =
[PATCH v5 13/14] platform/x86: wmi: create character devices when requested by drivers
For WMI operations that are only Set or Query read or write sysfs attributes created by WMI vendor drivers make sense. For other WMI operations that are run on Method, there needs to be a way to guarantee to userspace that the results from the method call belong to the data request to the method call. Sysfs attributes don't work well in this scenario because two userspace processes may be competing at reading/writing an attribute and step on each other's data. When a WMI vendor driver declares an ioctl callback in the wmi_driver the WMI bus driver will create a character device that maps to that function. That character device will correspond to this path: /dev/wmi/$driver The WMI bus driver will interpret the IOCTL calls, test them for a valid instance and pass them on to the vendor driver to run. This creates an implicit policy that only driver per character device. If a module matches multiple GUID's, the wmi_devices will need to be all handled by the same wmi_driver if the same character device is used. The WMI vendor drivers will be responsible for managing access to this character device and proper locking on it. When a WMI vendor driver is unloaded the WMI bus driver will clean up the character device. Signed-off-by: Mario Limonciello --- MAINTAINERS| 1 + drivers/platform/x86/wmi.c | 85 ++ include/linux/wmi.h| 5 +++ include/uapi/linux/wmi.h | 19 +++ 4 files changed, 110 insertions(+) create mode 100644 include/uapi/linux/wmi.h diff --git a/MAINTAINERS b/MAINTAINERS index e7514b616e13..2a99ee9fd883 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -372,6 +372,7 @@ ACPI WMI DRIVER L: platform-driver-...@vger.kernel.org S: Orphan F: drivers/platform/x86/wmi.c +F: include/uapi/linux/wmi.h AD1889 ALSA SOUND DRIVER M: Thibaut Varene diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index bcb41c1c7f52..114d28aafa16 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,7 @@ struct wmi_block { struct wmi_device dev; struct list_head list; struct guid_block gblock; + struct miscdevice misc_dev; struct acpi_device *acpi_device; wmi_notify_handler handler; void *handler_data; @@ -765,12 +767,90 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) return 0; } +static int match_ioctl(struct file *filp, unsigned int cmd, unsigned long arg, + int compat) +{ + struct wmi_driver *wdriver = NULL; + struct wmi_block *wblock = NULL; + const char *driver_name; + struct list_head *p; + + if (_IOC_TYPE(cmd) != WMI_IOC) + return -ENOTTY; + + driver_name = filp->f_path.dentry->d_iname; + + list_for_each(p, &wmi_block_list) { + wblock = list_entry(p, struct wmi_block, list); + wdriver = container_of(wblock->dev.dev.driver, + struct wmi_driver, driver); + if (!wdriver) + continue; + if (strcmp(driver_name, wdriver->driver.name) == 0) + break; + } + + if (!wdriver) + return -ENODEV; + + /* make sure we're not calling a higher instance than exists*/ + if (_IOC_NR(cmd) > wblock->gblock.instance_count - 1) + return -EINVAL; + + if (!compat) + return wdriver->unlocked_ioctl(&wblock->dev, cmd, arg); + + /* not all vendor drivers may specify this */ + if (!wdriver->compat_ioctl) + return -ENODEV; + + return wdriver->compat_ioctl(&wblock->dev, cmd, arg); +} + +static long wmi_unlocked_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + return match_ioctl(filp, cmd, arg, 0); +} + +static long wmi_compat_ioctl(struct file *filp, unsigned int cmd, +unsigned long arg) +{ + return match_ioctl(filp, cmd, arg, 1); +} + +static const struct file_operations wmi_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = wmi_unlocked_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = wmi_compat_ioctl, +#endif +}; + static int wmi_dev_probe(struct device *dev) { struct wmi_block *wblock = dev_to_wblock(dev); struct wmi_driver *wdriver = container_of(dev->driver, struct wmi_driver, driver); int ret = 0; + char *buf; + + /* driver wants a character device made */ + if (wdriver->unlocked_ioctl) { + buf = kmalloc(strlen(wdriver->driver.name) + 4, GFP_KERNEL); + if (!buf) + return -ENOMEM; + sprintf(buf, "wmi/%s", wdriver->driver.name); + wblock->mis
[PATCH v5 14/14] platform/x86: dell-smbios-wmi: introduce userspace interface
It's important for the driver to provide a R/W ioctl to ensure that two competing userspace processes don't race to provide or read each others data. This userspace character device will be used to perform SMBIOS calls from any applications. It provides an ioctl that will allow passing the WMI calling interface buffer between userspace and kernel space. This character device is intended to deprecate the dcdbas kernel module and the interface that it provides to userspace. To use the character device the buffer needed for the machine will also be needed. This information is exported to a sysfs attribute. The API for interacting with this interface is defined in documentation as well as a uapi header provides the format of the structures. Signed-off-by: Mario Limonciello --- Documentation/ABI/testing/dell-smbios-wmi | 41 .../ABI/testing/sysfs-platform-dell-smbios-wmi | 10 ++ MAINTAINERS| 1 + drivers/platform/x86/dell-smbios-wmi.c | 104 ++--- drivers/platform/x86/dell-smbios.h | 11 +-- include/uapi/linux/dell-smbios.h | 42 + 6 files changed, 188 insertions(+), 21 deletions(-) create mode 100644 Documentation/ABI/testing/dell-smbios-wmi create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-smbios-wmi create mode 100644 include/uapi/linux/dell-smbios.h diff --git a/Documentation/ABI/testing/dell-smbios-wmi b/Documentation/ABI/testing/dell-smbios-wmi new file mode 100644 index ..e067e955fcc9 --- /dev/null +++ b/Documentation/ABI/testing/dell-smbios-wmi @@ -0,0 +1,41 @@ +What: /dev/wmi/dell-smbios +Date: November 2017 +KernelVersion: 4.15 +Contact: "Mario Limonciello" +Description: + Perform SMBIOS calls on supported Dell machines. + through the Dell ACPI-WMI interface. + + IOCTL's and buffer formats are defined in: + + + 1) To perform a call from userspace, you'll need to first + determine the minimum size of the calling interface buffer + for your machine. + Platforms that contain larger buffers can return larger + objects from the system firmware. + Commonly this size is either 4k or 32k. + + To determine the size of the buffer, refer to: + sysfs-platform-dell-smbios-wmi + + 2) After you've determined the minimum size of the calling + interface buffer, you can allocate a structure that represents + the structure documented above. + + 3) In the 'length' object store the size of the buffer you + determined above and allocated. + + 4) In this buffer object, prepare as necessary for the SMBIOS + call you're interested in. Typically SMBIOS buffers have + "class", "select", and "input" defined to values that coincide + with the data you are interested in. + Documenting class/select/input values is outside of the scope + of this documentation. Check with the libsmbios project for + further documentation on these values. + + 6) Run the call by using ioctl() as described in the header. + + 7) The output will be returned in the buffer object. + + 8) Be sure to free up your allocated object. diff --git a/Documentation/ABI/testing/sysfs-platform-dell-smbios-wmi b/Documentation/ABI/testing/sysfs-platform-dell-smbios-wmi new file mode 100644 index ..6a0513703a3c --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-smbios-wmi @@ -0,0 +1,10 @@ +What: /sys/devices/platform//buffer_size +Date: November 2017 +KernelVersion: 4.15 +Contact: "Mario Limonciello" +Description: + A read-only description of the size of a calling + interface buffer that can be passed to Dell + firmware. + + Commonly this size is either 4k or 32k. diff --git a/MAINTAINERS b/MAINTAINERS index 2a99ee9fd883..4940f3c7481b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3986,6 +3986,7 @@ M:Mario Limonciello L: platform-driver-...@vger.kernel.org S: Maintained F: drivers/platform/x86/dell-smbios-wmi.c +F: include/uapi/linux/dell-smbios.h DELL LAPTOP DRIVER M: Matthew Garrett diff --git a/drivers/platform/x86/dell-smbios-wmi.c b/drivers/platform/x86/dell-smbios-wmi.c index 3de8abea38f8..2b78aba68755 100644 --- a/drivers/platform/x86/dell-smbios-wmi.c +++ b/drivers/platform/x86/dell-smbios-wmi.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "dell-smbios.h" #include "dell-wmi-descriptor.h" static DEFINE_MUTEX(call_mutex); @@ -29,19 +30,9 @@ struct misc_bios_flags_structure { #define DELL_WMI_SMBIOS_GUID "A80593CE-A99
[PATCH v5 06/14] platform/x86: wmi: Don't allow drivers to get each other's GUIDs
The only driver using this was dell-wmi, and it really was a hack. The driver was getting a data attribute from another driver and this type of action should not be encouraged. Rather drivers that need to interact with one another should pass data back and forth via exported functions. Signed-off-by: Mario Limonciello --- drivers/platform/x86/wmi.c | 17 - include/linux/wmi.h| 4 2 files changed, 21 deletions(-) diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 4d73a87c2ddf..bcb41c1c7f52 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -368,23 +368,6 @@ union acpi_object *wmidev_block_query(struct wmi_device *wdev, u8 instance) } EXPORT_SYMBOL_GPL(wmidev_block_query); -struct wmi_device *wmidev_get_other_guid(struct wmi_device *wdev, -const char *guid_string) -{ - struct wmi_block *this_wb = container_of(wdev, struct wmi_block, dev); - struct wmi_block *other_wb; - - if (!find_guid(guid_string, &other_wb)) - return NULL; - - if (other_wb->acpi_device != this_wb->acpi_device) - return NULL; - - get_device(&other_wb->dev.dev); - return &other_wb->dev; -} -EXPORT_SYMBOL_GPL(wmidev_get_other_guid); - /** * wmi_set_block - Write to a WMI block * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba diff --git a/include/linux/wmi.h b/include/linux/wmi.h index 2cd10c3b89e9..ddee427e0721 100644 --- a/include/linux/wmi.h +++ b/include/linux/wmi.h @@ -36,10 +36,6 @@ extern acpi_status wmidev_evaluate_method(struct wmi_device *wdev, extern union acpi_object *wmidev_block_query(struct wmi_device *wdev, u8 instance); -/* Gets another device on the same bus. Caller must put_device the result. */ -extern struct wmi_device *wmidev_get_other_guid(struct wmi_device *wdev, - const char *guid_string); - struct wmi_device_id { const char *guid_string; }; -- 2.14.1
[PATCH v5 12/14] platform/x86: dell-smbios-smm: test for WSMT
WSMT is as an attestation to the OS that the platform won't modify memory outside of pre-defined areas. If a platform has WSMT enabled in BIOS setup, SMM calls through dcdbas will fail. The only way to access platform data in these instances is through the WMI SMBIOS calling interface. Signed-off-by: Mario Limonciello --- drivers/platform/x86/dell-smbios-smm.c | 34 ++ 1 file changed, 34 insertions(+) diff --git a/drivers/platform/x86/dell-smbios-smm.c b/drivers/platform/x86/dell-smbios-smm.c index 223531e43fea..ba315753e847 100644 --- a/drivers/platform/x86/dell-smbios-smm.c +++ b/drivers/platform/x86/dell-smbios-smm.c @@ -25,6 +25,8 @@ static struct calling_interface_buffer *buffer; struct platform_device *platform_device; static DEFINE_MUTEX(smm_mutex); +#define WSMT_EN_TOKEN 0x04EC + static const struct dmi_system_id dell_device_table[] __initconst = { { .ident = "Dell laptop", @@ -76,6 +78,30 @@ int dell_smbios_smm_call(struct calling_interface_buffer *input) return 0; } +static int test_wsmt_enabled(void) +{ + struct calling_interface_token *token; + + /* if token doesn't exist, SMM will work */ + token = dell_smbios_find_token(WSMT_EN_TOKEN); + if (!token) + return 0; + + /* if token exists, try to access over SMM */ + buffer->class = 0; + buffer->select = 0; + memset(buffer, 0, sizeof(struct calling_interface_buffer)); + buffer->input[0] = token->location; + dell_smbios_smm_call(buffer); + + /* if lookup failed, we know WSMT was enabled */ + if (buffer->output[0] != 0) + return 1; + + /* query token status if it didn't fail */ + return (buffer->output[1] == token->value); +} + static int __init dell_smbios_smm_init(void) { int ret; @@ -88,6 +114,13 @@ static int __init dell_smbios_smm_init(void) return -ENOMEM; dell_smbios_get_smm_address(&da_command_address, &da_command_code); + ret = test_wsmt_enabled(); + pr_debug("WSMT enable test: %d\n", ret); + if (ret) { + ret = -ENODEV; + goto fail_wsmt; + } + platform_device = platform_device_alloc("dell-smbios", 1); if (!platform_device) { ret = -ENOMEM; @@ -111,6 +144,7 @@ static int __init dell_smbios_smm_init(void) fail_platform_device_add: platform_device_put(platform_device); +fail_wsmt: fail_platform_device_alloc: free_page((unsigned long)buffer); return ret; -- 2.14.1
Re: [ANNOUNCE] v4.11.12-rt13
On Fri, 2017-10-06 at 19:38 +0200, Mike Galbraith wrote: > On Fri, 2017-10-06 at 15:33 +0200, Mike Galbraith wrote: > > > > I'll run full ltp again, make sure there are no new failure deltas. > > Haven't done that yet, but I have checked all of the reported failures. > > time-hrtimer:-Use-softirq-based-wakeups-for-non-RT-threads.patch fixes > clock_settime_8-1.run-test, hrtimer:-Update-offset-for-soft-bases.patch > fixes the rest. > > However... testcases/open_posix_testsuite/conformance/interfaces/clock_settime/8-1.c: * Steps: * - get time T0 * - in child: set clock_nanosleep() to sleep for SLEEPSEC seconds * - in parent: sleep SMALLTIME (< SLEEPSEC) * - in parent: set time back to T0 * - in child: ensure time when clock_nanosleep() expires is within * ACCEPTABLEDELTA of T0+(SLEEPSEC-SMALLTIME) ... #define SLEEPSEC 5 #define SMALLTIME 2 #define ACCEPTABLEDELTA 1 homer:..debug/tracing # time chrt -o 0 /usr/local/ltp/conformance/interfaces/clock_settime/clock_settime_8-1.run-test Test PASSED real0m5.002s user0m0.000s sys 0m0.001s homer:..debug/tracing # time chrt -f 1 /usr/local/ltp/conformance/interfaces/clock_settime/clock_settime_8-1.run-test Ended too late. 1507351636 >> 1507351634 Test FAILED real0m7.002s user0m0.000s sys 0m0.002s
[rcu:rcu/next 48/97] drivers/firmware/tegra/ivc.c:154:39: error: lvalue required as left operand of assignment
tree: https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next head: bd76953f4e7b0b1f66b3fe631106fcc4c85a380c commit: 669f98e232aa6f77bd602e2826dd55c3694109e5 [48/97] drivers/firmware/tegra: Convert ACCESS_ONCE() to READ_ONCE() config: arm64-defconfig (attached as .config) compiler: aarch64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 669f98e232aa6f77bd602e2826dd55c3694109e5 # save the attached .config to linux build tree make.cross ARCH=arm64 All errors (new ones prefixed by >>): drivers/firmware/tegra/ivc.c: In function 'tegra_ivc_advance_tx': >> drivers/firmware/tegra/ivc.c:154:39: error: lvalue required as left operand >> of assignment READ_ONCE(ivc->tx.channel->tx.count) = ^ drivers/firmware/tegra/ivc.c: In function 'tegra_ivc_advance_rx': drivers/firmware/tegra/ivc.c:165:39: error: lvalue required as left operand of assignment READ_ONCE(ivc->rx.channel->rx.count) = ^ vim +154 drivers/firmware/tegra/ivc.c 151 152 static inline void tegra_ivc_advance_tx(struct tegra_ivc *ivc) 153 { > 154 READ_ONCE(ivc->tx.channel->tx.count) = 155 READ_ONCE(ivc->tx.channel->tx.count) + 1; 156 157 if (ivc->tx.position == ivc->num_frames - 1) 158 ivc->tx.position = 0; 159 else 160 ivc->tx.position++; 161 } 162 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] crypto: bcm: use of_device_get_match_data
On Wed, Sep 20, 2017 at 08:47:26PM +0200, Corentin Labbe wrote: > The usage of of_device_get_match_data reduce the code size a bit. > Furthermore, it prevents an improbable dereference when > of_match_device() return NULL. > > Signed-off-by: Corentin Labbe Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH] crypto: stm32: use of_device_get_match_data
On Wed, Sep 20, 2017 at 08:31:40PM +0200, Corentin Labbe wrote: > The usage of of_device_get_match_data reduce the code size a bit. > Furthermore, it prevents an improbable dereference when > of_match_device() return NULL. > > Signed-off-by: Corentin Labbe Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH] crypto: omap: use of_device_get_match_data
On Wed, Sep 20, 2017 at 08:42:48PM +0200, Corentin Labbe wrote: > The usage of of_device_get_match_data reduce the code size a bit. > Furthermore, it prevents an improbable dereference when > of_match_device() return NULL. > > Signed-off-by: Corentin Labbe Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH] crypto: algboss: remove redundant setting of len to zero
On Thu, Sep 14, 2017 at 07:02:19PM +0100, Colin King wrote: > From: Colin Ian King > > The variable len is set to zero, never read and then later updated > to p - name, so clearly the zero'ing of len is redundant and > can be removed. > > Detected by clang scan-build: > " warning: Value stored to 'len' is never read" > > Signed-off-by: Colin Ian King Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH 02/10] drivers:crypto: return -ENOMEM on allocation failure.
Allen Pais wrote: > Signed-off-by: Allen Pais Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH 1/2] crypto: stm32 - Fix uninitialized data usage
On Tue, Sep 12, 2017 at 11:35:38AM +0200, Arnd Bergmann wrote: > The error handling in stm32_hash_irq_thread passes > uninitialized data into stm32_hash_finish_req, as gcc > points out: > > drivers/crypto/stm32/stm32-hash.c: In function 'stm32_hash_irq_thread': > drivers/crypto/stm32/stm32-hash.c:1088:2: error: 'err' may be used > uninitialized in this function [-Werror=maybe-uninitialized] > > I could not tell what data should be passed there instead, > so this changes the code to always pass zero, making it > well-defined, though possibly still wrong. Please check. > > Signed-off-by: Arnd Bergmann This is already fixed in cryptodev. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH 2/2] crypto: stm32 - Try to fix hash padding
On Tue, Sep 12, 2017 at 11:35:39AM +0200, Arnd Bergmann wrote: > gcc warns that the length for the extra unaligned data in the hash > function may be used unaligned. In theory this could happen if > we pass a zero-length sg_list, or if sg_is_last() was never true: > > In file included from drivers/crypto/stm32/stm32-hash.c:23: > drivers/crypto/stm32/stm32-hash.c: In function 'stm32_hash_one_request': > include/uapi/linux/kernel.h:12:49: error: 'ncp' may be used uninitialized in > this function [-Werror=maybe-uninitialized] > #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) > > Neither of these can happen in practice, so the warning is harmless. > > However while trying to suppress the warning, I noticed multiple > problems with that code: > > - On big-endian kernels, we byte-swap the data like we do for > register accesses, however this is a data stream and almost > certainly needs to use a single writesl() instead of series > of writel() to give the correct hash. > > - If the length is not a multiple of four bytes, we skip the > last word entirely, since we write the truncated length > using stm32_hash_set_nblw(). > > - If we change the code to round the length up rather than > down, the last bytes contain stale data, so it needs some > form of padding. > > This tries to address all four problems, by correctly > initializing the length to zero, using endian-safe copy > functions, adding zero-padding and passing the padded length. > > I have done no testing on this patch, so please review > carefully and if possible test with an unaligned length > and big-endian kernel builds. > > Fixes: 8a1012d3f2ab ("crypto: stm32 - Support for STM32 HASH module") > Signed-off-by: Arnd Bergmann Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH] crc32-pclmul: remove useless relative addressing
On Wed, Sep 06, 2017 at 10:41:21PM -0400, Mikulas Patocka wrote: > In 32-bit mode, the x86 architecture can hold full 32-bit pointers. > Therefore, the code that copies the current address to the %ecx register > and uses %ecx-relative addressing is useless, we could just use absolute > addressing. > > The processors have a stack of return addresses for branch prediction. If > we use a call instruction and pop the return address, it desynchronizes > the return stack and causes branch prediction misses. > > This patch also moves the data to the .rodata section. > > Signed-off-by: Mikulas Patocka Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH] crypto: xts - Fix an error handling path in 'create()'
On Tue, Sep 26, 2017 at 08:17:44AM +0200, Christophe JAILLET wrote: > All error handling paths 'goto err_drop_spawn' except this one. > In order to avoid some resources leak, we should do it as well here. > > Fixes: f1c131b45410 ("crypto: xts - Convert to skcipher") > Signed-off-by: Christophe JAILLET Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [Patch v6 1/7] slimbus: Device management on SLIMbus
Hi, I have some more or less trivial comments below. On Fri, Oct 06, 2017 at 05:51:30PM +0200, srinivas.kandaga...@linaro.org wrote: > From: Sagar Dharia > > SLIMbus (Serial Low Power Interchip Media Bus) is a specification > developed by MIPI (Mobile Industry Processor Interface) alliance. > SLIMbus is a 2-wire implementation, which is used to communicate with > peripheral components like audio-codec. > SLIMbus uses Time-Division-Multiplexing to accommodate multiple data > channels, and control channel. Control channel has messages to do > device-enumeration, messages to send/receive control-data to/from > slimbus devices, messages for port/channel management, and messages to > do bandwidth allocation. > The framework supports multiple instances of the bus (1 controller per > bus), and multiple slave devices per controller. > > This patch does device enumeration, logical address assignment, > informing device when the device reports present/absent etc. > Reporting present may need the driver to do the needful (e.g. turning > on voltage regulators powering the device). Additionally device is > probed when it reports present if that device doesn't need any such > steps mentioned above. > > Signed-off-by: Sagar Dharia > Signed-off-by: Srinivas Kandagatla > --- [...] > +SLIMbus example for Qualcomm's slimbus manager component: > + > + slim@2808 { > + compatible = "qcom,slim-msm"; > + reg = <0x2808 0x2000>, > + interrupts = <0 33 0>; > + clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>; > + clock-names = "iface_clk", "core_clk"; > + #address-cells = <2>; > + #size-cells = <0>; > + > + codec: wcd9310@1{ > + compatible = "slim217,60""; ^ spurious quote? > + reg = <1 0>; > + }; > + }; > diff --git a/Documentation/slimbus/summary b/Documentation/slimbus/summary > new file mode 100644 > index 000..e7f90bb > --- /dev/null > +++ b/Documentation/slimbus/summary Should this file have a .rst extension, like other Restructured Text files? > @@ -0,0 +1,109 @@ > +Overview of Linux kernel SLIMbus support > + [...] > +Device notifications to the driver: > +--- > +Since SLIMbus devices have mechanisms for reporting their presence, the > +framework allows drivers to bind when corresponding devices report their > +presence on the bus. > +However, it is possible that the driver needs to be probed > +first so that it can enable corresponding SLIMbus devie (e.g. power it up > and/or s/devie/device/ I guess > +take it out of reset). To support that behavior, the framework allows drivers > +to probe first as well (e.g. using standard DeviceTree compatbility field). > +This creates the necessity for the driver to know when the device is > functional > +(i.e. reported present). device_up callback is used for that reason when the > +device reports present and is assigned a logical address by the controller. [...] > +/** > + * struct slim_addrt: slimbus address used internally by the slimbus > framework. > + * @valid: If the device is present. Valid is set to false when device > reports > + * absent. > + * @eaddr: Enumeration address > + * @laddr: It is possible that controller will set a predefined logical > address > + * rather than the one assigned by framework. (i.e. logical address may > + * not be same as index into this table). This entry will store the > + * logical address value for this enumeration address. > + */ > +struct slim_addrt { > + boolvalid; > + struct slim_eaddr eaddr; > + u8 laddr; > +}; I wonder if valid should be moved after eaddr, to reduce the need for padding. AFAICS, struct slim_eaddr is 6 bytes long and requires 2-byte alignment, so if valid is one byte long, there would be one byte of padding after it, slightly bloating struct slim_addrt, unnecessarily. > +/** > + * struct slim_controller: Controls every instance of SLIMbus > + * (similar to 'master' on SPI) > + * 'Manager device' is responsible for device management, bandwidth > + * allocation, channel setup, and port associations per channel. > + * Device management means Logical address assignment/removal based on > + * enumeration (report-present, report-absent) if a device. s/if a device/of a device/ ? > + * Bandwidth allocation is done dynamically by the manager based on active > + * channels on the bus, message-bandwidth requests made by slimbus devices. > + * Based on current bandwidth usage, manager chooses a frequency to run > + * the bus at (in steps of 'clock-gear', 1 through 10, each clock gear > + * representing twice the frequency than the previous gear). > + * Manager is also responsible for entering (and exiting) low-po
Re: [PATCH 1/2] Revert "vmalloc: back off when the current task is killed"
Johannes Weiner wrote: > On Sat, Oct 07, 2017 at 11:21:26AM +0900, Tetsuo Handa wrote: > > On 2017/10/05 19:36, Tetsuo Handa wrote: > > > I don't want this patch backported. If you want to backport, > > > "s/fatal_signal_pending/tsk_is_oom_victim/" is the safer way. > > > > If you backport this patch, you will see "complete depletion of memory > > reserves" > > and "extra OOM kills due to depletion of memory reserves" using below > > reproducer. > > > > -- > > #include > > #include > > #include > > > > static char *buffer; > > > > static int __init test_init(void) > > { > > set_current_oom_origin(); > > buffer = vmalloc((1UL << 32) - 480 * 1048576); > > That's not a reproducer, that's a kernel module. It's not hard to > crash the kernel from within the kernel. > When did we agree that "reproducer" is "userspace program" ? A "reproducer" is a program that triggers something intended. Year by year, people are spending efforts for kernel hardening. It is silly to say that "It's not hard to crash the kernel from within the kernel." when we can easily mitigate. Even with cd04ae1e2dc8, there is no point with triggering extra OOM kills by needlessly consuming memory reserves.
Re: [PATCH] sched/rt.c: pick and check task if double_lock_balance() unlock the rq
Hi Steven, Peter, On 2017/9/26 11:18, Steven Rostedt wrote: On Tue, 26 Sep 2017 09:23:20 +0800 zhouchengming wrote: On 2017/9/26 3:40, Steven Rostedt wrote: On Mon, 11 Sep 2017 14:51:49 +0800 Zhou Chengming wrote: push_rt_task() pick the first pushable task and find an eligible lowest_rq, then double_lock_balance(rq, lowest_rq). So if double_lock_balance() unlock the rq (when double_lock_balance() return 1), we have to check if this task is still on the rq. The problem is that the check conditions are not sufficient: if (unlikely(task_rq(task) != rq || !cpumask_test_cpu(lowest_rq->cpu,&task->cpus_allowed) || task_running(rq, task) || !rt_task(task) || !task_on_rq_queued(task))) { cpu2cpu1cpu0 push_rt_task(rq1) pick task_A on rq1 find rq0 double_lock_balance(rq1, rq0) unlock(rq1) rq1 __schedule pick task_A run task_A sleep (dequeued) lock(rq0) lock(rq1) do_above_check(task_A) task_rq(task_A) == rq1 cpus_allowed unchanged task_running == false rt_task(task_A) == true try_to_wake_up(task_A) select_cpu = cpu3 enqueue(rq3, task_A) How can this happen? The try_to_wake_up(task_A) needs to grab the rq that task A is on, and we have that rq lock. /me confused. -- Steve Thanks for the reply! After the task_A sleep on cpu1, the try_to_wake_up(task_A) on cpu0 select a different cpu3, so it will grab the rq3 lock, not the rq1 lock. Ah crap. This is caused by 7608dec2ce20 ("sched: Drop the rq argument to sched_class::select_task_rq()"). Because this code depends on try_to_wake_up() grabbing the task's rq lock. But it no longer does that, and it causes this race. OK, I need to look at this deeper when I'm not so jetlagged and typing this because I can't sleep at 5am. Thanks for pointing this out! It may be fixed by simply grabbing the run queue lock on migration, as that would sync things up. Is there any new solution? I don't think grabbing the rq lock without the task->pi_lock will fix this problem. And I think my patch is correct and the changes are small. Thanks! Peter? -- Steve .
Re: [RFC PATCH] crypto: make the seed() function optional
Mathieu Malaterre wrote: > This makes it simplier for driver author to not provide the seed() function > in case of a pseudo RNG where the seed operation is a no-op. > > Document that the seed() function pointer is optional in header. > > Signed-off-by: Mathieu Malaterre > --- > The PRNG as found on Ingenic JZ4780 is one such example. This is found on a > MIPS Creator CI20 SoC. So how does it seed itself? This also contradicts with the JZ4780 driver that's currently in the patch queue as it does contain a seed function. Cheers, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH] mwifiex: Use put_unaligned_le32
Hi Himanshu, [auto build test ERROR on wireless-drivers-next/master] [also build test ERROR on v4.14-rc3 next-20170929] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Himanshu-Jha/mwifiex-Use-put_unaligned_le32/20171007-095017 base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master config: xtensa-allyesconfig (attached as .config) compiler: xtensa-linux-gcc (GCC) 4.9.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=xtensa All errors (new ones prefixed by >>): In file included from arch/xtensa/include/asm/unaligned.h:22:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_struct.h:6:19: error: redefinition of >> 'get_unaligned_be16' static inline u16 get_unaligned_be16(const void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:22:28: note: previous definition of 'get_unaligned_be16' was here static __always_inline u16 get_unaligned_be16(const void *p) ^ In file included from arch/xtensa/include/asm/unaligned.h:22:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_struct.h:11:19: error: redefinition of >> 'get_unaligned_be32' static inline u32 get_unaligned_be32(const void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:27:28: note: previous definition of 'get_unaligned_be32' was here static __always_inline u32 get_unaligned_be32(const void *p) ^ In file included from arch/xtensa/include/asm/unaligned.h:22:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_struct.h:16:19: error: redefinition of >> 'get_unaligned_be64' static inline u64 get_unaligned_be64(const void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:32:28: note: previous definition of 'get_unaligned_be64' was here static __always_inline u64 get_unaligned_be64(const void *p) ^ In file included from arch/xtensa/include/asm/unaligned.h:22:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_struct.h:21:20: error: redefinition of >> 'put_unaligned_be16' static inline void put_unaligned_be16(u16 val, void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:52:29: note: previous definition of 'put_unaligned_be16' was here static __always_inline void put_unaligned_be16(u16 val, void *p) ^ In file included from arch/xtensa/include/asm/unaligned.h:22:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28, from drivers/net//wireless/marvell/mwifiex/cmdevt.c:21: >> include/linux/unaligned/be_struct.h:26:20: error: redefinition of >> 'put_unaligned_be32' static inline void put_unaligned_be32(u32 val, void *p) ^ In file included from drivers/net//wireless/marvell/mwifiex/cmdevt.c:20:0: include/linux/unaligned/access_ok.h:57:29: note: previous definition of 'put_unaligned_be32' was here static __always_inline void put_unaligned_be32(u32 val, void *p) ^ In file included from arch/xtensa/include/asm/unaligned.h:22:0, from include/linux/etherdevice.h:28, from include/linux/ieee80211.h:22, from drivers/net//wireless/marvell/mwifiex/decl.h:28,
Re: [PATCH tip/core/rcu 1/9] rcu: Provide GP ordering in face of migrations and delays
On Fri, Oct 06, 2017 at 10:15:37PM +0200, Peter Zijlstra wrote: > On Fri, Oct 06, 2017 at 12:18:22PM -0700, Paul E. McKenney wrote: > > > /me goes and install this herd thing again.. I'm sure I had it running > > > _somewhere_.. A well. > > > > > > C C-PaulEMcKenney-W+RWC4+2017-10-05 > > > > > > { > > > } > > > > > > P0(int *a, int *x) > > > { > > > WRITE_ONCE(*a, 1); > > > smp_mb(); /* Lock acquisition for rcu_node ->lock. */ > > > WRITE_ONCE(*x, 1); > > > } > > > > > > P1(int *x, int *y) > > > { > > > r3 = READ_ONCE(*x); > > > smp_mb(); /* Lock acquisition for rcu_node ->lock. */ > > > smp_store_release(y, 1); > > > } > > > > > > P2(int *y, int *b) > > > { > > > r4 = smp_load_acquire(y); > > > r1 = READ_ONCE(*b); > > > } > > > > > > P3(int *b, int *a) > > > { > > > WRITE_ONCE(*b, 1); > > > smp_mb(); > > > r2 = READ_ONCE(*a); > > > } > > > > > > exists (1:r3=1 /\ 2:r4=1 /\ 2:r1=0 /\ 3:r2=0) > > > > > > > > > Is what I was thinking of, I think that is the minimal ordering > > > complete()/wait_for_completion() need to provide. > > > > OK, I will bite... What do the smp_store_release() and the > > smp_load_acquire() correspond to? I see just plain locking in > > wait_for_completion() and complete(). > > They reflect the concept of complete() / wait_for_completion(). > Fundamentally all it needs to do is pass the message of 'completion'. > > That is, if we were to go optimize our completion implementation, it > would be impossible to be weaker than this and still correct. OK, though the model does not provide spinlocks, and there can be differences in behavior between spinlocks and release-acquire. But yes, in this case, it works. > > So I dropped that patch yesterday. The main thing I was missing was > > that there is no ordering-free fastpath in wait_for_completion() and > > complete(): Each unconditionally acquires the lock. So the smp_mb() > > that I was trying to add doesn't need to be there. > > Going by the above, it never needs to be there, even if there was a > lock-free fast-path. Given that wait_for_completion()/complete() both acquire the same lock, yes, and agreed, if it were lockless but provided the release and acquire ordering, then yes. But if it was instead structured like wait_event()/wake_up(), there would be ordering only if the caller supplied it. All that aside, paring the ordering down to the bare minimum is not always the right approach. Nevertheless, in this particular case, there is plenty of ordering, so yet again, I have dropped this commit. Like yesterday. ;-) Thanx, Paul
follow this information
hello,note that i am having problem with other e-mail. i therefore, recommend you to register free via below link to increase your finance, free money no charges click or copy link - http://woredrzydo.win/8071093818423/ please get back to me after registration.
Re: [BUG] GPF on reboot of box
This bug still crashes my box on rc3 -- Steve On October 6, 2017 10:21:26 PM EDT, Nadav Amit wrote: >Steven Rostedt wrote: > >> Starting with v4.14-rc1 my box crashes during a reboot. All I get is >> the following: >> >> [ 250.615793] sd 0:0:0:0: [sda] Synchronizing SCSI cache >> [ 250.635639] reboot: Restarting system >> [ 250.639671] reboot: machine restart >> [ 250.643842] general protection fault: [#1] PREEMPT SMP KASAN >> >> Then nothing. No reboot, it just hangs there. >> >> I bisected it down to this commit: >> >> 660da7c9228f ("x86/mm: Enable CR4.PCIDE on supported systems") >> >> If I comment out the setting of X86_CR4_PCIDE in that commit, it >boots >> fine. But... >> >> I noticed that commit c7ad5ad29 ("x86/mm/64: Initialize CR4.PCIDE >> early") moved the problem code from arch/x86/kernel/cpu/common.c to >> arch/x86/mm/init.c >> >> If I comment it out in v4.14-rc1, it crashes on boot up. >> >> It appears that my box doesn't like having X86_CR4_PCIDE set. it >causes >> reboot to fail. But it also appears that setting that is required for >> some other code to work. > >IIRC, there was a problem in rc1, which should be resolved in newer >rcs. >If you need to run rc1, you can try to use the kernel parameter >“nopcid". > >Nadav -- Sent from my Android device with K-9 Mail. Please excuse my brevity.
Re: [PATCH 4.9 086/104] arm64: kasan: avoid bad virt_to_pfn()
On Fri, Oct 06, 2017 at 07:13:22PM +0100, Mark Rutland wrote: >Hi Greg, > >On Fri, Oct 06, 2017 at 10:52:04AM +0200, Greg Kroah-Hartman wrote: >> 4.9-stable review patch. If anyone has any objections, please let me know. > >I'm a little confused as to why this is being backported, given it >wasn't Cc'd stable or marked as a fix. > >The lm_alias() helper was only introduced in v4.10, and I don't recall >seeing that backported. > >What's going on here? Mark, We are experimenting with using neural network to aid with patch selection for stable kernel trees. There are quite a few commits that were not marked for stable, but are stable material, and we're trying to get them into their appropriate kernel trees. -- Thanks, Sasha
Re: [PATCH v8 01/20] crypto: change transient busy return code to -EAGAIN
On Tue, Sep 05, 2017 at 03:38:40PM +0300, Gilad Ben-Yossef wrote: > > diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c > index 5e92bd2..3b3c154 100644 > --- a/crypto/algif_hash.c > +++ b/crypto/algif_hash.c > @@ -39,6 +39,20 @@ struct algif_hash_tfm { > bool has_key; > }; > > +/* Previous versions of crypto_* ops used to return -EBUSY > + * rather than -EAGAIN to indicate being tied up. The in > + * kernel API changed but we don't want to break the user > + * space API. As only the hash user interface exposed this > + * error ever to the user, do the translation here. > + */ > +static inline int crypto_user_err(int err) > +{ > + if (err == -EAGAIN) > + return -EBUSY; > + > + return err; I don't see the need to carry along this baggage. Does anyone in user-space actually rely on EBUSY? Cheers, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[PATCH v2 2/4] kmemcheck: stop using GFP_NOTRACK and SLAB_NOTRACK
Convert all allocations that used a NOTRACK flag to stop using it. Signed-off-by: Sasha Levin --- arch/arm/include/asm/pgalloc.h | 2 +- arch/arm64/include/asm/pgalloc.h | 2 +- arch/powerpc/include/asm/pgalloc.h | 2 +- arch/sh/kernel/dwarf.c | 4 ++-- arch/sh/kernel/process.c | 2 +- arch/sparc/mm/init_64.c | 4 ++-- arch/unicore32/include/asm/pgalloc.h | 2 +- arch/x86/kernel/espfix_64.c | 2 +- arch/x86/mm/init.c | 3 +-- arch/x86/mm/init_64.c| 2 +- arch/x86/mm/pageattr.c | 10 +- arch/x86/mm/pgtable.c| 2 +- arch/x86/platform/efi/efi_64.c | 2 +- crypto/xor.c | 7 +-- include/linux/thread_info.h | 5 ++--- init/do_mounts.c | 3 +-- kernel/fork.c| 12 ++-- kernel/signal.c | 3 +-- mm/kmemcheck.c | 2 +- mm/slab.c| 2 +- mm/slab.h| 5 ++--- mm/slab_common.c | 2 +- mm/slub.c| 4 +--- 23 files changed, 36 insertions(+), 48 deletions(-) diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h index b2902a5cd780..2d7344f0e208 100644 --- a/arch/arm/include/asm/pgalloc.h +++ b/arch/arm/include/asm/pgalloc.h @@ -57,7 +57,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) extern pgd_t *pgd_alloc(struct mm_struct *mm); extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); -#define PGALLOC_GFP(GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +#define PGALLOC_GFP(GFP_KERNEL | __GFP_ZERO) static inline void clean_pte_table(pte_t *pte) { diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h index d25f4f137c2a..5ca6a573a701 100644 --- a/arch/arm64/include/asm/pgalloc.h +++ b/arch/arm64/include/asm/pgalloc.h @@ -26,7 +26,7 @@ #define check_pgt_cache() do { } while (0) -#define PGALLOC_GFP(GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +#define PGALLOC_GFP(GFP_KERNEL | __GFP_ZERO) #define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t)) #if CONFIG_PGTABLE_LEVELS > 2 diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h index 45ae1212ab8a..bb01297b617a 100644 --- a/arch/powerpc/include/asm/pgalloc.h +++ b/arch/powerpc/include/asm/pgalloc.h @@ -17,7 +17,7 @@ static inline gfp_t pgtable_gfp_flags(struct mm_struct *mm, gfp_t gfp) } #endif /* MODULE */ -#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +#define PGALLOC_GFP (GFP_KERNEL | __GFP_ZERO) #ifdef CONFIG_PPC_BOOK3S #include diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index e1d751ae2498..1a2526676a87 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -1172,11 +1172,11 @@ static int __init dwarf_unwinder_init(void) dwarf_frame_cachep = kmem_cache_create("dwarf_frames", sizeof(struct dwarf_frame), 0, - SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL); + SLAB_PANIC | SLAB_HWCACHE_ALIGN, NULL); dwarf_reg_cachep = kmem_cache_create("dwarf_regs", sizeof(struct dwarf_reg), 0, - SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL); + SLAB_PANIC | SLAB_HWCACHE_ALIGN, NULL); dwarf_frame_pool = mempool_create_slab_pool(DWARF_FRAME_MIN_REQ, dwarf_frame_cachep); diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index f8a695a223dd..ded55e7461f8 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -58,7 +58,7 @@ void arch_task_cache_init(void) task_xstate_cachep = kmem_cache_create("task_xstate", xstate_size, __alignof__(union thread_xstate), - SLAB_PANIC | SLAB_NOTRACK, NULL); + SLAB_PANIC, NULL); } #ifdef CONFIG_SH_FPU_EMU diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index b2ba410b26f4..78f79004be2c 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -2926,7 +2926,7 @@ void __flush_tlb_all(void) pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); + struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO); pte_t *pte = NULL; if (page) @@ -2938,7 +2938,7 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) { - struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); + struct page *p
[PATCH v2 1/4] kmemcheck: remove annotations
Remove kmemcheck annotations, and calls to kmemcheck from the kernel. Signed-off-by: Sasha Levin --- arch/arm/include/asm/dma-iommu.h| 1 - arch/openrisc/include/asm/dma-mapping.h | 1 - arch/x86/Makefile | 5 - arch/x86/include/asm/dma-mapping.h | 1 - arch/x86/include/asm/xor.h | 5 + arch/x86/kernel/traps.c | 5 - arch/x86/mm/fault.c | 6 -- drivers/char/random.c | 1 - drivers/misc/c2port/core.c | 2 -- fs/dcache.c | 2 -- include/linux/c2port.h | 4 include/linux/dma-mapping.h | 4 include/linux/filter.h | 2 -- include/linux/mm_types.h| 8 include/linux/net.h | 3 --- include/linux/ring_buffer.h | 3 --- include/linux/skbuff.h | 3 --- include/net/inet_sock.h | 3 --- include/net/inet_timewait_sock.h| 4 include/net/sock.h | 3 --- init/main.c | 1 - kernel/bpf/core.c | 6 -- kernel/locking/lockdep.c| 3 --- kernel/trace/ring_buffer.c | 3 --- mm/kmemleak.c | 9 - mm/page_alloc.c | 14 -- mm/slab.c | 14 -- mm/slab.h | 2 -- mm/slub.c | 20 net/core/skbuff.c | 5 - net/core/sock.c | 2 -- net/ipv4/inet_timewait_sock.c | 3 --- net/ipv4/tcp_input.c| 1 - net/socket.c| 1 - 34 files changed, 1 insertion(+), 149 deletions(-) diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h index c090ec675eac..5ad676f2de22 100644 --- a/arch/arm/include/asm/dma-iommu.h +++ b/arch/arm/include/asm/dma-iommu.h @@ -6,7 +6,6 @@ #include #include #include -#include #include #define ARM_MAPPING_ERROR (~(dma_addr_t)0x0) diff --git a/arch/openrisc/include/asm/dma-mapping.h b/arch/openrisc/include/asm/dma-mapping.h index f41bd3cb76d9..e212a1f0b6d2 100644 --- a/arch/openrisc/include/asm/dma-mapping.h +++ b/arch/openrisc/include/asm/dma-mapping.h @@ -23,7 +23,6 @@ */ #include -#include #include extern const struct dma_map_ops or1k_dma_map_ops; diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 6276572259c8..559eb0a282fd 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -157,11 +157,6 @@ ifdef CONFIG_X86_X32 endif export CONFIG_X86_X32_ABI -# Don't unroll struct assignments with kmemcheck enabled -ifeq ($(CONFIG_KMEMCHECK),y) - KBUILD_CFLAGS += $(call cc-option,-fno-builtin-memcpy) -endif - # # If the function graph tracer is used with mcount instead of fentry, # '-maccumulate-outgoing-args' is needed to prevent a GCC bug diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index 1387dafdba2d..bd974c04c9aa 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -6,7 +6,6 @@ * Documentation/DMA-API.txt for documentation. */ -#include #include #include #include diff --git a/arch/x86/include/asm/xor.h b/arch/x86/include/asm/xor.h index 1f5c5161ead6..45c8605467f1 100644 --- a/arch/x86/include/asm/xor.h +++ b/arch/x86/include/asm/xor.h @@ -1,7 +1,4 @@ -#ifdef CONFIG_KMEMCHECK -/* kmemcheck doesn't handle MMX/SSE/SSE2 instructions */ -# include -#elif !defined(_ASM_X86_XOR_H) +#ifndef _ASM_X86_XOR_H #define _ASM_X86_XOR_H /* diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 67db4f43309e..969bb67e06f4 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -42,7 +42,6 @@ #include #endif -#include #include #include #include @@ -740,10 +739,6 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) if (!dr6 && user_mode(regs)) user_icebp = 1; - /* Catch kmemcheck conditions! */ - if ((dr6 & DR_STEP) && kmemcheck_trap(regs)) - goto exit; - /* Store the virtualized DR6 value */ tsk->thread.debugreg6 = dr6; diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index e2baeaa053a5..a4f96448bc7a 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -19,7 +19,6 @@ #include /* boot_cpu_has, ...*/ #include /* dotraplinkage, ... */ #include/* pgd_*(), ... */ -#include /* kmemcheck_*(), ... */ #include /* VSYSCALL_ADDR */ #include /* emulate_vsyscall */ #include /* struct vm86 */ @@ -12
[PATCH v2 3/4] kmemcheck: rip it out
Fix up makefiles, remove references, and git rm kmemcheck. Signed-off-by: Sasha Levin --- Documentation/admin-guide/kernel-parameters.txt | 7 - Documentation/dev-tools/index.rst | 1 - Documentation/dev-tools/kmemcheck.rst | 733 MAINTAINERS | 10 - arch/x86/Kconfig| 3 +- arch/x86/include/asm/kmemcheck.h| 42 -- arch/x86/include/asm/string_32.h| 9 - arch/x86/include/asm/string_64.h| 8 - arch/x86/kernel/cpu/intel.c | 15 - arch/x86/mm/Makefile| 2 - arch/x86/mm/init.c | 5 +- arch/x86/mm/kmemcheck/Makefile | 1 - arch/x86/mm/kmemcheck/error.c | 227 arch/x86/mm/kmemcheck/error.h | 15 - arch/x86/mm/kmemcheck/kmemcheck.c | 658 - arch/x86/mm/kmemcheck/opcode.c | 106 arch/x86/mm/kmemcheck/opcode.h | 9 - arch/x86/mm/kmemcheck/pte.c | 22 - arch/x86/mm/kmemcheck/pte.h | 10 - arch/x86/mm/kmemcheck/selftest.c| 70 --- arch/x86/mm/kmemcheck/selftest.h| 6 - arch/x86/mm/kmemcheck/shadow.c | 173 -- arch/x86/mm/kmemcheck/shadow.h | 18 - include/linux/interrupt.h | 15 - include/linux/kmemcheck.h | 171 -- kernel/softirq.c| 10 - kernel/sysctl.c | 10 - lib/Kconfig.debug | 6 +- lib/Kconfig.kmemcheck | 94 --- mm/Kconfig.debug| 1 - mm/Makefile | 2 - mm/kmemcheck.c | 125 mm/slub.c | 5 +- scripts/kernel-doc | 2 - tools/include/linux/kmemcheck.h | 8 - 35 files changed, 7 insertions(+), 2592 deletions(-) delete mode 100644 Documentation/dev-tools/kmemcheck.rst delete mode 100644 arch/x86/include/asm/kmemcheck.h delete mode 100644 arch/x86/mm/kmemcheck/Makefile delete mode 100644 arch/x86/mm/kmemcheck/error.c delete mode 100644 arch/x86/mm/kmemcheck/error.h delete mode 100644 arch/x86/mm/kmemcheck/kmemcheck.c delete mode 100644 arch/x86/mm/kmemcheck/opcode.c delete mode 100644 arch/x86/mm/kmemcheck/opcode.h delete mode 100644 arch/x86/mm/kmemcheck/pte.c delete mode 100644 arch/x86/mm/kmemcheck/pte.h delete mode 100644 arch/x86/mm/kmemcheck/selftest.c delete mode 100644 arch/x86/mm/kmemcheck/selftest.h delete mode 100644 arch/x86/mm/kmemcheck/shadow.c delete mode 100644 arch/x86/mm/kmemcheck/shadow.h delete mode 100644 include/linux/kmemcheck.h delete mode 100644 lib/Kconfig.kmemcheck delete mode 100644 mm/kmemcheck.c delete mode 100644 tools/include/linux/kmemcheck.h diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 05496622b4ef..5e1e0e7ebee3 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1841,13 +1841,6 @@ Built with CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y, the default is off. - kmemcheck= [X86] Boot-time kmemcheck enable/disable/one-shot mode - Valid arguments: 0, 1, 2 - kmemcheck=0 (disabled) - kmemcheck=1 (enabled) - kmemcheck=2 (one-shot mode) - Default: 2 (one-shot mode) - kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs. Default is 0 (don't ignore, but inject #GP) diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/index.rst index a81787cd47d7..e313925fb0fa 100644 --- a/Documentation/dev-tools/index.rst +++ b/Documentation/dev-tools/index.rst @@ -21,7 +21,6 @@ whole; patches welcome! kasan ubsan kmemleak - kmemcheck gdb-kernel-debugging kgdb kselftest diff --git a/Documentation/dev-tools/kmemcheck.rst b/Documentation/dev-tools/kmemcheck.rst deleted file mode 100644 index 7f3d1985de74.. --- a/Documentation/dev-tools/kmemcheck.rst +++ /dev/null @@ -1,733 +0,0 @@ -Getting started with kmemcheck -== - -Vegard Nossum - - -Introduction - - -kmemcheck is a debugging feature for the Linux Kernel. More specifically, it -is a dynamic checker that detects and warns about some uses of uninitialized -memory. - -Userspace programmers might be familiar with Valgrind's memcheck. The main -difference between memcheck and kmemcheck is that memcheck works for userspace -programs o
[PATCH v2 4/4] kmemcheck: remove whats left of NOTRACK flags
Now that kmemcheck is gone, we don't need the NOTRACK flags. Signed-off-by: Sasha Levin --- arch/x86/include/asm/pgtable.h | 5 - arch/x86/include/asm/pgtable_types.h | 13 - include/linux/gfp.h | 9 - include/linux/slab.h | 6 -- include/trace/events/mmflags.h | 1 - mm/slub.c| 2 -- tools/perf/builtin-kmem.c| 1 - 7 files changed, 37 deletions(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index b714934512b3..d110e38893d1 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -666,11 +666,6 @@ static inline bool pte_accessible(struct mm_struct *mm, pte_t a) return false; } -static inline int pte_hidden(pte_t pte) -{ - return pte_flags(pte) & _PAGE_HIDDEN; -} - static inline int pmd_present(pmd_t pmd) { /* diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index f1492473f10e..27e230dec7a4 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -31,7 +31,6 @@ #define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1 #define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1 -#define _PAGE_BIT_HIDDEN _PAGE_BIT_SOFTW3 /* hidden by kmemcheck */ #define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */ #define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4 @@ -78,18 +77,6 @@ #define _PAGE_KNL_ERRATUM_MASK 0 #endif -#ifdef CONFIG_KMEMCHECK -#define _PAGE_HIDDEN (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN) -#else -#define _PAGE_HIDDEN (_AT(pteval_t, 0)) -#endif - -/* - * The same hidden bit is used by kmemcheck, but since kmemcheck - * works on kernel pages while soft-dirty engine on user space, - * they do not conflict with each other. - */ - #ifdef CONFIG_MEM_SOFT_DIRTY #define _PAGE_SOFT_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_SOFT_DIRTY) #else diff --git a/include/linux/gfp.h b/include/linux/gfp.h index f780718b7391..3427fb8d936a 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -36,7 +36,6 @@ struct vm_area_struct; #define ___GFP_THISNODE0x4u #define ___GFP_ATOMIC 0x8u #define ___GFP_ACCOUNT 0x10u -#define ___GFP_NOTRACK 0x20u #define ___GFP_DIRECT_RECLAIM 0x40u #define ___GFP_WRITE 0x80u #define ___GFP_KSWAPD_RECLAIM 0x100u @@ -200,19 +199,11 @@ struct vm_area_struct; * __GFP_COMP address compound page metadata. * * __GFP_ZERO returns a zeroed page on success. - * - * __GFP_NOTRACK avoids tracking with kmemcheck. - * - * __GFP_NOTRACK_FALSE_POSITIVE is an alias of __GFP_NOTRACK. It's a means of - * distinguishing in the source between false positives and allocations that - * cannot be supported (e.g. page tables). */ #define __GFP_COLD ((__force gfp_t)___GFP_COLD) #define __GFP_NOWARN ((__force gfp_t)___GFP_NOWARN) #define __GFP_COMP ((__force gfp_t)___GFP_COMP) #define __GFP_ZERO ((__force gfp_t)___GFP_ZERO) -#define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK) -#define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK) /* Disable lockdep for GFP context tracking */ #define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP) diff --git a/include/linux/slab.h b/include/linux/slab.h index 41473df6dfb0..f35c640687a0 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -77,12 +77,6 @@ #define SLAB_NOLEAKTRACE 0x0080UL/* Avoid kmemleak tracing */ -/* Don't track use of uninitialized memory */ -#ifdef CONFIG_KMEMCHECK -# define SLAB_NOTRACK 0x0100UL -#else -# define SLAB_NOTRACK 0xUL -#endif #ifdef CONFIG_FAILSLAB # define SLAB_FAILSLAB 0x0200UL/* Fault injection mark */ #else diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h index fec6291a6703..937d5d54d1b9 100644 --- a/include/trace/events/mmflags.h +++ b/include/trace/events/mmflags.h @@ -45,7 +45,6 @@ {(unsigned long)__GFP_RECLAIMABLE, "__GFP_RECLAIMABLE"}, \ {(unsigned long)__GFP_MOVABLE, "__GFP_MOVABLE"}, \ {(unsigned long)__GFP_ACCOUNT, "__GFP_ACCOUNT"}, \ - {(unsigned long)__GFP_NOTRACK, "__GFP_NOTRACK"}, \ {(unsigned long)__GFP_WRITE,"__GFP_WRITE"}, \ {(unsigned long)__GFP_RECLAIM, "__GFP_RECLAIM"}, \ {(unsigned long)__GFP_DIRECT_RECLAIM, "__GFP_DIRECT_RECLAIM"},\ diff --git a/mm/slub.c b/mm/slub.c index a3ccf106fc0b..ea182bbd52b6 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -5631,8 +5631,6 @@ static char *create_unique_id(struct kmem_cache *s) *p++ = 'a'; if (s->flags & SLAB_CONSISTENCY_CHECKS) *p++ = 'F'; - if (!(s->flags & SLAB_NOTRACK)) - *p++ = 't'; if (s->flags & SLAB_ACCOUNT) *p++ = 'A'; i
[PATCH v2 0/4] kmemcheck: kill kmemcheck
2 Years ago I proposed to kill kmemcheck: > As discussed on LSF/MM, kill kmemcheck. > > KASan is a replacement that is able to work without the limitation of > kmemcheck (single CPU, slow). KASan is already upstream. > > We are also not aware of any users of kmemcheck (or users who don't consider > KASan as a suitable replacement). The only objection was that since KASAN wasn't supported by all GCC versions provided by distros at that time we should hold off for 2 years, and try again. Now that 2 years have passed, and all distros provide gcc that supports KASAN, kill kmemcheck again for the very same reasons. Changes for v2: - Break patch out. Sasha Levin (4): kmemcheck: remove annotations kmemcheck: stop using GFP_NOTRACK and SLAB_NOTRACK kmemcheck: rip it out kmemcheck: remove whats left of NOTRACK flags Documentation/admin-guide/kernel-parameters.txt | 7 - Documentation/dev-tools/index.rst | 1 - Documentation/dev-tools/kmemcheck.rst | 733 MAINTAINERS | 10 - arch/arm/include/asm/dma-iommu.h| 1 - arch/arm/include/asm/pgalloc.h | 2 +- arch/arm64/include/asm/pgalloc.h| 2 +- arch/openrisc/include/asm/dma-mapping.h | 1 - arch/powerpc/include/asm/pgalloc.h | 2 +- arch/sh/kernel/dwarf.c | 4 +- arch/sh/kernel/process.c| 2 +- arch/sparc/mm/init_64.c | 4 +- arch/unicore32/include/asm/pgalloc.h| 2 +- arch/x86/Kconfig| 3 +- arch/x86/Makefile | 5 - arch/x86/include/asm/dma-mapping.h | 1 - arch/x86/include/asm/kmemcheck.h| 42 -- arch/x86/include/asm/pgtable.h | 5 - arch/x86/include/asm/pgtable_types.h| 13 - arch/x86/include/asm/string_32.h| 9 - arch/x86/include/asm/string_64.h| 8 - arch/x86/include/asm/xor.h | 5 +- arch/x86/kernel/cpu/intel.c | 15 - arch/x86/kernel/espfix_64.c | 2 +- arch/x86/kernel/traps.c | 5 - arch/x86/mm/Makefile| 2 - arch/x86/mm/fault.c | 6 - arch/x86/mm/init.c | 8 +- arch/x86/mm/init_64.c | 2 +- arch/x86/mm/kmemcheck/Makefile | 1 - arch/x86/mm/kmemcheck/error.c | 227 arch/x86/mm/kmemcheck/error.h | 15 - arch/x86/mm/kmemcheck/kmemcheck.c | 658 - arch/x86/mm/kmemcheck/opcode.c | 106 arch/x86/mm/kmemcheck/opcode.h | 9 - arch/x86/mm/kmemcheck/pte.c | 22 - arch/x86/mm/kmemcheck/pte.h | 10 - arch/x86/mm/kmemcheck/selftest.c| 70 --- arch/x86/mm/kmemcheck/selftest.h| 6 - arch/x86/mm/kmemcheck/shadow.c | 173 -- arch/x86/mm/kmemcheck/shadow.h | 18 - arch/x86/mm/pageattr.c | 10 +- arch/x86/mm/pgtable.c | 2 +- arch/x86/platform/efi/efi_64.c | 2 +- crypto/xor.c| 7 +- drivers/char/random.c | 1 - drivers/misc/c2port/core.c | 2 - fs/dcache.c | 2 - include/linux/c2port.h | 4 - include/linux/dma-mapping.h | 4 - include/linux/filter.h | 2 - include/linux/gfp.h | 9 - include/linux/interrupt.h | 15 - include/linux/kmemcheck.h | 171 -- include/linux/mm_types.h| 8 - include/linux/net.h | 3 - include/linux/ring_buffer.h | 3 - include/linux/skbuff.h | 3 - include/linux/slab.h| 6 - include/linux/thread_info.h | 5 +- include/net/inet_sock.h | 3 - include/net/inet_timewait_sock.h| 4 - include/net/sock.h | 3 - include/trace/events/mmflags.h | 1 - init/do_mounts.c| 3 +- init/main.c | 1 - kernel/bpf/core.c | 6 - kernel/fork.c | 12 +- kernel/locking/lockdep.c| 3 - kernel/signal.c | 3 +- kernel/softirq.c| 10 - kernel/sysctl.c
Re: [PATCH] Userfaultfd: Add description for UFFD_FEATURE_SIGBUS
cc: Andrea Arcangeli On 10/6/17 7:52 PM, Prakash Sangappa wrote: Userfaultfd feature UFFD_FEATURE_SIGBUS was merged recently and should be available in Linux 4.14 release. This patch is for the manpage changes documenting this API. Documents the following commit: commit 2d6d6f5a09a96cc1fec7ed992b825e05f64cb50e Author: Prakash Sangappa Date: Wed Sep 6 16:23:39 2017 -0700 mm: userfaultfd: add feature to request for a signal delivery Signed-off-by: Prakash Sangappa --- man2/ioctl_userfaultfd.2 | 9 + man2/userfaultfd.2 | 17 + 2 files changed, 26 insertions(+) diff --git a/man2/ioctl_userfaultfd.2 b/man2/ioctl_userfaultfd.2 index 60fd29b..cfc65ae 100644 --- a/man2/ioctl_userfaultfd.2 +++ b/man2/ioctl_userfaultfd.2 @@ -196,6 +196,15 @@ with the flag set, .BR memfd_create (2), and so on. +.TP +.B UFFD_FEATURE_SIGBUS +Since Linux 4.14, If this feature bit is set, no page-fault events( +.B UFFD_EVENT_PAGEFAULT +) will be delivered, instead a +.B SIGBUS +signal will be sent to the faulting process. Applications using this +feature will not require the use of a userfaultfd monitor for handling +page-fault events. .IP The returned .I ioctls diff --git a/man2/userfaultfd.2 b/man2/userfaultfd.2 index 1741ee3..a033742 100644 --- a/man2/userfaultfd.2 +++ b/man2/userfaultfd.2 @@ -172,6 +172,23 @@ or .BR ioctl (2) operations to resolve the page fault. .PP +Starting from Linux 4.14, if application sets +.B UFFD_FEATURE_SIGBUS +feature bit using +.B UFFDIO_API +.BR ioctl (2) +, no page fault notification will be forwarded to +the user-space, instead a +.B SIGBUS +signal is delivered to the faulting process. With this feature, +userfaultfd can be used for robustness purpose to simply catch +any access to areas within the registered address range that do not +have pages allocated, without having to deal with page-fault events. +No userfaultd monitor will be required for handling page faults. For +example, this feature can be useful for applications that want to +prevent the kernel from automatically allocating pages and filling +holes in sparse files when the hole is accessed thru mapped address. +.PP Details of the various .BR ioctl (2) operations can be found in
[PATCH] Userfaultfd: Add description for UFFD_FEATURE_SIGBUS
Userfaultfd feature UFFD_FEATURE_SIGBUS was merged recently and should be available in Linux 4.14 release. This patch is for the manpage changes documenting this API. Documents the following commit: commit 2d6d6f5a09a96cc1fec7ed992b825e05f64cb50e Author: Prakash Sangappa Date: Wed Sep 6 16:23:39 2017 -0700 mm: userfaultfd: add feature to request for a signal delivery Signed-off-by: Prakash Sangappa --- man2/ioctl_userfaultfd.2 | 9 + man2/userfaultfd.2 | 17 + 2 files changed, 26 insertions(+) diff --git a/man2/ioctl_userfaultfd.2 b/man2/ioctl_userfaultfd.2 index 60fd29b..cfc65ae 100644 --- a/man2/ioctl_userfaultfd.2 +++ b/man2/ioctl_userfaultfd.2 @@ -196,6 +196,15 @@ with the flag set, .BR memfd_create (2), and so on. +.TP +.B UFFD_FEATURE_SIGBUS +Since Linux 4.14, If this feature bit is set, no page-fault events( +.B UFFD_EVENT_PAGEFAULT +) will be delivered, instead a +.B SIGBUS +signal will be sent to the faulting process. Applications using this +feature will not require the use of a userfaultfd monitor for handling +page-fault events. .IP The returned .I ioctls diff --git a/man2/userfaultfd.2 b/man2/userfaultfd.2 index 1741ee3..a033742 100644 --- a/man2/userfaultfd.2 +++ b/man2/userfaultfd.2 @@ -172,6 +172,23 @@ or .BR ioctl (2) operations to resolve the page fault. .PP +Starting from Linux 4.14, if application sets +.B UFFD_FEATURE_SIGBUS +feature bit using +.B UFFDIO_API +.BR ioctl (2) +, no page fault notification will be forwarded to +the user-space, instead a +.B SIGBUS +signal is delivered to the faulting process. With this feature, +userfaultfd can be used for robustness purpose to simply catch +any access to areas within the registered address range that do not +have pages allocated, without having to deal with page-fault events. +No userfaultd monitor will be required for handling page faults. For +example, this feature can be useful for applications that want to +prevent the kernel from automatically allocating pages and filling +holes in sparse files when the hole is accessed thru mapped address. +.PP Details of the various .BR ioctl (2) operations can be found in -- 2.7.4
Re: [PATCH 1/2] Revert "vmalloc: back off when the current task is killed"
On Sat, Oct 07, 2017 at 11:21:26AM +0900, Tetsuo Handa wrote: > On 2017/10/05 19:36, Tetsuo Handa wrote: > > I don't want this patch backported. If you want to backport, > > "s/fatal_signal_pending/tsk_is_oom_victim/" is the safer way. > > If you backport this patch, you will see "complete depletion of memory > reserves" > and "extra OOM kills due to depletion of memory reserves" using below > reproducer. > > -- > #include > #include > #include > > static char *buffer; > > static int __init test_init(void) > { > set_current_oom_origin(); > buffer = vmalloc((1UL << 32) - 480 * 1048576); That's not a reproducer, that's a kernel module. It's not hard to crash the kernel from within the kernel.
[RFC v4 5/8] platform/x86: intel_punit_ipc: Fix resource ioremap warning
From: Kuppuswamy Sathyanarayanan For PUNIT device, ISPDRIVER_IPC and GTDDRIVER_IPC resources are not mandatory. So when PMC IPC driver creates a PUNIT device, if these resources are not available then it creates dummy resource entries for these missing resources. But during PUNIT device probe , doing ioremap on these dummy resources generates following warning messages. intel_punit_ipc intel_punit_ipc: can't request region for resource [mem 0x] intel_punit_ipc intel_punit_ipc: can't request region for resource [mem 0x] intel_punit_ipc intel_punit_ipc: can't request region for resource [mem 0x] intel_punit_ipc intel_punit_ipc: can't request region for resource [mem 0x] This patch fixes this issue by adding extra check for resource size before performing ioremap operation. Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/platform/x86/intel_punit_ipc.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c index a47a41f..b5b8901 100644 --- a/drivers/platform/x86/intel_punit_ipc.c +++ b/drivers/platform/x86/intel_punit_ipc.c @@ -252,28 +252,28 @@ static int intel_punit_get_bars(struct platform_device *pdev) * - GTDRIVER_IPC BASE_IFACE */ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); - if (res) { + if (res && resource_size(res) > 1) { addr = devm_ioremap_resource(&pdev->dev, res); if (!IS_ERR(addr)) punit_ipcdev->base[ISPDRIVER_IPC][BASE_DATA] = addr; } res = platform_get_resource(pdev, IORESOURCE_MEM, 3); - if (res) { + if (res && resource_size(res) > 1) { addr = devm_ioremap_resource(&pdev->dev, res); if (!IS_ERR(addr)) punit_ipcdev->base[ISPDRIVER_IPC][BASE_IFACE] = addr; } res = platform_get_resource(pdev, IORESOURCE_MEM, 4); - if (res) { + if (res && resource_size(res) > 1) { addr = devm_ioremap_resource(&pdev->dev, res); if (!IS_ERR(addr)) punit_ipcdev->base[GTDRIVER_IPC][BASE_DATA] = addr; } res = platform_get_resource(pdev, IORESOURCE_MEM, 5); - if (res) { + if (res && resource_size(res) > 1) { addr = devm_ioremap_resource(&pdev->dev, res); if (!IS_ERR(addr)) punit_ipcdev->base[GTDRIVER_IPC][BASE_IFACE] = addr; -- 2.7.4
[RFC v4 7/8] platform/x86: intel_pmc_ipc: Use generic Intel IPC device calls
From: Kuppuswamy Sathyanarayanan Removed redundant IPC helper functions and refactored the driver to use generic IPC device driver APIs. Also, cleaned up the driver to minimize the usage of global variable ipcdev by propogating the struct intel_pmc_ipc_dev pointer or by getting it from device private data. This patch also cleans-up PMC IPC user drivers(intel_telemetry_pltdrv.c, intel_soc_pmic_bxtwc.c) to use APIs provided by generic IPC driver. Signed-off-by: Kuppuswamy Sathyanarayanan --- arch/x86/include/asm/intel_pmc_ipc.h | 37 +-- drivers/mfd/intel_soc_pmic_bxtwc.c| 21 +- drivers/platform/x86/intel_pmc_ipc.c | 393 ++ drivers/platform/x86/intel_telemetry_pltdrv.c | 119 include/linux/mfd/intel_soc_pmic.h| 2 + 5 files changed, 238 insertions(+), 334 deletions(-) Changes since v3: * Added unique name to PMC regmaps. * Added support to clear interrupt bit. * Added intel_ipc_dev_put() support. Changes since v1: * Removed custom APIs. * Cleaned up PMC IPC user drivers to use APIs provided by generic IPC driver. diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h index fac89eb..9fc7c3c 100644 --- a/arch/x86/include/asm/intel_pmc_ipc.h +++ b/arch/x86/include/asm/intel_pmc_ipc.h @@ -1,10 +1,15 @@ #ifndef _ASM_X86_INTEL_PMC_IPC_H_ #define _ASM_X86_INTEL_PMC_IPC_H_ +#include + +#define INTEL_PMC_IPC_DEV "intel_pmc_ipc" +#define PMC_PARAM_LEN 2 + /* Commands */ #define PMC_IPC_PMIC_ACCESS0xFF -#definePMC_IPC_PMIC_ACCESS_READ0x0 -#definePMC_IPC_PMIC_ACCESS_WRITE 0x1 +#definePMC_IPC_PMIC_ACCESS_READ0x0 +#definePMC_IPC_PMIC_ACCESS_WRITE 0x1 #define PMC_IPC_USB_PWR_CTRL 0xF0 #define PMC_IPC_PMIC_BLACKLIST_SEL 0xEF #define PMC_IPC_PHY_CONFIG 0xEE @@ -28,13 +33,14 @@ #define PMC_GCR_TELEM_DEEP_S0IX_REG0x78 #define PMC_GCR_TELEM_SHLW_S0IX_REG0x80 +static inline void pmc_cmd_init(u32 *cmd, u32 param1, u32 param2) +{ + cmd[0] = param1; + cmd[1] = param2; +} + #if IS_ENABLED(CONFIG_INTEL_PMC_IPC) -int intel_pmc_ipc_simple_command(int cmd, int sub); -int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, - u32 *out, u32 outlen, u32 dptr, u32 sptr); -int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, - u32 *out, u32 outlen); int intel_pmc_s0ix_counter_read(u64 *data); int intel_pmc_gcr_read(u32 offset, u32 *data); int intel_pmc_gcr_write(u32 offset, u32 data); @@ -42,23 +48,6 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val); #else -static inline int intel_pmc_ipc_simple_command(int cmd, int sub) -{ - return -EINVAL; -} - -static inline int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, - u32 *out, u32 outlen, u32 dptr, u32 sptr) -{ - return -EINVAL; -} - -static inline int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, - u32 *out, u32 outlen) -{ - return -EINVAL; -} - static inline int intel_pmc_s0ix_counter_read(u64 *data) { return -EINVAL; diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c index 15bc052..f9df9e7 100644 --- a/drivers/mfd/intel_soc_pmic_bxtwc.c +++ b/drivers/mfd/intel_soc_pmic_bxtwc.c @@ -271,6 +271,8 @@ static int regmap_ipc_byte_reg_read(void *context, unsigned int reg, u8 ipc_in[2]; u8 ipc_out[4]; struct intel_soc_pmic *pmic = context; + u32 cmd[PMC_PARAM_LEN] = {PMC_IPC_PMIC_ACCESS, + PMC_IPC_PMIC_ACCESS_READ}; if (!pmic) return -EINVAL; @@ -284,9 +286,8 @@ static int regmap_ipc_byte_reg_read(void *context, unsigned int reg, ipc_in[0] = reg; ipc_in[1] = i2c_addr; - ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS, - PMC_IPC_PMIC_ACCESS_READ, - ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1); + ret = ipc_dev_raw_cmd(pmic->ipc_dev, cmd, PMC_PARAM_LEN, ipc_in, + sizeof(ipc_in), (u32 *)ipc_out, 1, 0, 0); if (ret) { dev_err(pmic->dev, "Failed to read from PMIC\n"); return ret; @@ -303,6 +304,8 @@ static int regmap_ipc_byte_reg_write(void *context, unsigned int reg, int i2c_addr; u8 ipc_in[3]; struct intel_soc_pmic *pmic = context; + u32 cmd[PMC_PARAM_LEN] = {PMC_IPC_PMIC_ACCESS, + PMC_IPC_PMIC_ACCESS_WRITE}; if (!pmic) return -EINVAL; @@ -317,9 +320,8 @@ static int regmap_ipc_byte_reg_write(void *context, unsigned int reg, ipc_in[0] = reg; ipc_in[1] = i2c_addr; ipc_in[2] = val; - ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS, - PMC_IPC_PMIC_ACCESS_WRITE, - ipc_in, sizeof(ipc
[RFC v4 6/8] platform/x86: intel_punit_ipc: Use generic intel ipc device calls
From: Kuppuswamy Sathyanarayanan Removed redundant IPC helper functions and refactored the driver to use APIs provided by generic IPC driver. This patch also cleans-up PUNIT IPC user drivers(intel_telemetry_pltdrv.c) to use APIs provided by generic IPC driver. Signed-off-by: Kuppuswamy Sathyanarayanan --- arch/x86/include/asm/intel_punit_ipc.h| 125 +-- drivers/platform/x86/Kconfig | 1 + drivers/platform/x86/intel_punit_ipc.c| 303 ++ drivers/platform/x86/intel_telemetry_pltdrv.c | 97 + 4 files changed, 223 insertions(+), 303 deletions(-) Changes since v2: * Added unique name to PUNIT BIOS, GTD, & ISP regmaps. * Added intel_ipc_dev_put() support. Changes since v1: * Removed custom APIs. * Cleaned up PUNIT IPC user drivers to use APIs provided by generic IPC driver. diff --git a/arch/x86/include/asm/intel_punit_ipc.h b/arch/x86/include/asm/intel_punit_ipc.h index 201eb9d..cf1630c 100644 --- a/arch/x86/include/asm/intel_punit_ipc.h +++ b/arch/x86/include/asm/intel_punit_ipc.h @@ -1,10 +1,8 @@ #ifndef _ASM_X86_INTEL_PUNIT_IPC_H_ #define _ASM_X86_INTEL_PUNIT_IPC_H_ -/* - * Three types of 8bit P-Unit IPC commands are supported, - * bit[7:6]: [00]: BIOS; [01]: GTD; [10]: ISPD. - */ +#include + typedef enum { BIOS_IPC = 0, GTDRIVER_IPC, @@ -12,61 +10,60 @@ typedef enum { RESERVED_IPC, } IPC_TYPE; -#define IPC_TYPE_OFFSET6 -#define IPC_PUNIT_BIOS_CMD_BASE(BIOS_IPC << IPC_TYPE_OFFSET) -#define IPC_PUNIT_GTD_CMD_BASE (GTDDRIVER_IPC << IPC_TYPE_OFFSET) -#define IPC_PUNIT_ISPD_CMD_BASE(ISPDRIVER_IPC << IPC_TYPE_OFFSET) -#define IPC_PUNIT_CMD_TYPE_MASK(RESERVED_IPC << IPC_TYPE_OFFSET) +#define PUNIT_BIOS_IPC_DEV "punit_bios_ipc" +#define PUNIT_GTD_IPC_DEV "punit_gtd_ipc" +#define PUNIT_ISP_IPC_DEV "punit_isp_ipc" +#define PUNIT_PARAM_LEN3 /* BIOS => Pcode commands */ -#define IPC_PUNIT_BIOS_ZERO(IPC_PUNIT_BIOS_CMD_BASE | 0x00) -#define IPC_PUNIT_BIOS_VR_INTERFACE(IPC_PUNIT_BIOS_CMD_BASE | 0x01) -#define IPC_PUNIT_BIOS_READ_PCS (IPC_PUNIT_BIOS_CMD_BASE | 0x02) -#define IPC_PUNIT_BIOS_WRITE_PCS (IPC_PUNIT_BIOS_CMD_BASE | 0x03) -#define IPC_PUNIT_BIOS_READ_PCU_CONFIG (IPC_PUNIT_BIOS_CMD_BASE | 0x04) -#define IPC_PUNIT_BIOS_WRITE_PCU_CONFIG (IPC_PUNIT_BIOS_CMD_BASE | 0x05) -#define IPC_PUNIT_BIOS_READ_PL1_SETTING (IPC_PUNIT_BIOS_CMD_BASE | 0x06) -#define IPC_PUNIT_BIOS_WRITE_PL1_SETTING (IPC_PUNIT_BIOS_CMD_BASE | 0x07) -#define IPC_PUNIT_BIOS_TRIGGER_VDD_RAM (IPC_PUNIT_BIOS_CMD_BASE | 0x08) -#define IPC_PUNIT_BIOS_READ_TELE_INFO (IPC_PUNIT_BIOS_CMD_BASE | 0x09) -#define IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL(IPC_PUNIT_BIOS_CMD_BASE | 0x0a) -#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x0b) -#define IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL(IPC_PUNIT_BIOS_CMD_BASE | 0x0c) -#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x0d) -#define IPC_PUNIT_BIOS_READ_TELE_TRACE (IPC_PUNIT_BIOS_CMD_BASE | 0x0e) -#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE (IPC_PUNIT_BIOS_CMD_BASE | 0x0f) -#define IPC_PUNIT_BIOS_READ_TELE_EVENT (IPC_PUNIT_BIOS_CMD_BASE | 0x10) -#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT (IPC_PUNIT_BIOS_CMD_BASE | 0x11) -#define IPC_PUNIT_BIOS_READ_MODULE_TEMP (IPC_PUNIT_BIOS_CMD_BASE | 0x12) -#define IPC_PUNIT_BIOS_RESERVED (IPC_PUNIT_BIOS_CMD_BASE | 0x13) -#define IPC_PUNIT_BIOS_READ_VOLTAGE_OVER (IPC_PUNIT_BIOS_CMD_BASE | 0x14) -#define IPC_PUNIT_BIOS_WRITE_VOLTAGE_OVER (IPC_PUNIT_BIOS_CMD_BASE | 0x15) -#define IPC_PUNIT_BIOS_READ_RATIO_OVER (IPC_PUNIT_BIOS_CMD_BASE | 0x16) -#define IPC_PUNIT_BIOS_WRITE_RATIO_OVER (IPC_PUNIT_BIOS_CMD_BASE | 0x17) -#define IPC_PUNIT_BIOS_READ_VF_GL_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x18) -#define IPC_PUNIT_BIOS_WRITE_VF_GL_CTRL (IPC_PUNIT_BIOS_CMD_BASE | 0x19) -#define IPC_PUNIT_BIOS_READ_FM_SOC_TEMP_THRESH (IPC_PUNIT_BIOS_CMD_BASE | 0x1a) -#define IPC_PUNIT_BIOS_WRITE_FM_SOC_TEMP_THRESH (IPC_PUNIT_BIOS_CMD_BASE | 0x1b) +#define IPC_PUNIT_BIOS_ZERO(0x00) +#define IPC_PUNIT_BIOS_VR_INTERFACE(0x01) +#define IPC_PUNIT_BIOS_READ_PCS(0x02) +#define IPC_PUNIT_BIOS_WRITE_PCS (0x03) +#define IPC_PUNIT_BIOS_READ_PCU_CONFIG (0x04) +#define IPC_PUNIT_BIOS_WRITE_PCU_CONFIG(0x05) +#define IPC_PUNIT_BIOS_READ_PL1_SETTING(0x06) +#define IPC_PUNIT_BIOS_WRITE_PL1_SETTING (0x07) +#define IPC_PUNIT_BIOS_TRIGGER_VDD_RAM (0x08) +#define IPC_PUNIT_BIOS_READ_
[RFC v4 4/8] platform: x86: Add generic Intel IPC driver
From: Kuppuswamy Sathyanarayanan Currently intel_scu_ipc.c, intel_pmc_ipc.c and intel_punit_ipc.c redundantly implements the same IPC features and has lot of code duplication between them. This driver addresses this issue by grouping the common IPC functionalities under the same driver. Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/platform/x86/Kconfig| 8 + drivers/platform/x86/Makefile | 1 + drivers/platform/x86/intel_ipc_dev.c| 576 include/linux/platform_data/x86/intel_ipc_dev.h | 206 + 4 files changed, 791 insertions(+) create mode 100644 drivers/platform/x86/intel_ipc_dev.c create mode 100644 include/linux/platform_data/x86/intel_ipc_dev.h Changes since v3: * Fixed NULL pointer exception in intel_ipc_dev_get(). * Fixed error in check for duplicate intel_ipc_dev. * Added custom interrupt handler support. * Used char array for error string conversion. * Added put dev support. * Added devm_* variant of intel_ipc_dev_get(). Changes since v2: * Added ipc_dev_cmd API support. diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index da2d9ba..724ee696 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1153,6 +1153,14 @@ config SILEAD_DMI with the OS-image for the device. This option supplies the missing information. Enable this for x86 tablets with Silead touchscreens. +config INTEL_IPC_DEV + bool "Intel IPC Device Driver" + depends on X86_64 + ---help--- + This driver implements core features of Intel IPC device. Devices + like PMC, SCU, PUNIT, etc can use interfaces provided by this + driver to implement IPC protocol of their respective device. + endif # X86_PLATFORM_DEVICES config PMC_ATOM diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 2b315d0..99a1af1 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -84,3 +84,4 @@ obj-$(CONFIG_PMC_ATOM)+= pmc_atom.o obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o obj-$(CONFIG_MLX_CPLD_PLATFORM)+= mlxcpld-hotplug.o obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o +obj-$(CONFIG_INTEL_IPC_DEV)+= intel_ipc_dev.o diff --git a/drivers/platform/x86/intel_ipc_dev.c b/drivers/platform/x86/intel_ipc_dev.c new file mode 100644 index 000..f55ddec --- /dev/null +++ b/drivers/platform/x86/intel_ipc_dev.c @@ -0,0 +1,576 @@ +/* + * intel_ipc_dev.c: Intel IPC device class driver + * + * (C) Copyright 2017 Intel Corporation + * + * 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; version 2 + * of the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* mutex to sync different ipc devices in same channel */ +static struct mutex channel_lock[IPC_CHANNEL_MAX]; + +static char *ipc_err_sources[] = { + [IPC_DEV_ERR_NONE] = + "No error", + [IPC_DEV_ERR_CMD_NOT_SUPPORTED] = + "Command not-supported/Invalid", + [IPC_DEV_ERR_CMD_NOT_SERVICED] = + "Command not-serviced/Invalid param", + [IPC_DEV_ERR_UNABLE_TO_SERVICE] = + "Unable-to-service/Cmd-timeout", + [IPC_DEV_ERR_CMD_INVALID] = + "Command-invalid/Cmd-locked", + [IPC_DEV_ERR_CMD_FAILED] = + "Command-failed/Invalid-VR-id", + [IPC_DEV_ERR_EMSECURITY] = + "Invalid Battery/VR-Error", + [IPC_DEV_ERR_UNSIGNEDKERNEL] = + "Unsigned kernel", +}; + +static void ipc_channel_lock_init(void) +{ + int i; + + for (i = 0; i < IPC_CHANNEL_MAX; i++) + mutex_init(&channel_lock[i]); +} + +static struct class intel_ipc_class = { + .name = "intel_ipc", + .owner = THIS_MODULE, +}; + +static int ipc_dev_lock(struct intel_ipc_dev *ipc_dev) +{ + int chan_type; + + if (!ipc_dev || !ipc_dev->cfg) + return -ENODEV; + + chan_type = ipc_dev->cfg->chan_type; + if (chan_type > IPC_CHANNEL_MAX) + return -EINVAL; + + /* acquire channel lock */ + mutex_lock(&channel_lock[chan_type]); + + /* acquire IPC device lock */ + mutex_lock(&ipc_dev->lock); + + return 0; +} + +static int ipc_dev_unlock(struct intel_ipc_dev *ipc_dev) +{ + int chan_type; + + if (!ipc_dev || !ipc_dev->cfg) + return -ENODEV; + + chan_type = ipc_dev->cfg->chan_type; + if (chan_type > IPC_CHANNEL_MAX) + return -EINVAL; + + /* release IPC device lock */ + mutex_unlock(&ipc_dev->lock); + + /* release channel lock */ + mutex_unlock(&channel_lock[chan_type]); + + return 0; +} + +static const char *ipc_dev_e
[RFC v4 1/8] platform/x86: intel_pmc_ipc: Use MFD framework to create dependent devices
From: Kuppuswamy Sathyanarayanan Currently, we have lot of repetitive code in dependent device resource allocation and device creation handling code. This logic can be improved if we use MFD framework for dependent device creation. This patch adds this support. Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/platform/x86/intel_pmc_ipc.c | 394 --- 1 file changed, 137 insertions(+), 257 deletions(-) Changes since v3: * Changed PLATFORM_DEVID_AUTO to PLATFORM_DEVID_NONE in mfd device creation. * Fixed error in resource initalization logic in ipc_create_punit_device. * Removed mfd cell id initialization. diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index 751b121..c85351e 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -87,6 +88,7 @@ #define PLAT_RESOURCE_ISP_IFACE_INDEX 5 #define PLAT_RESOURCE_GTD_DATA_INDEX 6 #define PLAT_RESOURCE_GTD_IFACE_INDEX 7 +#define PLAT_RESOURCE_MEM_MAX_INDEX8 #define PLAT_RESOURCE_ACPI_IO_INDEX0 /* @@ -105,8 +107,6 @@ #define TELEM_SSRAM_SIZE 240 #define TELEM_PMC_SSRAM_OFFSET 0x1B00 #define TELEM_PUNIT_SSRAM_OFFSET 0x1A00 -#define TCO_PMC_OFFSET 0x8 -#define TCO_PMC_SIZE 0x4 /* PMC register bit definitions */ @@ -123,25 +123,9 @@ static struct intel_pmc_ipc_dev { int cmd; struct completion cmd_complete; - /* The following PMC BARs share the same ACPI device with the IPC */ - resource_size_t acpi_io_base; - int acpi_io_size; - struct platform_device *tco_dev; - /* gcr */ void __iomem *gcr_mem_base; bool has_gcr_regs; - - /* punit */ - struct platform_device *punit_dev; - - /* Telemetry */ - resource_size_t telem_pmc_ssram_base; - resource_size_t telem_punit_ssram_base; - int telem_pmc_ssram_size; - int telem_punit_ssram_size; - u8 telem_res_inval; - struct platform_device *telemetry_dev; } ipcdev; static char *ipc_err_sources[] = { @@ -589,44 +573,6 @@ static const struct attribute_group intel_ipc_group = { .attrs = intel_ipc_attrs, }; -static struct resource punit_res_array[] = { - /* Punit BIOS */ - { - .flags = IORESOURCE_MEM, - }, - { - .flags = IORESOURCE_MEM, - }, - /* Punit ISP */ - { - .flags = IORESOURCE_MEM, - }, - { - .flags = IORESOURCE_MEM, - }, - /* Punit GTD */ - { - .flags = IORESOURCE_MEM, - }, - { - .flags = IORESOURCE_MEM, - }, -}; - -#define TCO_RESOURCE_ACPI_IO 0 -#define TCO_RESOURCE_SMI_EN_IO 1 -#define TCO_RESOURCE_GCR_MEM 2 -static struct resource tco_res[] = { - /* ACPI - TCO */ - { - .flags = IORESOURCE_IO, - }, - /* ACPI - SMI */ - { - .flags = IORESOURCE_IO, - }, -}; - static struct itco_wdt_platform_data tco_info = { .name = "Apollo Lake SoC", .version = 5, @@ -634,234 +580,179 @@ static struct itco_wdt_platform_data tco_info = { .update_no_reboot_bit = update_no_reboot_bit, }; -#define TELEMETRY_RESOURCE_PUNIT_SSRAM 0 -#define TELEMETRY_RESOURCE_PMC_SSRAM 1 -static struct resource telemetry_res[] = { - /*Telemetry*/ - { - .flags = IORESOURCE_MEM, - }, - { - .flags = IORESOURCE_MEM, - }, -}; - -static int ipc_create_punit_device(void) +static int ipc_create_punit_device(struct platform_device *pdev) { - struct platform_device *pdev; - const struct platform_device_info pdevinfo = { - .parent = ipcdev.dev, - .name = PUNIT_DEVICE_NAME, - .id = -1, - .res = punit_res_array, - .num_res = ARRAY_SIZE(punit_res_array), + struct resource *res; + static struct resource punit_res[PLAT_RESOURCE_MEM_MAX_INDEX]; + static struct mfd_cell punit_cell; + int mindex, pindex = 0; + + for (mindex = 0; mindex <= PLAT_RESOURCE_MEM_MAX_INDEX; mindex++) { + + res = platform_get_resource(pdev, IORESOURCE_MEM, mindex); + + switch (mindex) { + /* Get PUNIT resources */ + case PLAT_RESOURCE_BIOS_DATA_INDEX: + case PLAT_RESOURCE_BIOS_IFACE_INDEX: + /* BIOS resources are required, so return error if not +* available */ + if (!res) { + dev_err(&pdev->dev, + "Failed to get punit mem resource %d\n", + pindex); + return -ENXI
[RFC v4 0/8] PMC/PUNIT IPC driver cleanup
From: Kuppuswamy Sathyanarayanan Hi All, Currently intel_pmc_ipc.c, intel_punit_ipc.c, intel_scu_ipc.c drivers implements the same IPC features. This code duplication could be avoided if we implement the IPC driver as a generic library and let custom device drivers use API provided by generic driver. This patchset mainly addresses this issue. Along with above code duplication issue, This patchset also addresses following issues in intel_pmc_ipc and intel_punit_ipc drivers. 1. Intel_pmc_ipc.c driver does not use any resource managed (devm_*) calls. 2. In Intel_pmc_ipc.c driver, dependent devices like PUNIT, Telemetry and iTCO are created manually and uses lot of redundant buffer code. 3. Global variable is used to store the IPC device structure and it is used across all functions in intel_pmc_ipc.c and intel_punit_ipc.c. More info on Intel IPC device library: - A generic Intel IPC class driver has been implemented and all common IPC helper functions has been moved to this driver. It exposes APIs to create IPC device channel, send raw IPC command and simple IPC commands. It also creates device attribute to send IPC command from user space. API for creating a new IPC channel device is, struct intel_ipc_dev *devm_intel_ipc_dev_create(struct device *dev, const char *devname, struct intel_ipc_dev_cfg *cfg, struct intel_ipc_dev_ops *ops) The IPC channel drivers (PUNIT/PMC/SCU) when creating a new device can configure their device params like register mapping, irq, irq-mode, channel type,etc using intel_ipc_dev_cfg and intel_ipc_dev_ops arguments. After a new IPC channel device is created, IPC users can use the generic APIs to make IPC calls. For example, after using this new model, IPC call to PMC device will look like, pmc_ipc_dev = intel_ipc_dev_get(INTEL_PMC_IPC_DEV); ipc_dev_raw_cmd(pmc_ipc_dev, cmd, PMC_PARAM_LEN, (u32 *)ipc_in, 1, NULL, 0, 0, 0); intel_ipc_dev_put(pmc_ipc_dev); I am still testing the driver in different products. But posted it to get some early comments. I also welcome any PMC/PUNIT driver users to check these patches in their product. Changes since v3: * Rebased on top of Andy's review branch. * Fixed resource ioremap warning in intel_punit_ipc.c. * Divided "platform/x86: intel_pmc_ipc: Use regmap calls for GCR updates" patch into two patches. One fixing the existing issue and another to add regmap support. * Fixed error in resource initalization logic in ipc_create_punit_device. * Changed PLATFORM_DEVID_AUTO to PLATFORM_DEVID_NONE in mfd device creation. * Added unique name to PUNIT BIOS, GTD, & ISP regmaps. * Fixed NULL pointer exception in intel_ipc_dev_get(). * In intel_ipc_dev.c, * Fixed error in check for duplicate intel_ipc_dev. * Added custom interrupt handler support. * Used char array for error string conversion. * Added put dev support. Changes since v2: * Refactored intel_scu_ipc.c to use generic IPC device APIs. * Fixed intel_pmc_ipc.c to use pcim_* device managed functions. Changes since v1: * Merged devm_* changes in pmc_plat_probe and pmc_pci_probe functions into a single patch. * Addressed Andy's comment about keeping the library generic by not implementing the low level reg access calls in intel_ipc_dev.c. This version will start using the regmap pointer provided by channel drivers instead of fixed memory map. * Removed custom IPC APIs in intel_pmc_ipc.c and intel_punit_ipc.c. * Cleaned up IPC driver users to use APIs provided by generic library (intel_ipc_dev.c). Kuppuswamy Sathyanarayanan (8): platform/x86: intel_pmc_ipc: Use MFD framework to create dependent devices platform/x86: intel_pmc_ipc: Use spin_lock to protect GCR updates platform/x86: intel_pmc_ipc: Use regmap calls for GCR updates platform: x86: Add generic Intel IPC driver platform/x86: intel_punit_ipc: Fix resource ioremap warning platform/x86: intel_punit_ipc: Use generic intel ipc device calls platform/x86: intel_pmc_ipc: Use generic Intel IPC device calls platform/x86: intel_scu_ipc: Use generic Intel IPC device calls arch/x86/include/asm/intel_pmc_ipc.h| 37 +- arch/x86/include/asm/intel_punit_ipc.h | 125 ++-- arch/x86/include/asm/intel_scu_ipc.h| 23 +- arch/x86/platform/intel-mid/intel-mid.c | 15 +- drivers/mfd/intel_soc_pmic_bxtwc.c | 21 +- drivers/platform/x86/Kconfig| 11 + drivers/platform/x86/Makefile | 1 + drivers/platform/x86/intel_ipc_dev.c| 576 +++ drivers/platform/x86/intel_pmc_ipc.c| 886 +--- drivers/platform/x86/intel_punit_ipc.c | 311 +++-- drivers/platform/x86/intel_scu_ipc.c| 483 ++--- drivers/platform/x86/intel_telemetry_pltdrv.c | 212 +++--- drivers/rtc/rtc-mrst.c | 16 +- drivers/watchdog/intel-mid_wdt.c| 12
[RFC v4 8/8] platform/x86: intel_scu_ipc: Use generic Intel IPC device calls
From: Kuppuswamy Sathyanarayanan Removed redundant IPC helper functions and refactored the driver to use generic IPC device driver APIs. This patch also cleans-up SCU IPC user drivers(rtc-mrst.c, intel-mid_wdt.c, intel-mid_wdt.c, intel-mid.c) to use APIs provided by generic IPC driver. Signed-off-by: Kuppuswamy Sathyanarayanan Acked-by: Alexandre Belloni --- arch/x86/include/asm/intel_scu_ipc.h| 23 +- arch/x86/platform/intel-mid/intel-mid.c | 15 +- drivers/platform/x86/Kconfig| 1 + drivers/platform/x86/intel_scu_ipc.c| 483 +--- drivers/rtc/rtc-mrst.c | 16 +- drivers/watchdog/intel-mid_wdt.c| 12 +- drivers/watchdog/intel_scu_watchdog.c | 18 +- 7 files changed, 256 insertions(+), 312 deletions(-) Changes since v3: * Added intel_ipc_dev_put() support. diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h index 81d3d87..5842534 100644 --- a/arch/x86/include/asm/intel_scu_ipc.h +++ b/arch/x86/include/asm/intel_scu_ipc.h @@ -14,9 +14,19 @@ #define IPCMSG_COLD_BOOT 0xF3 #define IPCMSG_VRTC0xFA /* Set vRTC device */ - /* Command id associated with message IPCMSG_VRTC */ - #define IPC_CMD_VRTC_SETTIME 1 /* Set time */ - #define IPC_CMD_VRTC_SETALARM 2 /* Set alarm */ + +/* Command id associated with message IPCMSG_VRTC */ +#define IPC_CMD_VRTC_SETTIME 1 /* Set time */ +#define IPC_CMD_VRTC_SETALARM 2 /* Set alarm */ + +#define INTEL_SCU_IPC_DEV "intel_scu_ipc" +#define SCU_PARAM_LEN 2 + +static inline void scu_cmd_init(u32 *cmd, u32 param1, u32 param2) +{ + cmd[0] = param1; + cmd[1] = param2; +} /* Read single register */ int intel_scu_ipc_ioread8(u16 addr, u8 *data); @@ -45,13 +55,6 @@ int intel_scu_ipc_writev(u16 *addr, u8 *data, int len); /* Update single register based on the mask */ int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask); -/* Issue commands to the SCU with or without data */ -int intel_scu_ipc_simple_command(int cmd, int sub); -int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, - u32 *out, int outlen); -int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen, - u32 *out, int outlen, u32 dptr, u32 sptr); - /* I2C control api */ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data); diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c index 86676ce..23b3ab3 100644 --- a/arch/x86/platform/intel-mid/intel-mid.c +++ b/arch/x86/platform/intel-mid/intel-mid.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -70,16 +71,26 @@ EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip); static void intel_mid_power_off(void) { + struct intel_ipc_dev *ipc_dev; + u32 cmds[SCU_PARAM_LEN] = {IPCMSG_COLD_OFF, 1}; + /* Shut down South Complex via PWRMU */ intel_mid_pwr_power_off(); + ipc_dev = intel_ipc_dev_get(INTEL_SCU_IPC_DEV); /* Only for Tangier, the rest will ignore this command */ - intel_scu_ipc_simple_command(IPCMSG_COLD_OFF, 1); + ipc_dev_simple_cmd(ipc_dev, cmds, SCU_PARAM_LEN); + intel_ipc_dev_put(ipc_dev); }; static void intel_mid_reboot(void) { - intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0); + struct intel_ipc_dev *ipc_dev; + u32 cmds[SCU_PARAM_LEN] = {IPCMSG_COLD_BOOT, 0}; + + ipc_dev = intel_ipc_dev_get(INTEL_SCU_IPC_DEV); + ipc_dev_simple_cmd(ipc_dev, cmds, SCU_PARAM_LEN); + intel_ipc_dev_put(ipc_dev); } static unsigned long __init intel_mid_calibrate_tsc(void) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 9442c23..1b9093c 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -863,6 +863,7 @@ config INTEL_VBTN config INTEL_SCU_IPC bool "Intel SCU IPC Support" depends on X86_INTEL_MID + select REGMAP_MMIO default y ---help--- IPC is used to bridge the communications between kernel and SCU on diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 2c85f75..8812202 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -39,6 +41,25 @@ #define IPC_CMD_PCNTRL_R 1 /* Register read */ #define IPC_CMD_PCNTRL_M 2 /* Register read-modify-write */ +/* IPC dev register offsets */ +/* + * IPC Read Buffer (Read Only): + * 16 byte buffer for receiving data from SCU, if IPC command + * processing results in response data + */ +#define IPC_DEV_SCU_RBUF_OFFSET0x90 +#define IPC_DEV_SCU_WRBUF_OFFSET 0x80 +#define IPC_DEV_SCU_SPTR_OFFSET0x08 +#define IPC_DEV_SCU_DPTR_OFFSET
[RFC v4 3/8] platform/x86: intel_pmc_ipc: Use regmap calls for GCR updates
From: Kuppuswamy Sathyanarayanan This patch adds support for regmap based implementation for GCR read/write/update APIs. Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/platform/x86/Kconfig | 1 + drivers/platform/x86/intel_pmc_ipc.c | 120 +-- 2 files changed, 44 insertions(+), 77 deletions(-) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 1f7959f..da2d9ba 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1067,6 +1067,7 @@ config PVPANIC config INTEL_PMC_IPC tristate "Intel PMC IPC Driver" depends on ACPI + select REGMAP_MMIO ---help--- This driver provides support for PMC control on some Intel platforms. The PMC is an ARC processor which defines IPC commands for communication diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index c68f6a4..55611d2 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -126,8 +127,7 @@ static struct intel_pmc_ipc_dev { /* gcr */ void __iomem *gcr_mem_base; - bool has_gcr_regs; - spinlock_t gcr_lock; + struct regmap *gcr_regs; } ipcdev; static char *ipc_err_sources[] = { @@ -149,6 +149,15 @@ static char *ipc_err_sources[] = { "Unsigned kernel", }; +static struct regmap_config gcr_regmap_config = { + .name = "intel_pmc_gcr", +.reg_bits = 32, +.reg_stride = 4, +.val_bits = 32, + .fast_io = true, + .max_register = PLAT_RESOURCE_GCR_SIZE, +}; + /* Prevent concurrent calls to the PMC */ static DEFINE_MUTEX(ipclock); @@ -182,21 +191,6 @@ static inline u32 ipc_data_readl(u32 offset) return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); } -static inline u64 gcr_data_readq(u32 offset) -{ - return readq(ipcdev.gcr_mem_base + offset); -} - -static inline int is_gcr_valid(u32 offset) -{ - if (!ipcdev.has_gcr_regs) - return -EACCES; - - if (offset > PLAT_RESOURCE_GCR_SIZE) - return -EINVAL; - - return 0; -} /** * intel_pmc_gcr_read() - Read PMC GCR register @@ -209,21 +203,12 @@ static inline int is_gcr_valid(u32 offset) */ int intel_pmc_gcr_read(u32 offset, u32 *data) { - int ret; - - spin_lock(&ipcdev.gcr_lock); - - ret = is_gcr_valid(offset); - if (ret < 0) { - spin_unlock(&ipcdev.gcr_lock); - return ret; - } - - *data = readl(ipcdev.gcr_mem_base + offset); + struct intel_pmc_ipc_dev *pmc = &ipcdev; - spin_unlock(&ipcdev.gcr_lock); + if (!pmc->gcr_regs) + return -EACCES; - return 0; + return regmap_read(pmc->gcr_regs, offset, data); } EXPORT_SYMBOL_GPL(intel_pmc_gcr_read); @@ -239,21 +224,12 @@ EXPORT_SYMBOL_GPL(intel_pmc_gcr_read); */ int intel_pmc_gcr_write(u32 offset, u32 data) { - int ret; - - spin_lock(&ipcdev.gcr_lock); - - ret = is_gcr_valid(offset); - if (ret < 0) { - spin_unlock(&ipcdev.gcr_lock); - return ret; - } - - writel(data, ipcdev.gcr_mem_base + offset); + struct intel_pmc_ipc_dev *pmc = &ipcdev; - spin_unlock(&ipcdev.gcr_lock); + if (!pmc->gcr_regs) + return -EACCES; - return 0; + return regmap_write(pmc->gcr_regs, offset, data); } EXPORT_SYMBOL_GPL(intel_pmc_gcr_write); @@ -270,33 +246,12 @@ EXPORT_SYMBOL_GPL(intel_pmc_gcr_write); */ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val) { - u32 new_val; - int ret = 0; - - spin_lock(&ipcdev.gcr_lock); - - ret = is_gcr_valid(offset); - if (ret < 0) - goto gcr_ipc_unlock; - - new_val = readl(ipcdev.gcr_mem_base + offset); - - new_val &= ~mask; - new_val |= val & mask; - - writel(new_val, ipcdev.gcr_mem_base + offset); - - new_val = readl(ipcdev.gcr_mem_base + offset); + struct intel_pmc_ipc_dev *pmc = &ipcdev; - /* check whether the bit update is successful */ - if ((new_val & mask) != (val & mask)) { - ret = -EIO; - goto gcr_ipc_unlock; - } + if (!pmc->gcr_regs) + return -EACCES; -gcr_ipc_unlock: - spin_unlock(&ipcdev.gcr_lock); - return ret; + return regmap_update_bits(pmc->gcr_regs, offset, mask, val); } EXPORT_SYMBOL_GPL(intel_pmc_gcr_update); @@ -473,8 +428,6 @@ static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (pmc->dev) return -EBUSY; - spin_lock_init(&ipcdev.gcr_lock); - pmc->irq_mode = IPC_TRIGGER_MODE_IRQ; ret = pcim_enable_device(pdev); @@ -769,17 +722,26 @@ static int ipc_plat_get_res(struct platform_device *pdev) */ int
[RFC v4 2/8] platform/x86: intel_pmc_ipc: Use spin_lock to protect GCR updates
From: Kuppuswamy Sathyanarayanan Currently, update_no_reboot_bit() function implemented in this driver uses mutex_lock() to protect its register updates. But this function is called with in atomic context in iTCO_wdt_start() and iTCO_wdt_stop() functions in iTCO_wdt.c driver, which in turn causes "sleeping into atomic context" issue. This patch fixes this issue by replacing the mutex_lock() with spin_lock() to protect the GCR read/write/update APIs. Fixes: 9d855d4 ("platform/x86: intel_pmc_ipc: Fix iTCO_wdt GCS memory mapping failure") Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/platform/x86/intel_pmc_ipc.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index c85351e..c68f6a4 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -126,6 +127,7 @@ static struct intel_pmc_ipc_dev { /* gcr */ void __iomem *gcr_mem_base; bool has_gcr_regs; + spinlock_t gcr_lock; } ipcdev; static char *ipc_err_sources[] = { @@ -209,17 +211,17 @@ int intel_pmc_gcr_read(u32 offset, u32 *data) { int ret; - mutex_lock(&ipclock); + spin_lock(&ipcdev.gcr_lock); ret = is_gcr_valid(offset); if (ret < 0) { - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return ret; } *data = readl(ipcdev.gcr_mem_base + offset); - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return 0; } @@ -239,17 +241,17 @@ int intel_pmc_gcr_write(u32 offset, u32 data) { int ret; - mutex_lock(&ipclock); + spin_lock(&ipcdev.gcr_lock); ret = is_gcr_valid(offset); if (ret < 0) { - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return ret; } writel(data, ipcdev.gcr_mem_base + offset); - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return 0; } @@ -271,7 +273,7 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val) u32 new_val; int ret = 0; - mutex_lock(&ipclock); + spin_lock(&ipcdev.gcr_lock); ret = is_gcr_valid(offset); if (ret < 0) @@ -293,7 +295,7 @@ int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val) } gcr_ipc_unlock: - mutex_unlock(&ipclock); + spin_unlock(&ipcdev.gcr_lock); return ret; } EXPORT_SYMBOL_GPL(intel_pmc_gcr_update); @@ -471,6 +473,8 @@ static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (pmc->dev) return -EBUSY; + spin_lock_init(&ipcdev.gcr_lock); + pmc->irq_mode = IPC_TRIGGER_MODE_IRQ; ret = pcim_enable_device(pdev); @@ -794,6 +798,7 @@ static int ipc_plat_probe(struct platform_device *pdev) ipcdev.dev = &pdev->dev; ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ; init_completion(&ipcdev.cmd_complete); + spin_lock_init(&ipcdev.gcr_lock); ipcdev.irq = platform_get_irq(pdev, 0); if (ipcdev.irq < 0) { -- 2.7.4
Re: [PATCH] bcache: Remove nested function from sysfs
On 2017/10/7 上午5:35, Matthias Kaehlcke wrote: > From: Behan Webster > > Replace the use of nested functions where a normal function will > suffice. > > Nested functions are not liked by upstream kernel developers in > general. Their use breaks the use of clang as a compiler, and > doesn't make the code any better. > > This code now works for both gcc and clang. > > From: Behan Webster > Signed-off-by: Behan Webster > Reviewed-by: Mark Charlebois > Suggested-by: Arnd Bergmann > Signed-off-by: Matthias Kaehlcke Hi Behan, This patch was posted by Peter Foley in Nov 2016, I test it, and add it to for-next directory. It should be in 4.15. Thanks. Coly > --- > drivers/md/bcache/sysfs.c | 10 ++ > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c > index 104c57cd666c..440c3906f852 100644 > --- a/drivers/md/bcache/sysfs.c > +++ b/drivers/md/bcache/sysfs.c > @@ -745,6 +745,11 @@ static struct attribute *bch_cache_set_internal_files[] > = { > }; > KTYPE(bch_cache_set_internal); > > +static int __bch_cache_cmp(const void *l, const void *r) > +{ > + return *((uint16_t *) r) - *((uint16_t *) l); > +} > + > SHOW(__bch_cache) > { > struct cache *ca = container_of(kobj, struct cache, kobj); > @@ -769,9 +774,6 @@ SHOW(__bch_cache) > CACHE_REPLACEMENT(&ca->sb)); > > if (attr == &sysfs_priority_stats) { > - int cmp(const void *l, const void *r) > - { return *((uint16_t *) r) - *((uint16_t *) l); } > - > struct bucket *b; > size_t n = ca->sb.nbuckets, i; > size_t unused = 0, available = 0, dirty = 0, meta = 0; > @@ -800,7 +802,7 @@ SHOW(__bch_cache) > p[i] = ca->buckets[i].prio; > mutex_unlock(&ca->set->bucket_lock); > > - sort(p, n, sizeof(uint16_t), cmp, NULL); > + sort(p, n, sizeof(uint16_t), __bch_cache_cmp, NULL); > > while (n && > !cached[n - 1]) >
[PATCH v2 02/18] powerpc/vas: Validate window credits
NX-842, the only user of VAS, sets the window credits to default values but VAS should check the credits against the possible max values. The VAS_WCREDS_MIN is not needed and can be dropped. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas-window.c | 6 ++ arch/powerpc/platforms/powernv/vas.h| 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index cec7ab7..a2fe120 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -738,6 +738,9 @@ static bool rx_win_args_valid(enum vas_cop_type cop, if (attr->rx_fifo_size > VAS_RX_FIFO_SIZE_MAX) return false; + if (attr->wcreds_max > VAS_RX_WCREDS_MAX) + return false; + if (attr->nx_win) { /* cannot be fault or user window if it is nx */ if (attr->fault_win || attr->user_win) @@ -927,6 +930,9 @@ static bool tx_win_args_valid(enum vas_cop_type cop, if (cop > VAS_COP_TYPE_MAX) return false; + if (attr->wcreds_max > VAS_TX_WCREDS_MAX) + return false; + if (attr->user_win && (cop != VAS_COP_TYPE_FTW || attr->rsvd_txbuf_count)) return false; diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h index 38dee5d..fea0de4 100644 --- a/arch/powerpc/platforms/powernv/vas.h +++ b/arch/powerpc/platforms/powernv/vas.h @@ -106,8 +106,8 @@ * * TODO: Needs tuning for per-process credits */ -#define VAS_WCREDS_MIN 16 -#define VAS_WCREDS_MAX ((64 << 10) - 1) +#define VAS_RX_WCREDS_MAX ((64 << 10) - 1) +#define VAS_TX_WCREDS_MAX ((4 << 10) - 1) #define VAS_WCREDS_DEFAULT (1 << 10) /* -- 2.7.4
[PATCH v2 01/18] powerpc/vas: init missing fields from [rt]xattr
Initialize a few missing window context fields from the window attributes specified by the caller. These fields are currently set to their default values by the caller (NX-842), but would be good to apply them anyway. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas-window.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 5aae845..cec7ab7 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -679,10 +679,13 @@ static void init_winctx_for_rxwin(struct vas_window *rxwin, winctx->nx_win = rxattr->nx_win; winctx->fault_win = rxattr->fault_win; + winctx->user_win = rxattr->user_win; + winctx->rej_no_credit = rxattr->rej_no_credit; winctx->rx_word_mode = rxattr->rx_win_ord_mode; winctx->tx_word_mode = rxattr->tx_win_ord_mode; winctx->rx_wcred_mode = rxattr->rx_wcred_mode; winctx->tx_wcred_mode = rxattr->tx_wcred_mode; + winctx->notify_early = rxattr->notify_early; if (winctx->nx_win) { winctx->data_stamp = true; @@ -889,11 +892,14 @@ static void init_winctx_for_txwin(struct vas_window *txwin, winctx->user_win = txattr->user_win; winctx->nx_win = txwin->rxwin->nx_win; winctx->pin_win = txattr->pin_win; + winctx->rej_no_credit = txattr->rej_no_credit; + winctx->rsvd_txbuf_enable = txattr->rsvd_txbuf_enable; winctx->rx_wcred_mode = txattr->rx_wcred_mode; winctx->tx_wcred_mode = txattr->tx_wcred_mode; winctx->rx_word_mode = txattr->rx_win_ord_mode; winctx->tx_word_mode = txattr->tx_win_ord_mode; + winctx->rsvd_txbuf_count = txattr->rsvd_txbuf_count; if (winctx->nx_win) { winctx->data_stamp = true; -- 2.7.4
Re: [BUG] fs/aio: A possible sleep-in-atomic bug in aio_migratepage
On Sat, Oct 07, 2017 at 09:36:48AM +0800, Jia-Ju Bai wrote: > According to fs/aio.c, cond_resched is called under a spinlock, > and the function call path is: > aio_migratepage (acquire the spinlock) > migrate_page_copy > copy_huge_page > __copy_gigantic_page > cond_resched > might_sleep > > This bug is found by my static analysis tool and my code review. > A possible fix is to remove cond_resched in __copy_gigantic_page. How the hell would a huge page end up in page cache of inode created by aio_private_file()???
[PATCH v2 05/18] powerpc/vas: Use helper to unpin/close window
Use a helper to have the hardware unpin and mark a window closed. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas-window.c | 22 +++--- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 8ab8a82..95622a9 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -1101,6 +1101,20 @@ static void poll_window_castout(struct vas_window *window) } /* + * Unpin and close a window so no new requests are accepted and the + * hardware can evict this window from cache if necessary. + */ +static void unpin_close_window(struct vas_window *window) +{ + u64 val; + + val = read_hvwc_reg(window, VREG(WINCTL)); + val = SET_FIELD(VAS_WINCTL_PIN, val, 0); + val = SET_FIELD(VAS_WINCTL_OPEN, val, 0); + write_hvwc_reg(window, VREG(WINCTL), val); +} + +/* * Close a window. * * See Section 1.12.1 of VAS workbook v1.05 for details on closing window: @@ -1114,8 +1128,6 @@ static void poll_window_castout(struct vas_window *window) */ int vas_win_close(struct vas_window *window) { - u64 val; - if (!window) return 0; @@ -1131,11 +1143,7 @@ int vas_win_close(struct vas_window *window) poll_window_busy_state(window); - /* Unpin window from cache and close it */ - val = read_hvwc_reg(window, VREG(WINCTL)); - val = SET_FIELD(VAS_WINCTL_PIN, val, 0); - val = SET_FIELD(VAS_WINCTL_OPEN, val, 0); - write_hvwc_reg(window, VREG(WINCTL), val); + unpin_close_window(window); poll_window_castout(window); -- 2.7.4
[PATCH v2 06/18] powerpc/vas: Reduce polling interval for busy state
A VAS window is normally in "busy" state for only a short duration. Reduce the time we wait for the window to go to "not-busy" state to speed-up vas_win_close() a bit. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas-window.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 95622a9..1422cdd 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -1060,21 +1060,23 @@ int vas_paste_crb(struct vas_window *txwin, int offset, bool re) } EXPORT_SYMBOL_GPL(vas_paste_crb); +/* + * Wait for the window to go to "not-busy" state. It should only take a + * short time to queue a CRB, so window should not be busy for too long. + * Trying 5ms intervals. + */ static void poll_window_busy_state(struct vas_window *window) { int busy; u64 val; retry: - /* -* Poll Window Busy flag -*/ val = read_hvwc_reg(window, VREG(WIN_STATUS)); busy = GET_FIELD(VAS_WIN_BUSY, val); if (busy) { val = 0; set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); + schedule_timeout(msecs_to_jiffies(5)); goto retry; } } -- 2.7.4
[PATCH v2 07/18] powerpc/vas: Save configured window credits
Save the configured max window credits for a window in the vas_window structure. We will need this when polling for return of window credits. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas-window.c | 6 -- arch/powerpc/platforms/powernv/vas.h| 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 1422cdd..a59a187 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -674,7 +674,7 @@ static void init_winctx_for_rxwin(struct vas_window *rxwin, winctx->rx_fifo = rxattr->rx_fifo; winctx->rx_fifo_size = rxattr->rx_fifo_size; - winctx->wcreds_max = rxattr->wcreds_max ?: VAS_WCREDS_DEFAULT; + winctx->wcreds_max = rxwin->wcreds_max; winctx->pin_win = rxattr->pin_win; winctx->nx_win = rxattr->nx_win; @@ -844,6 +844,7 @@ struct vas_window *vas_rx_win_open(int vasid, enum vas_cop_type cop, rxwin->nx_win = rxattr->nx_win; rxwin->user_win = rxattr->user_win; rxwin->cop = cop; + rxwin->wcreds_max = rxattr->wcreds_max ?: VAS_WCREDS_DEFAULT; if (rxattr->user_win) rxwin->pid = task_pid_vnr(current); @@ -893,7 +894,7 @@ static void init_winctx_for_txwin(struct vas_window *txwin, */ memset(winctx, 0, sizeof(struct vas_winctx)); - winctx->wcreds_max = txattr->wcreds_max ?: VAS_WCREDS_DEFAULT; + winctx->wcreds_max = txwin->wcreds_max; winctx->user_win = txattr->user_win; winctx->nx_win = txwin->rxwin->nx_win; @@ -978,6 +979,7 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, txwin->nx_win = txwin->rxwin->nx_win; txwin->pid = attr->pid; txwin->user_win = attr->user_win; + txwin->wcreds_max = attr->wcreds_max ?: VAS_WCREDS_DEFAULT; init_winctx_for_txwin(txwin, attr, &winctx); diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h index 15d2dfa..ad906f6 100644 --- a/arch/powerpc/platforms/powernv/vas.h +++ b/arch/powerpc/platforms/powernv/vas.h @@ -332,6 +332,7 @@ struct vas_window { void *hvwc_map; /* HV window context */ void *uwc_map; /* OS/User window context */ pid_t pid; /* Linux process id of owner */ + int wcreds_max; /* Window credits */ /* Fields applicable only to send windows */ void *paste_kaddr; -- 2.7.4
[PATCH v2 09/18] powerpc/vas: Create cpu to vas id mapping
Create a cpu to vasid mapping so callers can specify -1 instead of trying to find a VAS id. Changelog[v2] [Michael Ellerman] Use per-cpu variables to simplify code. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/vas.c b/arch/powerpc/platforms/powernv/vas.c index 565a487..abb7090 100644 --- a/arch/powerpc/platforms/powernv/vas.c +++ b/arch/powerpc/platforms/powernv/vas.c @@ -18,15 +18,18 @@ #include #include #include +#include #include "vas.h" static DEFINE_MUTEX(vas_mutex); static LIST_HEAD(vas_instances); +static DEFINE_PER_CPU(int, cpu_vas_id); + static int init_vas_instance(struct platform_device *pdev) { - int rc, vasid; + int rc, cpu, vasid; struct resource *res; struct vas_instance *vinst; struct device_node *dn = pdev->dev.of_node; @@ -74,6 +77,11 @@ static int init_vas_instance(struct platform_device *pdev) "paste_win_id_shift 0x%llx\n", pdev->name, vasid, vinst->paste_base_addr, vinst->paste_win_id_shift); + for_each_possible_cpu(cpu) { + if (cpu_to_chip_id(cpu) == of_get_ibm_chip_id(dn)) + per_cpu(cpu_vas_id, cpu) = vasid; + } + mutex_lock(&vas_mutex); list_add(&vinst->node, &vas_instances); mutex_unlock(&vas_mutex); @@ -98,6 +106,10 @@ struct vas_instance *find_vas_instance(int vasid) struct vas_instance *vinst; mutex_lock(&vas_mutex); + + if (vasid == -1) + vasid = per_cpu(cpu_vas_id, smp_processor_id()); + list_for_each(ent, &vas_instances) { vinst = list_entry(ent, struct vas_instance, node); if (vinst->vas_id == vasid) { -- 2.7.4
[PATCH v2 11/18] powerpc/vas: Export HVWC to debugfs
Export the VAS Window context information to debugfs. We need to hold a mutex when closing the window to prevent a race with the debugfs read(). Rather than introduce a per-instance mutex, we use the global vas_mutex for now, since it is not heavily contended. The window->cop field is only relevant to a receive window so we were not setting it for a send window (which is is paired to a receive window anyway). But to simplify reporting in debugfs, set the 'cop' field for the send window also. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/Makefile | 3 +- arch/powerpc/platforms/powernv/vas-debug.c | 209 arch/powerpc/platforms/powernv/vas-window.c | 34 - arch/powerpc/platforms/powernv/vas.c| 6 +- arch/powerpc/platforms/powernv/vas.h| 14 ++ 5 files changed, 259 insertions(+), 7 deletions(-) create mode 100644 arch/powerpc/platforms/powernv/vas-debug.c diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 37d60f7..17921c4 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -14,4 +14,5 @@ obj-$(CONFIG_TRACEPOINTS) += opal-tracepoints.o obj-$(CONFIG_OPAL_PRD) += opal-prd.o obj-$(CONFIG_PERF_EVENTS) += opal-imc.o obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o -obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o +obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o vas-debug.o +obj-$(CONFIG_PPC_FTW) += nx-ftw.o diff --git a/arch/powerpc/platforms/powernv/vas-debug.c b/arch/powerpc/platforms/powernv/vas-debug.c new file mode 100644 index 000..ca22f1e --- /dev/null +++ b/arch/powerpc/platforms/powernv/vas-debug.c @@ -0,0 +1,209 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * 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. + */ + +#define pr_fmt(fmt) "vas: " fmt + +#include +#include +#include +#include +#include "vas.h" + +static struct dentry *vas_debugfs; + +static char *cop_to_str(int cop) +{ + switch (cop) { + case VAS_COP_TYPE_FAULT:return "Fault"; + case VAS_COP_TYPE_842: return "NX-842 Normal Priority"; + case VAS_COP_TYPE_842_HIPRI:return "NX-842 High Priority"; + case VAS_COP_TYPE_GZIP: return "NX-GZIP Normal Priority"; + case VAS_COP_TYPE_GZIP_HIPRI: return "NX-GZIP High Priority"; + case VAS_COP_TYPE_FTW: return "Fast Thread-wakeup"; + default:return "Unknown"; + } +} + +static int info_dbg_show(struct seq_file *s, void *private) +{ + struct vas_window *window = s->private; + + mutex_lock(&vas_mutex); + + /* ensure window is not unmapped */ + if (!window->hvwc_map) + goto unlock; + + seq_printf(s, "Type: %s, %s\n", cop_to_str(window->cop), + window->tx_win ? "Send" : "Receive"); + seq_printf(s, "Pid : %d\n", window->pid); + +unlock: + mutex_unlock(&vas_mutex); + return 0; +} + +static int info_dbg_open(struct inode *inode, struct file *file) +{ + return single_open(file, info_dbg_show, inode->i_private); +} + +static const struct file_operations info_fops = { + .open = info_dbg_open, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, +}; + +static inline void print_reg(struct seq_file *s, struct vas_window *win, + char *name, u32 reg) +{ + seq_printf(s, "0x%016llx %s\n", read_hvwc_reg(win, name, reg), name); +} + +static int hvwc_dbg_show(struct seq_file *s, void *private) +{ + struct vas_window *window = s->private; + + mutex_lock(&vas_mutex); + + /* ensure window is not unmapped */ + if (!window->hvwc_map) + goto unlock; + + print_reg(s, window, VREG(LPID)); + print_reg(s, window, VREG(PID)); + print_reg(s, window, VREG(XLATE_MSR)); + print_reg(s, window, VREG(XLATE_LPCR)); + print_reg(s, window, VREG(XLATE_CTL)); + print_reg(s, window, VREG(AMR)); + print_reg(s, window, VREG(SEIDR)); + print_reg(s, window, VREG(FAULT_TX_WIN)); + print_reg(s, window, VREG(OSU_INTR_SRC_RA)); + print_reg(s, window, VREG(HV_INTR_SRC_RA)); + print_reg(s, window, VREG(PSWID)); + print_reg(s, window, VREG(LFIFO_BAR)); + print_reg(s, window, VREG(LDATA_STAMP_CTL)); + print_reg(s, window, VREG(LDMA_CACHE_CTL)); + print_reg(s, window, VREG(LRFIFO_PUSH)); + print_reg(s, window, VREG(CURR_MSG_COUNT)); + print_reg(s, window, VREG(LNOTIFY_AFTER_COUNT)); + print_reg(s, window, VREG(LRX_WCRED)); + print_reg(s, window, VREG(LRX_WCRED_ADDER)); + print_reg(s, window, VR
[PATCH v2 08/18] powerpc/vas: poll for return of window credits
Normally, the NX driver waits for the CRBs to be processed before closing the window. But it is better to ensure that the credits are returned before the window gets reassigned later. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas-window.c | 45 + 1 file changed, 45 insertions(+) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index a59a187..23c13a7 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -1063,6 +1063,49 @@ int vas_paste_crb(struct vas_window *txwin, int offset, bool re) EXPORT_SYMBOL_GPL(vas_paste_crb); /* + * If credit checking is enabled for this window, poll for the return + * of window credits (i.e for NX engines to process any outstanding CRBs). + * Since NX-842 waits for the CRBs to be processed before closing the + * window, we should not have to wait for too long. + * + * TODO: We retry in 10ms intervals now. We could/should probably peek at + * the VAS_LRFIFO_PUSH_OFFSET register to get an estimate of pending + * CRBs on the FIFO and compute the delay dynamically on each retry. + * But that is not really needed until we support NX-GZIP access from + * user space. (NX-842 driver waits for CSB and Fast thread-wakeup + * doesn't use credit checking). + */ +static void poll_window_credits(struct vas_window *window) +{ + u64 val; + int creds, mode; + + val = read_hvwc_reg(window, VREG(WINCTL)); + if (window->tx_win) + mode = GET_FIELD(VAS_WINCTL_TX_WCRED_MODE, val); + else + mode = GET_FIELD(VAS_WINCTL_RX_WCRED_MODE, val); + + if (!mode) + return; +retry: + if (window->tx_win) { + val = read_hvwc_reg(window, VREG(TX_WCRED)); + creds = GET_FIELD(VAS_TX_WCRED, val); + } else { + val = read_hvwc_reg(window, VREG(LRX_WCRED)); + creds = GET_FIELD(VAS_LRX_WCRED, val); + } + + if (creds < window->wcreds_max) { + val = 0; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(msecs_to_jiffies(10)); + goto retry; + } +} + +/* * Wait for the window to go to "not-busy" state. It should only take a * short time to queue a CRB, so window should not be busy for too long. * Trying 5ms intervals. @@ -1149,6 +1192,8 @@ int vas_win_close(struct vas_window *window) unpin_close_window(window); + poll_window_credits(window); + poll_window_castout(window); /* if send window, drop reference to matching receive window */ -- 2.7.4
[PATCH v2 12/18] powerpc: have copy depend on CONFIG_BOOK3S_64
Have the COPY/PASTE instructions depend on CONFIG_BOOK3S_64 rather than CONFIG_PPC_STD_MMU_64. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/kernel/process.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index a0c74bb..37ed60b 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1215,10 +1215,14 @@ struct task_struct *__switch_to(struct task_struct *prev, batch = this_cpu_ptr(&ppc64_tlb_batch); batch->active = 1; } +#endif /* CONFIG_PPC_STD_MMU_64 */ if (current_thread_info()->task->thread.regs) { +#ifdef CONFIG_PPC_STD_MMU_64 restore_math(current_thread_info()->task->thread.regs); +#endif /* CONFIG_PPC_STD_MMU_64 */ +#ifdef CONFIG_PPC_BOOK3S_64 /* * The copy-paste buffer can only store into foreign real * addresses, so unprivileged processes can not see the @@ -1237,8 +1241,8 @@ struct task_struct *__switch_to(struct task_struct *prev, asm volatile(PPC_COPY(%0, %1) : : "r"(dummy_copy_buffer), "r"(0)); } +#endif /* CONFIG_PPC_BOOK3S_64 */ } -#endif /* CONFIG_PPC_STD_MMU_64 */ return last; } -- 2.7.4
[PATCH v2 10/18] powerpc/vas, nx-842: Define and use chip_to_vas_id()
Define a helper, chip_to_vas_id() to map a given chip id to corresponding vas id. Normally, callers of vas_rx_win_open() and vas_tx_win_open() want the VAS window to be on the same chip where the calling thread is executing. These callers can pass in -1 for the VAS id. This interface will be useful if a thread running on one chip wants to open a window on another chip (like the NX-842 driver does during start up). Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/include/asm/vas.h | 9 + arch/powerpc/platforms/powernv/vas.c | 11 +++ drivers/crypto/nx/nx-842-powernv.c | 18 +++--- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h index fd5963a..044748f 100644 --- a/arch/powerpc/include/asm/vas.h +++ b/arch/powerpc/include/asm/vas.h @@ -104,6 +104,15 @@ struct vas_tx_win_attr { }; /* + * Helper to map a chip id to VAS id. + * For POWER9, this is a 1:1 mapping. In the future this maybe a 1:N + * mapping in which case, we will need to update this helper. + * + * Return the VAS id or -1 if no matching vasid is found. + */ +int chip_to_vas_id(int chipid); + +/* * Helper to initialize receive window attributes to defaults for an * NX window. */ diff --git a/arch/powerpc/platforms/powernv/vas.c b/arch/powerpc/platforms/powernv/vas.c index abb7090..cd9a733 100644 --- a/arch/powerpc/platforms/powernv/vas.c +++ b/arch/powerpc/platforms/powernv/vas.c @@ -123,6 +123,17 @@ struct vas_instance *find_vas_instance(int vasid) return NULL; } +int chip_to_vas_id(int chipid) +{ + int cpu; + + for_each_possible_cpu(cpu) { + if (cpu_to_chip_id(cpu) == chipid) + return per_cpu(cpu_vas_id, cpu); + } + return -1; +} + static int vas_probe(struct platform_device *pdev) { return init_vas_instance(pdev); diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c index 874ddf5..eb221ed 100644 --- a/drivers/crypto/nx/nx-842-powernv.c +++ b/drivers/crypto/nx/nx-842-powernv.c @@ -847,24 +847,12 @@ static int __init nx842_powernv_probe_vas(struct device_node *pn) return -EINVAL; } - for_each_compatible_node(dn, NULL, "ibm,power9-vas-x") { - if (of_get_ibm_chip_id(dn) == chip_id) - break; - } - - if (!dn) { - pr_err("Missing VAS device node\n"); + vasid = chip_to_vas_id(chip_id); + if (vasid < 0) { + pr_err("Unable to map chip_id %d to vasid\n", chip_id); return -EINVAL; } - if (of_property_read_u32(dn, "ibm,vas-id", &vasid)) { - pr_err("Missing ibm,vas-id device property\n"); - of_node_put(dn); - return -EINVAL; - } - - of_node_put(dn); - for_each_child_of_node(pn, dn) { if (of_device_is_compatible(dn, "ibm,p9-nx-842")) { ret = vas_cfg_coproc_info(dn, chip_id, vasid); -- 2.7.4
[PATCH v2 13/18] powerpc: Add support for setting SPRN_TIDR
We need the SPRN_TIDR to be set for use with fast thread-wakeup (core- to-core wakeup) and also with CAPI. Each thread in a process needs to have a unique id within the process. But as explained below, for now, we assign globally unique thread ids to all threads in the system. Signed-off-by: Sukadev Bhattiprolu Signed-off-by: Philippe Bergheaud Signed-off-by: Christophe Lombard --- Changelog[v3] - Merge changes with and address comments to Christophe's patch. (i.e drop CONFIG_PPC_VAS; use CONFIG_PPC64; check CPU_ARCH_300 before setting TIDR). Defer following to separate patches: - emulation parts of Christophe's patch, - setting TIDR for tasks other than 'current' - setting feature bit in AT_HWCAP2 Changelog[v2] - Michael Ellerman: Use an interface to assign TIDR so it is assigned to only threads that need it; move assignment to restore_sprs(). Drop lint from rebase; --- arch/powerpc/include/asm/processor.h | 1 + arch/powerpc/include/asm/switch_to.h | 3 + arch/powerpc/kernel/process.c| 122 +++ 3 files changed, 126 insertions(+) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index fab7ff8..58cc212 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -329,6 +329,7 @@ struct thread_struct { */ int dscr_inherit; unsigned long ppr;/* used to save/restore SMT priority */ + unsigned long tidr; #endif #ifdef CONFIG_PPC_BOOK3S_64 unsigned long tar; diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 17c8380..f5da32f 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -91,4 +91,7 @@ static inline void clear_task_ebb(struct task_struct *t) #endif } +extern int set_thread_tidr(struct task_struct *t); +extern void clear_thread_tidr(struct task_struct *t); + #endif /* _ASM_POWERPC_SWITCH_TO_H */ diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 37ed60b..d861fcd 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1120,6 +1120,13 @@ static inline void restore_sprs(struct thread_struct *old_thread, mtspr(SPRN_TAR, new_thread->tar); } #endif +#ifdef CONFIG_PPC64 + if (old_thread->tidr != new_thread->tidr) { + /* TIDR should be non-zero only with ISA3.0. */ + WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_ARCH_300)); + mtspr(SPRN_TIDR, new_thread->tidr); + } +#endif } #ifdef CONFIG_PPC_BOOK3S_64 @@ -1438,9 +1445,117 @@ void flush_thread(void) #endif /* CONFIG_HAVE_HW_BREAKPOINT */ } +#ifdef CONFIG_PPC64 +static DEFINE_SPINLOCK(vas_thread_id_lock); +static DEFINE_IDA(vas_thread_ida); + +/* + * We need to assign a unique thread id to each thread in a process. + * + * This thread id, referred to as TIDR, and separate from the Linux's tgid, + * is intended to be used to direct an ASB_Notify from the hardware to the + * thread, when a suitable event occurs in the system. + * + * One such event is a "paste" instruction in the context of Fast Thread + * Wakeup (aka Core-to-core wake up in the Virtual Accelerator Switchboard + * (VAS) in POWER9. + * + * To get a unique TIDR per process we could simply reuse task_pid_nr() but + * the problem is that task_pid_nr() is not yet available copy_thread() is + * called. Fixing that would require changing more intrusive arch-neutral + * code in code path in copy_process()?. + * + * Further, to assign unique TIDRs within each process, we need an atomic + * field (or an IDR) in task_struct, which again intrudes into the arch- + * neutral code. So try to assign globally unique TIDRs for now. + * + * NOTE: TIDR 0 indicates that the thread does not need a TIDR value. + * For now, only threads that expect to be notified by the VAS + * hardware need a TIDR value and we assign values > 0 for those. + */ +#define MAX_THREAD_CONTEXT ((1 << 16) - 1) +static int assign_thread_tidr(void) +{ + int index; + int err; + +again: + if (!ida_pre_get(&vas_thread_ida, GFP_KERNEL)) + return -ENOMEM; + + spin_lock(&vas_thread_id_lock); + err = ida_get_new_above(&vas_thread_ida, 1, &index); + spin_unlock(&vas_thread_id_lock); + + if (err == -EAGAIN) + goto again; + else if (err) + return err; + + if (index > MAX_THREAD_CONTEXT) { + spin_lock(&vas_thread_id_lock); + ida_remove(&vas_thread_ida, index); + spin_unlock(&vas_thread_id_lock); + return -ENOMEM; + } + + return index; +} + +static void free_thread_tidr(int id) +{ + spin_lock(&vas_thread_id_lock); + ida_remove(&vas_thread_ida, id);
[PATCH v2 17/18] powerpc/vas: Define vas_win_id()
Define an interface to return a system-wide unique id for a given VAS window. The vas_win_id() will be used in a follow-on patch to generate an unique handle for a user space receive window. Applications can use this handle to pair send and receive windows for fast thread-wakeup. The hardware refers to this system-wide unique id as a Partition Send Window ID which is expected to be used during fault handling. Hence the "pswid" in the function names. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/include/asm/vas.h | 5 + arch/powerpc/platforms/powernv/vas-window.c | 9 + arch/powerpc/platforms/powernv/vas.h| 28 3 files changed, 42 insertions(+) diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h index f98ade8..7714562 100644 --- a/arch/powerpc/include/asm/vas.h +++ b/arch/powerpc/include/asm/vas.h @@ -168,6 +168,11 @@ int vas_copy_crb(void *crb, int offset); int vas_paste_crb(struct vas_window *win, int offset, bool re); /* + * Return a system-wide unique id for the VAS window @win. + */ +extern u32 vas_win_id(struct vas_window *win); + +/* * Return the power bus paste address associated with @win so the caller * can map that address into their address space. */ diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index e4a9c7b..1d08b64 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -1239,3 +1239,12 @@ int vas_win_close(struct vas_window *window) return 0; } EXPORT_SYMBOL_GPL(vas_win_close); + +/* + * Return a system-wide unique window id for the window @win. + */ +u32 vas_win_id(struct vas_window *win) +{ + return encode_pswid(win->vinst->vas_id, win->winid); +} +EXPORT_SYMBOL_GPL(vas_win_id); diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h index 145749a..78a8926 100644 --- a/arch/powerpc/platforms/powernv/vas.h +++ b/arch/powerpc/platforms/powernv/vas.h @@ -447,4 +447,32 @@ static inline u64 read_hvwc_reg(struct vas_window *win, return in_be64(win->hvwc_map+reg); } +/* + * Encode/decode the Partition Send Window ID (PSWID) for a window in + * a way that we can uniquely identify any window in the system. i.e. + * we should be able to locate the 'struct vas_window' given the PSWID. + * + * BitsUsage + * 0:7 VAS id (8 bits) + * 8:15Unused, 0 (3 bits) + * 16:31 Window id (16 bits) + */ +static inline u32 encode_pswid(int vasid, int winid) +{ + u32 pswid = 0; + + pswid |= vasid << (31 - 7); + pswid |= winid; + + return pswid; +} + +static inline void decode_pswid(u32 pswid, int *vasid, int *winid) +{ + if (vasid) + *vasid = pswid >> (31 - 7) & 0xFF; + + if (winid) + *winid = pswid & 0x; +} #endif /* _VAS_H */ -- 2.7.4
[PATCH v2 18/18] powerpc/vas: Add support for user receive window
Add support for user space receive window (for the Fast thread-wakeup coprocessor type) Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas-window.c | 59 + 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 1d08b64..99642ec 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -16,7 +16,8 @@ #include #include #include - +#include +#include #include "vas.h" #include "copy-paste.h" @@ -602,6 +603,32 @@ static void put_rx_win(struct vas_window *rxwin) } /* + * Find the user space receive window given the @pswid. + * - We must have a valid vasid and it must belong to this instance. + *(so both send and receive windows are on the same VAS instance) + * - The window must refer to an OPEN, FTW, RECEIVE window. + * + * NOTE: We access ->windows[] table and assume that vinst->mutex is held. + */ +static struct vas_window *get_user_rxwin(struct vas_instance *vinst, u32 pswid) +{ + int vasid, winid; + struct vas_window *rxwin; + + decode_pswid(pswid, &vasid, &winid); + + if (vinst->vas_id != vasid) + return ERR_PTR(-EINVAL); + + rxwin = vinst->windows[winid]; + + if (!rxwin || rxwin->tx_win || rxwin->cop != VAS_COP_TYPE_FTW) + return ERR_PTR(-EINVAL); + + return rxwin; +} + +/* * Get the VAS receive window associated with NX engine identified * by @cop and if applicable, @pswid. * @@ -614,10 +641,10 @@ static struct vas_window *get_vinst_rxwin(struct vas_instance *vinst, mutex_lock(&vinst->mutex); - if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) - rxwin = vinst->rxwin[cop] ?: ERR_PTR(-EINVAL); + if (cop == VAS_COP_TYPE_FTW) + rxwin = get_user_rxwin(vinst, pswid); else - rxwin = ERR_PTR(-EINVAL); + rxwin = vinst->rxwin[cop] ?: ERR_PTR(-EINVAL); if (!IS_ERR(rxwin)) atomic_inc(&rxwin->num_txwins); @@ -941,10 +968,9 @@ static void init_winctx_for_txwin(struct vas_window *txwin, winctx->tx_word_mode = txattr->tx_win_ord_mode; winctx->rsvd_txbuf_count = txattr->rsvd_txbuf_count; - if (winctx->nx_win) { + winctx->intr_disable = true; + if (winctx->nx_win) winctx->data_stamp = true; - winctx->intr_disable = true; - } winctx->lpid = txattr->lpid; winctx->pidr = txattr->pidr; @@ -989,6 +1015,14 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, if (!tx_win_args_valid(cop, attr)) return ERR_PTR(-EINVAL); + /* +* If caller did not specify a vasid but specified the PSWID of a +* receive window (applicable only to FTW windows), use the vasid +* from that receive window. +*/ + if (vasid == -1 && attr->pswid) + decode_pswid(attr->pswid, &vasid, NULL); + vinst = find_vas_instance(vasid); if (!vinst) { pr_devel("vasid %d not found!\n", vasid); @@ -1037,6 +1071,17 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, set_vinst_win(vinst, txwin); + set_thread_used_vas(); + + /* +* Even a process that has no foreign real address mapping can use +* an unpaired COPY instruction (to no real effect). Issue CP_ABORT +* to clear any pending COPY and prevent a covert channel. +* +* __switch_to() will issue CP_ABORT on future context switches. +*/ + asm volatile(PPC_CP_ABORT); + return txwin; free_window: -- 2.7.4
[PATCH v2 14/18] powerpc: Define set_thread_used_vas()
A CP_ABORT instruction is required in processes that have mapped a VAS "paste address" with the intention of using COPY/PASTE instructions. But since CP_ABORT is expensive, we want to restrict it to only processes that use/intend to use COPY/PASTE. Define an interface, set_thread_used_vas(), that VAS can use to indicate that the current process opened a send window. During context switch, issue CP_ABORT only for processes that have the flag set. Thanks for input from Nick Piggin, Michael Ellerman. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/include/asm/processor.h | 2 ++ arch/powerpc/include/asm/switch_to.h | 2 ++ arch/powerpc/kernel/process.c| 32 ++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 58cc212..bdab3b74 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -341,7 +341,9 @@ struct thread_struct { unsigned long sier; unsigned long mmcr2; unsignedmmcr0; + unsignedused_ebb; + unsigned intused_vas; #endif }; diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index f5da32f..aeb305b 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -91,6 +91,8 @@ static inline void clear_task_ebb(struct task_struct *t) #endif } +extern int set_thread_used_vas(void); + extern int set_thread_tidr(struct task_struct *t); extern void clear_thread_tidr(struct task_struct *t); diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index d861fcd..cb5f108 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1234,17 +1234,17 @@ struct task_struct *__switch_to(struct task_struct *prev, * The copy-paste buffer can only store into foreign real * addresses, so unprivileged processes can not see the * data or use it in any way unless they have foreign real -* mappings. We don't have a VAS driver that allocates those -* yet, so no cpabort is required. +* mappings. If the new process has the foreign real address +* mappings, we must issue a cp_abort to clear any state and +* prevent a covert channel being setup. +* +* DD1 allows paste into normal system memory so we do an +* unpaired copy, rather than cp_abort, to clear the buffer, +* since cp_abort is quite expensive. */ - if (cpu_has_feature(CPU_FTR_POWER9_DD1)) { - /* -* DD1 allows paste into normal system memory, so we -* do an unpaired copy here to clear the buffer and -* prevent a covert channel being set up. -* -* cpabort is not used because it is quite expensive. -*/ + if (new_thread->used_vas) { + asm volatile(PPC_CP_ABORT); + } else if (cpu_has_feature(CPU_FTR_POWER9_DD1)) { asm volatile(PPC_COPY(%0, %1) : : "r"(dummy_copy_buffer), "r"(0)); } @@ -1445,6 +1445,18 @@ void flush_thread(void) #endif /* CONFIG_HAVE_HW_BREAKPOINT */ } +int set_thread_used_vas(void) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + return -EINVAL; + + current->thread.used_vas = 1; + +#endif /* CONFIG_PPC_BOOK3S_64 */ + return 0; +} + #ifdef CONFIG_PPC64 static DEFINE_SPINLOCK(vas_thread_id_lock); static DEFINE_IDA(vas_thread_ida); -- 2.7.4
[PATCH v2 16/18] powerpc/vas: Define vas_win_paste_addr()
Define an interface that the NX drivers can use to find the physical paste address of a send window. This interface is expected to be used with the mmap() operation of the NX driver's device. i.e the user space process can use driver's mmap() operation to map the send window's paste address into their address space and then use copy and paste instructions to submit the CRBs to the NX engine. Note that kernel drivers will use vas_paste_crb() directly and don't need this interface. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/include/asm/vas.h | 7 +++ arch/powerpc/platforms/powernv/vas-window.c | 10 ++ 2 files changed, 17 insertions(+) diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h index 044748f..f98ade8 100644 --- a/arch/powerpc/include/asm/vas.h +++ b/arch/powerpc/include/asm/vas.h @@ -10,6 +10,8 @@ #ifndef _ASM_POWERPC_VAS_H #define _ASM_POWERPC_VAS_H +struct vas_window; + /* * Min and max FIFO sizes are based on Version 1.05 Section 3.1.4.25 * (Local FIFO Size Register) of the VAS workbook. @@ -165,4 +167,9 @@ int vas_copy_crb(void *crb, int offset); */ int vas_paste_crb(struct vas_window *win, int offset, bool re); +/* + * Return the power bus paste address associated with @win so the caller + * can map that address into their address space. + */ +extern u64 vas_win_paste_addr(struct vas_window *win); #endif /* __ASM_POWERPC_VAS_H */ diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 088ce56..e4a9c7b 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -40,6 +40,16 @@ static void compute_paste_address(struct vas_window *window, u64 *addr, int *len pr_debug("Txwin #%d: Paste addr 0x%llx\n", winid, *addr); } +u64 vas_win_paste_addr(struct vas_window *win) +{ + u64 addr; + + compute_paste_address(win, &addr, NULL); + + return addr; +} +EXPORT_SYMBOL(vas_win_paste_addr); + static inline void get_hvwc_mmio_bar(struct vas_window *window, u64 *start, int *len) { -- 2.7.4
[PATCH v2 00/18] powerpc/vas: Add support for FTW
The first 10 patches in this set were posted earlier[1] and don't have any significant changes since then. This set sanitizes cpu/chip id to VAS id mapping, improves vas_win_close() performance and adds a check for return of credits and cleans up some code. Patch 11 adds debugfs support for the VAS window contexts. Patches 11-18 add support for user space aka Fast thread-wakeup windows in VAS. These include a patch from Michael Neuling to support emulating the paste instruction. Michael Neuling (1): powerpc: Emulate paste instruction Sukadev Bhattiprolu (17): powerpc/vas: init missing fields from [rt]xattr powerpc/vas: Validate window credits powerpc/vas: Cleanup some debug code powerpc/vas: Drop poll_window_cast_out(). powerpc/vas: Use helper to unpin/close window powerpc/vas: Reduce polling interval for busy state powerpc/vas: Save configured window credits powerpc/vas: poll for return of window credits powerpc/vas: Create cpu to vas id mapping powerpc/vas, nx-842: Define and use chip_to_vas_id() powerpc/vas: Export HVWC to debugfs powerpc: have copy depend on CONFIG_BOOK3S_64 powerpc: Add support for setting SPRN_TIDR powerpc: Define set_thread_used_vas() powerpc/vas: Define vas_win_paste_addr() powerpc/vas: Define vas_win_id() powerpc/vas: Add support for user receive window arch/powerpc/include/asm/emulated_ops.h | 1 + arch/powerpc/include/asm/ppc-opcode.h | 1 + arch/powerpc/include/asm/processor.h| 3 + arch/powerpc/include/asm/reg.h | 2 + arch/powerpc/include/asm/switch_to.h| 5 + arch/powerpc/include/asm/vas.h | 21 +++ arch/powerpc/kernel/process.c | 160 -- arch/powerpc/kernel/traps.c | 64 arch/powerpc/platforms/powernv/Makefile | 3 +- arch/powerpc/platforms/powernv/vas-debug.c | 209 arch/powerpc/platforms/powernv/vas-window.c | 245 +++- arch/powerpc/platforms/powernv/vas.c| 31 +++- arch/powerpc/platforms/powernv/vas.h| 95 ++- drivers/crypto/nx/nx-842-powernv.c | 18 +- 14 files changed, 745 insertions(+), 113 deletions(-) create mode 100644 arch/powerpc/platforms/powernv/vas-debug.c -- 2.7.4
Re: [PATCH] ext2/super: Fix a possible sleep-in-atomic bug in parse_options
On Sat, Oct 07, 2017 at 03:02:17AM +0100, Al Viro wrote: > > I do wonder if we shouldn't just use something like > > > > "skip leading zeroes, copy to size-limited stack location instead" > > > > because the input length really *is* limited once you skip leading > > zeroes (and whatever base marker we have). We might have at most a > > 64-bit value in octal, so 22 bytes max. > > > > But I guess just changing the two GFP_KERNEL's to GFP_ATOMIC is much > > simpler. > > There's match_strdup() as well... > > FWIW, ext2 side also looks fishy; it might be cleaner if we > collected new state into some object and applied it only after the last > possible failure exit. The entire "restore the original state" logics > would go away... I'm not saying that the bug had been introduced by conversion to spinlock, BTW - it was racy back when ext2_remount() relied upon BKL. I hadn't considered the atomicity issues back then - mea culpa...
[PATCH v2 15/18] powerpc: Emulate paste instruction
From: Michael Neuling On POWER9 DD2.1 and below there are issues when the paste instruction generates an error. If an error occurs when thread reconfiguration happens (ie another thread in the core goes into/out of powersave) the core may hang. To avoid this a special sequence is required which stops thread configuration so that the paste can be safely executed. This patch assumes paste executed in userspace are trapped into the illegal instruction exception at 0xe40. Here we re-execute the paste instruction but with the required sequence to ensure thread reconfiguration doesn't occur. Signed-off-by: Michael Neuling Signed-off-by: Sukadev Bhattiprolu --- Edit by Sukadev: Use PPC_PASTE() rather than the paste instruction since in older versions the instruction required a third parameter. --- arch/powerpc/include/asm/emulated_ops.h | 1 + arch/powerpc/include/asm/ppc-opcode.h | 1 + arch/powerpc/include/asm/reg.h | 2 ++ arch/powerpc/kernel/traps.c | 64 + 4 files changed, 68 insertions(+) diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h index f00e10e..9247af9 100644 --- a/arch/powerpc/include/asm/emulated_ops.h +++ b/arch/powerpc/include/asm/emulated_ops.h @@ -55,6 +55,7 @@ extern struct ppc_emulated { struct ppc_emulated_entry mfdscr; struct ppc_emulated_entry mtdscr; struct ppc_emulated_entry lq_stq; + struct ppc_emulated_entry paste; #endif } ppc_emulated; diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index ce0930d..a55d2ef 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -229,6 +229,7 @@ #define PPC_INST_MTTMR 0x7c0003dc #define PPC_INST_NOP 0x6000 #define PPC_INST_PASTE 0x7c20070d +#define PPC_INST_PASTE_MASK0xfc2007ff #define PPC_INST_POPCNTB 0x7cf4 #define PPC_INST_POPCNTB_MASK 0xfc0007fe #define PPC_INST_POPCNTD 0x7c0003f4 diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index f92eaf7..5cde1c4 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -468,6 +468,8 @@ #define SPRN_DBAT7U0x23E /* Data BAT 7 Upper Register */ #define SPRN_PPR 0x380 /* SMT Thread status Register */ #define SPRN_TSCR 0x399 /* Thread Switch Control Register */ +#define SPRN_TRIG1 0x371 /* WAT Trigger 1 */ +#define SPRN_TRIG2 0x372 /* WAT Trigger 2 */ #define SPRN_DEC 0x016 /* Decrement Register */ #define SPRN_DER 0x095 /* Debug Enable Register */ diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 13c9dcd..7e6b1fe 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -956,6 +956,65 @@ static inline bool tm_abort_check(struct pt_regs *regs, int reason) } #endif +static DEFINE_SPINLOCK(paste_emulation_lock); + +static inline int paste(void *i) +{ + int cr; + long retval = 0; + + /* Need per core lock to ensure trig1/2 writes don't race */ + spin_lock(&paste_emulation_lock); + mtspr(SPRN_TRIG1, 0); /* data doesn't matter */ + mtspr(SPRN_TRIG1, 0); /* HW says do this twice */ + asm volatile( + "1: " PPC_PASTE(0, %2) "\n" + "2: mfcr %1\n" + ".section .fixup,\"ax\"\n" + "3: li %0,%3\n" + " li %2,0\n" + " b 2b\n" + ".previous\n" + EX_TABLE(1b, 3b) + : "=r" (retval), "=r" (cr) + : "b" (i), "i" (-EFAULT), "0" (retval)); + mtspr(SPRN_TRIG2, 0); + spin_unlock(&paste_emulation_lock); + return cr; +} + +static int emulate_paste(struct pt_regs *regs, u32 instword) +{ + const void __user *addr; + unsigned long ea; + u8 ra, rb; + + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + return -EINVAL; + + ra = (instword >> 16) & 0x1f; + rb = (instword >> 11) & 0x1f; + + ea = regs->gpr[rb] + (ra ? regs->gpr[ra] : 0ul); + if (is_32bit_task()) + ea &= 0xul; + addr = (__force const void __user *)ea; + + if (!access_ok(VERIFY_WRITE, addr, 128)) // cacheline size == 128 + return -EFAULT; + + hard_irq_disable(); /* FIXME: could we just soft disable ?? */ + pagefault_disable(); + + PPC_WARN_EMULATED(paste, regs); + regs->ccr = paste((void *)addr); + + pagefault_enable(); + may_hard_irq_enable(); + + return 0; +} + static int emulate_instruction(struct pt_regs *regs) { u32 instword; @@ -968,6 +1027,10 @@ static int emulate_instruction(struct pt_regs *regs) if (get_user(instword, (u32 __user *)(regs->nip))) return -EFAULT; +
[PATCH v2 04/18] powerpc/vas: Drop poll_window_cast_out().
Polling for window cast out is listed in the spec, but turns out that it is not strictly necessary and slows down window close. Making it a stub for now. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas-window.c | 34 ++--- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 67ffc5d..8ab8a82 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -1079,25 +1079,25 @@ static void poll_window_busy_state(struct vas_window *window) } } +/* + * Have the hardware cast a window out of cache and wait for it to + * be completed. + * + * NOTE: It can take a relatively long time to cast the window context + * out of the cache. It is not strictly necessary to cast out if: + * + * - we clear the "Pin Window" bit (so hardware is free to evict) + * + * - we re-initialize the window context when it is reassigned. + * + * We do the former in vas_win_close() and latter in vas_win_open(). + * So, ignoring the cast-out for now. We can add it as needed. If + * casting out becomes necessary we should consider offloading the + * job to a worker thread, so the window close can proceed quickly. + */ static void poll_window_castout(struct vas_window *window) { - int cached; - u64 val; - - /* Cast window context out of the cache */ -retry: - val = read_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL)); - cached = GET_FIELD(VAS_WIN_CACHE_STATUS, val); - if (cached) { - val = 0ULL; - val = SET_FIELD(VAS_CASTOUT_REQ, val, 1); - val = SET_FIELD(VAS_PUSH_TO_MEM, val, 0); - write_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL), val); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); - goto retry; - } + /* stub for now */ } /* -- 2.7.4
[PATCH v2 03/18] powerpc/vas: Cleanup some debug code
Clean up vas.h and the debug code around ifdef vas_debug. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/platforms/powernv/vas-window.c | 8 +++-- arch/powerpc/platforms/powernv/vas.h| 56 +++-- 2 files changed, 18 insertions(+), 46 deletions(-) diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index a2fe120..67ffc5d 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -726,7 +726,10 @@ static void init_winctx_for_rxwin(struct vas_window *rxwin, static bool rx_win_args_valid(enum vas_cop_type cop, struct vas_rx_win_attr *attr) { - dump_rx_win_attr(attr); + pr_debug("Rxattr: fault %d, notify %d, intr %d, early %d, fifo %d\n", + attr->fault_win, attr->notify_disable, + attr->intr_disable, attr->notify_early, + attr->rx_fifo_size); if (cop >= VAS_COP_TYPE_MAX) return false; @@ -1050,7 +1053,8 @@ int vas_paste_crb(struct vas_window *txwin, int offset, bool re) else rc = -EINVAL; - print_fifo_msg_count(txwin); + pr_debug("Txwin #%d: Msg count %llu\n", txwin->winid, + read_hvwc_reg(txwin, VREG(LRFIFO_PUSH))); return rc; } diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h index fea0de4..15d2dfa 100644 --- a/arch/powerpc/platforms/powernv/vas.h +++ b/arch/powerpc/platforms/powernv/vas.h @@ -259,6 +259,16 @@ #define VAS_NX_UTIL_ADDER PPC_BITMASK(32, 63) /* + * VREG(x): + * Expand a register's short name (eg: LPID) into two parameters: + * - the register's short name in string form ("LPID"), and + * - the name of the macro (eg: VAS_LPID_OFFSET), defining the + * register's offset in the window context + */ +#define VREG_SFX(n, s) __stringify(n), VAS_##n##s +#define VREG(r)VREG_SFX(r, _OFFSET) + +/* * Local Notify Scope Control Register. (Receive windows only). */ enum vas_notify_scope { @@ -385,43 +395,15 @@ struct vas_winctx { extern struct vas_instance *find_vas_instance(int vasid); -/* - * VREG(x): - * Expand a register's short name (eg: LPID) into two parameters: - * - the register's short name in string form ("LPID"), and - * - the name of the macro (eg: VAS_LPID_OFFSET), defining the - * register's offset in the window context - */ -#define VREG_SFX(n, s) __stringify(n), VAS_##n##s -#define VREG(r)VREG_SFX(r, _OFFSET) - -#ifdef vas_debug -static inline void dump_rx_win_attr(struct vas_rx_win_attr *attr) -{ - pr_err("fault %d, notify %d, intr %d early %d\n", - attr->fault_win, attr->notify_disable, - attr->intr_disable, attr->notify_early); - - pr_err("rx_fifo_size %d, max value %d\n", - attr->rx_fifo_size, VAS_RX_FIFO_SIZE_MAX); -} - static inline void vas_log_write(struct vas_window *win, char *name, void *regptr, u64 val) { - if (val) - pr_err("%swin #%d: %s reg %p, val 0x%016llx\n", + if (!val) + pr_debug("%swin #%d: %s reg %p, val 0x%016llx\n", win->tx_win ? "Tx" : "Rx", win->winid, name, regptr, val); } -#else /* vas_debug */ - -#define vas_log_write(win, name, reg, val) -#define dump_rx_win_attr(attr) - -#endif /* vas_debug */ - static inline void write_uwc_reg(struct vas_window *win, char *name, s32 reg, u64 val) { @@ -450,18 +432,4 @@ static inline u64 read_hvwc_reg(struct vas_window *win, return in_be64(win->hvwc_map+reg); } -#ifdef vas_debug - -static void print_fifo_msg_count(struct vas_window *txwin) -{ - uint64_t read_hvwc_reg(struct vas_window *w, char *n, uint64_t o); - pr_devel("Winid %d, Msg count %llu\n", txwin->winid, - (uint64_t)read_hvwc_reg(txwin, VREG(LRFIFO_PUSH))); -} -#else /* vas_debug */ - -#define print_fifo_msg_count(window) - -#endif /* vas_debug */ - #endif /* _VAS_H */ -- 2.7.4
Re: [BUG] fs/dlm: A possible sleep-in-atomic bug in dlm_master_lookup
On Sat, Oct 07, 2017 at 09:59:41AM +0800, Jia-Ju Bai wrote: > According to fs/dlm/lock.c, the kernel may sleep under a spinlock, > and the function call path is: > dlm_master_lookup (acquire the spinlock) > dlm_send_rcom_lookup_dump > create_rcom > dlm_lowcomms_get_buffer > nodeid2con > mutex_lock --> may sleep > > This bug is found by my static analysis tool and my code review. Umm... dlm_master_lookup() locking is not nice, but to trigger that you would need a combination of * from_nodeid != our_nodeid (or we would've buggered off long before that point) * dir_nodeid == our_nodeid * failing dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r) (success would have the lock dropped) * succeeding dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r) * from_master being true * r->res_master_nodeid != from_nodeid and r->res_master_nodeid == our_nodeid (the former is follows from the latter, actually) The last one might or might not be impossible - I'm not familiar with dlm guts, but it does have log_error(ls, "from_master %d our_master", from_nodeid); just before that call, so it's worth a further look.
Re: [PATCH v3 03/22] dt-bindings: arm: scmi: add ARM MHU specific mailbox client bindings
On Fri, Oct 6, 2017 at 9:24 PM, Rob Herring wrote: > On Fri, Oct 6, 2017 at 6:01 AM, Jassi Brar wrote: >> On Fri, Oct 6, 2017 at 4:50 AM, Rob Herring wrote: >>> On Thu, Sep 28, 2017 at 02:11:27PM +0100, Sudeep Holla wrote: >>> +- mbox-data : For each phandle listed in mboxes property, an unsigned 32-bit + data as expected by the mailbox controller >>> >>> Shouldn't that be cells as part of mboxes property? >>> >> A MHU client can send any number of commands (such u32 values) over a >> channel. >> This client (SCMI) sends just one command over a channel, but other >> clients may/do send two or more. > > Okay, then I guess I don't understand why this is in DT. > Yeah the client has to provide code (u32 value) for the commands it sends, and that value is going to be platform specific. For example, on Juno the ITS_AN_SCMI_COMMAND may be defined as BIT(7) while on my platform it may be 0x4567 For MHU based platforms, it becomes easy if the u32 is passed from DT. And that should be ok since that is like a h/w parameter - a value chosen/expected by the remote firmware. thnx
Re: [PATCH 1/2] Revert "vmalloc: back off when the current task is killed"
On 2017/10/05 19:36, Tetsuo Handa wrote: > I don't want this patch backported. If you want to backport, > "s/fatal_signal_pending/tsk_is_oom_victim/" is the safer way. If you backport this patch, you will see "complete depletion of memory reserves" and "extra OOM kills due to depletion of memory reserves" using below reproducer. -- #include #include #include static char *buffer; static int __init test_init(void) { set_current_oom_origin(); buffer = vmalloc((1UL << 32) - 480 * 1048576); clear_current_oom_origin(); return buffer ? 0 : -ENOMEM; } static void test_exit(void) { vfree(buffer); } module_init(test_init); module_exit(test_exit); MODULE_LICENSE("GPL"); -- -- CentOS Linux 7 (Core) Kernel 4.13.5+ on an x86_64 ccsecurity login: [ 53.637666] test: loading out-of-tree module taints kernel. [ 53.856166] insmod invoked oom-killer: gfp_mask=0x14002c2(GFP_KERNEL|__GFP_HIGHMEM|__GFP_NOWARN), nodemask=(null), order=0, oom_score_adj=0 [ 53.858754] insmod cpuset=/ mems_allowed=0 [ 53.859713] CPU: 1 PID: 2763 Comm: insmod Tainted: G O4.13.5+ #10 [ 53.861134] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015 [ 53.863072] Call Trace: [ 53.863548] dump_stack+0x4d/0x6f [ 53.864172] dump_header+0x92/0x22a [ 53.864869] ? has_ns_capability_noaudit+0x30/0x40 [ 53.865887] oom_kill_process+0x250/0x440 [ 53.866644] out_of_memory+0x10d/0x480 [ 53.867343] __alloc_pages_nodemask+0x1087/0x1140 [ 53.868216] alloc_pages_current+0x65/0xd0 [ 53.869086] __vmalloc_node_range+0x129/0x230 [ 53.869895] vmalloc+0x39/0x40 [ 53.870472] ? test_init+0x26/0x1000 [test] [ 53.871248] test_init+0x26/0x1000 [test] [ 53.871993] ? 0xa00fa000 [ 53.872609] do_one_initcall+0x4d/0x190 [ 53.873301] do_init_module+0x5a/0x1f7 [ 53.873999] load_module+0x2022/0x2960 [ 53.874678] ? vfs_read+0x116/0x130 [ 53.875312] SyS_finit_module+0xe1/0xf0 [ 53.876074] ? SyS_finit_module+0xe1/0xf0 [ 53.876806] do_syscall_64+0x5c/0x140 [ 53.877488] entry_SYSCALL64_slow_path+0x25/0x25 [ 53.878316] RIP: 0033:0x7f1b27c877f9 [ 53.878964] RSP: 002b:7552e718 EFLAGS: 0206 ORIG_RAX: 0139 [ 53.880620] RAX: ffda RBX: 00a2d210 RCX: 7f1b27c877f9 [ 53.881883] RDX: RSI: 0041a678 RDI: 0003 [ 53.883167] RBP: 0041a678 R08: R09: 7552e8b8 [ 53.884685] R10: 0003 R11: 0206 R12: [ 53.885949] R13: 00a2d1e0 R14: R15: [ 53.887392] Mem-Info: [ 53.887909] active_anon:14248 inactive_anon:2088 isolated_anon:0 [ 53.887909] active_file:4 inactive_file:2 isolated_file:2 [ 53.887909] unevictable:0 dirty:3 writeback:2 unstable:0 [ 53.887909] slab_reclaimable:2818 slab_unreclaimable:4420 [ 53.887909] mapped:453 shmem:2162 pagetables:1676 bounce:0 [ 53.887909] free:21418 free_pcp:0 free_cma:0 [ 53.895172] Node 0 active_anon:56992kB inactive_anon:8352kB active_file:12kB inactive_file:12kB unevictable:0kB isolated(anon):0kB isolated(file):8kB mapped:1812kB dirty:12kB writeback:8kB shmem:8648kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 6144kB writeback_tmp:0kB unstable:0kB all_unreclaimable? no [ 53.901844] Node 0 DMA free:14932kB min:284kB low:352kB high:420kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB present:15988kB managed:15904kB mlocked:0kB kernel_stack:0kB pagetables:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB [ 53.907765] lowmem_reserve[]: 0 2703 3662 3662 [ 53.909333] Node 0 DMA32 free:53424kB min:49684kB low:62104kB high:74524kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB present:3129216kB managed:2790292kB mlocked:0kB kernel_stack:0kB pagetables:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB [ 53.915597] lowmem_reserve[]: 0 0 958 958 [ 53.916992] Node 0 Normal free:17192kB min:17608kB low:22008kB high:26408kB active_anon:56992kB inactive_anon:8352kB active_file:12kB inactive_file:12kB unevictable:0kB writepending:20kB present:1048576kB managed:981384kB mlocked:0kB kernel_stack:3648kB pagetables:6704kB bounce:0kB free_pcp:112kB local_pcp:0kB free_cma:0kB [ 53.924610] lowmem_reserve[]: 0 0 0 0 [ 53.926131] Node 0 DMA: 1*4kB (U) 0*8kB 1*16kB (U) 0*32kB 1*64kB (U) 0*128kB 0*256kB 1*512kB (U) 0*1024kB 1*2048kB (M) 3*4096kB (M) = 14932kB [ 53.929273] Node 0 DMA32: 4*4kB (UM) 2*8kB (UM) 5*16kB (UM) 4*32kB (M) 3*64kB (M) 4*128kB (M) 5*256kB (UM) 4*512kB (M) 4*1024kB (UM) 2*2048kB (UM) 10*4096kB (M) = 53424kB [ 53.934010] Node 0 Normal: 896*4kB (ME) 466*8kB (UME) 288*16kB (UME) 128*32kB (UME) 23*64kB (UM) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 17488kB [ 53.9378
Re: [BUG] GPF on reboot of box
Steven Rostedt wrote: > Starting with v4.14-rc1 my box crashes during a reboot. All I get is > the following: > > [ 250.615793] sd 0:0:0:0: [sda] Synchronizing SCSI cache > [ 250.635639] reboot: Restarting system > [ 250.639671] reboot: machine restart > [ 250.643842] general protection fault: [#1] PREEMPT SMP KASAN > > Then nothing. No reboot, it just hangs there. > > I bisected it down to this commit: > > 660da7c9228f ("x86/mm: Enable CR4.PCIDE on supported systems") > > If I comment out the setting of X86_CR4_PCIDE in that commit, it boots > fine. But... > > I noticed that commit c7ad5ad29 ("x86/mm/64: Initialize CR4.PCIDE > early") moved the problem code from arch/x86/kernel/cpu/common.c to > arch/x86/mm/init.c > > If I comment it out in v4.14-rc1, it crashes on boot up. > > It appears that my box doesn't like having X86_CR4_PCIDE set. it causes > reboot to fail. But it also appears that setting that is required for > some other code to work. IIRC, there was a problem in rc1, which should be resolved in newer rcs. If you need to run rc1, you can try to use the kernel parameter “nopcid". Nadav
Re: [PATCH 0/6] Shrinking DT memory usage
On 10/05/17 12:44, Rob Herring wrote: > On kernels with a minimal config and a RAM target in the 100s of KB, DT > is quite a hog of runtime memory usage. How much is dependent on how many > nodes and properties in the DT which have a corresponding struct device_node > and struct property in the kernel. Just skipping disabled nodes saves a > lot by not creating the device_nodes in the first place[1], but there's > more low hanging fruit by making some of the fields in struct property and > struct device_node optional. With the changes here, the memory usage goes > from 17KB to under 8KB on QEMU's ARM virt machine which is a relatively > small DT. > > The majority of the diffstat here is just moving all the kobject/sysfs > related code to its own file so we can avoid adding a bunch of ifdefs. > > There's more drastic approaches we could take such as doing the > unflattening at build time and storing the bulk of the unflattened tree > as const data. Grant also has some ideas on storing properties as ids > instead. He's explained it to me, but I still don't understand it. > > Rob > > [1] https://patchwork.kernel.org/patch/9983203/ > > Rob Herring (6): > of: fix missing kobject init for !SYSFS && OF_DYNAMIC config > of: remove struct property.unique_id for FDT > of: make struct property _flags field configurable > of: move kobj_to_device_node() into dynamic.c > of: wrap accesses to device_node kobject > of: make kobject and bin_attribute support configurable > > drivers/base/core.c | 2 +- > drivers/of/Kconfig | 4 ++ > drivers/of/Makefile | 1 + > drivers/of/base.c | 133 --- > drivers/of/dynamic.c| 27 ++-- > drivers/of/kobj.c | 164 > > drivers/of/of_private.h | 29 +++-- > include/linux/of.h | 28 + > 8 files changed, 215 insertions(+), 173 deletions(-) > create mode 100644 drivers/of/kobj.c > For the entire series: Reviewed-by: Frank Rowand I don't know if there will be any conflicts between my series "[PATCH 00/12] of: overlay: clean up device tree overlay code" and this series. If you choose to apply this series first, I will make any needed changes to my series. -Frank
[rcu:rcu/next 93/97] include/linux/pm_runtime.h:108:34: error: lvalue required as left operand of assignment
tree: https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next head: f561b44bd4bd0518dc12c5d112bf3c9fb8ec56e7 commit: bb506b193f6f9bea58316cedceec18e680f93161 [93/97] include/linux: Convert ACCESS_ONCE() to READ_ONCE() config: i386-randconfig-x001-201740 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: git checkout bb506b193f6f9bea58316cedceec18e680f93161 # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): In file included from drivers/net/ethernet/realtek/r8169.c:26:0: include/linux/pm_runtime.h: In function 'pm_runtime_mark_last_busy': >> include/linux/pm_runtime.h:108:34: error: lvalue required as left operand of >> assignment READ_ONCE(dev->power.last_busy) = jiffies; ^ vim +108 include/linux/pm_runtime.h 105 106 static inline void pm_runtime_mark_last_busy(struct device *dev) 107 { > 108 READ_ONCE(dev->power.last_busy) = jiffies; 109 } 110 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH 3/4] sched: WARN when migrating to an offline CPU
On Fri, Sep 29, 2017 at 01:11:26PM +0200, Peter Zijlstra wrote: >I can't seem to trigger :-( > >Can you please run with the below patch and: > > # echo 1 > /proc/sys/kernel/traceoff_on_warning The call stack trace looks like so: [ 2073.492089] Unregister pv shared memory for cpu 2 [ 2073.495414] NOHZ: local_softirq_pending 202 [ 2073.516166] [ cut here ] [ 2073.519047] WARNING: CPU: 2 PID: 24 at kernel/sched/core.c:1178 set_task_cpu (kernel/sched/core.c:1157) [ 2073.520317] Modules linked in: [ 2073.520816] CPU: 2 PID: 24 Comm: migration/2 Not tainted 4.14.0-rc2-next-20170927+ #256 [ 2073.522046] task: 8801ab7cc040 task.stack: 8801ab7d8000 [ 2073.522963] RIP: 0010:set_task_cpu (??:?) [ 2073.523655] RSP: 0018:8801ab807b20 EFLAGS: 00010096 [ 2073.524662] RAX: 0002 RBX: 880189810040 RCX: 1100356f993a [ 2073.525747] RDX: RSI: RDI: 0046 [ 2073.526845] RBP: 8801ab807b60 R08: R09: [ 2073.527940] R10: R11: R12: 001e5900 [ 2073.529027] R13: 0006 R14: 0002 R15: 8801898100a4 [ 2073.530118] FS: () GS:8801ab80() knlGS: [ 2073.531556] CS: 0010 DS: ES: CR0: 80050033 [ 2073.532443] CR2: 7ffd965f1be8 CR3: 000187ede001 CR4: 000606a0 [ 2073.533546] Call Trace: [ 2073.533944] [ 2073.534280] detach_task.isra.80 (kernel/sched/fair.c:6816) [ 2073.534939] load_balance (./include/linux/list.h:78 kernel/sched/fair.c:6902 kernel/sched/fair.c:8204) [ 2073.535543] ? find_busiest_group (kernel/sched/fair.c:8133) [ 2073.536252] rebalance_domains (kernel/sched/fair.c:8838) [ 2073.536903] ? pick_next_task_fair (kernel/sched/fair.c:8787) [ 2073.537628] ? check_preemption_disabled (lib/smp_processor_id.c:52) [ 2073.538395] run_rebalance_domains (kernel/sched/fair.c:9062) [ 2073.539096] ? check_preemption_disabled (lib/smp_processor_id.c:52) [ 2073.539850] __do_softirq (kernel/softirq.c:284 ./include/linux/jump_label.h:141 ./include/trace/events/irq.h:141 kernel/softirq.c:285) [ 2073.540424] ? check_preemption_disabled (lib/smp_processor_id.c:52) [ 2073.541189] irq_exit (kernel/softirq.c:364 kernel/softirq.c:405) [ 2073.541715] smp_apic_timer_interrupt (./arch/x86/include/asm/irq_regs.h:26 arch/x86/kernel/apic/apic.c:1043) [ 2073.542452] apic_timer_interrupt (arch/x86/entry/entry_64.S:770) [ 2073.543116] [ 2073.543463] RIP: 0010:multi_cpu_stop (??:?) [ 2073.544173] RSP: 0018:8801ab7dfd88 EFLAGS: 0292 ORIG_RAX: ff11 [ 2073.545326] RAX: 0007 RBX: 0004 RCX: 000a [ 2073.546406] RDX: RSI: 9c46eee0 RDI: 0292 [ 2073.547503] RBP: 8801ab7dfde0 R08: R09: [ 2073.548587] R10: R11: R12: 88012aaf7890 [ 2073.549668] R13: 88012aaf78b4 R14: dc00 R15: 0003 [ 2073.550765] ? __this_cpu_preempt_check (lib/smp_processor_id.c:63) [ 2073.551501] ? cpu_stop_queue_work (kernel/stop_machine.c:176) [ 2073.552195] cpu_stopper_thread (kernel/stop_machine.c:480) [ 2073.552845] ? cpu_stop_create (kernel/stop_machine.c:458) [ 2073.553462] smpboot_thread_fn (kernel/smpboot.c:164) [ 2073.554104] ? sort_range (kernel/smpboot.c:107) [ 2073.554671] ? schedule (./arch/x86/include/asm/bitops.h:324 (discriminator 1) ./include/linux/thread_info.h:79 (discriminator 1) ./include/linux/sched.h:1605 (discriminator 1) kernel/sched/core.c:3435 (discriminator 1)) [ 2073.555230] ? __kthread_parkme (kernel/kthread.c:188) [ 2073.555892] kthread (kernel/kthread.c:242) [ 2073.556408] ? sort_range (kernel/smpboot.c:107) [ 2073.556963] ? kthread_create_on_node (kernel/kthread.c:198) [ 2073.557693] ret_from_fork (arch/x86/entry/entry_64.S:437) [ 2073.558261] Code: 09 84 d2 74 05 e8 84 3a 4b 00 f7 83 84 00 00 00 fd ff ff ff 0f 84 a0 f9 ff ff 0f ff e9 99 f9 ff ff e8 78 18 ff ff e9 c7 fd ff ff <0f> ff e9 ea f9 ff ff e8 67 18 ff ff e9 f5 f9 ff ff e8 fd 85 0f All code 0: 09 84 d2 74 05 e8 84or %eax,-0x7b17fa8c(%rdx,%rdx,8) 7: 3a 4b 00cmp0x0(%rbx),%cl a: f7 83 84 00 00 00 fdtestl $0xfffd,0x84(%rbx) 11: ff ff ff 14: 0f 84 a0 f9 ff ff je 0xf9ba 1a: 0f ff (bad) 1c: e9 99 f9 ff ff jmpq 0xf9ba 21: e8 78 18 ff ff callq 0x189e 26: e9 c7 fd ff ff jmpq 0xfdf2 2b:* 0f ff (bad) <-- trapping instruction 2d: e9 ea f9 ff ff jmpq 0xfa1c 32: e8 67 18 ff ff callq 0x189e 37: e9 f5 f9 ff ff jmpq 0xfa31 3c: e8 fd 85 0f 00 callq 0xf863e Code starting with the faulting instructi
Re: [PATCH] ext2/super: Fix a possible sleep-in-atomic bug in parse_options
On Fri, Oct 06, 2017 at 06:37:11PM -0700, Linus Torvalds wrote: > On Fri, Oct 6, 2017 at 6:20 PM, Jia-Ju Bai wrote: > > > > To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. > > This bug is found by my static analysis tool and my code review. > > I'm not saying your patch is wrong, but it's a shame that we do that > extra allocation in match_number() and match_u64int(), and that we > don't have anything that is just size-limited. > > And there really isn't anything saying that we shouldn't do the same > silly thing to match_u64int(). Maybe we don't have any actual users > that need it for now, but still.. > > Oh well. > > I do wonder if we shouldn't just use something like > > "skip leading zeroes, copy to size-limited stack location instead" > > because the input length really *is* limited once you skip leading > zeroes (and whatever base marker we have). We might have at most a > 64-bit value in octal, so 22 bytes max. > > But I guess just changing the two GFP_KERNEL's to GFP_ATOMIC is much simpler. There's match_strdup() as well... FWIW, ext2 side also looks fishy; it might be cleaner if we collected new state into some object and applied it only after the last possible failure exit. The entire "restore the original state" logics would go away...
Re: [PATCH net-next 2/2] bnxt_en: tc: only the function prototypes need to be wrapped in #ifdef
From: Michael Chan Date: Fri, 6 Oct 2017 18:27:31 -0700 > On Fri, Oct 6, 2017 at 12:48 PM, Jonathan Toppins wrote: >> There is no reason to wrap the data structures inside the ifdef. > > What's so bad about wrapping unused data structures inside #ifdef? > These structures are only used if CONFIG_BNXT_FLOWER_OFFLOAD is > defined. Yeah I agree, this ifdef is actually a good way to trap unintentional usage of those datastructures so it's doubly best to keep the ifdef.
Re: [PATCH net-next 1/2] bnxt_en: don't consider building bnxt_tc.o if option not enabled
From: Michael Chan Date: Fri, 6 Oct 2017 18:01:57 -0700 > On Fri, Oct 6, 2017 at 12:48 PM, Jonathan Toppins wrote: >> Instead of zeroing out bnxt_tc.c with a #ifdef foo, instead don't compile >> the file when the option is not enabled. Now make and the preprocessor do >> not have to waste time compiling a no-op. >> >> Signed-off-by: Jonathan Toppins > > Acked-by: Michael Chan Applied.
[BUG] fs/dlm: A possible sleep-in-atomic bug in dlm_master_lookup
According to fs/dlm/lock.c, the kernel may sleep under a spinlock, and the function call path is: dlm_master_lookup (acquire the spinlock) dlm_send_rcom_lookup_dump create_rcom dlm_lowcomms_get_buffer nodeid2con mutex_lock --> may sleep This bug is found by my static analysis tool and my code review. Thanks, Jia-Ju Bai
Re: [PATCH] ext2/super: Fix a possible sleep-in-atomic bug in parse_options
Thanks for your reply. I agree that extra allocation in match_number() and match_u64int() may be unnecessary. Thanks, Jia-Ju Bai On 2017/10/7 9:37, Linus Torvalds wrote: On Fri, Oct 6, 2017 at 6:20 PM, Jia-Ju Bai wrote: To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. This bug is found by my static analysis tool and my code review. I'm not saying your patch is wrong, but it's a shame that we do that extra allocation in match_number() and match_u64int(), and that we don't have anything that is just size-limited. And there really isn't anything saying that we shouldn't do the same silly thing to match_u64int(). Maybe we don't have any actual users that need it for now, but still.. Oh well. I do wonder if we shouldn't just use something like "skip leading zeroes, copy to size-limited stack location instead" because the input length really *is* limited once you skip leading zeroes (and whatever base marker we have). We might have at most a 64-bit value in octal, so 22 bytes max. But I guess just changing the two GFP_KERNEL's to GFP_ATOMIC is much simpler. Linus
[BUG] GPF on reboot of box
Starting with v4.14-rc1 my box crashes during a reboot. All I get is the following: [ 250.615793] sd 0:0:0:0: [sda] Synchronizing SCSI cache [ 250.635639] reboot: Restarting system [ 250.639671] reboot: machine restart [ 250.643842] general protection fault: [#1] PREEMPT SMP KASAN Then nothing. No reboot, it just hangs there. I bisected it down to this commit: 660da7c9228f ("x86/mm: Enable CR4.PCIDE on supported systems") If I comment out the setting of X86_CR4_PCIDE in that commit, it boots fine. But... I noticed that commit c7ad5ad29 ("x86/mm/64: Initialize CR4.PCIDE early") moved the problem code from arch/x86/kernel/cpu/common.c to arch/x86/mm/init.c If I comment it out in v4.14-rc1, it crashes on boot up. It appears that my box doesn't like having X86_CR4_PCIDE set. it causes reboot to fail. But it also appears that setting that is required for some other code to work. Help! -- Steve
Re: [PATCH] ext2/super: Fix a possible sleep-in-atomic bug in parse_options
On Fri, Oct 6, 2017 at 6:20 PM, Jia-Ju Bai wrote: > > To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. > This bug is found by my static analysis tool and my code review. I'm not saying your patch is wrong, but it's a shame that we do that extra allocation in match_number() and match_u64int(), and that we don't have anything that is just size-limited. And there really isn't anything saying that we shouldn't do the same silly thing to match_u64int(). Maybe we don't have any actual users that need it for now, but still.. Oh well. I do wonder if we shouldn't just use something like "skip leading zeroes, copy to size-limited stack location instead" because the input length really *is* limited once you skip leading zeroes (and whatever base marker we have). We might have at most a 64-bit value in octal, so 22 bytes max. But I guess just changing the two GFP_KERNEL's to GFP_ATOMIC is much simpler. Linus
[BUG] fs/aio: A possible sleep-in-atomic bug in aio_migratepage
According to fs/aio.c, cond_resched is called under a spinlock, and the function call path is: aio_migratepage (acquire the spinlock) migrate_page_copy copy_huge_page __copy_gigantic_page cond_resched might_sleep This bug is found by my static analysis tool and my code review. A possible fix is to remove cond_resched in __copy_gigantic_page. Thanks, Jia-Ju Bai
Re: [PATCH net-next 2/2] bnxt_en: tc: only the function prototypes need to be wrapped in #ifdef
On Fri, Oct 6, 2017 at 12:48 PM, Jonathan Toppins wrote: > There is no reason to wrap the data structures inside the ifdef. What's so bad about wrapping unused data structures inside #ifdef? These structures are only used if CONFIG_BNXT_FLOWER_OFFLOAD is defined.