110859Sandreas.sandberg@arm.com/* 210859Sandreas.sandberg@arm.com * Copyright (c) 2015 ARM Limited 310859Sandreas.sandberg@arm.com * All rights reserved 410859Sandreas.sandberg@arm.com * 510859Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 610859Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 710859Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 810859Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 910859Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1010859Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1110859Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1210859Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1310859Sandreas.sandberg@arm.com * 1410859Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 1510859Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 1610859Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 1710859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 1810859Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1910859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2010859Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2110859Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2210859Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2310859Sandreas.sandberg@arm.com * this software without specific prior written permission. 2410859Sandreas.sandberg@arm.com * 2510859Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610859Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710859Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810859Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910859Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010859Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110859Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210859Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310859Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410859Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510859Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610859Sandreas.sandberg@arm.com * 3710859Sandreas.sandberg@arm.com * Authors: Andreas Sandberg 3810859Sandreas.sandberg@arm.com */ 3910859Sandreas.sandberg@arm.com 4010859Sandreas.sandberg@arm.com#include "cpu/kvm/device.hh" 4110859Sandreas.sandberg@arm.com 4210859Sandreas.sandberg@arm.com#include <linux/kvm.h> 4310859Sandreas.sandberg@arm.com#include <sys/ioctl.h> 4410859Sandreas.sandberg@arm.com#include <unistd.h> 4510859Sandreas.sandberg@arm.com 4610859Sandreas.sandberg@arm.com#include <cassert> 4710859Sandreas.sandberg@arm.com#include <cerrno> 4810859Sandreas.sandberg@arm.com 4912334Sgabeblack@google.com#include "base/logging.hh" 5010859Sandreas.sandberg@arm.com 5110859Sandreas.sandberg@arm.comKvmDevice::KvmDevice(int _fd) 5210859Sandreas.sandberg@arm.com : fd(_fd) 5310859Sandreas.sandberg@arm.com{ 5410859Sandreas.sandberg@arm.com} 5510859Sandreas.sandberg@arm.com 5610859Sandreas.sandberg@arm.comKvmDevice::~KvmDevice() 5710859Sandreas.sandberg@arm.com{ 5810859Sandreas.sandberg@arm.com close(fd); 5910859Sandreas.sandberg@arm.com} 6010859Sandreas.sandberg@arm.com 6110859Sandreas.sandberg@arm.comvoid 6210859Sandreas.sandberg@arm.comKvmDevice::getAttrPtr(uint32_t group, uint64_t attr, void *data) const 6310859Sandreas.sandberg@arm.com{ 6410859Sandreas.sandberg@arm.com#ifdef KVM_GET_DEVICE_ATTR 6510859Sandreas.sandberg@arm.com struct kvm_device_attr dattr = { 6610859Sandreas.sandberg@arm.com 0, // Flags 6710859Sandreas.sandberg@arm.com group, 6810859Sandreas.sandberg@arm.com attr, 6910859Sandreas.sandberg@arm.com reinterpret_cast<uint64_t>(data), 7010859Sandreas.sandberg@arm.com }; 7110859Sandreas.sandberg@arm.com 7210859Sandreas.sandberg@arm.com if (ioctl(KVM_GET_DEVICE_ATTR, &dattr) == -1) { 7310859Sandreas.sandberg@arm.com panic("Failed to get attribute (group: %i, attr: %i, errno: %i)", 7410859Sandreas.sandberg@arm.com group, attr, errno); 7510859Sandreas.sandberg@arm.com } 7610859Sandreas.sandberg@arm.com#else 7710859Sandreas.sandberg@arm.com panic("Kernel headers don't support KVM_GET_DEVICE_ATTR\n"); 7810859Sandreas.sandberg@arm.com#endif 7910859Sandreas.sandberg@arm.com} 8010859Sandreas.sandberg@arm.com 8110859Sandreas.sandberg@arm.comvoid 8210859Sandreas.sandberg@arm.comKvmDevice::setAttrPtr(uint32_t group, uint64_t attr, const void *data) const 8310859Sandreas.sandberg@arm.com{ 8410859Sandreas.sandberg@arm.com#ifdef KVM_SET_DEVICE_ATTR 8510859Sandreas.sandberg@arm.com struct kvm_device_attr dattr = { 8610859Sandreas.sandberg@arm.com 0, // Flags 8710859Sandreas.sandberg@arm.com group, 8810859Sandreas.sandberg@arm.com attr, 8910859Sandreas.sandberg@arm.com reinterpret_cast<uint64_t>(data), 9010859Sandreas.sandberg@arm.com }; 9110859Sandreas.sandberg@arm.com 9210859Sandreas.sandberg@arm.com if (ioctl(KVM_SET_DEVICE_ATTR, &dattr) == -1) { 9310859Sandreas.sandberg@arm.com panic("Failed to set attribute (group: %i, attr: %i, errno: %i)", 9410859Sandreas.sandberg@arm.com group, attr, errno); 9510859Sandreas.sandberg@arm.com } 9610859Sandreas.sandberg@arm.com#else 9710859Sandreas.sandberg@arm.com panic("Kernel headers don't support KVM_GET_DEVICE_ATTR\n"); 9810859Sandreas.sandberg@arm.com#endif 9910859Sandreas.sandberg@arm.com} 10010859Sandreas.sandberg@arm.com 10110859Sandreas.sandberg@arm.combool 10210859Sandreas.sandberg@arm.comKvmDevice::hasAttr(uint32_t group, uint64_t attr) const 10310859Sandreas.sandberg@arm.com{ 10410859Sandreas.sandberg@arm.com#ifdef KVM_HAS_DEVICE_ATTR 10510859Sandreas.sandberg@arm.com struct kvm_device_attr dattr = { 10610859Sandreas.sandberg@arm.com 0, // Flags 10710859Sandreas.sandberg@arm.com group, 10810859Sandreas.sandberg@arm.com attr, 10910859Sandreas.sandberg@arm.com 0, // Data address (ignored) 11010859Sandreas.sandberg@arm.com }; 11110859Sandreas.sandberg@arm.com 11210859Sandreas.sandberg@arm.com return ioctl(KVM_HAS_DEVICE_ATTR, &dattr) == 0; 11310859Sandreas.sandberg@arm.com#else 11410859Sandreas.sandberg@arm.com panic("Kernel headers don't support KVM_HAS_DEVICE_ATTR\n"); 11510859Sandreas.sandberg@arm.com#endif 11610859Sandreas.sandberg@arm.com} 11710859Sandreas.sandberg@arm.com 11810859Sandreas.sandberg@arm.comint 11910859Sandreas.sandberg@arm.comKvmDevice::ioctl(int request, long p1) const 12010859Sandreas.sandberg@arm.com{ 12110859Sandreas.sandberg@arm.com assert(fd != -1); 12210859Sandreas.sandberg@arm.com 12310859Sandreas.sandberg@arm.com return ::ioctl(fd, request, p1); 12410859Sandreas.sandberg@arm.com} 12510859Sandreas.sandberg@arm.com 126