mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 23:52:08 +02:00
KVM/riscv fixes for 6.18, take #2
- Fix check for local interrupts on riscv32 - Read HGEIP CSR on the correct cpu when checking for IMSIC interrupts - Remove automatic I/O mapping from kvm_arch_prepare_memory_region() -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEZdn75s5e6LHDQ+f/rUjsVaLHLAcFAmj7oxkACgkQrUjsVaLH LAfbKw/+Jl2/qRE5i23MwtZkQHwJirPKBAmXuV7f3IX8W3txzjdN/1LlcCmgKoUI NxYo6ITMq+faTjVgECC5xbJXxptmdqkhqAfyQ9T9vfCiWePGpGB7wxQ/qYh+o7+d jktVk+hXUNQAQzhpv6Jzf0Uctl9HUE+65YEPGF7XN3tgNJ+/68SA15q/g4+FnEDi aIrLVdiBMsDDliW6z6FAcmCK70pgcqrdS5dKqAIoZ7koj/rLZ/e2ms5H/bKE7YoL cWSQX2HHBP6c/xk6WSFFOcpVVH0wHcRZvsuDNlM7iTrApJMNouOGZGVBzXvegNnR b0gjI0/qDsx/7ePmt5HHUNhweoC0R91vxB7s5u9GeSk9PXzLmr5VEajT9NM2xaBt eWJaStUtkM2O+ZfdVDJXPryApOOh7warFk7qreB4D/WGnUIYeKWAWR7FNItHbe0v MUGl9aAF0PSGCmb+GHR6adX0jjFYiUatrATOyBy+IKAcOQFUHrgS3c6hxKEMJat3 ykjdrxd09jVctmMBfz6Srnm4uJtJQfi9yroqhvXjTjtHGuLP8cW8E2tzK8l/zPvq YmUDhPMURwNdXqLZEI2h6xxbwe3OFJdHhVgTMAPy6Rdgux3eL9bCT19Mtqt1psty GxOUXzS333MK6K9XvD2FjvPAPHPZOejN3N1XdsURRBxBZDAmlXs= =2QD5 -----END PGP SIGNATURE----- Merge tag 'kvm-riscv-fixes-6.18-2' of https://github.com/kvm-riscv/linux into HEAD KVM/riscv fixes for 6.18, take #2 - Fix check for local interrupts on riscv32 - Read HGEIP CSR on the correct cpu when checking for IMSIC interrupts - Remove automatic I/O mapping from kvm_arch_prepare_memory_region()
This commit is contained in:
commit
36567f1de1
|
|
@ -689,8 +689,20 @@ bool kvm_riscv_vcpu_aia_imsic_has_interrupt(struct kvm_vcpu *vcpu)
|
|||
*/
|
||||
|
||||
read_lock_irqsave(&imsic->vsfile_lock, flags);
|
||||
if (imsic->vsfile_cpu > -1)
|
||||
ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei));
|
||||
if (imsic->vsfile_cpu > -1) {
|
||||
/*
|
||||
* This function is typically called from kvm_vcpu_block() via
|
||||
* kvm_arch_vcpu_runnable() upon WFI trap. The kvm_vcpu_block()
|
||||
* can be preempted and the blocking VCPU might resume on a
|
||||
* different CPU. This means it is possible that current CPU
|
||||
* does not match the imsic->vsfile_cpu hence this function
|
||||
* must check imsic->vsfile_cpu before accessing HGEIP CSR.
|
||||
*/
|
||||
if (imsic->vsfile_cpu != vcpu->cpu)
|
||||
ret = true;
|
||||
else
|
||||
ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei));
|
||||
}
|
||||
read_unlock_irqrestore(&imsic->vsfile_lock, flags);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -171,7 +171,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
|||
enum kvm_mr_change change)
|
||||
{
|
||||
hva_t hva, reg_end, size;
|
||||
gpa_t base_gpa;
|
||||
bool writable;
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -190,15 +189,13 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
|||
hva = new->userspace_addr;
|
||||
size = new->npages << PAGE_SHIFT;
|
||||
reg_end = hva + size;
|
||||
base_gpa = new->base_gfn << PAGE_SHIFT;
|
||||
writable = !(new->flags & KVM_MEM_READONLY);
|
||||
|
||||
mmap_read_lock(current->mm);
|
||||
|
||||
/*
|
||||
* A memory region could potentially cover multiple VMAs, and
|
||||
* any holes between them, so iterate over all of them to find
|
||||
* out if we can map any of them right now.
|
||||
* any holes between them, so iterate over all of them.
|
||||
*
|
||||
* +--------------------------------------------+
|
||||
* +---------------+----------------+ +----------------+
|
||||
|
|
@ -209,7 +206,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
|||
*/
|
||||
do {
|
||||
struct vm_area_struct *vma;
|
||||
hva_t vm_start, vm_end;
|
||||
hva_t vm_end;
|
||||
|
||||
vma = find_vma_intersection(current->mm, hva, reg_end);
|
||||
if (!vma)
|
||||
|
|
@ -225,36 +222,18 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
|
|||
}
|
||||
|
||||
/* Take the intersection of this VMA with the memory region */
|
||||
vm_start = max(hva, vma->vm_start);
|
||||
vm_end = min(reg_end, vma->vm_end);
|
||||
|
||||
if (vma->vm_flags & VM_PFNMAP) {
|
||||
gpa_t gpa = base_gpa + (vm_start - hva);
|
||||
phys_addr_t pa;
|
||||
|
||||
pa = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
|
||||
pa += vm_start - vma->vm_start;
|
||||
|
||||
/* IO region dirty page logging not allowed */
|
||||
if (new->flags & KVM_MEM_LOG_DIRTY_PAGES) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = kvm_riscv_mmu_ioremap(kvm, gpa, pa, vm_end - vm_start,
|
||||
writable, false);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
hva = vm_end;
|
||||
} while (hva < reg_end);
|
||||
|
||||
if (change == KVM_MR_FLAGS_ONLY)
|
||||
goto out;
|
||||
|
||||
if (ret)
|
||||
kvm_riscv_mmu_iounmap(kvm, base_gpa, size);
|
||||
|
||||
out:
|
||||
mmap_read_unlock(current->mm);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
|
|||
|
||||
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return (kvm_riscv_vcpu_has_interrupts(vcpu, -1UL) &&
|
||||
return (kvm_riscv_vcpu_has_interrupts(vcpu, -1ULL) &&
|
||||
!kvm_riscv_vcpu_stopped(vcpu) && !vcpu->arch.pause);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user