arch/powerpc/kvm/book3s_hv_builtin.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kvm/book3s_hv_builtin.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kvm/book3s_hv_builtin.c
Extension
.c
Size
16111 bytes
Lines
630
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if ((threads_ceded | threads_conferring) == threads_running) {
			rv = H_TOO_HARD; /* => do yield */
			break;
		}
	}
	clear_bit(ptid, &vc->conferring_threads);
	return rv;
}

/*
 * When running HV mode KVM we need to block certain operations while KVM VMs
 * exist in the system. We use a counter of VMs to track this.
 *
 * One of the operations we need to block is onlining of secondaries, so we
 * protect hv_vm_count with cpus_read_lock/unlock().
 */
static atomic_t hv_vm_count;

void kvm_hv_vm_activated(void)
{
	cpus_read_lock();
	atomic_inc(&hv_vm_count);
	cpus_read_unlock();
}
EXPORT_SYMBOL_GPL(kvm_hv_vm_activated);

void kvm_hv_vm_deactivated(void)
{
	cpus_read_lock();
	atomic_dec(&hv_vm_count);
	cpus_read_unlock();
}
EXPORT_SYMBOL_GPL(kvm_hv_vm_deactivated);

bool kvm_hv_mode_active(void)
{
	return atomic_read(&hv_vm_count) != 0;
}

extern int hcall_real_table[], hcall_real_table_end[];

int kvmppc_hcall_impl_hv_realmode(unsigned long cmd)
{
	cmd /= 4;
	if (cmd < hcall_real_table_end - hcall_real_table &&
	    hcall_real_table[cmd])
		return 1;

	return 0;
}
EXPORT_SYMBOL_GPL(kvmppc_hcall_impl_hv_realmode);

int kvmppc_hwrng_present(void)
{
	return ppc_md.get_random_seed != NULL;
}
EXPORT_SYMBOL_GPL(kvmppc_hwrng_present);

long kvmppc_rm_h_random(struct kvm_vcpu *vcpu)
{
	unsigned long rand;

	if (ppc_md.get_random_seed &&
	    ppc_md.get_random_seed(&rand)) {
		kvmppc_set_gpr(vcpu, 4, rand);
		return H_SUCCESS;
	}

	return H_HARDWARE;
}

/*
 * Send an interrupt or message to another CPU.
 * The caller needs to include any barrier needed to order writes
 * to memory vs. the IPI/message.
 */
void kvmhv_rm_send_ipi(int cpu)
{
	void __iomem *xics_phys;
	unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);

	/* On POWER9 we can use msgsnd for any destination cpu. */
	if (cpu_has_feature(CPU_FTR_ARCH_300)) {
		msg |= get_hard_smp_processor_id(cpu);
		__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
		return;
	}

	/* On POWER8 for IPIs to threads in the same core, use msgsnd. */
	if (cpu_has_feature(CPU_FTR_ARCH_207S) &&

Annotation

Implementation Notes