KVM/ARM Fixes for Linux v4.6-rc2.
Fixes a bug that corrupts stage-2 translationson 16-bit VMID equipped systems and fixes CPU PM and Hotplug after the EL2 init code has been moved to C. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJW/jk7AAoJEEtpOizt6ddyL1EH/RcWeOllk64dLpFouig8F+Oe Lm7b6okB8qJjZdpyStqWYGEWjd2kwZ5buUqmCf8kNPrQ143c3xwKAeb3hBly+6vK RDbef6nZqqPihbYTohFzquQKOY8haselciYwmW6+Lkq8uaZ6jNSTbDKwjtDI8rry +1FuSZKrUVz5xaj5qn4gDJjTmnZbX5rcdtwN3S9/AikPDtNZFZHcj8Qn/ps9jjLP jB2XCIRXFZdxxYOAlYbRx+sTVEnsTBYAwCrvFErJAfBH8m0QR94mn1epU7QzdrKN dnKbG4IYy19aPmOpfhGuQrUZ1G09QNSWQQ+BhG0pvq0/GBD0exkMdRssp11AXoI= =XE1Y -----END PGP SIGNATURE----- Merge tag 'kvm-arm-for-4.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD KVM/ARM Fixes for Linux v4.6-rc2. Fixes a bug that corrupts stage-2 translationson 16-bit VMID equipped systems and fixes CPU PM and Hotplug after the EL2 init code has been moved to C.
This commit is contained in:
commit
c26e5f303a
|
@ -1061,15 +1061,27 @@ static void cpu_init_hyp_mode(void *dummy)
|
||||||
kvm_arm_init_debug();
|
kvm_arm_init_debug();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cpu_hyp_reinit(void)
|
||||||
|
{
|
||||||
|
if (is_kernel_in_hyp_mode()) {
|
||||||
|
/*
|
||||||
|
* cpu_init_stage2() is safe to call even if the PM
|
||||||
|
* event was cancelled before the CPU was reset.
|
||||||
|
*/
|
||||||
|
cpu_init_stage2(NULL);
|
||||||
|
} else {
|
||||||
|
if (__hyp_get_vectors() == hyp_default_vectors)
|
||||||
|
cpu_init_hyp_mode(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int hyp_init_cpu_notify(struct notifier_block *self,
|
static int hyp_init_cpu_notify(struct notifier_block *self,
|
||||||
unsigned long action, void *cpu)
|
unsigned long action, void *cpu)
|
||||||
{
|
{
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case CPU_STARTING:
|
case CPU_STARTING:
|
||||||
case CPU_STARTING_FROZEN:
|
case CPU_STARTING_FROZEN:
|
||||||
if (__hyp_get_vectors() == hyp_default_vectors)
|
cpu_hyp_reinit();
|
||||||
cpu_init_hyp_mode(NULL);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
|
@ -1084,9 +1096,8 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
|
||||||
unsigned long cmd,
|
unsigned long cmd,
|
||||||
void *v)
|
void *v)
|
||||||
{
|
{
|
||||||
if (cmd == CPU_PM_EXIT &&
|
if (cmd == CPU_PM_EXIT) {
|
||||||
__hyp_get_vectors() == hyp_default_vectors) {
|
cpu_hyp_reinit();
|
||||||
cpu_init_hyp_mode(NULL);
|
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1127,6 +1138,22 @@ static int init_subsystems(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register CPU Hotplug notifier
|
||||||
|
*/
|
||||||
|
cpu_notifier_register_begin();
|
||||||
|
err = __register_cpu_notifier(&hyp_init_cpu_nb);
|
||||||
|
cpu_notifier_register_done();
|
||||||
|
if (err) {
|
||||||
|
kvm_err("Cannot register KVM init CPU notifier (%d)\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register CPU lower-power notifier
|
||||||
|
*/
|
||||||
|
hyp_cpu_pm_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init HYP view of VGIC
|
* Init HYP view of VGIC
|
||||||
*/
|
*/
|
||||||
|
@ -1270,19 +1297,6 @@ static int init_hyp_mode(void)
|
||||||
free_boot_hyp_pgd();
|
free_boot_hyp_pgd();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpu_notifier_register_begin();
|
|
||||||
|
|
||||||
err = __register_cpu_notifier(&hyp_init_cpu_nb);
|
|
||||||
|
|
||||||
cpu_notifier_register_done();
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
kvm_err("Cannot register HYP init CPU notifier (%d)\n", err);
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
hyp_cpu_pm_init();
|
|
||||||
|
|
||||||
/* set size of VMID supported by CPU */
|
/* set size of VMID supported by CPU */
|
||||||
kvm_vmid_bits = kvm_get_vmid_bits();
|
kvm_vmid_bits = kvm_get_vmid_bits();
|
||||||
kvm_info("%d-bit VMID\n", kvm_vmid_bits);
|
kvm_info("%d-bit VMID\n", kvm_vmid_bits);
|
||||||
|
|
|
@ -124,7 +124,9 @@
|
||||||
#define VTCR_EL2_SL0_LVL1 (1 << 6)
|
#define VTCR_EL2_SL0_LVL1 (1 << 6)
|
||||||
#define VTCR_EL2_T0SZ_MASK 0x3f
|
#define VTCR_EL2_T0SZ_MASK 0x3f
|
||||||
#define VTCR_EL2_T0SZ_40B 24
|
#define VTCR_EL2_T0SZ_40B 24
|
||||||
#define VTCR_EL2_VS 19
|
#define VTCR_EL2_VS_SHIFT 19
|
||||||
|
#define VTCR_EL2_VS_8BIT (0 << VTCR_EL2_VS_SHIFT)
|
||||||
|
#define VTCR_EL2_VS_16BIT (1 << VTCR_EL2_VS_SHIFT)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We configure the Stage-2 page tables to always restrict the IPA space to be
|
* We configure the Stage-2 page tables to always restrict the IPA space to be
|
||||||
|
|
|
@ -141,6 +141,9 @@
|
||||||
#define ID_AA64MMFR1_VMIDBITS_SHIFT 4
|
#define ID_AA64MMFR1_VMIDBITS_SHIFT 4
|
||||||
#define ID_AA64MMFR1_HADBS_SHIFT 0
|
#define ID_AA64MMFR1_HADBS_SHIFT 0
|
||||||
|
|
||||||
|
#define ID_AA64MMFR1_VMIDBITS_8 0
|
||||||
|
#define ID_AA64MMFR1_VMIDBITS_16 2
|
||||||
|
|
||||||
/* id_aa64mmfr2 */
|
/* id_aa64mmfr2 */
|
||||||
#define ID_AA64MMFR2_UAO_SHIFT 4
|
#define ID_AA64MMFR2_UAO_SHIFT 4
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,10 @@ void __hyp_text __init_stage2_translation(void)
|
||||||
* Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS
|
* Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS
|
||||||
* bit in VTCR_EL2.
|
* bit in VTCR_EL2.
|
||||||
*/
|
*/
|
||||||
tmp = (read_sysreg(id_aa64mmfr1_el1) >> 4) & 0xf;
|
tmp = (read_sysreg(id_aa64mmfr1_el1) >> ID_AA64MMFR1_VMIDBITS_SHIFT) & 0xf;
|
||||||
val |= (tmp == 2) ? VTCR_EL2_VS : 0;
|
val |= (tmp == ID_AA64MMFR1_VMIDBITS_16) ?
|
||||||
|
VTCR_EL2_VS_16BIT :
|
||||||
|
VTCR_EL2_VS_8BIT;
|
||||||
|
|
||||||
write_sysreg(val, vtcr_el2);
|
write_sysreg(val, vtcr_el2);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue