[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 27/40] spapr_events: event-scan RTAS interface
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PULL 27/40] spapr_events: event-scan RTAS interface |
Date: |
Wed, 3 Jun 2015 23:45:28 +0200 |
From: Tyrel Datwyler <address@hidden>
We don't actually rely on this interface to surface hotplug events, and
instead rely on the similar-but-interrupt-driven check-exception RTAS
interface used for EPOW events. However, the existence of this interface
is needed to ensure guest kernels initialize the event-reporting
interfaces which will in turn be used by userspace tools to handle these
events, so we implement this interface here.
Since events surfaced by this call are mutually exclusive to those
surfaced via check-exception, we also update the RTAS event queue code
to accept a boolean to mark/filter for events accordingly.
Events of this sort are not currently generated by QEMU, but the interface
has been tested by surfacing hotplug events via event-scan in place
of check-exception.
Signed-off-by: Tyrel Datwyler <address@hidden>
Signed-off-by: Michael Roth <address@hidden>
Reviewed-by: David Gibson <address@hidden>
Signed-off-by: David Gibson <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
hw/ppc/spapr.c | 2 ++
hw/ppc/spapr_events.c | 65 ++++++++++++++++++++++++++++++++++++++++++++------
include/hw/ppc/spapr.h | 3 +++
3 files changed, 63 insertions(+), 7 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 15eebb4..b0b9f81 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -533,6 +533,8 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
refpoints, sizeof(refpoints))));
_FDT((fdt_property_cell(fdt, "rtas-error-log-max", RTAS_ERROR_LOG_MAX)));
+ _FDT((fdt_property_cell(fdt, "rtas-event-scan-rate",
+ RTAS_EVENT_SCAN_RATE)));
/*
* According to PAPR, rtas ibm,os-term does not guarantee a return
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index c634a3b..fda9e35 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -236,17 +236,19 @@ void spapr_events_fdt_skel(void *fdt, uint32_t
check_exception_irq)
_FDT((fdt_end_node(fdt)));
}
-static void rtas_event_log_queue(int log_type, void *data)
+static void rtas_event_log_queue(int log_type, void *data, bool exception)
{
sPAPREventLogEntry *entry = g_new(sPAPREventLogEntry, 1);
g_assert(data);
entry->log_type = log_type;
+ entry->exception = exception;
entry->data = data;
QTAILQ_INSERT_TAIL(&spapr->pending_events, entry, next);
}
-static sPAPREventLogEntry *rtas_event_log_dequeue(uint32_t event_mask)
+static sPAPREventLogEntry *rtas_event_log_dequeue(uint32_t event_mask,
+ bool exception)
{
sPAPREventLogEntry *entry = NULL;
@@ -256,6 +258,10 @@ static sPAPREventLogEntry *rtas_event_log_dequeue(uint32_t
event_mask)
}
QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
+ if (entry->exception != exception) {
+ continue;
+ }
+
/* EPOW and hotplug events are surfaced in the same manner */
if (entry->log_type == RTAS_LOG_TYPE_EPOW ||
entry->log_type == RTAS_LOG_TYPE_HOTPLUG) {
@@ -270,7 +276,7 @@ static sPAPREventLogEntry *rtas_event_log_dequeue(uint32_t
event_mask)
return entry;
}
-static bool rtas_event_log_contains(uint32_t event_mask)
+static bool rtas_event_log_contains(uint32_t event_mask, bool exception)
{
sPAPREventLogEntry *entry = NULL;
@@ -280,6 +286,10 @@ static bool rtas_event_log_contains(uint32_t event_mask)
}
QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
+ if (entry->exception != exception) {
+ continue;
+ }
+
/* EPOW and hotplug events are surfaced in the same manner */
if (entry->log_type == RTAS_LOG_TYPE_EPOW ||
entry->log_type == RTAS_LOG_TYPE_HOTPLUG) {
@@ -367,7 +377,7 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
epow->event_modifier = RTAS_LOG_V6_EPOW_MODIFIER_NORMAL;
epow->extended_modifier = RTAS_LOG_V6_EPOW_XMODIFIER_PARTITION_SPECIFIC;
- rtas_event_log_queue(RTAS_LOG_TYPE_EPOW, new_epow);
+ rtas_event_log_queue(RTAS_LOG_TYPE_EPOW, new_epow, true);
qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
}
@@ -428,7 +438,7 @@ static void spapr_hotplug_req_event(sPAPRDRConnector *drc,
uint8_t hp_action)
return;
}
- rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp);
+ rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true);
qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
}
@@ -466,7 +476,7 @@ static void check_exception(PowerPCCPU *cpu,
sPAPREnvironment *spapr,
xinfo |= (uint64_t)rtas_ld(args, 6) << 32;
}
- event = rtas_event_log_dequeue(mask);
+ event = rtas_event_log_dequeue(mask, true);
if (!event) {
goto out_no_events;
}
@@ -488,7 +498,7 @@ static void check_exception(PowerPCCPU *cpu,
sPAPREnvironment *spapr,
* do the latter here, since our code relies on edge-triggered
* interrupts.
*/
- if (rtas_event_log_contains(mask)) {
+ if (rtas_event_log_contains(mask, true)) {
qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
}
@@ -498,6 +508,46 @@ out_no_events:
rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
}
+static void event_scan(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args,
+ uint32_t nret, target_ulong rets)
+{
+ uint32_t mask, buf, len, event_len;
+ sPAPREventLogEntry *event;
+ struct rtas_error_log *hdr;
+
+ if (nargs != 4 || nret != 1) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ mask = rtas_ld(args, 0);
+ buf = rtas_ld(args, 2);
+ len = rtas_ld(args, 3);
+
+ event = rtas_event_log_dequeue(mask, false);
+ if (!event) {
+ goto out_no_events;
+ }
+
+ hdr = event->data;
+ event_len = be32_to_cpu(hdr->extended_length) + sizeof(*hdr);
+
+ if (event_len < len) {
+ len = event_len;
+ }
+
+ cpu_physical_memory_write(buf, event->data, len);
+ rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+ g_free(event->data);
+ g_free(event);
+ return;
+
+out_no_events:
+ rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
+}
+
void spapr_events_init(sPAPREnvironment *spapr)
{
QTAILQ_INIT(&spapr->pending_events);
@@ -506,4 +556,5 @@ void spapr_events_init(sPAPREnvironment *spapr)
qemu_register_powerdown_notifier(&spapr->epow_notifier);
spapr_rtas_register(RTAS_CHECK_EXCEPTION, "check-exception",
check_exception);
+ spapr_rtas_register(RTAS_EVENT_SCAN, "event-scan", event_scan);
}
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 71b3e08..7b4b1bb 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -514,6 +514,8 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr
rtas_addr,
#define RTAS_ERROR_LOG_MAX 2048
+#define RTAS_EVENT_SCAN_RATE 1
+
typedef struct sPAPRTCETable sPAPRTCETable;
#define TYPE_SPAPR_TCE_TABLE "spapr-tce-table"
@@ -539,6 +541,7 @@ sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn);
struct sPAPREventLogEntry {
int log_type;
+ bool exception;
void *data;
QTAILQ_ENTRY(sPAPREventLogEntry) next;
};
--
1.8.1.4
- [Qemu-devel] [PULL 16/40] pseries: Add pseries-2.4 machine type, (continued)
- [Qemu-devel] [PULL 16/40] pseries: Add pseries-2.4 machine type, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 13/40] spapr_pci: Rework device-tree rendering, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 38/40] tci: do not use CPUArchState in tcg-target.h, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 37/40] Add David Gibson for sPAPR in MAINTAINERS file, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 35/40] spapr: override default ram size to 512MB, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 29/40] spapr_pci: add dynamic-reconfiguration option for spapr-pci-host-bridge, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 17/40] hw/ppc/spapr: Fix error message when firmware could not be loaded, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 21/40] spapr_rtas: add get/set-power-level RTAS interfaces, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 11/40] spapr_pci: Make find_phb()/find_dev() public, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 22/40] spapr_rtas: add set-indicator RTAS interface, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 27/40] spapr_events: event-scan RTAS interface,
Alexander Graf <=
- [Qemu-devel] [PULL 39/40] tcg: add TCG_TARGET_TLB_DISPLACEMENT_BITS, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 25/40] spapr_rtas: add ibm, configure-connector RTAS interface, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 40/40] softmmu: support up to 12 MMU modes, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 34/40] machine: add default_ram_size to machine class, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 36/40] pseries: Enable in-kernel H_LOGICAL_CI_{LOAD, STORE} implementations, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 28/40] spapr_drc: add spapr_drc_populate_dt(), Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 19/40] docs: add sPAPR hotplug/dynamic-reconfiguration documentation, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 26/40] spapr_events: re-use EPOW event infrastructure for hotplug events, Alexander Graf, 2015/06/03
- [Qemu-devel] [PULL 32/40] spapr_pci: enable basic hotplug operations, Alexander Graf, 2015/06/03