diff mbox

[v4,11/14] pnpbios: replace paravirt_enabled() check with legacy device check

Message ID 1459987594-5434-12-git-send-email-mcgrof@kernel.org (mailing list archive)
State New, archived
Headers show

Commit Message

Luis Chamberlain April 7, 2016, 12:06 a.m. UTC
Since we are removing paravirt_enabled() replace it with a
logical equivalent. Even though PNPBIOS is x86 specific we
add an arch-specific type call, which can be implemented by
any architecture to show how other legacy attribute devices
can later be also checked for with other ACPI legacy attribute
flags.

This implicates the first ACPI 5.2.9.3 IA-PC Boot Architecture
ACPI_FADT_LEGACY_DEVICES flag device, and shows how to add more.

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 arch/x86/include/asm/x86_init.h   | 26 ++++++++++++++++++++++++++
 arch/x86/kernel/platform-quirks.c | 10 ++++++++++
 drivers/pnp/pnpbios/core.c        |  3 ++-
 include/linux/pnp.h               |  2 ++
 4 files changed, 40 insertions(+), 1 deletion(-)

Comments

David Vrabel April 7, 2016, 9:46 a.m. UTC | #1
On 07/04/16 01:06, Luis R. Rodriguez wrote:
> Since we are removing paravirt_enabled() replace it with a
> logical equivalent. Even though PNPBIOS is x86 specific we
> add an arch-specific type call, which can be implemented by
> any architecture to show how other legacy attribute devices
> can later be also checked for with other ACPI legacy attribute
> flags.
> 
> This implicates the first ACPI 5.2.9.3 IA-PC Boot Architecture
> ACPI_FADT_LEGACY_DEVICES flag device, and shows how to add more.
[...]
> +struct x86_legacy_devices {
> +	int pnpbios;
> +};

It's not clear why pnpbios needs a new structure and why this structure
of devices does not have the bit for the rtc device.

David
Luis Chamberlain April 7, 2016, 9:42 p.m. UTC | #2
On Thu, Apr 07, 2016 at 10:46:11AM +0100, David Vrabel wrote:
> On 07/04/16 01:06, Luis R. Rodriguez wrote:
> > Since we are removing paravirt_enabled() replace it with a
> > logical equivalent. Even though PNPBIOS is x86 specific we
> > add an arch-specific type call, which can be implemented by
> > any architecture to show how other legacy attribute devices
> > can later be also checked for with other ACPI legacy attribute
> > flags.
> > 
> > This implicates the first ACPI 5.2.9.3 IA-PC Boot Architecture
> > ACPI_FADT_LEGACY_DEVICES flag device, and shows how to add more.
> [...]
> > +struct x86_legacy_devices {
> > +	int pnpbios;
> > +};
> 
> It's not clear why pnpbios needs a new structure

I'm glad you asked. Dealing with placing pnpbios quirk in a more useful generic
fashion was perhaps the most difficult challenge in this series.  As I reviewed
possibilities to remove paravirt_enabled() the best prospect I found was to see
if Xen could instead use ACPI 5.2.9.3 IA-PC Boot Architecture flags to annotate
some quirks. It turns out that it is possible, but there are only so many flags,
and also, we didn't want to have a solution that incurred respective upstream
Xen hypervisor change, that would be silly.

To make this quirk more useful then this folds the pnpbios quirk as a sub
quirk under the more borad ACPI_FADT_LEGACY_DEVICES ACPI flag. What this
does, as can be seen by also looking at the next patch, "x86, ACPI: parse
ACPI_FADT_LEGACY_DEVICES" is it explicitly folds pnpbios as one of the
ACPI_FADT_LEGACY_DEVICES devices, but also paves the way for further known
main legacy components to added to the list.

> and why this structure of devices does not have the bit for the rtc device.

That's because ACPI has its own dedicated flag for it, so there already
is a one-to-one mapping available. All we needed to do to replace the
RTC hack was to provide a mechanism to unify both the paravirt RTC hack
with the ACPI RTC flag.

  Luis
diff mbox

Patch

diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index f3f81122ae3b..894cc29529f9 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -142,15 +142,41 @@  struct x86_cpuinit_ops {
 struct timespec;
 
 /**
+ * struct x86_legacy_devices - legacy x86 devices
+ *
+ * @pnpbios: this platform can have a PNPBIOS. If this is disabled the platform
+ * 	is known to never have a PNPBIOS.
+ *
+ * These are devices known to require LPC or ISA bus. The definition of legacy
+ * devices adheres to the ACPI 5.2.9.3 IA-PC Boot Architecture flag
+ * ACPI_FADT_LEGACY_DEVICES. These devices consist of user visible devices on
+ * the LPC or ISA bus. User visible devices are devices that have end-user
+ * accessible connectors (for example, LPT parallel port). Legacy devices on
+ * the LPC bus consist for example of serial and parallel ports, PS/2 keyboard
+ * / mouse, and the floppy disk controller. A system that lacks all known
+ * legacy devices can assume all devices can be detected exclusively via
+ * standard device enumeration mechanisms including the ACPI namespace.
+ *
+ * A system which has does not have ACPI_FADT_LEGACY_DEVICES enabled must not
+ * have any of the legacy devices enumerated below present.
+ */
+struct x86_legacy_devices {
+	int pnpbios;
+};
+
+/**
  * struct x86_legacy_features - legacy x86 features
  *
  * @rtc: this device has a CMOS real-time clock present
  * @ebda_search: it's safe to search for the EBDA signature in the hardware's
  * 	low RAM
+ * @devices: legacy x86 devices, refer to struct x86_legacy_devices
+ * 	documentation for further details.
  */
 struct x86_legacy_features {
 	int rtc;
 	int ebda_search;
+	struct x86_legacy_devices devices;
 };
 
 /**
diff --git a/arch/x86/kernel/platform-quirks.c b/arch/x86/kernel/platform-quirks.c
index a871b6b0e35f..742f879da871 100644
--- a/arch/x86/kernel/platform-quirks.c
+++ b/arch/x86/kernel/platform-quirks.c
@@ -8,6 +8,7 @@  void __init x86_early_init_platform_quirks(void)
 {
 	x86_platform.legacy.rtc = 1;
 	x86_platform.legacy.ebda_search = 0;
+	x86_platform.legacy.devices.pnpbios = 1;
 
 	switch (boot_params.hdr.hardware_subarch) {
 	case X86_SUBARCH_PC:
@@ -15,8 +16,17 @@  void __init x86_early_init_platform_quirks(void)
 		break;
 	case X86_SUBARCH_XEN:
 	case X86_SUBARCH_LGUEST:
+		x86_platform.legacy.devices.pnpbios = 0;
+	/* fall through */
 	case X86_SUBARCH_INTEL_MID:
 		x86_platform.legacy.rtc = 0;
 		break;
 	}
 }
+
+#if defined(CONFIG_PNPBIOS)
+bool __init arch_pnpbios_disabled(void)
+{
+	return x86_platform.legacy.devices.pnpbios == 0;
+}
+#endif
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index facd43b8516c..81603d99082b 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -521,10 +521,11 @@  static int __init pnpbios_init(void)
 	int ret;
 
 	if (pnpbios_disabled || dmi_check_system(pnpbios_dmi_table) ||
-	    paravirt_enabled()) {
+	    arch_pnpbios_disabled()) {
 		printk(KERN_INFO "PnPBIOS: Disabled\n");
 		return -ENODEV;
 	}
+
 #ifdef CONFIG_PNPACPI
 	if (!acpi_disabled && !pnpacpi_disabled) {
 		pnpbios_disabled = 1;
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 5df733b8f704..2588ca6a9028 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -337,9 +337,11 @@  extern struct mutex pnp_res_mutex;
 
 #ifdef CONFIG_PNPBIOS
 extern struct pnp_protocol pnpbios_protocol;
+extern bool arch_pnpbios_disabled(void);
 #define pnp_device_is_pnpbios(dev) ((dev)->protocol == (&pnpbios_protocol))
 #else
 #define pnp_device_is_pnpbios(dev) 0
+#define arch_pnpbios_disabled()	false
 #endif
 
 #ifdef CONFIG_PNPACPI