Commit 3aa6b46c authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'locking/urgent' into locking/core, to pick up fixes

Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 975db45e 8a5fd564
...@@ -182,6 +182,7 @@ ...@@ -182,6 +182,7 @@
#define CPTR_EL2_TCPAC (1 << 31) #define CPTR_EL2_TCPAC (1 << 31)
#define CPTR_EL2_TTA (1 << 20) #define CPTR_EL2_TTA (1 << 20)
#define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT) #define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT)
#define CPTR_EL2_DEFAULT 0x000033ff
/* Hyp Debug Configuration Register bits */ /* Hyp Debug Configuration Register bits */
#define MDCR_EL2_TDRA (1 << 11) #define MDCR_EL2_TDRA (1 << 11)
......
...@@ -127,10 +127,14 @@ static inline unsigned long *vcpu_spsr(const struct kvm_vcpu *vcpu) ...@@ -127,10 +127,14 @@ static inline unsigned long *vcpu_spsr(const struct kvm_vcpu *vcpu)
static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu) static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu)
{ {
u32 mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK; u32 mode;
if (vcpu_mode_is_32bit(vcpu)) if (vcpu_mode_is_32bit(vcpu)) {
mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
return mode > COMPAT_PSR_MODE_USR; return mode > COMPAT_PSR_MODE_USR;
}
mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK;
return mode != PSR_MODE_EL0t; return mode != PSR_MODE_EL0t;
} }
......
...@@ -36,7 +36,11 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu) ...@@ -36,7 +36,11 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
write_sysreg(val, hcr_el2); write_sysreg(val, hcr_el2);
/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */ /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
write_sysreg(1 << 15, hstr_el2); write_sysreg(1 << 15, hstr_el2);
write_sysreg(CPTR_EL2_TTA | CPTR_EL2_TFP, cptr_el2);
val = CPTR_EL2_DEFAULT;
val |= CPTR_EL2_TTA | CPTR_EL2_TFP;
write_sysreg(val, cptr_el2);
write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
} }
...@@ -45,7 +49,7 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu) ...@@ -45,7 +49,7 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
write_sysreg(HCR_RW, hcr_el2); write_sysreg(HCR_RW, hcr_el2);
write_sysreg(0, hstr_el2); write_sysreg(0, hstr_el2);
write_sysreg(read_sysreg(mdcr_el2) & MDCR_EL2_HPMN_MASK, mdcr_el2); write_sysreg(read_sysreg(mdcr_el2) & MDCR_EL2_HPMN_MASK, mdcr_el2);
write_sysreg(0, cptr_el2); write_sysreg(CPTR_EL2_DEFAULT, cptr_el2);
} }
static void __hyp_text __activate_vm(struct kvm_vcpu *vcpu) static void __hyp_text __activate_vm(struct kvm_vcpu *vcpu)
......
...@@ -27,7 +27,11 @@ ...@@ -27,7 +27,11 @@
#define PSTATE_FAULT_BITS_64 (PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | \ #define PSTATE_FAULT_BITS_64 (PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | \
PSR_I_BIT | PSR_D_BIT) PSR_I_BIT | PSR_D_BIT)
#define EL1_EXCEPT_SYNC_OFFSET 0x200
#define CURRENT_EL_SP_EL0_VECTOR 0x0
#define CURRENT_EL_SP_ELx_VECTOR 0x200
#define LOWER_EL_AArch64_VECTOR 0x400
#define LOWER_EL_AArch32_VECTOR 0x600
static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset) static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
{ {
...@@ -97,6 +101,34 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt, ...@@ -97,6 +101,34 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt,
*fsr = 0x14; *fsr = 0x14;
} }
enum exception_type {
except_type_sync = 0,
except_type_irq = 0x80,
except_type_fiq = 0x100,
except_type_serror = 0x180,
};
static u64 get_except_vector(struct kvm_vcpu *vcpu, enum exception_type type)
{
u64 exc_offset;
switch (*vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT)) {
case PSR_MODE_EL1t:
exc_offset = CURRENT_EL_SP_EL0_VECTOR;
break;
case PSR_MODE_EL1h:
exc_offset = CURRENT_EL_SP_ELx_VECTOR;
break;
case PSR_MODE_EL0t:
exc_offset = LOWER_EL_AArch64_VECTOR;
break;
default:
exc_offset = LOWER_EL_AArch32_VECTOR;
}
return vcpu_sys_reg(vcpu, VBAR_EL1) + exc_offset + type;
}
static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr) static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr)
{ {
unsigned long cpsr = *vcpu_cpsr(vcpu); unsigned long cpsr = *vcpu_cpsr(vcpu);
...@@ -108,8 +140,8 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr ...@@ -108,8 +140,8 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr
*vcpu_spsr(vcpu) = cpsr; *vcpu_spsr(vcpu) = cpsr;
*vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu);
*vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
*vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
*vcpu_pc(vcpu) = vcpu_sys_reg(vcpu, VBAR_EL1) + EL1_EXCEPT_SYNC_OFFSET;
vcpu_sys_reg(vcpu, FAR_EL1) = addr; vcpu_sys_reg(vcpu, FAR_EL1) = addr;
...@@ -143,8 +175,8 @@ static void inject_undef64(struct kvm_vcpu *vcpu) ...@@ -143,8 +175,8 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
*vcpu_spsr(vcpu) = cpsr; *vcpu_spsr(vcpu) = cpsr;
*vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu);
*vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
*vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
*vcpu_pc(vcpu) = vcpu_sys_reg(vcpu, VBAR_EL1) + EL1_EXCEPT_SYNC_OFFSET;
/* /*
* Build an unknown exception, depending on the instruction * Build an unknown exception, depending on the instruction
......
...@@ -1007,10 +1007,9 @@ static int emulate_cp(struct kvm_vcpu *vcpu, ...@@ -1007,10 +1007,9 @@ static int emulate_cp(struct kvm_vcpu *vcpu,
if (likely(r->access(vcpu, params, r))) { if (likely(r->access(vcpu, params, r))) {
/* Skip instruction, since it was emulated */ /* Skip instruction, since it was emulated */
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
/* Handled */
return 0;
} }
/* Handled */
return 0;
} }
/* Not handled */ /* Not handled */
...@@ -1043,7 +1042,7 @@ static void unhandled_cp_access(struct kvm_vcpu *vcpu, ...@@ -1043,7 +1042,7 @@ static void unhandled_cp_access(struct kvm_vcpu *vcpu,
} }
/** /**
* kvm_handle_cp_64 -- handles a mrrc/mcrr trap on a guest CP15 access * kvm_handle_cp_64 -- handles a mrrc/mcrr trap on a guest CP14/CP15 access
* @vcpu: The VCPU pointer * @vcpu: The VCPU pointer
* @run: The kvm_run struct * @run: The kvm_run struct
*/ */
...@@ -1095,7 +1094,7 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, ...@@ -1095,7 +1094,7 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
} }
/** /**
* kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access * kvm_handle_cp_32 -- handles a mrc/mcr trap on a guest CP14/CP15 access
* @vcpu: The VCPU pointer * @vcpu: The VCPU pointer
* @run: The kvm_run struct * @run: The kvm_run struct
*/ */
......
...@@ -74,6 +74,7 @@ uart0: serial@10000100 { ...@@ -74,6 +74,7 @@ uart0: serial@10000100 {
timer: timer@10000040 { timer: timer@10000040 {
compatible = "syscon"; compatible = "syscon";
reg = <0x10000040 0x2c>; reg = <0x10000040 0x2c>;
little-endian;
}; };
reboot { reboot {
......
...@@ -98,6 +98,7 @@ upg_irq0_intc: upg_irq0_intc@406780 { ...@@ -98,6 +98,7 @@ upg_irq0_intc: upg_irq0_intc@406780 {
sun_top_ctrl: syscon@404000 { sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7125-sun-top-ctrl", "syscon"; compatible = "brcm,bcm7125-sun-top-ctrl", "syscon";
reg = <0x404000 0x60c>; reg = <0x404000 0x60c>;
little-endian;
}; };
reboot { reboot {
......
...@@ -118,6 +118,7 @@ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { ...@@ -118,6 +118,7 @@ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
sun_top_ctrl: syscon@404000 { sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7346-sun-top-ctrl", "syscon"; compatible = "brcm,bcm7346-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>; reg = <0x404000 0x51c>;
little-endian;
}; };
reboot { reboot {
......
...@@ -112,6 +112,7 @@ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { ...@@ -112,6 +112,7 @@ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
sun_top_ctrl: syscon@404000 { sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7358-sun-top-ctrl", "syscon"; compatible = "brcm,bcm7358-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>; reg = <0x404000 0x51c>;
little-endian;
}; };
reboot { reboot {
......
...@@ -112,6 +112,7 @@ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { ...@@ -112,6 +112,7 @@ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
sun_top_ctrl: syscon@404000 { sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7360-sun-top-ctrl", "syscon"; compatible = "brcm,bcm7360-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>; reg = <0x404000 0x51c>;
little-endian;
}; };
reboot { reboot {
......
...@@ -118,6 +118,7 @@ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { ...@@ -118,6 +118,7 @@ upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 {
sun_top_ctrl: syscon@404000 { sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7362-sun-top-ctrl", "syscon"; compatible = "brcm,bcm7362-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>; reg = <0x404000 0x51c>;
little-endian;
}; };
reboot { reboot {
......
...@@ -99,6 +99,7 @@ upg_irq0_intc: upg_irq0_intc@406780 { ...@@ -99,6 +99,7 @@ upg_irq0_intc: upg_irq0_intc@406780 {
sun_top_ctrl: syscon@404000 { sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7420-sun-top-ctrl", "syscon"; compatible = "brcm,bcm7420-sun-top-ctrl", "syscon";
reg = <0x404000 0x60c>; reg = <0x404000 0x60c>;
little-endian;
}; };
reboot { reboot {
......
...@@ -100,6 +100,7 @@ upg_irq0_intc: upg_irq0_intc@406780 { ...@@ -100,6 +100,7 @@ upg_irq0_intc: upg_irq0_intc@406780 {
sun_top_ctrl: syscon@404000 { sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon"; compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>; reg = <0x404000 0x51c>;
little-endian;
}; };
reboot { reboot {
......
...@@ -114,6 +114,7 @@ upg_irq0_intc: upg_irq0_intc@406780 { ...@@ -114,6 +114,7 @@ upg_irq0_intc: upg_irq0_intc@406780 {
sun_top_ctrl: syscon@404000 { sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon"; compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>; reg = <0x404000 0x51c>;
little-endian;
}; };
reboot { reboot {
......
...@@ -133,17 +133,17 @@ static int regmap_mmio_gather_write(void *context, ...@@ -133,17 +133,17 @@ static int regmap_mmio_gather_write(void *context,
while (val_size) { while (val_size) {
switch (ctx->val_bytes) { switch (ctx->val_bytes) {
case 1: case 1:
__raw_writeb(*(u8 *)val, ctx->regs + offset); writeb(*(u8 *)val, ctx->regs + offset);
break; break;
case 2: case 2:
__raw_writew(*(u16 *)val, ctx->regs + offset); writew(*(u16 *)val, ctx->regs + offset);
break; break;
case 4: case 4:
__raw_writel(*(u32 *)val, ctx->regs + offset); writel(*(u32 *)val, ctx->regs + offset);
break; break;
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
case 8: case 8:
__raw_writeq(*(u64 *)val, ctx->regs + offset); writeq(*(u64 *)val, ctx->regs + offset);
break; break;
#endif #endif
default: default:
...@@ -193,17 +193,17 @@ static int regmap_mmio_read(void *context, ...@@ -193,17 +193,17 @@ static int regmap_mmio_read(void *context,
while (val_size) { while (val_size) {
switch (ctx->val_bytes) { switch (ctx->val_bytes) {
case 1: case 1:
*(u8 *)val = __raw_readb(ctx->regs + offset); *(u8 *)val = readb(ctx->regs + offset);
break; break;
case 2: case 2:
*(u16 *)val = __raw_readw(ctx->regs + offset); *(u16 *)val = readw(ctx->regs + offset);
break; break;
case 4: case 4:
*(u32 *)val = __raw_readl(ctx->regs + offset); *(u32 *)val = readl(ctx->regs + offset);
break; break;
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
case 8: case 8:
*(u64 *)val = __raw_readq(ctx->regs + offset); *(u64 *)val = readq(ctx->regs + offset);
break; break;
#endif #endif
default: default:
......
...@@ -1822,7 +1822,7 @@ check_deadlock(struct task_struct *curr, struct held_lock *next, ...@@ -1822,7 +1822,7 @@ check_deadlock(struct task_struct *curr, struct held_lock *next,
*/ */
static int static int
check_prev_add(struct task_struct *curr, struct held_lock *prev, check_prev_add(struct task_struct *curr, struct held_lock *prev,
struct held_lock *next, int distance, int trylock_loop) struct held_lock *next, int distance, int *stack_saved)
{ {
struct lock_list *entry; struct lock_list *entry;
int ret; int ret;
...@@ -1883,8 +1883,11 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev, ...@@ -1883,8 +1883,11 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
} }
} }
if (!trylock_loop && !save_trace(&trace)) if (!*stack_saved) {
return 0; if (!save_trace(&trace))
return 0;
*stack_saved = 1;
}
/* /*
* Ok, all validations passed, add the new lock * Ok, all validations passed, add the new lock
...@@ -1907,6 +1910,8 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev, ...@@ -1907,6 +1910,8 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
* Debugging printouts: * Debugging printouts:
*/ */
if (verbose(hlock_class(prev)) || verbose(hlock_class(next))) { if (verbose(hlock_class(prev)) || verbose(hlock_class(next))) {
/* We drop graph lock, so another thread can overwrite trace. */
*stack_saved = 0;
graph_unlock(); graph_unlock();
printk("\n new dependency: "); printk("\n new dependency: ");
print_lock_name(hlock_class(prev)); print_lock_name(hlock_class(prev));
...@@ -1929,7 +1934,7 @@ static int ...@@ -1929,7 +1934,7 @@ static int
check_prevs_add(struct task_struct *curr, struct held_lock *next) check_prevs_add(struct task_struct *curr, struct held_lock *next)
{ {
int depth = curr->lockdep_depth; int depth = curr->lockdep_depth;
int trylock_loop = 0; int stack_saved = 0;
struct held_lock *hlock; struct held_lock *hlock;
/* /*
...@@ -1956,7 +1961,7 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next) ...@@ -1956,7 +1961,7 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
*/ */
if (hlock->read != 2 && hlock->check) { if (hlock->read != 2 && hlock->check) {
if (!check_prev_add(curr, hlock, next, if (!check_prev_add(curr, hlock, next,
distance, trylock_loop)) distance, &stack_saved))
return 0; return 0;
/* /*
* Stop after the first non-trylock entry, * Stop after the first non-trylock entry,
...@@ -1979,7 +1984,6 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next) ...@@ -1979,7 +1984,6 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
if (curr->held_locks[depth].irq_context != if (curr->held_locks[depth].irq_context !=
curr->held_locks[depth-1].irq_context) curr->held_locks[depth-1].irq_context)
break; break;
trylock_loop = 1;
} }
return 1; return 1;
out_bug: out_bug:
......
...@@ -598,9 +598,9 @@ EXPORT_SYMBOL(sg_miter_next); ...@@ -598,9 +598,9 @@ EXPORT_SYMBOL(sg_miter_next);
* *
* Description: * Description:
* Stops mapping iterator @miter. @miter should have been started * Stops mapping iterator @miter. @miter should have been started
* started using sg_miter_start(). A stopped iteration can be * using sg_miter_start(). A stopped iteration can be resumed by
* resumed by calling sg_miter_next() on it. This is useful when * calling sg_miter_next() on it. This is useful when resources (kmap)
* resources (kmap) need to be released during iteration. * need to be released during iteration.
* *
* Context: * Context:
* Preemption disabled if the SG_MITER_ATOMIC is set. Don't care * Preemption disabled if the SG_MITER_ATOMIC is set. Don't care
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment