2008-02-11 19:25:39

by Glauber Costa

[permalink] [raw]
Subject: [PATCH 1/5] Change vsmp compile dependency

Change Makefile so vsmp_64.o object is dependent
on PARAVIRT, rather than X86_VSMP

Signed-off-by: Glauber Costa <[email protected]>
Signed-off-by: Ravikiran Thirumalai <[email protected]>
Acked-by: Shai Fultheim <[email protected]>
---
arch/x86/kernel/Makefile | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 21dc1a0..71a92a2 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -52,7 +52,7 @@ obj-$(CONFIG_KEXEC) += relocate_kernel_
obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o
-obj-$(CONFIG_X86_VSMP) += vsmp_64.o
+obj-$(CONFIG_PARAVIRT) += vsmp_64.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_MODULES) += module_$(BITS).o
obj-$(CONFIG_ACPI_SRAT) += srat_32.o
--
1.4.2


2008-02-11 19:29:25

by Glauber Costa

[permalink] [raw]
Subject: [PATCH 5/5] [PATCH] use the paravirt helpers

Signed-off-by: Glauber Costa <[email protected]>
Signed-off-by: Ravikiran Thirumalai <[email protected]>
Acked-by: Shai Fultheim <[email protected]>
---
arch/x86/kernel/vsmp_64.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index b93ed66..54202b1 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -87,6 +87,13 @@ void __init vsmp_init(void)
PCI_DEVICE_ID_SCALEMP_VSMP_CTL))
return;

+ /* If we are, use the distinguished irq functions */
+ pv_irq_ops.irq_disable = vsmp_irq_disable;
+ pv_irq_ops.irq_enable = vsmp_irq_enable;
+ pv_irq_ops.save_fl = vsmp_save_fl;
+ pv_irq_ops.restore_fl = vsmp_restore_fl;
+ pv_init_ops.patch = vsmp_patch;
+
/* set vSMP magic bits to indicate vSMP capable kernel */
cfg = read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0);
address = early_ioremap(cfg, 8);
--
1.4.2

2008-02-11 19:29:38

by Glauber Costa

[permalink] [raw]
Subject: [PATCH 3/5] [PATCH] call vsmp_init explicitly

It becomes to early for ioremap, so we use early_ioremap

Signed-off-by: Glauber Costa <[email protected]>
Signed-off-by: Ravikiran Thirumalai <[email protected]>
Acked-by: Shai Fultheim <[email protected]>
---
arch/x86/kernel/setup_64.c | 4 ++++
arch/x86/kernel/vsmp_64.c | 11 +++++------
include/asm-x86/setup.h | 4 ++++
3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index a49f5f7..6f5571c 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -346,6 +346,10 @@ #endif
if (efi_enabled)
efi_init();

+#ifdef CONFIG_PARAVIRT
+ vsmp_init();
+#endif
+
dmi_scan_machine();

io_delay_init();
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index 9766917..fdf9fba 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -16,10 +16,10 @@ #include <linux/pci_regs.h>
#include <asm/pci-direct.h>
#include <asm/io.h>

-static void __init vsmp_init(void)
+void __init vsmp_init(void)
{
void *address;
- unsigned int cap, ctl;
+ unsigned int cap, ctl, cfg;

if (!early_pci_allowed())
return;
@@ -32,7 +32,8 @@ static void __init vsmp_init(void)
return;

/* set vSMP magic bits to indicate vSMP capable kernel */
- address = ioremap(read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0), 8);
+ cfg = read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0);
+ address = early_ioremap(cfg, 8);
cap = readl(address);
ctl = readl(address + 4);
printk(KERN_INFO "vSMP CTL: capabilities:0x%08x control:0x%08x\n",
@@ -45,8 +46,6 @@ static void __init vsmp_init(void)
printk(KERN_INFO "vSMP CTL: control set to:0x%08x\n", ctl);
}

- iounmap(address);
+ early_iounmap(address, 8);
return;
}
-
-core_initcall(vsmp_init);
diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h
index 071e054..f745de2 100644
--- a/include/asm-x86/setup.h
+++ b/include/asm-x86/setup.h
@@ -4,6 +4,10 @@ #define _ASM_X86_SETUP_H
#define COMMAND_LINE_SIZE 2048

#ifndef __ASSEMBLY__
+
+/* Interrupt control for vSMPowered x86_64 systems */
+void vsmp_init(void);
+
char *machine_specific_memory_setup(void);
#ifndef CONFIG_PARAVIRT
#define paravirt_post_allocator_init() do {} while (0)
--
1.4.2

2008-02-11 19:29:59

by Glauber Costa

[permalink] [raw]
Subject: [PATCH 4/5] [PATCH] introduce paravirt helpers

Signed-off-by: Glauber Costa <[email protected]>
Signed-off-by: Ravikiran Thirumalai <[email protected]>
Acked-by: Shai Fultheim <[email protected]>
---
arch/x86/Kconfig | 3 ++
arch/x86/kernel/vsmp_64.c | 56 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+), 1 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9d0aced..0c4134b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -323,7 +323,8 @@ config X86_RDC321X
config X86_VSMP
bool "Support for ScaleMP vSMP"
depends on X86_64 && PCI
- help
+ select PARAVIRT
+ help
Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is
supposed to run on these EM64T-based machines. Only choose this option
if you have one of these machines.
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index fdf9fba..b93ed66 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -8,6 +8,8 @@
*
* Ravikiran Thirumalai <[email protected]>,
* Shai Fultheim <[email protected]>
+ * Paravirt ops integration: Glauber de Oliveira Costa <[email protected]>,
+ * Ravikiran Thirumalai <[email protected]>
*/

#include <linux/init.h>
@@ -15,6 +17,60 @@ #include <linux/pci_ids.h>
#include <linux/pci_regs.h>
#include <asm/pci-direct.h>
#include <asm/io.h>
+#include <asm/paravirt.h>
+
+/*
+ * Interrupt control on vSMPowered systems:
+ * ~AC is a shadow of IF. If IF is 'on' AC should be 'off'
+ * and vice versa.
+ */
+
+static unsigned long vsmp_save_fl(void)
+{
+ unsigned long flags = native_save_fl();
+
+ if (!(flags & X86_EFLAGS_IF) || (flags & X86_EFLAGS_AC))
+ flags &= ~X86_EFLAGS_IF;
+ return flags;
+}
+
+static void vsmp_restore_fl(unsigned long flags)
+{
+ if (flags & X86_EFLAGS_IF)
+ flags &= ~X86_EFLAGS_AC;
+ else
+ flags |= X86_EFLAGS_AC;
+ native_restore_fl(flags);
+}
+
+static void vsmp_irq_disable(void)
+{
+ unsigned long flags = native_save_fl();
+
+ native_restore_fl((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC);
+}
+
+static void vsmp_irq_enable(void)
+{
+ unsigned long flags = native_save_fl();
+
+ native_restore_fl((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC));
+}
+
+static unsigned __init vsmp_patch(u8 type, u16 clobbers, void *ibuf,
+ unsigned long addr, unsigned len)
+{
+ switch (type) {
+ case PARAVIRT_PATCH(pv_irq_ops.irq_enable):
+ case PARAVIRT_PATCH(pv_irq_ops.irq_disable):
+ case PARAVIRT_PATCH(pv_irq_ops.save_fl):
+ case PARAVIRT_PATCH(pv_irq_ops.restore_fl):
+ return paravirt_patch_default(type, clobbers, ibuf, addr, len);
+ default:
+ return native_patch(type, clobbers, ibuf, addr, len);
+ }
+
+}

void __init vsmp_init(void)
{
--
1.4.2

2008-02-11 19:30:31

by Glauber Costa

[permalink] [raw]
Subject: [PATCH 2/5] [PATCH] make vsmp_init void, instead of static int

Signed-off-by: Glauber Costa <[email protected]>
Signed-off-by: Ravikiran Thirumalai <[email protected]>
Acked-by: Shai Fultheim <[email protected]>
---
arch/x86/kernel/vsmp_64.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index d971210..9766917 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -16,20 +16,20 @@ #include <linux/pci_regs.h>
#include <asm/pci-direct.h>
#include <asm/io.h>

-static int __init vsmp_init(void)
+static void __init vsmp_init(void)
{
void *address;
unsigned int cap, ctl;

if (!early_pci_allowed())
- return 0;
+ return;

/* Check if we are running on a ScaleMP vSMP box */
if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) !=
PCI_VENDOR_ID_SCALEMP) ||
(read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) !=
PCI_DEVICE_ID_SCALEMP_VSMP_CTL))
- return 0;
+ return;

/* set vSMP magic bits to indicate vSMP capable kernel */
address = ioremap(read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0), 8);
@@ -46,7 +46,7 @@ static int __init vsmp_init(void)
}

iounmap(address);
- return 0;
+ return;
}

core_initcall(vsmp_init);
--
1.4.2

2008-02-17 18:05:36

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 3/5] [PATCH] call vsmp_init explicitly


* Glauber Costa <[email protected]> wrote:

> --- a/arch/x86/kernel/setup_64.c
> +++ b/arch/x86/kernel/setup_64.c
> @@ -346,6 +346,10 @@ #endif
> if (efi_enabled)
> efi_init();
>
> +#ifdef CONFIG_PARAVIRT
> + vsmp_init();
> +#endif

that #ifdef should be in setup.h, instead of polluting a .c file with
it.

Ingo

2008-02-17 18:06:19

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 4/5] [PATCH] introduce paravirt helpers


* Glauber Costa <[email protected]> wrote:

> config X86_VSMP
> bool "Support for ScaleMP vSMP"
> depends on X86_64 && PCI
> - help
> + select PARAVIRT
> + help

hm, what's the idea here?

Ingo

2008-02-17 20:57:14

by Glauber Costa

[permalink] [raw]
Subject: Re: [PATCH 4/5] [PATCH] introduce paravirt helpers

On Feb 17, 2008 4:05 PM, Ingo Molnar <[email protected]> wrote:
>
> * Glauber Costa <[email protected]> wrote:
>
> > config X86_VSMP
> > bool "Support for ScaleMP vSMP"
> > depends on X86_64 && PCI
> > - help
> > + select PARAVIRT
> > + help
>
> hm, what's the idea here?

guys from scalemp can probably give a better picture if needed,
but in a nutshell, there are two aspects involved with the vsmp
support. The first one
is special L1 alignments, and the second, specialized irq handling routines.

Only the second one is paravirt in itself, and are the ones addressed
in this patch.
The specialized routines now goes through paravirt ops. So when using
a vsmp machine,
paravirt has to be selected, in order to enable such functions.

--
Glauber Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."

2008-02-19 20:48:17

by Ravikiran Thirumalai

[permalink] [raw]
Subject: Re: [PATCH 4/5] [PATCH] introduce paravirt helpers

On Sun, Feb 17, 2008 at 06:56:56PM -0200, Glauber Costa wrote:
>On Feb 17, 2008 4:05 PM, Ingo Molnar <[email protected]> wrote:
>>
>> * Glauber Costa <[email protected]> wrote:
>>
>> > config X86_VSMP
>> > bool "Support for ScaleMP vSMP"
>> > depends on X86_64 && PCI
>> > - help
>> > + select PARAVIRT
>> > + help
>>
>> hm, what's the idea here?
>
>guys from scalemp can probably give a better picture if needed,
>but in a nutshell, there are two aspects involved with the vsmp
>support. The first one
>is special L1 alignments, and the second, specialized irq handling routines.
>
>Only the second one is paravirt in itself, and are the ones addressed
>in this patch.
>The specialized routines now goes through paravirt ops. So when using
>a vsmp machine,
>paravirt has to be selected, in order to enable such functions.

Thanks Glauber. Well put.

That said, future revs of vSMP will have the ability to work optimally even
without the paravirtualized irq ops. This is an upcoming feature, and did not
exist when we tested the paravirt ops 2-3 months ago. So, it will be
better, now, not to select PARAVIRT while selecting X86_VSMP. Then,
CONFIG_VSMP will just select the cacheline padding to be used and PARAVIRT
will be needed if irq operations need to be paravirtualized.

I shall submit a patch to that effect.

Thanks,
Kiran