18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Based on the x86 implementation. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2012 ARM Ltd. 68c2ecf20Sopenharmony_ci * Author: Marc Zyngier <marc.zyngier@arm.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/perf_event.h> 108c2ecf20Sopenharmony_ci#include <linux/kvm_host.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <asm/kvm_emulate.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic int kvm_is_in_guest(void) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci return kvm_get_running_vcpu() != NULL; 178c2ecf20Sopenharmony_ci} 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic int kvm_is_user_mode(void) 208c2ecf20Sopenharmony_ci{ 218c2ecf20Sopenharmony_ci struct kvm_vcpu *vcpu; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci vcpu = kvm_get_running_vcpu(); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci if (vcpu) 268c2ecf20Sopenharmony_ci return !vcpu_mode_priv(vcpu); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci return 0; 298c2ecf20Sopenharmony_ci} 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistatic unsigned long kvm_get_guest_ip(void) 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci struct kvm_vcpu *vcpu; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci vcpu = kvm_get_running_vcpu(); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci if (vcpu) 388c2ecf20Sopenharmony_ci return *vcpu_pc(vcpu); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci return 0; 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic struct perf_guest_info_callbacks kvm_guest_cbs = { 448c2ecf20Sopenharmony_ci .is_in_guest = kvm_is_in_guest, 458c2ecf20Sopenharmony_ci .is_user_mode = kvm_is_user_mode, 468c2ecf20Sopenharmony_ci .get_guest_ip = kvm_get_guest_ip, 478c2ecf20Sopenharmony_ci}; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ciint kvm_perf_init(void) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci return perf_register_guest_info_callbacks(&kvm_guest_cbs); 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ciint kvm_perf_teardown(void) 558c2ecf20Sopenharmony_ci{ 568c2ecf20Sopenharmony_ci return perf_unregister_guest_info_callbacks(&kvm_guest_cbs); 578c2ecf20Sopenharmony_ci} 58