mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
Merge branch 'android-4.9' into amlogic-4.9-dev
This commit is contained in:
@@ -11,24 +11,56 @@ in AArch64 Linux.
|
||||
The kernel configures the translation tables so that translations made
|
||||
via TTBR0 (i.e. userspace mappings) have the top byte (bits 63:56) of
|
||||
the virtual address ignored by the translation hardware. This frees up
|
||||
this byte for application use, with the following caveats:
|
||||
this byte for application use.
|
||||
|
||||
(1) The kernel requires that all user addresses passed to EL1
|
||||
are tagged with tag 0x00. This means that any syscall
|
||||
parameters containing user virtual addresses *must* have
|
||||
their top byte cleared before trapping to the kernel.
|
||||
|
||||
(2) Non-zero tags are not preserved when delivering signals.
|
||||
This means that signal handlers in applications making use
|
||||
of tags cannot rely on the tag information for user virtual
|
||||
addresses being maintained for fields inside siginfo_t.
|
||||
One exception to this rule is for signals raised in response
|
||||
to watchpoint debug exceptions, where the tag information
|
||||
will be preserved.
|
||||
Passing tagged addresses to the kernel
|
||||
--------------------------------------
|
||||
|
||||
(3) Special care should be taken when using tagged pointers,
|
||||
since it is likely that C compilers will not hazard two
|
||||
virtual addresses differing only in the upper byte.
|
||||
All interpretation of userspace memory addresses by the kernel assumes
|
||||
an address tag of 0x00.
|
||||
|
||||
This includes, but is not limited to, addresses found in:
|
||||
|
||||
- pointer arguments to system calls, including pointers in structures
|
||||
passed to system calls,
|
||||
|
||||
- the stack pointer (sp), e.g. when interpreting it to deliver a
|
||||
signal,
|
||||
|
||||
- the frame pointer (x29) and frame records, e.g. when interpreting
|
||||
them to generate a backtrace or call graph.
|
||||
|
||||
Using non-zero address tags in any of these locations may result in an
|
||||
error code being returned, a (fatal) signal being raised, or other modes
|
||||
of failure.
|
||||
|
||||
For these reasons, passing non-zero address tags to the kernel via
|
||||
system calls is forbidden, and using a non-zero address tag for sp is
|
||||
strongly discouraged.
|
||||
|
||||
Programs maintaining a frame pointer and frame records that use non-zero
|
||||
address tags may suffer impaired or inaccurate debug and profiling
|
||||
visibility.
|
||||
|
||||
|
||||
Preserving tags
|
||||
---------------
|
||||
|
||||
Non-zero tags are not preserved when delivering signals. This means that
|
||||
signal handlers in applications making use of tags cannot rely on the
|
||||
tag information for user virtual addresses being maintained for fields
|
||||
inside siginfo_t. One exception to this rule is for signals raised in
|
||||
response to watchpoint debug exceptions, where the tag information will
|
||||
be preserved.
|
||||
|
||||
The architecture prevents the use of a tagged PC, so the upper byte will
|
||||
be set to a sign-extension of bit 55 on exception return.
|
||||
|
||||
|
||||
Other considerations
|
||||
--------------------
|
||||
|
||||
Special care should be taken when using tagged pointers, since it is
|
||||
likely that C compilers will not hazard two virtual addresses differing
|
||||
only in the upper byte.
|
||||
|
||||
@@ -308,6 +308,12 @@ Color Management Properties
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c
|
||||
:export:
|
||||
|
||||
Explicit Fencing Properties
|
||||
---------------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
|
||||
:doc: explicit fencing properties
|
||||
|
||||
Existing KMS Properties
|
||||
-----------------------
|
||||
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 27
|
||||
SUBLEVEL = 30
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -97,4 +97,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _UAPI_ASM_SOCKET_H */
|
||||
|
||||
@@ -1188,8 +1188,10 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
|
||||
if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
|
||||
return -EFAULT;
|
||||
|
||||
err = 0;
|
||||
err |= put_user(status, ustatus);
|
||||
err = put_user(status, ustatus);
|
||||
if (ret < 0)
|
||||
return err ? err : ret;
|
||||
|
||||
err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
|
||||
err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
|
||||
err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
|
||||
|
||||
@@ -162,9 +162,10 @@
|
||||
};
|
||||
|
||||
adc0: adc@f8018000 {
|
||||
atmel,adc-vref = <3300>;
|
||||
atmel,adc-channels-used = <0xfe>;
|
||||
pinctrl-0 = <
|
||||
&pinctrl_adc0_adtrg
|
||||
&pinctrl_adc0_ad0
|
||||
&pinctrl_adc0_ad1
|
||||
&pinctrl_adc0_ad2
|
||||
&pinctrl_adc0_ad3
|
||||
@@ -172,8 +173,6 @@
|
||||
&pinctrl_adc0_ad5
|
||||
&pinctrl_adc0_ad6
|
||||
&pinctrl_adc0_ad7
|
||||
&pinctrl_adc0_ad8
|
||||
&pinctrl_adc0_ad9
|
||||
>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
|
||||
open-source;
|
||||
priority = <200>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
|
||||
open-source;
|
||||
priority = <200>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpioa 31 GPIO_ACTIVE_LOW>;
|
||||
open-source;
|
||||
priority = <200>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
|
||||
open-source;
|
||||
priority = <200>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
|
||||
open-source;
|
||||
priority = <200>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
|
||||
open-source;
|
||||
priority = <200>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
|
||||
open-source;
|
||||
priority = <200>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -12,23 +12,6 @@
|
||||
model = "Freescale i.MX6 SoloX SDB RevB Board";
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
996000 1250000
|
||||
792000 1175000
|
||||
396000 1175000
|
||||
198000 1175000
|
||||
>;
|
||||
fsl,soc-operating-points = <
|
||||
/* ARM kHz SOC uV */
|
||||
996000 1250000
|
||||
792000 1175000
|
||||
396000 1175000
|
||||
198000 1175000
|
||||
>;
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
clock-frequency = <100000>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
@@ -65,13 +65,13 @@
|
||||
cxo_board {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <19200000>;
|
||||
clock-frequency = <25000000>;
|
||||
};
|
||||
|
||||
pxo_board {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <27000000>;
|
||||
clock-frequency = <25000000>;
|
||||
};
|
||||
|
||||
sleep_clk: sleep_clk {
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
reg = <8>;
|
||||
label = "cpu";
|
||||
ethernet = <&gmac>;
|
||||
phy-mode = "rgmii";
|
||||
phy-mode = "rgmii-txid";
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
|
||||
@@ -569,6 +569,7 @@
|
||||
regulator-name = "+3VS,vdd_pnl";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
gpio = <&gpio TEGRA_GPIO(A, 4) GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
@@ -31,7 +31,8 @@ void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table);
|
||||
int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
|
||||
|
||||
@@ -18,13 +18,18 @@ enum {
|
||||
};
|
||||
#endif
|
||||
|
||||
struct mod_plt_sec {
|
||||
struct elf32_shdr *plt;
|
||||
int plt_count;
|
||||
};
|
||||
|
||||
struct mod_arch_specific {
|
||||
#ifdef CONFIG_ARM_UNWIND
|
||||
struct unwind_table *unwind[ARM_SEC_MAX];
|
||||
#endif
|
||||
#ifdef CONFIG_ARM_MODULE_PLTS
|
||||
struct elf32_shdr *plt;
|
||||
int plt_count;
|
||||
struct mod_plt_sec core;
|
||||
struct mod_plt_sec init;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
|
||||
* Copyright (C) 2014-2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
|
||||
*
|
||||
* 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
|
||||
@@ -31,9 +31,17 @@ struct plt_entries {
|
||||
u32 lit[PLT_ENT_COUNT];
|
||||
};
|
||||
|
||||
static bool in_init(const struct module *mod, unsigned long loc)
|
||||
{
|
||||
return loc - (u32)mod->init_layout.base < mod->init_layout.size;
|
||||
}
|
||||
|
||||
u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
|
||||
{
|
||||
struct plt_entries *plt = (struct plt_entries *)mod->arch.plt->sh_addr;
|
||||
struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core :
|
||||
&mod->arch.init;
|
||||
|
||||
struct plt_entries *plt = (struct plt_entries *)pltsec->plt->sh_addr;
|
||||
int idx = 0;
|
||||
|
||||
/*
|
||||
@@ -41,9 +49,9 @@ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
|
||||
* relocations are sorted, this will be the last entry we allocated.
|
||||
* (if one exists).
|
||||
*/
|
||||
if (mod->arch.plt_count > 0) {
|
||||
plt += (mod->arch.plt_count - 1) / PLT_ENT_COUNT;
|
||||
idx = (mod->arch.plt_count - 1) % PLT_ENT_COUNT;
|
||||
if (pltsec->plt_count > 0) {
|
||||
plt += (pltsec->plt_count - 1) / PLT_ENT_COUNT;
|
||||
idx = (pltsec->plt_count - 1) % PLT_ENT_COUNT;
|
||||
|
||||
if (plt->lit[idx] == val)
|
||||
return (u32)&plt->ldr[idx];
|
||||
@@ -53,8 +61,8 @@ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
|
||||
plt++;
|
||||
}
|
||||
|
||||
mod->arch.plt_count++;
|
||||
BUG_ON(mod->arch.plt_count * PLT_ENT_SIZE > mod->arch.plt->sh_size);
|
||||
pltsec->plt_count++;
|
||||
BUG_ON(pltsec->plt_count * PLT_ENT_SIZE > pltsec->plt->sh_size);
|
||||
|
||||
if (!idx)
|
||||
/* Populate a new set of entries */
|
||||
@@ -129,7 +137,7 @@ static bool duplicate_rel(Elf32_Addr base, const Elf32_Rel *rel, int num)
|
||||
|
||||
/* Count how many PLT entries we may need */
|
||||
static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
|
||||
const Elf32_Rel *rel, int num)
|
||||
const Elf32_Rel *rel, int num, Elf32_Word dstidx)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
const Elf32_Sym *s;
|
||||
@@ -144,13 +152,17 @@ static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
|
||||
case R_ARM_THM_JUMP24:
|
||||
/*
|
||||
* We only have to consider branch targets that resolve
|
||||
* to undefined symbols. This is not simply a heuristic,
|
||||
* it is a fundamental limitation, since the PLT itself
|
||||
* is part of the module, and needs to be within range
|
||||
* as well, so modules can never grow beyond that limit.
|
||||
* to symbols that are defined in a different section.
|
||||
* This is not simply a heuristic, it is a fundamental
|
||||
* limitation, since there is no guaranteed way to emit
|
||||
* PLT entries sufficiently close to the branch if the
|
||||
* section size exceeds the range of a branch
|
||||
* instruction. So ignore relocations against defined
|
||||
* symbols if they live in the same section as the
|
||||
* relocation target.
|
||||
*/
|
||||
s = syms + ELF32_R_SYM(rel[i].r_info);
|
||||
if (s->st_shndx != SHN_UNDEF)
|
||||
if (s->st_shndx == dstidx)
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -161,7 +173,12 @@ static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
|
||||
* So we need to support them, but there is no need to
|
||||
* take them into consideration when trying to optimize
|
||||
* this code. So let's only check for duplicates when
|
||||
* the addend is zero.
|
||||
* the addend is zero. (Note that calls into the core
|
||||
* module via init PLT entries could involve section
|
||||
* relative symbol references with non-zero addends, for
|
||||
* which we may end up emitting duplicates, but the init
|
||||
* PLT is released along with the rest of the .init
|
||||
* region as soon as module loading completes.)
|
||||
*/
|
||||
if (!is_zero_addend_relocation(base, rel + i) ||
|
||||
!duplicate_rel(base, rel, i))
|
||||
@@ -174,7 +191,8 @@ static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
|
||||
int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
|
||||
char *secstrings, struct module *mod)
|
||||
{
|
||||
unsigned long plts = 0;
|
||||
unsigned long core_plts = 0;
|
||||
unsigned long init_plts = 0;
|
||||
Elf32_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;
|
||||
Elf32_Sym *syms = NULL;
|
||||
|
||||
@@ -184,13 +202,15 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
|
||||
*/
|
||||
for (s = sechdrs; s < sechdrs_end; ++s) {
|
||||
if (strcmp(".plt", secstrings + s->sh_name) == 0)
|
||||
mod->arch.plt = s;
|
||||
mod->arch.core.plt = s;
|
||||
else if (strcmp(".init.plt", secstrings + s->sh_name) == 0)
|
||||
mod->arch.init.plt = s;
|
||||
else if (s->sh_type == SHT_SYMTAB)
|
||||
syms = (Elf32_Sym *)s->sh_addr;
|
||||
}
|
||||
|
||||
if (!mod->arch.plt) {
|
||||
pr_err("%s: module PLT section missing\n", mod->name);
|
||||
if (!mod->arch.core.plt || !mod->arch.init.plt) {
|
||||
pr_err("%s: module PLT section(s) missing\n", mod->name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (!syms) {
|
||||
@@ -213,16 +233,29 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
|
||||
/* sort by type and symbol index */
|
||||
sort(rels, numrels, sizeof(Elf32_Rel), cmp_rel, NULL);
|
||||
|
||||
plts += count_plts(syms, dstsec->sh_addr, rels, numrels);
|
||||
if (strncmp(secstrings + dstsec->sh_name, ".init", 5) != 0)
|
||||
core_plts += count_plts(syms, dstsec->sh_addr, rels,
|
||||
numrels, s->sh_info);
|
||||
else
|
||||
init_plts += count_plts(syms, dstsec->sh_addr, rels,
|
||||
numrels, s->sh_info);
|
||||
}
|
||||
|
||||
mod->arch.plt->sh_type = SHT_NOBITS;
|
||||
mod->arch.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
|
||||
mod->arch.plt->sh_addralign = L1_CACHE_BYTES;
|
||||
mod->arch.plt->sh_size = round_up(plts * PLT_ENT_SIZE,
|
||||
sizeof(struct plt_entries));
|
||||
mod->arch.plt_count = 0;
|
||||
mod->arch.core.plt->sh_type = SHT_NOBITS;
|
||||
mod->arch.core.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
|
||||
mod->arch.core.plt->sh_addralign = L1_CACHE_BYTES;
|
||||
mod->arch.core.plt->sh_size = round_up(core_plts * PLT_ENT_SIZE,
|
||||
sizeof(struct plt_entries));
|
||||
mod->arch.core.plt_count = 0;
|
||||
|
||||
pr_debug("%s: plt=%x\n", __func__, mod->arch.plt->sh_size);
|
||||
mod->arch.init.plt->sh_type = SHT_NOBITS;
|
||||
mod->arch.init.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
|
||||
mod->arch.init.plt->sh_addralign = L1_CACHE_BYTES;
|
||||
mod->arch.init.plt->sh_size = round_up(init_plts * PLT_ENT_SIZE,
|
||||
sizeof(struct plt_entries));
|
||||
mod->arch.init.plt_count = 0;
|
||||
|
||||
pr_debug("%s: plt=%x, init.plt=%x\n", __func__,
|
||||
mod->arch.core.plt->sh_size, mod->arch.init.plt->sh_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
SECTIONS {
|
||||
.plt : { BYTE(0) }
|
||||
.init.plt : { BYTE(0) }
|
||||
}
|
||||
|
||||
@@ -93,12 +93,6 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
{
|
||||
kvm_inject_undefined(vcpu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
|
||||
{
|
||||
/*
|
||||
@@ -514,12 +508,7 @@ static int emulate_cp15(struct kvm_vcpu *vcpu,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
|
||||
* @vcpu: The VCPU pointer
|
||||
* @run: The kvm_run struct
|
||||
*/
|
||||
int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
static struct coproc_params decode_64bit_hsr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct coproc_params params;
|
||||
|
||||
@@ -533,9 +522,38 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
|
||||
params.CRm = 0;
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
|
||||
* @vcpu: The VCPU pointer
|
||||
* @run: The kvm_run struct
|
||||
*/
|
||||
int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
{
|
||||
struct coproc_params params = decode_64bit_hsr(vcpu);
|
||||
|
||||
return emulate_cp15(vcpu, ¶ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access
|
||||
* @vcpu: The VCPU pointer
|
||||
* @run: The kvm_run struct
|
||||
*/
|
||||
int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
{
|
||||
struct coproc_params params = decode_64bit_hsr(vcpu);
|
||||
|
||||
/* raz_wi cp14 */
|
||||
pm_fake(vcpu, ¶ms, NULL);
|
||||
|
||||
/* handled */
|
||||
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void reset_coproc_regs(struct kvm_vcpu *vcpu,
|
||||
const struct coproc_reg *table, size_t num)
|
||||
{
|
||||
@@ -546,12 +564,7 @@ static void reset_coproc_regs(struct kvm_vcpu *vcpu,
|
||||
table[i].reset(vcpu, &table[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
|
||||
* @vcpu: The VCPU pointer
|
||||
* @run: The kvm_run struct
|
||||
*/
|
||||
int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
static struct coproc_params decode_32bit_hsr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct coproc_params params;
|
||||
|
||||
@@ -565,9 +578,37 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7;
|
||||
params.Rt2 = 0;
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
|
||||
* @vcpu: The VCPU pointer
|
||||
* @run: The kvm_run struct
|
||||
*/
|
||||
int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
{
|
||||
struct coproc_params params = decode_32bit_hsr(vcpu);
|
||||
return emulate_cp15(vcpu, ¶ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_handle_cp14_32 -- handles a mrc/mcr trap on a guest CP14 access
|
||||
* @vcpu: The VCPU pointer
|
||||
* @run: The kvm_run struct
|
||||
*/
|
||||
int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
{
|
||||
struct coproc_params params = decode_32bit_hsr(vcpu);
|
||||
|
||||
/* raz_wi cp14 */
|
||||
pm_fake(vcpu, ¶ms, NULL);
|
||||
|
||||
/* handled */
|
||||
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Userspace API
|
||||
*****************************************************************************/
|
||||
|
||||
@@ -83,9 +83,9 @@ static exit_handle_fn arm_exit_handlers[] = {
|
||||
[HSR_EC_WFI] = kvm_handle_wfx,
|
||||
[HSR_EC_CP15_32] = kvm_handle_cp15_32,
|
||||
[HSR_EC_CP15_64] = kvm_handle_cp15_64,
|
||||
[HSR_EC_CP14_MR] = kvm_handle_cp14_access,
|
||||
[HSR_EC_CP14_MR] = kvm_handle_cp14_32,
|
||||
[HSR_EC_CP14_LS] = kvm_handle_cp14_load_store,
|
||||
[HSR_EC_CP14_64] = kvm_handle_cp14_access,
|
||||
[HSR_EC_CP14_64] = kvm_handle_cp14_64,
|
||||
[HSR_EC_CP_0_13] = kvm_handle_cp_0_13_access,
|
||||
[HSR_EC_CP10_ID] = kvm_handle_cp10_id,
|
||||
[HSR_EC_HVC] = handle_hvc,
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# Makefile for Kernel-based Virtual Machine module, HYP part
|
||||
#
|
||||
|
||||
ccflags-y += -fno-stack-protector
|
||||
|
||||
KVM=../../../../virt/kvm
|
||||
|
||||
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
|
||||
|
||||
@@ -48,7 +48,9 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu, u32 *fpexc_host)
|
||||
write_sysreg(HSTR_T(15), HSTR);
|
||||
write_sysreg(HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11), HCPTR);
|
||||
val = read_sysreg(HDCR);
|
||||
write_sysreg(val | HDCR_TPM | HDCR_TPMCR, HDCR);
|
||||
val |= HDCR_TPM | HDCR_TPMCR; /* trap performance monitors */
|
||||
val |= HDCR_TDRA | HDCR_TDOSA | HDCR_TDA; /* trap debug regs */
|
||||
write_sysreg(val, HDCR);
|
||||
}
|
||||
|
||||
static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
|
||||
|
||||
@@ -208,9 +208,10 @@ int kvm_psci_version(struct kvm_vcpu *vcpu)
|
||||
|
||||
static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
int ret = 1;
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
|
||||
unsigned long val;
|
||||
int ret = 1;
|
||||
|
||||
switch (psci_fn) {
|
||||
case PSCI_0_2_FN_PSCI_VERSION:
|
||||
@@ -230,7 +231,9 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
|
||||
break;
|
||||
case PSCI_0_2_FN_CPU_ON:
|
||||
case PSCI_0_2_FN64_CPU_ON:
|
||||
mutex_lock(&kvm->lock);
|
||||
val = kvm_psci_vcpu_on(vcpu);
|
||||
mutex_unlock(&kvm->lock);
|
||||
break;
|
||||
case PSCI_0_2_FN_AFFINITY_INFO:
|
||||
case PSCI_0_2_FN64_AFFINITY_INFO:
|
||||
@@ -279,6 +282,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
|
||||
|
||||
static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
|
||||
unsigned long val;
|
||||
|
||||
@@ -288,7 +292,9 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
|
||||
val = PSCI_RET_SUCCESS;
|
||||
break;
|
||||
case KVM_PSCI_FN_CPU_ON:
|
||||
mutex_lock(&kvm->lock);
|
||||
val = kvm_psci_vcpu_on(vcpu);
|
||||
mutex_unlock(&kvm->lock);
|
||||
break;
|
||||
default:
|
||||
val = PSCI_RET_NOT_SUPPORTED;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
#include "omap44xx.h"
|
||||
|
||||
@@ -66,7 +67,7 @@ wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
|
||||
cmp r0, r4
|
||||
bne wait_2
|
||||
ldr r12, =API_HYP_ENTRY
|
||||
adr r0, hyp_boot
|
||||
badr r0, hyp_boot
|
||||
smc #0
|
||||
hyp_boot:
|
||||
b omap_secondary_startup
|
||||
|
||||
@@ -147,10 +147,10 @@ __v7m_setup_cont:
|
||||
|
||||
@ Configure caches (if implemented)
|
||||
teq r8, #0
|
||||
stmneia r12, {r0-r6, lr} @ v7m_invalidate_l1 touches r0-r6
|
||||
stmneia sp, {r0-r6, lr} @ v7m_invalidate_l1 touches r0-r6
|
||||
blne v7m_invalidate_l1
|
||||
teq r8, #0 @ re-evalutae condition
|
||||
ldmneia r12, {r0-r6, lr}
|
||||
ldmneia sp, {r0-r6, lr}
|
||||
|
||||
@ Configure the System Control Register to ensure 8-byte stack alignment
|
||||
@ Note the STKALIGN bit is either RW or RAO.
|
||||
|
||||
@@ -772,6 +772,7 @@
|
||||
clocks = <&sys_ctrl 2>, <&sys_ctrl 1>;
|
||||
clock-names = "ciu", "biu";
|
||||
resets = <&sys_ctrl PERIPH_RSTDIS0_MMC0>;
|
||||
reset-names = "reset";
|
||||
bus-width = <0x8>;
|
||||
vmmc-supply = <&ldo19>;
|
||||
pinctrl-names = "default";
|
||||
@@ -795,6 +796,7 @@
|
||||
clocks = <&sys_ctrl 4>, <&sys_ctrl 3>;
|
||||
clock-names = "ciu", "biu";
|
||||
resets = <&sys_ctrl PERIPH_RSTDIS0_MMC1>;
|
||||
reset-names = "reset";
|
||||
vqmmc-supply = <&ldo7>;
|
||||
vmmc-supply = <&ldo10>;
|
||||
bus-width = <0x4>;
|
||||
@@ -813,6 +815,7 @@
|
||||
clocks = <&sys_ctrl HI6220_MMC2_CIUCLK>, <&sys_ctrl HI6220_MMC2_CLK>;
|
||||
clock-names = "ciu", "biu";
|
||||
resets = <&sys_ctrl PERIPH_RSTDIS0_MMC2>;
|
||||
reset-names = "reset";
|
||||
bus-width = <0x4>;
|
||||
broken-cd;
|
||||
pinctrl-names = "default", "idle";
|
||||
|
||||
@@ -553,6 +553,7 @@
|
||||
phy-mode = "rgmii-id";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
can0: can@e6c30000 {
|
||||
|
||||
@@ -42,25 +42,35 @@
|
||||
#define __smp_rmb() dmb(ishld)
|
||||
#define __smp_wmb() dmb(ishst)
|
||||
|
||||
#define __smp_store_release(p, v) \
|
||||
#define __smp_store_release(p, v) \
|
||||
do { \
|
||||
union { typeof(*p) __val; char __c[1]; } __u = \
|
||||
{ .__val = (__force typeof(*p)) (v) }; \
|
||||
compiletime_assert_atomic_type(*p); \
|
||||
switch (sizeof(*p)) { \
|
||||
case 1: \
|
||||
asm volatile ("stlrb %w1, %0" \
|
||||
: "=Q" (*p) : "r" (v) : "memory"); \
|
||||
: "=Q" (*p) \
|
||||
: "r" (*(__u8 *)__u.__c) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
case 2: \
|
||||
asm volatile ("stlrh %w1, %0" \
|
||||
: "=Q" (*p) : "r" (v) : "memory"); \
|
||||
: "=Q" (*p) \
|
||||
: "r" (*(__u16 *)__u.__c) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
case 4: \
|
||||
asm volatile ("stlr %w1, %0" \
|
||||
: "=Q" (*p) : "r" (v) : "memory"); \
|
||||
: "=Q" (*p) \
|
||||
: "r" (*(__u32 *)__u.__c) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
case 8: \
|
||||
asm volatile ("stlr %1, %0" \
|
||||
: "=Q" (*p) : "r" (v) : "memory"); \
|
||||
: "=Q" (*p) \
|
||||
: "r" (*(__u64 *)__u.__c) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -46,7 +46,7 @@ static inline unsigned long __xchg_case_##name(unsigned long x, \
|
||||
" swp" #acq_lse #rel #sz "\t%" #w "3, %" #w "0, %2\n" \
|
||||
__nops(3) \
|
||||
" " #nop_lse) \
|
||||
: "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr) \
|
||||
: "=&r" (ret), "=&r" (tmp), "+Q" (*(unsigned long *)ptr) \
|
||||
: "r" (x) \
|
||||
: cl); \
|
||||
\
|
||||
|
||||
@@ -240,6 +240,12 @@ static inline u8 kvm_vcpu_trap_get_fault_type(const struct kvm_vcpu *vcpu)
|
||||
return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_FSC_TYPE;
|
||||
}
|
||||
|
||||
static inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u32 esr = kvm_vcpu_get_hsr(vcpu);
|
||||
return (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return vcpu_sys_reg(vcpu, MPIDR_EL1) & MPIDR_HWID_BITMASK;
|
||||
|
||||
@@ -71,9 +71,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
|
||||
#define pte_young(pte) (!!(pte_val(pte) & PTE_AF))
|
||||
#define pte_special(pte) (!!(pte_val(pte) & PTE_SPECIAL))
|
||||
#define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE))
|
||||
#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
|
||||
#define pte_user_exec(pte) (!(pte_val(pte) & PTE_UXN))
|
||||
#define pte_cont(pte) (!!(pte_val(pte) & PTE_CONT))
|
||||
#define pte_ng(pte) (!!(pte_val(pte) & PTE_NG))
|
||||
|
||||
#ifdef CONFIG_ARM64_HW_AFDBM
|
||||
#define pte_hw_dirty(pte) (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
|
||||
@@ -84,8 +83,12 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
|
||||
#define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte))
|
||||
|
||||
#define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID))
|
||||
#define pte_valid_global(pte) \
|
||||
((pte_val(pte) & (PTE_VALID | PTE_NG)) == PTE_VALID)
|
||||
/*
|
||||
* Execute-only user mappings do not have the PTE_USER bit set. All valid
|
||||
* kernel mappings have the PTE_UXN bit set.
|
||||
*/
|
||||
#define pte_valid_not_user(pte) \
|
||||
((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
|
||||
#define pte_valid_young(pte) \
|
||||
((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF))
|
||||
|
||||
@@ -178,7 +181,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
|
||||
* Only if the new pte is valid and kernel, otherwise TLB maintenance
|
||||
* or update_mmu_cache() have the necessary barriers.
|
||||
*/
|
||||
if (pte_valid_global(pte)) {
|
||||
if (pte_valid_not_user(pte)) {
|
||||
dsb(ishst);
|
||||
isb();
|
||||
}
|
||||
@@ -212,7 +215,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_val(pte) &= ~PTE_RDONLY;
|
||||
else
|
||||
pte_val(pte) |= PTE_RDONLY;
|
||||
if (pte_ng(pte) && pte_exec(pte) && !pte_special(pte))
|
||||
if (pte_user_exec(pte) && !pte_special(pte))
|
||||
__sync_icache_dcache(pte, addr);
|
||||
}
|
||||
|
||||
|
||||
@@ -97,11 +97,12 @@ static inline void set_fs(mm_segment_t fs)
|
||||
*/
|
||||
#define __range_ok(addr, size) \
|
||||
({ \
|
||||
unsigned long __addr = (unsigned long __force)(addr); \
|
||||
unsigned long flag, roksum; \
|
||||
__chk_user_ptr(addr); \
|
||||
asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, ls" \
|
||||
: "=&r" (flag), "=&r" (roksum) \
|
||||
: "1" (addr), "Ir" (size), \
|
||||
: "1" (__addr), "Ir" (size), \
|
||||
"r" (current_thread_info()->addr_limit) \
|
||||
: "cc"); \
|
||||
flag; \
|
||||
|
||||
@@ -306,7 +306,8 @@ do { \
|
||||
_ASM_EXTABLE(0b, 4b) \
|
||||
_ASM_EXTABLE(1b, 4b) \
|
||||
: "=&r" (res), "+r" (data), "=&r" (temp), "=&r" (temp2) \
|
||||
: "r" (addr), "i" (-EAGAIN), "i" (-EFAULT), \
|
||||
: "r" ((unsigned long)addr), "i" (-EAGAIN), \
|
||||
"i" (-EFAULT), \
|
||||
"i" (__SWP_LL_SC_LOOPS) \
|
||||
: "memory"); \
|
||||
uaccess_disable(); \
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# Makefile for Kernel-based Virtual Machine module, HYP part
|
||||
#
|
||||
|
||||
ccflags-y += -fno-stack-protector
|
||||
|
||||
KVM=../../../../virt/kvm
|
||||
|
||||
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
|
||||
|
||||
@@ -1573,8 +1573,8 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
struct sys_reg_params params;
|
||||
u32 hsr = kvm_vcpu_get_hsr(vcpu);
|
||||
int Rt = (hsr >> 5) & 0xf;
|
||||
int Rt2 = (hsr >> 10) & 0xf;
|
||||
int Rt = kvm_vcpu_sys_get_rt(vcpu);
|
||||
int Rt2 = (hsr >> 10) & 0x1f;
|
||||
|
||||
params.is_aarch32 = true;
|
||||
params.is_32bit = false;
|
||||
@@ -1625,7 +1625,7 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
struct sys_reg_params params;
|
||||
u32 hsr = kvm_vcpu_get_hsr(vcpu);
|
||||
int Rt = (hsr >> 5) & 0xf;
|
||||
int Rt = kvm_vcpu_sys_get_rt(vcpu);
|
||||
|
||||
params.is_aarch32 = true;
|
||||
params.is_32bit = true;
|
||||
@@ -1740,7 +1740,7 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
||||
{
|
||||
struct sys_reg_params params;
|
||||
unsigned long esr = kvm_vcpu_get_hsr(vcpu);
|
||||
int Rt = (esr >> 5) & 0x1f;
|
||||
int Rt = kvm_vcpu_sys_get_rt(vcpu);
|
||||
int ret;
|
||||
|
||||
trace_kvm_handle_sys_reg(esr);
|
||||
|
||||
@@ -779,14 +779,14 @@ static int build_body(struct jit_ctx *ctx)
|
||||
int ret;
|
||||
|
||||
ret = build_insn(insn, ctx);
|
||||
|
||||
if (ctx->image == NULL)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
|
||||
if (ret > 0) {
|
||||
i++;
|
||||
if (ctx->image == NULL)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
continue;
|
||||
}
|
||||
if (ctx->image == NULL)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -90,4 +90,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _UAPI__ASM_AVR32_SOCKET_H */
|
||||
|
||||
@@ -90,5 +90,7 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
|
||||
@@ -99,4 +99,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _ASM_IA64_SOCKET_H */
|
||||
|
||||
@@ -90,4 +90,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _ASM_M32R_SOCKET_H */
|
||||
|
||||
@@ -28,24 +28,32 @@
|
||||
|
||||
#define segment_eq(a, b) ((a).seg == (b).seg)
|
||||
|
||||
#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
|
||||
/*
|
||||
* Explicitly allow NULL pointers here. Parts of the kernel such
|
||||
* as readv/writev use access_ok to validate pointers, but want
|
||||
* to allow NULL pointers for various reasons. NULL pointers are
|
||||
* safe to allow through because the first page is not mappable on
|
||||
* Meta.
|
||||
*
|
||||
* We also wish to avoid letting user code access the system area
|
||||
* and the kernel half of the address space.
|
||||
*/
|
||||
#define __user_bad(addr, size) (((addr) > 0 && (addr) < META_MEMORY_BASE) || \
|
||||
((addr) > PAGE_OFFSET && \
|
||||
(addr) < LINCORE_BASE))
|
||||
|
||||
static inline int __access_ok(unsigned long addr, unsigned long size)
|
||||
{
|
||||
return __kernel_ok || !__user_bad(addr, size);
|
||||
/*
|
||||
* Allow access to the user mapped memory area, but not the system area
|
||||
* before it. The check extends to the top of the address space when
|
||||
* kernel access is allowed (there's no real reason to user copy to the
|
||||
* system area in any case).
|
||||
*/
|
||||
if (likely(addr >= META_MEMORY_BASE && addr < get_fs().seg &&
|
||||
size <= get_fs().seg - addr))
|
||||
return true;
|
||||
/*
|
||||
* Explicitly allow NULL pointers here. Parts of the kernel such
|
||||
* as readv/writev use access_ok to validate pointers, but want
|
||||
* to allow NULL pointers for various reasons. NULL pointers are
|
||||
* safe to allow through because the first page is not mappable on
|
||||
* Meta.
|
||||
*/
|
||||
if (!addr)
|
||||
return true;
|
||||
/* Allow access to core code memory area... */
|
||||
if (addr >= LINCORE_CODE_BASE && addr <= LINCORE_CODE_LIMIT &&
|
||||
size <= LINCORE_CODE_LIMIT + 1 - addr)
|
||||
return true;
|
||||
/* ... but no other areas. */
|
||||
return false;
|
||||
}
|
||||
|
||||
#define access_ok(type, addr, size) __access_ok((unsigned long)(addr), \
|
||||
@@ -186,8 +194,13 @@ do { \
|
||||
extern long __must_check __strncpy_from_user(char *dst, const char __user *src,
|
||||
long count);
|
||||
|
||||
#define strncpy_from_user(dst, src, count) __strncpy_from_user(dst, src, count)
|
||||
|
||||
static inline long
|
||||
strncpy_from_user(char *dst, const char __user *src, long count)
|
||||
{
|
||||
if (!access_ok(VERIFY_READ, src, 1))
|
||||
return -EFAULT;
|
||||
return __strncpy_from_user(dst, src, count);
|
||||
}
|
||||
/*
|
||||
* Return the size of a string (including the ending 0)
|
||||
*
|
||||
|
||||
@@ -1368,6 +1368,7 @@ config CPU_LOONGSON3
|
||||
select WEAK_ORDERING
|
||||
select WEAK_REORDERING_BEYOND_LLSC
|
||||
select MIPS_PGD_C0_CONTEXT
|
||||
select MIPS_L1_CACHE_SHIFT_6
|
||||
select GPIOLIB
|
||||
help
|
||||
The Loongson 3 processor implements the MIPS64R2 instruction
|
||||
|
||||
@@ -108,4 +108,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _UAPI_ASM_SOCKET_H */
|
||||
|
||||
@@ -433,8 +433,8 @@ static int multu_func(struct pt_regs *regs, u32 ir)
|
||||
rs = regs->regs[MIPSInst_RS(ir)];
|
||||
res = (u64)rt * (u64)rs;
|
||||
rt = res;
|
||||
regs->lo = (s64)rt;
|
||||
regs->hi = (s64)(res >> 32);
|
||||
regs->lo = (s64)(s32)rt;
|
||||
regs->hi = (s64)(s32)(res >> 32);
|
||||
|
||||
MIPS_R2_STATS(muls);
|
||||
|
||||
@@ -670,9 +670,9 @@ static int maddu_func(struct pt_regs *regs, u32 ir)
|
||||
res += ((((s64)rt) << 32) | (u32)rs);
|
||||
|
||||
rt = res;
|
||||
regs->lo = (s64)rt;
|
||||
regs->lo = (s64)(s32)rt;
|
||||
rs = res >> 32;
|
||||
regs->hi = (s64)rs;
|
||||
regs->hi = (s64)(s32)rs;
|
||||
|
||||
MIPS_R2_STATS(dsps);
|
||||
|
||||
@@ -728,9 +728,9 @@ static int msubu_func(struct pt_regs *regs, u32 ir)
|
||||
res = ((((s64)rt) << 32) | (u32)rs) - res;
|
||||
|
||||
rt = res;
|
||||
regs->lo = (s64)rt;
|
||||
regs->lo = (s64)(s32)rt;
|
||||
rs = res >> 32;
|
||||
regs->hi = (s64)rs;
|
||||
regs->hi = (s64)(s32)rs;
|
||||
|
||||
MIPS_R2_STATS(dsps);
|
||||
|
||||
|
||||
@@ -90,4 +90,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
@@ -89,4 +89,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 0x402E
|
||||
|
||||
#define SO_COOKIE 0x4032
|
||||
|
||||
#endif /* _UAPI_ASM_SOCKET_H */
|
||||
|
||||
@@ -388,8 +388,8 @@ config DISABLE_MPROFILE_KERNEL
|
||||
be disabled also.
|
||||
|
||||
If you have a toolchain which supports mprofile-kernel, then you can
|
||||
enable this. Otherwise leave it disabled. If you're not sure, say
|
||||
"N".
|
||||
disable this. Otherwise leave it enabled. If you're not sure, say
|
||||
"Y".
|
||||
|
||||
config MPROFILE_KERNEL
|
||||
depends on PPC64 && CPU_LITTLE_ENDIAN
|
||||
|
||||
@@ -70,8 +70,9 @@ extern void drop_cop(unsigned long acop, struct mm_struct *mm);
|
||||
* switch_mm is the entry point called from the architecture independent
|
||||
* code in kernel/sched/core.c
|
||||
*/
|
||||
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
struct task_struct *tsk)
|
||||
static inline void switch_mm_irqs_off(struct mm_struct *prev,
|
||||
struct mm_struct *next,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
/* Mark this context has been used on the new CPU */
|
||||
if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next)))
|
||||
@@ -110,6 +111,18 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
switch_mmu_context(prev, next, tsk);
|
||||
}
|
||||
|
||||
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
switch_mm_irqs_off(prev, next, tsk);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
#define switch_mm_irqs_off switch_mm_irqs_off
|
||||
|
||||
|
||||
#define deactivate_mm(tsk,mm) do { } while (0)
|
||||
|
||||
/*
|
||||
|
||||
@@ -337,7 +337,7 @@
|
||||
#define LPCR_DPFD_SH 52
|
||||
#define LPCR_DPFD (ASM_CONST(7) << LPCR_DPFD_SH)
|
||||
#define LPCR_VRMASD_SH 47
|
||||
#define LPCR_VRMASD (ASM_CONST(1) << LPCR_VRMASD_SH)
|
||||
#define LPCR_VRMASD (ASM_CONST(0x1f) << LPCR_VRMASD_SH)
|
||||
#define LPCR_VRMA_L ASM_CONST(0x0008000000000000)
|
||||
#define LPCR_VRMA_LP0 ASM_CONST(0x0001000000000000)
|
||||
#define LPCR_VRMA_LP1 ASM_CONST(0x0000800000000000)
|
||||
|
||||
@@ -97,4 +97,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _ASM_POWERPC_SOCKET_H */
|
||||
|
||||
@@ -15,7 +15,7 @@ CFLAGS_btext.o += -fPIC
|
||||
endif
|
||||
|
||||
CFLAGS_cputable.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
|
||||
CFLAGS_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
|
||||
CFLAGS_prom_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
|
||||
CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
|
||||
CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
|
||||
|
||||
|
||||
@@ -724,7 +724,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
|
||||
*/
|
||||
#define MAX_WAIT_FOR_RECOVERY 300
|
||||
|
||||
static void eeh_handle_normal_event(struct eeh_pe *pe)
|
||||
static bool eeh_handle_normal_event(struct eeh_pe *pe)
|
||||
{
|
||||
struct pci_bus *frozen_bus;
|
||||
struct eeh_dev *edev, *tmp;
|
||||
@@ -736,7 +736,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
|
||||
if (!frozen_bus) {
|
||||
pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n",
|
||||
__func__, pe->phb->global_number, pe->addr);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
eeh_pe_update_time_stamp(pe);
|
||||
@@ -870,7 +870,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
|
||||
pr_info("EEH: Notify device driver to resume\n");
|
||||
eeh_pe_dev_traverse(pe, eeh_report_resume, NULL);
|
||||
|
||||
return;
|
||||
return false;
|
||||
|
||||
excess_failures:
|
||||
/*
|
||||
@@ -915,8 +915,12 @@ perm_error:
|
||||
pci_lock_rescan_remove();
|
||||
pci_hp_remove_devices(frozen_bus);
|
||||
pci_unlock_rescan_remove();
|
||||
|
||||
/* The passed PE should no longer be used */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void eeh_handle_special_event(void)
|
||||
@@ -982,7 +986,14 @@ static void eeh_handle_special_event(void)
|
||||
*/
|
||||
if (rc == EEH_NEXT_ERR_FROZEN_PE ||
|
||||
rc == EEH_NEXT_ERR_FENCED_PHB) {
|
||||
eeh_handle_normal_event(pe);
|
||||
/*
|
||||
* eeh_handle_normal_event() can make the PE stale if it
|
||||
* determines that the PE cannot possibly be recovered.
|
||||
* Don't modify the PE state if that's the case.
|
||||
*/
|
||||
if (eeh_handle_normal_event(pe))
|
||||
continue;
|
||||
|
||||
eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
|
||||
} else {
|
||||
pci_lock_rescan_remove();
|
||||
|
||||
@@ -735,8 +735,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
||||
andis. r15,r14,(DBSR_IC|DBSR_BT)@h
|
||||
beq+ 1f
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
ld r15,PACATOC(r13)
|
||||
ld r14,interrupt_base_book3e@got(r15)
|
||||
ld r15,__end_interrupts@got(r15)
|
||||
#else
|
||||
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
|
||||
LOAD_REG_IMMEDIATE(r15,__end_interrupts)
|
||||
#endif
|
||||
cmpld cr0,r10,r14
|
||||
cmpld cr1,r10,r15
|
||||
blt+ cr0,1f
|
||||
@@ -799,8 +805,14 @@ kernel_dbg_exc:
|
||||
andis. r15,r14,(DBSR_IC|DBSR_BT)@h
|
||||
beq+ 1f
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
ld r15,PACATOC(r13)
|
||||
ld r14,interrupt_base_book3e@got(r15)
|
||||
ld r15,__end_interrupts@got(r15)
|
||||
#else
|
||||
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
|
||||
LOAD_REG_IMMEDIATE(r15,__end_interrupts)
|
||||
#endif
|
||||
cmpld cr0,r10,r14
|
||||
cmpld cr1,r10,r15
|
||||
blt+ cr0,1f
|
||||
|
||||
@@ -205,6 +205,8 @@ static void machine_check_process_queued_event(struct irq_work *work)
|
||||
{
|
||||
int index;
|
||||
|
||||
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||
|
||||
/*
|
||||
* For now just print it to console.
|
||||
* TODO: log this error event to FSP or nvram.
|
||||
|
||||
@@ -561,6 +561,7 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
|
||||
static struct pstore_info nvram_pstore_info = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "nvram",
|
||||
.flags = PSTORE_FLAGS_DMESG,
|
||||
.open = nvram_pstore_open,
|
||||
.read = nvram_pstore_read,
|
||||
.write = nvram_pstore_write,
|
||||
|
||||
@@ -839,6 +839,25 @@ static void tm_reclaim_thread(struct thread_struct *thr,
|
||||
if (!MSR_TM_SUSPENDED(mfmsr()))
|
||||
return;
|
||||
|
||||
/*
|
||||
* If we are in a transaction and FP is off then we can't have
|
||||
* used FP inside that transaction. Hence the checkpointed
|
||||
* state is the same as the live state. We need to copy the
|
||||
* live state to the checkpointed state so that when the
|
||||
* transaction is restored, the checkpointed state is correct
|
||||
* and the aborted transaction sees the correct state. We use
|
||||
* ckpt_regs.msr here as that's what tm_reclaim will use to
|
||||
* determine if it's going to write the checkpointed state or
|
||||
* not. So either this will write the checkpointed registers,
|
||||
* or reclaim will. Similarly for VMX.
|
||||
*/
|
||||
if ((thr->ckpt_regs.msr & MSR_FP) == 0)
|
||||
memcpy(&thr->ckfp_state, &thr->fp_state,
|
||||
sizeof(struct thread_fp_state));
|
||||
if ((thr->ckpt_regs.msr & MSR_VEC) == 0)
|
||||
memcpy(&thr->ckvr_state, &thr->vr_state,
|
||||
sizeof(struct thread_vr_state));
|
||||
|
||||
giveup_all(container_of(thr, struct task_struct, thread));
|
||||
|
||||
tm_reclaim(thr, thr->ckpt_regs.msr, cause);
|
||||
|
||||
@@ -302,8 +302,6 @@ long machine_check_early(struct pt_regs *regs)
|
||||
|
||||
__this_cpu_inc(irq_stat.mce_exceptions);
|
||||
|
||||
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||
|
||||
if (cur_cpu_spec && cur_cpu_spec->machine_check_early)
|
||||
handled = cur_cpu_spec->machine_check_early(regs);
|
||||
return handled;
|
||||
@@ -737,6 +735,8 @@ void machine_check_exception(struct pt_regs *regs)
|
||||
|
||||
__this_cpu_inc(irq_stat.mce_exceptions);
|
||||
|
||||
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||
|
||||
/* See if any machine dependent calls. In theory, we would want
|
||||
* to call the CPU first, and call the ppc_md. one if the CPU
|
||||
* one returns a positive number. However there is existing code
|
||||
|
||||
@@ -81,7 +81,7 @@ struct page *new_iommu_non_cma_page(struct page *page, unsigned long private,
|
||||
gfp_t gfp_mask = GFP_USER;
|
||||
struct page *new_page;
|
||||
|
||||
if (PageHuge(page) || PageTransHuge(page) || PageCompound(page))
|
||||
if (PageCompound(page))
|
||||
return NULL;
|
||||
|
||||
if (PageHighMem(page))
|
||||
@@ -100,7 +100,7 @@ static int mm_iommu_move_page_from_cma(struct page *page)
|
||||
LIST_HEAD(cma_migrate_pages);
|
||||
|
||||
/* Ignore huge pages for now */
|
||||
if (PageHuge(page) || PageTransHuge(page) || PageCompound(page))
|
||||
if (PageCompound(page))
|
||||
return -EBUSY;
|
||||
|
||||
lru_add_drain();
|
||||
|
||||
@@ -146,7 +146,7 @@ opal_tracepoint_entry:
|
||||
opal_tracepoint_return:
|
||||
std r3,STK_REG(R31)(r1)
|
||||
mr r4,r3
|
||||
ld r0,STK_REG(R23)(r1)
|
||||
ld r3,STK_REG(R23)(r1)
|
||||
bl __trace_opal_exit
|
||||
ld r3,STK_REG(R31)(r1)
|
||||
addi r1,r1,STACKFRAMESIZE
|
||||
|
||||
@@ -288,7 +288,6 @@ int dlpar_detach_node(struct device_node *dn)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
of_node_put(dn); /* Must decrement the refcount */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,4 +96,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
@@ -426,6 +426,20 @@ static void *nt_vmcoreinfo(void *ptr)
|
||||
return nt_init_name(ptr, 0, vmcoreinfo, size, "VMCOREINFO");
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize final note (needed for /proc/vmcore code)
|
||||
*/
|
||||
static void *nt_final(void *ptr)
|
||||
{
|
||||
Elf64_Nhdr *note;
|
||||
|
||||
note = (Elf64_Nhdr *) ptr;
|
||||
note->n_namesz = 0;
|
||||
note->n_descsz = 0;
|
||||
note->n_type = 0;
|
||||
return PTR_ADD(ptr, sizeof(Elf64_Nhdr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize ELF header (new kernel)
|
||||
*/
|
||||
@@ -513,6 +527,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
|
||||
if (sa->prefix != 0)
|
||||
ptr = fill_cpu_elf_notes(ptr, cpu++, sa);
|
||||
ptr = nt_vmcoreinfo(ptr);
|
||||
ptr = nt_final(ptr);
|
||||
memset(phdr, 0, sizeof(*phdr));
|
||||
phdr->p_type = PT_NOTE;
|
||||
phdr->p_offset = notes_offset;
|
||||
|
||||
@@ -321,6 +321,7 @@ ENTRY(system_call)
|
||||
lg %r14,__LC_VDSO_PER_CPU
|
||||
lmg %r0,%r10,__PT_R0(%r11)
|
||||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
|
||||
.Lsysc_exit_timer:
|
||||
stpt __LC_EXIT_TIMER
|
||||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||
lmg %r11,%r15,__PT_R11(%r11)
|
||||
@@ -606,6 +607,7 @@ ENTRY(io_int_handler)
|
||||
lg %r14,__LC_VDSO_PER_CPU
|
||||
lmg %r0,%r10,__PT_R0(%r11)
|
||||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
|
||||
.Lio_exit_timer:
|
||||
stpt __LC_EXIT_TIMER
|
||||
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
|
||||
lmg %r11,%r15,__PT_R11(%r11)
|
||||
@@ -1135,15 +1137,23 @@ cleanup_critical:
|
||||
br %r14
|
||||
|
||||
.Lcleanup_sysc_restore:
|
||||
# check if stpt has been executed
|
||||
clg %r9,BASED(.Lcleanup_sysc_restore_insn)
|
||||
jh 0f
|
||||
mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
|
||||
cghi %r11,__LC_SAVE_AREA_ASYNC
|
||||
je 0f
|
||||
mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
|
||||
0: clg %r9,BASED(.Lcleanup_sysc_restore_insn+8)
|
||||
je 1f
|
||||
lg %r9,24(%r11) # get saved pointer to pt_regs
|
||||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
|
||||
mvc 0(64,%r11),__PT_R8(%r9)
|
||||
lmg %r0,%r7,__PT_R0(%r9)
|
||||
0: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
1: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
br %r14
|
||||
.Lcleanup_sysc_restore_insn:
|
||||
.quad .Lsysc_exit_timer
|
||||
.quad .Lsysc_done - 4
|
||||
|
||||
.Lcleanup_io_tif:
|
||||
@@ -1151,15 +1161,20 @@ cleanup_critical:
|
||||
br %r14
|
||||
|
||||
.Lcleanup_io_restore:
|
||||
# check if stpt has been executed
|
||||
clg %r9,BASED(.Lcleanup_io_restore_insn)
|
||||
je 0f
|
||||
jh 0f
|
||||
mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
|
||||
0: clg %r9,BASED(.Lcleanup_io_restore_insn+8)
|
||||
je 1f
|
||||
lg %r9,24(%r11) # get saved r11 pointer to pt_regs
|
||||
mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
|
||||
mvc 0(64,%r11),__PT_R8(%r9)
|
||||
lmg %r0,%r7,__PT_R0(%r9)
|
||||
0: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
1: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
br %r14
|
||||
.Lcleanup_io_restore_insn:
|
||||
.quad .Lio_exit_timer
|
||||
.quad .Lio_done - 4
|
||||
|
||||
.Lcleanup_idle:
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
|
||||
#define SO_CNX_ADVICE 0x0037
|
||||
|
||||
#define SO_COOKIE 0x003b
|
||||
|
||||
/* Security levels - as per NRL IPv6 - don't actually do anything */
|
||||
#define SO_SECURITY_AUTHENTICATION 0x5001
|
||||
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
|
||||
|
||||
@@ -935,3 +935,9 @@ ENTRY(__retl_o1)
|
||||
retl
|
||||
mov %o1, %o0
|
||||
ENDPROC(__retl_o1)
|
||||
|
||||
ENTRY(__retl_o1_asi)
|
||||
wr %o5, 0x0, %asi
|
||||
retl
|
||||
mov %o1, %o0
|
||||
ENDPROC(__retl_o1_asi)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
98: x,y; \
|
||||
.section __ex_table,"a";\
|
||||
.align 4; \
|
||||
.word 98b, __retl_o1; \
|
||||
.word 98b, __retl_o1_asi;\
|
||||
.text; \
|
||||
.align 4;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
98: x,y; \
|
||||
.section __ex_table,"a";\
|
||||
.align 4; \
|
||||
.word 98b, __retl_o1; \
|
||||
.word 98b, __retl_o1_asi;\
|
||||
.text; \
|
||||
.align 4;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
static char *initrd __initdata = NULL;
|
||||
static int load_initrd(char *filename, void *buf, int size);
|
||||
|
||||
static int __init read_initrd(void)
|
||||
int __init read_initrd(void)
|
||||
{
|
||||
void *area;
|
||||
long long size;
|
||||
@@ -46,8 +46,6 @@ static int __init read_initrd(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
__uml_postsetup(read_initrd);
|
||||
|
||||
static int __init uml_initrd_setup(char *line, int *add)
|
||||
{
|
||||
initrd = line;
|
||||
|
||||
@@ -336,11 +336,17 @@ int __init linux_main(int argc, char **argv)
|
||||
return start_uml();
|
||||
}
|
||||
|
||||
int __init __weak read_initrd(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init setup_arch(char **cmdline_p)
|
||||
{
|
||||
stack_protections((unsigned long) &init_thread_info);
|
||||
setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
|
||||
mem_total_pages(physmem_size, iomem_size, highmem);
|
||||
read_initrd();
|
||||
|
||||
paging_init();
|
||||
strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#ifndef BOOT_BOOT_H
|
||||
#define BOOT_BOOT_H
|
||||
|
||||
#define STACK_SIZE 512 /* Minimum number of bytes for stack */
|
||||
#define STACK_SIZE 1024 /* Minimum number of bytes for stack */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
||||
@@ -106,18 +106,24 @@ static struct attribute_group pt_cap_group = {
|
||||
};
|
||||
|
||||
PMU_FORMAT_ATTR(cyc, "config:1" );
|
||||
PMU_FORMAT_ATTR(pwr_evt, "config:4" );
|
||||
PMU_FORMAT_ATTR(fup_on_ptw, "config:5" );
|
||||
PMU_FORMAT_ATTR(mtc, "config:9" );
|
||||
PMU_FORMAT_ATTR(tsc, "config:10" );
|
||||
PMU_FORMAT_ATTR(noretcomp, "config:11" );
|
||||
PMU_FORMAT_ATTR(ptw, "config:12" );
|
||||
PMU_FORMAT_ATTR(mtc_period, "config:14-17" );
|
||||
PMU_FORMAT_ATTR(cyc_thresh, "config:19-22" );
|
||||
PMU_FORMAT_ATTR(psb_period, "config:24-27" );
|
||||
|
||||
static struct attribute *pt_formats_attr[] = {
|
||||
&format_attr_cyc.attr,
|
||||
&format_attr_pwr_evt.attr,
|
||||
&format_attr_fup_on_ptw.attr,
|
||||
&format_attr_mtc.attr,
|
||||
&format_attr_tsc.attr,
|
||||
&format_attr_noretcomp.attr,
|
||||
&format_attr_ptw.attr,
|
||||
&format_attr_mtc_period.attr,
|
||||
&format_attr_cyc_thresh.attr,
|
||||
&format_attr_psb_period.attr,
|
||||
|
||||
@@ -759,7 +759,7 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
|
||||
|
||||
X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_CORE, hsw_rapl_init),
|
||||
X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E, hsw_rapl_init),
|
||||
X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X, hsw_rapl_init),
|
||||
X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X, hsx_rapl_init),
|
||||
X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, hsw_rapl_init),
|
||||
|
||||
X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_rapl_init),
|
||||
|
||||
@@ -103,7 +103,7 @@ static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes,
|
||||
|
||||
if (bytes < 8) {
|
||||
if (!IS_ALIGNED(dest, 4) || (bytes != 4))
|
||||
arch_wb_cache_pmem(addr, 1);
|
||||
arch_wb_cache_pmem(addr, bytes);
|
||||
} else {
|
||||
if (!IS_ALIGNED(dest, 8)) {
|
||||
dest = ALIGN(dest, boot_cpu_data.x86_clflush_size);
|
||||
|
||||
@@ -315,10 +315,10 @@ do { \
|
||||
#define __get_user_asm_u64(x, ptr, retval, errret) \
|
||||
({ \
|
||||
__typeof__(ptr) __ptr = (ptr); \
|
||||
asm volatile(ASM_STAC "\n" \
|
||||
asm volatile("\n" \
|
||||
"1: movl %2,%%eax\n" \
|
||||
"2: movl %3,%%edx\n" \
|
||||
"3: " ASM_CLAC "\n" \
|
||||
"3:\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"4: mov %4,%0\n" \
|
||||
" xorl %%eax,%%eax\n" \
|
||||
@@ -327,7 +327,7 @@ do { \
|
||||
".previous\n" \
|
||||
_ASM_EXTABLE(1b, 4b) \
|
||||
_ASM_EXTABLE(2b, 4b) \
|
||||
: "=r" (retval), "=A"(x) \
|
||||
: "=r" (retval), "=&A"(x) \
|
||||
: "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1), \
|
||||
"i" (errret), "0" (retval)); \
|
||||
})
|
||||
|
||||
@@ -20,4 +20,15 @@ static inline int xen_irqs_disabled(struct pt_regs *regs)
|
||||
/* No need for a barrier -- XCHG is a barrier on x86. */
|
||||
#define xchg_xen_ulong(ptr, val) xchg((ptr), (val))
|
||||
|
||||
extern int xen_have_vector_callback;
|
||||
|
||||
/*
|
||||
* Events delivered via platform PCI interrupts are always
|
||||
* routed to vcpu 0 and hence cannot be rebound.
|
||||
*/
|
||||
static inline bool xen_support_evtchn_rebind(void)
|
||||
{
|
||||
return (!xen_hvm_domain() || xen_have_vector_callback);
|
||||
}
|
||||
|
||||
#endif /* _ASM_X86_XEN_EVENTS_H */
|
||||
|
||||
@@ -1876,6 +1876,7 @@ static struct irq_chip ioapic_chip __read_mostly = {
|
||||
.irq_ack = irq_chip_ack_parent,
|
||||
.irq_eoi = ioapic_ack_level,
|
||||
.irq_set_affinity = ioapic_set_affinity,
|
||||
.irq_retrigger = irq_chip_retrigger_hierarchy,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
@@ -1887,6 +1888,7 @@ static struct irq_chip ioapic_ir_chip __read_mostly = {
|
||||
.irq_ack = irq_chip_ack_parent,
|
||||
.irq_eoi = ioapic_ir_ack_level,
|
||||
.irq_set_affinity = ioapic_set_affinity,
|
||||
.irq_retrigger = irq_chip_retrigger_hierarchy,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
|
||||
* Boot time FPU feature detection code:
|
||||
*/
|
||||
unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
|
||||
EXPORT_SYMBOL_GPL(mxcsr_feature_mask);
|
||||
|
||||
static void __init fpu__init_system_mxcsr(void)
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
#endif
|
||||
|
||||
/* Ensure if the instruction can be boostable */
|
||||
extern int can_boost(kprobe_opcode_t *instruction);
|
||||
extern int can_boost(kprobe_opcode_t *instruction, void *addr);
|
||||
/* Recover instruction if given address is probed */
|
||||
extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf,
|
||||
unsigned long addr);
|
||||
|
||||
@@ -166,12 +166,12 @@ NOKPROBE_SYMBOL(skip_prefixes);
|
||||
* Returns non-zero if opcode is boostable.
|
||||
* RIP relative instructions are adjusted at copying time in 64 bits mode
|
||||
*/
|
||||
int can_boost(kprobe_opcode_t *opcodes)
|
||||
int can_boost(kprobe_opcode_t *opcodes, void *addr)
|
||||
{
|
||||
kprobe_opcode_t opcode;
|
||||
kprobe_opcode_t *orig_opcodes = opcodes;
|
||||
|
||||
if (search_exception_tables((unsigned long)opcodes))
|
||||
if (search_exception_tables((unsigned long)addr))
|
||||
return 0; /* Page fault may occur on this address. */
|
||||
|
||||
retry:
|
||||
@@ -416,7 +416,7 @@ static int arch_copy_kprobe(struct kprobe *p)
|
||||
* __copy_instruction can modify the displacement of the instruction,
|
||||
* but it doesn't affect boostable check.
|
||||
*/
|
||||
if (can_boost(p->ainsn.insn))
|
||||
if (can_boost(p->ainsn.insn, p->addr))
|
||||
p->ainsn.boostable = 0;
|
||||
else
|
||||
p->ainsn.boostable = -1;
|
||||
|
||||
@@ -178,7 +178,7 @@ static int copy_optimized_instructions(u8 *dest, u8 *src)
|
||||
|
||||
while (len < RELATIVEJUMP_SIZE) {
|
||||
ret = __copy_instruction(dest + len, src + len);
|
||||
if (!ret || !can_boost(dest + len))
|
||||
if (!ret || !can_boost(dest + len, src + len))
|
||||
return -EINVAL;
|
||||
len += ret;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
|
||||
|
||||
/* were we called with bad_dma_address? */
|
||||
badend = DMA_ERROR_CODE + (EMERGENCY_PAGES * PAGE_SIZE);
|
||||
if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) {
|
||||
if (unlikely(dma_addr < badend)) {
|
||||
WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
|
||||
"address 0x%Lx\n", dma_addr);
|
||||
return;
|
||||
|
||||
@@ -846,12 +846,6 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
|
||||
if (!best)
|
||||
best = check_cpuid_limit(vcpu, function, index);
|
||||
|
||||
/*
|
||||
* Perfmon not yet supported for L2 guest.
|
||||
*/
|
||||
if (is_guest_mode(vcpu) && function == 0xa)
|
||||
best = NULL;
|
||||
|
||||
if (best) {
|
||||
*eax = best->eax;
|
||||
*ebx = best->ebx;
|
||||
|
||||
@@ -8051,8 +8051,6 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
|
||||
case EXIT_REASON_TASK_SWITCH:
|
||||
return true;
|
||||
case EXIT_REASON_CPUID:
|
||||
if (kvm_register_read(vcpu, VCPU_REGS_RAX) == 0xa)
|
||||
return false;
|
||||
return true;
|
||||
case EXIT_REASON_HLT:
|
||||
return nested_cpu_has(vmcs12, CPU_BASED_HLT_EXITING);
|
||||
@@ -8137,6 +8135,9 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
|
||||
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES);
|
||||
case EXIT_REASON_PREEMPTION_TIMER:
|
||||
return false;
|
||||
case EXIT_REASON_PML_FULL:
|
||||
/* We don't expose PML support to L1. */
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@@ -10073,6 +10074,18 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
|
||||
|
||||
}
|
||||
|
||||
if (enable_pml) {
|
||||
/*
|
||||
* Conceptually we want to copy the PML address and index from
|
||||
* vmcs01 here, and then back to vmcs01 on nested vmexit. But,
|
||||
* since we always flush the log on each vmexit, this happens
|
||||
* to be equivalent to simply resetting the fields in vmcs02.
|
||||
*/
|
||||
ASSERT(vmx->pml_pg);
|
||||
vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
|
||||
vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
}
|
||||
|
||||
if (nested_cpu_has_ept(vmcs12)) {
|
||||
kvm_mmu_unload(vcpu);
|
||||
nested_ept_init_mmu_context(vcpu);
|
||||
|
||||
@@ -1735,6 +1735,7 @@ static u64 __get_kvmclock_ns(struct kvm *kvm)
|
||||
{
|
||||
struct kvm_arch *ka = &kvm->arch;
|
||||
struct pvclock_vcpu_time_info hv_clock;
|
||||
u64 ret;
|
||||
|
||||
spin_lock(&ka->pvclock_gtod_sync_lock);
|
||||
if (!ka->use_master_clock) {
|
||||
@@ -1746,10 +1747,17 @@ static u64 __get_kvmclock_ns(struct kvm *kvm)
|
||||
hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
|
||||
spin_unlock(&ka->pvclock_gtod_sync_lock);
|
||||
|
||||
/* both __this_cpu_read() and rdtsc() should be on the same cpu */
|
||||
get_cpu();
|
||||
|
||||
kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL,
|
||||
&hv_clock.tsc_shift,
|
||||
&hv_clock.tsc_to_system_mul);
|
||||
return __pvclock_read_cycles(&hv_clock, rdtsc());
|
||||
ret = __pvclock_read_cycles(&hv_clock, rdtsc());
|
||||
|
||||
put_cpu();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u64 get_kvmclock_ns(struct kvm *kvm)
|
||||
@@ -3051,6 +3059,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
|
||||
(events->exception.nr > 31 || events->exception.nr == NMI_VECTOR))
|
||||
return -EINVAL;
|
||||
|
||||
/* INITs are latched while in SMM */
|
||||
if (events->flags & KVM_VCPUEVENT_VALID_SMM &&
|
||||
(events->smi.smm || events->smi.pending) &&
|
||||
vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED)
|
||||
return -EINVAL;
|
||||
|
||||
process_nmi(vcpu);
|
||||
vcpu->arch.exception.pending = events->exception.injected;
|
||||
vcpu->arch.exception.nr = events->exception.nr;
|
||||
@@ -3225,11 +3239,14 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
|
||||
}
|
||||
}
|
||||
|
||||
#define XSAVE_MXCSR_OFFSET 24
|
||||
|
||||
static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
|
||||
struct kvm_xsave *guest_xsave)
|
||||
{
|
||||
u64 xstate_bv =
|
||||
*(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)];
|
||||
u32 mxcsr = *(u32 *)&guest_xsave->region[XSAVE_MXCSR_OFFSET / sizeof(u32)];
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_XSAVE)) {
|
||||
/*
|
||||
@@ -3237,11 +3254,13 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
|
||||
* CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility
|
||||
* with old userspace.
|
||||
*/
|
||||
if (xstate_bv & ~kvm_supported_xcr0())
|
||||
if (xstate_bv & ~kvm_supported_xcr0() ||
|
||||
mxcsr & ~mxcsr_feature_mask)
|
||||
return -EINVAL;
|
||||
load_xsave(vcpu, (u8 *)guest_xsave->region);
|
||||
} else {
|
||||
if (xstate_bv & ~XFEATURE_MASK_FPSSE)
|
||||
if (xstate_bv & ~XFEATURE_MASK_FPSSE ||
|
||||
mxcsr & ~mxcsr_feature_mask)
|
||||
return -EINVAL;
|
||||
memcpy(&vcpu->arch.guest_fpu.state.fxsave,
|
||||
guest_xsave->region, sizeof(struct fxregs_state));
|
||||
@@ -4744,16 +4763,20 @@ emul_write:
|
||||
|
||||
static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
|
||||
{
|
||||
/* TODO: String I/O for in kernel device */
|
||||
int r;
|
||||
int r = 0, i;
|
||||
|
||||
if (vcpu->arch.pio.in)
|
||||
r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port,
|
||||
vcpu->arch.pio.size, pd);
|
||||
else
|
||||
r = kvm_io_bus_write(vcpu, KVM_PIO_BUS,
|
||||
vcpu->arch.pio.port, vcpu->arch.pio.size,
|
||||
pd);
|
||||
for (i = 0; i < vcpu->arch.pio.count; i++) {
|
||||
if (vcpu->arch.pio.in)
|
||||
r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port,
|
||||
vcpu->arch.pio.size, pd);
|
||||
else
|
||||
r = kvm_io_bus_write(vcpu, KVM_PIO_BUS,
|
||||
vcpu->arch.pio.port, vcpu->arch.pio.size,
|
||||
pd);
|
||||
if (r)
|
||||
break;
|
||||
pd += vcpu->arch.pio.size;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -4791,6 +4814,8 @@ static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt,
|
||||
if (vcpu->arch.pio.count)
|
||||
goto data_avail;
|
||||
|
||||
memset(vcpu->arch.pio_data, 0, size * count);
|
||||
|
||||
ret = emulator_pio_in_out(vcpu, size, port, val, count, true);
|
||||
if (ret) {
|
||||
data_avail:
|
||||
@@ -7162,6 +7187,12 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
|
||||
mp_state->mp_state != KVM_MP_STATE_RUNNABLE)
|
||||
return -EINVAL;
|
||||
|
||||
/* INITs are latched while in SMM */
|
||||
if ((is_smm(vcpu) || vcpu->arch.smi_pending) &&
|
||||
(mp_state->mp_state == KVM_MP_STATE_SIPI_RECEIVED ||
|
||||
mp_state->mp_state == KVM_MP_STATE_INIT_RECEIVED))
|
||||
return -EINVAL;
|
||||
|
||||
if (mp_state->mp_state == KVM_MP_STATE_SIPI_RECEIVED) {
|
||||
vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED;
|
||||
set_bit(KVM_APIC_SIPI, &vcpu->arch.apic->pending_events);
|
||||
|
||||
@@ -447,7 +447,7 @@ void __init xen_msi_init(void)
|
||||
|
||||
int __init pci_xen_hvm_init(void)
|
||||
{
|
||||
if (!xen_feature(XENFEAT_hvm_pirqs))
|
||||
if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs))
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <asm/intel_scu_ipc.h>
|
||||
#include <asm/io_apic.h>
|
||||
|
||||
#define TANGIER_EXT_TIMER0_MSI 15
|
||||
#define TANGIER_EXT_TIMER0_MSI 12
|
||||
|
||||
static struct platform_device wdt_dev = {
|
||||
.name = "intel_mid_wdt",
|
||||
|
||||
@@ -125,7 +125,7 @@ int poke_user(struct task_struct *child, long addr, long data)
|
||||
else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
|
||||
(addr <= offsetof(struct user, u_debugreg[7]))) {
|
||||
addr -= offsetof(struct user, u_debugreg[0]);
|
||||
addr = addr >> 2;
|
||||
addr = addr >> 3;
|
||||
if ((addr == 4) || (addr == 5))
|
||||
return -EIO;
|
||||
child->thread.arch.debugregs[addr] = data;
|
||||
|
||||
@@ -137,6 +137,8 @@ struct shared_info xen_dummy_shared_info;
|
||||
void *xen_initial_gdt;
|
||||
|
||||
RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
|
||||
__read_mostly int xen_have_vector_callback;
|
||||
EXPORT_SYMBOL_GPL(xen_have_vector_callback);
|
||||
|
||||
static int xen_cpu_up_prepare(unsigned int cpu);
|
||||
static int xen_cpu_up_online(unsigned int cpu);
|
||||
@@ -1521,7 +1523,10 @@ static void __init xen_pvh_early_guest_init(void)
|
||||
if (!xen_feature(XENFEAT_auto_translated_physmap))
|
||||
return;
|
||||
|
||||
BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector));
|
||||
if (!xen_feature(XENFEAT_hvm_callback_vector))
|
||||
return;
|
||||
|
||||
xen_have_vector_callback = 1;
|
||||
|
||||
xen_pvh_early_cpu_init(0, false);
|
||||
xen_pvh_set_cr_flags(0);
|
||||
@@ -1860,7 +1865,9 @@ static int xen_cpu_up_prepare(unsigned int cpu)
|
||||
xen_vcpu_setup(cpu);
|
||||
}
|
||||
|
||||
if (xen_pv_domain() || xen_feature(XENFEAT_hvm_safe_pvclock))
|
||||
if (xen_pv_domain() ||
|
||||
(xen_have_vector_callback &&
|
||||
xen_feature(XENFEAT_hvm_safe_pvclock)))
|
||||
xen_setup_timer(cpu);
|
||||
|
||||
rc = xen_smp_intr_init(cpu);
|
||||
@@ -1876,7 +1883,9 @@ static int xen_cpu_dead(unsigned int cpu)
|
||||
{
|
||||
xen_smp_intr_free(cpu);
|
||||
|
||||
if (xen_pv_domain() || xen_feature(XENFEAT_hvm_safe_pvclock))
|
||||
if (xen_pv_domain() ||
|
||||
(xen_have_vector_callback &&
|
||||
xen_feature(XENFEAT_hvm_safe_pvclock)))
|
||||
xen_teardown_timer(cpu);
|
||||
|
||||
return 0;
|
||||
@@ -1915,8 +1924,8 @@ static void __init xen_hvm_guest_init(void)
|
||||
|
||||
xen_panic_handler_init();
|
||||
|
||||
BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector));
|
||||
|
||||
if (xen_feature(XENFEAT_hvm_callback_vector))
|
||||
xen_have_vector_callback = 1;
|
||||
xen_hvm_smp_init();
|
||||
WARN_ON(xen_cpuhp_setup());
|
||||
xen_unplug_emulated_devices();
|
||||
@@ -1954,7 +1963,7 @@ bool xen_hvm_need_lapic(void)
|
||||
return false;
|
||||
if (!xen_hvm_domain())
|
||||
return false;
|
||||
if (xen_feature(XENFEAT_hvm_pirqs))
|
||||
if (xen_feature(XENFEAT_hvm_pirqs) && xen_have_vector_callback)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2028,7 +2028,8 @@ static unsigned long __init xen_read_phys_ulong(phys_addr_t addr)
|
||||
|
||||
/*
|
||||
* Translate a virtual address to a physical one without relying on mapped
|
||||
* page tables.
|
||||
* page tables. Don't rely on big pages being aligned in (guest) physical
|
||||
* space!
|
||||
*/
|
||||
static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
|
||||
{
|
||||
@@ -2049,7 +2050,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
|
||||
sizeof(pud)));
|
||||
if (!pud_present(pud))
|
||||
return 0;
|
||||
pa = pud_pfn(pud) << PAGE_SHIFT;
|
||||
pa = pud_val(pud) & PTE_PFN_MASK;
|
||||
if (pud_large(pud))
|
||||
return pa + (vaddr & ~PUD_MASK);
|
||||
|
||||
@@ -2057,7 +2058,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
|
||||
sizeof(pmd)));
|
||||
if (!pmd_present(pmd))
|
||||
return 0;
|
||||
pa = pmd_pfn(pmd) << PAGE_SHIFT;
|
||||
pa = pmd_val(pmd) & PTE_PFN_MASK;
|
||||
if (pmd_large(pmd))
|
||||
return pa + (vaddr & ~PMD_MASK);
|
||||
|
||||
|
||||
@@ -765,6 +765,8 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus)
|
||||
|
||||
void __init xen_hvm_smp_init(void)
|
||||
{
|
||||
if (!xen_have_vector_callback)
|
||||
return;
|
||||
smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus;
|
||||
smp_ops.smp_send_reschedule = xen_smp_send_reschedule;
|
||||
smp_ops.cpu_die = xen_cpu_die;
|
||||
|
||||
@@ -432,6 +432,11 @@ static void xen_hvm_setup_cpu_clockevents(void)
|
||||
|
||||
void __init xen_hvm_init_time_ops(void)
|
||||
{
|
||||
/* vector callback is needed otherwise we cannot receive interrupts
|
||||
* on cpu > 0 and at this point we don't know how many cpus are
|
||||
* available */
|
||||
if (!xen_have_vector_callback)
|
||||
return;
|
||||
if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
|
||||
printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
|
||||
"disable pv timer\n");
|
||||
|
||||
@@ -101,4 +101,6 @@
|
||||
|
||||
#define SO_CNX_ADVICE 53
|
||||
|
||||
#define SO_COOKIE 57
|
||||
|
||||
#endif /* _XTENSA_SOCKET_H */
|
||||
|
||||
@@ -412,12 +412,13 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
|
||||
|
||||
bi->flags = BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE |
|
||||
template->flags;
|
||||
bi->interval_exp = ilog2(queue_logical_block_size(disk->queue));
|
||||
bi->interval_exp = template->interval_exp ? :
|
||||
ilog2(queue_logical_block_size(disk->queue));
|
||||
bi->profile = template->profile ? template->profile : &nop_profile;
|
||||
bi->tuple_size = template->tuple_size;
|
||||
bi->tag_size = template->tag_size;
|
||||
|
||||
blk_integrity_revalidate(disk);
|
||||
disk->queue->backing_dev_info.capabilities |= BDI_CAP_STABLE_WRITES;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_integrity_register);
|
||||
|
||||
@@ -430,26 +431,11 @@ EXPORT_SYMBOL(blk_integrity_register);
|
||||
*/
|
||||
void blk_integrity_unregister(struct gendisk *disk)
|
||||
{
|
||||
blk_integrity_revalidate(disk);
|
||||
disk->queue->backing_dev_info.capabilities &= ~BDI_CAP_STABLE_WRITES;
|
||||
memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity));
|
||||
}
|
||||
EXPORT_SYMBOL(blk_integrity_unregister);
|
||||
|
||||
void blk_integrity_revalidate(struct gendisk *disk)
|
||||
{
|
||||
struct blk_integrity *bi = &disk->queue->integrity;
|
||||
|
||||
if (!(disk->flags & GENHD_FL_UP))
|
||||
return;
|
||||
|
||||
if (bi->profile)
|
||||
disk->queue->backing_dev_info.capabilities |=
|
||||
BDI_CAP_STABLE_WRITES;
|
||||
else
|
||||
disk->queue->backing_dev_info.capabilities &=
|
||||
~BDI_CAP_STABLE_WRITES;
|
||||
}
|
||||
|
||||
void blk_integrity_add(struct gendisk *disk)
|
||||
{
|
||||
if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype,
|
||||
|
||||
@@ -447,7 +447,6 @@ rescan:
|
||||
|
||||
if (disk->fops->revalidate_disk)
|
||||
disk->fops->revalidate_disk(disk);
|
||||
blk_integrity_revalidate(disk);
|
||||
check_disk_size_change(disk, bdev);
|
||||
bdev->bd_invalidated = 0;
|
||||
if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
|
||||
|
||||
@@ -44,6 +44,11 @@ struct aead_async_req {
|
||||
char iv[];
|
||||
};
|
||||
|
||||
struct aead_tfm {
|
||||
struct crypto_aead *aead;
|
||||
bool has_key;
|
||||
};
|
||||
|
||||
struct aead_ctx {
|
||||
struct aead_sg_list tsgl;
|
||||
struct aead_async_rsgl first_rsgl;
|
||||
@@ -732,24 +737,146 @@ static struct proto_ops algif_aead_ops = {
|
||||
.poll = aead_poll,
|
||||
};
|
||||
|
||||
static int aead_check_key(struct socket *sock)
|
||||
{
|
||||
int err = 0;
|
||||
struct sock *psk;
|
||||
struct alg_sock *pask;
|
||||
struct aead_tfm *tfm;
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock_child;
|
||||
|
||||
psk = ask->parent;
|
||||
pask = alg_sk(ask->parent);
|
||||
tfm = pask->private;
|
||||
|
||||
err = -ENOKEY;
|
||||
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
||||
if (!tfm->has_key)
|
||||
goto unlock;
|
||||
|
||||
if (!pask->refcnt++)
|
||||
sock_hold(psk);
|
||||
|
||||
ask->refcnt = 1;
|
||||
sock_put(psk);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(psk);
|
||||
unlock_child:
|
||||
release_sock(sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aead_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = aead_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return aead_sendmsg(sock, msg, size);
|
||||
}
|
||||
|
||||
static ssize_t aead_sendpage_nokey(struct socket *sock, struct page *page,
|
||||
int offset, size_t size, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = aead_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return aead_sendpage(sock, page, offset, size, flags);
|
||||
}
|
||||
|
||||
static int aead_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = aead_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return aead_recvmsg(sock, msg, ignored, flags);
|
||||
}
|
||||
|
||||
static struct proto_ops algif_aead_ops_nokey = {
|
||||
.family = PF_ALG,
|
||||
|
||||
.connect = sock_no_connect,
|
||||
.socketpair = sock_no_socketpair,
|
||||
.getname = sock_no_getname,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = sock_no_shutdown,
|
||||
.getsockopt = sock_no_getsockopt,
|
||||
.mmap = sock_no_mmap,
|
||||
.bind = sock_no_bind,
|
||||
.accept = sock_no_accept,
|
||||
.setsockopt = sock_no_setsockopt,
|
||||
|
||||
.release = af_alg_release,
|
||||
.sendmsg = aead_sendmsg_nokey,
|
||||
.sendpage = aead_sendpage_nokey,
|
||||
.recvmsg = aead_recvmsg_nokey,
|
||||
.poll = aead_poll,
|
||||
};
|
||||
|
||||
static void *aead_bind(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
return crypto_alloc_aead(name, type, mask);
|
||||
struct aead_tfm *tfm;
|
||||
struct crypto_aead *aead;
|
||||
|
||||
tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
||||
if (!tfm)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
aead = crypto_alloc_aead(name, type, mask);
|
||||
if (IS_ERR(aead)) {
|
||||
kfree(tfm);
|
||||
return ERR_CAST(aead);
|
||||
}
|
||||
|
||||
tfm->aead = aead;
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
static void aead_release(void *private)
|
||||
{
|
||||
crypto_free_aead(private);
|
||||
struct aead_tfm *tfm = private;
|
||||
|
||||
crypto_free_aead(tfm->aead);
|
||||
kfree(tfm);
|
||||
}
|
||||
|
||||
static int aead_setauthsize(void *private, unsigned int authsize)
|
||||
{
|
||||
return crypto_aead_setauthsize(private, authsize);
|
||||
struct aead_tfm *tfm = private;
|
||||
|
||||
return crypto_aead_setauthsize(tfm->aead, authsize);
|
||||
}
|
||||
|
||||
static int aead_setkey(void *private, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return crypto_aead_setkey(private, key, keylen);
|
||||
struct aead_tfm *tfm = private;
|
||||
int err;
|
||||
|
||||
err = crypto_aead_setkey(tfm->aead, key, keylen);
|
||||
tfm->has_key = !err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void aead_sock_destruct(struct sock *sk)
|
||||
@@ -766,12 +893,14 @@ static void aead_sock_destruct(struct sock *sk)
|
||||
af_alg_release_parent(sk);
|
||||
}
|
||||
|
||||
static int aead_accept_parent(void *private, struct sock *sk)
|
||||
static int aead_accept_parent_nokey(void *private, struct sock *sk)
|
||||
{
|
||||
struct aead_ctx *ctx;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(private);
|
||||
unsigned int ivlen = crypto_aead_ivsize(private);
|
||||
struct aead_tfm *tfm = private;
|
||||
struct crypto_aead *aead = tfm->aead;
|
||||
unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(aead);
|
||||
unsigned int ivlen = crypto_aead_ivsize(aead);
|
||||
|
||||
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
||||
if (!ctx)
|
||||
@@ -798,7 +927,7 @@ static int aead_accept_parent(void *private, struct sock *sk)
|
||||
|
||||
ask->private = ctx;
|
||||
|
||||
aead_request_set_tfm(&ctx->aead_req, private);
|
||||
aead_request_set_tfm(&ctx->aead_req, aead);
|
||||
aead_request_set_callback(&ctx->aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
af_alg_complete, &ctx->completion);
|
||||
|
||||
@@ -807,13 +936,25 @@ static int aead_accept_parent(void *private, struct sock *sk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aead_accept_parent(void *private, struct sock *sk)
|
||||
{
|
||||
struct aead_tfm *tfm = private;
|
||||
|
||||
if (!tfm->has_key)
|
||||
return -ENOKEY;
|
||||
|
||||
return aead_accept_parent_nokey(private, sk);
|
||||
}
|
||||
|
||||
static const struct af_alg_type algif_type_aead = {
|
||||
.bind = aead_bind,
|
||||
.release = aead_release,
|
||||
.setkey = aead_setkey,
|
||||
.setauthsize = aead_setauthsize,
|
||||
.accept = aead_accept_parent,
|
||||
.accept_nokey = aead_accept_parent_nokey,
|
||||
.ops = &algif_aead_ops,
|
||||
.ops_nokey = &algif_aead_ops_nokey,
|
||||
.name = "aead",
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
||||
@@ -101,6 +101,7 @@ obj-$(CONFIG_USB_PHY) += usb/
|
||||
obj-$(CONFIG_USB) += usb/
|
||||
obj-$(CONFIG_PCI) += usb/
|
||||
obj-$(CONFIG_USB_GADGET) += usb/
|
||||
obj-$(CONFIG_OF) += usb/
|
||||
obj-$(CONFIG_SERIO) += input/serio/
|
||||
obj-$(CONFIG_GAMEPORT) += input/gameport/
|
||||
obj-$(CONFIG_INPUT) += input/
|
||||
|
||||
@@ -287,6 +287,9 @@ static int bcm_open(struct hci_uart *hu)
|
||||
|
||||
hu->priv = bcm;
|
||||
|
||||
if (!hu->tty->dev)
|
||||
goto out;
|
||||
|
||||
mutex_lock(&bcm_device_lock);
|
||||
list_for_each(p, &bcm_device_list) {
|
||||
struct bcm_device *dev = list_entry(p, struct bcm_device, list);
|
||||
@@ -307,7 +310,7 @@ static int bcm_open(struct hci_uart *hu)
|
||||
}
|
||||
|
||||
mutex_unlock(&bcm_device_lock);
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user