Merge "Merge tag 'lsk-v4.4-16.12-android' into branch 'msm-4.4'"
This commit is contained in:
commit
048676be41
985 changed files with 19238 additions and 8057 deletions
|
@ -374,82 +374,3 @@ One can experience an overall throughput drop if you have created multiple
|
|||
groups and put applications in that group which are not driving enough
|
||||
IO to keep disk busy. In that case set group_idle=0, and CFQ will not idle
|
||||
on individual groups and throughput should improve.
|
||||
|
||||
Writeback
|
||||
=========
|
||||
|
||||
Page cache is dirtied through buffered writes and shared mmaps and
|
||||
written asynchronously to the backing filesystem by the writeback
|
||||
mechanism. Writeback sits between the memory and IO domains and
|
||||
regulates the proportion of dirty memory by balancing dirtying and
|
||||
write IOs.
|
||||
|
||||
On traditional cgroup hierarchies, relationships between different
|
||||
controllers cannot be established making it impossible for writeback
|
||||
to operate accounting for cgroup resource restrictions and all
|
||||
writeback IOs are attributed to the root cgroup.
|
||||
|
||||
If both the blkio and memory controllers are used on the v2 hierarchy
|
||||
and the filesystem supports cgroup writeback, writeback operations
|
||||
correctly follow the resource restrictions imposed by both memory and
|
||||
blkio controllers.
|
||||
|
||||
Writeback examines both system-wide and per-cgroup dirty memory status
|
||||
and enforces the more restrictive of the two. Also, writeback control
|
||||
parameters which are absolute values - vm.dirty_bytes and
|
||||
vm.dirty_background_bytes - are distributed across cgroups according
|
||||
to their current writeback bandwidth.
|
||||
|
||||
There's a peculiarity stemming from the discrepancy in ownership
|
||||
granularity between memory controller and writeback. While memory
|
||||
controller tracks ownership per page, writeback operates on inode
|
||||
basis. cgroup writeback bridges the gap by tracking ownership by
|
||||
inode but migrating ownership if too many foreign pages, pages which
|
||||
don't match the current inode ownership, have been encountered while
|
||||
writing back the inode.
|
||||
|
||||
This is a conscious design choice as writeback operations are
|
||||
inherently tied to inodes making strictly following page ownership
|
||||
complicated and inefficient. The only use case which suffers from
|
||||
this compromise is multiple cgroups concurrently dirtying disjoint
|
||||
regions of the same inode, which is an unlikely use case and decided
|
||||
to be unsupported. Note that as memory controller assigns page
|
||||
ownership on the first use and doesn't update it until the page is
|
||||
released, even if cgroup writeback strictly follows page ownership,
|
||||
multiple cgroups dirtying overlapping areas wouldn't work as expected.
|
||||
In general, write-sharing an inode across multiple cgroups is not well
|
||||
supported.
|
||||
|
||||
Filesystem support for cgroup writeback
|
||||
---------------------------------------
|
||||
|
||||
A filesystem can make writeback IOs cgroup-aware by updating
|
||||
address_space_operations->writepage[s]() to annotate bio's using the
|
||||
following two functions.
|
||||
|
||||
* wbc_init_bio(@wbc, @bio)
|
||||
|
||||
Should be called for each bio carrying writeback data and associates
|
||||
the bio with the inode's owner cgroup. Can be called anytime
|
||||
between bio allocation and submission.
|
||||
|
||||
* wbc_account_io(@wbc, @page, @bytes)
|
||||
|
||||
Should be called for each data segment being written out. While
|
||||
this function doesn't care exactly when it's called during the
|
||||
writeback session, it's the easiest and most natural to call it as
|
||||
data segments are added to a bio.
|
||||
|
||||
With writeback bio's annotated, cgroup support can be enabled per
|
||||
super_block by setting MS_CGROUPWB in ->s_flags. This allows for
|
||||
selective disabling of cgroup writeback support which is helpful when
|
||||
certain filesystem features, e.g. journaled data mode, are
|
||||
incompatible.
|
||||
|
||||
wbc_init_bio() binds the specified bio to its cgroup. Depending on
|
||||
the configuration, the bio may be executed at a lower priority and if
|
||||
the writeback session is holding shared resources, e.g. a journal
|
||||
entry, may lead to priority inversion. There is no one easy solution
|
||||
for the problem. Filesystems can try to work around specific problem
|
||||
cases by skipping wbc_init_bio() or using bio_associate_blkcg()
|
||||
directly.
|
|
@ -578,15 +578,6 @@ is completely unused; @cgrp->parent is still valid. (Note - can also
|
|||
be called for a newly-created cgroup if an error occurs after this
|
||||
subsystem's create() method has been called for the new cgroup).
|
||||
|
||||
int allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
|
||||
(cgroup_mutex held by caller)
|
||||
|
||||
Called prior to moving a task into a cgroup; if the subsystem
|
||||
returns an error, this will abort the attach operation. Used
|
||||
to extend the permission checks - if all subsystems in a cgroup
|
||||
return 0, the attach will be allowed to proceed, even if the
|
||||
default permission check (root or same user) fails.
|
||||
|
||||
int can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
|
||||
(cgroup_mutex held by caller)
|
||||
|
1293
Documentation/cgroup.txt
Normal file
1293
Documentation/cgroup.txt
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,647 +0,0 @@
|
|||
|
||||
Cgroup unified hierarchy
|
||||
|
||||
April, 2014 Tejun Heo <tj@kernel.org>
|
||||
|
||||
This document describes the changes made by unified hierarchy and
|
||||
their rationales. It will eventually be merged into the main cgroup
|
||||
documentation.
|
||||
|
||||
CONTENTS
|
||||
|
||||
1. Background
|
||||
2. Basic Operation
|
||||
2-1. Mounting
|
||||
2-2. cgroup.subtree_control
|
||||
2-3. cgroup.controllers
|
||||
3. Structural Constraints
|
||||
3-1. Top-down
|
||||
3-2. No internal tasks
|
||||
4. Delegation
|
||||
4-1. Model of delegation
|
||||
4-2. Common ancestor rule
|
||||
5. Other Changes
|
||||
5-1. [Un]populated Notification
|
||||
5-2. Other Core Changes
|
||||
5-3. Controller File Conventions
|
||||
5-3-1. Format
|
||||
5-3-2. Control Knobs
|
||||
5-4. Per-Controller Changes
|
||||
5-4-1. io
|
||||
5-4-2. cpuset
|
||||
5-4-3. memory
|
||||
6. Planned Changes
|
||||
6-1. CAP for resource control
|
||||
|
||||
|
||||
1. Background
|
||||
|
||||
cgroup allows an arbitrary number of hierarchies and each hierarchy
|
||||
can host any number of controllers. While this seems to provide a
|
||||
high level of flexibility, it isn't quite useful in practice.
|
||||
|
||||
For example, as there is only one instance of each controller, utility
|
||||
type controllers such as freezer which can be useful in all
|
||||
hierarchies can only be used in one. The issue is exacerbated by the
|
||||
fact that controllers can't be moved around once hierarchies are
|
||||
populated. Another issue is that all controllers bound to a hierarchy
|
||||
are forced to have exactly the same view of the hierarchy. It isn't
|
||||
possible to vary the granularity depending on the specific controller.
|
||||
|
||||
In practice, these issues heavily limit which controllers can be put
|
||||
on the same hierarchy and most configurations resort to putting each
|
||||
controller on its own hierarchy. Only closely related ones, such as
|
||||
the cpu and cpuacct controllers, make sense to put on the same
|
||||
hierarchy. This often means that userland ends up managing multiple
|
||||
similar hierarchies repeating the same steps on each hierarchy
|
||||
whenever a hierarchy management operation is necessary.
|
||||
|
||||
Unfortunately, support for multiple hierarchies comes at a steep cost.
|
||||
Internal implementation in cgroup core proper is dazzlingly
|
||||
complicated but more importantly the support for multiple hierarchies
|
||||
restricts how cgroup is used in general and what controllers can do.
|
||||
|
||||
There's no limit on how many hierarchies there may be, which means
|
||||
that a task's cgroup membership can't be described in finite length.
|
||||
The key may contain any varying number of entries and is unlimited in
|
||||
length, which makes it highly awkward to handle and leads to addition
|
||||
of controllers which exist only to identify membership, which in turn
|
||||
exacerbates the original problem.
|
||||
|
||||
Also, as a controller can't have any expectation regarding what shape
|
||||
of hierarchies other controllers would be on, each controller has to
|
||||
assume that all other controllers are operating on completely
|
||||
orthogonal hierarchies. This makes it impossible, or at least very
|
||||
cumbersome, for controllers to cooperate with each other.
|
||||
|
||||
In most use cases, putting controllers on hierarchies which are
|
||||
completely orthogonal to each other isn't necessary. What usually is
|
||||
called for is the ability to have differing levels of granularity
|
||||
depending on the specific controller. In other words, hierarchy may
|
||||
be collapsed from leaf towards root when viewed from specific
|
||||
controllers. For example, a given configuration might not care about
|
||||
how memory is distributed beyond a certain level while still wanting
|
||||
to control how CPU cycles are distributed.
|
||||
|
||||
Unified hierarchy is the next version of cgroup interface. It aims to
|
||||
address the aforementioned issues by having more structure while
|
||||
retaining enough flexibility for most use cases. Various other
|
||||
general and controller-specific interface issues are also addressed in
|
||||
the process.
|
||||
|
||||
|
||||
2. Basic Operation
|
||||
|
||||
2-1. Mounting
|
||||
|
||||
Currently, unified hierarchy can be mounted with the following mount
|
||||
command. Note that this is still under development and scheduled to
|
||||
change soon.
|
||||
|
||||
mount -t cgroup -o __DEVEL__sane_behavior cgroup $MOUNT_POINT
|
||||
|
||||
All controllers which support the unified hierarchy and are not bound
|
||||
to other hierarchies are automatically bound to unified hierarchy and
|
||||
show up at the root of it. Controllers which are enabled only in the
|
||||
root of unified hierarchy can be bound to other hierarchies. This
|
||||
allows mixing unified hierarchy with the traditional multiple
|
||||
hierarchies in a fully backward compatible way.
|
||||
|
||||
A controller can be moved across hierarchies only after the controller
|
||||
is no longer referenced in its current hierarchy. Because per-cgroup
|
||||
controller states are destroyed asynchronously and controllers may
|
||||
have lingering references, a controller may not show up immediately on
|
||||
the unified hierarchy after the final umount of the previous
|
||||
hierarchy. Similarly, a controller should be fully disabled to be
|
||||
moved out of the unified hierarchy and it may take some time for the
|
||||
disabled controller to become available for other hierarchies;
|
||||
furthermore, due to dependencies among controllers, other controllers
|
||||
may need to be disabled too.
|
||||
|
||||
While useful for development and manual configurations, dynamically
|
||||
moving controllers between the unified and other hierarchies is
|
||||
strongly discouraged for production use. It is recommended to decide
|
||||
the hierarchies and controller associations before starting using the
|
||||
controllers.
|
||||
|
||||
|
||||
2-2. cgroup.subtree_control
|
||||
|
||||
All cgroups on unified hierarchy have a "cgroup.subtree_control" file
|
||||
which governs which controllers are enabled on the children of the
|
||||
cgroup. Let's assume a hierarchy like the following.
|
||||
|
||||
root - A - B - C
|
||||
\ D
|
||||
|
||||
root's "cgroup.subtree_control" file determines which controllers are
|
||||
enabled on A. A's on B. B's on C and D. This coincides with the
|
||||
fact that controllers on the immediate sub-level are used to
|
||||
distribute the resources of the parent. In fact, it's natural to
|
||||
assume that resource control knobs of a child belong to its parent.
|
||||
Enabling a controller in a "cgroup.subtree_control" file declares that
|
||||
distribution of the respective resources of the cgroup will be
|
||||
controlled. Note that this means that controller enable states are
|
||||
shared among siblings.
|
||||
|
||||
When read, the file contains a space-separated list of currently
|
||||
enabled controllers. A write to the file should contain a
|
||||
space-separated list of controllers with '+' or '-' prefixed (without
|
||||
the quotes). Controllers prefixed with '+' are enabled and '-'
|
||||
disabled. If a controller is listed multiple times, the last entry
|
||||
wins. The specific operations are executed atomically - either all
|
||||
succeed or fail.
|
||||
|
||||
|
||||
2-3. cgroup.controllers
|
||||
|
||||
Read-only "cgroup.controllers" file contains a space-separated list of
|
||||
controllers which can be enabled in the cgroup's
|
||||
"cgroup.subtree_control" file.
|
||||
|
||||
In the root cgroup, this lists controllers which are not bound to
|
||||
other hierarchies and the content changes as controllers are bound to
|
||||
and unbound from other hierarchies.
|
||||
|
||||
In non-root cgroups, the content of this file equals that of the
|
||||
parent's "cgroup.subtree_control" file as only controllers enabled
|
||||
from the parent can be used in its children.
|
||||
|
||||
|
||||
3. Structural Constraints
|
||||
|
||||
3-1. Top-down
|
||||
|
||||
As it doesn't make sense to nest control of an uncontrolled resource,
|
||||
all non-root "cgroup.subtree_control" files can only contain
|
||||
controllers which are enabled in the parent's "cgroup.subtree_control"
|
||||
file. A controller can be enabled only if the parent has the
|
||||
controller enabled and a controller can't be disabled if one or more
|
||||
children have it enabled.
|
||||
|
||||
|
||||
3-2. No internal tasks
|
||||
|
||||
One long-standing issue that cgroup faces is the competition between
|
||||
tasks belonging to the parent cgroup and its children cgroups. This
|
||||
is inherently nasty as two different types of entities compete and
|
||||
there is no agreed-upon obvious way to handle it. Different
|
||||
controllers are doing different things.
|
||||
|
||||
The cpu controller considers tasks and cgroups as equivalents and maps
|
||||
nice levels to cgroup weights. This works for some cases but falls
|
||||
flat when children should be allocated specific ratios of CPU cycles
|
||||
and the number of internal tasks fluctuates - the ratios constantly
|
||||
change as the number of competing entities fluctuates. There also are
|
||||
other issues. The mapping from nice level to weight isn't obvious or
|
||||
universal, and there are various other knobs which simply aren't
|
||||
available for tasks.
|
||||
|
||||
The io controller implicitly creates a hidden leaf node for each
|
||||
cgroup to host the tasks. The hidden leaf has its own copies of all
|
||||
the knobs with "leaf_" prefixed. While this allows equivalent control
|
||||
over internal tasks, it's with serious drawbacks. It always adds an
|
||||
extra layer of nesting which may not be necessary, makes the interface
|
||||
messy and significantly complicates the implementation.
|
||||
|
||||
The memory controller currently doesn't have a way to control what
|
||||
happens between internal tasks and child cgroups and the behavior is
|
||||
not clearly defined. There have been attempts to add ad-hoc behaviors
|
||||
and knobs to tailor the behavior to specific workloads. Continuing
|
||||
this direction will lead to problems which will be extremely difficult
|
||||
to resolve in the long term.
|
||||
|
||||
Multiple controllers struggle with internal tasks and came up with
|
||||
different ways to deal with it; unfortunately, all the approaches in
|
||||
use now are severely flawed and, furthermore, the widely different
|
||||
behaviors make cgroup as whole highly inconsistent.
|
||||
|
||||
It is clear that this is something which needs to be addressed from
|
||||
cgroup core proper in a uniform way so that controllers don't need to
|
||||
worry about it and cgroup as a whole shows a consistent and logical
|
||||
behavior. To achieve that, unified hierarchy enforces the following
|
||||
structural constraint:
|
||||
|
||||
Except for the root, only cgroups which don't contain any task may
|
||||
have controllers enabled in their "cgroup.subtree_control" files.
|
||||
|
||||
Combined with other properties, this guarantees that, when a
|
||||
controller is looking at the part of the hierarchy which has it
|
||||
enabled, tasks are always only on the leaves. This rules out
|
||||
situations where child cgroups compete against internal tasks of the
|
||||
parent.
|
||||
|
||||
There are two things to note. Firstly, the root cgroup is exempt from
|
||||
the restriction. Root contains tasks and anonymous resource
|
||||
consumption which can't be associated with any other cgroup and
|
||||
requires special treatment from most controllers. How resource
|
||||
consumption in the root cgroup is governed is up to each controller.
|
||||
|
||||
Secondly, the restriction doesn't take effect if there is no enabled
|
||||
controller in the cgroup's "cgroup.subtree_control" file. This is
|
||||
important as otherwise it wouldn't be possible to create children of a
|
||||
populated cgroup. To control resource distribution of a cgroup, the
|
||||
cgroup must create children and transfer all its tasks to the children
|
||||
before enabling controllers in its "cgroup.subtree_control" file.
|
||||
|
||||
|
||||
4. Delegation
|
||||
|
||||
4-1. Model of delegation
|
||||
|
||||
A cgroup can be delegated to a less privileged user by granting write
|
||||
access of the directory and its "cgroup.procs" file to the user. Note
|
||||
that the resource control knobs in a given directory concern the
|
||||
resources of the parent and thus must not be delegated along with the
|
||||
directory.
|
||||
|
||||
Once delegated, the user can build sub-hierarchy under the directory,
|
||||
organize processes as it sees fit and further distribute the resources
|
||||
it got from the parent. The limits and other settings of all resource
|
||||
controllers are hierarchical and regardless of what happens in the
|
||||
delegated sub-hierarchy, nothing can escape the resource restrictions
|
||||
imposed by the parent.
|
||||
|
||||
Currently, cgroup doesn't impose any restrictions on the number of
|
||||
cgroups in or nesting depth of a delegated sub-hierarchy; however,
|
||||
this may in the future be limited explicitly.
|
||||
|
||||
|
||||
4-2. Common ancestor rule
|
||||
|
||||
On the unified hierarchy, to write to a "cgroup.procs" file, in
|
||||
addition to the usual write permission to the file and uid match, the
|
||||
writer must also have write access to the "cgroup.procs" file of the
|
||||
common ancestor of the source and destination cgroups. This prevents
|
||||
delegatees from smuggling processes across disjoint sub-hierarchies.
|
||||
|
||||
Let's say cgroups C0 and C1 have been delegated to user U0 who created
|
||||
C00, C01 under C0 and C10 under C1 as follows.
|
||||
|
||||
~~~~~~~~~~~~~ - C0 - C00
|
||||
~ cgroup ~ \ C01
|
||||
~ hierarchy ~
|
||||
~~~~~~~~~~~~~ - C1 - C10
|
||||
|
||||
C0 and C1 are separate entities in terms of resource distribution
|
||||
regardless of their relative positions in the hierarchy. The
|
||||
resources the processes under C0 are entitled to are controlled by
|
||||
C0's ancestors and may be completely different from C1. It's clear
|
||||
that the intention of delegating C0 to U0 is allowing U0 to organize
|
||||
the processes under C0 and further control the distribution of C0's
|
||||
resources.
|
||||
|
||||
On traditional hierarchies, if a task has write access to "tasks" or
|
||||
"cgroup.procs" file of a cgroup and its uid agrees with the target, it
|
||||
can move the target to the cgroup. In the above example, U0 will not
|
||||
only be able to move processes in each sub-hierarchy but also across
|
||||
the two sub-hierarchies, effectively allowing it to violate the
|
||||
organizational and resource restrictions implied by the hierarchical
|
||||
structure above C0 and C1.
|
||||
|
||||
On the unified hierarchy, let's say U0 wants to write the pid of a
|
||||
process which has a matching uid and is currently in C10 into
|
||||
"C00/cgroup.procs". U0 obviously has write access to the file and
|
||||
migration permission on the process; however, the common ancestor of
|
||||
the source cgroup C10 and the destination cgroup C00 is above the
|
||||
points of delegation and U0 would not have write access to its
|
||||
"cgroup.procs" and thus be denied with -EACCES.
|
||||
|
||||
|
||||
5. Other Changes
|
||||
|
||||
5-1. [Un]populated Notification
|
||||
|
||||
cgroup users often need a way to determine when a cgroup's
|
||||
subhierarchy becomes empty so that it can be cleaned up. cgroup
|
||||
currently provides release_agent for it; unfortunately, this mechanism
|
||||
is riddled with issues.
|
||||
|
||||
- It delivers events by forking and execing a userland binary
|
||||
specified as the release_agent. This is a long deprecated method of
|
||||
notification delivery. It's extremely heavy, slow and cumbersome to
|
||||
integrate with larger infrastructure.
|
||||
|
||||
- There is single monitoring point at the root. There's no way to
|
||||
delegate management of a subtree.
|
||||
|
||||
- The event isn't recursive. It triggers when a cgroup doesn't have
|
||||
any tasks or child cgroups. Events for internal nodes trigger only
|
||||
after all children are removed. This again makes it impossible to
|
||||
delegate management of a subtree.
|
||||
|
||||
- Events are filtered from the kernel side. A "notify_on_release"
|
||||
file is used to subscribe to or suppress release events. This is
|
||||
unnecessarily complicated and probably done this way because event
|
||||
delivery itself was expensive.
|
||||
|
||||
Unified hierarchy implements "populated" field in "cgroup.events"
|
||||
interface file which can be used to monitor whether the cgroup's
|
||||
subhierarchy has tasks in it or not. Its value is 0 if there is no
|
||||
task in the cgroup and its descendants; otherwise, 1. poll and
|
||||
[id]notify events are triggered when the value changes.
|
||||
|
||||
This is significantly lighter and simpler and trivially allows
|
||||
delegating management of subhierarchy - subhierarchy monitoring can
|
||||
block further propagation simply by putting itself or another process
|
||||
in the subhierarchy and monitor events that it's interested in from
|
||||
there without interfering with monitoring higher in the tree.
|
||||
|
||||
In unified hierarchy, the release_agent mechanism is no longer
|
||||
supported and the interface files "release_agent" and
|
||||
"notify_on_release" do not exist.
|
||||
|
||||
|
||||
5-2. Other Core Changes
|
||||
|
||||
- None of the mount options is allowed.
|
||||
|
||||
- remount is disallowed.
|
||||
|
||||
- rename(2) is disallowed.
|
||||
|
||||
- The "tasks" file is removed. Everything should at process
|
||||
granularity. Use the "cgroup.procs" file instead.
|
||||
|
||||
- The "cgroup.procs" file is not sorted. pids will be unique unless
|
||||
they got recycled in-between reads.
|
||||
|
||||
- The "cgroup.clone_children" file is removed.
|
||||
|
||||
- /proc/PID/cgroup keeps reporting the cgroup that a zombie belonged
|
||||
to before exiting. If the cgroup is removed before the zombie is
|
||||
reaped, " (deleted)" is appeneded to the path.
|
||||
|
||||
|
||||
5-3. Controller File Conventions
|
||||
|
||||
5-3-1. Format
|
||||
|
||||
In general, all controller files should be in one of the following
|
||||
formats whenever possible.
|
||||
|
||||
- Values only files
|
||||
|
||||
VAL0 VAL1...\n
|
||||
|
||||
- Flat keyed files
|
||||
|
||||
KEY0 VAL0\n
|
||||
KEY1 VAL1\n
|
||||
...
|
||||
|
||||
- Nested keyed files
|
||||
|
||||
KEY0 SUB_KEY0=VAL00 SUB_KEY1=VAL01...
|
||||
KEY1 SUB_KEY0=VAL10 SUB_KEY1=VAL11...
|
||||
...
|
||||
|
||||
For a writeable file, the format for writing should generally match
|
||||
reading; however, controllers may allow omitting later fields or
|
||||
implement restricted shortcuts for most common use cases.
|
||||
|
||||
For both flat and nested keyed files, only the values for a single key
|
||||
can be written at a time. For nested keyed files, the sub key pairs
|
||||
may be specified in any order and not all pairs have to be specified.
|
||||
|
||||
|
||||
5-3-2. Control Knobs
|
||||
|
||||
- Settings for a single feature should generally be implemented in a
|
||||
single file.
|
||||
|
||||
- In general, the root cgroup should be exempt from resource control
|
||||
and thus shouldn't have resource control knobs.
|
||||
|
||||
- If a controller implements ratio based resource distribution, the
|
||||
control knob should be named "weight" and have the range [1, 10000]
|
||||
and 100 should be the default value. The values are chosen to allow
|
||||
enough and symmetric bias in both directions while keeping it
|
||||
intuitive (the default is 100%).
|
||||
|
||||
- If a controller implements an absolute resource guarantee and/or
|
||||
limit, the control knobs should be named "min" and "max"
|
||||
respectively. If a controller implements best effort resource
|
||||
gurantee and/or limit, the control knobs should be named "low" and
|
||||
"high" respectively.
|
||||
|
||||
In the above four control files, the special token "max" should be
|
||||
used to represent upward infinity for both reading and writing.
|
||||
|
||||
- If a setting has configurable default value and specific overrides,
|
||||
the default settings should be keyed with "default" and appear as
|
||||
the first entry in the file. Specific entries can use "default" as
|
||||
its value to indicate inheritance of the default value.
|
||||
|
||||
- For events which are not very high frequency, an interface file
|
||||
"events" should be created which lists event key value pairs.
|
||||
Whenever a notifiable event happens, file modified event should be
|
||||
generated on the file.
|
||||
|
||||
|
||||
5-4. Per-Controller Changes
|
||||
|
||||
5-4-1. io
|
||||
|
||||
- blkio is renamed to io. The interface is overhauled anyway. The
|
||||
new name is more in line with the other two major controllers, cpu
|
||||
and memory, and better suited given that it may be used for cgroup
|
||||
writeback without involving block layer.
|
||||
|
||||
- Everything including stat is always hierarchical making separate
|
||||
recursive stat files pointless and, as no internal node can have
|
||||
tasks, leaf weights are meaningless. The operation model is
|
||||
simplified and the interface is overhauled accordingly.
|
||||
|
||||
io.stat
|
||||
|
||||
The stat file. The reported stats are from the point where
|
||||
bio's are issued to request_queue. The stats are counted
|
||||
independent of which policies are enabled. Each line in the
|
||||
file follows the following format. More fields may later be
|
||||
added at the end.
|
||||
|
||||
$MAJ:$MIN rbytes=$RBYTES wbytes=$WBYTES rios=$RIOS wrios=$WIOS
|
||||
|
||||
io.weight
|
||||
|
||||
The weight setting, currently only available and effective if
|
||||
cfq-iosched is in use for the target device. The weight is
|
||||
between 1 and 10000 and defaults to 100. The first line
|
||||
always contains the default weight in the following format to
|
||||
use when per-device setting is missing.
|
||||
|
||||
default $WEIGHT
|
||||
|
||||
Subsequent lines list per-device weights of the following
|
||||
format.
|
||||
|
||||
$MAJ:$MIN $WEIGHT
|
||||
|
||||
Writing "$WEIGHT" or "default $WEIGHT" changes the default
|
||||
setting. Writing "$MAJ:$MIN $WEIGHT" sets per-device weight
|
||||
while "$MAJ:$MIN default" clears it.
|
||||
|
||||
This file is available only on non-root cgroups.
|
||||
|
||||
io.max
|
||||
|
||||
The maximum bandwidth and/or iops setting, only available if
|
||||
blk-throttle is enabled. The file is of the following format.
|
||||
|
||||
$MAJ:$MIN rbps=$RBPS wbps=$WBPS riops=$RIOPS wiops=$WIOPS
|
||||
|
||||
${R|W}BPS are read/write bytes per second and ${R|W}IOPS are
|
||||
read/write IOs per second. "max" indicates no limit. Writing
|
||||
to the file follows the same format but the individual
|
||||
settings may be omitted or specified in any order.
|
||||
|
||||
This file is available only on non-root cgroups.
|
||||
|
||||
|
||||
5-4-2. cpuset
|
||||
|
||||
- Tasks are kept in empty cpusets after hotplug and take on the masks
|
||||
of the nearest non-empty ancestor, instead of being moved to it.
|
||||
|
||||
- A task can be moved into an empty cpuset, and again it takes on the
|
||||
masks of the nearest non-empty ancestor.
|
||||
|
||||
|
||||
5-4-3. memory
|
||||
|
||||
- use_hierarchy is on by default and the cgroup file for the flag is
|
||||
not created.
|
||||
|
||||
- The original lower boundary, the soft limit, is defined as a limit
|
||||
that is per default unset. As a result, the set of cgroups that
|
||||
global reclaim prefers is opt-in, rather than opt-out. The costs
|
||||
for optimizing these mostly negative lookups are so high that the
|
||||
implementation, despite its enormous size, does not even provide the
|
||||
basic desirable behavior. First off, the soft limit has no
|
||||
hierarchical meaning. All configured groups are organized in a
|
||||
global rbtree and treated like equal peers, regardless where they
|
||||
are located in the hierarchy. This makes subtree delegation
|
||||
impossible. Second, the soft limit reclaim pass is so aggressive
|
||||
that it not just introduces high allocation latencies into the
|
||||
system, but also impacts system performance due to overreclaim, to
|
||||
the point where the feature becomes self-defeating.
|
||||
|
||||
The memory.low boundary on the other hand is a top-down allocated
|
||||
reserve. A cgroup enjoys reclaim protection when it and all its
|
||||
ancestors are below their low boundaries, which makes delegation of
|
||||
subtrees possible. Secondly, new cgroups have no reserve per
|
||||
default and in the common case most cgroups are eligible for the
|
||||
preferred reclaim pass. This allows the new low boundary to be
|
||||
efficiently implemented with just a minor addition to the generic
|
||||
reclaim code, without the need for out-of-band data structures and
|
||||
reclaim passes. Because the generic reclaim code considers all
|
||||
cgroups except for the ones running low in the preferred first
|
||||
reclaim pass, overreclaim of individual groups is eliminated as
|
||||
well, resulting in much better overall workload performance.
|
||||
|
||||
- The original high boundary, the hard limit, is defined as a strict
|
||||
limit that can not budge, even if the OOM killer has to be called.
|
||||
But this generally goes against the goal of making the most out of
|
||||
the available memory. The memory consumption of workloads varies
|
||||
during runtime, and that requires users to overcommit. But doing
|
||||
that with a strict upper limit requires either a fairly accurate
|
||||
prediction of the working set size or adding slack to the limit.
|
||||
Since working set size estimation is hard and error prone, and
|
||||
getting it wrong results in OOM kills, most users tend to err on the
|
||||
side of a looser limit and end up wasting precious resources.
|
||||
|
||||
The memory.high boundary on the other hand can be set much more
|
||||
conservatively. When hit, it throttles allocations by forcing them
|
||||
into direct reclaim to work off the excess, but it never invokes the
|
||||
OOM killer. As a result, a high boundary that is chosen too
|
||||
aggressively will not terminate the processes, but instead it will
|
||||
lead to gradual performance degradation. The user can monitor this
|
||||
and make corrections until the minimal memory footprint that still
|
||||
gives acceptable performance is found.
|
||||
|
||||
In extreme cases, with many concurrent allocations and a complete
|
||||
breakdown of reclaim progress within the group, the high boundary
|
||||
can be exceeded. But even then it's mostly better to satisfy the
|
||||
allocation from the slack available in other groups or the rest of
|
||||
the system than killing the group. Otherwise, memory.max is there
|
||||
to limit this type of spillover and ultimately contain buggy or even
|
||||
malicious applications.
|
||||
|
||||
- The original control file names are unwieldy and inconsistent in
|
||||
many different ways. For example, the upper boundary hit count is
|
||||
exported in the memory.failcnt file, but an OOM event count has to
|
||||
be manually counted by listening to memory.oom_control events, and
|
||||
lower boundary / soft limit events have to be counted by first
|
||||
setting a threshold for that value and then counting those events.
|
||||
Also, usage and limit files encode their units in the filename.
|
||||
That makes the filenames very long, even though this is not
|
||||
information that a user needs to be reminded of every time they type
|
||||
out those names.
|
||||
|
||||
To address these naming issues, as well as to signal clearly that
|
||||
the new interface carries a new configuration model, the naming
|
||||
conventions in it necessarily differ from the old interface.
|
||||
|
||||
- The original limit files indicate the state of an unset limit with a
|
||||
Very High Number, and a configured limit can be unset by echoing -1
|
||||
into those files. But that very high number is implementation and
|
||||
architecture dependent and not very descriptive. And while -1 can
|
||||
be understood as an underflow into the highest possible value, -2 or
|
||||
-10M etc. do not work, so it's not consistent.
|
||||
|
||||
memory.low, memory.high, and memory.max will use the string "max" to
|
||||
indicate and set the highest possible value.
|
||||
|
||||
6. Planned Changes
|
||||
|
||||
6-1. CAP for resource control
|
||||
|
||||
Unified hierarchy will require one of the capabilities(7), which is
|
||||
yet to be decided, for all resource control related knobs. Process
|
||||
organization operations - creation of sub-cgroups and migration of
|
||||
processes in sub-hierarchies may be delegated by changing the
|
||||
ownership and/or permissions on the cgroup directory and
|
||||
"cgroup.procs" interface file; however, all operations which affect
|
||||
resource control - writes to a "cgroup.subtree_control" file or any
|
||||
controller-specific knobs - will require an explicit CAP privilege.
|
||||
|
||||
This, in part, is to prevent the cgroup interface from being
|
||||
inadvertently promoted to programmable API used by non-privileged
|
||||
binaries. cgroup exposes various aspects of the system in ways which
|
||||
aren't properly abstracted for direct consumption by regular programs.
|
||||
This is an administration interface much closer to sysctl knobs than
|
||||
system calls. Even the basic access model, being filesystem path
|
||||
based, isn't suitable for direct consumption. There's no way to
|
||||
access "my cgroup" in a race-free way or make multiple operations
|
||||
atomic against migration to another cgroup.
|
||||
|
||||
Another aspect is that, for better or for worse, the cgroup interface
|
||||
goes through far less scrutiny than regular interfaces for
|
||||
unprivileged userland. The upside is that cgroup is able to expose
|
||||
useful features which may not be suitable for general consumption in a
|
||||
reasonable time frame. It provides a relatively short path between
|
||||
internal details and userland-visible interface. Of course, this
|
||||
shortcut comes with high risk. We go through what we go through for
|
||||
general kernel APIs for good reasons. It may end up leaking internal
|
||||
details in a way which can exert significant pain by locking the
|
||||
kernel into a contract that can't be maintained in a reasonable
|
||||
manner.
|
||||
|
||||
Also, due to the specific nature, cgroup and its controllers don't
|
||||
tend to attract attention from a wide scope of developers. cgroup's
|
||||
short history is already fraught with severely mis-designed
|
||||
interfaces, unnecessary commitments to and exposing of internal
|
||||
details, broken and dangerous implementations of various features.
|
||||
|
||||
Keeping cgroup as an administration interface is both advantageous for
|
||||
its role and imperative given its nature. Some of the cgroup features
|
||||
may make sense for unprivileged access. If deemed justified, those
|
||||
must be further abstracted and implemented as a different interface,
|
||||
be it a system call or process-private filesystem, and survive through
|
||||
the scrutiny that any interface for general consumption is required to
|
||||
go through.
|
||||
|
||||
Requiring CAP is not a complete solution but should serve as a
|
||||
significant deterrent against spraying cgroup usages in non-privileged
|
||||
programs.
|
17
Documentation/devicetree/bindings/goldfish/audio.txt
Normal file
17
Documentation/devicetree/bindings/goldfish/audio.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
Android Goldfish Audio
|
||||
|
||||
Android goldfish audio device generated by android emulator.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should contain "google,goldfish-audio" to match emulator
|
||||
- reg : <registers mapping>
|
||||
- interrupts : <interrupt mapping>
|
||||
|
||||
Example:
|
||||
|
||||
goldfish_audio@9030000 {
|
||||
compatible = "google,goldfish-audio";
|
||||
reg = <0x9030000 0x100>;
|
||||
interrupts = <0x4>;
|
||||
};
|
17
Documentation/devicetree/bindings/goldfish/battery.txt
Normal file
17
Documentation/devicetree/bindings/goldfish/battery.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
Android Goldfish Battery
|
||||
|
||||
Android goldfish battery device generated by android emulator.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should contain "google,goldfish-battery" to match emulator
|
||||
- reg : <registers mapping>
|
||||
- interrupts : <interrupt mapping>
|
||||
|
||||
Example:
|
||||
|
||||
goldfish_battery@9020000 {
|
||||
compatible = "google,goldfish-battery";
|
||||
reg = <0x9020000 0x1000>;
|
||||
interrupts = <0x3>;
|
||||
};
|
17
Documentation/devicetree/bindings/goldfish/events.txt
Normal file
17
Documentation/devicetree/bindings/goldfish/events.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
Android Goldfish Events Keypad
|
||||
|
||||
Android goldfish events keypad device generated by android emulator.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should contain "google,goldfish-events-keypad" to match emulator
|
||||
- reg : <registers mapping>
|
||||
- interrupts : <interrupt mapping>
|
||||
|
||||
Example:
|
||||
|
||||
goldfish-events@9040000 {
|
||||
compatible = "google,goldfish-events-keypad";
|
||||
reg = <0x9040000 0x1000>;
|
||||
interrupts = <0x5>;
|
||||
};
|
17
Documentation/devicetree/bindings/goldfish/tty.txt
Normal file
17
Documentation/devicetree/bindings/goldfish/tty.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
Android Goldfish TTY
|
||||
|
||||
Android goldfish tty device generated by android emulator.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should contain "google,goldfish-tty" to match emulator
|
||||
- reg : <registers mapping>
|
||||
- interrupts : <interrupt mapping>
|
||||
|
||||
Example:
|
||||
|
||||
goldfish_tty@1f004000 {
|
||||
compatible = "google,goldfish-tty";
|
||||
reg = <0x1f004000 0x1000>;
|
||||
interrupts = <0xc>;
|
||||
};
|
|
@ -12,6 +12,11 @@ Required properties:
|
|||
- vref-supply: The regulator supply ADC reference voltage.
|
||||
- #io-channel-cells: Should be 1, see ../iio-bindings.txt
|
||||
|
||||
Optional properties:
|
||||
- resets: Must contain an entry for each entry in reset-names if need support
|
||||
this option. See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the name "saradc-apb".
|
||||
|
||||
Example:
|
||||
saradc: saradc@2006c000 {
|
||||
compatible = "rockchip,saradc";
|
||||
|
@ -19,6 +24,8 @@ Example:
|
|||
interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
|
||||
clock-names = "saradc", "apb_pclk";
|
||||
resets = <&cru SRST_SARADC>;
|
||||
reset-names = "saradc-apb";
|
||||
#io-channel-cells = <1>;
|
||||
vref-supply = <&vcc18>;
|
||||
};
|
||||
|
|
|
@ -81,9 +81,9 @@ pm8916:
|
|||
l14, l15, l16, l17, l18
|
||||
|
||||
pm8941:
|
||||
s1, s2, s3, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14,
|
||||
l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3,
|
||||
mvs1, mvs2
|
||||
s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13,
|
||||
l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3,
|
||||
5vs1, 5vs2
|
||||
|
||||
The content of each sub-node is defined by the standard binding for regulators -
|
||||
see regulator.txt - with additional custom properties described below:
|
||||
|
|
|
@ -1381,7 +1381,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
|
||||
controllers
|
||||
i8042.notimeout [HW] Ignore timeout condition signalled by controller
|
||||
i8042.reset [HW] Reset the controller during init and cleanup
|
||||
i8042.reset [HW] Reset the controller during init, cleanup and
|
||||
suspend-to-ram transitions, only during s2r
|
||||
transitions, or never reset
|
||||
Format: { 1 | Y | y | 0 | N | n }
|
||||
1, Y, y: always reset controller
|
||||
0, N, n: don't ever reset controller
|
||||
Default: only on s2r transitions on x86; most other
|
||||
architectures force reset to be always executed
|
||||
i8042.unlock [HW] Unlock (ignore) the keylock
|
||||
i8042.kbdreset [HW] Reset device connected to KBD port
|
||||
|
||||
|
|
|
@ -1538,9 +1538,9 @@ set_cmdline(struct mic_info *mic)
|
|||
|
||||
len = snprintf(buffer, PATH_MAX,
|
||||
"clocksource=tsc highres=off nohz=off ");
|
||||
len += snprintf(buffer + len, PATH_MAX,
|
||||
len += snprintf(buffer + len, PATH_MAX - len,
|
||||
"cpufreq_on;corec6_off;pc3_off;pc6_off ");
|
||||
len += snprintf(buffer + len, PATH_MAX,
|
||||
len += snprintf(buffer + len, PATH_MAX - len,
|
||||
"ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0",
|
||||
mic->id + 1);
|
||||
|
||||
|
|
|
@ -831,7 +831,7 @@ separate memory range only intended for GPIO driving, and the register
|
|||
range dealing with pin config and pin multiplexing get placed into a
|
||||
different memory range and a separate section of the data sheet.
|
||||
|
||||
A flag "strict" in struct pinctrl_desc is available to check and deny
|
||||
A flag "strict" in struct pinmux_ops is available to check and deny
|
||||
simultaneous access to the same pin from GPIO and pin multiplexing
|
||||
consumers on hardware of this type. The pinctrl driver should set this flag
|
||||
accordingly.
|
||||
|
|
|
@ -357,6 +357,26 @@ of ftrace. Here is a list of some of the key files:
|
|||
to correlate events across hypervisor/guest if
|
||||
tb_offset is known.
|
||||
|
||||
mono: This uses the fast monotonic clock (CLOCK_MONOTONIC)
|
||||
which is monotonic and is subject to NTP rate adjustments.
|
||||
|
||||
mono_raw:
|
||||
This is the raw monotonic clock (CLOCK_MONOTONIC_RAW)
|
||||
which is montonic but is not subject to any rate adjustments
|
||||
and ticks at the same rate as the hardware clocksource.
|
||||
|
||||
boot: This is the boot clock (CLOCK_BOOTTIME) and is based on the
|
||||
fast monotonic clock, but also accounts for time spent in
|
||||
suspend. Since the clock access is designed for use in
|
||||
tracing in the suspend path, some side effects are possible
|
||||
if clock is accessed after the suspend time is accounted before
|
||||
the fast mono clock is updated. In this case, the clock update
|
||||
appears to happen slightly sooner than it normally would have.
|
||||
Also on 32-bit systems, its possible that the 64-bit boot offset
|
||||
sees a partial update. These effects are rare and post
|
||||
processing should be able to handle them. See comments on
|
||||
ktime_get_boot_fast_ns function for more information.
|
||||
|
||||
To set a clock, simply echo the clock name into this file.
|
||||
|
||||
echo global > trace_clock
|
||||
|
|
31
Makefile
31
Makefile
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 21
|
||||
SUBLEVEL = 38
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
|
@ -128,6 +128,10 @@ _all:
|
|||
# Cancel implicit rules on top Makefile
|
||||
$(CURDIR)/Makefile Makefile: ;
|
||||
|
||||
ifneq ($(words $(subst :, ,$(CURDIR))), 1)
|
||||
$(error main directory cannot contain spaces nor colons)
|
||||
endif
|
||||
|
||||
ifneq ($(KBUILD_OUTPUT),)
|
||||
# Invoke a second make in the output directory, passing relevant variables
|
||||
# check that the output directory actually exists
|
||||
|
@ -395,11 +399,12 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
|||
-fno-strict-aliasing -fno-common \
|
||||
-Werror-implicit-function-declaration \
|
||||
-Wno-format-security \
|
||||
-std=gnu89
|
||||
-std=gnu89 $(call cc-option,-fno-PIE)
|
||||
|
||||
|
||||
KBUILD_AFLAGS_KERNEL :=
|
||||
KBUILD_CFLAGS_KERNEL :=
|
||||
KBUILD_AFLAGS := -D__ASSEMBLY__
|
||||
KBUILD_AFLAGS := -D__ASSEMBLY__ $(call cc-option,-fno-PIE)
|
||||
KBUILD_AFLAGS_MODULE := -DMODULE
|
||||
KBUILD_CFLAGS_MODULE := -DMODULE
|
||||
KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
|
||||
|
@ -499,6 +504,12 @@ ifeq ($(KBUILD_EXTMOD),)
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
# install and module_install need also be processed one by one
|
||||
ifneq ($(filter install,$(MAKECMDGOALS)),)
|
||||
ifneq ($(filter modules_install,$(MAKECMDGOALS)),)
|
||||
mixed-targets := 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(mixed-targets),1)
|
||||
# ===========================================================================
|
||||
|
@ -610,11 +621,17 @@ ARCH_CFLAGS :=
|
|||
include arch/$(SRCARCH)/Makefile
|
||||
|
||||
KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
|
||||
|
||||
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
|
||||
KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,)
|
||||
KBUILD_CFLAGS += -Os
|
||||
else
|
||||
ifdef CONFIG_PROFILE_ALL_BRANCHES
|
||||
KBUILD_CFLAGS += -O2
|
||||
else
|
||||
KBUILD_CFLAGS += -O2
|
||||
endif
|
||||
endif
|
||||
|
||||
# Tell gcc to never replace conditional load with a non-conditional one
|
||||
|
@ -1265,7 +1282,7 @@ help:
|
|||
@echo ' firmware_install- Install all firmware to INSTALL_FW_PATH'
|
||||
@echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)'
|
||||
@echo ' dir/ - Build all files in dir and below'
|
||||
@echo ' dir/file.[oisS] - Build specified target only'
|
||||
@echo ' dir/file.[ois] - Build specified target only'
|
||||
@echo ' dir/file.lst - Build specified mixed source/assembly target only'
|
||||
@echo ' (requires a recent binutils and recent build (System.map))'
|
||||
@echo ' dir/file.ko - Build module including final link'
|
||||
|
@ -1505,11 +1522,11 @@ image_name:
|
|||
# Clear a bunch of variables before executing the submake
|
||||
tools/: FORCE
|
||||
$(Q)mkdir -p $(objtree)/tools
|
||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/
|
||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/
|
||||
|
||||
tools/%: FORCE
|
||||
$(Q)mkdir -p $(objtree)/tools
|
||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/ $*
|
||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $*
|
||||
|
||||
# Single targets
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
@ -24,6 +24,7 @@ CONFIG_DM_VERITY=y
|
|||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_EMBEDDED=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_HARDENED_USERCOPY=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_INET6_AH=y
|
||||
CONFIG_INET6_ESP=y
|
||||
|
@ -139,6 +140,7 @@ CONFIG_PPP_MPPE=y
|
|||
CONFIG_PREEMPT=y
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_RANDOMIZE_BASE=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_SECCOMP=y
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# KEEP ALPHABETICALLY SORTED
|
||||
# CONFIG_AIO is not set
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
|
|
|
@ -371,14 +371,6 @@ __copy_tofrom_user_nocheck(void *to, const void *from, long len)
|
|||
return __cu_len;
|
||||
}
|
||||
|
||||
extern inline long
|
||||
__copy_tofrom_user(void *to, const void *from, long len, const void __user *validate)
|
||||
{
|
||||
if (__access_ok((unsigned long)validate, len, get_fs()))
|
||||
len = __copy_tofrom_user_nocheck(to, from, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
#define __copy_to_user(to, from, n) \
|
||||
({ \
|
||||
__chk_user_ptr(to); \
|
||||
|
@ -393,17 +385,22 @@ __copy_tofrom_user(void *to, const void *from, long len, const void __user *vali
|
|||
#define __copy_to_user_inatomic __copy_to_user
|
||||
#define __copy_from_user_inatomic __copy_from_user
|
||||
|
||||
|
||||
extern inline long
|
||||
copy_to_user(void __user *to, const void *from, long n)
|
||||
{
|
||||
return __copy_tofrom_user((__force void *)to, from, n, to);
|
||||
if (likely(__access_ok((unsigned long)to, n, get_fs())))
|
||||
n = __copy_tofrom_user_nocheck((__force void *)to, from, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
extern inline long
|
||||
copy_from_user(void *to, const void __user *from, long n)
|
||||
{
|
||||
return __copy_tofrom_user(to, (__force void *)from, n, from);
|
||||
if (likely(__access_ok((unsigned long)from, n, get_fs())))
|
||||
n = __copy_tofrom_user_nocheck(to, (__force void *)from, n);
|
||||
else
|
||||
memset(to, 0, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
extern void __do_clear_user(void);
|
||||
|
|
|
@ -22,10 +22,11 @@
|
|||
static inline void __delay(unsigned long loops)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
" lp 1f \n"
|
||||
" nop \n"
|
||||
"1: \n"
|
||||
: "+l"(loops));
|
||||
" mov lp_count, %0 \n"
|
||||
" lp 1f \n"
|
||||
" nop \n"
|
||||
"1: \n"
|
||||
: : "r"(loops));
|
||||
}
|
||||
|
||||
extern void __bad_udelay(void);
|
||||
|
|
|
@ -277,8 +277,7 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
|
|||
|
||||
#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
|
||||
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
|
||||
#define pfn_pte(pfn, prot) (__pte(((pte_t)(pfn) << PAGE_SHIFT) | \
|
||||
pgprot_val(prot)))
|
||||
#define pfn_pte(pfn, prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
|
||||
#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
|
||||
|
||||
/*
|
||||
|
|
|
@ -83,7 +83,10 @@
|
|||
"2: ;nop\n" \
|
||||
" .section .fixup, \"ax\"\n" \
|
||||
" .align 4\n" \
|
||||
"3: mov %0, %3\n" \
|
||||
"3: # return -EFAULT\n" \
|
||||
" mov %0, %3\n" \
|
||||
" # zero out dst ptr\n" \
|
||||
" mov %1, 0\n" \
|
||||
" j 2b\n" \
|
||||
" .previous\n" \
|
||||
" .section __ex_table, \"a\"\n" \
|
||||
|
@ -101,7 +104,11 @@
|
|||
"2: ;nop\n" \
|
||||
" .section .fixup, \"ax\"\n" \
|
||||
" .align 4\n" \
|
||||
"3: mov %0, %3\n" \
|
||||
"3: # return -EFAULT\n" \
|
||||
" mov %0, %3\n" \
|
||||
" # zero out dst ptr\n" \
|
||||
" mov %1, 0\n" \
|
||||
" mov %R1, 0\n" \
|
||||
" j 2b\n" \
|
||||
" .previous\n" \
|
||||
" .section __ex_table, \"a\"\n" \
|
||||
|
|
|
@ -107,13 +107,13 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
|
|||
struct user_regs_struct uregs;
|
||||
|
||||
err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
|
||||
if (!err)
|
||||
set_current_blocked(&set);
|
||||
|
||||
err |= __copy_from_user(&uregs.scratch,
|
||||
&(sf->uc.uc_mcontext.regs.scratch),
|
||||
sizeof(sf->uc.uc_mcontext.regs.scratch));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
set_current_blocked(&set);
|
||||
regs->bta = uregs.scratch.bta;
|
||||
regs->lp_start = uregs.scratch.lp_start;
|
||||
regs->lp_end = uregs.scratch.lp_end;
|
||||
|
@ -138,7 +138,7 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
|
|||
regs->r0 = uregs.scratch.r0;
|
||||
regs->sp = uregs.scratch.sp;
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_do_ss_needed(unsigned int magic)
|
||||
|
|
|
@ -130,14 +130,17 @@ static cycle_t arc_counter_read(struct clocksource *cs)
|
|||
cycle_t full;
|
||||
} stamp;
|
||||
|
||||
|
||||
__asm__ __volatile(
|
||||
"1: \n"
|
||||
" lr %0, [AUX_RTC_LOW] \n"
|
||||
" lr %1, [AUX_RTC_HIGH] \n"
|
||||
" lr %2, [AUX_RTC_CTRL] \n"
|
||||
" bbit0.nt %2, 31, 1b \n"
|
||||
: "=r" (stamp.low), "=r" (stamp.high), "=r" (status));
|
||||
/*
|
||||
* hardware has an internal state machine which tracks readout of
|
||||
* low/high and updates the CTRL.status if
|
||||
* - interrupt/exception taken between the two reads
|
||||
* - high increments after low has been read
|
||||
*/
|
||||
do {
|
||||
stamp.low = read_aux_reg(AUX_RTC_LOW);
|
||||
stamp.high = read_aux_reg(AUX_RTC_HIGH);
|
||||
status = read_aux_reg(AUX_RTC_CTRL);
|
||||
} while (!(status & _BITUL(31)));
|
||||
|
||||
return stamp.full;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ config ARM
|
|||
select HAVE_ARCH_HARDENED_USERCOPY
|
||||
select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARM_SMCCC if CPU_V7
|
||||
select HAVE_BPF_JIT
|
||||
select HAVE_CC_STACKPROTECTOR
|
||||
select HAVE_CONTEXT_TRACKING
|
||||
|
@ -1462,8 +1463,7 @@ config BIG_LITTLE
|
|||
|
||||
config BL_SWITCHER
|
||||
bool "big.LITTLE switcher support"
|
||||
depends on BIG_LITTLE && MCPM && HOTPLUG_CPU
|
||||
select ARM_CPU_SUSPEND
|
||||
depends on BIG_LITTLE && MCPM && HOTPLUG_CPU && ARM_GIC
|
||||
select CPU_PM
|
||||
help
|
||||
The big.LITTLE "switcher" provides the core functionality to
|
||||
|
@ -1521,7 +1521,7 @@ config HOTPLUG_CPU
|
|||
|
||||
config ARM_PSCI
|
||||
bool "Support for the ARM Power State Coordination Interface (PSCI)"
|
||||
depends on CPU_V7
|
||||
depends on HAVE_ARM_SMCCC
|
||||
select ARM_PSCI_FW
|
||||
help
|
||||
Say Y here if you want Linux to communicate with system firmware
|
||||
|
@ -2227,7 +2227,8 @@ config ARCH_SUSPEND_POSSIBLE
|
|||
def_bool y
|
||||
|
||||
config ARM_CPU_SUSPEND
|
||||
def_bool PM_SLEEP
|
||||
def_bool PM_SLEEP || BL_SWITCHER || ARM_PSCI_FW
|
||||
depends on ARCH_SUSPEND_POSSIBLE
|
||||
|
||||
config ARCH_HIBERNATION_POSSIBLE
|
||||
bool
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#include "armada-39x.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "marvell,armada390";
|
||||
|
||||
soc {
|
||||
internal-regs {
|
||||
pinctrl@18000 {
|
||||
|
@ -54,4 +56,5 @@
|
|||
reg = <0x18000 0x20>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -221,7 +221,7 @@
|
|||
clocks = <&clks IMX6QDL_CLK_SPDIF_GCLK>, <&clks IMX6QDL_CLK_OSC>,
|
||||
<&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_ASRC>,
|
||||
<&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_ESAI_EXTAL>,
|
||||
<&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_MLB>,
|
||||
<&clks IMX6QDL_CLK_IPG>, <&clks IMX6QDL_CLK_DUMMY>,
|
||||
<&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_SPBA>;
|
||||
clock-names = "core", "rxtx0",
|
||||
"rxtx1", "rxtx2",
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
|
||||
partition@e0000 {
|
||||
label = "u-boot environment";
|
||||
reg = <0xe0000 0x100000>;
|
||||
reg = <0xe0000 0x20000>;
|
||||
};
|
||||
|
||||
partition@100000 {
|
||||
|
|
|
@ -223,7 +223,9 @@
|
|||
};
|
||||
|
||||
&gpmc {
|
||||
ranges = <0 0 0x00000000 0x20000000>;
|
||||
ranges = <0 0 0x30000000 0x1000000>, /* CS0 */
|
||||
<4 0 0x2b000000 0x1000000>, /* CS4 */
|
||||
<5 0 0x2c000000 0x1000000>; /* CS5 */
|
||||
|
||||
nand@0,0 {
|
||||
linux,mtd-name= "micron,mt29c4g96maz";
|
||||
|
|
|
@ -55,8 +55,6 @@
|
|||
#include "omap-gpmc-smsc9221.dtsi"
|
||||
|
||||
&gpmc {
|
||||
ranges = <5 0 0x2c000000 0x1000000>; /* CS5 */
|
||||
|
||||
ethernet@gpmc {
|
||||
reg = <5 0 0xff>;
|
||||
interrupt-parent = <&gpio6>;
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include "omap-gpmc-smsc9221.dtsi"
|
||||
|
||||
&gpmc {
|
||||
ranges = <5 0 0x2c000000 0x1000000>; /* CS5 */
|
||||
|
||||
ethernet@gpmc {
|
||||
reg = <5 0 0xff>;
|
||||
interrupt-parent = <&gpio6>;
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
#include "omap-gpmc-smsc9221.dtsi"
|
||||
|
||||
&gpmc {
|
||||
ranges = <4 0 0x2b000000 0x1000000>, /* CS4 */
|
||||
<5 0 0x2c000000 0x1000000>; /* CS5 */
|
||||
|
||||
smsc1: ethernet@gpmc {
|
||||
reg = <5 0 0xff>;
|
||||
interrupt-parent = <&gpio6>;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <dt-bindings/reset/qcom,gcc-msm8960.h>
|
||||
#include <dt-bindings/clock/qcom,mmcc-msm8960.h>
|
||||
#include <dt-bindings/soc/qcom,gsbi.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
/ {
|
||||
model = "Qualcomm APQ8064";
|
||||
|
@ -354,22 +355,50 @@
|
|||
|
||||
compatible = "qcom,pm8921-gpio";
|
||||
reg = <0x150>;
|
||||
interrupts = <192 1>, <193 1>, <194 1>,
|
||||
<195 1>, <196 1>, <197 1>,
|
||||
<198 1>, <199 1>, <200 1>,
|
||||
<201 1>, <202 1>, <203 1>,
|
||||
<204 1>, <205 1>, <206 1>,
|
||||
<207 1>, <208 1>, <209 1>,
|
||||
<210 1>, <211 1>, <212 1>,
|
||||
<213 1>, <214 1>, <215 1>,
|
||||
<216 1>, <217 1>, <218 1>,
|
||||
<219 1>, <220 1>, <221 1>,
|
||||
<222 1>, <223 1>, <224 1>,
|
||||
<225 1>, <226 1>, <227 1>,
|
||||
<228 1>, <229 1>, <230 1>,
|
||||
<231 1>, <232 1>, <233 1>,
|
||||
<234 1>, <235 1>;
|
||||
|
||||
interrupts = <192 IRQ_TYPE_NONE>,
|
||||
<193 IRQ_TYPE_NONE>,
|
||||
<194 IRQ_TYPE_NONE>,
|
||||
<195 IRQ_TYPE_NONE>,
|
||||
<196 IRQ_TYPE_NONE>,
|
||||
<197 IRQ_TYPE_NONE>,
|
||||
<198 IRQ_TYPE_NONE>,
|
||||
<199 IRQ_TYPE_NONE>,
|
||||
<200 IRQ_TYPE_NONE>,
|
||||
<201 IRQ_TYPE_NONE>,
|
||||
<202 IRQ_TYPE_NONE>,
|
||||
<203 IRQ_TYPE_NONE>,
|
||||
<204 IRQ_TYPE_NONE>,
|
||||
<205 IRQ_TYPE_NONE>,
|
||||
<206 IRQ_TYPE_NONE>,
|
||||
<207 IRQ_TYPE_NONE>,
|
||||
<208 IRQ_TYPE_NONE>,
|
||||
<209 IRQ_TYPE_NONE>,
|
||||
<210 IRQ_TYPE_NONE>,
|
||||
<211 IRQ_TYPE_NONE>,
|
||||
<212 IRQ_TYPE_NONE>,
|
||||
<213 IRQ_TYPE_NONE>,
|
||||
<214 IRQ_TYPE_NONE>,
|
||||
<215 IRQ_TYPE_NONE>,
|
||||
<216 IRQ_TYPE_NONE>,
|
||||
<217 IRQ_TYPE_NONE>,
|
||||
<218 IRQ_TYPE_NONE>,
|
||||
<219 IRQ_TYPE_NONE>,
|
||||
<220 IRQ_TYPE_NONE>,
|
||||
<221 IRQ_TYPE_NONE>,
|
||||
<222 IRQ_TYPE_NONE>,
|
||||
<223 IRQ_TYPE_NONE>,
|
||||
<224 IRQ_TYPE_NONE>,
|
||||
<225 IRQ_TYPE_NONE>,
|
||||
<226 IRQ_TYPE_NONE>,
|
||||
<227 IRQ_TYPE_NONE>,
|
||||
<228 IRQ_TYPE_NONE>,
|
||||
<229 IRQ_TYPE_NONE>,
|
||||
<230 IRQ_TYPE_NONE>,
|
||||
<231 IRQ_TYPE_NONE>,
|
||||
<232 IRQ_TYPE_NONE>,
|
||||
<233 IRQ_TYPE_NONE>,
|
||||
<234 IRQ_TYPE_NONE>,
|
||||
<235 IRQ_TYPE_NONE>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
|
@ -381,9 +410,18 @@
|
|||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupts =
|
||||
<128 1>, <129 1>, <130 1>, <131 1>,
|
||||
<132 1>, <133 1>, <134 1>, <135 1>,
|
||||
<136 1>, <137 1>, <138 1>, <139 1>;
|
||||
<128 IRQ_TYPE_NONE>,
|
||||
<129 IRQ_TYPE_NONE>,
|
||||
<130 IRQ_TYPE_NONE>,
|
||||
<131 IRQ_TYPE_NONE>,
|
||||
<132 IRQ_TYPE_NONE>,
|
||||
<133 IRQ_TYPE_NONE>,
|
||||
<134 IRQ_TYPE_NONE>,
|
||||
<135 IRQ_TYPE_NONE>,
|
||||
<136 IRQ_TYPE_NONE>,
|
||||
<137 IRQ_TYPE_NONE>,
|
||||
<138 IRQ_TYPE_NONE>,
|
||||
<139 IRQ_TYPE_NONE>;
|
||||
};
|
||||
|
||||
rtc@11d {
|
||||
|
|
|
@ -497,8 +497,9 @@
|
|||
interrupt-names = "mmcirq";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mmc0>;
|
||||
clock-names = "mmc";
|
||||
clocks = <&clk_s_c0_flexgen CLK_MMC_0>;
|
||||
clock-names = "mmc", "icn";
|
||||
clocks = <&clk_s_c0_flexgen CLK_MMC_0>,
|
||||
<&clk_s_c0_flexgen CLK_RX_ICN_HVA>;
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
};
|
||||
|
@ -512,8 +513,9 @@
|
|||
interrupt-names = "mmcirq";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sd1>;
|
||||
clock-names = "mmc";
|
||||
clocks = <&clk_s_c0_flexgen CLK_MMC_1>;
|
||||
clock-names = "mmc", "icn";
|
||||
clocks = <&clk_s_c0_flexgen CLK_MMC_1>,
|
||||
<&clk_s_c0_flexgen CLK_RX_ICN_HVA>;
|
||||
resets = <&softreset STIH407_MMC1_SOFTRESET>;
|
||||
bus-width = <4>;
|
||||
};
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
compatible = "st,st-ohci-300x";
|
||||
reg = <0x9a03c00 0x100>;
|
||||
interrupts = <GIC_SPI 180 IRQ_TYPE_NONE>;
|
||||
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
|
||||
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
|
||||
<&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>;
|
||||
resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
|
||||
<&softreset STIH407_USB2_PORT0_SOFTRESET>;
|
||||
reset-names = "power", "softreset";
|
||||
|
@ -57,7 +58,8 @@
|
|||
interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usb0>;
|
||||
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
|
||||
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
|
||||
<&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>;
|
||||
resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
|
||||
<&softreset STIH407_USB2_PORT0_SOFTRESET>;
|
||||
reset-names = "power", "softreset";
|
||||
|
@ -71,7 +73,8 @@
|
|||
compatible = "st,st-ohci-300x";
|
||||
reg = <0x9a83c00 0x100>;
|
||||
interrupts = <GIC_SPI 181 IRQ_TYPE_NONE>;
|
||||
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
|
||||
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
|
||||
<&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>;
|
||||
resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
|
||||
<&softreset STIH407_USB2_PORT1_SOFTRESET>;
|
||||
reset-names = "power", "softreset";
|
||||
|
@ -87,7 +90,8 @@
|
|||
interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usb1>;
|
||||
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
|
||||
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
|
||||
<&clk_s_c0_flexgen CLK_RX_ICN_DISP_0>;
|
||||
resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
|
||||
<&softreset STIH407_USB2_PORT1_SOFTRESET>;
|
||||
reset-names = "power", "softreset";
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
trips {
|
||||
cpu_alert0: cpu_alert0 {
|
||||
/* milliCelsius */
|
||||
temperature = <850000>;
|
||||
temperature = <85000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
};
|
||||
|
|
|
@ -869,9 +869,9 @@ struct sa1111_save_data {
|
|||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int sa1111_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct sa1111 *sachip = platform_get_drvdata(dev);
|
||||
struct sa1111 *sachip = dev_get_drvdata(dev);
|
||||
struct sa1111_save_data *save;
|
||||
unsigned long flags;
|
||||
unsigned int val;
|
||||
|
@ -934,9 +934,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
|
|||
* restored by their respective drivers, and must be called
|
||||
* via LDM after this function.
|
||||
*/
|
||||
static int sa1111_resume(struct platform_device *dev)
|
||||
static int sa1111_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct sa1111 *sachip = platform_get_drvdata(dev);
|
||||
struct sa1111 *sachip = dev_get_drvdata(dev);
|
||||
struct sa1111_save_data *save;
|
||||
unsigned long flags, id;
|
||||
void __iomem *base;
|
||||
|
@ -952,7 +952,7 @@ static int sa1111_resume(struct platform_device *dev)
|
|||
id = sa1111_readl(sachip->base + SA1111_SKID);
|
||||
if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
|
||||
__sa1111_remove(sachip);
|
||||
platform_set_drvdata(dev, NULL);
|
||||
dev_set_drvdata(dev, NULL);
|
||||
kfree(save);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1003,8 +1003,8 @@ static int sa1111_resume(struct platform_device *dev)
|
|||
}
|
||||
|
||||
#else
|
||||
#define sa1111_suspend NULL
|
||||
#define sa1111_resume NULL
|
||||
#define sa1111_suspend_noirq NULL
|
||||
#define sa1111_resume_noirq NULL
|
||||
#endif
|
||||
|
||||
static int sa1111_probe(struct platform_device *pdev)
|
||||
|
@ -1038,6 +1038,11 @@ static int sa1111_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct dev_pm_ops sa1111_pm_ops = {
|
||||
.suspend_noirq = sa1111_suspend_noirq,
|
||||
.resume_noirq = sa1111_resume_noirq,
|
||||
};
|
||||
|
||||
/*
|
||||
* Not sure if this should be on the system bus or not yet.
|
||||
* We really want some way to register a system device at
|
||||
|
@ -1050,10 +1055,9 @@ static int sa1111_remove(struct platform_device *pdev)
|
|||
static struct platform_driver sa1111_device_driver = {
|
||||
.probe = sa1111_probe,
|
||||
.remove = sa1111_remove,
|
||||
.suspend = sa1111_suspend,
|
||||
.resume = sa1111_resume,
|
||||
.driver = {
|
||||
.name = "sa1111",
|
||||
.pm = &sa1111_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
315
arch/arm/configs/ranchu_defconfig
Normal file
315
arch/arm/configs/ranchu_defconfig
Normal file
|
@ -0,0 +1,315 @@
|
|||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CGROUP_DEBUG=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=16
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ARCH_VIRT=y
|
||||
CONFIG_ARM_KERNMEM_PERMS=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_CMDLINE="console=ttyAMA0"
|
||||
CONFIG_VFP=y
|
||||
CONFIG_NEON=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_PM_AUTOSLEEP=y
|
||||
CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_PM_WAKELOCKS_LIMIT=0
|
||||
# CONFIG_PM_WAKELOCKS_GC is not set
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_INET_ESP=y
|
||||
# CONFIG_INET_LRO is not set
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_ROUTE_INFO=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=y
|
||||
CONFIG_INET6_ESP=y
|
||||
CONFIG_INET6_IPCOMP=y
|
||||
CONFIG_IPV6_MIP6=y
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=y
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_SCTP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=y
|
||||
CONFIG_NF_CONNTRACK_FTP=y
|
||||
CONFIG_NF_CONNTRACK_H323=y
|
||||
CONFIG_NF_CONNTRACK_IRC=y
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
|
||||
CONFIG_NF_CONNTRACK_PPTP=y
|
||||
CONFIG_NF_CONNTRACK_SANE=y
|
||||
CONFIG_NF_CONNTRACK_TFTP=y
|
||||
CONFIG_NF_CT_NETLINK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=y
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=y
|
||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=y
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=y
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=y
|
||||
CONFIG_NF_CONNTRACK_IPV4=y
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
CONFIG_IP_NF_MATCH_AH=y
|
||||
CONFIG_IP_NF_MATCH_ECN=y
|
||||
CONFIG_IP_NF_MATCH_TTL=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_TARGET_REJECT=y
|
||||
CONFIG_IP_NF_MANGLE=y
|
||||
CONFIG_IP_NF_RAW=y
|
||||
CONFIG_IP_NF_SECURITY=y
|
||||
CONFIG_IP_NF_ARPTABLES=y
|
||||
CONFIG_IP_NF_ARPFILTER=y
|
||||
CONFIG_IP_NF_ARP_MANGLE=y
|
||||
CONFIG_NF_CONNTRACK_IPV6=y
|
||||
CONFIG_IP6_NF_IPTABLES=y
|
||||
CONFIG_IP6_NF_FILTER=y
|
||||
CONFIG_IP6_NF_TARGET_REJECT=y
|
||||
CONFIG_IP6_NF_MANGLE=y
|
||||
CONFIG_IP6_NF_RAW=y
|
||||
CONFIG_BRIDGE=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=y
|
||||
CONFIG_NET_CLS_U32=y
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_EMATCH_U32=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
CONFIG_MTD_CFI=y
|
||||
CONFIG_MTD_CFI_INTELEXT=y
|
||||
CONFIG_MTD_CFI_AMDSTD=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=8192
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_TUN=y
|
||||
CONFIG_VIRTIO_NET=y
|
||||
CONFIG_SMSC911X=y
|
||||
CONFIG_PPP=y
|
||||
CONFIG_PPP_BSDCOMP=y
|
||||
CONFIG_PPP_DEFLATE=y
|
||||
CONFIG_PPP_MPPE=y
|
||||
CONFIG_PPPOLAC=y
|
||||
CONFIG_PPPOPNS=y
|
||||
CONFIG_USB_USBNET=y
|
||||
# CONFIG_WLAN is not set
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_INPUT_KEYRESET=y
|
||||
CONFIG_KEYBOARD_GOLDFISH_EVENTS=y
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_JOYSTICK=y
|
||||
CONFIG_JOYSTICK_XPAD=y
|
||||
CONFIG_JOYSTICK_XPAD_FF=y
|
||||
CONFIG_JOYSTICK_XPAD_LEDS=y
|
||||
CONFIG_INPUT_TABLET=y
|
||||
CONFIG_TABLET_USB_ACECAD=y
|
||||
CONFIG_TABLET_USB_AIPTEK=y
|
||||
CONFIG_TABLET_USB_GTCO=y
|
||||
CONFIG_TABLET_USB_HANWANG=y
|
||||
CONFIG_TABLET_USB_KBTAB=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_KEYCHORD=y
|
||||
CONFIG_INPUT_UINPUT=y
|
||||
CONFIG_INPUT_GPIO=y
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
CONFIG_SERIO_AMBAKMI=y
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVMEM is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_AMBA_PL011=y
|
||||
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_GOLDFISH=y
|
||||
CONFIG_FB_SIMPLE=y
|
||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
# CONFIG_LOGO_LINUX_VGA16 is not set
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_HIDRAW=y
|
||||
CONFIG_UHID=y
|
||||
CONFIG_HID_A4TECH=y
|
||||
CONFIG_HID_ACRUX=y
|
||||
CONFIG_HID_ACRUX_FF=y
|
||||
CONFIG_HID_APPLE=y
|
||||
CONFIG_HID_BELKIN=y
|
||||
CONFIG_HID_CHERRY=y
|
||||
CONFIG_HID_CHICONY=y
|
||||
CONFIG_HID_PRODIKEYS=y
|
||||
CONFIG_HID_CYPRESS=y
|
||||
CONFIG_HID_DRAGONRISE=y
|
||||
CONFIG_DRAGONRISE_FF=y
|
||||
CONFIG_HID_EMS_FF=y
|
||||
CONFIG_HID_ELECOM=y
|
||||
CONFIG_HID_EZKEY=y
|
||||
CONFIG_HID_HOLTEK=y
|
||||
CONFIG_HID_KEYTOUCH=y
|
||||
CONFIG_HID_KYE=y
|
||||
CONFIG_HID_UCLOGIC=y
|
||||
CONFIG_HID_WALTOP=y
|
||||
CONFIG_HID_GYRATION=y
|
||||
CONFIG_HID_TWINHAN=y
|
||||
CONFIG_HID_KENSINGTON=y
|
||||
CONFIG_HID_LCPOWER=y
|
||||
CONFIG_HID_LOGITECH=y
|
||||
CONFIG_HID_LOGITECH_DJ=y
|
||||
CONFIG_LOGITECH_FF=y
|
||||
CONFIG_LOGIRUMBLEPAD2_FF=y
|
||||
CONFIG_LOGIG940_FF=y
|
||||
CONFIG_HID_MAGICMOUSE=y
|
||||
CONFIG_HID_MICROSOFT=y
|
||||
CONFIG_HID_MONTEREY=y
|
||||
CONFIG_HID_MULTITOUCH=y
|
||||
CONFIG_HID_NTRIG=y
|
||||
CONFIG_HID_ORTEK=y
|
||||
CONFIG_HID_PANTHERLORD=y
|
||||
CONFIG_PANTHERLORD_FF=y
|
||||
CONFIG_HID_PETALYNX=y
|
||||
CONFIG_HID_PICOLCD=y
|
||||
CONFIG_HID_PRIMAX=y
|
||||
CONFIG_HID_ROCCAT=y
|
||||
CONFIG_HID_SAITEK=y
|
||||
CONFIG_HID_SAMSUNG=y
|
||||
CONFIG_HID_SONY=y
|
||||
CONFIG_HID_SPEEDLINK=y
|
||||
CONFIG_HID_SUNPLUS=y
|
||||
CONFIG_HID_GREENASIA=y
|
||||
CONFIG_GREENASIA_FF=y
|
||||
CONFIG_HID_SMARTJOYPLUS=y
|
||||
CONFIG_SMARTJOYPLUS_FF=y
|
||||
CONFIG_HID_TIVO=y
|
||||
CONFIG_HID_TOPSEED=y
|
||||
CONFIG_HID_THRUSTMASTER=y
|
||||
CONFIG_HID_WACOM=y
|
||||
CONFIG_HID_WIIMOTE=y
|
||||
CONFIG_HID_ZEROPLUS=y
|
||||
CONFIG_HID_ZYDACRON=y
|
||||
CONFIG_USB_HIDDEV=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_OTG_WAKELOCK=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_PL031=y
|
||||
CONFIG_VIRTIO_MMIO=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_ASHMEM=y
|
||||
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
|
||||
CONFIG_SYNC=y
|
||||
CONFIG_SW_SYNC=y
|
||||
CONFIG_SW_SYNC_USER=y
|
||||
CONFIG_ION=y
|
||||
CONFIG_GOLDFISH_AUDIO=y
|
||||
CONFIG_GOLDFISH=y
|
||||
CONFIG_GOLDFISH_PIPE=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_PSTORE=y
|
||||
CONFIG_PSTORE_CONSOLE=y
|
||||
CONFIG_PSTORE_RAM=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_ROOT_NFS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_PANIC_TIMEOUT=5
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_SCHEDSTATS=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_ENABLE_DEFAULT_TRACERS=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_VIRTUALIZATION=y
|
|
@ -279,7 +279,7 @@ static int ctr_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
|||
err = blkcipher_walk_done(desc, &walk,
|
||||
walk.nbytes % AES_BLOCK_SIZE);
|
||||
}
|
||||
if (nbytes) {
|
||||
if (walk.nbytes % AES_BLOCK_SIZE) {
|
||||
u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
|
||||
u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
|
||||
u8 __aligned(8) tail[AES_BLOCK_SIZE];
|
||||
|
|
|
@ -226,6 +226,27 @@ static int ghash_async_digest(struct ahash_request *req)
|
|||
}
|
||||
}
|
||||
|
||||
static int ghash_async_import(struct ahash_request *req, const void *in)
|
||||
{
|
||||
struct ahash_request *cryptd_req = ahash_request_ctx(req);
|
||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||
struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
|
||||
struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
|
||||
|
||||
desc->tfm = cryptd_ahash_child(ctx->cryptd_tfm);
|
||||
desc->flags = req->base.flags;
|
||||
|
||||
return crypto_shash_import(desc, in);
|
||||
}
|
||||
|
||||
static int ghash_async_export(struct ahash_request *req, void *out)
|
||||
{
|
||||
struct ahash_request *cryptd_req = ahash_request_ctx(req);
|
||||
struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
|
||||
|
||||
return crypto_shash_export(desc, out);
|
||||
}
|
||||
|
||||
static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
|
@ -274,7 +295,10 @@ static struct ahash_alg ghash_async_alg = {
|
|||
.final = ghash_async_final,
|
||||
.setkey = ghash_async_setkey,
|
||||
.digest = ghash_async_digest,
|
||||
.import = ghash_async_import,
|
||||
.export = ghash_async_export,
|
||||
.halg.digestsize = GHASH_DIGEST_SIZE,
|
||||
.halg.statesize = sizeof(struct ghash_desc_ctx),
|
||||
.halg.base = {
|
||||
.cra_name = "ghash",
|
||||
.cra_driver_name = "ghash-ce",
|
||||
|
|
|
@ -30,7 +30,7 @@ static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
|
|||
struct device_node;
|
||||
|
||||
struct cpuidle_ops {
|
||||
int (*suspend)(int cpu, unsigned long arg);
|
||||
int (*suspend)(unsigned long arg);
|
||||
int (*init)(struct device_node *, int cpu);
|
||||
};
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
|
|||
/* The ARM override for dma_max_pfn() */
|
||||
static inline unsigned long dma_max_pfn(struct device *dev)
|
||||
{
|
||||
return PHYS_PFN_OFFSET + dma_to_pfn(dev, *dev->dma_mask);
|
||||
return dma_to_pfn(dev, *dev->dma_mask);
|
||||
}
|
||||
#define dma_max_pfn(dev) dma_max_pfn(dev)
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#define fd_outb(val,port) \
|
||||
do { \
|
||||
if ((port) == FD_DOR) \
|
||||
if ((port) == (u32)FD_DOR) \
|
||||
fd_setdor((val)); \
|
||||
else \
|
||||
outb((val),(port)); \
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#ifndef __ARM_KVM_ARM_H__
|
||||
#define __ARM_KVM_ARM_H__
|
||||
|
||||
#include <linux/const.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Hyp Configuration Register (HCR) bits */
|
||||
|
@ -132,10 +133,9 @@
|
|||
* space.
|
||||
*/
|
||||
#define KVM_PHYS_SHIFT (40)
|
||||
#define KVM_PHYS_SIZE (1ULL << KVM_PHYS_SHIFT)
|
||||
#define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1ULL)
|
||||
#define PTRS_PER_S2_PGD (1ULL << (KVM_PHYS_SHIFT - 30))
|
||||
#define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t))
|
||||
#define KVM_PHYS_SIZE (_AC(1, ULL) << KVM_PHYS_SHIFT)
|
||||
#define KVM_PHYS_MASK (KVM_PHYS_SIZE - _AC(1, ULL))
|
||||
#define PTRS_PER_S2_PGD (_AC(1, ULL) << (KVM_PHYS_SHIFT - 30))
|
||||
|
||||
/* Virtualization Translation Control Register (VTCR) bits */
|
||||
#define VTCR_SH0 (3 << 12)
|
||||
|
@ -162,17 +162,17 @@
|
|||
#define VTTBR_X (5 - KVM_T0SZ)
|
||||
#endif
|
||||
#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
|
||||
#define VTTBR_BADDR_MASK (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
|
||||
#define VTTBR_VMID_SHIFT (48LLU)
|
||||
#define VTTBR_VMID_MASK (0xffLLU << VTTBR_VMID_SHIFT)
|
||||
#define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
|
||||
#define VTTBR_VMID_SHIFT _AC(48, ULL)
|
||||
#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
|
||||
|
||||
/* Hyp Syndrome Register (HSR) bits */
|
||||
#define HSR_EC_SHIFT (26)
|
||||
#define HSR_EC (0x3fU << HSR_EC_SHIFT)
|
||||
#define HSR_IL (1U << 25)
|
||||
#define HSR_EC (_AC(0x3f, UL) << HSR_EC_SHIFT)
|
||||
#define HSR_IL (_AC(1, UL) << 25)
|
||||
#define HSR_ISS (HSR_IL - 1)
|
||||
#define HSR_ISV_SHIFT (24)
|
||||
#define HSR_ISV (1U << HSR_ISV_SHIFT)
|
||||
#define HSR_ISV (_AC(1, UL) << HSR_ISV_SHIFT)
|
||||
#define HSR_SRT_SHIFT (16)
|
||||
#define HSR_SRT_MASK (0xf << HSR_SRT_SHIFT)
|
||||
#define HSR_FSC (0x3f)
|
||||
|
@ -180,9 +180,9 @@
|
|||
#define HSR_SSE (1 << 21)
|
||||
#define HSR_WNR (1 << 6)
|
||||
#define HSR_CV_SHIFT (24)
|
||||
#define HSR_CV (1U << HSR_CV_SHIFT)
|
||||
#define HSR_CV (_AC(1, UL) << HSR_CV_SHIFT)
|
||||
#define HSR_COND_SHIFT (20)
|
||||
#define HSR_COND (0xfU << HSR_COND_SHIFT)
|
||||
#define HSR_COND (_AC(0xf, UL) << HSR_COND_SHIFT)
|
||||
|
||||
#define FSC_FAULT (0x04)
|
||||
#define FSC_ACCESS (0x08)
|
||||
|
@ -210,13 +210,13 @@
|
|||
#define HSR_EC_DABT (0x24)
|
||||
#define HSR_EC_DABT_HYP (0x25)
|
||||
|
||||
#define HSR_WFI_IS_WFE (1U << 0)
|
||||
#define HSR_WFI_IS_WFE (_AC(1, UL) << 0)
|
||||
|
||||
#define HSR_HVC_IMM_MASK ((1UL << 16) - 1)
|
||||
#define HSR_HVC_IMM_MASK ((_AC(1, UL) << 16) - 1)
|
||||
|
||||
#define HSR_DABT_S1PTW (1U << 7)
|
||||
#define HSR_DABT_CM (1U << 8)
|
||||
#define HSR_DABT_EA (1U << 9)
|
||||
#define HSR_DABT_S1PTW (_AC(1, UL) << 7)
|
||||
#define HSR_DABT_CM (_AC(1, UL) << 8)
|
||||
#define HSR_DABT_EA (_AC(1, UL) << 9)
|
||||
|
||||
#define kvm_arm_exception_type \
|
||||
{0, "RESET" }, \
|
||||
|
|
|
@ -214,6 +214,19 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
|
|||
kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr);
|
||||
}
|
||||
|
||||
static inline void __cpu_init_stage2(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void __cpu_reset_hyp_mode(phys_addr_t boot_pgd_ptr,
|
||||
phys_addr_t phys_idmap_start)
|
||||
{
|
||||
/*
|
||||
* TODO
|
||||
* kvm_call_reset(boot_pgd_ptr, phys_idmap_start);
|
||||
*/
|
||||
}
|
||||
|
||||
static inline int kvm_arch_dev_ioctl_check_extension(long ext)
|
||||
{
|
||||
return 0;
|
||||
|
@ -226,7 +239,6 @@ void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
|
|||
|
||||
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
|
||||
|
||||
static inline void kvm_arch_hardware_disable(void) {}
|
||||
static inline void kvm_arch_hardware_unsetup(void) {}
|
||||
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
|
||||
static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
|
||||
|
|
|
@ -66,6 +66,7 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
|
|||
phys_addr_t kvm_mmu_get_httbr(void);
|
||||
phys_addr_t kvm_mmu_get_boot_httbr(void);
|
||||
phys_addr_t kvm_get_idmap_vector(void);
|
||||
phys_addr_t kvm_get_idmap_start(void);
|
||||
int kvm_mmu_init(void);
|
||||
void kvm_clear_hyp_idmap(void);
|
||||
|
||||
|
@ -279,6 +280,11 @@ static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd,
|
|||
pgd_t *merged_hyp_pgd,
|
||||
unsigned long hyp_idmap_start) { }
|
||||
|
||||
static inline unsigned int kvm_get_vmid_bits(void)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ARM_KVM_MMU_H__ */
|
||||
|
|
|
@ -250,6 +250,7 @@ PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF);
|
|||
PMD_BIT_FUNC(mksplitting, |= L_PMD_SECT_SPLITTING);
|
||||
PMD_BIT_FUNC(mkwrite, &= ~L_PMD_SECT_RDONLY);
|
||||
PMD_BIT_FUNC(mkdirty, |= L_PMD_SECT_DIRTY);
|
||||
PMD_BIT_FUNC(mkclean, &= ~L_PMD_SECT_DIRTY);
|
||||
PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
|
||||
|
||||
#define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
|
||||
|
|
|
@ -121,7 +121,6 @@ extern unsigned long profile_pc(struct pt_regs *regs);
|
|||
#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0))
|
||||
|
||||
extern int regs_query_register_offset(const char *name);
|
||||
extern const char *regs_query_register_name(unsigned int offset);
|
||||
extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
|
||||
extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
|
||||
unsigned int n);
|
||||
|
|
|
@ -74,6 +74,15 @@ static inline bool is_hyp_mode_mismatched(void)
|
|||
{
|
||||
return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH);
|
||||
}
|
||||
|
||||
static inline bool is_kernel_in_hyp_mode(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The section containing the hypervisor text */
|
||||
extern char __hyp_text_start[];
|
||||
extern char __hyp_text_end[];
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
|
|
@ -88,8 +88,9 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
|||
|
||||
obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o
|
||||
ifeq ($(CONFIG_ARM_PSCI),y)
|
||||
obj-y += psci-call.o
|
||||
obj-$(CONFIG_SMP) += psci_smp.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o
|
||||
|
||||
extra-y := $(head-y) vmlinux.lds
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/syscalls.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/arm-smccc.h>
|
||||
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
@ -175,3 +176,8 @@ EXPORT_SYMBOL(__gnu_mcount_nc);
|
|||
EXPORT_SYMBOL(__pv_phys_pfn_offset);
|
||||
EXPORT_SYMBOL(__pv_offset);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_SMCCC
|
||||
EXPORT_SYMBOL(arm_smccc_smc);
|
||||
EXPORT_SYMBOL(arm_smccc_hvc);
|
||||
#endif
|
||||
|
|
|
@ -56,7 +56,7 @@ int arm_cpuidle_suspend(int index)
|
|||
int cpu = smp_processor_id();
|
||||
|
||||
if (cpuidle_ops[cpu].suspend)
|
||||
ret = cpuidle_ops[cpu].suspend(cpu, index);
|
||||
ret = cpuidle_ops[cpu].suspend(index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ void __init arm_dt_init_cpu_maps(void)
|
|||
return;
|
||||
|
||||
for_each_child_of_node(cpus, cpu) {
|
||||
int prop_bytes;
|
||||
u32 hwid;
|
||||
const __be32 *cell;
|
||||
|
||||
|
@ -107,10 +108,15 @@ void __init arm_dt_init_cpu_maps(void)
|
|||
}
|
||||
hwid = of_read_number(cell, of_n_addr_cells(cpu));
|
||||
/*
|
||||
* 8 MSBs must be set to 0 in the DT since the reg property
|
||||
* Bits n:24 must be set to 0 in the DT since the reg property
|
||||
* defines the MPIDR[23:0].
|
||||
*/
|
||||
if (hwid & ~MPIDR_HWID_BITMASK) {
|
||||
do {
|
||||
hwid = be32_to_cpu(*cell++);
|
||||
prop_bytes -= sizeof(*cell);
|
||||
} while (!hwid && prop_bytes > 0);
|
||||
|
||||
if (prop_bytes || (hwid & ~MPIDR_HWID_BITMASK)) {
|
||||
of_node_put(cpu);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2015 ARM Limited
|
||||
*
|
||||
* Author: Mark Rutland <mark.rutland@arm.com>
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/opcodes-sec.h>
|
||||
#include <asm/opcodes-virt.h>
|
||||
|
||||
/* int __invoke_psci_fn_hvc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */
|
||||
ENTRY(__invoke_psci_fn_hvc)
|
||||
__HVC(0)
|
||||
bx lr
|
||||
ENDPROC(__invoke_psci_fn_hvc)
|
||||
|
||||
/* int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */
|
||||
ENTRY(__invoke_psci_fn_smc)
|
||||
__SMC(0)
|
||||
bx lr
|
||||
ENDPROC(__invoke_psci_fn_smc)
|
62
arch/arm/kernel/smccc-call.S
Normal file
62
arch/arm/kernel/smccc-call.S
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Linaro Limited
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/opcodes-sec.h>
|
||||
#include <asm/opcodes-virt.h>
|
||||
#include <asm/unwind.h>
|
||||
|
||||
/*
|
||||
* Wrap c macros in asm macros to delay expansion until after the
|
||||
* SMCCC asm macro is expanded.
|
||||
*/
|
||||
.macro SMCCC_SMC
|
||||
__SMC(0)
|
||||
.endm
|
||||
|
||||
.macro SMCCC_HVC
|
||||
__HVC(0)
|
||||
.endm
|
||||
|
||||
.macro SMCCC instr
|
||||
UNWIND( .fnstart)
|
||||
mov r12, sp
|
||||
push {r4-r7}
|
||||
UNWIND( .save {r4-r7})
|
||||
ldm r12, {r4-r7}
|
||||
\instr
|
||||
pop {r4-r7}
|
||||
ldr r12, [sp, #(4 * 4)]
|
||||
stm r12, {r0-r3}
|
||||
bx lr
|
||||
UNWIND( .fnend)
|
||||
.endm
|
||||
|
||||
/*
|
||||
* void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
|
||||
* unsigned long a3, unsigned long a4, unsigned long a5,
|
||||
* unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
|
||||
*/
|
||||
ENTRY(arm_smccc_smc)
|
||||
SMCCC SMCCC_SMC
|
||||
ENDPROC(arm_smccc_smc)
|
||||
|
||||
/*
|
||||
* void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
|
||||
* unsigned long a3, unsigned long a4, unsigned long a5,
|
||||
* unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
|
||||
*/
|
||||
ENTRY(arm_smccc_hvc)
|
||||
SMCCC SMCCC_HVC
|
||||
ENDPROC(arm_smccc_hvc)
|
|
@ -16,7 +16,6 @@
|
|||
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -44,6 +43,7 @@
|
|||
#include <asm/kvm_emulate.h>
|
||||
#include <asm/kvm_coproc.h>
|
||||
#include <asm/kvm_psci.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
#ifdef REQUIRES_VIRT
|
||||
__asm__(".arch_extension virt");
|
||||
|
@ -58,9 +58,14 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
|
|||
|
||||
/* The VMID used in the VTTBR */
|
||||
static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
|
||||
static u8 kvm_next_vmid;
|
||||
static u32 kvm_next_vmid;
|
||||
static unsigned int kvm_vmid_bits __read_mostly;
|
||||
static DEFINE_SPINLOCK(kvm_vmid_lock);
|
||||
|
||||
static bool vgic_present;
|
||||
|
||||
static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled);
|
||||
|
||||
static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
BUG_ON(preemptible());
|
||||
|
@ -85,11 +90,6 @@ struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void)
|
|||
return &kvm_arm_running_vcpu;
|
||||
}
|
||||
|
||||
int kvm_arch_hardware_enable(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
|
||||
|
@ -132,7 +132,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
kvm->arch.vmid_gen = 0;
|
||||
|
||||
/* The maximum number of VCPUs is limited by the host's GIC model */
|
||||
kvm->arch.max_vcpus = kvm_vgic_get_max_vcpus();
|
||||
kvm->arch.max_vcpus = vgic_present ?
|
||||
kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
|
||||
|
||||
return ret;
|
||||
out_free_stage2_pgd:
|
||||
|
@ -155,8 +156,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
|
|||
{
|
||||
int i;
|
||||
|
||||
kvm_free_stage2_pgd(kvm);
|
||||
|
||||
for (i = 0; i < KVM_MAX_VCPUS; ++i) {
|
||||
if (kvm->vcpus[i]) {
|
||||
kvm_arch_vcpu_free(kvm->vcpus[i]);
|
||||
|
@ -172,6 +171,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
|||
int r;
|
||||
switch (ext) {
|
||||
case KVM_CAP_IRQCHIP:
|
||||
r = vgic_present;
|
||||
break;
|
||||
case KVM_CAP_IOEVENTFD:
|
||||
case KVM_CAP_DEVICE_CTRL:
|
||||
case KVM_CAP_USER_MEMORY:
|
||||
|
@ -433,11 +434,12 @@ static void update_vttbr(struct kvm *kvm)
|
|||
kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen);
|
||||
kvm->arch.vmid = kvm_next_vmid;
|
||||
kvm_next_vmid++;
|
||||
kvm_next_vmid &= (1 << kvm_vmid_bits) - 1;
|
||||
|
||||
/* update vttbr to be used with the new vmid */
|
||||
pgd_phys = virt_to_phys(kvm_get_hwpgd(kvm));
|
||||
BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK);
|
||||
vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK;
|
||||
vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits);
|
||||
kvm->arch.vttbr = pgd_phys | vmid;
|
||||
|
||||
spin_unlock(&kvm_vmid_lock);
|
||||
|
@ -913,6 +915,8 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
|
|||
|
||||
switch (dev_id) {
|
||||
case KVM_ARM_DEVICE_VGIC_V2:
|
||||
if (!vgic_present)
|
||||
return -ENXIO;
|
||||
return kvm_vgic_addr(kvm, type, &dev_addr->addr, true);
|
||||
default:
|
||||
return -ENODEV;
|
||||
|
@ -927,6 +931,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
|
|||
|
||||
switch (ioctl) {
|
||||
case KVM_CREATE_IRQCHIP: {
|
||||
if (!vgic_present)
|
||||
return -ENXIO;
|
||||
return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
|
||||
}
|
||||
case KVM_ARM_SET_DEVICE_ADDR: {
|
||||
|
@ -972,40 +978,96 @@ static void cpu_init_hyp_mode(void *dummy)
|
|||
vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);
|
||||
|
||||
__cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
|
||||
__cpu_init_stage2();
|
||||
|
||||
kvm_arm_init_debug();
|
||||
}
|
||||
|
||||
static int hyp_init_cpu_notify(struct notifier_block *self,
|
||||
unsigned long action, void *cpu)
|
||||
static void cpu_hyp_reinit(void)
|
||||
{
|
||||
switch (action) {
|
||||
case CPU_STARTING:
|
||||
case CPU_STARTING_FROZEN:
|
||||
if (is_kernel_in_hyp_mode()) {
|
||||
/*
|
||||
* __cpu_init_stage2() is safe to call even if the PM
|
||||
* event was cancelled before the CPU was reset.
|
||||
*/
|
||||
__cpu_init_stage2();
|
||||
} else {
|
||||
if (__hyp_get_vectors() == hyp_default_vectors)
|
||||
cpu_init_hyp_mode(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block hyp_init_cpu_nb = {
|
||||
.notifier_call = hyp_init_cpu_notify,
|
||||
};
|
||||
static void cpu_hyp_reset(void)
|
||||
{
|
||||
phys_addr_t boot_pgd_ptr;
|
||||
phys_addr_t phys_idmap_start;
|
||||
|
||||
if (!is_kernel_in_hyp_mode()) {
|
||||
boot_pgd_ptr = kvm_mmu_get_boot_httbr();
|
||||
phys_idmap_start = kvm_get_idmap_start();
|
||||
|
||||
__cpu_reset_hyp_mode(boot_pgd_ptr, phys_idmap_start);
|
||||
}
|
||||
}
|
||||
|
||||
static void _kvm_arch_hardware_enable(void *discard)
|
||||
{
|
||||
if (!__this_cpu_read(kvm_arm_hardware_enabled)) {
|
||||
cpu_hyp_reinit();
|
||||
__this_cpu_write(kvm_arm_hardware_enabled, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_arch_hardware_enable(void)
|
||||
{
|
||||
_kvm_arch_hardware_enable(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _kvm_arch_hardware_disable(void *discard)
|
||||
{
|
||||
if (__this_cpu_read(kvm_arm_hardware_enabled)) {
|
||||
cpu_hyp_reset();
|
||||
__this_cpu_write(kvm_arm_hardware_enabled, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_arch_hardware_disable(void)
|
||||
{
|
||||
_kvm_arch_hardware_disable(NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_PM
|
||||
static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
|
||||
unsigned long cmd,
|
||||
void *v)
|
||||
{
|
||||
if (cmd == CPU_PM_EXIT &&
|
||||
__hyp_get_vectors() == hyp_default_vectors) {
|
||||
cpu_init_hyp_mode(NULL);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
/*
|
||||
* kvm_arm_hardware_enabled is left with its old value over
|
||||
* PM_ENTER->PM_EXIT. It is used to indicate PM_EXIT should
|
||||
* re-enable hyp.
|
||||
*/
|
||||
switch (cmd) {
|
||||
case CPU_PM_ENTER:
|
||||
if (__this_cpu_read(kvm_arm_hardware_enabled))
|
||||
/*
|
||||
* don't update kvm_arm_hardware_enabled here
|
||||
* so that the hardware will be re-enabled
|
||||
* when we resume. See below.
|
||||
*/
|
||||
cpu_hyp_reset();
|
||||
|
||||
return NOTIFY_DONE;
|
||||
return NOTIFY_OK;
|
||||
case CPU_PM_EXIT:
|
||||
if (__this_cpu_read(kvm_arm_hardware_enabled))
|
||||
/* The hardware was enabled before suspend. */
|
||||
cpu_hyp_reinit();
|
||||
|
||||
return NOTIFY_OK;
|
||||
|
||||
default:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
static struct notifier_block hyp_init_cpu_pm_nb = {
|
||||
|
@ -1022,6 +1084,91 @@ static inline void hyp_cpu_pm_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void teardown_common_resources(void)
|
||||
{
|
||||
free_percpu(kvm_host_cpu_state);
|
||||
}
|
||||
|
||||
static int init_common_resources(void)
|
||||
{
|
||||
kvm_host_cpu_state = alloc_percpu(kvm_cpu_context_t);
|
||||
if (!kvm_host_cpu_state) {
|
||||
kvm_err("Cannot allocate host CPU state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_subsystems(void)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
/*
|
||||
* Enable hardware so that subsystem initialisation can access EL2.
|
||||
*/
|
||||
on_each_cpu(_kvm_arch_hardware_enable, NULL, 1);
|
||||
|
||||
/*
|
||||
* Register CPU lower-power notifier
|
||||
*/
|
||||
hyp_cpu_pm_init();
|
||||
|
||||
/*
|
||||
* Init HYP view of VGIC
|
||||
*/
|
||||
err = kvm_vgic_hyp_init();
|
||||
switch (err) {
|
||||
case 0:
|
||||
vgic_present = true;
|
||||
break;
|
||||
case -ENODEV:
|
||||
case -ENXIO:
|
||||
vgic_present = false;
|
||||
err = 0;
|
||||
break;
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Init HYP architected timer support
|
||||
*/
|
||||
err = kvm_timer_hyp_init();
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
kvm_perf_init();
|
||||
kvm_coproc_table_init();
|
||||
|
||||
out:
|
||||
on_each_cpu(_kvm_arch_hardware_disable, NULL, 1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void teardown_hyp_mode(void)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
if (is_kernel_in_hyp_mode())
|
||||
return;
|
||||
|
||||
free_hyp_pgds();
|
||||
for_each_possible_cpu(cpu)
|
||||
free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
|
||||
}
|
||||
|
||||
static int init_vhe_mode(void)
|
||||
{
|
||||
/* set size of VMID supported by CPU */
|
||||
kvm_vmid_bits = kvm_get_vmid_bits();
|
||||
kvm_info("%d-bit VMID\n", kvm_vmid_bits);
|
||||
|
||||
kvm_info("VHE mode initialized successfully\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits Hyp-mode on all online CPUs
|
||||
*/
|
||||
|
@ -1052,7 +1199,7 @@ static int init_hyp_mode(void)
|
|||
stack_page = __get_free_page(GFP_KERNEL);
|
||||
if (!stack_page) {
|
||||
err = -ENOMEM;
|
||||
goto out_free_stack_pages;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
per_cpu(kvm_arm_hyp_stack_page, cpu) = stack_page;
|
||||
|
@ -1065,7 +1212,14 @@ static int init_hyp_mode(void)
|
|||
kvm_ksym_ref(__kvm_hyp_code_end));
|
||||
if (err) {
|
||||
kvm_err("Cannot map world-switch code\n");
|
||||
goto out_free_mappings;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
err = create_hyp_mappings(kvm_ksym_ref(__start_rodata),
|
||||
kvm_ksym_ref(__end_rodata));
|
||||
if (err) {
|
||||
kvm_err("Cannot map rodata section\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1077,20 +1231,10 @@ static int init_hyp_mode(void)
|
|||
|
||||
if (err) {
|
||||
kvm_err("Cannot map hyp stack\n");
|
||||
goto out_free_mappings;
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the host CPU structures
|
||||
*/
|
||||
kvm_host_cpu_state = alloc_percpu(kvm_cpu_context_t);
|
||||
if (!kvm_host_cpu_state) {
|
||||
err = -ENOMEM;
|
||||
kvm_err("Cannot allocate host CPU state\n");
|
||||
goto out_free_mappings;
|
||||
}
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
kvm_cpu_context_t *cpu_ctxt;
|
||||
|
||||
|
@ -1099,46 +1243,24 @@ static int init_hyp_mode(void)
|
|||
|
||||
if (err) {
|
||||
kvm_err("Cannot map host CPU state: %d\n", err);
|
||||
goto out_free_context;
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the init code on each CPU.
|
||||
*/
|
||||
on_each_cpu(cpu_init_hyp_mode, NULL, 1);
|
||||
|
||||
/*
|
||||
* Init HYP view of VGIC
|
||||
*/
|
||||
err = kvm_vgic_hyp_init();
|
||||
if (err)
|
||||
goto out_free_context;
|
||||
|
||||
/*
|
||||
* Init HYP architected timer support
|
||||
*/
|
||||
err = kvm_timer_hyp_init();
|
||||
if (err)
|
||||
goto out_free_context;
|
||||
|
||||
#ifndef CONFIG_HOTPLUG_CPU
|
||||
free_boot_hyp_pgd();
|
||||
#endif
|
||||
|
||||
kvm_perf_init();
|
||||
/* set size of VMID supported by CPU */
|
||||
kvm_vmid_bits = kvm_get_vmid_bits();
|
||||
kvm_info("%d-bit VMID\n", kvm_vmid_bits);
|
||||
|
||||
kvm_info("Hyp mode initialized successfully\n");
|
||||
|
||||
return 0;
|
||||
out_free_context:
|
||||
free_percpu(kvm_host_cpu_state);
|
||||
out_free_mappings:
|
||||
free_hyp_pgds();
|
||||
out_free_stack_pages:
|
||||
for_each_possible_cpu(cpu)
|
||||
free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
|
||||
|
||||
out_err:
|
||||
teardown_hyp_mode();
|
||||
kvm_err("error initializing Hyp mode: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
@ -1182,26 +1304,27 @@ int kvm_arch_init(void *opaque)
|
|||
}
|
||||
}
|
||||
|
||||
cpu_notifier_register_begin();
|
||||
err = init_common_resources();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = init_hyp_mode();
|
||||
if (is_kernel_in_hyp_mode())
|
||||
err = init_vhe_mode();
|
||||
else
|
||||
err = init_hyp_mode();
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
||||
err = __register_cpu_notifier(&hyp_init_cpu_nb);
|
||||
if (err) {
|
||||
kvm_err("Cannot register HYP init CPU notifier (%d)\n", err);
|
||||
goto out_err;
|
||||
}
|
||||
err = init_subsystems();
|
||||
if (err)
|
||||
goto out_hyp;
|
||||
|
||||
cpu_notifier_register_done();
|
||||
|
||||
hyp_cpu_pm_init();
|
||||
|
||||
kvm_coproc_table_init();
|
||||
return 0;
|
||||
|
||||
out_hyp:
|
||||
teardown_hyp_mode();
|
||||
out_err:
|
||||
cpu_notifier_register_done();
|
||||
teardown_common_resources();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -275,6 +275,40 @@ static u32 exc_vector_base(struct kvm_vcpu *vcpu)
|
|||
return vbar;
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch to an exception mode, updating both CPSR and SPSR. Follow
|
||||
* the logic described in AArch32.EnterMode() from the ARMv8 ARM.
|
||||
*/
|
||||
static void kvm_update_psr(struct kvm_vcpu *vcpu, unsigned long mode)
|
||||
{
|
||||
unsigned long cpsr = *vcpu_cpsr(vcpu);
|
||||
u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
|
||||
|
||||
*vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | mode;
|
||||
|
||||
switch (mode) {
|
||||
case FIQ_MODE:
|
||||
*vcpu_cpsr(vcpu) |= PSR_F_BIT;
|
||||
/* Fall through */
|
||||
case ABT_MODE:
|
||||
case IRQ_MODE:
|
||||
*vcpu_cpsr(vcpu) |= PSR_A_BIT;
|
||||
/* Fall through */
|
||||
default:
|
||||
*vcpu_cpsr(vcpu) |= PSR_I_BIT;
|
||||
}
|
||||
|
||||
*vcpu_cpsr(vcpu) &= ~(PSR_IT_MASK | PSR_J_BIT | PSR_E_BIT | PSR_T_BIT);
|
||||
|
||||
if (sctlr & SCTLR_TE)
|
||||
*vcpu_cpsr(vcpu) |= PSR_T_BIT;
|
||||
if (sctlr & SCTLR_EE)
|
||||
*vcpu_cpsr(vcpu) |= PSR_E_BIT;
|
||||
|
||||
/* Note: These now point to the mode banked copies */
|
||||
*vcpu_spsr(vcpu) = cpsr;
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_inject_undefined - inject an undefined exception into the guest
|
||||
* @vcpu: The VCPU to receive the undefined exception
|
||||
|
@ -286,29 +320,13 @@ static u32 exc_vector_base(struct kvm_vcpu *vcpu)
|
|||
*/
|
||||
void kvm_inject_undefined(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
unsigned long new_lr_value;
|
||||
unsigned long new_spsr_value;
|
||||
unsigned long cpsr = *vcpu_cpsr(vcpu);
|
||||
u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
|
||||
bool is_thumb = (cpsr & PSR_T_BIT);
|
||||
u32 vect_offset = 4;
|
||||
u32 return_offset = (is_thumb) ? 2 : 4;
|
||||
|
||||
new_spsr_value = cpsr;
|
||||
new_lr_value = *vcpu_pc(vcpu) - return_offset;
|
||||
|
||||
*vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | UND_MODE;
|
||||
*vcpu_cpsr(vcpu) |= PSR_I_BIT;
|
||||
*vcpu_cpsr(vcpu) &= ~(PSR_IT_MASK | PSR_J_BIT | PSR_E_BIT | PSR_T_BIT);
|
||||
|
||||
if (sctlr & SCTLR_TE)
|
||||
*vcpu_cpsr(vcpu) |= PSR_T_BIT;
|
||||
if (sctlr & SCTLR_EE)
|
||||
*vcpu_cpsr(vcpu) |= PSR_E_BIT;
|
||||
|
||||
/* Note: These now point to UND banked copies */
|
||||
*vcpu_spsr(vcpu) = cpsr;
|
||||
*vcpu_reg(vcpu, 14) = new_lr_value;
|
||||
kvm_update_psr(vcpu, UND_MODE);
|
||||
*vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) - return_offset;
|
||||
|
||||
/* Branch to exception vector */
|
||||
*vcpu_pc(vcpu) = exc_vector_base(vcpu) + vect_offset;
|
||||
|
@ -320,30 +338,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
|
|||
*/
|
||||
static void inject_abt(struct kvm_vcpu *vcpu, bool is_pabt, unsigned long addr)
|
||||
{
|
||||
unsigned long new_lr_value;
|
||||
unsigned long new_spsr_value;
|
||||
unsigned long cpsr = *vcpu_cpsr(vcpu);
|
||||
u32 sctlr = vcpu->arch.cp15[c1_SCTLR];
|
||||
bool is_thumb = (cpsr & PSR_T_BIT);
|
||||
u32 vect_offset;
|
||||
u32 return_offset = (is_thumb) ? 4 : 0;
|
||||
bool is_lpae;
|
||||
|
||||
new_spsr_value = cpsr;
|
||||
new_lr_value = *vcpu_pc(vcpu) + return_offset;
|
||||
|
||||
*vcpu_cpsr(vcpu) = (cpsr & ~MODE_MASK) | ABT_MODE;
|
||||
*vcpu_cpsr(vcpu) |= PSR_I_BIT | PSR_A_BIT;
|
||||
*vcpu_cpsr(vcpu) &= ~(PSR_IT_MASK | PSR_J_BIT | PSR_E_BIT | PSR_T_BIT);
|
||||
|
||||
if (sctlr & SCTLR_TE)
|
||||
*vcpu_cpsr(vcpu) |= PSR_T_BIT;
|
||||
if (sctlr & SCTLR_EE)
|
||||
*vcpu_cpsr(vcpu) |= PSR_E_BIT;
|
||||
|
||||
/* Note: These now point to ABT banked copies */
|
||||
*vcpu_spsr(vcpu) = cpsr;
|
||||
*vcpu_reg(vcpu, 14) = new_lr_value;
|
||||
kvm_update_psr(vcpu, ABT_MODE);
|
||||
*vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
|
||||
|
||||
if (is_pabt)
|
||||
vect_offset = 12;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <asm/kvm_mmio.h>
|
||||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_emulate.h>
|
||||
#include <asm/virt.h>
|
||||
|
||||
#include "trace.h"
|
||||
|
||||
|
@ -598,6 +599,9 @@ int create_hyp_mappings(void *from, void *to)
|
|||
unsigned long start = KERN_TO_HYP((unsigned long)from);
|
||||
unsigned long end = KERN_TO_HYP((unsigned long)to);
|
||||
|
||||
if (is_kernel_in_hyp_mode())
|
||||
return 0;
|
||||
|
||||
start = start & PAGE_MASK;
|
||||
end = PAGE_ALIGN(end);
|
||||
|
||||
|
@ -630,6 +634,9 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr)
|
|||
unsigned long start = KERN_TO_HYP((unsigned long)from);
|
||||
unsigned long end = KERN_TO_HYP((unsigned long)to);
|
||||
|
||||
if (is_kernel_in_hyp_mode())
|
||||
return 0;
|
||||
|
||||
/* Check for a valid kernel IO mapping */
|
||||
if (!is_vmalloc_addr(from) || !is_vmalloc_addr(to - 1))
|
||||
return -EINVAL;
|
||||
|
@ -656,9 +663,9 @@ static void *kvm_alloc_hwpgd(void)
|
|||
* kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation.
|
||||
* @kvm: The KVM struct pointer for the VM.
|
||||
*
|
||||
* Allocates the 1st level table only of size defined by S2_PGD_ORDER (can
|
||||
* support either full 40-bit input addresses or limited to 32-bit input
|
||||
* addresses). Clears the allocated pages.
|
||||
* Allocates only the stage-2 HW PGD level table(s) (can support either full
|
||||
* 40-bit input addresses or limited to 32-bit input addresses). Clears the
|
||||
* allocated pages.
|
||||
*
|
||||
* Note we don't need locking here as this is only called when the VM is
|
||||
* created, which can only be done once.
|
||||
|
@ -1648,6 +1655,11 @@ phys_addr_t kvm_get_idmap_vector(void)
|
|||
return hyp_idmap_vector;
|
||||
}
|
||||
|
||||
phys_addr_t kvm_get_idmap_start(void)
|
||||
{
|
||||
return hyp_idmap_start;
|
||||
}
|
||||
|
||||
int kvm_mmu_init(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -1852,6 +1864,7 @@ void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslots *slots)
|
|||
|
||||
void kvm_arch_flush_shadow_all(struct kvm *kvm)
|
||||
{
|
||||
kvm_free_stage2_pgd(kvm);
|
||||
}
|
||||
|
||||
void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
|
||||
|
|
|
@ -295,7 +295,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
|
|||
val &= ~BM_CLPCR_SBYOS;
|
||||
if (cpu_is_imx6sl())
|
||||
val |= BM_CLPCR_BYPASS_PMIC_READY;
|
||||
if (cpu_is_imx6sl() || cpu_is_imx6sx())
|
||||
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
|
||||
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
|
||||
else
|
||||
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
|
||||
|
@ -310,7 +310,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
|
|||
val |= 0x3 << BP_CLPCR_STBY_COUNT;
|
||||
val |= BM_CLPCR_VSTBY;
|
||||
val |= BM_CLPCR_SBYOS;
|
||||
if (cpu_is_imx6sl())
|
||||
if (cpu_is_imx6sl() || cpu_is_imx6sx())
|
||||
val |= BM_CLPCR_BYPASS_PMIC_READY;
|
||||
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
|
||||
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
|
||||
|
|
|
@ -1474,6 +1474,7 @@ static void omap_hwmod_am43xx_rst(void)
|
|||
{
|
||||
RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET);
|
||||
RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET);
|
||||
RSTST(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTST_OFFSET);
|
||||
RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET);
|
||||
}
|
||||
|
||||
|
|
|
@ -723,8 +723,20 @@ static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
|
|||
* display serial interface controller
|
||||
*/
|
||||
|
||||
static struct omap_hwmod_class_sysconfig omap3xxx_dsi_sysc = {
|
||||
.rev_offs = 0x0000,
|
||||
.sysc_offs = 0x0010,
|
||||
.syss_offs = 0x0014,
|
||||
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
|
||||
SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
|
||||
SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
|
||||
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
|
||||
.sysc_fields = &omap_hwmod_sysc_type1,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = {
|
||||
.name = "dsi",
|
||||
.sysc = &omap3xxx_dsi_sysc,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
/* RM RSTST offsets */
|
||||
#define AM43XX_RM_GFX_RSTST_OFFSET 0x0014
|
||||
#define AM43XX_RM_PER_RSTST_OFFSET 0x0014
|
||||
#define AM43XX_RM_WKUP_RSTST_OFFSET 0x0014
|
||||
|
||||
/* CM instances */
|
||||
|
|
|
@ -83,7 +83,8 @@ static struct resource smc91x_resources[] = {
|
|||
};
|
||||
|
||||
static struct smc91x_platdata smc91x_platdata = {
|
||||
.flags = SMC91X_USE_32BIT | SMC91X_USE_DMA | SMC91X_NOWAIT,
|
||||
.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
|
||||
SMC91X_USE_DMA | SMC91X_NOWAIT,
|
||||
};
|
||||
|
||||
static struct platform_device smc91x_device = {
|
||||
|
|
|
@ -41,30 +41,35 @@ static irqreturn_t cplds_irq_handler(int in_irq, void *d)
|
|||
unsigned long pending;
|
||||
unsigned int bit;
|
||||
|
||||
pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
|
||||
for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
|
||||
generic_handle_irq(irq_find_mapping(fpga->irqdomain, bit));
|
||||
do {
|
||||
pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
|
||||
for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) {
|
||||
generic_handle_irq(irq_find_mapping(fpga->irqdomain,
|
||||
bit));
|
||||
}
|
||||
} while (pending);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void cplds_irq_mask_ack(struct irq_data *d)
|
||||
static void cplds_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct cplds *fpga = irq_data_get_irq_chip_data(d);
|
||||
unsigned int cplds_irq = irqd_to_hwirq(d);
|
||||
unsigned int set, bit = BIT(cplds_irq);
|
||||
unsigned int bit = BIT(cplds_irq);
|
||||
|
||||
fpga->irq_mask &= ~bit;
|
||||
writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
|
||||
set = readl(fpga->base + FPGA_IRQ_SET_CLR);
|
||||
writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
|
||||
}
|
||||
|
||||
static void cplds_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct cplds *fpga = irq_data_get_irq_chip_data(d);
|
||||
unsigned int cplds_irq = irqd_to_hwirq(d);
|
||||
unsigned int bit = BIT(cplds_irq);
|
||||
unsigned int set, bit = BIT(cplds_irq);
|
||||
|
||||
set = readl(fpga->base + FPGA_IRQ_SET_CLR);
|
||||
writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
|
||||
|
||||
fpga->irq_mask |= bit;
|
||||
writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
|
||||
|
@ -72,7 +77,8 @@ static void cplds_irq_unmask(struct irq_data *d)
|
|||
|
||||
static struct irq_chip cplds_irq_chip = {
|
||||
.name = "pxa_cplds",
|
||||
.irq_mask_ack = cplds_irq_mask_ack,
|
||||
.irq_ack = cplds_irq_mask,
|
||||
.irq_mask = cplds_irq_mask,
|
||||
.irq_unmask = cplds_irq_unmask,
|
||||
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
|
|
@ -120,7 +120,8 @@ static struct resource smc91x_resources[] = {
|
|||
};
|
||||
|
||||
static struct smc91x_platdata xcep_smc91x_info = {
|
||||
.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
|
||||
.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
|
||||
SMC91X_NOWAIT | SMC91X_USE_DMA,
|
||||
};
|
||||
|
||||
static struct platform_device smc91x_device = {
|
||||
|
|
|
@ -95,7 +95,8 @@ static struct smsc911x_platform_config smsc911x_config = {
|
|||
};
|
||||
|
||||
static struct smc91x_platdata smc91x_platdata = {
|
||||
.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
|
||||
.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
|
||||
SMC91X_NOWAIT,
|
||||
};
|
||||
|
||||
static struct platform_device realview_eth_device = {
|
||||
|
|
|
@ -125,6 +125,8 @@ static unsigned long clk_36864_get_rate(struct clk *clk)
|
|||
}
|
||||
|
||||
static struct clkops clk_36864_ops = {
|
||||
.enable = clk_cpu_enable,
|
||||
.disable = clk_cpu_disable,
|
||||
.get_rate = clk_36864_get_rate,
|
||||
};
|
||||
|
||||
|
@ -140,9 +142,8 @@ static struct clk_lookup sa11xx_clkregs[] = {
|
|||
CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
|
||||
};
|
||||
|
||||
static int __init sa11xx_clk_init(void)
|
||||
int __init sa11xx_clk_init(void)
|
||||
{
|
||||
clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
|
||||
return 0;
|
||||
}
|
||||
core_initcall(sa11xx_clk_init);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/reset.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include <clocksource/pxa.h>
|
||||
|
@ -95,6 +96,8 @@ static void sa1100_power_off(void)
|
|||
|
||||
void sa11x0_restart(enum reboot_mode mode, const char *cmd)
|
||||
{
|
||||
clear_reset_status(RESET_STATUS_ALL);
|
||||
|
||||
if (mode == REBOOT_SOFT) {
|
||||
/* Jump into ROM at address 0 */
|
||||
soft_restart(0);
|
||||
|
@ -388,6 +391,7 @@ void __init sa1100_init_irq(void)
|
|||
sa11x0_init_irq_nodt(IRQ_GPIO0_SC, irq_resource.start);
|
||||
|
||||
sa1100_init_gpio();
|
||||
sa11xx_clk_init();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -44,3 +44,5 @@ int sa11x0_pm_init(void);
|
|||
#else
|
||||
static inline int sa11x0_pm_init(void) { return 0; }
|
||||
#endif
|
||||
|
||||
int sa11xx_clk_init(void);
|
||||
|
|
|
@ -45,7 +45,7 @@ static struct resource smc91x_resources[] = {
|
|||
};
|
||||
|
||||
static struct smc91x_platdata smc91x_platdata = {
|
||||
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
|
||||
.flags = SMC91X_USE_16BIT | SMC91X_USE_8BIT | SMC91X_NOWAIT,
|
||||
};
|
||||
|
||||
static struct platform_device smc91x_device = {
|
||||
|
|
|
@ -41,40 +41,27 @@
|
|||
|
||||
#define REGULATOR_IRQ_MASK BIT(2) /* IRQ2, active low */
|
||||
|
||||
/* start of DA9210 System Control and Event Registers */
|
||||
#define DA9210_REG_MASK_A 0x54
|
||||
|
||||
static void __iomem *irqc;
|
||||
|
||||
static const u8 da9063_mask_regs[] = {
|
||||
DA9063_REG_IRQ_MASK_A,
|
||||
DA9063_REG_IRQ_MASK_B,
|
||||
DA9063_REG_IRQ_MASK_C,
|
||||
DA9063_REG_IRQ_MASK_D,
|
||||
/* first byte sets the memory pointer, following are consecutive reg values */
|
||||
static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff };
|
||||
static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff };
|
||||
|
||||
static struct i2c_msg da9xxx_msgs[2] = {
|
||||
{
|
||||
.addr = 0x58,
|
||||
.len = ARRAY_SIZE(da9063_irq_clr),
|
||||
.buf = da9063_irq_clr,
|
||||
}, {
|
||||
.addr = 0x68,
|
||||
.len = ARRAY_SIZE(da9210_irq_clr),
|
||||
.buf = da9210_irq_clr,
|
||||
},
|
||||
};
|
||||
|
||||
/* DA9210 System Control and Event Registers */
|
||||
#define DA9210_REG_MASK_A 0x54
|
||||
#define DA9210_REG_MASK_B 0x55
|
||||
|
||||
static const u8 da9210_mask_regs[] = {
|
||||
DA9210_REG_MASK_A,
|
||||
DA9210_REG_MASK_B,
|
||||
};
|
||||
|
||||
static void da9xxx_mask_irqs(struct i2c_client *client, const u8 regs[],
|
||||
unsigned int nregs)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
dev_info(&client->dev, "Masking %s interrupt sources\n", client->name);
|
||||
|
||||
for (i = 0; i < nregs; i++) {
|
||||
int error = i2c_smbus_write_byte_data(client, regs[i], ~0);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "i2c error %d\n", error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int regulator_quirk_notify(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
|
@ -93,12 +80,15 @@ static int regulator_quirk_notify(struct notifier_block *nb,
|
|||
client = to_i2c_client(dev);
|
||||
dev_dbg(dev, "Detected %s\n", client->name);
|
||||
|
||||
if ((client->addr == 0x58 && !strcmp(client->name, "da9063")))
|
||||
da9xxx_mask_irqs(client, da9063_mask_regs,
|
||||
ARRAY_SIZE(da9063_mask_regs));
|
||||
else if (client->addr == 0x68 && !strcmp(client->name, "da9210"))
|
||||
da9xxx_mask_irqs(client, da9210_mask_regs,
|
||||
ARRAY_SIZE(da9210_mask_regs));
|
||||
if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) ||
|
||||
(client->addr == 0x68 && !strcmp(client->name, "da9210"))) {
|
||||
int ret;
|
||||
|
||||
dev_info(&client->dev, "clearing da9063/da9210 interrupts\n");
|
||||
ret = i2c_transfer(client->adapter, da9xxx_msgs, ARRAY_SIZE(da9xxx_msgs));
|
||||
if (ret != ARRAY_SIZE(da9xxx_msgs))
|
||||
dev_err(&client->dev, "i2c error %d\n", ret);
|
||||
}
|
||||
|
||||
mon = ioread32(irqc + IRQC_MONITOR);
|
||||
if (mon & REGULATOR_IRQ_MASK)
|
||||
|
|
|
@ -82,9 +82,12 @@ config ARM64
|
|||
select HAVE_PERF_EVENTS
|
||||
select HAVE_PERF_REGS
|
||||
select HAVE_PERF_USER_STACK_DUMP
|
||||
select HAVE_REGS_AND_STACK_ACCESS_API
|
||||
select HAVE_RCU_TABLE_FREE
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
select IOMMU_DMA if (IOMMU_SUPPORT && !ARCH_QCOM)
|
||||
select HAVE_KPROBES
|
||||
select HAVE_KRETPROBES if HAVE_KPROBES
|
||||
select IRQ_DOMAIN
|
||||
select IRQ_FORCED_THREADING
|
||||
select MODULES_USE_ELF_RELA
|
||||
|
@ -99,6 +102,7 @@ config ARM64
|
|||
select SPARSE_IRQ
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select HAVE_CONTEXT_TRACKING
|
||||
select HAVE_ARM_SMCCC
|
||||
help
|
||||
ARM 64-bit (AArch64) Linux support.
|
||||
|
||||
|
@ -807,6 +811,14 @@ config SETEND_EMULATION
|
|||
If unsure, say Y
|
||||
endif
|
||||
|
||||
config ARM64_SW_TTBR0_PAN
|
||||
bool "Emulate Priviledged Access Never using TTBR0_EL1 switching"
|
||||
help
|
||||
Enabling this option prevents the kernel from accessing
|
||||
user-space memory directly by pointing TTBR0_EL1 to a reserved
|
||||
zeroed area and reserved ASID. The user access routines
|
||||
restore the valid TTBR0_EL1 temporarily.
|
||||
|
||||
menu "ARMv8.1 architectural features"
|
||||
|
||||
config ARM64_HW_AFDBM
|
||||
|
@ -893,7 +905,7 @@ config RELOCATABLE
|
|||
|
||||
config RANDOMIZE_BASE
|
||||
bool "Randomize the address of the kernel image"
|
||||
select ARM64_MODULE_PLTS
|
||||
select ARM64_MODULE_PLTS if MODULES
|
||||
select RELOCATABLE
|
||||
help
|
||||
Randomizes the virtual address at which the kernel image is
|
||||
|
@ -1053,6 +1065,14 @@ menu "Power management options"
|
|||
|
||||
source "kernel/power/Kconfig"
|
||||
|
||||
config ARCH_HIBERNATION_POSSIBLE
|
||||
def_bool y
|
||||
depends on CPU_PM
|
||||
|
||||
config ARCH_HIBERNATION_HEADER
|
||||
def_bool y
|
||||
depends on HIBERNATION
|
||||
|
||||
config ARCH_SUSPEND_POSSIBLE
|
||||
def_bool y
|
||||
|
||||
|
|
|
@ -226,3 +226,6 @@ CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
|
|||
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
|
||||
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
|
||||
CONFIG_CRYPTO_CRC32_ARM64=y
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_CORESIGHT=y
|
||||
|
|
311
arch/arm64/configs/ranchu64_defconfig
Normal file
311
arch/arm64/configs/ranchu64_defconfig
Normal file
|
@ -0,0 +1,311 @@
|
|||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_CGROUP_DEBUG=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=24
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
CONFIG_ARCH_VEXPRESS=y
|
||||
CONFIG_NR_CPUS=4
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_ARMV8_DEPRECATED=y
|
||||
CONFIG_SWP_EMULATION=y
|
||||
CONFIG_CP15_BARRIER_EMULATION=y
|
||||
CONFIG_SETEND_EMULATION=y
|
||||
CONFIG_CMDLINE="console=ttyAMA0"
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_COMPAT=y
|
||||
CONFIG_PM_AUTOSLEEP=y
|
||||
CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_PM_WAKELOCKS_LIMIT=0
|
||||
# CONFIG_PM_WAKELOCKS_GC is not set
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_INET_ESP=y
|
||||
# CONFIG_INET_LRO is not set
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_ROUTE_INFO=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=y
|
||||
CONFIG_INET6_ESP=y
|
||||
CONFIG_INET6_IPCOMP=y
|
||||
CONFIG_IPV6_MIP6=y
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=y
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_SCTP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=y
|
||||
CONFIG_NF_CONNTRACK_FTP=y
|
||||
CONFIG_NF_CONNTRACK_H323=y
|
||||
CONFIG_NF_CONNTRACK_IRC=y
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
|
||||
CONFIG_NF_CONNTRACK_PPTP=y
|
||||
CONFIG_NF_CONNTRACK_SANE=y
|
||||
CONFIG_NF_CONNTRACK_TFTP=y
|
||||
CONFIG_NF_CT_NETLINK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=y
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=y
|
||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=y
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=y
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=y
|
||||
CONFIG_NF_CONNTRACK_IPV4=y
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
CONFIG_IP_NF_MATCH_AH=y
|
||||
CONFIG_IP_NF_MATCH_ECN=y
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=y
|
||||
CONFIG_IP_NF_MATCH_TTL=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_TARGET_REJECT=y
|
||||
CONFIG_IP_NF_MANGLE=y
|
||||
CONFIG_IP_NF_TARGET_ECN=y
|
||||
CONFIG_IP_NF_TARGET_TTL=y
|
||||
CONFIG_IP_NF_RAW=y
|
||||
CONFIG_IP_NF_SECURITY=y
|
||||
CONFIG_IP_NF_ARPTABLES=y
|
||||
CONFIG_IP_NF_ARPFILTER=y
|
||||
CONFIG_IP_NF_ARP_MANGLE=y
|
||||
CONFIG_NF_CONNTRACK_IPV6=y
|
||||
CONFIG_IP6_NF_IPTABLES=y
|
||||
CONFIG_IP6_NF_MATCH_AH=y
|
||||
CONFIG_IP6_NF_MATCH_EUI64=y
|
||||
CONFIG_IP6_NF_MATCH_FRAG=y
|
||||
CONFIG_IP6_NF_MATCH_OPTS=y
|
||||
CONFIG_IP6_NF_MATCH_HL=y
|
||||
CONFIG_IP6_NF_MATCH_IPV6HEADER=y
|
||||
CONFIG_IP6_NF_MATCH_MH=y
|
||||
CONFIG_IP6_NF_MATCH_RT=y
|
||||
CONFIG_IP6_NF_TARGET_HL=y
|
||||
CONFIG_IP6_NF_FILTER=y
|
||||
CONFIG_IP6_NF_TARGET_REJECT=y
|
||||
CONFIG_IP6_NF_MANGLE=y
|
||||
CONFIG_IP6_NF_RAW=y
|
||||
CONFIG_BRIDGE=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=y
|
||||
CONFIG_NET_CLS_U32=y
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_EMATCH_U32=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=8192
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_TUN=y
|
||||
CONFIG_VIRTIO_NET=y
|
||||
CONFIG_SMC91X=y
|
||||
CONFIG_PPP=y
|
||||
CONFIG_PPP_BSDCOMP=y
|
||||
CONFIG_PPP_DEFLATE=y
|
||||
CONFIG_PPP_MPPE=y
|
||||
CONFIG_PPPOLAC=y
|
||||
CONFIG_PPPOPNS=y
|
||||
# CONFIG_WLAN is not set
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_INPUT_KEYRESET=y
|
||||
CONFIG_KEYBOARD_GOLDFISH_EVENTS=y
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_JOYSTICK=y
|
||||
CONFIG_INPUT_TABLET=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_KEYCHORD=y
|
||||
CONFIG_INPUT_UINPUT=y
|
||||
CONFIG_INPUT_GPIO=y
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVMEM is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_AMBA_PL011=y
|
||||
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_BATTERY_GOLDFISH=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_GOLDFISH=y
|
||||
CONFIG_FB_SIMPLE=y
|
||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
# CONFIG_LOGO_LINUX_VGA16 is not set
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_HIDRAW=y
|
||||
CONFIG_UHID=y
|
||||
CONFIG_HID_A4TECH=y
|
||||
CONFIG_HID_ACRUX=y
|
||||
CONFIG_HID_ACRUX_FF=y
|
||||
CONFIG_HID_APPLE=y
|
||||
CONFIG_HID_BELKIN=y
|
||||
CONFIG_HID_CHERRY=y
|
||||
CONFIG_HID_CHICONY=y
|
||||
CONFIG_HID_PRODIKEYS=y
|
||||
CONFIG_HID_CYPRESS=y
|
||||
CONFIG_HID_DRAGONRISE=y
|
||||
CONFIG_DRAGONRISE_FF=y
|
||||
CONFIG_HID_EMS_FF=y
|
||||
CONFIG_HID_ELECOM=y
|
||||
CONFIG_HID_EZKEY=y
|
||||
CONFIG_HID_KEYTOUCH=y
|
||||
CONFIG_HID_KYE=y
|
||||
CONFIG_HID_WALTOP=y
|
||||
CONFIG_HID_GYRATION=y
|
||||
CONFIG_HID_TWINHAN=y
|
||||
CONFIG_HID_KENSINGTON=y
|
||||
CONFIG_HID_LCPOWER=y
|
||||
CONFIG_HID_LOGITECH=y
|
||||
CONFIG_HID_LOGITECH_DJ=y
|
||||
CONFIG_LOGITECH_FF=y
|
||||
CONFIG_LOGIRUMBLEPAD2_FF=y
|
||||
CONFIG_LOGIG940_FF=y
|
||||
CONFIG_HID_MAGICMOUSE=y
|
||||
CONFIG_HID_MICROSOFT=y
|
||||
CONFIG_HID_MONTEREY=y
|
||||
CONFIG_HID_MULTITOUCH=y
|
||||
CONFIG_HID_ORTEK=y
|
||||
CONFIG_HID_PANTHERLORD=y
|
||||
CONFIG_PANTHERLORD_FF=y
|
||||
CONFIG_HID_PETALYNX=y
|
||||
CONFIG_HID_PICOLCD=y
|
||||
CONFIG_HID_PRIMAX=y
|
||||
CONFIG_HID_SAITEK=y
|
||||
CONFIG_HID_SAMSUNG=y
|
||||
CONFIG_HID_SPEEDLINK=y
|
||||
CONFIG_HID_SUNPLUS=y
|
||||
CONFIG_HID_GREENASIA=y
|
||||
CONFIG_GREENASIA_FF=y
|
||||
CONFIG_HID_SMARTJOYPLUS=y
|
||||
CONFIG_SMARTJOYPLUS_FF=y
|
||||
CONFIG_HID_TIVO=y
|
||||
CONFIG_HID_TOPSEED=y
|
||||
CONFIG_HID_THRUSTMASTER=y
|
||||
CONFIG_HID_WACOM=y
|
||||
CONFIG_HID_WIIMOTE=y
|
||||
CONFIG_HID_ZEROPLUS=y
|
||||
CONFIG_HID_ZYDACRON=y
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_VIRTIO_MMIO=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_ASHMEM=y
|
||||
CONFIG_ANDROID_TIMED_GPIO=y
|
||||
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
|
||||
CONFIG_SYNC=y
|
||||
CONFIG_SW_SYNC=y
|
||||
CONFIG_SW_SYNC_USER=y
|
||||
CONFIG_ION=y
|
||||
CONFIG_GOLDFISH_AUDIO=y
|
||||
CONFIG_GOLDFISH=y
|
||||
CONFIG_GOLDFISH_PIPE=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_ROOT_NFS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_PANIC_TIMEOUT=5
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_SCHEDSTATS=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_ATOMIC64_SELFTEST=y
|
||||
CONFIG_DEBUG_RODATA=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
|
@ -211,7 +211,7 @@ static int ctr_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
|||
err = blkcipher_walk_done(desc, &walk,
|
||||
walk.nbytes % AES_BLOCK_SIZE);
|
||||
}
|
||||
if (nbytes) {
|
||||
if (walk.nbytes % AES_BLOCK_SIZE) {
|
||||
u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
|
||||
u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
|
||||
u8 __aligned(8) tail[AES_BLOCK_SIZE];
|
||||
|
|
|
@ -95,13 +95,11 @@ void apply_alternatives(void *start, size_t length);
|
|||
* The code that follows this macro will be assembled and linked as
|
||||
* normal. There are no restrictions on this code.
|
||||
*/
|
||||
.macro alternative_if_not cap, enable = 1
|
||||
.if \enable
|
||||
.macro alternative_if_not cap
|
||||
.pushsection .altinstructions, "a"
|
||||
altinstruction_entry 661f, 663f, \cap, 662f-661f, 664f-663f
|
||||
.popsection
|
||||
661:
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
|
@ -118,27 +116,27 @@ void apply_alternatives(void *start, size_t length);
|
|||
* alternative sequence it is defined in (branches into an
|
||||
* alternative sequence are not fixed up).
|
||||
*/
|
||||
.macro alternative_else, enable = 1
|
||||
.if \enable
|
||||
.macro alternative_else
|
||||
662: .pushsection .altinstr_replacement, "ax"
|
||||
663:
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Complete an alternative code sequence.
|
||||
*/
|
||||
.macro alternative_endif, enable = 1
|
||||
.if \enable
|
||||
.macro alternative_endif
|
||||
664: .popsection
|
||||
.org . - (664b-663b) + (662b-661b)
|
||||
.org . - (662b-661b) + (664b-663b)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
#define _ALTERNATIVE_CFG(insn1, insn2, cap, cfg, ...) \
|
||||
alternative_insn insn1, insn2, cap, IS_ENABLED(cfg)
|
||||
|
||||
.macro user_alt, label, oldinstr, newinstr, cond
|
||||
9999: alternative_insn "\oldinstr", "\newinstr", \cond
|
||||
_ASM_EXTABLE 9999b, \label
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Generate the assembly for UAO alternatives with exception table entries.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Based on arch/arm/include/asm/assembler.h
|
||||
* Based on arch/arm/include/asm/assembler.h, arch/arm/mm/proc-macros.S
|
||||
*
|
||||
* Copyright (C) 1996-2000 Russell King
|
||||
* Copyright (C) 2012 ARM Ltd.
|
||||
|
@ -23,6 +23,10 @@
|
|||
#ifndef __ASM_ASSEMBLER_H
|
||||
#define __ASM_ASSEMBLER_H
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable-hwdef.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
|
@ -49,6 +53,15 @@
|
|||
msr daifclr, #2
|
||||
.endm
|
||||
|
||||
.macro save_and_disable_irq, flags
|
||||
mrs \flags, daif
|
||||
msr daifset, #2
|
||||
.endm
|
||||
|
||||
.macro restore_irq, flags
|
||||
msr daif, \flags
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Save/disable and restore interrupts.
|
||||
*/
|
||||
|
@ -223,6 +236,111 @@ lr .req x30 // link register
|
|||
add \reg, \reg, \tmp
|
||||
.endm
|
||||
|
||||
/*
|
||||
* vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
|
||||
*/
|
||||
.macro vma_vm_mm, rd, rn
|
||||
ldr \rd, [\rn, #VMA_VM_MM]
|
||||
.endm
|
||||
|
||||
/*
|
||||
* mmid - get context id from mm pointer (mm->context.id)
|
||||
*/
|
||||
.macro mmid, rd, rn
|
||||
ldr \rd, [\rn, #MM_CONTEXT_ID]
|
||||
.endm
|
||||
|
||||
/*
|
||||
* dcache_line_size - get the minimum D-cache line size from the CTR register.
|
||||
*/
|
||||
.macro dcache_line_size, reg, tmp
|
||||
mrs \tmp, ctr_el0 // read CTR
|
||||
ubfm \tmp, \tmp, #16, #19 // cache line size encoding
|
||||
mov \reg, #4 // bytes per word
|
||||
lsl \reg, \reg, \tmp // actual cache line size
|
||||
.endm
|
||||
|
||||
/*
|
||||
* icache_line_size - get the minimum I-cache line size from the CTR register.
|
||||
*/
|
||||
.macro icache_line_size, reg, tmp
|
||||
mrs \tmp, ctr_el0 // read CTR
|
||||
and \tmp, \tmp, #0xf // cache line size encoding
|
||||
mov \reg, #4 // bytes per word
|
||||
lsl \reg, \reg, \tmp // actual cache line size
|
||||
.endm
|
||||
|
||||
/*
|
||||
* tcr_set_idmap_t0sz - update TCR.T0SZ so that we can load the ID map
|
||||
*/
|
||||
.macro tcr_set_idmap_t0sz, valreg, tmpreg
|
||||
#ifndef CONFIG_ARM64_VA_BITS_48
|
||||
ldr_l \tmpreg, idmap_t0sz
|
||||
bfi \valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Macro to perform a data cache maintenance for the interval
|
||||
* [kaddr, kaddr + size)
|
||||
*
|
||||
* op: operation passed to dc instruction
|
||||
* domain: domain used in dsb instruciton
|
||||
* kaddr: starting virtual address of the region
|
||||
* size: size of the region
|
||||
* Corrupts: kaddr, size, tmp1, tmp2
|
||||
*/
|
||||
.macro dcache_by_line_op op, domain, kaddr, size, tmp1, tmp2
|
||||
dcache_line_size \tmp1, \tmp2
|
||||
add \size, \kaddr, \size
|
||||
sub \tmp2, \tmp1, #1
|
||||
bic \kaddr, \kaddr, \tmp2
|
||||
9998:
|
||||
.if (\op == cvau || \op == cvac)
|
||||
alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE
|
||||
dc \op, \kaddr
|
||||
alternative_else
|
||||
dc civac, \kaddr
|
||||
alternative_endif
|
||||
.else
|
||||
dc \op, \kaddr
|
||||
.endif
|
||||
add \kaddr, \kaddr, \tmp1
|
||||
cmp \kaddr, \size
|
||||
b.lo 9998b
|
||||
dsb \domain
|
||||
.endm
|
||||
|
||||
/*
|
||||
* reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present
|
||||
*/
|
||||
.macro reset_pmuserenr_el0, tmpreg
|
||||
mrs \tmpreg, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer
|
||||
sbfx \tmpreg, \tmpreg, #8, #4
|
||||
cmp \tmpreg, #1 // Skip if no PMU present
|
||||
b.lt 9000f
|
||||
msr pmuserenr_el0, xzr // Disable PMU access from EL0
|
||||
9000:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* copy_page - copy src to dest using temp registers t1-t8
|
||||
*/
|
||||
.macro copy_page dest:req src:req t1:req t2:req t3:req t4:req t5:req t6:req t7:req t8:req
|
||||
9998: ldp \t1, \t2, [\src]
|
||||
ldp \t3, \t4, [\src, #16]
|
||||
ldp \t5, \t6, [\src, #32]
|
||||
ldp \t7, \t8, [\src, #48]
|
||||
add \src, \src, #64
|
||||
stnp \t1, \t2, [\dest]
|
||||
stnp \t3, \t4, [\dest, #16]
|
||||
stnp \t5, \t6, [\dest, #32]
|
||||
stnp \t7, \t8, [\dest, #48]
|
||||
add \dest, \dest, #64
|
||||
tst \src, #(PAGE_SIZE - 1)
|
||||
b.ne 9998b
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Annotate a function as position independent, i.e., safe to be called before
|
||||
* the kernel virtual mapping is activated.
|
||||
|
@ -265,4 +383,28 @@ lr .req x30 // link register
|
|||
movk \reg, :abs_g0_nc:\val
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Return the current thread_info.
|
||||
*/
|
||||
.macro get_thread_info, rd
|
||||
mrs \rd, sp_el0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Errata workaround post TTBR0_EL1 update.
|
||||
*/
|
||||
.macro post_ttbr0_update_workaround
|
||||
#ifdef CONFIG_CAVIUM_ERRATUM_27456
|
||||
alternative_if_not ARM64_WORKAROUND_CAVIUM_27456
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
alternative_else
|
||||
ic iallu
|
||||
dsb nsh
|
||||
isb
|
||||
alternative_endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* __ASM_ASSEMBLER_H */
|
||||
|
|
|
@ -34,9 +34,9 @@
|
|||
#define ARM64_HAS_UAO 9
|
||||
#define ARM64_ALT_PAN_NOT_UAO 10
|
||||
|
||||
#define ARM64_NCAPS 11
|
||||
#define ARM64_WORKAROUND_CAVIUM_27456 12
|
||||
|
||||
#define ARM64_WORKAROUND_CAVIUM_27456 11
|
||||
#define ARM64_HAS_VIRT_HOST_EXTN 12
|
||||
#define ARM64_NCAPS 13
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
@ -83,7 +83,7 @@ struct arm64_cpu_capabilities {
|
|||
const char *desc;
|
||||
u16 capability;
|
||||
bool (*matches)(const struct arm64_cpu_capabilities *);
|
||||
void (*enable)(void *); /* Called on all active CPUs */
|
||||
int (*enable)(void *); /* Called on all active CPUs */
|
||||
union {
|
||||
struct { /* To be used for erratum handling only */
|
||||
u32 midr_model;
|
||||
|
@ -191,6 +191,12 @@ static inline bool system_supports_mixed_endian_el0(void)
|
|||
return id_aa64mmfr0_mixed_endian_el0(read_system_reg(SYS_ID_AA64MMFR0_EL1));
|
||||
}
|
||||
|
||||
static inline bool system_uses_ttbr0_pan(void)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN) &&
|
||||
!cpus_have_cap(ARM64_HAS_PAN);
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,6 +66,11 @@
|
|||
|
||||
#define CACHE_FLUSH_IS_SAFE 1
|
||||
|
||||
/* kprobes BRK opcodes with ESR encoding */
|
||||
#define BRK64_ESR_MASK 0xFFFF
|
||||
#define BRK64_ESR_KPROBES 0x0004
|
||||
#define BRK64_OPCODE_KPROBES (AARCH64_BREAK_MON | (BRK64_ESR_KPROBES << 5))
|
||||
|
||||
/* AArch32 */
|
||||
#define DBG_ESR_EVT_BKPT 0x4
|
||||
#define DBG_ESR_EVT_VECC 0x5
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#ifndef _ASM_EFI_H
|
||||
#define _ASM_EFI_H
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/neon.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#ifdef CONFIG_EFI
|
||||
extern void efi_init(void);
|
||||
|
@ -10,6 +13,8 @@ extern void efi_init(void);
|
|||
#define efi_init()
|
||||
#endif
|
||||
|
||||
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
|
||||
|
||||
#define efi_call_virt(f, ...) \
|
||||
({ \
|
||||
efi_##f##_t *__f; \
|
||||
|
@ -63,6 +68,34 @@ extern void efi_init(void);
|
|||
* Services are enabled and the EFI_RUNTIME_SERVICES bit set.
|
||||
*/
|
||||
|
||||
static inline void efi_set_pgd(struct mm_struct *mm)
|
||||
{
|
||||
__switch_mm(mm);
|
||||
|
||||
if (system_uses_ttbr0_pan()) {
|
||||
if (mm != current->active_mm) {
|
||||
/*
|
||||
* Update the current thread's saved ttbr0 since it is
|
||||
* restored as part of a return from exception. Set
|
||||
* the hardware TTBR0_EL1 using cpu_switch_mm()
|
||||
* directly to enable potential errata workarounds.
|
||||
*/
|
||||
update_saved_ttbr0(current, mm);
|
||||
cpu_switch_mm(mm->pgd, mm);
|
||||
} else {
|
||||
/*
|
||||
* Defer the switch to the current thread's TTBR0_EL1
|
||||
* until uaccess_enable(). Restore the current
|
||||
* thread's saved ttbr0 corresponding to its active_mm
|
||||
* (if different from init_mm).
|
||||
*/
|
||||
cpu_set_reserved_ttbr0();
|
||||
if (current->active_mm != &init_mm)
|
||||
update_saved_ttbr0(current, current->active_mm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void efi_virtmap_load(void);
|
||||
void efi_virtmap_unload(void);
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
|
||||
#define ESR_ELx_EC_SHIFT (26)
|
||||
#define ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT)
|
||||
#define ESR_ELx_EC(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT)
|
||||
|
||||
#define ESR_ELx_IL (UL(1) << 25)
|
||||
#define ESR_ELx_ISS_MASK (ESR_ELx_IL - 1)
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
#include <asm/sysreg.h>
|
||||
|
||||
#define __futex_atomic_op(insn, ret, oldval, uaddr, tmp, oparg) \
|
||||
do { \
|
||||
uaccess_enable(); \
|
||||
asm volatile( \
|
||||
ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, \
|
||||
CONFIG_ARM64_PAN) \
|
||||
" prfm pstl1strm, %2\n" \
|
||||
"1: ldxr %w1, %2\n" \
|
||||
insn "\n" \
|
||||
|
@ -44,11 +44,11 @@
|
|||
" .popsection\n" \
|
||||
_ASM_EXTABLE(1b, 4b) \
|
||||
_ASM_EXTABLE(2b, 4b) \
|
||||
ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
|
||||
CONFIG_ARM64_PAN) \
|
||||
: "=&r" (ret), "=&r" (oldval), "+Q" (*uaddr), "=&r" (tmp) \
|
||||
: "r" (oparg), "Ir" (-EFAULT) \
|
||||
: "memory")
|
||||
: "memory"); \
|
||||
uaccess_disable(); \
|
||||
} while (0)
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
|
@ -118,8 +118,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
|||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
uaccess_enable();
|
||||
asm volatile("// futex_atomic_cmpxchg_inatomic\n"
|
||||
ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
|
||||
" prfm pstl1strm, %2\n"
|
||||
"1: ldxr %w1, %2\n"
|
||||
" sub %w3, %w1, %w4\n"
|
||||
|
@ -134,10 +134,10 @@ ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
|
|||
" .popsection\n"
|
||||
_ASM_EXTABLE(1b, 4b)
|
||||
_ASM_EXTABLE(2b, 4b)
|
||||
ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
|
||||
: "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp)
|
||||
: "r" (oldval), "r" (newval), "Ir" (-EFAULT)
|
||||
: "memory");
|
||||
uaccess_disable();
|
||||
|
||||
*uval = val;
|
||||
return ret;
|
||||
|
|
|
@ -120,6 +120,29 @@ enum aarch64_insn_register {
|
|||
AARCH64_INSN_REG_SP = 31 /* Stack pointer: as load/store base reg */
|
||||
};
|
||||
|
||||
enum aarch64_insn_special_register {
|
||||
AARCH64_INSN_SPCLREG_SPSR_EL1 = 0xC200,
|
||||
AARCH64_INSN_SPCLREG_ELR_EL1 = 0xC201,
|
||||
AARCH64_INSN_SPCLREG_SP_EL0 = 0xC208,
|
||||
AARCH64_INSN_SPCLREG_SPSEL = 0xC210,
|
||||
AARCH64_INSN_SPCLREG_CURRENTEL = 0xC212,
|
||||
AARCH64_INSN_SPCLREG_DAIF = 0xDA11,
|
||||
AARCH64_INSN_SPCLREG_NZCV = 0xDA10,
|
||||
AARCH64_INSN_SPCLREG_FPCR = 0xDA20,
|
||||
AARCH64_INSN_SPCLREG_DSPSR_EL0 = 0xDA28,
|
||||
AARCH64_INSN_SPCLREG_DLR_EL0 = 0xDA29,
|
||||
AARCH64_INSN_SPCLREG_SPSR_EL2 = 0xE200,
|
||||
AARCH64_INSN_SPCLREG_ELR_EL2 = 0xE201,
|
||||
AARCH64_INSN_SPCLREG_SP_EL1 = 0xE208,
|
||||
AARCH64_INSN_SPCLREG_SPSR_INQ = 0xE218,
|
||||
AARCH64_INSN_SPCLREG_SPSR_ABT = 0xE219,
|
||||
AARCH64_INSN_SPCLREG_SPSR_UND = 0xE21A,
|
||||
AARCH64_INSN_SPCLREG_SPSR_FIQ = 0xE21B,
|
||||
AARCH64_INSN_SPCLREG_SPSR_EL3 = 0xF200,
|
||||
AARCH64_INSN_SPCLREG_ELR_EL3 = 0xF201,
|
||||
AARCH64_INSN_SPCLREG_SP_EL2 = 0xF210
|
||||
};
|
||||
|
||||
enum aarch64_insn_variant {
|
||||
AARCH64_INSN_VARIANT_32BIT,
|
||||
AARCH64_INSN_VARIANT_64BIT
|
||||
|
@ -223,8 +246,15 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
|
|||
static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
|
||||
{ return (val); }
|
||||
|
||||
__AARCH64_INSN_FUNCS(adr_adrp, 0x1F000000, 0x10000000)
|
||||
__AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000)
|
||||
__AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800)
|
||||
__AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800)
|
||||
__AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000)
|
||||
__AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000)
|
||||
__AARCH64_INSN_FUNCS(exclusive, 0x3F800000, 0x08000000)
|
||||
__AARCH64_INSN_FUNCS(load_ex, 0x3F400000, 0x08400000)
|
||||
__AARCH64_INSN_FUNCS(store_ex, 0x3F400000, 0x08000000)
|
||||
__AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000)
|
||||
__AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000)
|
||||
__AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000)
|
||||
|
@ -273,10 +303,15 @@ __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001)
|
|||
__AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002)
|
||||
__AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003)
|
||||
__AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000)
|
||||
__AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000)
|
||||
__AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F)
|
||||
__AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000)
|
||||
__AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000)
|
||||
__AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000)
|
||||
__AARCH64_INSN_FUNCS(eret, 0xFFFFFFFF, 0xD69F03E0)
|
||||
__AARCH64_INSN_FUNCS(mrs, 0xFFF00000, 0xD5300000)
|
||||
__AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F)
|
||||
__AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000)
|
||||
|
||||
#undef __AARCH64_INSN_FUNCS
|
||||
|
||||
|
@ -286,6 +321,8 @@ bool aarch64_insn_is_branch_imm(u32 insn);
|
|||
int aarch64_insn_read(void *addr, u32 *insnp);
|
||||
int aarch64_insn_write(void *addr, u32 insn);
|
||||
enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn);
|
||||
bool aarch64_insn_uses_literal(u32 insn);
|
||||
bool aarch64_insn_is_branch(u32 insn);
|
||||
u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn);
|
||||
u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
|
||||
u32 insn, u64 imm);
|
||||
|
@ -367,9 +404,13 @@ bool aarch32_insn_is_wide(u32 insn);
|
|||
#define A32_RT_OFFSET 12
|
||||
#define A32_RT2_OFFSET 0
|
||||
|
||||
u32 aarch64_insn_extract_system_reg(u32 insn);
|
||||
u32 aarch32_insn_extract_reg_num(u32 insn, int offset);
|
||||
u32 aarch32_insn_mcr_extract_opc2(u32 insn);
|
||||
u32 aarch32_insn_mcr_extract_crm(u32 insn);
|
||||
|
||||
typedef bool (pstate_check_t)(unsigned long);
|
||||
extern pstate_check_t * const aarch32_opcode_cond_checks[16];
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_INSN_H */
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#ifndef __ASM_KERNEL_PGTABLE_H
|
||||
#define __ASM_KERNEL_PGTABLE_H
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/sparsemem.h>
|
||||
|
||||
/*
|
||||
* The linear mapping and the start of memory are both 2M aligned (per
|
||||
|
@ -53,6 +55,12 @@
|
|||
#define SWAPPER_DIR_SIZE (SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
|
||||
#define IDMAP_DIR_SIZE (IDMAP_PGTABLE_LEVELS * PAGE_SIZE)
|
||||
|
||||
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
|
||||
#define RESERVED_TTBR0_SIZE (PAGE_SIZE)
|
||||
#else
|
||||
#define RESERVED_TTBR0_SIZE (0)
|
||||
#endif
|
||||
|
||||
/* Initial memory map size */
|
||||
#if ARM64_SWAPPER_USES_SECTION_MAPS
|
||||
#define SWAPPER_BLOCK_SHIFT SECTION_SHIFT
|
||||
|
@ -86,10 +94,24 @@
|
|||
* (64k granule), or a multiple that can be mapped using contiguous bits
|
||||
* in the page tables: 32 * PMD_SIZE (16k granule)
|
||||
*/
|
||||
#ifdef CONFIG_ARM64_64K_PAGES
|
||||
#define ARM64_MEMSTART_ALIGN SZ_512M
|
||||
#if defined(CONFIG_ARM64_4K_PAGES)
|
||||
#define ARM64_MEMSTART_SHIFT PUD_SHIFT
|
||||
#elif defined(CONFIG_ARM64_16K_PAGES)
|
||||
#define ARM64_MEMSTART_SHIFT (PMD_SHIFT + 5)
|
||||
#else
|
||||
#define ARM64_MEMSTART_ALIGN SZ_1G
|
||||
#define ARM64_MEMSTART_SHIFT PMD_SHIFT
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sparsemem vmemmap imposes an additional requirement on the alignment of
|
||||
* memstart_addr, due to the fact that the base of the vmemmap region
|
||||
* has a direct correspondence, and needs to appear sufficiently aligned
|
||||
* in the virtual address space.
|
||||
*/
|
||||
#if defined(CONFIG_SPARSEMEM_VMEMMAP) && ARM64_MEMSTART_SHIFT < SECTION_SIZE_BITS
|
||||
#define ARM64_MEMSTART_ALIGN (1UL << SECTION_SIZE_BITS)
|
||||
#else
|
||||
#define ARM64_MEMSTART_ALIGN (1UL << ARM64_MEMSTART_SHIFT)
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_KERNEL_PGTABLE_H */
|
||||
|
|
60
arch/arm64/include/asm/kprobes.h
Normal file
60
arch/arm64/include/asm/kprobes.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* arch/arm64/include/asm/kprobes.h
|
||||
*
|
||||
* Copyright (C) 2013 Linaro Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _ARM_KPROBES_H
|
||||
#define _ARM_KPROBES_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#define __ARCH_WANT_KPROBES_INSN_SLOT
|
||||
#define MAX_INSN_SIZE 1
|
||||
|
||||
#define flush_insn_slot(p) do { } while (0)
|
||||
#define kretprobe_blacklist_size 0
|
||||
|
||||
#include <asm/probes.h>
|
||||
|
||||
struct prev_kprobe {
|
||||
struct kprobe *kp;
|
||||
unsigned int status;
|
||||
};
|
||||
|
||||
/* Single step context for kprobe */
|
||||
struct kprobe_step_ctx {
|
||||
unsigned long ss_pending;
|
||||
unsigned long match_addr;
|
||||
};
|
||||
|
||||
/* per-cpu kprobe control block */
|
||||
struct kprobe_ctlblk {
|
||||
unsigned int kprobe_status;
|
||||
unsigned long saved_irqflag;
|
||||
struct prev_kprobe prev_kprobe;
|
||||
struct kprobe_step_ctx ss_ctx;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
};
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *);
|
||||
int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
|
||||
int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
int kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr);
|
||||
int kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr);
|
||||
void kretprobe_trampoline(void);
|
||||
void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
|
||||
|
||||
#endif /* _ARM_KPROBES_H */
|
|
@ -83,17 +83,6 @@
|
|||
#define HCR_INT_OVERRIDE (HCR_FMO | HCR_IMO)
|
||||
|
||||
|
||||
/* Hyp System Control Register (SCTLR_EL2) bits */
|
||||
#define SCTLR_EL2_EE (1 << 25)
|
||||
#define SCTLR_EL2_WXN (1 << 19)
|
||||
#define SCTLR_EL2_I (1 << 12)
|
||||
#define SCTLR_EL2_SA (1 << 3)
|
||||
#define SCTLR_EL2_C (1 << 2)
|
||||
#define SCTLR_EL2_A (1 << 1)
|
||||
#define SCTLR_EL2_M 1
|
||||
#define SCTLR_EL2_FLAGS (SCTLR_EL2_M | SCTLR_EL2_A | SCTLR_EL2_C | \
|
||||
SCTLR_EL2_SA | SCTLR_EL2_I)
|
||||
|
||||
/* TCR_EL2 Registers bits */
|
||||
#define TCR_EL2_RES1 ((1 << 31) | (1 << 23))
|
||||
#define TCR_EL2_TBI (1 << 20)
|
||||
|
@ -123,6 +112,7 @@
|
|||
#define VTCR_EL2_SL0_LVL1 (1 << 6)
|
||||
#define VTCR_EL2_T0SZ_MASK 0x3f
|
||||
#define VTCR_EL2_T0SZ_40B 24
|
||||
#define VTCR_EL2_VS 19
|
||||
|
||||
/*
|
||||
* We configure the Stage-2 page tables to always restrict the IPA space to be
|
||||
|
@ -167,7 +157,7 @@
|
|||
#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
|
||||
#define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
|
||||
#define VTTBR_VMID_SHIFT (UL(48))
|
||||
#define VTTBR_VMID_MASK (UL(0xFF) << VTTBR_VMID_SHIFT)
|
||||
#define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
|
||||
|
||||
/* Hyp System Trap Register */
|
||||
#define HSTR_EL2_T(x) (1 << x)
|
||||
|
|
|
@ -20,84 +20,10 @@
|
|||
|
||||
#include <asm/virt.h>
|
||||
|
||||
/*
|
||||
* 0 is reserved as an invalid value.
|
||||
* Order *must* be kept in sync with the hyp switch code.
|
||||
*/
|
||||
#define MPIDR_EL1 1 /* MultiProcessor Affinity Register */
|
||||
#define CSSELR_EL1 2 /* Cache Size Selection Register */
|
||||
#define SCTLR_EL1 3 /* System Control Register */
|
||||
#define ACTLR_EL1 4 /* Auxiliary Control Register */
|
||||
#define CPACR_EL1 5 /* Coprocessor Access Control */
|
||||
#define TTBR0_EL1 6 /* Translation Table Base Register 0 */
|
||||
#define TTBR1_EL1 7 /* Translation Table Base Register 1 */
|
||||
#define TCR_EL1 8 /* Translation Control Register */
|
||||
#define ESR_EL1 9 /* Exception Syndrome Register */
|
||||
#define AFSR0_EL1 10 /* Auxilary Fault Status Register 0 */
|
||||
#define AFSR1_EL1 11 /* Auxilary Fault Status Register 1 */
|
||||
#define FAR_EL1 12 /* Fault Address Register */
|
||||
#define MAIR_EL1 13 /* Memory Attribute Indirection Register */
|
||||
#define VBAR_EL1 14 /* Vector Base Address Register */
|
||||
#define CONTEXTIDR_EL1 15 /* Context ID Register */
|
||||
#define TPIDR_EL0 16 /* Thread ID, User R/W */
|
||||
#define TPIDRRO_EL0 17 /* Thread ID, User R/O */
|
||||
#define TPIDR_EL1 18 /* Thread ID, Privileged */
|
||||
#define AMAIR_EL1 19 /* Aux Memory Attribute Indirection Register */
|
||||
#define CNTKCTL_EL1 20 /* Timer Control Register (EL1) */
|
||||
#define PAR_EL1 21 /* Physical Address Register */
|
||||
#define MDSCR_EL1 22 /* Monitor Debug System Control Register */
|
||||
#define MDCCINT_EL1 23 /* Monitor Debug Comms Channel Interrupt Enable Reg */
|
||||
|
||||
/* 32bit specific registers. Keep them at the end of the range */
|
||||
#define DACR32_EL2 24 /* Domain Access Control Register */
|
||||
#define IFSR32_EL2 25 /* Instruction Fault Status Register */
|
||||
#define FPEXC32_EL2 26 /* Floating-Point Exception Control Register */
|
||||
#define DBGVCR32_EL2 27 /* Debug Vector Catch Register */
|
||||
#define NR_SYS_REGS 28
|
||||
|
||||
/* 32bit mapping */
|
||||
#define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
|
||||
#define c0_CSSELR (CSSELR_EL1 * 2)/* Cache Size Selection Register */
|
||||
#define c1_SCTLR (SCTLR_EL1 * 2) /* System Control Register */
|
||||
#define c1_ACTLR (ACTLR_EL1 * 2) /* Auxiliary Control Register */
|
||||
#define c1_CPACR (CPACR_EL1 * 2) /* Coprocessor Access Control */
|
||||
#define c2_TTBR0 (TTBR0_EL1 * 2) /* Translation Table Base Register 0 */
|
||||
#define c2_TTBR0_high (c2_TTBR0 + 1) /* TTBR0 top 32 bits */
|
||||
#define c2_TTBR1 (TTBR1_EL1 * 2) /* Translation Table Base Register 1 */
|
||||
#define c2_TTBR1_high (c2_TTBR1 + 1) /* TTBR1 top 32 bits */
|
||||
#define c2_TTBCR (TCR_EL1 * 2) /* Translation Table Base Control R. */
|
||||
#define c3_DACR (DACR32_EL2 * 2)/* Domain Access Control Register */
|
||||
#define c5_DFSR (ESR_EL1 * 2) /* Data Fault Status Register */
|
||||
#define c5_IFSR (IFSR32_EL2 * 2)/* Instruction Fault Status Register */
|
||||
#define c5_ADFSR (AFSR0_EL1 * 2) /* Auxiliary Data Fault Status R */
|
||||
#define c5_AIFSR (AFSR1_EL1 * 2) /* Auxiliary Instr Fault Status R */
|
||||
#define c6_DFAR (FAR_EL1 * 2) /* Data Fault Address Register */
|
||||
#define c6_IFAR (c6_DFAR + 1) /* Instruction Fault Address Register */
|
||||
#define c7_PAR (PAR_EL1 * 2) /* Physical Address Register */
|
||||
#define c7_PAR_high (c7_PAR + 1) /* PAR top 32 bits */
|
||||
#define c10_PRRR (MAIR_EL1 * 2) /* Primary Region Remap Register */
|
||||
#define c10_NMRR (c10_PRRR + 1) /* Normal Memory Remap Register */
|
||||
#define c12_VBAR (VBAR_EL1 * 2) /* Vector Base Address Register */
|
||||
#define c13_CID (CONTEXTIDR_EL1 * 2) /* Context ID Register */
|
||||
#define c13_TID_URW (TPIDR_EL0 * 2) /* Thread ID, User R/W */
|
||||
#define c13_TID_URO (TPIDRRO_EL0 * 2)/* Thread ID, User R/O */
|
||||
#define c13_TID_PRIV (TPIDR_EL1 * 2) /* Thread ID, Privileged */
|
||||
#define c10_AMAIR0 (AMAIR_EL1 * 2) /* Aux Memory Attr Indirection Reg */
|
||||
#define c10_AMAIR1 (c10_AMAIR0 + 1)/* Aux Memory Attr Indirection Reg */
|
||||
#define c14_CNTKCTL (CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */
|
||||
|
||||
#define cp14_DBGDSCRext (MDSCR_EL1 * 2)
|
||||
#define cp14_DBGBCR0 (DBGBCR0_EL1 * 2)
|
||||
#define cp14_DBGBVR0 (DBGBVR0_EL1 * 2)
|
||||
#define cp14_DBGBXVR0 (cp14_DBGBVR0 + 1)
|
||||
#define cp14_DBGWCR0 (DBGWCR0_EL1 * 2)
|
||||
#define cp14_DBGWVR0 (DBGWVR0_EL1 * 2)
|
||||
#define cp14_DBGDCCINT (MDCCINT_EL1 * 2)
|
||||
|
||||
#define NR_COPRO_REGS (NR_SYS_REGS * 2)
|
||||
|
||||
#define ARM_EXCEPTION_IRQ 0
|
||||
#define ARM_EXCEPTION_TRAP 1
|
||||
/* The hyp-stub will return this for any kvm_call_hyp() call */
|
||||
#define ARM_EXCEPTION_HYP_GONE 2
|
||||
|
||||
#define KVM_ARM64_DEBUG_DIRTY_SHIFT 0
|
||||
#define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
|
||||
|
@ -105,11 +31,27 @@
|
|||
#define kvm_ksym_ref(sym) phys_to_virt((u64)&sym - kimage_voffset)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#if __GNUC__ > 4
|
||||
#define kvm_ksym_shift (PAGE_OFFSET - KIMAGE_VADDR)
|
||||
#else
|
||||
/*
|
||||
* GCC versions 4.9 and older will fold the constant below into the addend of
|
||||
* the reference to 'sym' above if kvm_ksym_shift is declared static or if the
|
||||
* constant is used directly. However, since we use the small code model for
|
||||
* the core kernel, the reference to 'sym' will be emitted as a adrp/add pair,
|
||||
* with a +/- 4 GB range, resulting in linker relocation errors if the shift
|
||||
* is sufficiently large. So prevent the compiler from folding the shift into
|
||||
* the addend, by making the shift a variable with external linkage.
|
||||
*/
|
||||
__weak u64 kvm_ksym_shift = PAGE_OFFSET - KIMAGE_VADDR;
|
||||
#endif
|
||||
|
||||
struct kvm;
|
||||
struct kvm_vcpu;
|
||||
|
||||
extern char __kvm_hyp_init[];
|
||||
extern char __kvm_hyp_init_end[];
|
||||
extern char __kvm_hyp_reset[];
|
||||
|
||||
extern char __kvm_hyp_vector[];
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include <asm/esr.h>
|
||||
#include <asm/kvm_arm.h>
|
||||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_mmio.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/cputype.h>
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/kvm_types.h>
|
||||
#include <asm/kvm.h>
|
||||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_mmio.h>
|
||||
|
||||
#define __KVM_HAVE_ARCH_INTC_INITIALIZED
|
||||
|
@ -45,6 +44,7 @@
|
|||
int __attribute_const__ kvm_target_cpu(void);
|
||||
int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
|
||||
int kvm_arch_dev_ioctl_check_extension(long ext);
|
||||
phys_addr_t kvm_hyp_reset_entry(void);
|
||||
|
||||
struct kvm_arch {
|
||||
/* The VMID generation used for the virt. memory system */
|
||||
|
@ -85,6 +85,86 @@ struct kvm_vcpu_fault_info {
|
|||
u64 hpfar_el2; /* Hyp IPA Fault Address Register */
|
||||
};
|
||||
|
||||
/*
|
||||
* 0 is reserved as an invalid value.
|
||||
* Order should be kept in sync with the save/restore code.
|
||||
*/
|
||||
enum vcpu_sysreg {
|
||||
__INVALID_SYSREG__,
|
||||
MPIDR_EL1, /* MultiProcessor Affinity Register */
|
||||
CSSELR_EL1, /* Cache Size Selection Register */
|
||||
SCTLR_EL1, /* System Control Register */
|
||||
ACTLR_EL1, /* Auxiliary Control Register */
|
||||
CPACR_EL1, /* Coprocessor Access Control */
|
||||
TTBR0_EL1, /* Translation Table Base Register 0 */
|
||||
TTBR1_EL1, /* Translation Table Base Register 1 */
|
||||
TCR_EL1, /* Translation Control Register */
|
||||
ESR_EL1, /* Exception Syndrome Register */
|
||||
AFSR0_EL1, /* Auxilary Fault Status Register 0 */
|
||||
AFSR1_EL1, /* Auxilary Fault Status Register 1 */
|
||||
FAR_EL1, /* Fault Address Register */
|
||||
MAIR_EL1, /* Memory Attribute Indirection Register */
|
||||
VBAR_EL1, /* Vector Base Address Register */
|
||||
CONTEXTIDR_EL1, /* Context ID Register */
|
||||
TPIDR_EL0, /* Thread ID, User R/W */
|
||||
TPIDRRO_EL0, /* Thread ID, User R/O */
|
||||
TPIDR_EL1, /* Thread ID, Privileged */
|
||||
AMAIR_EL1, /* Aux Memory Attribute Indirection Register */
|
||||
CNTKCTL_EL1, /* Timer Control Register (EL1) */
|
||||
PAR_EL1, /* Physical Address Register */
|
||||
MDSCR_EL1, /* Monitor Debug System Control Register */
|
||||
MDCCINT_EL1, /* Monitor Debug Comms Channel Interrupt Enable Reg */
|
||||
|
||||
/* 32bit specific registers. Keep them at the end of the range */
|
||||
DACR32_EL2, /* Domain Access Control Register */
|
||||
IFSR32_EL2, /* Instruction Fault Status Register */
|
||||
FPEXC32_EL2, /* Floating-Point Exception Control Register */
|
||||
DBGVCR32_EL2, /* Debug Vector Catch Register */
|
||||
|
||||
NR_SYS_REGS /* Nothing after this line! */
|
||||
};
|
||||
|
||||
/* 32bit mapping */
|
||||
#define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
|
||||
#define c0_CSSELR (CSSELR_EL1 * 2)/* Cache Size Selection Register */
|
||||
#define c1_SCTLR (SCTLR_EL1 * 2) /* System Control Register */
|
||||
#define c1_ACTLR (ACTLR_EL1 * 2) /* Auxiliary Control Register */
|
||||
#define c1_CPACR (CPACR_EL1 * 2) /* Coprocessor Access Control */
|
||||
#define c2_TTBR0 (TTBR0_EL1 * 2) /* Translation Table Base Register 0 */
|
||||
#define c2_TTBR0_high (c2_TTBR0 + 1) /* TTBR0 top 32 bits */
|
||||
#define c2_TTBR1 (TTBR1_EL1 * 2) /* Translation Table Base Register 1 */
|
||||
#define c2_TTBR1_high (c2_TTBR1 + 1) /* TTBR1 top 32 bits */
|
||||
#define c2_TTBCR (TCR_EL1 * 2) /* Translation Table Base Control R. */
|
||||
#define c3_DACR (DACR32_EL2 * 2)/* Domain Access Control Register */
|
||||
#define c5_DFSR (ESR_EL1 * 2) /* Data Fault Status Register */
|
||||
#define c5_IFSR (IFSR32_EL2 * 2)/* Instruction Fault Status Register */
|
||||
#define c5_ADFSR (AFSR0_EL1 * 2) /* Auxiliary Data Fault Status R */
|
||||
#define c5_AIFSR (AFSR1_EL1 * 2) /* Auxiliary Instr Fault Status R */
|
||||
#define c6_DFAR (FAR_EL1 * 2) /* Data Fault Address Register */
|
||||
#define c6_IFAR (c6_DFAR + 1) /* Instruction Fault Address Register */
|
||||
#define c7_PAR (PAR_EL1 * 2) /* Physical Address Register */
|
||||
#define c7_PAR_high (c7_PAR + 1) /* PAR top 32 bits */
|
||||
#define c10_PRRR (MAIR_EL1 * 2) /* Primary Region Remap Register */
|
||||
#define c10_NMRR (c10_PRRR + 1) /* Normal Memory Remap Register */
|
||||
#define c12_VBAR (VBAR_EL1 * 2) /* Vector Base Address Register */
|
||||
#define c13_CID (CONTEXTIDR_EL1 * 2) /* Context ID Register */
|
||||
#define c13_TID_URW (TPIDR_EL0 * 2) /* Thread ID, User R/W */
|
||||
#define c13_TID_URO (TPIDRRO_EL0 * 2)/* Thread ID, User R/O */
|
||||
#define c13_TID_PRIV (TPIDR_EL1 * 2) /* Thread ID, Privileged */
|
||||
#define c10_AMAIR0 (AMAIR_EL1 * 2) /* Aux Memory Attr Indirection Reg */
|
||||
#define c10_AMAIR1 (c10_AMAIR0 + 1)/* Aux Memory Attr Indirection Reg */
|
||||
#define c14_CNTKCTL (CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */
|
||||
|
||||
#define cp14_DBGDSCRext (MDSCR_EL1 * 2)
|
||||
#define cp14_DBGBCR0 (DBGBCR0_EL1 * 2)
|
||||
#define cp14_DBGBVR0 (DBGBVR0_EL1 * 2)
|
||||
#define cp14_DBGBXVR0 (cp14_DBGBVR0 + 1)
|
||||
#define cp14_DBGWCR0 (DBGWCR0_EL1 * 2)
|
||||
#define cp14_DBGWVR0 (DBGWVR0_EL1 * 2)
|
||||
#define cp14_DBGDCCINT (MDCCINT_EL1 * 2)
|
||||
|
||||
#define NR_COPRO_REGS (NR_SYS_REGS * 2)
|
||||
|
||||
struct kvm_cpu_context {
|
||||
struct kvm_regs gp_regs;
|
||||
union {
|
||||
|
@ -247,7 +327,21 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
|
|||
hyp_stack_ptr, vector_ptr);
|
||||
}
|
||||
|
||||
static inline void kvm_arch_hardware_disable(void) {}
|
||||
static inline void __cpu_init_stage2(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void __cpu_reset_hyp_mode(phys_addr_t boot_pgd_ptr,
|
||||
phys_addr_t phys_idmap_start)
|
||||
{
|
||||
/*
|
||||
* Call reset code, and switch back to stub hyp vectors.
|
||||
* Uses __kvm_call_hyp() to avoid kaslr's kvm_ksym_ref() translation.
|
||||
*/
|
||||
__kvm_call_hyp((void *)kvm_hyp_reset_entry(),
|
||||
boot_pgd_ptr, phys_idmap_start);
|
||||
}
|
||||
|
||||
static inline void kvm_arch_hardware_unsetup(void) {}
|
||||
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
|
||||
static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#define __ARM64_KVM_MMIO_H__
|
||||
|
||||
#include <linux/kvm_host.h>
|
||||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_arm.h>
|
||||
|
||||
/*
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue