KVM/arm64 fixes for 5.16, take #1 - Fix the host S2 finalization by solely iterating over the memblocks instead of the whole IPA space - Tighten the return value of kvm_vcpu_preferred_target() now that 32bit support is long gone - Make sure the extraction of ESR_ELx.EC is limited to the architected bits - Comment fixups
Unified · Split
| @@ -68,6 +68,7 @@ · 67 unmodified lines | ||
| 68 | 68 | #define ESR_ELx_EC_MAX (0x3F) |
| 69 | 69 | |
| 70 | 70 | #define ESR_ELx_EC_SHIFT (26) |
| 71 | +#define ESR_ELx_EC_WIDTH (6) | |
| 71 | 72 | #define ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT) |
| 72 | 73 | #define ESR_ELx_EC(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT) |
| 73 | 74 | |
| @@ -584,7 +584,7 @@ struct kvm_vcpu_stat { · 583 unmodified lines | ||
| 584 | 584 | u64 exits; |
| 585 | 585 | }; |
| 586 | 586 | |
| 587 | −int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init); | |
| 587 | +void kvm_vcpu_preferred_target(struct kvm_vcpu_init *init); | |
| 588 | 588 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); |
| 589 | 589 | int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); |
| 590 | 590 | int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); |
| @@ -1389,12 +1389,9 @@ long kvm_arch_vm_ioctl(struct file *filp, · 1388 unmodified lines | ||
| 1389 | 1389 | return kvm_vm_ioctl_set_device_addr(kvm, &dev_addr); |
| 1390 | 1390 | } |
| 1391 | 1391 | case KVM_ARM_PREFERRED_TARGET: { |
| 1392 | − int err; | |
| 1393 | 1392 | struct kvm_vcpu_init init; |
| 1394 | 1393 | |
| 1395 | − err = kvm_vcpu_preferred_target(&init); | |
| 1396 | − if (err) | |
| 1397 | − return err; | |
| 1394 | + kvm_vcpu_preferred_target(&init); | |
| 1398 | 1395 | |
| 1399 | 1396 | if (copy_to_user(argp, &init, sizeof(init))) |
| 1400 | 1397 | return -EFAULT; |
| @@ -869,13 +869,10 @@ u32 __attribute_const__ kvm_target_cpu(void) · 868 unmodified lines | ||
| 869 | 869 | return KVM_ARM_TARGET_GENERIC_V8; |
| 870 | 870 | } |
| 871 | 871 | |
| 872 | −int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) | |
| 872 | +void kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) | |
| 873 | 873 | { |
| 874 | 874 | u32 target = kvm_target_cpu(); |
| 875 | 875 | |
| 876 | − if (target < 0) | |
| 877 | − return -ENODEV; | |
| 878 | − | |
| 879 | 876 | memset(init, 0, sizeof(*init)); |
| 880 | 877 | |
| 881 | 878 | /* |
| @@ -885,8 +882,6 @@ int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init) · 3 unmodified lines | ||
| 885 | 882 | * target type. |
| 886 | 883 | */ |
| 887 | 884 | init->target = (__u32)target; |
| 888 | − | |
| 889 | − return 0; | |
| 890 | 885 | } |
| 891 | 886 | |
| 892 | 887 | int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) |
| @@ -44,7 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | el1_sync: // Guest trapped into EL2 |
| 45 | 45 | |
| 46 | 46 | mrs x0, esr_el2 |
| 47 | − lsr x0, x0, #ESR_ELx_EC_SHIFT | |
| 47 | + ubfx x0, x0, #ESR_ELx_EC_SHIFT, #ESR_ELx_EC_WIDTH | |
| 48 | 48 | cmp x0, #ESR_ELx_EC_HVC64 |
| 49 | 49 | ccmp x0, #ESR_ELx_EC_HVC32, #4, ne |
| 50 | 50 | b.ne el1_trap |
| @@ -141,7 +141,7 @@ SYM_FUNC_END(__host_hvc) · 140 unmodified lines | ||
| 141 | 141 | .L__vect_start\@: |
| 142 | 142 | stp x0, x1, [sp, #-16]! |
| 143 | 143 | mrs x0, esr_el2 |
| 144 | − lsr x0, x0, #ESR_ELx_EC_SHIFT | |
| 144 | + ubfx x0, x0, #ESR_ELx_EC_SHIFT, #ESR_ELx_EC_WIDTH | |
| 145 | 145 | cmp x0, #ESR_ELx_EC_HVC64 |
| 146 | 146 | b.eq __host_hvc |
| 147 | 147 | b __host_exit |
| @@ -178,7 +178,7 @@ static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level, · 177 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | phys = kvm_pte_to_phys(pte); |
| 180 | 180 | if (!addr_is_memory(phys)) |
| 181 | − return 0; | |
| 181 | + return -EINVAL; | |
| 182 | 182 | |
| 183 | 183 | /* |
| 184 | 184 | * Adjust the host stage-2 mappings to match the ownership attributes |
| @@ -207,8 +207,18 @@ static int finalize_host_mappings(void) · 22 unmodified lines | ||
| 207 | 207 | .cb = finalize_host_mappings_walker, |
| 208 | 208 | .flags = KVM_PGTABLE_WALK_LEAF, |
| 209 | 209 | }; |
| 210 | + int i, ret; | |
| 211 | + | |
| 212 | + for (i = 0; i < hyp_memblock_nr; i++) { | |
| 213 | + struct memblock_region *reg = &hyp_memory[i]; | |
| 214 | + u64 start = (u64)hyp_phys_to_virt(reg->base); | |
| 215 | + | |
| 216 | + ret = kvm_pgtable_walk(&pkvm_pgtable, start, reg->size, &walker); | |
| 217 | + if (ret) | |
| 218 | + return ret; | |
| 219 | + } | |
| 210 | 220 | |
| 211 | − return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker); | |
| 221 | + return 0; | |
| 212 | 222 | } |
| 213 | 223 | |
| 214 | 224 | void __noreturn __pkvm_init_finalise(void) |
| @@ -474,7 +474,7 @@ bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code) · 473 unmodified lines | ||
| 474 | 474 | return true; |
| 475 | 475 | } |
| 476 | 476 | |
| 477 | −/** | |
| 477 | +/* | |
| 478 | 478 | * Handler for protected VM restricted exceptions. |
| 479 | 479 | * |
| 480 | 480 | * Inject an undefined exception into the guest and return true to indicate that |