The qemu coding standard is to use CamelCase for type and structure names, and the pseries code follows that... sort of. There are quite a lot of places where we bend the rules in order to preserve the capitalization of internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR". That was a bad idea - it frequently leads to names ending up with hard to read clusters of capital letters, and means they don't catch the eye as type identifiers, which is kind of the point of the CamelCase convention in the first place. In short, keeping type identifiers look like CamelCase is more important than preserving standard capitalization of internal "words". So, this patch renames a heap of spapr internal type names to a more standard CamelCase. In addition to case changes, we also make some other identifier renames: VIOsPAPR* -> SpaprVio* The reverse word ordering was only ever used to mitigate the capital cluster, so revert to the natural ordering. VIOsPAPRVTYDevice -> SpaprVioVty VIOsPAPRVLANDevice -> SpaprVioVlan Brevity, since the "Device" didn't add useful information sPAPRDRConnector -> SpaprDrc sPAPRDRConnectorClass -> SpaprDrcClass Brevity, and makes it clearer this is the same thing as a "DRC" mentioned in many other places in the code This is 100% a mechanical search-and-replace patch. It will, however, conflict with essentially any and all outstanding patches touching the spapr code. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
165 lines
4.5 KiB
C
165 lines
4.5 KiB
C
/*
|
|
* QEMU sPAPR random number generator "device" for H_RANDOM hypercall
|
|
*
|
|
* Copyright 2015 Thomas Huth, Red Hat Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License,
|
|
* or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qapi/error.h"
|
|
#include "qemu-common.h"
|
|
#include "cpu.h"
|
|
#include "qemu/error-report.h"
|
|
#include "sysemu/sysemu.h"
|
|
#include "sysemu/device_tree.h"
|
|
#include "sysemu/rng.h"
|
|
#include "hw/ppc/spapr.h"
|
|
#include "kvm_ppc.h"
|
|
|
|
#define SPAPR_RNG(obj) \
|
|
OBJECT_CHECK(SpaprRngState, (obj), TYPE_SPAPR_RNG)
|
|
|
|
struct SpaprRngState {
|
|
/*< private >*/
|
|
DeviceState ds;
|
|
RngBackend *backend;
|
|
bool use_kvm;
|
|
};
|
|
typedef struct SpaprRngState SpaprRngState;
|
|
|
|
struct HRandomData {
|
|
QemuSemaphore sem;
|
|
union {
|
|
uint64_t v64;
|
|
uint8_t v8[8];
|
|
} val;
|
|
int received;
|
|
};
|
|
typedef struct HRandomData HRandomData;
|
|
|
|
/* Callback function for the RngBackend */
|
|
static void random_recv(void *dest, const void *src, size_t size)
|
|
{
|
|
HRandomData *hrdp = dest;
|
|
|
|
if (src && size > 0) {
|
|
assert(size + hrdp->received <= sizeof(hrdp->val.v8));
|
|
memcpy(&hrdp->val.v8[hrdp->received], src, size);
|
|
hrdp->received += size;
|
|
}
|
|
|
|
qemu_sem_post(&hrdp->sem);
|
|
}
|
|
|
|
/* Handler for the H_RANDOM hypercall */
|
|
static target_ulong h_random(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
|
target_ulong opcode, target_ulong *args)
|
|
{
|
|
SpaprRngState *rngstate;
|
|
HRandomData hrdata;
|
|
|
|
rngstate = SPAPR_RNG(object_resolve_path_type("", TYPE_SPAPR_RNG, NULL));
|
|
|
|
if (!rngstate || !rngstate->backend) {
|
|
return H_HARDWARE;
|
|
}
|
|
|
|
qemu_sem_init(&hrdata.sem, 0);
|
|
hrdata.val.v64 = 0;
|
|
hrdata.received = 0;
|
|
|
|
while (hrdata.received < 8) {
|
|
rng_backend_request_entropy(rngstate->backend, 8 - hrdata.received,
|
|
random_recv, &hrdata);
|
|
qemu_mutex_unlock_iothread();
|
|
qemu_sem_wait(&hrdata.sem);
|
|
qemu_mutex_lock_iothread();
|
|
}
|
|
|
|
qemu_sem_destroy(&hrdata.sem);
|
|
args[0] = hrdata.val.v64;
|
|
|
|
return H_SUCCESS;
|
|
}
|
|
|
|
static void spapr_rng_instance_init(Object *obj)
|
|
{
|
|
if (object_resolve_path_type("", TYPE_SPAPR_RNG, NULL) != NULL) {
|
|
error_report("spapr-rng can not be instantiated twice!");
|
|
return;
|
|
}
|
|
|
|
object_property_set_description(obj, "rng",
|
|
"ID of the random number generator backend",
|
|
NULL);
|
|
}
|
|
|
|
static void spapr_rng_realize(DeviceState *dev, Error **errp)
|
|
{
|
|
|
|
SpaprRngState *rngstate = SPAPR_RNG(dev);
|
|
|
|
if (rngstate->use_kvm) {
|
|
if (kvmppc_enable_hwrng() == 0) {
|
|
return;
|
|
}
|
|
/*
|
|
* If user specified both, use-kvm and a backend, we fall back to
|
|
* the backend now. If not, provide an appropriate error message.
|
|
*/
|
|
if (!rngstate->backend) {
|
|
error_setg(errp, "Could not initialize in-kernel H_RANDOM call!");
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (rngstate->backend) {
|
|
spapr_register_hypercall(H_RANDOM, h_random);
|
|
} else {
|
|
error_setg(errp, "spapr-rng needs an RNG backend!");
|
|
}
|
|
}
|
|
|
|
static Property spapr_rng_properties[] = {
|
|
DEFINE_PROP_BOOL("use-kvm", SpaprRngState, use_kvm, false),
|
|
DEFINE_PROP_LINK("rng", SpaprRngState, backend, TYPE_RNG_BACKEND,
|
|
RngBackend *),
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
};
|
|
|
|
static void spapr_rng_class_init(ObjectClass *oc, void *data)
|
|
{
|
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
|
|
|
dc->realize = spapr_rng_realize;
|
|
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
|
dc->props = spapr_rng_properties;
|
|
dc->hotpluggable = false;
|
|
}
|
|
|
|
static const TypeInfo spapr_rng_info = {
|
|
.name = TYPE_SPAPR_RNG,
|
|
.parent = TYPE_DEVICE,
|
|
.instance_size = sizeof(SpaprRngState),
|
|
.instance_init = spapr_rng_instance_init,
|
|
.class_init = spapr_rng_class_init,
|
|
};
|
|
|
|
static void spapr_rng_register_type(void)
|
|
{
|
|
type_register_static(&spapr_rng_info);
|
|
}
|
|
type_init(spapr_rng_register_type)
|