summaryrefslogtreecommitdiff
path: root/drivers/xen/pcpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/pcpu.c')
-rw-r--r--drivers/xen/pcpu.c87
1 files changed, 47 insertions, 40 deletions
diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c
index cdc6daa7a9f6..093ad4a08672 100644
--- a/drivers/xen/pcpu.c
+++ b/drivers/xen/pcpu.c
@@ -47,6 +47,9 @@
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
+#ifdef CONFIG_ACPI
+#include <acpi/processor.h>
+#endif
/*
* @cpu_id: Xen physical cpu logic number
@@ -58,10 +61,11 @@ struct pcpu {
struct list_head list;
struct device dev;
uint32_t cpu_id;
+ uint32_t acpi_id;
uint32_t flags;
};
-static struct bus_type xen_pcpu_subsys = {
+static const struct bus_type xen_pcpu_subsys = {
.name = "xen_cpu",
.dev_name = "xen_cpu",
};
@@ -92,7 +96,7 @@ static int xen_pcpu_up(uint32_t cpu_id)
return HYPERVISOR_platform_op(&op);
}
-static ssize_t show_online(struct device *dev,
+static ssize_t online_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -101,7 +105,7 @@ static ssize_t show_online(struct device *dev,
return sprintf(buf, "%u\n", !!(cpu->flags & XEN_PCPU_FLAGS_ONLINE));
}
-static ssize_t __ref store_online(struct device *dev,
+static ssize_t online_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -130,7 +134,7 @@ static ssize_t __ref store_online(struct device *dev,
ret = count;
return ret;
}
-static DEVICE_ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online);
+static DEVICE_ATTR_RW(online);
static struct attribute *pcpu_dev_attrs[] = {
&dev_attr_online.attr,
@@ -228,7 +232,7 @@ static int register_pcpu(struct pcpu *pcpu)
err = device_register(dev);
if (err) {
- pcpu_release(dev);
+ put_device(dev);
return err;
}
@@ -249,6 +253,7 @@ static struct pcpu *create_and_register_pcpu(struct xenpf_pcpuinfo *info)
INIT_LIST_HEAD(&pcpu->list);
pcpu->cpu_id = info->xen_cpuid;
+ pcpu->acpi_id = info->acpi_id;
pcpu->flags = info->flags;
/* Need hold on xen_pcpu_lock before pcpu list manipulations */
@@ -345,41 +350,6 @@ static irqreturn_t xen_pcpu_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-/* Sync with Xen hypervisor after cpu hotadded */
-void xen_pcpu_hotplug_sync(void)
-{
- schedule_work(&xen_pcpu_work);
-}
-EXPORT_SYMBOL_GPL(xen_pcpu_hotplug_sync);
-
-/*
- * For hypervisor presented cpu, return logic cpu id;
- * For hypervisor non-presented cpu, return -ENODEV.
- */
-int xen_pcpu_id(uint32_t acpi_id)
-{
- int cpu_id = 0, max_id = 0;
- struct xen_platform_op op;
-
- op.cmd = XENPF_get_cpuinfo;
- while (cpu_id <= max_id) {
- op.u.pcpu_info.xen_cpuid = cpu_id;
- if (HYPERVISOR_platform_op(&op)) {
- cpu_id++;
- continue;
- }
-
- if (acpi_id == op.u.pcpu_info.acpi_id)
- return cpu_id;
- if (op.u.pcpu_info.max_present > max_id)
- max_id = op.u.pcpu_info.max_present;
- cpu_id++;
- }
-
- return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(xen_pcpu_id);
-
static int __init xen_pcpu_init(void)
{
int irq, ret;
@@ -416,3 +386,40 @@ err1:
return ret;
}
arch_initcall(xen_pcpu_init);
+
+#ifdef CONFIG_ACPI
+bool __init xen_processor_present(uint32_t acpi_id)
+{
+ const struct pcpu *pcpu;
+ bool online = false;
+
+ mutex_lock(&xen_pcpu_lock);
+ list_for_each_entry(pcpu, &xen_pcpus, list)
+ if (pcpu->acpi_id == acpi_id) {
+ online = pcpu->flags & XEN_PCPU_FLAGS_ONLINE;
+ break;
+ }
+ mutex_unlock(&xen_pcpu_lock);
+
+ return online;
+}
+
+void xen_sanitize_proc_cap_bits(uint32_t *cap)
+{
+ struct xen_platform_op op = {
+ .cmd = XENPF_set_processor_pminfo,
+ .u.set_pminfo.id = -1,
+ .u.set_pminfo.type = XEN_PM_PDC,
+ };
+ u32 buf[3] = { ACPI_PDC_REVISION_ID, 1, *cap };
+ int ret;
+
+ set_xen_guest_handle(op.u.set_pminfo.pdc, buf);
+ ret = HYPERVISOR_platform_op(&op);
+ if (ret)
+ pr_err("sanitize of _PDC buffer bits from Xen failed: %d\n",
+ ret);
+ else
+ *cap = buf[2];
+}
+#endif