* [PATCH 00/15] RFC: ia64/pv_ops take 4
@ 2008-04-09 4:48 Isaku Yamahata
2008-04-09 4:48 ` [PATCH 01/15] ia64: preparation: remove extern in irq_ia64.c Isaku Yamahata
` (16 more replies)
0 siblings, 17 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:48 UTC (permalink / raw)
To: linux-ia64
Hi. This patchset implements ia64/pv_ops support which is the
framework for virtualization support.
Please review and comments.
On x86 various ways to support virtualization were proposed, and
eventually pv_ops won. So on ia64 the pv_ops strategy is appropriate too.
Later I'll post the patchset which implements xen domU based on
ia64/pv_ops. Currently only ia64/xen pv_ops implementation exists,
but I believe ia64/kvm can also obtain benefits from this ia64/pv_ops
frame work.
Eddie Dong also has been working on ia64/pv_ops and posted a mail
requesting for suggestion/comments.
The corresponding patch is "[10/15] ia64/pv_ops: paravirtualize entry.S"
As discussed before, ivt.S was paravirtualized by single source and multi
compile way. But he thinks other way is appropriate for other hand
written assembly code. Which way is acceptable?
This patchset does the followings.
- some preparation work. Mainly make the kernel virtualization friendly.
- introduce pv_info which describes the execution environment.
- introduce macros for hand written assembly code to paravirtualize
hand written code to replace sensitive/privileged instructions.
- introduce various hooks to replace the implementation with
paravirtualized.
They are defined as function tables called, pv_init_ops, pv_cpu_ops,
pv_irq_ops, pv_iosapic_ops and, pv_time_ops.
They represent
pv_init_ops: hooks for various initialization.
pv_cpu_ops: hooks for ia64 intrinsics.
pv_irq_ops: hooks for irq related operations.
pv_iosapic_ops: hooks for paravirtualized iosapic.
pv_time_ops: hooks for steal time accounting
The working full source is available from
http://people.valinux.co.jp/~yamahata/xen-ia64/linux-2.6-xen-ia64.git/
branch: xen-ia64-2008apr08
At this phase, we don't address the following issues.
Those will be addressed after the first merge.
- optimization by binary patch
In fact, we had the patch to do that, but we intentionally dropped
for patch size/readability/cleanness.
- freeing the unused pages, i.e. pages for unused ivt.S.
Changes from take 3:
- split the patch set into pv_op part and xen domU part.
- many clean ups.
- introduced pv_ops: pv_cpu_ops and pv_time_ops.
Changes from take 2:
- many clean ups following to comments.
- clean up:assembly instruction macro.
- introduced pv_ops: pv_info, pv_init_ops, pv_iosapic_ops, pv_irq_ops.
Changes from take 1:
Single IVT source code. compile multitimes using assembler macros.
thanks,
Diffstat:
arch/ia64/kernel/Makefile | 11 +
arch/ia64/kernel/entry.S | 107 +++++++----
arch/ia64/kernel/iosapic.c | 45 +++--
arch/ia64/kernel/irq_ia64.c | 19 ++-
arch/ia64/kernel/ivt.S | 223 +++++++++++-----------
arch/ia64/kernel/minstate.h | 13 +-
arch/ia64/kernel/paravirt.c | 367 ++++++++++++++++++++++++++++++++++++
arch/ia64/kernel/paravirt_inst.h | 29 +++
arch/ia64/kernel/paravirtentry.S | 60 ++++++
arch/ia64/kernel/setup.c | 10 +
arch/ia64/kernel/smpboot.c | 2 +
arch/ia64/kernel/time.c | 23 +++
include/asm-ia64/Kbuild | 2 +-
include/asm-ia64/gcc_intrin.h | 24 ++--
include/asm-ia64/hw_irq.h | 23 ++-
include/asm-ia64/intel_intrin.h | 41 ++--
include/asm-ia64/intrinsics.h | 55 ++++++
include/asm-ia64/iosapic.h | 18 ++-
include/asm-ia64/irq.h | 10 +-
include/asm-ia64/mmu_context.h | 6 +-
include/asm-ia64/native/inst.h | 180 ++++++++++++++++++
include/asm-ia64/paravirt.h | 252 +++++++++++++++++++++++++
include/asm-ia64/paravirt_irq.h | 49 +++++
include/asm-ia64/paravirt_privop.h | 114 +++++++++++
include/asm-ia64/smp.h | 2 +
include/asm-ia64/system.h | 4 +-
26 files changed, 1464 insertions(+), 225 deletions(-)
^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH 01/15] ia64: preparation: remove extern in irq_ia64.c
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
@ 2008-04-09 4:48 ` Isaku Yamahata
2008-04-09 4:48 ` [PATCH 02/15] ia64/pv_ops: preparation: introduce ia64_set_rr0_to_rr4() to make kernel paravirtualization friendly Isaku Yamahata
` (15 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:48 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
remove extern declaration of handle_IPI() in irq_ia64.c.
Instead, declare it in asm-ia64/smp.h.
Later handle_IPI() will be referenced from another file.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/irq_ia64.c | 1 -
include/asm-ia64/smp.h | 2 ++
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index d8be23f..711635d 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -600,7 +600,6 @@ static irqreturn_t dummy_handler (int irq, void *dev_id)
{
BUG();
}
-extern irqreturn_t handle_IPI (int irq, void *dev_id);
static struct irqaction ipi_irqaction = {
.handler = handle_IPI,
diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h
index 4fa733d..0a8435f 100644
--- a/include/asm-ia64/smp.h
+++ b/include/asm-ia64/smp.h
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/cpumask.h>
#include <linux/bitops.h>
+#include <linux/irqreturn.h>
#include <asm/io.h>
#include <asm/param.h>
@@ -120,6 +121,7 @@ extern void __init smp_build_cpu_map(void);
extern void __init init_smp_config (void);
extern void smp_do_timer (struct pt_regs *regs);
+extern irqreturn_t handle_IPI(int irq, void *dev_id);
extern void smp_send_reschedule (int cpu);
extern void lock_ipi_calllock(void);
extern void unlock_ipi_calllock(void);
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 02/15] ia64/pv_ops: preparation: introduce ia64_set_rr0_to_rr4() to make kernel paravirtualization friendly.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
2008-04-09 4:48 ` [PATCH 01/15] ia64: preparation: remove extern in irq_ia64.c Isaku Yamahata
@ 2008-04-09 4:48 ` Isaku Yamahata
2008-04-09 4:48 ` [PATCH 03/15] ia64/pv_ops: preparation: introduce ia64_get_psr_i() " Isaku Yamahata
` (14 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:48 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
make kernel paravirtualization friendly by introducing
ia64_set_rr0_to_rr4().
ia64/Xen will replace setting rr[0-4] with single hypercall later.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
include/asm-ia64/intrinsics.h | 10 ++++++++++
include/asm-ia64/mmu_context.h | 6 +-----
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h
index f1135b5..72f0383 100644
--- a/include/asm-ia64/intrinsics.h
+++ b/include/asm-ia64/intrinsics.h
@@ -18,6 +18,15 @@
# include <asm/gcc_intrin.h>
#endif
+#define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \
+do { \
+ ia64_set_rr(0x0000000000000000UL, (val0)); \
+ ia64_set_rr(0x2000000000000000UL, (val1)); \
+ ia64_set_rr(0x4000000000000000UL, (val2)); \
+ ia64_set_rr(0x6000000000000000UL, (val3)); \
+ ia64_set_rr(0x8000000000000000UL, (val4)); \
+} while (0)
+
/*
* Force an unresolved reference if someone tries to use
* ia64_fetch_and_add() with a bad value.
@@ -183,4 +192,5 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void);
#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
#endif
+
#endif /* _ASM_IA64_INTRINSICS_H */
diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h
index cef2400..040bc87 100644
--- a/include/asm-ia64/mmu_context.h
+++ b/include/asm-ia64/mmu_context.h
@@ -152,11 +152,7 @@ reload_context (nv_mm_context_t context)
# endif
#endif
- ia64_set_rr(0x0000000000000000UL, rr0);
- ia64_set_rr(0x2000000000000000UL, rr1);
- ia64_set_rr(0x4000000000000000UL, rr2);
- ia64_set_rr(0x6000000000000000UL, rr3);
- ia64_set_rr(0x8000000000000000UL, rr4);
+ ia64_set_rr0_to_rr4(rr0, rr1, rr2, rr3, rr4);
ia64_srlz_i(); /* srlz.i implies srlz.d */
}
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 03/15] ia64/pv_ops: preparation: introduce ia64_get_psr_i() to make kernel paravirtualization friendly.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
2008-04-09 4:48 ` [PATCH 01/15] ia64: preparation: remove extern in irq_ia64.c Isaku Yamahata
2008-04-09 4:48 ` [PATCH 02/15] ia64/pv_ops: preparation: introduce ia64_set_rr0_to_rr4() to make kernel paravirtualization friendly Isaku Yamahata
@ 2008-04-09 4:48 ` Isaku Yamahata
2008-04-09 4:48 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Isaku Yamahata
` (13 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:48 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
__local_irq_save() and local_save_flags() are used to mask interruptions.
They read all psr bits that requres whole bit emulation.
On the other hand, reading only psr.i, the single bit, can be virtualized
cheaply.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
include/asm-ia64/intrinsics.h | 2 ++
include/asm-ia64/system.h | 4 ++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h
index 72f0383..aae6013 100644
--- a/include/asm-ia64/intrinsics.h
+++ b/include/asm-ia64/intrinsics.h
@@ -18,6 +18,8 @@
# include <asm/gcc_intrin.h>
#endif
+#define ia64_get_psr_i() (ia64_getreg(_IA64_REG_PSR) & IA64_PSR_I)
+
#define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \
do { \
ia64_set_rr(0x0000000000000000UL, (val0)); \
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 595112b..2bca73e 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -125,7 +125,7 @@ extern struct ia64_boot_param {
#define __local_irq_save(x) \
do { \
ia64_stop(); \
- (x) = ia64_getreg(_IA64_REG_PSR); \
+ (x) = ia64_get_psr_i(); \
ia64_stop(); \
ia64_rsm(IA64_PSR_I); \
} while (0)
@@ -173,7 +173,7 @@ do { \
#endif /* !CONFIG_IA64_DEBUG_IRQ */
#define local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
-#define local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); })
+#define local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_get_psr_i(); })
#define irqs_disabled() \
({ \
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
@ 2008-04-09 4:48 ` Isaku Yamahata
2008-04-22 9:16 ` Jes Sorensen
` (9 more replies)
0 siblings, 10 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:48 UTC (permalink / raw)
To: linux-ia64
introduce pv_info which describes some randome info about
underlying execution environment.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/Makefile | 2 +
arch/ia64/kernel/paravirt.c | 41 ++++++++++++++++++++++++++++
include/asm-ia64/paravirt.h | 62 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 105 insertions(+), 0 deletions(-)
create mode 100644 arch/ia64/kernel/paravirt.c
create mode 100644 include/asm-ia64/paravirt.h
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 33e5a59..40a10e7 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -36,6 +36,8 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
+obj-$(CONFIG_PARAVIRT) += paravirt.o
+
obj-$(CONFIG_IA64_ESI) += esi.o
ifneq ($(CONFIG_IA64_ESI),)
obj-y += esi_stub.o # must be in kernel proper
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
new file mode 100644
index 0000000..d295ea5
--- /dev/null
+++ b/arch/ia64/kernel/paravirt.c
@@ -0,0 +1,41 @@
+/******************************************************************************
+ * arch/ia64/kernel/paravirt.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ * Yaozu (Eddie) Dong <eddie.dong@intel.com>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+
+#include <linux/compiler.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/iosapic.h>
+#include <asm/paravirt.h>
+
+/***************************************************************************
+ * general info
+ */
+struct pv_info pv_info = {
+ .kernel_rpl = 0,
+ .paravirt_enabled = 0,
+ .name = "bare hardware"
+};
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h
new file mode 100644
index 0000000..26b4334
--- /dev/null
+++ b/include/asm-ia64/paravirt.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ * include/asm-ia64/paravirt.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#ifndef __ASM_PARAVIRT_H
+#define __ASM_PARAVIRT_H
+
+#ifdef CONFIG_PARAVIRT_GUEST
+
+#ifndef __ASSEMBLY__
+
+#include <asm/hw_irq.h>
+#include <asm/meminit.h>
+
+/******************************************************************************
+ * general info
+ */
+struct pv_info {
+ unsigned int kernel_rpl;
+ int paravirt_enabled;
+ const char *name;
+};
+
+extern struct pv_info pv_info;
+
+static inline int paravirt_enabled(void)
+{
+ return pv_info.paravirt_enabled;
+}
+
+static inline unsigned int get_kernel_rpl(void)
+{
+ return pv_info.kernel_rpl;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#else
+/* fallback for native case */
+
+#endif /* CONFIG_PARAVIRT_GUEST */
+
+#endif /* __ASM_PARAVIRT_H */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (2 preceding siblings ...)
2008-04-09 4:48 ` [PATCH 03/15] ia64/pv_ops: preparation: introduce ia64_get_psr_i() " Isaku Yamahata
@ 2008-04-09 4:48 ` Isaku Yamahata
2008-04-09 4:48 ` Isaku Yamahata
` (12 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:48 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
introduce pv_info which describes some randome info about
underlying execution environment.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/Makefile | 2 +
arch/ia64/kernel/paravirt.c | 41 ++++++++++++++++++++++++++++
include/asm-ia64/paravirt.h | 62 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 105 insertions(+), 0 deletions(-)
create mode 100644 arch/ia64/kernel/paravirt.c
create mode 100644 include/asm-ia64/paravirt.h
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 33e5a59..40a10e7 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -36,6 +36,8 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
+obj-$(CONFIG_PARAVIRT) += paravirt.o
+
obj-$(CONFIG_IA64_ESI) += esi.o
ifneq ($(CONFIG_IA64_ESI),)
obj-y += esi_stub.o # must be in kernel proper
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
new file mode 100644
index 0000000..d295ea5
--- /dev/null
+++ b/arch/ia64/kernel/paravirt.c
@@ -0,0 +1,41 @@
+/******************************************************************************
+ * arch/ia64/kernel/paravirt.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ * Yaozu (Eddie) Dong <eddie.dong@intel.com>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+
+#include <linux/compiler.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/iosapic.h>
+#include <asm/paravirt.h>
+
+/***************************************************************************
+ * general info
+ */
+struct pv_info pv_info = {
+ .kernel_rpl = 0,
+ .paravirt_enabled = 0,
+ .name = "bare hardware"
+};
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h
new file mode 100644
index 0000000..26b4334
--- /dev/null
+++ b/include/asm-ia64/paravirt.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ * include/asm-ia64/paravirt.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#ifndef __ASM_PARAVIRT_H
+#define __ASM_PARAVIRT_H
+
+#ifdef CONFIG_PARAVIRT_GUEST
+
+#ifndef __ASSEMBLY__
+
+#include <asm/hw_irq.h>
+#include <asm/meminit.h>
+
+/******************************************************************************
+ * general info
+ */
+struct pv_info {
+ unsigned int kernel_rpl;
+ int paravirt_enabled;
+ const char *name;
+};
+
+extern struct pv_info pv_info;
+
+static inline int paravirt_enabled(void)
+{
+ return pv_info.paravirt_enabled;
+}
+
+static inline unsigned int get_kernel_rpl(void)
+{
+ return pv_info.kernel_rpl;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#else
+/* fallback for native case */
+
+#endif /* CONFIG_PARAVIRT_GUEST */
+
+#endif /* __ASM_PARAVIRT_H */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 05/15] ia64/pv_ops: introduce pv_cpu_ops to paravirtualize privileged instructions.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (4 preceding siblings ...)
2008-04-09 4:48 ` Isaku Yamahata
@ 2008-04-09 4:48 ` Isaku Yamahata
2008-04-09 4:48 ` [PATCH 06/15] ia64/pv_ops: preparation for paravirtulization of hand written assembly code Isaku Yamahata
` (10 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:48 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
introduce pv_cpu_ops to paravirtualize privleged instructions
which are defined by ia64 intrinsics.
make them indirect C function calls by introducing function
tables, pv_cpu_ops.
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/paravirt.c | 245 ++++++++++++++++++++++++++++++++++++
include/asm-ia64/Kbuild | 2 +-
include/asm-ia64/gcc_intrin.h | 24 ++--
include/asm-ia64/intel_intrin.h | 41 +++---
include/asm-ia64/intrinsics.h | 61 ++++++++--
include/asm-ia64/paravirt_privop.h | 91 +++++++++++++
6 files changed, 422 insertions(+), 42 deletions(-)
create mode 100644 include/asm-ia64/paravirt_privop.h
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index d295ea5..bcfcb8b 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -39,3 +39,248 @@ struct pv_info pv_info = {
.paravirt_enabled = 0,
.name = "bare hardware"
};
+
+/***************************************************************************
+ * pv_cpu_ops
+ * intrinsics hooks.
+ */
+
+/* ia64_native_xxx are macros so that we have to make them real functions */
+
+#define DEFINE_VOID_FUNC1(name) \
+ static void \
+ ia64_native_ ## name ## _func(unsigned long arg) \
+ { \
+ ia64_native_ ## name(arg); \
+ } \
+
+#define DEFINE_VOID_FUNC2(name) \
+ static void \
+ ia64_native_ ## name ## _func(unsigned long arg0, \
+ unsigned long arg1) \
+ { \
+ ia64_native_ ## name(arg0, arg1); \
+ } \
+
+#define DEFINE_FUNC0(name) \
+ static unsigned long \
+ ia64_native_ ## name ## _func(void) \
+ { \
+ return ia64_native_ ## name(); \
+ }
+
+#define DEFINE_FUNC1(name, type) \
+ static unsigned long \
+ ia64_native_ ## name ## _func(type arg) \
+ { \
+ return ia64_native_ ## name(arg); \
+ } \
+
+DEFINE_VOID_FUNC1(fc);
+DEFINE_VOID_FUNC1(intrin_local_irq_restore);
+
+DEFINE_VOID_FUNC2(ptcga);
+DEFINE_VOID_FUNC2(set_rr);
+
+DEFINE_FUNC0(get_psr_i);
+
+DEFINE_FUNC1(thash, unsigned long);
+DEFINE_FUNC1(get_cpuid, int);
+DEFINE_FUNC1(get_pmd, int);
+DEFINE_FUNC1(get_rr, unsigned long);
+
+static void
+ia64_native_ssm_i_func(void)
+{
+ ia64_native_ssm(IA64_PSR_I);
+}
+
+static void
+ia64_native_rsm_i_func(void)
+{
+ ia64_native_rsm(IA64_PSR_I);
+}
+
+static void
+ia64_native_set_rr0_to_rr4_func(unsigned long val0, unsigned long val1,
+ unsigned long val2, unsigned long val3,
+ unsigned long val4)
+{
+ ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4);
+}
+
+#define CASE_GET_REG(id) \
+ case _IA64_REG_ ## id: \
+ res = ia64_native_getreg(_IA64_REG_ ## id); \
+ break;
+#define CASE_GET_AR(id) CASE_GET_REG(AR_ ## id)
+#define CASE_GET_CR(id) CASE_GET_REG(CR_ ## id)
+
+unsigned long
+ia64_native_getreg_func(int regnum)
+{
+ unsigned long res = -1;
+ switch (regnum) {
+ CASE_GET_REG(GP);
+ CASE_GET_REG(IP);
+ CASE_GET_REG(PSR);
+ CASE_GET_REG(TP);
+ CASE_GET_REG(SP);
+
+ CASE_GET_AR(KR0);
+ CASE_GET_AR(KR1);
+ CASE_GET_AR(KR2);
+ CASE_GET_AR(KR3);
+ CASE_GET_AR(KR4);
+ CASE_GET_AR(KR5);
+ CASE_GET_AR(KR6);
+ CASE_GET_AR(KR7);
+ CASE_GET_AR(RSC);
+ CASE_GET_AR(BSP);
+ CASE_GET_AR(BSPSTORE);
+ CASE_GET_AR(RNAT);
+ CASE_GET_AR(FCR);
+ CASE_GET_AR(EFLAG);
+ CASE_GET_AR(CSD);
+ CASE_GET_AR(SSD);
+ CASE_GET_AR(CFLAG);
+ CASE_GET_AR(FSR);
+ CASE_GET_AR(FIR);
+ CASE_GET_AR(FDR);
+ CASE_GET_AR(CCV);
+ CASE_GET_AR(UNAT);
+ CASE_GET_AR(FPSR);
+ CASE_GET_AR(ITC);
+ CASE_GET_AR(PFS);
+ CASE_GET_AR(LC);
+ CASE_GET_AR(EC);
+
+ CASE_GET_CR(DCR);
+ CASE_GET_CR(ITM);
+ CASE_GET_CR(IVA);
+ CASE_GET_CR(PTA);
+ CASE_GET_CR(IPSR);
+ CASE_GET_CR(ISR);
+ CASE_GET_CR(IIP);
+ CASE_GET_CR(IFA);
+ CASE_GET_CR(ITIR);
+ CASE_GET_CR(IIPA);
+ CASE_GET_CR(IFS);
+ CASE_GET_CR(IIM);
+ CASE_GET_CR(IHA);
+ CASE_GET_CR(LID);
+ CASE_GET_CR(IVR);
+ CASE_GET_CR(TPR);
+ CASE_GET_CR(EOI);
+ CASE_GET_CR(IRR0);
+ CASE_GET_CR(IRR1);
+ CASE_GET_CR(IRR2);
+ CASE_GET_CR(IRR3);
+ CASE_GET_CR(ITV);
+ CASE_GET_CR(PMV);
+ CASE_GET_CR(CMCV);
+ CASE_GET_CR(LRR0);
+ CASE_GET_CR(LRR1);
+
+ default:
+ printk(KERN_CRIT "wrong_getreg %d\n", regnum);
+ break;
+ }
+ return res;
+}
+
+#define CASE_SET_REG(id) \
+ case _IA64_REG_ ## id: \
+ ia64_native_setreg(_IA64_REG_ ## id, val); \
+ break;
+#define CASE_SET_AR(id) CASE_SET_REG(AR_ ## id)
+#define CASE_SET_CR(id) CASE_SET_REG(CR_ ## id)
+
+void
+ia64_native_setreg_func(int regnum, unsigned long val)
+{
+ switch (regnum) {
+ case _IA64_REG_PSR_L:
+ ia64_native_setreg(_IA64_REG_PSR_L, val);
+ ia64_dv_serialize_data();
+ break;
+ CASE_SET_REG(SP);
+ CASE_SET_REG(GP);
+
+ CASE_SET_AR(KR0);
+ CASE_SET_AR(KR1);
+ CASE_SET_AR(KR2);
+ CASE_SET_AR(KR3);
+ CASE_SET_AR(KR4);
+ CASE_SET_AR(KR5);
+ CASE_SET_AR(KR6);
+ CASE_SET_AR(KR7);
+ CASE_SET_AR(RSC);
+ CASE_SET_AR(BSP);
+ CASE_SET_AR(BSPSTORE);
+ CASE_SET_AR(RNAT);
+ CASE_SET_AR(FCR);
+ CASE_SET_AR(EFLAG);
+ CASE_SET_AR(CSD);
+ CASE_SET_AR(SSD);
+ CASE_SET_AR(CFLAG);
+ CASE_SET_AR(FSR);
+ CASE_SET_AR(FIR);
+ CASE_SET_AR(FDR);
+ CASE_SET_AR(CCV);
+ CASE_SET_AR(UNAT);
+ CASE_SET_AR(FPSR);
+ CASE_SET_AR(ITC);
+ CASE_SET_AR(PFS);
+ CASE_SET_AR(LC);
+ CASE_SET_AR(EC);
+
+ CASE_SET_CR(DCR);
+ CASE_SET_CR(ITM);
+ CASE_SET_CR(IVA);
+ CASE_SET_CR(PTA);
+ CASE_SET_CR(IPSR);
+ CASE_SET_CR(ISR);
+ CASE_SET_CR(IIP);
+ CASE_SET_CR(IFA);
+ CASE_SET_CR(ITIR);
+ CASE_SET_CR(IIPA);
+ CASE_SET_CR(IFS);
+ CASE_SET_CR(IIM);
+ CASE_SET_CR(IHA);
+ CASE_SET_CR(LID);
+ CASE_SET_CR(IVR);
+ CASE_SET_CR(TPR);
+ CASE_SET_CR(EOI);
+ CASE_SET_CR(IRR0);
+ CASE_SET_CR(IRR1);
+ CASE_SET_CR(IRR2);
+ CASE_SET_CR(IRR3);
+ CASE_SET_CR(ITV);
+ CASE_SET_CR(PMV);
+ CASE_SET_CR(CMCV);
+ CASE_SET_CR(LRR0);
+ CASE_SET_CR(LRR1);
+ default:
+ printk(KERN_CRIT "wrong setreg %d\n", regnum);
+ break;
+ }
+}
+
+struct pv_cpu_ops pv_cpu_ops = {
+ .fc = ia64_native_fc_func,
+ .thash = ia64_native_thash_func,
+ .get_cpuid = ia64_native_get_cpuid_func,
+ .get_pmd = ia64_native_get_pmd_func,
+ .ptcga = ia64_native_ptcga_func,
+ .get_rr = ia64_native_get_rr_func,
+ .set_rr = ia64_native_set_rr_func,
+ .set_rr0_to_rr4 = ia64_native_set_rr0_to_rr4_func,
+ .ssm_i = ia64_native_ssm_i_func,
+ .getreg = ia64_native_getreg_func,
+ .setreg = ia64_native_setreg_func,
+ .rsm_i = ia64_native_rsm_i_func,
+ .get_psr_i = ia64_native_get_psr_i_func,
+ .intrin_local_irq_restore
+ = ia64_native_intrin_local_irq_restore_func,
+};
diff --git a/include/asm-ia64/Kbuild b/include/asm-ia64/Kbuild
index eb24a3f..ccbe8ae 100644
--- a/include/asm-ia64/Kbuild
+++ b/include/asm-ia64/Kbuild
@@ -5,12 +5,12 @@ header-y += fpu.h
header-y += fpswa.h
header-y += ia64regs.h
header-y += intel_intrin.h
-header-y += intrinsics.h
header-y += perfmon_default_smpl.h
header-y += ptrace_offsets.h
header-y += rse.h
header-y += ucontext.h
unifdef-y += gcc_intrin.h
+unifdef-y += intrinsics.h
unifdef-y += perfmon.h
unifdef-y += ustack.h
diff --git a/include/asm-ia64/gcc_intrin.h b/include/asm-ia64/gcc_intrin.h
index de2ed2c..a065e89 100644
--- a/include/asm-ia64/gcc_intrin.h
+++ b/include/asm-ia64/gcc_intrin.h
@@ -28,7 +28,7 @@ extern void ia64_bad_param_for_getreg (void);
register unsigned long ia64_r13 asm ("r13") __used;
#endif
-#define ia64_setreg(regnum, val) \
+#define ia64_native_setreg(regnum, val) \
({ \
switch (regnum) { \
case _IA64_REG_PSR_L: \
@@ -57,7 +57,7 @@ register unsigned long ia64_r13 asm ("r13") __used;
} \
})
-#define ia64_getreg(regnum) \
+#define ia64_native_getreg(regnum) \
({ \
__u64 ia64_intri_res; \
\
@@ -381,7 +381,7 @@ register unsigned long ia64_r13 asm ("r13") __used;
#define ia64_invala() asm volatile ("invala" ::: "memory")
-#define ia64_thash(addr) \
+#define ia64_native_thash(addr) \
({ \
__u64 ia64_intri_res; \
asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
@@ -434,10 +434,10 @@ register unsigned long ia64_r13 asm ("r13") __used;
#define ia64_set_pmd(index, val) \
asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
-#define ia64_set_rr(index, val) \
+#define ia64_native_set_rr(index, val) \
asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
-#define ia64_get_cpuid(index) \
+#define ia64_native_get_cpuid(index) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index)); \
@@ -473,33 +473,33 @@ register unsigned long ia64_r13 asm ("r13") __used;
})
-#define ia64_get_pmd(index) \
+#define ia64_native_get_pmd(index) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
ia64_intri_res; \
})
-#define ia64_get_rr(index) \
+#define ia64_native_get_rr(index) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index)); \
ia64_intri_res; \
})
-#define ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
+#define ia64_native_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
-#define ia64_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory")
-#define ia64_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory")
+#define ia64_native_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory")
+#define ia64_native_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory")
#define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory")
#define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory")
#define ia64_ptce(addr) asm volatile ("ptc.e %0" :: "r"(addr))
-#define ia64_ptcga(addr, size) \
+#define ia64_native_ptcga(addr, size) \
do { \
asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory"); \
ia64_dv_serialize_data(); \
@@ -596,7 +596,7 @@ do { \
} \
})
-#define ia64_intrin_local_irq_restore(x) \
+#define ia64_native_intrin_local_irq_restore(x) \
do { \
asm volatile (";; cmp.ne p6,p7=%0,r0;;" \
"(p6) ssm psr.i;" \
diff --git a/include/asm-ia64/intel_intrin.h b/include/asm-ia64/intel_intrin.h
index a520d10..53cec57 100644
--- a/include/asm-ia64/intel_intrin.h
+++ b/include/asm-ia64/intel_intrin.h
@@ -16,8 +16,8 @@
* intrinsic
*/
-#define ia64_getreg __getReg
-#define ia64_setreg __setReg
+#define ia64_native_getreg __getReg
+#define ia64_native_setreg __setReg
#define ia64_hint __hint
#define ia64_hint_pause __hint_pause
@@ -39,10 +39,10 @@
#define ia64_invala_fr __invala_fr
#define ia64_nop __nop
#define ia64_sum __sum
-#define ia64_ssm __ssm
+#define ia64_native_ssm __ssm
#define ia64_rum __rum
-#define ia64_rsm __rsm
-#define ia64_fc __fc
+#define ia64_native_rsm __rsm
+#define ia64_native_fc __fc
#define ia64_ldfs __ldfs
#define ia64_ldfd __ldfd
@@ -88,16 +88,17 @@
__setIndReg(_IA64_REG_INDR_PMC, index, val)
#define ia64_set_pmd(index, val) \
__setIndReg(_IA64_REG_INDR_PMD, index, val)
-#define ia64_set_rr(index, val) \
+#define ia64_native_set_rr(index, val) \
__setIndReg(_IA64_REG_INDR_RR, index, val)
-#define ia64_get_cpuid(index) __getIndReg(_IA64_REG_INDR_CPUID, index)
-#define __ia64_get_dbr(index) __getIndReg(_IA64_REG_INDR_DBR, index)
-#define ia64_get_ibr(index) __getIndReg(_IA64_REG_INDR_IBR, index)
-#define ia64_get_pkr(index) __getIndReg(_IA64_REG_INDR_PKR, index)
-#define ia64_get_pmc(index) __getIndReg(_IA64_REG_INDR_PMC, index)
-#define ia64_get_pmd(index) __getIndReg(_IA64_REG_INDR_PMD, index)
-#define ia64_get_rr(index) __getIndReg(_IA64_REG_INDR_RR, index)
+#define ia64_native_get_cpuid(index) \
+ __getIndReg(_IA64_REG_INDR_CPUID, index)
+#define __ia64_get_dbr(index) __getIndReg(_IA64_REG_INDR_DBR, index)
+#define ia64_get_ibr(index) __getIndReg(_IA64_REG_INDR_IBR, index)
+#define ia64_get_pkr(index) __getIndReg(_IA64_REG_INDR_PKR, index)
+#define ia64_get_pmc(index) __getIndReg(_IA64_REG_INDR_PMC, index)
+#define ia64_native_get_pmd(index) __getIndReg(_IA64_REG_INDR_PMD, index)
+#define ia64_native_get_rr(index) __getIndReg(_IA64_REG_INDR_RR, index)
#define ia64_srlz_d __dsrlz
#define ia64_srlz_i __isrlz
@@ -119,16 +120,16 @@
#define ia64_ld8_acq __ld8_acq
#define ia64_sync_i __synci
-#define ia64_thash __thash
-#define ia64_ttag __ttag
+#define ia64_native_thash __thash
+#define ia64_native_ttag __ttag
#define ia64_itcd __itcd
#define ia64_itci __itci
#define ia64_itrd __itrd
#define ia64_itri __itri
#define ia64_ptce __ptce
#define ia64_ptcl __ptcl
-#define ia64_ptcg __ptcg
-#define ia64_ptcga __ptcga
+#define ia64_native_ptcg __ptcg
+#define ia64_native_ptcga __ptcga
#define ia64_ptri __ptri
#define ia64_ptrd __ptrd
#define ia64_dep_mi _m64_dep_mi
@@ -145,13 +146,13 @@
#define ia64_lfetch_fault __lfetch_fault
#define ia64_lfetch_fault_excl __lfetch_fault_excl
-#define ia64_intrin_local_irq_restore(x) \
+#define ia64_native_intrin_local_irq_restore(x) \
do { \
if ((x) != 0) { \
- ia64_ssm(IA64_PSR_I); \
+ ia64_native_ssm(IA64_PSR_I); \
ia64_srlz_d(); \
} else { \
- ia64_rsm(IA64_PSR_I); \
+ ia64_native_rsm(IA64_PSR_I); \
} \
} while (0)
diff --git a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h
index aae6013..47d686d 100644
--- a/include/asm-ia64/intrinsics.h
+++ b/include/asm-ia64/intrinsics.h
@@ -18,15 +18,15 @@
# include <asm/gcc_intrin.h>
#endif
-#define ia64_get_psr_i() (ia64_getreg(_IA64_REG_PSR) & IA64_PSR_I)
-
-#define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \
-do { \
- ia64_set_rr(0x0000000000000000UL, (val0)); \
- ia64_set_rr(0x2000000000000000UL, (val1)); \
- ia64_set_rr(0x4000000000000000UL, (val2)); \
- ia64_set_rr(0x6000000000000000UL, (val3)); \
- ia64_set_rr(0x8000000000000000UL, (val4)); \
+#define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
+
+#define ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4) \
+do { \
+ ia64_native_set_rr(0x0000000000000000UL, (val0)); \
+ ia64_native_set_rr(0x2000000000000000UL, (val1)); \
+ ia64_native_set_rr(0x4000000000000000UL, (val2)); \
+ ia64_native_set_rr(0x6000000000000000UL, (val3)); \
+ ia64_native_set_rr(0x8000000000000000UL, (val4)); \
} while (0)
/*
@@ -195,4 +195,47 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void);
#endif
+#ifdef __KERNEL__
+#include <asm/paravirt_privop.h>
+#endif
+
+#ifndef __ASSEMBLY__
+#if defined(CONFIG_PARAVIRT) && defined(__KERNEL__)
+#define IA64_INTRINSIC_API(name) pv_cpu_ops.name
+#define IA64_INTRINSIC_MACRO(name) paravirt_ ## name
+#else
+#define IA64_INTRINSIC_API(name) ia64_native_ ## name
+#define IA64_INTRINSIC_MACRO(name) ia64_native_ ## name
+#endif
+
+/************************************************/
+/* Instructions paravirtualized for correctness */
+/************************************************/
+/* fc, thash, get_cpuid, get_pmd, get_eflags, set_eflags */
+/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
+ * is not currently used (though it may be in a long-format VHPT system!)
+ */
+#define ia64_fc IA64_INTRINSIC_API(fc)
+#define ia64_thash IA64_INTRINSIC_API(thash)
+#define ia64_get_cpuid IA64_INTRINSIC_API(get_cpuid)
+#define ia64_get_pmd IA64_INTRINSIC_API(get_pmd)
+
+
+/************************************************/
+/* Instructions paravirtualized for performance */
+/************************************************/
+#define ia64_ssm IA64_INTRINSIC_MACRO(ssm)
+#define ia64_rsm IA64_INTRINSIC_MACRO(rsm)
+#define ia64_getreg IA64_INTRINSIC_API(getreg)
+#define ia64_setreg IA64_INTRINSIC_API(setreg)
+#define ia64_set_rr IA64_INTRINSIC_API(set_rr)
+#define ia64_get_rr IA64_INTRINSIC_API(get_rr)
+#define ia64_ptcga IA64_INTRINSIC_API(ptcga)
+#define ia64_get_psr_i IA64_INTRINSIC_API(get_psr_i)
+#define ia64_intrin_local_irq_restore \
+ IA64_INTRINSIC_API(intrin_local_irq_restore)
+#define ia64_set_rr0_to_rr4 IA64_INTRINSIC_API(set_rr0_to_rr4)
+
+#endif /* !__ASSEMBLY__ */
+
#endif /* _ASM_IA64_INTRINSICS_H */
diff --git a/include/asm-ia64/paravirt_privop.h b/include/asm-ia64/paravirt_privop.h
new file mode 100644
index 0000000..7b133ae
--- /dev/null
+++ b/include/asm-ia64/paravirt_privop.h
@@ -0,0 +1,91 @@
+/******************************************************************************
+ * include/asm-ia64/paravirt_privops.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _ASM_IA64_PARAVIRT_PRIVOP_H
+#define _ASM_IA64_PARAVIRT_PRIVOP_H
+
+#ifdef CONFIG_PARAVIRT
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm/kregs.h> /* for IA64_PSR_I */
+
+/******************************************************************************
+ * replacement of intrinsics operations.
+ */
+
+struct pv_cpu_ops {
+ void (*fc)(unsigned long addr);
+ unsigned long (*thash)(unsigned long addr);
+ unsigned long (*get_cpuid)(int index);
+ unsigned long (*get_pmd)(int index);
+ unsigned long (*getreg)(int reg);
+ void (*setreg)(int reg, unsigned long val);
+ void (*ptcga)(unsigned long addr, unsigned long size);
+ unsigned long (*get_rr)(unsigned long index);
+ void (*set_rr)(unsigned long index, unsigned long val);
+ void (*set_rr0_to_rr4)(unsigned long val0, unsigned long val1,
+ unsigned long val2, unsigned long val3,
+ unsigned long val4);
+ void (*ssm_i)(void);
+ void (*rsm_i)(void);
+ unsigned long (*get_psr_i)(void);
+ void (*intrin_local_irq_restore)(unsigned long flags);
+};
+
+extern struct pv_cpu_ops pv_cpu_ops;
+
+extern void ia64_native_setreg_func(int regnum, unsigned long val);
+extern unsigned long ia64_native_getreg_func(int regnum);
+
+/************************************************/
+/* Instructions paravirtualized for performance */
+/************************************************/
+
+/* mask for ia64_native_ssm/rsm() must be constant.("i" constraing).
+ * static inline function doesn't satisfy it. */
+#define paravirt_ssm(mask) \
+ do { \
+ if ((mask) == IA64_PSR_I) \
+ pv_cpu_ops.ssm_i(); \
+ else \
+ ia64_native_ssm(mask); \
+ } while (0)
+
+#define paravirt_rsm(mask) \
+ do { \
+ if ((mask) == IA64_PSR_I) \
+ pv_cpu_ops.rsm_i(); \
+ else \
+ ia64_native_rsm(mask); \
+ } while (0)
+
+#endif /* __ASSEMBLY__ */
+
+#else
+
+/* fallback for native case */
+
+#endif /* CONFIG_PARAVIRT */
+
+#endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 06/15] ia64/pv_ops: preparation for paravirtulization of hand written assembly code.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (5 preceding siblings ...)
2008-04-09 4:48 ` [PATCH 05/15] ia64/pv_ops: introduce pv_cpu_ops to paravirtualize privileged instructions Isaku Yamahata
@ 2008-04-09 4:48 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 07/15] ia64/pv_ops: define paravirtualized instructions for native Isaku Yamahata
` (9 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:48 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
Preparation for paravirtualization of hand written assembly code.
They are paravirtualized by single source code and compiled multi times.
To tell those files for target (including native), add one defines.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/Makefile | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 40a10e7..a462669 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -72,3 +72,12 @@ $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
# We must build gate.so before we can assemble it.
# Note: kbuild does not track this dependency due to usage of .incbin
$(obj)/gate-data.o: $(obj)/gate.so
+
+#
+# native ivt.S and entry.S
+#
+ASM_PARAVIRT_OBJS = ivt.o entry.o
+define paravirtualized_native
+AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
+endef
+$(foreach obj,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_native,$(obj))))
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 07/15] ia64/pv_ops: define paravirtualized instructions for native.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (6 preceding siblings ...)
2008-04-09 4:48 ` [PATCH 06/15] ia64/pv_ops: preparation for paravirtulization of hand written assembly code Isaku Yamahata
@ 2008-04-09 4:49 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 08/15] ia64/pv_ops: paravirtualize minstate.h Isaku Yamahata
` (8 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
pv_cpu_asm_ops: define paravirtualized introduce for native execution
environment.
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
include/asm-ia64/native/inst.h | 170 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 170 insertions(+), 0 deletions(-)
create mode 100644 include/asm-ia64/native/inst.h
diff --git a/include/asm-ia64/native/inst.h b/include/asm-ia64/native/inst.h
new file mode 100644
index 0000000..295fde3
--- /dev/null
+++ b/include/asm-ia64/native/inst.h
@@ -0,0 +1,170 @@
+/******************************************************************************
+ * include/asm-ia64/native/inst.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK
+# define PARAVIRT_POISON 0xdeadbeefbaadf00d
+# define CLOBBER(clob) \
+ ;; \
+ movl clob = PARAVIRT_POISON; \
+ ;;
+#else
+# define CLOBBER(clob) /* nothing */
+#endif
+
+#define MOV_FROM_IFA(reg) \
+ mov reg = cr.ifa
+
+#define MOV_FROM_ITIR(reg) \
+ mov reg = cr.itir
+
+#define MOV_FROM_ISR(reg) \
+ mov reg = cr.isr
+
+#define MOV_FROM_IHA(reg) \
+ mov reg = cr.iha
+
+#define MOV_FROM_IPSR(pred, reg) \
+(pred) mov reg = cr.ipsr
+
+#define MOV_FROM_IIM(reg) \
+ mov reg = cr.iim
+
+#define MOV_FROM_IIP(reg) \
+ mov reg = cr.iip
+
+#define MOV_FROM_IVR(reg, clob) \
+ mov reg = cr.ivr \
+ CLOBBER(clob)
+
+#define MOV_FROM_PSR(pred, reg, clob) \
+(pred) mov reg = psr \
+ CLOBBER(clob)
+
+#define MOV_TO_IFA(reg, clob) \
+ mov cr.ifa = reg \
+ CLOBBER(clob)
+
+#define MOV_TO_ITIR(pred, reg, clob) \
+(pred) mov cr.itir = reg \
+ CLOBBER(clob)
+
+#define MOV_TO_IHA(pred, reg, clob) \
+(pred) mov cr.iha = reg \
+ CLOBBER(clob)
+
+#define MOV_TO_IPSR(reg, clob) \
+ mov cr.ipsr = reg \
+ CLOBBER(clob)
+
+#define MOV_TO_IFS(pred, reg, clob) \
+(pred) mov cr.ifs = reg \
+ CLOBBER(clob)
+
+#define MOV_TO_IIP(reg, clob) \
+ mov cr.iip = reg \
+ CLOBBER(clob)
+
+#define MOV_TO_KR(kr, reg, clob0, clob1) \
+ mov IA64_KR(kr) = reg \
+ CLOBBER(clob0) \
+ CLOBBER(clob1)
+
+#define ITC_I(pred, reg, clob) \
+(pred) itc.i reg \
+ CLOBBER(clob)
+
+#define ITC_D(pred, reg, clob) \
+(pred) itc.d reg \
+ CLOBBER(clob)
+
+#define ITC_I_AND_D(pred_i, pred_d, reg, clob) \
+(pred_i) itc.i reg; \
+(pred_d) itc.d reg \
+ CLOBBER(clob)
+
+#define THASH(pred, reg0, reg1, clob) \
+(pred) thash reg0 = reg1 \
+ CLOBBER(clob)
+
+#define SSM_PSR_IC_AND_DEFAULT_BITS(clob0, clob1) \
+ ssm psr.ic | PSR_DEFAULT_BITS \
+ CLOBBER(clob0) \
+ CLOBBER(clob1) \
+ ;; \
+ srlz.i /* guarantee that interruption collectin is on */ \
+ ;;
+
+#define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1) \
+ ssm psr.ic \
+ CLOBBER(clob0) \
+ CLOBBER(clob1) \
+ ;; \
+ srlz.d
+
+#define RSM_PSR_IC(clob) \
+ rsm psr.ic \
+ CLOBBER(clob)
+
+#define SSM_PSR_I(pred, clob) \
+(pred) ssm psr.i \
+ CLOBBER(clob)
+
+#define RSM_PSR_I(pred, clob0, clob1) \
+(pred) rsm psr.i \
+ CLOBBER(clob0) \
+ CLOBBER(clob1)
+
+#define RSM_PSR_I_IC(clob0, clob1, clob2) \
+ rsm psr.i | psr.ic \
+ CLOBBER(clob0) \
+ CLOBBER(clob1) \
+ CLOBBER(clob2)
+
+#define RSM_PSR_DT \
+ rsm psr.dt
+
+#define RSM_PSR_DT_AND_SRLZ_I \
+ rsm psr.dt \
+ ;; \
+ srlz.i
+
+#define SSM_PSR_DT_AND_SRLZ_I \
+ ssm psr.dt \
+ ;; \
+ srlz.i
+
+#define BSW_0(clob0, clob1, clob2) \
+ bsw.0 \
+ CLOBBER(clob0) \
+ CLOBBER(clob1) \
+ CLOBBER(clob2)
+
+#define BSW_1(clob0, clob1) \
+ bsw.1 \
+ CLOBBER(clob0) \
+ CLOBBER(clob1)
+
+#define COVER \
+ cover
+
+#define RFI \
+ rfi
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 08/15] ia64/pv_ops: paravirtualize minstate.h.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (7 preceding siblings ...)
2008-04-09 4:49 ` [PATCH 07/15] ia64/pv_ops: define paravirtualized instructions for native Isaku Yamahata
@ 2008-04-09 4:49 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 09/15] ia64/pv_ops: paravirtualize ivt.S Isaku Yamahata
` (7 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
paravirtualize minstate.h which are hand written assembly code.
They include sensitive or performance critical privileged
instructions. So that they are appropriate for paravirtualization.
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/minstate.h | 13 +++++++------
arch/ia64/kernel/paravirt_inst.h | 29 +++++++++++++++++++++++++++++
include/asm-ia64/native/inst.h | 2 ++
3 files changed, 38 insertions(+), 6 deletions(-)
create mode 100644 arch/ia64/kernel/paravirt_inst.h
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
index c9ac8ba..f00ca70 100644
--- a/arch/ia64/kernel/minstate.h
+++ b/arch/ia64/kernel/minstate.h
@@ -2,6 +2,7 @@
#include <asm/cache.h>
#include "entry.h"
+#include "paravirt_inst.h"
/*
* DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
@@ -28,16 +29,16 @@
* Note that psr.ic is NOT turned on by this macro. This is so that
* we can pass interruption state as arguments to a handler.
*/
-#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA) \
+#define IA64_NATIVE_DO_SAVE_MIN(__COVER,SAVE_IFS,EXTRA) \
mov r16=IA64_KR(CURRENT); /* M */ \
mov r27=ar.rsc; /* M */ \
mov r20=r1; /* A */ \
mov r25=ar.unat; /* M */ \
- mov r29=cr.ipsr; /* M */ \
+ MOV_FROM_IPSR(p0,r29); /* M */ \
mov r26=ar.pfs; /* I */ \
- mov r28=cr.iip; /* M */ \
+ MOV_FROM_IIP(r28); /* M */ \
mov r21=ar.fpsr; /* M */ \
- COVER; /* B;; (or nothing) */ \
+ __COVER; /* B;; (or nothing) */ \
;; \
adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16; \
;; \
@@ -192,6 +193,6 @@
st8 [r25]=r10; /* ar.ssd */ \
;;
-#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover, mov r30=cr.ifs,)
-#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19)
+#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(COVER, mov r30=cr.ifs,)
+#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(COVER, mov r30=cr.ifs, mov r15=r19)
#define SAVE_MIN DO_SAVE_MIN( , mov r30=r0, )
diff --git a/arch/ia64/kernel/paravirt_inst.h b/arch/ia64/kernel/paravirt_inst.h
new file mode 100644
index 0000000..5cad6fb
--- /dev/null
+++ b/arch/ia64/kernel/paravirt_inst.h
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * linux/arch/ia64/xen/paravirt_inst.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef __IA64_ASM_PARAVIRTUALIZED_XEN
+#include <asm/xen/inst.h>
+#include <asm/xen/minstate.h>
+#else
+#include <asm/native/inst.h>
+#endif
+
diff --git a/include/asm-ia64/native/inst.h b/include/asm-ia64/native/inst.h
index 295fde3..c167b7d 100644
--- a/include/asm-ia64/native/inst.h
+++ b/include/asm-ia64/native/inst.h
@@ -20,6 +20,8 @@
*
*/
+#define DO_SAVE_MIN IA64_NATIVE_DO_SAVE_MIN
+
#ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK
# define PARAVIRT_POISON 0xdeadbeefbaadf00d
# define CLOBBER(clob) \
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 09/15] ia64/pv_ops: paravirtualize ivt.S
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (8 preceding siblings ...)
2008-04-09 4:49 ` [PATCH 08/15] ia64/pv_ops: paravirtualize minstate.h Isaku Yamahata
@ 2008-04-09 4:49 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 10/15] ia64/pv_ops: paravirtualize entry.S Isaku Yamahata
` (6 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
paravirtualize ivt.S which implements fault handler in hand written
assembly code.
They includes sensitive or performance critical privileged instructions.
So they need paravirtualization.
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/ivt.S | 223 ++++++++++++++++++++++++------------------------
1 files changed, 113 insertions(+), 110 deletions(-)
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index 34f44d8..d516bf4 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -12,6 +12,14 @@
*
* 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP
* 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT.
+ *
+ * Copyright (C) 2005 Hewlett-Packard Co
+ * Dan Magenheimer <dan.magenheimer@hp.com>
+ * Xen paravirtualization
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ * pv_ops.
+ * Yaozu (Eddie) Dong <eddie.dong@intel.com>
*/
/*
* This file defines the interruption vector table used by the CPU.
@@ -102,13 +110,13 @@ ENTRY(vhpt_miss)
* - the faulting virtual address uses unimplemented address bits
* - the faulting virtual address has no valid page table mapping
*/
- mov r16=cr.ifa // get address that caused the TLB miss
+ MOV_FROM_IFA(r16) // get address that caused the TLB miss
#ifdef CONFIG_HUGETLB_PAGE
movl r18=PAGE_SHIFT
- mov r25=cr.itir
+ MOV_FROM_ITIR(r25)
#endif
;;
- rsm psr.dt // use physical addressing for data
+ RSM_PSR_DT // use physical addressing for data
mov r31=pr // save the predicate registers
mov r19=IA64_KR(PT_BASE) // get page table base address
shl r21=r16,3 // shift bit 60 into sign bit
@@ -168,21 +176,20 @@ ENTRY(vhpt_miss)
dep r21=r19,r20,3,(PAGE_SHIFT-3) // r21=pte_offset(pmd,addr)
;;
(p7) ld8 r18=[r21] // read *pte
- mov r19=cr.isr // cr.isr bit 32 tells us if this is an insn miss
+ MOV_FROM_ISR(r19) // cr.isr bit 32 tells us if this is an insn miss
;;
(p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared?
- mov r22=cr.iha // get the VHPT address that caused the TLB miss
+ MOV_FROM_IHA(r22) // get the VHPT address that caused the TLB miss
;; // avoid RAW on p7
(p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss?
dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address
;;
-(p10) itc.i r18 // insert the instruction TLB entry
-(p11) itc.d r18 // insert the data TLB entry
+ ITC_I_AND_D(p10, p11, r18, r24) // insert the instruction TLB entry and
+ // insert the data TLB entry
(p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault)
- mov cr.ifa=r22
-
+ MOV_TO_IFA(r22, r24)
#ifdef CONFIG_HUGETLB_PAGE
-(p8) mov cr.itir=r25 // change to default page-size for VHPT
+ MOV_TO_ITIR(p8, r25, r24) // change to default page-size for VHPT
#endif
/*
@@ -192,7 +199,7 @@ ENTRY(vhpt_miss)
*/
adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
;;
-(p7) itc.d r24
+ ITC_D(p7, r24, r25)
;;
#ifdef CONFIG_SMP
/*
@@ -234,7 +241,7 @@ ENTRY(vhpt_miss)
#endif
mov pr=r31,-1 // restore predicate registers
- rfi
+ RFI
END(vhpt_miss)
.org ia64_ivt+0x400
@@ -248,11 +255,11 @@ ENTRY(itlb_miss)
* mode, walk the page table, and then re-execute the PTE read and
* go on normally after that.
*/
- mov r16=cr.ifa // get virtual address
+ MOV_FROM_IFA(r16) // get virtual address
mov r29=b0 // save b0
mov r31=pr // save predicates
.itlb_fault:
- mov r17=cr.iha // get virtual address of PTE
+ MOV_FROM_IHA(r17) // get virtual address of PTE
movl r30=1f // load nested fault continuation point
;;
1: ld8 r18=[r17] // read *pte
@@ -261,7 +268,7 @@ ENTRY(itlb_miss)
tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
(p6) br.cond.spnt page_fault
;;
- itc.i r18
+ ITC_I(p0, r18, r19)
;;
#ifdef CONFIG_SMP
/*
@@ -278,7 +285,7 @@ ENTRY(itlb_miss)
(p7) ptc.l r16,r20
#endif
mov pr=r31,-1
- rfi
+ RFI
END(itlb_miss)
.org ia64_ivt+0x0800
@@ -292,11 +299,11 @@ ENTRY(dtlb_miss)
* mode, walk the page table, and then re-execute the PTE read and
* go on normally after that.
*/
- mov r16=cr.ifa // get virtual address
+ MOV_FROM_IFA(r16) // get virtual address
mov r29=b0 // save b0
mov r31=pr // save predicates
dtlb_fault:
- mov r17=cr.iha // get virtual address of PTE
+ MOV_FROM_IHA(r17) // get virtual address of PTE
movl r30=1f // load nested fault continuation point
;;
1: ld8 r18=[r17] // read *pte
@@ -305,7 +312,7 @@ dtlb_fault:
tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
(p6) br.cond.spnt page_fault
;;
- itc.d r18
+ ITC_D(p0, r18, r19)
;;
#ifdef CONFIG_SMP
/*
@@ -322,7 +329,7 @@ dtlb_fault:
(p7) ptc.l r16,r20
#endif
mov pr=r31,-1
- rfi
+ RFI
END(dtlb_miss)
.org ia64_ivt+0x0c00
@@ -330,9 +337,9 @@ END(dtlb_miss)
// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
ENTRY(alt_itlb_miss)
DBG_FAULT(3)
- mov r16=cr.ifa // get address that caused the TLB miss
+ MOV_FROM_IFA(r16) // get address that caused the TLB miss
movl r17=PAGE_KERNEL
- mov r21=cr.ipsr
+ MOV_FROM_IPSR(p0,r21)
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
mov r31=pr
;;
@@ -341,9 +348,9 @@ ENTRY(alt_itlb_miss)
;;
cmp.gt p8,p0=6,r22 // user mode
;;
-(p8) thash r17=r16
+ THASH(p8, r17, r16, r23)
;;
-(p8) mov cr.iha=r17
+ MOV_TO_IHA(p8, r17, r23)
(p8) mov r29=b0 // save b0
(p8) br.cond.dptk .itlb_fault
#endif
@@ -358,9 +365,9 @@ ENTRY(alt_itlb_miss)
or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6
(p8) br.cond.spnt page_fault
;;
- itc.i r19 // insert the TLB entry
+ ITC_I(p0, r19, r18) // insert the TLB entry
mov pr=r31,-1
- rfi
+ RFI
END(alt_itlb_miss)
.org ia64_ivt+0x1000
@@ -368,11 +375,11 @@ END(alt_itlb_miss)
// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
ENTRY(alt_dtlb_miss)
DBG_FAULT(4)
- mov r16=cr.ifa // get address that caused the TLB miss
+ MOV_FROM_IFA(r16) // get address that caused the TLB miss
movl r17=PAGE_KERNEL
- mov r20=cr.isr
+ MOV_FROM_ISR(r20)
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
- mov r21=cr.ipsr
+ MOV_FROM_IPSR(p0,r21)
mov r31=pr
mov r24=PERCPU_ADDR
;;
@@ -381,9 +388,9 @@ ENTRY(alt_dtlb_miss)
;;
cmp.gt p8,p0=6,r22 // access to region 0-5
;;
-(p8) thash r17=r16
+ THASH(p8, r17, r16, r25)
;;
-(p8) mov cr.iha=r17
+ MOV_TO_IHA(r17, r25)
(p8) mov r29=b0 // save b0
(p8) br.cond.dptk dtlb_fault
#endif
@@ -402,7 +409,7 @@ ENTRY(alt_dtlb_miss)
tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on?
;;
(p10) sub r19=r19,r26
-(p10) mov cr.itir=r25
+ MOV_TO_ITIR(p10, r25, r24)
cmp.ne p8,p0=r0,r23
(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field
(p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr
@@ -411,11 +418,11 @@ ENTRY(alt_dtlb_miss)
dep r21=-1,r21,IA64_PSR_ED_BIT,1
;;
or r19=r19,r17 // insert PTE control bits into r19
-(p6) mov cr.ipsr=r21
+ MOV_FROM_IPSR(p6,r21)
;;
-(p7) itc.d r19 // insert the TLB entry
+ ITC_D(p7, r19, r18) // insert the TLB entry
mov pr=r31,-1
- rfi
+ RFI
END(alt_dtlb_miss)
.org ia64_ivt+0x1400
@@ -444,10 +451,10 @@ ENTRY(nested_dtlb_miss)
*
* Clobbered: b0, r18, r19, r21, r22, psr.dt (cleared)
*/
- rsm psr.dt // switch to using physical data addressing
+ RSM_PSR_DT_AND_SRLZ_I // switch to using physical data addressing
mov r19=IA64_KR(PT_BASE) // get the page table base address
shl r21=r16,3 // shift bit 60 into sign bit
- mov r18=cr.itir
+ MOV_FROM_ITIR(r18)
;;
shr.u r17=r16,61 // get the region number into r17
extr.u r18=r18,2,6 // get the faulting page size
@@ -510,21 +517,15 @@ END(ikey_miss)
//-----------------------------------------------------------------------------------
// call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
ENTRY(page_fault)
- ssm psr.dt
- ;;
- srlz.i
+ SSM_PSR_DT_AND_SRLZ_I
;;
SAVE_MIN_WITH_COVER
alloc r15=ar.pfs,0,0,3,0
- mov out0=cr.ifa
- mov out1=cr.isr
+ MOV_FROM_IFA(out0)
+ MOV_FROM_ISR(out1)
+ SSM_PSR_IC_AND_DEFAULT_BITS(r14, r3)
adds r3=8,r2 // set up second base pointer
- ;;
- ssm psr.ic | PSR_DEFAULT_BITS
- ;;
- srlz.i // guarantee that interruption collectin is on
- ;;
-(p15) ssm psr.i // restore psr.i
+ SSM_PSR_I(p15, r14) // restore psr.i
movl r14=ia64_leave_kernel
;;
SAVE_REST
@@ -556,10 +557,10 @@ ENTRY(dirty_bit)
* page table TLB entry isn't present, we take a nested TLB miss hit where we look
* up the physical address of the L3 PTE and then continue at label 1 below.
*/
- mov r16=cr.ifa // get the address that caused the fault
+ MOV_FROM_IFA(r16) // get the address that caused the fault
movl r30=1f // load continuation point in case of nested fault
;;
- thash r17=r16 // compute virtual address of L3 PTE
+ THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
mov r29=b0 // save b0 in case of nested fault
mov r31=pr // save pr
#ifdef CONFIG_SMP
@@ -576,7 +577,7 @@ ENTRY(dirty_bit)
;;
(p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present
;;
-(p6) itc.d r25 // install updated PTE
+ ITC_D(p6, r25, r18) // install updated PTE
;;
/*
* Tell the assemblers dependency-violation checker that the above "itc" instructions
@@ -602,7 +603,7 @@ ENTRY(dirty_bit)
itc.d r18 // install updated PTE
#endif
mov pr=r31,-1 // restore pr
- rfi
+ RFI
END(dirty_bit)
.org ia64_ivt+0x2400
@@ -611,22 +612,22 @@ END(dirty_bit)
ENTRY(iaccess_bit)
DBG_FAULT(9)
// Like Entry 8, except for instruction access
- mov r16=cr.ifa // get the address that caused the fault
+ MOV_FROM_IFA(r16) // get the address that caused the fault
movl r30=1f // load continuation point in case of nested fault
mov r31=pr // save predicates
#ifdef CONFIG_ITANIUM
/*
* Erratum 10 (IFA may contain incorrect address) has "NoFix" status.
*/
- mov r17=cr.ipsr
+ MOV_FROM_IPSR(p0,r17)
;;
- mov r18=cr.iip
+ MOV_FROM_IIP(r18)
tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set?
;;
(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa
#endif /* CONFIG_ITANIUM */
;;
- thash r17=r16 // compute virtual address of L3 PTE
+ THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
mov r29=b0 // save b0 in case of nested fault)
#ifdef CONFIG_SMP
mov r28=ar.ccv // save ar.ccv
@@ -642,7 +643,7 @@ ENTRY(iaccess_bit)
;;
(p6) cmp.eq p6,p7=r26,r18 // Only if page present
;;
-(p6) itc.i r25 // install updated PTE
+ ITC_I(p6, r25, r26) // install updated PTE
;;
/*
* Tell the assemblers dependency-violation checker that the above "itc" instructions
@@ -668,7 +669,7 @@ ENTRY(iaccess_bit)
itc.i r18 // install updated PTE
#endif /* !CONFIG_SMP */
mov pr=r31,-1
- rfi
+ RFI
END(iaccess_bit)
.org ia64_ivt+0x2800
@@ -677,10 +678,10 @@ END(iaccess_bit)
ENTRY(daccess_bit)
DBG_FAULT(10)
// Like Entry 8, except for data access
- mov r16=cr.ifa // get the address that caused the fault
+ MOV_FROM_IFA(r16) // get the address that caused the fault
movl r30=1f // load continuation point in case of nested fault
;;
- thash r17=r16 // compute virtual address of L3 PTE
+ THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
mov r31=pr
mov r29=b0 // save b0 in case of nested fault)
#ifdef CONFIG_SMP
@@ -697,7 +698,7 @@ ENTRY(daccess_bit)
;;
(p6) cmp.eq p6,p7=r26,r18 // Only if page is present
;;
-(p6) itc.d r25 // install updated PTE
+ ITC_D(p6, r25, r26) // install updated PTE
/*
* Tell the assemblers dependency-violation checker that the above "itc" instructions
* cannot possibly affect the following loads:
@@ -721,7 +722,7 @@ ENTRY(daccess_bit)
#endif
mov b0=r29 // restore b0
mov pr=r31,-1
- rfi
+ RFI
END(daccess_bit)
.org ia64_ivt+0x2c00
@@ -745,10 +746,10 @@ ENTRY(break_fault)
*/
DBG_FAULT(11)
mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc)
- mov r29=cr.ipsr // M2 (12 cyc)
+ MOV_FROM_IPSR(p0,r29) // M2 (12 cyc)
mov r31=pr // I0 (2 cyc)
- mov r17=cr.iim // M2 (2 cyc)
+ MOV_FROM_IIM(r17) // M2 (2 cyc)
mov.m r27=ar.rsc // M2 (12 cyc)
mov r18=__IA64_BREAK_SYSCALL // A
@@ -767,7 +768,7 @@ ENTRY(break_fault)
nop.m 0
movl r30=sys_call_table // X
- mov r28=cr.iip // M2 (2 cyc)
+ MOV_FROM_IIP(r28) // M2 (2 cyc)
cmp.eq p0,p7=r18,r17 // I0 is this a system call?
(p7) br.cond.spnt non_syscall // B no ->
//
@@ -831,10 +832,10 @@ ENTRY(break_fault)
1:
mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
nop 0
- bsw.1 // B (6 cyc) regs are saved, switch to bank 1
+ BSW_1(r2, r14) // B (6 cyc) regs are saved, switch to bank 1
;;
- ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection
+ SSM_PSR_IC_AND_DEFAULT_BITS(r3, r16) // M2 now it's safe to re-enable intr.-collection
movl r3=ia64_ret_from_syscall // X
;;
@@ -842,7 +843,7 @@ ENTRY(break_fault)
mov rp=r3 // I0 set the real return addr
(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
-(p15) ssm psr.i // M2 restore psr.i
+ SSM_PSR_I(p15, r16) // M2 restore psr.i
(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr)
br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic
// NOT REACHED
@@ -866,7 +867,7 @@ ENTRY(interrupt)
mov r31=pr // prepare to save predicates
;;
SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3
- ssm psr.ic | PSR_DEFAULT_BITS
+ SSM_PSR_IC_AND_DEFAULT_BITS(r3, r14)
;;
adds r3=8,r2 // set up second base pointer for SAVE_REST
srlz.i // ensure everybody knows psr.ic is back on
@@ -875,7 +876,7 @@ ENTRY(interrupt)
;;
MCA_RECOVER_RANGE(interrupt)
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
- mov out0=cr.ivr // pass cr.ivr as first arg
+ MOV_FROM_IVR(out0, r8) // pass cr.ivr as first arg
add out1=16,sp // pass pointer to pt_regs as second arg
;;
srlz.d // make sure we see the effect of cr.ivr
@@ -944,6 +945,7 @@ END(interrupt)
* - ar.fpsr: set to kernel settings
* - b6: preserved (same as on entry)
*/
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
GLOBAL_ENTRY(ia64_syscall_setup)
#if PT(B6) != 0
# error This code assumes that b6 is the first field in pt_regs.
@@ -1035,6 +1037,7 @@ GLOBAL_ENTRY(ia64_syscall_setup)
(p10) mov r8=-EINVAL
br.ret.sptk.many b7
END(ia64_syscall_setup)
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
.org ia64_ivt+0x3c00
/////////////////////////////////////////////////////////////////////////////////////////
@@ -1055,11 +1058,11 @@ ENTRY(dispatch_illegal_op_fault)
.prologue
.body
SAVE_MIN_WITH_COVER
- ssm psr.ic | PSR_DEFAULT_BITS
+ SSM_PSR_IC_AND_DEFAULT_BITS(r3,r24)
;;
srlz.i // guarantee that interruption collection is on
;;
-(p15) ssm psr.i // restore psr.i
+ SSM_PSR_I(p15,r3) // restore psr.i
adds r3=8,r2 // set up second base pointer for SAVE_REST
;;
alloc r14=ar.pfs,0,0,1,0 // must be first in insn group
@@ -1107,15 +1110,15 @@ ENTRY(non_syscall)
// suitable spot...
alloc r14=ar.pfs,0,0,2,0
- mov out0=cr.iim
+ MOV_FROM_IIM(out0)
add out1=16,sp
adds r3=8,r2 // set up second base pointer for SAVE_REST
- ssm psr.ic | PSR_DEFAULT_BITS
+ SSM_PSR_IC_AND_DEFAULT_BITS(r15,r24)
;;
srlz.i // guarantee that interruption collection is on
;;
-(p15) ssm psr.i // restore psr.i
+ SSM_PSR_I(p15,r15) // restore psr.i
movl r15=ia64_leave_kernel
;;
SAVE_REST
@@ -1141,14 +1144,14 @@ ENTRY(dispatch_unaligned_handler)
SAVE_MIN_WITH_COVER
;;
alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!)
- mov out0=cr.ifa
+ MOV_FROM_IFA(out0)
adds out1=16,sp
- ssm psr.ic | PSR_DEFAULT_BITS
+ SSM_PSR_IC_AND_DEFAULT_BITS(r3,r24)
;;
srlz.i // guarantee that interruption collection is on
;;
-(p15) ssm psr.i // restore psr.i
+ SSM_PSR_I(p15,r3) // restore psr.i
adds r3=8,r2 // set up second base pointer
;;
SAVE_REST
@@ -1180,17 +1183,17 @@ ENTRY(dispatch_to_fault_handler)
*/
SAVE_MIN_WITH_COVER_R19
alloc r14=ar.pfs,0,0,5,0
- mov out0=r15
- mov out1=cr.isr
- mov out2=cr.ifa
- mov out3=cr.iim
- mov out4=cr.itir
+ MOV_FROM_ISR(out1)
+ MOV_FROM_IFA(out2)
+ MOV_FROM_IIM(out3)
+ MOV_FROM_ITIR(out4)
;;
- ssm psr.ic | PSR_DEFAULT_BITS
+ SSM_PSR_IC_AND_DEFAULT_BITS(r3, out0)
+ mov out0=r15
;;
srlz.i // guarantee that interruption collection is on
;;
-(p15) ssm psr.i // restore psr.i
+ SSM_PSR_I(p15,r3) // restore psr.i
adds r3=8,r2 // set up second base pointer for SAVE_REST
;;
SAVE_REST
@@ -1209,8 +1212,8 @@ END(dispatch_to_fault_handler)
// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
ENTRY(page_not_present)
DBG_FAULT(20)
- mov r16=cr.ifa
- rsm psr.dt
+ MOV_FROM_IFA(r16)
+ RSM_PSR_DT
/*
* The Linux page fault handler doesn't expect non-present pages to be in
* the TLB. Flush the existing entry now, so we meet that expectation.
@@ -1229,8 +1232,8 @@ END(page_not_present)
// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
ENTRY(key_permission)
DBG_FAULT(21)
- mov r16=cr.ifa
- rsm psr.dt
+ MOV_FROM_IFA(r16)
+ RSM_PSR_DT
mov r31=pr
;;
srlz.d
@@ -1242,8 +1245,8 @@ END(key_permission)
// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
ENTRY(iaccess_rights)
DBG_FAULT(22)
- mov r16=cr.ifa
- rsm psr.dt
+ MOV_FROM_IFA(r16)
+ RSM_PSR_DT
mov r31=pr
;;
srlz.d
@@ -1255,8 +1258,8 @@ END(iaccess_rights)
// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
ENTRY(daccess_rights)
DBG_FAULT(23)
- mov r16=cr.ifa
- rsm psr.dt
+ MOV_FROM_IFA(r16)
+ RSM_PSR_DT
mov r31=pr
;;
srlz.d
@@ -1268,7 +1271,7 @@ END(daccess_rights)
// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
ENTRY(general_exception)
DBG_FAULT(24)
- mov r16=cr.isr
+ MOV_FROM_ISR(r16)
mov r31=pr
;;
cmp4.eq p6,p0=0,r16
@@ -1297,8 +1300,8 @@ END(disabled_fp_reg)
ENTRY(nat_consumption)
DBG_FAULT(26)
- mov r16=cr.ipsr
- mov r17=cr.isr
+ MOV_FROM_IPSR(p0,r16);
+ MOV_FROM_ISR(r17);
mov r31=pr // save PR
;;
and r18=0xf,r17 // r18 = cr.ipsr.code{3:0}
@@ -1308,10 +1311,10 @@ ENTRY(nat_consumption)
dep r16=-1,r16,IA64_PSR_ED_BIT,1
(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
;;
- mov cr.ipsr=r16 // set cr.ipsr.na
+ MOV_TO_IPSR(r16,r18);
mov pr=r31,-1
;;
- rfi
+ RFI
1: mov pr=r31,-1
;;
@@ -1333,26 +1336,26 @@ ENTRY(speculation_vector)
*
* cr.imm contains zero_ext(imm21)
*/
- mov r18=cr.iim
+ MOV_FROM_IIM(r18)
;;
- mov r17=cr.iip
+ MOV_FROM_IIP(r17)
shl r18=r18,43 // put sign bit in position (43=64-21)
;;
- mov r16=cr.ipsr
+ MOV_FROM_IPSR(p0,r16)
shr r18=r18,39 // sign extend (39=43-4)
;;
add r17=r17,r18 // now add the offset
;;
- mov cr.iip=r17
+ MOV_FROM_IIP(r17)
dep r16=0,r16,41,2 // clear EI
;;
- mov cr.ipsr=r16
+ MOV_FROM_IPSR(p0,r16)
;;
- rfi // and go back
+ RFI
END(speculation_vector)
.org ia64_ivt+0x5800
@@ -1490,11 +1493,11 @@ ENTRY(ia32_intercept)
DBG_FAULT(46)
#ifdef CONFIG_IA32_SUPPORT
mov r31=pr
- mov r16=cr.isr
+ MOV_FROM_ISR(r16)
;;
extr.u r17=r16,16,8 // get ISR.code
mov r18=ar.eflag
- mov r19=cr.iim // old eflag value
+ MOV_FROM_IIM(r19) // old eflag value
;;
cmp.ne p6,p0=2,r17
(p6) br.cond.spnt 1f // not a system flag fault
@@ -1506,7 +1509,7 @@ ENTRY(ia32_intercept)
(p6) br.cond.spnt 1f // eflags.ac bit didn't change
;;
mov pr=r31,-1 // restore predicate registers
- rfi
+ RFI
1:
#endif // CONFIG_IA32_SUPPORT
@@ -1660,12 +1663,12 @@ END(ia32_interrupt)
ENTRY(dispatch_to_ia32_handler)
SAVE_MIN
;;
- mov r14=cr.isr
- ssm psr.ic | PSR_DEFAULT_BITS
+ MOV_FROM_ISR(r14)
+ SSM_PSR_IC_AND_DEFAULT_BITS(r3,r24)
;;
srlz.i // guarantee that interruption collection is on
;;
-(p15) ssm psr.i
+ SSM_PSR_I(p15,r3)
adds r3=8,r2 // Base pointer for SAVE_REST
;;
SAVE_REST
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 10/15] ia64/pv_ops: paravirtualize entry.S
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (9 preceding siblings ...)
2008-04-09 4:49 ` [PATCH 09/15] ia64/pv_ops: paravirtualize ivt.S Isaku Yamahata
@ 2008-04-09 4:49 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
` (5 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
paravirtualize ia64_swtich_to, ia64_leave_syscall and ia64_leave_kernel.
They include sensitive or performance critical privileged instructions
so that they need paravirtualization.
To paravirtualize them by single source and multi compile
they are converted into indirect jump. And define each pv instances.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/Makefile | 2 +-
arch/ia64/kernel/entry.S | 107 +++++++++++++++++++++++-------------
arch/ia64/kernel/paravirt.c | 19 ++++++
arch/ia64/kernel/paravirtentry.S | 60 ++++++++++++++++++++
include/asm-ia64/native/inst.h | 8 +++
include/asm-ia64/paravirt_privop.h | 23 ++++++++
6 files changed, 179 insertions(+), 40 deletions(-)
create mode 100644 arch/ia64/kernel/paravirtentry.S
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index a462669..7232273 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -36,7 +36,7 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
-obj-$(CONFIG_PARAVIRT) += paravirt.o
+obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o
obj-$(CONFIG_IA64_ESI) += esi.o
ifneq ($(CONFIG_IA64_ESI),)
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 3c331c4..655c1ee 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -23,6 +23,11 @@
* 11/07/2000
*/
/*
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ * pv_ops.
+ */
+/*
* Global (preserved) predicate usage on syscall entry/exit path:
*
* pKStk: See entry.h.
@@ -45,6 +50,7 @@
#include "minstate.h"
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
/*
* execve() is special because in case of success, we need to
* setup a null register window frame.
@@ -173,6 +179,7 @@ GLOBAL_ENTRY(sys_clone)
mov rp=loc0
br.ret.sptk.many rp
END(sys_clone)
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
/*
* prev_task <- ia64_switch_to(struct task_struct *next)
@@ -180,7 +187,7 @@ END(sys_clone)
* called. The code starting at .map relies on this. The rest of the code
* doesn't care about the interrupt masking status.
*/
-GLOBAL_ENTRY(ia64_switch_to)
+GLOBAL_ENTRY(__paravirt_switch_to)
.prologue
alloc r16=ar.pfs,1,0,0,0
DO_SAVE_SWITCH_STACK
@@ -204,7 +211,7 @@ GLOBAL_ENTRY(ia64_switch_to)
;;
.done:
ld8 sp=[r21] // load kernel stack pointer of new task
- mov IA64_KR(CURRENT)=in0 // update "current" application register
+ MOV_TO_KR(CURRENT, in0, r8, r9) // update "current" application register
mov r8=r13 // return pointer to previously running task
mov r13=in0 // set "current" pointer
;;
@@ -216,26 +223,25 @@ GLOBAL_ENTRY(ia64_switch_to)
br.ret.sptk.many rp // boogie on out in new context
.map:
- rsm psr.ic // interrupts (psr.i) are already disabled here
+ RSM_PSR_IC(r25) // interrupts (psr.i) are already disabled here
movl r25=PAGE_KERNEL
;;
srlz.d
or r23=r25,r20 // construct PA | page properties
mov r25=IA64_GRANULE_SHIFT<<2
;;
- mov cr.itir=r25
- mov cr.ifa=in0 // VA of next task...
+ MOV_TO_ITIR(p0, r25, r8)
+ MOV_TO_IFA(in0, r8) // VA of next task...
;;
mov r25=IA64_TR_CURRENT_STACK
- mov IA64_KR(CURRENT_STACK)=r26 // remember last page we mapped...
+ MOV_TO_KR(CURRENT_STACK, r26, r8, r9) // remember last page we mapped...
;;
itr.d dtr[r25]=r23 // wire in new mapping...
- ssm psr.ic // reenable the psr.ic bit
- ;;
- srlz.d
+ SSM_PSR_IC_AND_SRLZ_D(r8, r9) // reenable the psr.ic bit
br.cond.sptk .done
-END(ia64_switch_to)
+END(__paravirt_switch_to)
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
/*
* Note that interrupts are enabled during save_switch_stack and load_switch_stack. This
* means that we may get an interrupt with "sp" pointing to the new kernel stack while
@@ -375,7 +381,7 @@ END(save_switch_stack)
* - b7 holds address to return to
* - must not touch r8-r11
*/
-ENTRY(load_switch_stack)
+GLOBAL_ENTRY(load_switch_stack)
.prologue
.altrp b7
@@ -570,7 +576,7 @@ GLOBAL_ENTRY(ia64_trace_syscall)
br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
.ret3:
(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
- br.cond.sptk .work_pending_syscall_end
+ br.cond.sptk ia64_work_pending_syscall_end
strace_error:
ld8 r3=[r2] // load pt_regs.r8
@@ -635,8 +641,17 @@ GLOBAL_ENTRY(ia64_ret_from_syscall)
adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8
mov r10=r0 // clear error indication in r10
(p7) br.cond.spnt handle_syscall_error // handle potential syscall failure
+#ifdef CONFIG_PARAVIRT
+ ;;
+ br.cond.sptk.few ia64_leave_syscall
+ ;;
+#endif /* CONFIG_PARAVIRT */
END(ia64_ret_from_syscall)
+#ifndef CONFIG_PARAVIRT
// fall through
+#endif
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
+
/*
* ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
* need to switch to bank 0 and doesn't restore the scratch registers.
@@ -681,7 +696,7 @@ END(ia64_ret_from_syscall)
* ar.csd: cleared
* ar.ssd: cleared
*/
-ENTRY(ia64_leave_syscall)
+GLOBAL_ENTRY(__paravirt_leave_syscall)
PT_REGS_UNWIND_INFO(0)
/*
* work.need_resched etc. mustn't get changed by this CPU before it returns to
@@ -691,7 +706,7 @@ ENTRY(ia64_leave_syscall)
* extra work. We always check for extra work when returning to user-level.
* With CONFIG_PREEMPT, we also check for extra work when the preempt_count
* is 0. After extra work processing has been completed, execution
- * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
+ * resumes at ia64_work_processed_syscall with p6 set to 1 if the extra-work-check
* needs to be redone.
*/
#ifdef CONFIG_PREEMPT
@@ -705,11 +720,12 @@ ENTRY(ia64_leave_syscall)
;;
cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0)
#else /* !CONFIG_PREEMPT */
-(pUStk) rsm psr.i
+ RSM_PSR_I(pUStk, r2, r18)
cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall
(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
#endif
-.work_processed_syscall:
+.global __paravirt_work_processed_syscall;
+__paravirt_work_processed_syscall:
adds r2=PT(LOADRS)+16,r12
adds r3=PT(AR_BSPSTORE)+16,r12
adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
@@ -732,7 +748,7 @@ ENTRY(ia64_leave_syscall)
(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE!
;;
invala // M0|1 invalidate ALAT
- rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection
+ RSM_PSR_I_IC(r28, r29, r30) // M2 turn off interrupts and interruption collection
cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs
ld8 r29=[r2],16 // M0|1 load cr.ipsr
@@ -744,7 +760,7 @@ ENTRY(ia64_leave_syscall)
(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
;;
ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs
-(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled
+ MOV_FROM_PSR(pKStk, r22, r21) // M2 read PSR now that interrupts are disabled
nop 0
;;
ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
@@ -773,7 +789,7 @@ ENTRY(ia64_leave_syscall)
srlz.d // M0 ensure interruption collection is off (for cover)
shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition
- cover // B add current frame into dirty partition & set cr.ifs
+ COVER // B add current frame into dirty partition & set cr.ifs
;;
mov r19=ar.bsp // M2 get new backing store pointer
mov f10=f0 // F clear f10
@@ -788,8 +804,9 @@ ENTRY(ia64_leave_syscall)
mov.m ar.ssd=r0 // M2 clear ar.ssd
mov f11=f0 // F clear f11
br.cond.sptk.many rbs_switch // B
-END(ia64_leave_syscall)
+END(__paravirt_leave_syscall)
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
#ifdef CONFIG_IA32_SUPPORT
GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
PT_REGS_UNWIND_INFO(0)
@@ -800,10 +817,20 @@ GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit
.mem.offset 8,0
st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit
+#ifdef CONFIG_PARAVIRT
+ ;;
+ // don't fall through, ia64_leave_kernel may be #define'd
+ br.cond.sptk.few ia64_leave_kernel
+ ;;
+#endif /* CONFIG_PARAVIRT */
END(ia64_ret_from_ia32_execve)
+#ifndef CONFIG_PARAVIRT
// fall through
+#endif
#endif /* CONFIG_IA32_SUPPORT */
-GLOBAL_ENTRY(ia64_leave_kernel)
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
+
+GLOBAL_ENTRY(__paravirt_leave_kernel)
PT_REGS_UNWIND_INFO(0)
/*
* work.need_resched etc. mustn't get changed by this CPU before it returns to
@@ -827,7 +854,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
;;
cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0)
#else
-(pUStk) rsm psr.i
+ RSM_PSR_I(pUStk, r17, r31)
cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel
(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
#endif
@@ -875,7 +902,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
mov ar.csd=r30
mov ar.ssd=r31
;;
- rsm psr.i | psr.ic // initiate turning off of interrupt and interruption collection
+ RSM_PSR_I_IC(r23, r22, r25) // initiate turning off of interrupt and interruption collection
invala // invalidate ALAT
;;
ld8.fill r22=[r2],24
@@ -907,13 +934,13 @@ GLOBAL_ENTRY(ia64_leave_kernel)
mov ar.ccv=r15
;;
ldf.fill f11=[r2]
- bsw.0 // switch back to bank 0 (no stop bit required beforehand...)
+ BSW_0(r2, r3, r15) // switch back to bank 0 (no stop bit required beforehand...)
;;
(pUStk) mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
adds r16=PT(CR_IPSR)+16,r12
adds r17=PT(CR_IIP)+16,r12
-(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled
+ MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled
nop.i 0
nop.i 0
;;
@@ -961,7 +988,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
* NOTE: alloc, loadrs, and cover can't be predicated.
*/
(pNonSys) br.cond.dpnt dont_preserve_current_frame
- cover // add current frame into dirty partition and set cr.ifs
+ COVER // add current frame into dirty partition and set cr.ifs
;;
mov r19=ar.bsp // get new backing store pointer
rbs_switch:
@@ -1064,16 +1091,16 @@ skip_rbs_switch:
(pKStk) dep r29=r22,r29,21,1 // I0 update ipsr.pp with psr.pp
(pLvSys)mov r16=r0 // A clear r16 for leave_syscall, no-op otherwise
;;
- mov cr.ipsr=r29 // M2
+ MOV_TO_IPSR(r29, r25) // M2
mov ar.pfs=r26 // I0
(pLvSys)mov r17=r0 // A clear r17 for leave_syscall, no-op otherwise
-(p9) mov cr.ifs=r30 // M2
+ MOV_TO_IFS(p9, r30, r25)// M2
mov b0=r21 // I0
(pLvSys)mov r18=r0 // A clear r18 for leave_syscall, no-op otherwise
mov ar.fpsr=r20 // M2
- mov cr.iip=r28 // M2
+ MOV_TO_IIP(r28, r25) // M2
nop 0
;;
(pUStk) mov ar.rnat=r24 // M2 must happen with RSE in lazy mode
@@ -1082,7 +1109,7 @@ skip_rbs_switch:
mov ar.rsc=r27 // M2
mov pr=r31,-1 // I0
- rfi // B
+ RFI // B
/*
* On entry:
@@ -1108,32 +1135,33 @@ skip_rbs_switch:
#endif
br.call.spnt.many rp=schedule
.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1
- rsm psr.i // disable interrupts
+ RSM_PSR_I(p0, r2, r20) // disable interrupts
;;
#ifdef CONFIG_PREEMPT
(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
;;
(pKStk) st4 [r20]=r0 // preempt_count() <- 0
#endif
-(pLvSys)br.cond.sptk.few .work_pending_syscall_end
+(pLvSys)br.cond.sptk.few __paravirt_pending_syscall_end
br.cond.sptk.many .work_processed_kernel // re-check
.notify:
(pUStk) br.call.spnt.many rp=notify_resume_user
.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0
-(pLvSys)br.cond.sptk.few .work_pending_syscall_end
+(pLvSys)br.cond.sptk.few __paravirt_pending_syscall_end
br.cond.sptk.many .work_processed_kernel // don't re-check
-.work_pending_syscall_end:
+.global __paravirt_pending_syscall_end;
+__paravirt_pending_syscall_end:
adds r2=PT(R8)+16,r12
adds r3=PT(R10)+16,r12
;;
ld8 r8=[r2]
ld8 r10=[r3]
- br.cond.sptk.many .work_processed_syscall // re-check
-
-END(ia64_leave_kernel)
+ br.cond.sptk.many __paravirt_work_processed_syscall_target // re-check
+END(__paravirt_leave_kernel)
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
ENTRY(handle_syscall_error)
/*
* Some system calls (e.g., ptrace, mmap) can return arbitrary values which could
@@ -1172,7 +1200,7 @@ END(ia64_invoke_schedule_tail)
* be set up by the caller. We declare 8 input registers so the system call
* args get preserved, in case we need to restart a system call.
*/
-ENTRY(notify_resume_user)
+GLOBAL_ENTRY(notify_resume_user)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
mov r9=ar.unat
@@ -1234,7 +1262,7 @@ ENTRY(sys_rt_sigreturn)
adds sp=16,sp
;;
ld8 r9=[sp] // load new ar.unat
- mov.sptk b7=r8,ia64_leave_kernel
+ mov.sptk b7=r8,ia64_native_leave_kernel
;;
mov ar.unat=r9
br.many b7
@@ -1593,3 +1621,4 @@ sys_call_table:
data8 sys_timerfd_gettime
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index bcfcb8b..6d7ae59 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -284,3 +284,22 @@ struct pv_cpu_ops pv_cpu_ops = {
.intrin_local_irq_restore
= ia64_native_intrin_local_irq_restore_func,
};
+
+/******************************************************************************
+ * replacement of hand written assembly codes.
+ */
+
+void
+paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch)
+{
+ extern unsigned long paravirt_switch_to_targ;
+ extern unsigned long paravirt_leave_syscall_targ;
+ extern unsigned long paravirt_work_processed_syscall_targ;
+ extern unsigned long paravirt_leave_kernel_targ;
+
+ paravirt_switch_to_targ = cpu_asm_switch->switch_to;
+ paravirt_leave_syscall_targ = cpu_asm_switch->leave_syscall;
+ paravirt_work_processed_syscall_targ =
+ cpu_asm_switch->work_processed_syscall;
+ paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel;
+}
diff --git a/arch/ia64/kernel/paravirtentry.S b/arch/ia64/kernel/paravirtentry.S
new file mode 100644
index 0000000..2f42fcb
--- /dev/null
+++ b/arch/ia64/kernel/paravirtentry.S
@@ -0,0 +1,60 @@
+/******************************************************************************
+ * linux/arch/ia64/xen/paravirtentry.S
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <asm/asmmacro.h>
+#include <asm/asm-offsets.h>
+#include "entry.h"
+
+#define DATA8(sym, init_value) \
+ .pushsection .data.read_mostly ; \
+ .align 8 ; \
+ .global sym ; \
+ sym: ; \
+ data8 init_value ; \
+ .popsection
+
+#define BRANCH(targ, reg, breg) \
+ movl reg=targ ; \
+ ;; \
+ ld8 reg=[reg] ; \
+ ;; \
+ mov breg=reg ; \
+ br.cond.sptk.many breg
+
+#define BRANCH_PROC(sym, reg, breg) \
+ DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
+ GLOBAL_ENTRY(paravirt_ ## sym) ; \
+ BRANCH(paravirt_ ## sym ## _targ, reg, breg) ; \
+ END(paravirt_ ## sym)
+
+#define BRANCH_PROC_UNWINFO(sym, reg, breg) \
+ DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
+ GLOBAL_ENTRY(paravirt_ ## sym) ; \
+ PT_REGS_UNWIND_INFO(0) ; \
+ BRANCH(paravirt_ ## sym ## _targ, reg, breg) ; \
+ END(paravirt_ ## sym)
+
+
+BRANCH_PROC(switch_to, r22, b7)
+BRANCH_PROC_UNWINFO(leave_syscall, r22, b7)
+BRANCH_PROC(work_processed_syscall, r2, b7)
+BRANCH_PROC_UNWINFO(leave_kernel, r22, b7)
diff --git a/include/asm-ia64/native/inst.h b/include/asm-ia64/native/inst.h
index c167b7d..1855dae 100644
--- a/include/asm-ia64/native/inst.h
+++ b/include/asm-ia64/native/inst.h
@@ -22,6 +22,14 @@
#define DO_SAVE_MIN IA64_NATIVE_DO_SAVE_MIN
+#define __paravirt_switch_to ia64_native_switch_to
+#define __paravirt_leave_syscall ia64_native_leave_syscall
+#define __paravirt_work_processed_syscall ia64_native_work_processed_syscall
+#define __paravirt_leave_kernel ia64_native_leave_kernel
+#define __paravirt_pending_syscall_end ia64_work_pending_syscall_end
+#define __paravirt_work_processed_syscall_target \
+ ia64_work_processed_syscall
+
#ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK
# define PARAVIRT_POISON 0xdeadbeefbaadf00d
# define CLOBBER(clob) \
diff --git a/include/asm-ia64/paravirt_privop.h b/include/asm-ia64/paravirt_privop.h
index 7b133ae..52482e6 100644
--- a/include/asm-ia64/paravirt_privop.h
+++ b/include/asm-ia64/paravirt_privop.h
@@ -80,12 +80,35 @@ extern unsigned long ia64_native_getreg_func(int regnum);
ia64_native_rsm(mask); \
} while (0)
+/******************************************************************************
+ * replacement of hand written assembly codes.
+ */
+struct pv_cpu_asm_switch {
+ unsigned long switch_to;
+ unsigned long leave_syscall;
+ unsigned long work_processed_syscall;
+ unsigned long leave_kernel;
+};
+void paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch);
+
#endif /* __ASSEMBLY__ */
+#define IA64_PARAVIRT_ASM_FUNC(name) paravirt_ ## name
+
#else
/* fallback for native case */
+#define IA64_PARAVIRT_ASM_FUNC(name) ia64_native_ ## name
#endif /* CONFIG_PARAVIRT */
+/* these routines utilize privilege-sensitive or performance-sensitive
+ * privileged instructions so the code must be replaced with
+ * paravirtualized versions */
+#define ia64_switch_to IA64_PARAVIRT_ASM_FUNC(switch_to)
+#define ia64_leave_syscall IA64_PARAVIRT_ASM_FUNC(leave_syscall)
+#define ia64_work_processed_syscall \
+ IA64_PARAVIRT_ASM_FUNC(work_processed_syscall)
+#define ia64_leave_kernel IA64_PARAVIRT_ASM_FUNC(leave_kernel)
+
#endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
@ 2008-04-09 4:49 ` Isaku Yamahata
2008-04-22 9:08 ` Jes Sorensen
` (9 more replies)
0 siblings, 10 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64
Make NR_IRQ overridable by each pv instances.
Pv instance may need each own number of irqs so that
NR_IRQS should be the maximum number of nr_irqs each
pv instances need.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
include/asm-ia64/irq.h | 10 ++++++-
include/asm-ia64/paravirt_irq.h | 49 +++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 include/asm-ia64/paravirt_irq.h
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index a66d268..0463427 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -17,9 +17,15 @@
#define NR_VECTORS 256
#if (NR_VECTORS + 32 * NR_CPUS) < 1024
-#define NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
+#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
#else
-#define NR_IRQS 1024
+#define IA64_NATIVE_NR_IRQS 1024
+#endif
+
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt_irq.h>
+#else
+#define NR_IRQS IA64_NATIVE_NR_IRQS
#endif
static __inline__ int
diff --git a/include/asm-ia64/paravirt_irq.h b/include/asm-ia64/paravirt_irq.h
new file mode 100644
index 0000000..7dedf2a
--- /dev/null
+++ b/include/asm-ia64/paravirt_irq.h
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * include/asm-ia64/paravirt_irq.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_PARAVIRT_IRQ_H
+#define __ASM_PARAVIRT_IRQ_H
+
+#ifdef CONFIG_PARAVIRT
+
+/* Determine the maximal NR_IRQ which each pv instances require.
+ * i.e. NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...)
+ */
+
+#define NR_IRQS 1
+
+#if IA64_NATIVE_NR_IRQS > NR_IRQS
+#undef NR_IRQS
+#define NR_IRQS IA64_NATIVE_NR_IRQS
+#endif
+
+#ifdef CONFIG_XEN
+#include <asm/xen/irq.h>
+#if XEN_NR_IRQS > NR_IRQS
+#undef NR_IRQS
+#define NR_IRQS XEN_NR_IRQS
+#endif
+#endif /* CONFIG_XEN */
+
+#endif /* CONFIG_PARAVIRT */
+
+#endif /* __ASM_PARAVIRT_IRQ_H */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (11 preceding siblings ...)
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
@ 2008-04-09 4:49 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 12/15] ia64/pv_ops: define initialization hooks, pv_init_ops, for paravirtualized environment Isaku Yamahata
` (3 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
Make NR_IRQ overridable by each pv instances.
Pv instance may need each own number of irqs so that
NR_IRQS should be the maximum number of nr_irqs each
pv instances need.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
include/asm-ia64/irq.h | 10 ++++++-
include/asm-ia64/paravirt_irq.h | 49 +++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 include/asm-ia64/paravirt_irq.h
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index a66d268..0463427 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -17,9 +17,15 @@
#define NR_VECTORS 256
#if (NR_VECTORS + 32 * NR_CPUS) < 1024
-#define NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
+#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
#else
-#define NR_IRQS 1024
+#define IA64_NATIVE_NR_IRQS 1024
+#endif
+
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt_irq.h>
+#else
+#define NR_IRQS IA64_NATIVE_NR_IRQS
#endif
static __inline__ int
diff --git a/include/asm-ia64/paravirt_irq.h b/include/asm-ia64/paravirt_irq.h
new file mode 100644
index 0000000..7dedf2a
--- /dev/null
+++ b/include/asm-ia64/paravirt_irq.h
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * include/asm-ia64/paravirt_irq.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_PARAVIRT_IRQ_H
+#define __ASM_PARAVIRT_IRQ_H
+
+#ifdef CONFIG_PARAVIRT
+
+/* Determine the maximal NR_IRQ which each pv instances require.
+ * i.e. NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...)
+ */
+
+#define NR_IRQS 1
+
+#if IA64_NATIVE_NR_IRQS > NR_IRQS
+#undef NR_IRQS
+#define NR_IRQS IA64_NATIVE_NR_IRQS
+#endif
+
+#ifdef CONFIG_XEN
+#include <asm/xen/irq.h>
+#if XEN_NR_IRQS > NR_IRQS
+#undef NR_IRQS
+#define NR_IRQS XEN_NR_IRQS
+#endif
+#endif /* CONFIG_XEN */
+
+#endif /* CONFIG_PARAVIRT */
+
+#endif /* __ASM_PARAVIRT_IRQ_H */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 12/15] ia64/pv_ops: define initialization hooks, pv_init_ops, for paravirtualized environment.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (12 preceding siblings ...)
2008-04-09 4:49 ` Isaku Yamahata
@ 2008-04-09 4:49 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 13/15] ia64/pv_ops: add hooks, pv_iosapic_ops, to paravirtualize iosapic Isaku Yamahata
` (2 subsequent siblings)
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64
Cc: yamahata, xen-ia64-devel, eddie.dong, Alex Williamson,
virtualization
define pv_init_ops hooks which represents various initialization
hooks for paravirtualized environment. and add hooks.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/paravirt.c | 7 ++++
arch/ia64/kernel/setup.c | 10 ++++++
arch/ia64/kernel/smpboot.c | 2 +
include/asm-ia64/paravirt.h | 70 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index 6d7ae59..0b57a8d 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -41,6 +41,13 @@ struct pv_info pv_info = {
};
/***************************************************************************
+ * pv_init_ops
+ * initialization hooks.
+ */
+
+struct pv_init_ops pv_init_ops;
+
+/***************************************************************************
* pv_cpu_ops
* intrinsics hooks.
*/
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 4aa9eae..c7e95ba 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -51,6 +51,7 @@
#include <asm/mca.h>
#include <asm/meminit.h>
#include <asm/page.h>
+#include <asm/paravirt.h>
#include <asm/patch.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
@@ -288,6 +289,8 @@ reserve_memory (void)
rsvd_region[n].end = (unsigned long) ia64_imva(_end);
n++;
+ n += paravirt_reserve_memory(&rsvd_region[n]);
+
#ifdef CONFIG_BLK_DEV_INITRD
if (ia64_boot_param->initrd_start) {
rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start);
@@ -466,6 +469,8 @@ setup_arch (char **cmdline_p)
{
unw_init();
+ paravirt_arch_setup_early();
+
ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
*cmdline_p = __va(ia64_boot_param->command_line);
@@ -518,6 +523,9 @@ setup_arch (char **cmdline_p)
acpi_boot_init();
#endif
+ paravirt_banner();
+ paravirt_arch_setup_console(cmdline_p);
+
#ifdef CONFIG_VT
if (!conswitchp) {
# if defined(CONFIG_DUMMY_CONSOLE)
@@ -537,6 +545,8 @@ setup_arch (char **cmdline_p)
#endif
/* enable IA-64 Machine Check Abort Handling unless disabled */
+ if (paravirt_arch_setup_nomca())
+ nomca = 1;
if (!nomca)
ia64_mca_init();
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 32ee597..e7ce751 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -50,6 +50,7 @@
#include <asm/machvec.h>
#include <asm/mca.h>
#include <asm/page.h>
+#include <asm/paravirt.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
@@ -642,6 +643,7 @@ void __devinit smp_prepare_boot_cpu(void)
cpu_set(smp_processor_id(), cpu_online_map);
cpu_set(smp_processor_id(), cpu_callin_map);
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+ paravirt_post_smp_prepare_boot_cpu();
}
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h
index 26b4334..8778e8b 100644
--- a/include/asm-ia64/paravirt.h
+++ b/include/asm-ia64/paravirt.h
@@ -52,11 +52,81 @@ static inline unsigned int get_kernel_rpl(void)
return pv_info.kernel_rpl;
}
+/******************************************************************************
+ * initialization hooks.
+ */
+struct rsvd_region;
+
+struct pv_init_ops {
+ void (*banner)(void);
+
+ int (*reserve_memory)(struct rsvd_region *region);
+
+ void (*arch_setup_early)(void);
+ void (*arch_setup_console)(char **cmdline_p);
+ int (*arch_setup_nomca)(void);
+
+ void (*post_smp_prepare_boot_cpu)(void);
+};
+
+extern struct pv_init_ops pv_init_ops;
+
+static inline void paravirt_banner(void)
+{
+ if (pv_init_ops.banner)
+ pv_init_ops.banner();
+}
+
+static inline int paravirt_reserve_memory(struct rsvd_region *region)
+{
+ if (pv_init_ops.reserve_memory)
+ return pv_init_ops.reserve_memory(region);
+ return 0;
+}
+
+static inline void paravirt_arch_setup_early(void)
+{
+ if (pv_init_ops.arch_setup_early)
+ pv_init_ops.arch_setup_early();
+}
+
+static inline void paravirt_arch_setup_console(char **cmdline_p)
+{
+ if (pv_init_ops.arch_setup_console)
+ pv_init_ops.arch_setup_console(cmdline_p);
+}
+
+static inline int paravirt_arch_setup_nomca(void)
+{
+ if (pv_init_ops.arch_setup_nomca)
+ return pv_init_ops.arch_setup_nomca();
+ return 0;
+}
+
+static inline void paravirt_post_smp_prepare_boot_cpu(void)
+{
+ if (pv_init_ops.post_smp_prepare_boot_cpu)
+ pv_init_ops.post_smp_prepare_boot_cpu();
+}
+
#endif /* !__ASSEMBLY__ */
#else
/* fallback for native case */
+#ifndef __ASSEMBLY__
+
+#define paravirt_banner() do { } while (0)
+#define paravirt_reserve_memory(region) 0
+
+#define paravirt_arch_setup_early() do { } while (0)
+#define paravirt_arch_setup_console(cmdline_p) do { } while (0)
+#define paravirt_arch_setup_nomca() 0
+#define paravirt_post_smp_prepare_boot_cpu() do { } while (0)
+
+#endif /* __ASSEMBLY__ */
+
+
#endif /* CONFIG_PARAVIRT_GUEST */
#endif /* __ASM_PARAVIRT_H */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 13/15] ia64/pv_ops: add hooks, pv_iosapic_ops, to paravirtualize iosapic.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (13 preceding siblings ...)
2008-04-09 4:49 ` [PATCH 12/15] ia64/pv_ops: define initialization hooks, pv_init_ops, for paravirtualized environment Isaku Yamahata
@ 2008-04-09 4:49 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 14/15] ia64/pv_ops: add hooks, pv_irq_ops, to paravirtualized irq related operations Isaku Yamahata
2008-04-09 4:49 ` [PATCH 15/15] ia64/pv_ops: add to hooks, pv_time_ops, for steal time accounting Isaku Yamahata
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
add hooks to paravirtualize iosapic which is a real hardware resource.
On virtualized environment it may be replaced something virtualized
friendly.
Define pv_iosapic_ops and add the hooks.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/iosapic.c | 45 +++++++++++++++++++++++++++---------------
arch/ia64/kernel/paravirt.c | 25 +++++++++++++++++++++++
include/asm-ia64/iosapic.h | 18 +++++++++++++++-
include/asm-ia64/paravirt.h | 40 ++++++++++++++++++++++++++++++++++++++
4 files changed, 110 insertions(+), 18 deletions(-)
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 082c31d..587196d 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -587,6 +587,15 @@ static inline int irq_is_shared (int irq)
return (iosapic_intr_info[irq].count > 1);
}
+struct irq_chip*
+ia64_native_iosapic_get_irq_chip(unsigned long trigger)
+{
+ if (trigger == IOSAPIC_EDGE)
+ return &irq_type_iosapic_edge;
+ else
+ return &irq_type_iosapic_level;
+}
+
static int
register_intr (unsigned int gsi, int irq, unsigned char delivery,
unsigned long polarity, unsigned long trigger)
@@ -637,13 +646,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
iosapic_intr_info[irq].dmode = delivery;
iosapic_intr_info[irq].trigger = trigger;
- if (trigger == IOSAPIC_EDGE)
- irq_type = &irq_type_iosapic_edge;
- else
- irq_type = &irq_type_iosapic_level;
+ irq_type = iosapic_get_irq_chip(trigger);
idesc = irq_desc + irq;
- if (idesc->chip != irq_type) {
+ if (irq_type != NULL && idesc->chip != irq_type) {
if (idesc->chip != &no_irq_type)
printk(KERN_WARNING
"%s: changing vector %d from %s to %s\n",
@@ -976,6 +982,22 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
}
void __init
+ia64_native_iosapic_pcat_compat_init(void)
+{
+ if (pcat_compat) {
+ /*
+ * Disable the compatibility mode interrupts (8259 style),
+ * needs IN/OUT support enabled.
+ */
+ printk(KERN_INFO
+ "%s: Disabling PC-AT compatible 8259 interrupts\n",
+ __func__);
+ outb(0xff, 0xA1);
+ outb(0xff, 0x21);
+ }
+}
+
+void __init
iosapic_system_init (int system_pcat_compat)
{
int irq;
@@ -989,17 +1011,8 @@ iosapic_system_init (int system_pcat_compat)
}
pcat_compat = system_pcat_compat;
- if (pcat_compat) {
- /*
- * Disable the compatibility mode interrupts (8259 style),
- * needs IN/OUT support enabled.
- */
- printk(KERN_INFO
- "%s: Disabling PC-AT compatible 8259 interrupts\n",
- __func__);
- outb(0xff, 0xA1);
- outb(0xff, 0x21);
- }
+ if (pcat_compat)
+ iosapic_pcat_compat_init();
}
static inline int
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index 0b57a8d..4c54319 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -310,3 +310,28 @@ paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch)
cpu_asm_switch->work_processed_syscall;
paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel;
}
+
+/***************************************************************************
+ * pv_iosapic_ops
+ * iosapic read/write hooks.
+ */
+
+static unsigned int
+ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
+{
+ return __ia64_native_iosapic_read(iosapic, reg);
+}
+
+static void
+ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
+{
+ __ia64_native_iosapic_write(iosapic, reg, val);
+}
+
+struct pv_iosapic_ops pv_iosapic_ops = {
+ .pcat_compat_init = ia64_native_iosapic_pcat_compat_init,
+ .get_irq_chip = ia64_native_iosapic_get_irq_chip,
+
+ .__read = ia64_native_iosapic_read,
+ .__write = ia64_native_iosapic_write,
+};
diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h
index a3a4288..b9c102e 100644
--- a/include/asm-ia64/iosapic.h
+++ b/include/asm-ia64/iosapic.h
@@ -55,13 +55,27 @@
#define NR_IOSAPICS 256
-static inline unsigned int __iosapic_read(char __iomem *iosapic, unsigned int reg)
+#ifdef CONFIG_PARAVIRT_GUEST
+#include <asm/paravirt.h>
+#else
+#define iosapic_pcat_compat_init ia64_native_iosapic_pcat_compat_init
+#define __iosapic_read __ia64_native_iosapic_read
+#define __iosapic_write __ia64_native_iosapic_write
+#define iosapic_get_irq_chip ia64_native_iosapic_get_irq_chip
+#endif
+
+extern void __init ia64_native_iosapic_pcat_compat_init(void);
+extern struct irq_chip *ia64_native_iosapic_get_irq_chip(unsigned long trigger);
+
+static inline unsigned int
+__ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
{
writel(reg, iosapic + IOSAPIC_REG_SELECT);
return readl(iosapic + IOSAPIC_WINDOW);
}
-static inline void __iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
+static inline void
+__ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
{
writel(reg, iosapic + IOSAPIC_REG_SELECT);
writel(val, iosapic + IOSAPIC_WINDOW);
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h
index 8778e8b..48887a4 100644
--- a/include/asm-ia64/paravirt.h
+++ b/include/asm-ia64/paravirt.h
@@ -109,6 +109,46 @@ static inline void paravirt_post_smp_prepare_boot_cpu(void)
pv_init_ops.post_smp_prepare_boot_cpu();
}
+/******************************************************************************
+ * replacement of iosapic operations.
+ */
+
+struct pv_iosapic_ops {
+ void (*pcat_compat_init)(void);
+
+ struct irq_chip *(*get_irq_chip)(unsigned long trigger);
+
+ unsigned int (*__read)(char __iomem *iosapic, unsigned int reg);
+ void (*__write)(char __iomem *iosapic, unsigned int reg, u32 val);
+};
+
+extern struct pv_iosapic_ops pv_iosapic_ops;
+
+static inline void
+iosapic_pcat_compat_init(void)
+{
+ if (pv_iosapic_ops.pcat_compat_init)
+ pv_iosapic_ops.pcat_compat_init();
+}
+
+static inline struct irq_chip*
+iosapic_get_irq_chip(unsigned long trigger)
+{
+ return pv_iosapic_ops.get_irq_chip(trigger);
+}
+
+static inline unsigned int
+__iosapic_read(char __iomem *iosapic, unsigned int reg)
+{
+ return pv_iosapic_ops.__read(iosapic, reg);
+}
+
+static inline void
+__iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
+{
+ return pv_iosapic_ops.__write(iosapic, reg, val);
+}
+
#endif /* !__ASSEMBLY__ */
#else
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 14/15] ia64/pv_ops: add hooks, pv_irq_ops, to paravirtualized irq related operations.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (14 preceding siblings ...)
2008-04-09 4:49 ` [PATCH 13/15] ia64/pv_ops: add hooks, pv_iosapic_ops, to paravirtualize iosapic Isaku Yamahata
@ 2008-04-09 4:49 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 15/15] ia64/pv_ops: add to hooks, pv_time_ops, for steal time accounting Isaku Yamahata
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
introduce pv_irq_ops which adds hooks to paravirtualize irq related
operations.
On virtualized environment, interruption may be replaced by something
virtualization friendly. So the irq related operation also may need
paravirtualization.
This patch adds necessary hooks to paravirtualize irq related operations.
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/irq_ia64.c | 18 +++++++++++----
arch/ia64/kernel/paravirt.c | 15 +++++++++++++
include/asm-ia64/hw_irq.h | 23 +++++++++++++++++---
include/asm-ia64/paravirt.h | 48 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 95 insertions(+), 9 deletions(-)
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 711635d..d5e2a14 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -196,7 +196,7 @@ static void clear_irq_vector(int irq)
}
int
-assign_irq_vector (int irq)
+ia64_native_assign_irq_vector (int irq)
{
unsigned long flags;
int vector, cpu;
@@ -222,7 +222,7 @@ assign_irq_vector (int irq)
}
void
-free_irq_vector (int vector)
+ia64_native_free_irq_vector (int vector)
{
if (vector < IA64_FIRST_DEVICE_VECTOR ||
vector > IA64_LAST_DEVICE_VECTOR)
@@ -622,7 +622,7 @@ static struct irqaction tlb_irqaction = {
#endif
void
-register_percpu_irq (ia64_vector vec, struct irqaction *action)
+ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action)
{
irq_desc_t *desc;
unsigned int irq;
@@ -637,13 +637,21 @@ register_percpu_irq (ia64_vector vec, struct irqaction *action)
}
void __init
-init_IRQ (void)
+ia64_native_register_ipi(void)
{
- register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
#ifdef CONFIG_SMP
register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &tlb_irqaction);
+#endif
+}
+
+void __init
+init_IRQ (void)
+{
+ ia64_register_ipi();
+ register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
+#ifdef CONFIG_SMP
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)
if (vector_domain_type != VECTOR_DOMAIN_NONE) {
BUG_ON(IA64_FIRST_DEVICE_VECTOR != IA64_IRQ_MOVE_VECTOR);
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index 4c54319..8e47c3f 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -335,3 +335,18 @@ struct pv_iosapic_ops pv_iosapic_ops = {
.__read = ia64_native_iosapic_read,
.__write = ia64_native_iosapic_write,
};
+
+/***************************************************************************
+ * pv_irq_ops
+ * irq operations
+ */
+
+struct pv_irq_ops pv_irq_ops = {
+ .register_ipi = ia64_native_register_ipi,
+
+ .assign_irq_vector = ia64_native_assign_irq_vector,
+ .free_irq_vector = ia64_native_free_irq_vector,
+ .register_percpu_irq = ia64_native_register_percpu_irq,
+
+ .resend_irq = ia64_native_resend_irq,
+};
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
index 76366dc..5c99cbc 100644
--- a/include/asm-ia64/hw_irq.h
+++ b/include/asm-ia64/hw_irq.h
@@ -15,7 +15,11 @@
#include <asm/ptrace.h>
#include <asm/smp.h>
+#ifndef CONFIG_PARAVIRT
typedef u8 ia64_vector;
+#else
+typedef u16 ia64_vector;
+#endif
/*
* 0 special
@@ -104,13 +108,24 @@ DECLARE_PER_CPU(int[IA64_NUM_VECTORS], vector_irq);
extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt controller */
+#ifdef CONFIG_PARAVIRT_GUEST
+#include <asm/paravirt.h>
+#else
+#define ia64_register_ipi ia64_native_register_ipi
+#define assign_irq_vector ia64_native_assign_irq_vector
+#define free_irq_vector ia64_native_free_irq_vector
+#define register_percpu_irq ia64_native_register_percpu_irq
+#define ia64_resend_irq ia64_native_resend_irq
+#endif
+
+extern void ia64_native_register_ipi(void);
extern int bind_irq_vector(int irq, int vector, cpumask_t domain);
-extern int assign_irq_vector (int irq); /* allocate a free vector */
-extern void free_irq_vector (int vector);
+extern int ia64_native_assign_irq_vector (int irq); /* allocate a free vector */
+extern void ia64_native_free_irq_vector (int vector);
extern int reserve_irq_vector (int vector);
extern void __setup_vector_irq(int cpu);
extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
-extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
+extern void ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action);
extern int check_irq_used (int irq);
extern void destroy_and_reserve_irq (unsigned int irq);
@@ -122,7 +137,7 @@ static inline int irq_prepare_move(int irq, int cpu) { return 0; }
static inline void irq_complete_move(unsigned int irq) {}
#endif
-static inline void ia64_resend_irq(unsigned int vector)
+static inline void ia64_native_resend_irq(unsigned int vector)
{
platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
}
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h
index 48887a4..2203e9a 100644
--- a/include/asm-ia64/paravirt.h
+++ b/include/asm-ia64/paravirt.h
@@ -149,6 +149,54 @@ __iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
return pv_iosapic_ops.__write(iosapic, reg, val);
}
+/******************************************************************************
+ * replacement of irq operations.
+ */
+
+struct pv_irq_ops {
+ void (*register_ipi)(void);
+
+ int (*assign_irq_vector)(int irq);
+ void (*free_irq_vector)(int vector);
+
+ void (*register_percpu_irq)(ia64_vector vec,
+ struct irqaction *action);
+
+ void (*resend_irq)(unsigned int vector);
+};
+
+extern struct pv_irq_ops pv_irq_ops;
+
+static inline void
+ia64_register_ipi(void)
+{
+ pv_irq_ops.register_ipi();
+}
+
+static inline int
+assign_irq_vector(int irq)
+{
+ return pv_irq_ops.assign_irq_vector(irq);
+}
+
+static inline void
+free_irq_vector(int vector)
+{
+ return pv_irq_ops.free_irq_vector(vector);
+}
+
+static inline void
+register_percpu_irq(ia64_vector vec, struct irqaction *action)
+{
+ pv_irq_ops.register_percpu_irq(vec, action);
+}
+
+static inline void
+ia64_resend_irq(unsigned int vector)
+{
+ pv_irq_ops.resend_irq(vector);
+}
+
#endif /* !__ASSEMBLY__ */
#else
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 15/15] ia64/pv_ops: add to hooks, pv_time_ops, for steal time accounting.
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
` (15 preceding siblings ...)
2008-04-09 4:49 ` [PATCH 14/15] ia64/pv_ops: add hooks, pv_irq_ops, to paravirtualized irq related operations Isaku Yamahata
@ 2008-04-09 4:49 ` Isaku Yamahata
16 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-09 4:49 UTC (permalink / raw)
To: linux-ia64; +Cc: yamahata, xen-ia64-devel, eddie.dong, virtualization
Introduce pv_time_ops which adds hook to steal time accounting.
On virtualized environment, cpus are shared by many guests and
steal time is the time which is used for other guests.
On virtualized environtment, streal time should be accounted.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/paravirt.c | 15 +++++++++++++++
arch/ia64/kernel/time.c | 23 +++++++++++++++++++++++
include/asm-ia64/paravirt.h | 32 ++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index 8e47c3f..433cb9b 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -350,3 +350,18 @@ struct pv_irq_ops pv_irq_ops = {
.resend_irq = ia64_native_resend_irq,
};
+
+/***************************************************************************
+ * pv_time_ops
+ * time operations
+ */
+
+static int
+ia64_native_do_steal_accounting(unsigned long *new_itm)
+{
+ return 0;
+}
+
+struct pv_time_ops pv_time_ops = {
+ .do_steal_accounting = ia64_native_do_steal_accounting,
+};
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 17fda52..6fecc47 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -24,6 +24,7 @@
#include <asm/machvec.h>
#include <asm/delay.h>
#include <asm/hw_irq.h>
+#include <asm/paravirt.h>
#include <asm/ptrace.h>
#include <asm/sal.h>
#include <asm/sections.h>
@@ -48,6 +49,15 @@ EXPORT_SYMBOL(last_cli_ip);
#endif
+#ifdef CONFIG_PARAVIRT
+static void
+paravirt_clocksource_resume(void)
+{
+ if (pv_time_ops.clocksource_resume)
+ pv_time_ops.clocksource_resume();
+}
+#endif
+
static struct clocksource clocksource_itc = {
.name = "itc",
.rating = 350,
@@ -56,6 +66,9 @@ static struct clocksource clocksource_itc = {
.mult = 0, /*to be calculated*/
.shift = 16,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+#ifdef CONFIG_PARAVIRT
+ .resume = paravirt_clocksource_resume,
+#endif
};
static struct clocksource *itc_clocksource;
@@ -78,6 +91,9 @@ timer_interrupt (int irq, void *dev_id)
profile_tick(CPU_PROFILING);
+ if (paravirt_do_steal_accounting(&new_itm))
+ goto skip_process_time_accounting;
+
while (1) {
update_process_times(user_mode(get_irq_regs()));
@@ -107,6 +123,8 @@ timer_interrupt (int irq, void *dev_id)
local_irq_disable();
}
+skip_process_time_accounting:
+
do {
/*
* If we're too close to the next clock tick for
@@ -256,6 +274,11 @@ ia64_init_itm (void)
*/
clocksource_itc.rating = 50;
+ paravirt_init_missing_ticks_accounting(smp_processor_id());
+
+ /* avoid softlock up message when cpu is unplug and plugged again. */
+ touch_softlockup_watchdog();
+
/* Setup the CPU local timer tick */
ia64_cpu_local_tick();
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h
index 2203e9a..44017c1 100644
--- a/include/asm-ia64/paravirt.h
+++ b/include/asm-ia64/paravirt.h
@@ -197,6 +197,35 @@ ia64_resend_irq(unsigned int vector)
pv_irq_ops.resend_irq(vector);
}
+/******************************************************************************
+ * replacement of time operations.
+ */
+
+extern struct itc_jitter_data_t itc_jitter_data;
+extern volatile int time_keeper_id;
+
+struct pv_time_ops {
+ void (*init_missing_ticks_accounting)(int cpu);
+ int (*do_steal_accounting)(unsigned long *new_itm);
+
+ void (*clocksource_resume)(void);
+};
+
+extern struct pv_time_ops pv_time_ops;
+
+static inline void
+paravirt_init_missing_ticks_accounting(int cpu)
+{
+ if (pv_time_ops.init_missing_ticks_accounting)
+ pv_time_ops.init_missing_ticks_accounting(cpu);
+}
+
+static inline int
+paravirt_do_steal_accounting(unsigned long *new_itm)
+{
+ return pv_time_ops.do_steal_accounting(new_itm);
+}
+
#endif /* !__ASSEMBLY__ */
#else
@@ -212,6 +241,9 @@ ia64_resend_irq(unsigned int vector)
#define paravirt_arch_setup_nomca() 0
#define paravirt_post_smp_prepare_boot_cpu() do { } while (0)
+#define paravirt_init_missing_ticks_accounting(cpu) do { } while (0)
+#define paravirt_do_steal_accounting(new_itm) 0
+
#endif /* __ASSEMBLY__ */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
2008-04-22 9:08 ` Jes Sorensen
@ 2008-04-22 9:08 ` Jes Sorensen
2008-04-22 10:11 ` Isaku Yamahata
2008-04-22 10:11 ` Isaku Yamahata
` (7 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 9:08 UTC (permalink / raw)
To: linux-ia64
> Make NR_IRQ overridable by each pv instances.
> Pv instance may need each own number of irqs so that
> NR_IRQS should be the maximum number of nr_irqs each
> pv instances need.
This really looks dodgy.
+#ifdef CONFIG_PARAVIRT
+
+/* Determine the maximal NR_IRQ which each pv instances require.
+ * i.e. NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...)
+ */
+
+#define NR_IRQS 1
+
+#if IA64_NATIVE_NR_IRQS > NR_IRQS
+#undef NR_IRQS
+#define NR_IRQS IA64_NATIVE_NR_IRQS
+#endif
+
+#ifdef CONFIG_XEN
+#include <asm/xen/irq.h>
+#if XEN_NR_IRQS > NR_IRQS
+#undef NR_IRQS
+#define NR_IRQS XEN_NR_IRQS
+#endif
+#endif /* CONFIG_XEN */
I don't see why Xen needs special casing here, it really makes the
code gross. Please use one typedef for this, like PARAVIRT_NR_IRQS or
something like that, so we don't end up with a KVM special case, an
LGUEST special case and a Xen special case.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
@ 2008-04-22 9:08 ` Jes Sorensen
2008-04-22 9:08 ` Jes Sorensen
` (8 subsequent siblings)
9 siblings, 0 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 9:08 UTC (permalink / raw)
To: Isaku Yamahata; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
> Make NR_IRQ overridable by each pv instances.
> Pv instance may need each own number of irqs so that
> NR_IRQS should be the maximum number of nr_irqs each
> pv instances need.
This really looks dodgy.
+#ifdef CONFIG_PARAVIRT
+
+/* Determine the maximal NR_IRQ which each pv instances require.
+ * i.e. NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...)
+ */
+
+#define NR_IRQS 1
+
+#if IA64_NATIVE_NR_IRQS > NR_IRQS
+#undef NR_IRQS
+#define NR_IRQS IA64_NATIVE_NR_IRQS
+#endif
+
+#ifdef CONFIG_XEN
+#include <asm/xen/irq.h>
+#if XEN_NR_IRQS > NR_IRQS
+#undef NR_IRQS
+#define NR_IRQS XEN_NR_IRQS
+#endif
+#endif /* CONFIG_XEN */
I don't see why Xen needs special casing here, it really makes the
code gross. Please use one typedef for this, like PARAVIRT_NR_IRQS or
something like that, so we don't end up with a KVM special case, an
LGUEST special case and a Xen special case.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-09 4:48 ` Isaku Yamahata
2008-04-22 9:16 ` Jes Sorensen
@ 2008-04-22 9:16 ` Jes Sorensen
2008-04-22 10:02 ` Isaku Yamahata
2008-04-22 10:02 ` Isaku Yamahata
` (7 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 9:16 UTC (permalink / raw)
To: linux-ia64
>>>>> "Isaku" = Isaku Yamahata <yamahata@valinux.co.jp> writes:
Isaku> introduce pv_info which describes some randome info about
Isaku> underlying execution environment.
Hi Isaku,
I am missing some of the patches in this series for some reason.
However, I'd like to open the discussion and ask why you are
implementing the pv-ops seperately instead of adding them to the
machine vectors and using the machine vector interface to handle the
direct implementation?
It seems to me that pvops really are just an advanced level of the
ia64 machine vectors and building on top of the interface we already
have would make it easier to support different machine types through
pvops.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-09 4:48 ` Isaku Yamahata
@ 2008-04-22 9:16 ` Jes Sorensen
2008-04-22 9:16 ` Jes Sorensen
` (8 subsequent siblings)
9 siblings, 0 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 9:16 UTC (permalink / raw)
To: Isaku Yamahata; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
>>>>> "Isaku" == Isaku Yamahata <yamahata@valinux.co.jp> writes:
Isaku> introduce pv_info which describes some randome info about
Isaku> underlying execution environment.
Hi Isaku,
I am missing some of the patches in this series for some reason.
However, I'd like to open the discussion and ask why you are
implementing the pv-ops seperately instead of adding them to the
machine vectors and using the machine vector interface to handle the
direct implementation?
It seems to me that pvops really are just an advanced level of the
ia64 machine vectors and building on top of the interface we already
have would make it easier to support different machine types through
pvops.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-09 4:48 ` Isaku Yamahata
2008-04-22 9:16 ` Jes Sorensen
2008-04-22 9:16 ` Jes Sorensen
@ 2008-04-22 10:02 ` Isaku Yamahata
2008-04-22 10:37 ` Jes Sorensen
2008-04-22 10:37 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
` (6 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-22 10:02 UTC (permalink / raw)
To: linux-ia64
On Tue, Apr 22, 2008 at 05:16:41AM -0400, Jes Sorensen wrote:
> >>>>> "Isaku" = Isaku Yamahata <yamahata@valinux.co.jp> writes:
>
> Isaku> introduce pv_info which describes some randome info about
> Isaku> underlying execution environment.
>
> Hi Isaku,
Hi. I'm very glad to get reply.
> I am missing some of the patches in this series for some reason.
> However, I'd like to open the discussion and ask why you are
> implementing the pv-ops seperately instead of adding them to the
> machine vectors and using the machine vector interface to handle the
> direct implementation?
>
> It seems to me that pvops really are just an advanced level of the
> ia64 machine vectors and building on top of the interface we already
> have would make it easier to support different machine types through
> pvops.
Okay. Your question is quite reasonable and very good one.
In fact the current xen domU implementation is using both
pv_ops and machine vector because it simplifies the code.
pv_ops somewhat overlaps with machine vector.
Our justification is as follows.
The difference is its scope. pv_ops for virtualization and
machine vector is for platform difference.
- pv_ops does cover the area which shouldn't belong to machine vector.
For example, ia64 intrinsics paravirtualization.
It shouldn't belong to the machine vector.
It must be initialized very early before platform detection.
- pv_ops covers some performance critical part (e.g. ia64 intrinsics)
so that in the future they should be optimized with binary patch like x86.
We had the experimental patch to do that, but they are dropped for
the merge. It reduced patch size greatly.
After merging the first patch series, we're planning to optimize
pv_ops with binary patch.
The optimization with binary patch is out of the machine vector scope.
- The current pv_ops implements only one for only domU, but in future
pv_ops will support dom0. It means dom0 linux would run with
the underlying machine vector + pv_ops, i.e.
{dig, hpzx1, hpzx1_swiotlb, ...} machine vector + xen pv_ops
Probably some hooks of pv_ops could be replaced with
enhancing machine vector. But from the above separating pv_ops from
machine vector looks reasonable.
Integrating pv_ops functionality to machine vector would complicate
the machine vector implementation unnecessary, I think.
thanks,
--
yamahata
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-22 9:16 ` Jes Sorensen
@ 2008-04-22 10:02 ` Isaku Yamahata
0 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-22 10:02 UTC (permalink / raw)
To: Jes Sorensen; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
On Tue, Apr 22, 2008 at 05:16:41AM -0400, Jes Sorensen wrote:
> >>>>> "Isaku" == Isaku Yamahata <yamahata@valinux.co.jp> writes:
>
> Isaku> introduce pv_info which describes some randome info about
> Isaku> underlying execution environment.
>
> Hi Isaku,
Hi. I'm very glad to get reply.
> I am missing some of the patches in this series for some reason.
> However, I'd like to open the discussion and ask why you are
> implementing the pv-ops seperately instead of adding them to the
> machine vectors and using the machine vector interface to handle the
> direct implementation?
>
> It seems to me that pvops really are just an advanced level of the
> ia64 machine vectors and building on top of the interface we already
> have would make it easier to support different machine types through
> pvops.
Okay. Your question is quite reasonable and very good one.
In fact the current xen domU implementation is using both
pv_ops and machine vector because it simplifies the code.
pv_ops somewhat overlaps with machine vector.
Our justification is as follows.
The difference is its scope. pv_ops for virtualization and
machine vector is for platform difference.
- pv_ops does cover the area which shouldn't belong to machine vector.
For example, ia64 intrinsics paravirtualization.
It shouldn't belong to the machine vector.
It must be initialized very early before platform detection.
- pv_ops covers some performance critical part (e.g. ia64 intrinsics)
so that in the future they should be optimized with binary patch like x86.
We had the experimental patch to do that, but they are dropped for
the merge. It reduced patch size greatly.
After merging the first patch series, we're planning to optimize
pv_ops with binary patch.
The optimization with binary patch is out of the machine vector scope.
- The current pv_ops implements only one for only domU, but in future
pv_ops will support dom0. It means dom0 linux would run with
the underlying machine vector + pv_ops, i.e.
{dig, hpzx1, hpzx1_swiotlb, ...} machine vector + xen pv_ops
Probably some hooks of pv_ops could be replaced with
enhancing machine vector. But from the above separating pv_ops from
machine vector looks reasonable.
Integrating pv_ops functionality to machine vector would complicate
the machine vector implementation unnecessary, I think.
thanks,
--
yamahata
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
2008-04-22 9:08 ` Jes Sorensen
2008-04-22 9:08 ` Jes Sorensen
@ 2008-04-22 10:11 ` Isaku Yamahata
2008-04-22 12:05 ` Jes Sorensen
2008-04-22 12:05 ` Jes Sorensen
` (6 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-22 10:11 UTC (permalink / raw)
To: linux-ia64
On Tue, Apr 22, 2008 at 05:08:22AM -0400, Jes Sorensen wrote:
>
> > Make NR_IRQ overridable by each pv instances.
> > Pv instance may need each own number of irqs so that
> > NR_IRQS should be the maximum number of nr_irqs each
> > pv instances need.
>
> This really looks dodgy.
>
> +#ifdef CONFIG_PARAVIRT
> +
> +/* Determine the maximal NR_IRQ which each pv instances require.
> + * i.e. NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...)
> + */
> +
> +#define NR_IRQS 1
> +
> +#if IA64_NATIVE_NR_IRQS > NR_IRQS
> +#undef NR_IRQS
> +#define NR_IRQS IA64_NATIVE_NR_IRQS
> +#endif
> +
> +#ifdef CONFIG_XEN
> +#include <asm/xen/irq.h>
> +#if XEN_NR_IRQS > NR_IRQS
> +#undef NR_IRQS
> +#define NR_IRQS XEN_NR_IRQS
> +#endif
> +#endif /* CONFIG_XEN */
>
> I don't see why Xen needs special casing here, it really makes the
> code gross. Please use one typedef for this, like PARAVIRT_NR_IRQS or
> something like that, so we don't end up with a KVM special case, an
> LGUEST special case and a Xen special case.
I'm willing to introduce something like PARAVIRT_NR_IRQS,
but I don't see how PARAVIRT_NR_IRQS solves the issues.
What I want here is to define by cpp
#define PARAVIRT_NR_IRQS \
max( \
IA64_NATIVE_NR_IRQS, \
XEN_NR_IRQS, /* only if CONFIG_XEN */ \
LGUSET_NR_IRQS, /* only if CONFIG_LGUSET */ \
KVM_GUEST_NR_IRQS, /* only if CONFIG_KVM_GUEST */ \
MORE_FUTURE_VM_NR_IRQS, /* only if ...*/ \
.... \
)
Probably I'm missing something.
Could you suggest more concretly? Hopefully (pseudo) code snippet.
--
yamahata
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-22 9:08 ` Jes Sorensen
@ 2008-04-22 10:11 ` Isaku Yamahata
0 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-22 10:11 UTC (permalink / raw)
To: Jes Sorensen; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
On Tue, Apr 22, 2008 at 05:08:22AM -0400, Jes Sorensen wrote:
>
> > Make NR_IRQ overridable by each pv instances.
> > Pv instance may need each own number of irqs so that
> > NR_IRQS should be the maximum number of nr_irqs each
> > pv instances need.
>
> This really looks dodgy.
>
> +#ifdef CONFIG_PARAVIRT
> +
> +/* Determine the maximal NR_IRQ which each pv instances require.
> + * i.e. NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...)
> + */
> +
> +#define NR_IRQS 1
> +
> +#if IA64_NATIVE_NR_IRQS > NR_IRQS
> +#undef NR_IRQS
> +#define NR_IRQS IA64_NATIVE_NR_IRQS
> +#endif
> +
> +#ifdef CONFIG_XEN
> +#include <asm/xen/irq.h>
> +#if XEN_NR_IRQS > NR_IRQS
> +#undef NR_IRQS
> +#define NR_IRQS XEN_NR_IRQS
> +#endif
> +#endif /* CONFIG_XEN */
>
> I don't see why Xen needs special casing here, it really makes the
> code gross. Please use one typedef for this, like PARAVIRT_NR_IRQS or
> something like that, so we don't end up with a KVM special case, an
> LGUEST special case and a Xen special case.
I'm willing to introduce something like PARAVIRT_NR_IRQS,
but I don't see how PARAVIRT_NR_IRQS solves the issues.
What I want here is to define by cpp
#define PARAVIRT_NR_IRQS \
max( \
IA64_NATIVE_NR_IRQS, \
XEN_NR_IRQS, /* only if CONFIG_XEN */ \
LGUSET_NR_IRQS, /* only if CONFIG_LGUSET */ \
KVM_GUEST_NR_IRQS, /* only if CONFIG_KVM_GUEST */ \
MORE_FUTURE_VM_NR_IRQS, /* only if ...*/ \
.... \
)
Probably I'm missing something.
Could you suggest more concretly? Hopefully (pseudo) code snippet.
--
yamahata
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes
2008-04-09 4:48 ` Isaku Yamahata
` (2 preceding siblings ...)
2008-04-22 10:02 ` Isaku Yamahata
@ 2008-04-22 10:37 ` Jes Sorensen
2008-04-22 10:41 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Dong, Eddie
2008-04-22 11:02 ` Isaku Yamahata
2008-04-22 10:41 ` Dong, Eddie
` (5 subsequent siblings)
9 siblings, 2 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 10:37 UTC (permalink / raw)
To: linux-ia64
Isaku Yamahata wrote:
> Our justification is as follows.
> The difference is its scope. pv_ops for virtualization and
> machine vector is for platform difference.
>
> - pv_ops does cover the area which shouldn't belong to machine vector.
> For example, ia64 intrinsics paravirtualization.
> It shouldn't belong to the machine vector.
> It must be initialized very early before platform detection.
Hi Isaku,
Ok this is a good point.
> - pv_ops covers some performance critical part (e.g. ia64 intrinsics)
> so that in the future they should be optimized with binary patch like x86.
> We had the experimental patch to do that, but they are dropped for
> the merge. It reduced patch size greatly.
> After merging the first patch series, we're planning to optimize
> pv_ops with binary patch.
> The optimization with binary patch is out of the machine vector scope.
Rather than making these binary patches, why not make them fast syscalls
and using a vdso page. Some of the priviledged instructions are simply
reads and we could have that information in a read-only data page, so
there is no need to do a context switch at all. Others could benefit
from a fast system call that doesn't do a full context switch.
It would be nice if we could come up with a generic implementation for
such a vdso style interface that could be shared between xen/kvm/lguest.
> - The current pv_ops implements only one for only domU, but in future
> pv_ops will support dom0. It means dom0 linux would run with
> the underlying machine vector + pv_ops, i.e.
> {dig, hpzx1, hpzx1_swiotlb, ...} machine vector + xen pv_ops
>
> Probably some hooks of pv_ops could be replaced with
> enhancing machine vector. But from the above separating pv_ops from
> machine vector looks reasonable.
Would it make sense to make the pv_ops pointer part of the machine
vector?
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-22 10:02 ` Isaku Yamahata
@ 2008-04-22 10:37 ` Jes Sorensen
0 siblings, 0 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 10:37 UTC (permalink / raw)
To: Isaku Yamahata; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
Isaku Yamahata wrote:
> Our justification is as follows.
> The difference is its scope. pv_ops for virtualization and
> machine vector is for platform difference.
>
> - pv_ops does cover the area which shouldn't belong to machine vector.
> For example, ia64 intrinsics paravirtualization.
> It shouldn't belong to the machine vector.
> It must be initialized very early before platform detection.
Hi Isaku,
Ok this is a good point.
> - pv_ops covers some performance critical part (e.g. ia64 intrinsics)
> so that in the future they should be optimized with binary patch like x86.
> We had the experimental patch to do that, but they are dropped for
> the merge. It reduced patch size greatly.
> After merging the first patch series, we're planning to optimize
> pv_ops with binary patch.
> The optimization with binary patch is out of the machine vector scope.
Rather than making these binary patches, why not make them fast syscalls
and using a vdso page. Some of the priviledged instructions are simply
reads and we could have that information in a read-only data page, so
there is no need to do a context switch at all. Others could benefit
from a fast system call that doesn't do a full context switch.
It would be nice if we could come up with a generic implementation for
such a vdso style interface that could be shared between xen/kvm/lguest.
> - The current pv_ops implements only one for only domU, but in future
> pv_ops will support dom0. It means dom0 linux would run with
> the underlying machine vector + pv_ops, i.e.
> {dig, hpzx1, hpzx1_swiotlb, ...} machine vector + xen pv_ops
>
> Probably some hooks of pv_ops could be replaced with
> enhancing machine vector. But from the above separating pv_ops from
> machine vector looks reasonable.
Would it make sense to make the pv_ops pointer part of the machine
vector?
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* RE: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-09 4:48 ` Isaku Yamahata
` (3 preceding siblings ...)
2008-04-22 10:37 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
@ 2008-04-22 10:41 ` Dong, Eddie
2008-04-22 11:30 ` Jes Sorensen
2008-04-22 11:02 ` Isaku Yamahata
` (4 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Dong, Eddie @ 2008-04-22 10:41 UTC (permalink / raw)
To: linux-ia64
>
> Rather than making these binary patches, why not make them fast
> syscalls and using a vdso page. Some of the priviledged instructions
> are simply reads and we could have that information in a read-only
> data page, so there is no need to do a context switch at all. Others
> could benefit from a fast system call that doesn't do a full context
> switch.
The issue is we don't want to change Linux code a lot, otherwise it
won't be accepted. If we use same logic with original Linux,
but it is using indirect function call now, binary patching could help
in performance.
>
> It would be nice if we could come up with a generic implementation for
> such a vdso style interface that could be shared between
> xen/kvm/lguest.
>
Introducing a new mechanism to use it to replace Linux code to use them
is another different story.
Eddie
^ permalink raw reply [flat|nested] 52+ messages in thread
* RE: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-22 10:37 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
@ 2008-04-22 10:41 ` Dong, Eddie
2008-04-22 11:02 ` Isaku Yamahata
1 sibling, 0 replies; 52+ messages in thread
From: Dong, Eddie @ 2008-04-22 10:41 UTC (permalink / raw)
To: Jes Sorensen, Isaku Yamahata; +Cc: xen-ia64-devel, linux-ia64, virtualization
>
> Rather than making these binary patches, why not make them fast
> syscalls and using a vdso page. Some of the priviledged instructions
> are simply reads and we could have that information in a read-only
> data page, so there is no need to do a context switch at all. Others
> could benefit from a fast system call that doesn't do a full context
> switch.
The issue is we don't want to change Linux code a lot, otherwise it
won't be accepted. If we use same logic with original Linux,
but it is using indirect function call now, binary patching could help
in performance.
>
> It would be nice if we could come up with a generic implementation for
> such a vdso style interface that could be shared between
> xen/kvm/lguest.
>
Introducing a new mechanism to use it to replace Linux code to use them
is another different story.
Eddie
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-09 4:48 ` Isaku Yamahata
` (4 preceding siblings ...)
2008-04-22 10:41 ` Dong, Eddie
@ 2008-04-22 11:02 ` Isaku Yamahata
2008-04-22 11:30 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
` (3 subsequent siblings)
9 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-22 11:02 UTC (permalink / raw)
To: linux-ia64
On Tue, Apr 22, 2008 at 12:37:06PM +0200, Jes Sorensen wrote:
> >- pv_ops covers some performance critical part (e.g. ia64 intrinsics)
> > so that in the future they should be optimized with binary patch like
> > x86.
> > We had the experimental patch to do that, but they are dropped for
> > the merge. It reduced patch size greatly.
> > After merging the first patch series, we're planning to optimize
> > pv_ops with binary patch.
> > The optimization with binary patch is out of the machine vector scope.
>
> Rather than making these binary patches, why not make them fast syscalls
> and using a vdso page. Some of the priviledged instructions are simply
> reads and we could have that information in a read-only data page, so
> there is no need to do a context switch at all. Others could benefit
> from a fast system call that doesn't do a full context switch.
>
> It would be nice if we could come up with a generic implementation for
> such a vdso style interface that could be shared between xen/kvm/lguest.
Yes, the above is possible.
But what if native case? Probably the calling stub code should be
binary patched to eliminate the calling overhead completely.
Anyway binary patch doesn't prevent from implementing the above your proposal.
With binary patch, we can implement vdso page infrastructure in future.
> >- The current pv_ops implements only one for only domU, but in future
> > pv_ops will support dom0. It means dom0 linux would run with
> > the underlying machine vector + pv_ops, i.e.
> > {dig, hpzx1, hpzx1_swiotlb, ...} machine vector + xen pv_ops
> >
> >Probably some hooks of pv_ops could be replaced with
> >enhancing machine vector. But from the above separating pv_ops from
> >machine vector looks reasonable.
>
> Would it make sense to make the pv_ops pointer part of the machine
> vector?
I doubt it because it introduces just one more indirection
pv_ops->ops => machine_vector->pv_ops ->ops.
But it can be done if you like..
--
yamahata
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-22 10:37 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
2008-04-22 10:41 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Dong, Eddie
@ 2008-04-22 11:02 ` Isaku Yamahata
1 sibling, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-22 11:02 UTC (permalink / raw)
To: Jes Sorensen; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
On Tue, Apr 22, 2008 at 12:37:06PM +0200, Jes Sorensen wrote:
> >- pv_ops covers some performance critical part (e.g. ia64 intrinsics)
> > so that in the future they should be optimized with binary patch like
> > x86.
> > We had the experimental patch to do that, but they are dropped for
> > the merge. It reduced patch size greatly.
> > After merging the first patch series, we're planning to optimize
> > pv_ops with binary patch.
> > The optimization with binary patch is out of the machine vector scope.
>
> Rather than making these binary patches, why not make them fast syscalls
> and using a vdso page. Some of the priviledged instructions are simply
> reads and we could have that information in a read-only data page, so
> there is no need to do a context switch at all. Others could benefit
> from a fast system call that doesn't do a full context switch.
>
> It would be nice if we could come up with a generic implementation for
> such a vdso style interface that could be shared between xen/kvm/lguest.
Yes, the above is possible.
But what if native case? Probably the calling stub code should be
binary patched to eliminate the calling overhead completely.
Anyway binary patch doesn't prevent from implementing the above your proposal.
With binary patch, we can implement vdso page infrastructure in future.
> >- The current pv_ops implements only one for only domU, but in future
> > pv_ops will support dom0. It means dom0 linux would run with
> > the underlying machine vector + pv_ops, i.e.
> > {dig, hpzx1, hpzx1_swiotlb, ...} machine vector + xen pv_ops
> >
> >Probably some hooks of pv_ops could be replaced with
> >enhancing machine vector. But from the above separating pv_ops from
> >machine vector looks reasonable.
>
> Would it make sense to make the pv_ops pointer part of the machine
> vector?
I doubt it because it introduces just one more indirection
pv_ops->ops => machine_vector->pv_ops ->ops.
But it can be done if you like..
--
yamahata
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes
2008-04-09 4:48 ` Isaku Yamahata
` (5 preceding siblings ...)
2008-04-22 11:02 ` Isaku Yamahata
@ 2008-04-22 11:30 ` Jes Sorensen
2008-04-22 13:15 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Dong, Eddie
2008-04-22 13:15 ` Dong, Eddie
` (2 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 11:30 UTC (permalink / raw)
To: linux-ia64
Dong, Eddie wrote:
>> Rather than making these binary patches, why not make them fast
>> syscalls and using a vdso page. Some of the priviledged instructions
>> are simply reads and we could have that information in a read-only
>> data page, so there is no need to do a context switch at all. Others
>> could benefit from a fast system call that doesn't do a full context
>> switch.
>
> The issue is we don't want to change Linux code a lot, otherwise it
> won't be accepted. If we use same logic with original Linux,
> but it is using indirect function call now, binary patching could help
> in performance.
Hi Eddie,
Sorry but this is a wrong assumption. If the code is correct then there
is no reason why it will not be accepted. It's far more important to
avoid ugly clutter that makes the code hard to maintain.
>> It would be nice if we could come up with a generic implementation for
>> such a vdso style interface that could be shared between
>> xen/kvm/lguest.
>>
> Introducing a new mechanism to use it to replace Linux code to use them
> is another different story.
If someone starts doing a fast syscall implementation for hypercalls, it
is obvious the person(s) will be asked to make it generic on ia64.
Anything else would be silly, but it would definitely be a good thing to
do.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-22 10:41 ` Dong, Eddie
@ 2008-04-22 11:30 ` Jes Sorensen
0 siblings, 0 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 11:30 UTC (permalink / raw)
To: Dong, Eddie; +Cc: Isaku Yamahata, xen-ia64-devel, linux-ia64, virtualization
Dong, Eddie wrote:
>> Rather than making these binary patches, why not make them fast
>> syscalls and using a vdso page. Some of the priviledged instructions
>> are simply reads and we could have that information in a read-only
>> data page, so there is no need to do a context switch at all. Others
>> could benefit from a fast system call that doesn't do a full context
>> switch.
>
> The issue is we don't want to change Linux code a lot, otherwise it
> won't be accepted. If we use same logic with original Linux,
> but it is using indirect function call now, binary patching could help
> in performance.
Hi Eddie,
Sorry but this is a wrong assumption. If the code is correct then there
is no reason why it will not be accepted. It's far more important to
avoid ugly clutter that makes the code hard to maintain.
>> It would be nice if we could come up with a generic implementation for
>> such a vdso style interface that could be shared between
>> xen/kvm/lguest.
>>
> Introducing a new mechanism to use it to replace Linux code to use them
> is another different story.
If someone starts doing a fast syscall implementation for hypercalls, it
is obvious the person(s) will be asked to make it generic on ia64.
Anything else would be silly, but it would definitely be a good thing to
do.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
` (2 preceding siblings ...)
2008-04-22 10:11 ` Isaku Yamahata
@ 2008-04-22 12:05 ` Jes Sorensen
2008-04-23 2:54 ` Isaku Yamahata
2008-04-23 2:54 ` Isaku Yamahata
` (5 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 12:05 UTC (permalink / raw)
To: linux-ia64
Isaku Yamahata wrote:
> I'm willing to introduce something like PARAVIRT_NR_IRQS,
> but I don't see how PARAVIRT_NR_IRQS solves the issues.
> What I want here is to define by cpp
> #define PARAVIRT_NR_IRQS \
> max( \
> IA64_NATIVE_NR_IRQS, \
> XEN_NR_IRQS, /* only if CONFIG_XEN */ \
> LGUSET_NR_IRQS, /* only if CONFIG_LGUSET */ \
> KVM_GUEST_NR_IRQS, /* only if CONFIG_KVM_GUEST */ \
> MORE_FUTURE_VM_NR_IRQS, /* only if ...*/ \
> .... \
> )
>
> Probably I'm missing something.
> Could you suggest more concretly? Hopefully (pseudo) code snippet.
I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
all of these are constants anyway. If we cannot do that, then it would
be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
header files for Xen/KVM/lguest so we don't get the clutter in the main
makefile.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-22 10:11 ` Isaku Yamahata
@ 2008-04-22 12:05 ` Jes Sorensen
0 siblings, 0 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 12:05 UTC (permalink / raw)
To: Isaku Yamahata; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
Isaku Yamahata wrote:
> I'm willing to introduce something like PARAVIRT_NR_IRQS,
> but I don't see how PARAVIRT_NR_IRQS solves the issues.
> What I want here is to define by cpp
> #define PARAVIRT_NR_IRQS \
> max( \
> IA64_NATIVE_NR_IRQS, \
> XEN_NR_IRQS, /* only if CONFIG_XEN */ \
> LGUSET_NR_IRQS, /* only if CONFIG_LGUSET */ \
> KVM_GUEST_NR_IRQS, /* only if CONFIG_KVM_GUEST */ \
> MORE_FUTURE_VM_NR_IRQS, /* only if ...*/ \
> .... \
> )
>
> Probably I'm missing something.
> Could you suggest more concretly? Hopefully (pseudo) code snippet.
I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
all of these are constants anyway. If we cannot do that, then it would
be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
header files for Xen/KVM/lguest so we don't get the clutter in the main
makefile.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* RE: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-09 4:48 ` Isaku Yamahata
` (6 preceding siblings ...)
2008-04-22 11:30 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
@ 2008-04-22 13:15 ` Dong, Eddie
2008-04-22 13:55 ` Jes Sorensen
2008-04-22 13:55 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
2008-04-30 12:29 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Isaku Yamahata
9 siblings, 1 reply; 52+ messages in thread
From: Dong, Eddie @ 2008-04-22 13:15 UTC (permalink / raw)
To: linux-ia64
Jes Sorensen wrote:
> Dong, Eddie wrote:
>>> Rather than making these binary patches, why not make them fast
>>> syscalls and using a vdso page. Some of the priviledged instructions
>>> are simply reads and we could have that information in a read-only
>>> data page, so there is no need to do a context switch at all. Others
>>> could benefit from a fast system call that doesn't do a full context
>>> switch.
>>
>> The issue is we don't want to change Linux code a lot, otherwise it
>> won't be accepted. If we use same logic with original Linux,
>> but it is using indirect function call now, binary patching could
>> help in performance.
>
> Hi Eddie,
>
> Sorry but this is a wrong assumption. If the code is correct then
> there is no reason why it will not be accepted. It's far more
> important to avoid ugly clutter that makes the code hard to maintain.
>
My understanding is that code such as IVT table are well tuned and you
are really
difficult to pursuade people to replace those privilege resource access
instruction
to use vdso or something equalvalent such as mov GRx=CRy. For those C
code
previlige resource access, like Isaku mentioned, we need to consider
native too.
Anyway binary patching is just an optimization that X86 used and there
is no
reason IA64 can't take. At least replacing indirect function with direct
function
call.
Eddie
^ permalink raw reply [flat|nested] 52+ messages in thread
* RE: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-22 11:30 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
@ 2008-04-22 13:15 ` Dong, Eddie
0 siblings, 0 replies; 52+ messages in thread
From: Dong, Eddie @ 2008-04-22 13:15 UTC (permalink / raw)
To: Jes Sorensen; +Cc: Isaku Yamahata, xen-ia64-devel, linux-ia64, virtualization
Jes Sorensen wrote:
> Dong, Eddie wrote:
>>> Rather than making these binary patches, why not make them fast
>>> syscalls and using a vdso page. Some of the priviledged instructions
>>> are simply reads and we could have that information in a read-only
>>> data page, so there is no need to do a context switch at all. Others
>>> could benefit from a fast system call that doesn't do a full context
>>> switch.
>>
>> The issue is we don't want to change Linux code a lot, otherwise it
>> won't be accepted. If we use same logic with original Linux,
>> but it is using indirect function call now, binary patching could
>> help in performance.
>
> Hi Eddie,
>
> Sorry but this is a wrong assumption. If the code is correct then
> there is no reason why it will not be accepted. It's far more
> important to avoid ugly clutter that makes the code hard to maintain.
>
My understanding is that code such as IVT table are well tuned and you
are really
difficult to pursuade people to replace those privilege resource access
instruction
to use vdso or something equalvalent such as mov GRx=CRy. For those C
code
previlige resource access, like Isaku mentioned, we need to consider
native too.
Anyway binary patching is just an optimization that X86 used and there
is no
reason IA64 can't take. At least replacing indirect function with direct
function
call.
Eddie
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes
2008-04-09 4:48 ` Isaku Yamahata
` (7 preceding siblings ...)
2008-04-22 13:15 ` Dong, Eddie
@ 2008-04-22 13:55 ` Jes Sorensen
2008-04-30 12:29 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Isaku Yamahata
9 siblings, 0 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 13:55 UTC (permalink / raw)
To: linux-ia64
Dong, Eddie wrote:
> My understanding is that code such as IVT table are well tuned and you
> are really
> difficult to pursuade people to replace those privilege resource access
> instruction
> to use vdso or something equalvalent such as mov GRx=CRy. For those C
> code
> previlige resource access, like Isaku mentioned, we need to consider
> native too.
Hi Eddie,
I think binary patching of the ivt makes a lot of sense, I am certainly
not opposed to that. I was more thinking in terms of calls out of the
regular C code.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-22 13:15 ` Dong, Eddie
@ 2008-04-22 13:55 ` Jes Sorensen
0 siblings, 0 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-22 13:55 UTC (permalink / raw)
To: Dong, Eddie; +Cc: Isaku Yamahata, xen-ia64-devel, linux-ia64, virtualization
Dong, Eddie wrote:
> My understanding is that code such as IVT table are well tuned and you
> are really
> difficult to pursuade people to replace those privilege resource access
> instruction
> to use vdso or something equalvalent such as mov GRx=CRy. For those C
> code
> previlige resource access, like Isaku mentioned, we need to consider
> native too.
Hi Eddie,
I think binary patching of the ivt makes a lot of sense, I am certainly
not opposed to that. I was more thinking in terms of calls out of the
regular C code.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
` (3 preceding siblings ...)
2008-04-22 12:05 ` Jes Sorensen
@ 2008-04-23 2:54 ` Isaku Yamahata
2008-04-23 14:03 ` Jes Sorensen
2008-04-23 14:03 ` Jes Sorensen
` (4 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-23 2:54 UTC (permalink / raw)
To: linux-ia64
On Tue, Apr 22, 2008 at 02:05:59PM +0200, Jes Sorensen wrote:
> Isaku Yamahata wrote:
> >I'm willing to introduce something like PARAVIRT_NR_IRQS,
> >but I don't see how PARAVIRT_NR_IRQS solves the issues.
> >What I want here is to define by cpp
> >#define PARAVIRT_NR_IRQS \
> > max( \
> > IA64_NATIVE_NR_IRQS, \
> > XEN_NR_IRQS, /* only if CONFIG_XEN */ \
> > LGUSET_NR_IRQS, /* only if CONFIG_LGUSET */ \
> > KVM_GUEST_NR_IRQS, /* only if CONFIG_KVM_GUEST */ \
> > MORE_FUTURE_VM_NR_IRQS, /* only if ...*/ \
> > .... \
> > )
> >
> >Probably I'm missing something.
> >Could you suggest more concretly? Hopefully (pseudo) code snippet.
>
> I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
> all of these are constants anyway. If we cannot do that, then it would
> be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
> header files for Xen/KVM/lguest so we don't get the clutter in the main
> makefile.
Unfotunately Kconfig doesn't support arithmetic comparison.
So do you want something like the followings?
irq.h:
#if (NR_VECTORS + 32 * NR_CPUS) < 1024
#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
#else
#define IA64_NATIVE_NR_IRQS 1024
#endif
#define PARAVIRT_NR_IRQS IA64_NATIVE_NR_IRQS
/* CAUTION:each asm/xxx/irq.h may redefine PARAVIRT_NR_IRQS */
#include <asm/xen/irq.h>
#include <asm/kvm/irq.h>
#include <asm/foo/irq.h>
...
#define NR_IRQS PARAVIRT_NR_IRQS
asm/foo/irq.h:
#define FOO_NR_IRQ ...
#ifdef CONFIG_FOO
#if FOO_NR_IRQS > PARAVIRT_NR_IRQS
#undef PARAVIRT_NR_IRQS
#define PARAVIRT_NR_IRQS FOO_NR_IRQS
#endif
#endif
--
yamahata
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-22 12:05 ` Jes Sorensen
@ 2008-04-23 2:54 ` Isaku Yamahata
0 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-23 2:54 UTC (permalink / raw)
To: Jes Sorensen; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
On Tue, Apr 22, 2008 at 02:05:59PM +0200, Jes Sorensen wrote:
> Isaku Yamahata wrote:
> >I'm willing to introduce something like PARAVIRT_NR_IRQS,
> >but I don't see how PARAVIRT_NR_IRQS solves the issues.
> >What I want here is to define by cpp
> >#define PARAVIRT_NR_IRQS \
> > max( \
> > IA64_NATIVE_NR_IRQS, \
> > XEN_NR_IRQS, /* only if CONFIG_XEN */ \
> > LGUSET_NR_IRQS, /* only if CONFIG_LGUSET */ \
> > KVM_GUEST_NR_IRQS, /* only if CONFIG_KVM_GUEST */ \
> > MORE_FUTURE_VM_NR_IRQS, /* only if ...*/ \
> > .... \
> > )
> >
> >Probably I'm missing something.
> >Could you suggest more concretly? Hopefully (pseudo) code snippet.
>
> I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
> all of these are constants anyway. If we cannot do that, then it would
> be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
> header files for Xen/KVM/lguest so we don't get the clutter in the main
> makefile.
Unfotunately Kconfig doesn't support arithmetic comparison.
So do you want something like the followings?
irq.h:
#if (NR_VECTORS + 32 * NR_CPUS) < 1024
#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
#else
#define IA64_NATIVE_NR_IRQS 1024
#endif
#define PARAVIRT_NR_IRQS IA64_NATIVE_NR_IRQS
/* CAUTION:each asm/xxx/irq.h may redefine PARAVIRT_NR_IRQS */
#include <asm/xen/irq.h>
#include <asm/kvm/irq.h>
#include <asm/foo/irq.h>
...
#define NR_IRQS PARAVIRT_NR_IRQS
asm/foo/irq.h:
#define FOO_NR_IRQ ...
#ifdef CONFIG_FOO
#if FOO_NR_IRQS > PARAVIRT_NR_IRQS
#undef PARAVIRT_NR_IRQS
#define PARAVIRT_NR_IRQS FOO_NR_IRQS
#endif
#endif
--
yamahata
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
` (4 preceding siblings ...)
2008-04-23 2:54 ` Isaku Yamahata
@ 2008-04-23 14:03 ` Jes Sorensen
2008-04-24 11:19 ` Isaku Yamahata
2008-04-24 11:19 ` Isaku Yamahata
` (3 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Jes Sorensen @ 2008-04-23 14:03 UTC (permalink / raw)
To: linux-ia64
Isaku Yamahata wrote:
>> I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
>> all of these are constants anyway. If we cannot do that, then it would
>> be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
>> header files for Xen/KVM/lguest so we don't get the clutter in the main
>> makefile.
>
> Unfotunately Kconfig doesn't support arithmetic comparison.
> So do you want something like the followings?
IMHO, that would be better.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-23 2:54 ` Isaku Yamahata
@ 2008-04-23 14:03 ` Jes Sorensen
0 siblings, 0 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-23 14:03 UTC (permalink / raw)
To: Isaku Yamahata; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
Isaku Yamahata wrote:
>> I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
>> all of these are constants anyway. If we cannot do that, then it would
>> be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
>> header files for Xen/KVM/lguest so we don't get the clutter in the main
>> makefile.
>
> Unfotunately Kconfig doesn't support arithmetic comparison.
> So do you want something like the followings?
IMHO, that would be better.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
` (5 preceding siblings ...)
2008-04-23 14:03 ` Jes Sorensen
@ 2008-04-24 11:19 ` Isaku Yamahata
2008-04-24 11:52 ` Jes Sorensen
2008-04-24 11:52 ` Jes Sorensen
` (2 subsequent siblings)
9 siblings, 1 reply; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-24 11:19 UTC (permalink / raw)
To: linux-ia64
On Wed, Apr 23, 2008 at 04:03:58PM +0200, Jes Sorensen wrote:
> Isaku Yamahata wrote:
> >>I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
> >>all of these are constants anyway. If we cannot do that, then it would
> >>be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
> >>header files for Xen/KVM/lguest so we don't get the clutter in the main
> >>makefile.
> >
> >Unfotunately Kconfig doesn't support arithmetic comparison.
> >So do you want something like the followings?
>
> IMHO, that would be better.
How about this?
Eventually I found another way which doesn't use #undef trick.
ASM_OFFSET_C is somewhat tricky, but much better, I suppose.
From 8b13a7498112d2f3f1d8eb58543209956ffc5417 Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Thu, 24 Apr 2008 19:53:50 +0900
Subject: ia64/pv_ops: paravirtualize NR_IRQS
Make NR_IRQ overridable by each pv instances.
Pv instance may need each own number of irqs so that
NR_IRQS should be the maximum number of nr_irqs each
pv instances need.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/asm-offsets.c | 18 ++++++++++++++++++
include/asm-ia64/hardirq.h | 4 +++-
include/asm-ia64/irq.h | 13 +++++++++++--
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
index 230a6f9..dff6403 100644
--- a/arch/ia64/kernel/asm-offsets.c
+++ b/arch/ia64/kernel/asm-offsets.c
@@ -10,6 +10,7 @@
#include <linux/pid.h>
#include <linux/clocksource.h>
+#include <asm-ia64/irq.h>
#include <asm-ia64/processor.h>
#include <asm-ia64/ptrace.h>
#include <asm-ia64/siginfo.h>
@@ -291,4 +292,21 @@ void foo(void)
offsetof (struct itc_jitter_data_t, itc_jitter));
DEFINE(IA64_ITC_LASTCYCLE_OFFSET,
offsetof (struct itc_jitter_data_t, itc_lastcycle));
+ BLANK();
+
+ {
+ /*
+ * calculate
+ * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, FOO_NR_IRQS...)
+ * depending on config.
+ */
+ union paravirt_nr_irqs_max {
+ char ia64_native_nr_irqs[IA64_NATIVE_NR_IRQS];
+#ifdef CONFIG_XEN
+ char xen_nr_irqs[XEN_NR_IRQS];
+#endif
+ };
+
+ DEFINE(PARAVIRT_NR_IRQS, sizeof (union paravirt_nr_irqs_max));
+ }
}
diff --git a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h
index 140e495..7ee7626 100644
--- a/include/asm-ia64/hardirq.h
+++ b/include/asm-ia64/hardirq.h
@@ -8,7 +8,9 @@
#include <linux/threads.h>
+#ifndef ASM_OFFSETS_C
#include <linux/irq.h>
+#endif
#include <asm/processor.h>
@@ -26,7 +28,7 @@
* The hardirq mask has to be large enough to have space for potentially all IRQ sources
* in the system nesting on a single CPU:
*/
-#if (1 << HARDIRQ_BITS) < NR_IRQS
+#if !defined (ASM_OFFSETS_C) && ((1 << HARDIRQ_BITS) < NR_IRQS)
# error HARDIRQ_BITS is too low!
#endif
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index a66d268..5208318 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -17,9 +17,18 @@
#define NR_VECTORS 256
#if (NR_VECTORS + 32 * NR_CPUS) < 1024
-#define NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
+#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
#else
-#define NR_IRQS 1024
+#define IA64_NATIVE_NR_IRQS 1024
+#endif
+
+/*
+ * PARAVIRT_NR_IRQS is defined by asm-offsets.c as
+ * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) depending on config.
+ */
+#ifndef ASM_OFFSETS_C
+#include <asm/asm-offsets.h>
+#define NR_IRQS PARAVIRT_NR_IRQS
#endif
static __inline__ int
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-23 14:03 ` Jes Sorensen
@ 2008-04-24 11:19 ` Isaku Yamahata
0 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-24 11:19 UTC (permalink / raw)
To: Jes Sorensen; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
On Wed, Apr 23, 2008 at 04:03:58PM +0200, Jes Sorensen wrote:
> Isaku Yamahata wrote:
> >>I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
> >>all of these are constants anyway. If we cannot do that, then it would
> >>be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
> >>header files for Xen/KVM/lguest so we don't get the clutter in the main
> >>makefile.
> >
> >Unfotunately Kconfig doesn't support arithmetic comparison.
> >So do you want something like the followings?
>
> IMHO, that would be better.
How about this?
Eventually I found another way which doesn't use #undef trick.
ASM_OFFSET_C is somewhat tricky, but much better, I suppose.
From 8b13a7498112d2f3f1d8eb58543209956ffc5417 Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Thu, 24 Apr 2008 19:53:50 +0900
Subject: ia64/pv_ops: paravirtualize NR_IRQS
Make NR_IRQ overridable by each pv instances.
Pv instance may need each own number of irqs so that
NR_IRQS should be the maximum number of nr_irqs each
pv instances need.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/asm-offsets.c | 18 ++++++++++++++++++
include/asm-ia64/hardirq.h | 4 +++-
include/asm-ia64/irq.h | 13 +++++++++++--
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
index 230a6f9..dff6403 100644
--- a/arch/ia64/kernel/asm-offsets.c
+++ b/arch/ia64/kernel/asm-offsets.c
@@ -10,6 +10,7 @@
#include <linux/pid.h>
#include <linux/clocksource.h>
+#include <asm-ia64/irq.h>
#include <asm-ia64/processor.h>
#include <asm-ia64/ptrace.h>
#include <asm-ia64/siginfo.h>
@@ -291,4 +292,21 @@ void foo(void)
offsetof (struct itc_jitter_data_t, itc_jitter));
DEFINE(IA64_ITC_LASTCYCLE_OFFSET,
offsetof (struct itc_jitter_data_t, itc_lastcycle));
+ BLANK();
+
+ {
+ /*
+ * calculate
+ * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, FOO_NR_IRQS...)
+ * depending on config.
+ */
+ union paravirt_nr_irqs_max {
+ char ia64_native_nr_irqs[IA64_NATIVE_NR_IRQS];
+#ifdef CONFIG_XEN
+ char xen_nr_irqs[XEN_NR_IRQS];
+#endif
+ };
+
+ DEFINE(PARAVIRT_NR_IRQS, sizeof (union paravirt_nr_irqs_max));
+ }
}
diff --git a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h
index 140e495..7ee7626 100644
--- a/include/asm-ia64/hardirq.h
+++ b/include/asm-ia64/hardirq.h
@@ -8,7 +8,9 @@
#include <linux/threads.h>
+#ifndef ASM_OFFSETS_C
#include <linux/irq.h>
+#endif
#include <asm/processor.h>
@@ -26,7 +28,7 @@
* The hardirq mask has to be large enough to have space for potentially all IRQ sources
* in the system nesting on a single CPU:
*/
-#if (1 << HARDIRQ_BITS) < NR_IRQS
+#if !defined (ASM_OFFSETS_C) && ((1 << HARDIRQ_BITS) < NR_IRQS)
# error HARDIRQ_BITS is too low!
#endif
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index a66d268..5208318 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -17,9 +17,18 @@
#define NR_VECTORS 256
#if (NR_VECTORS + 32 * NR_CPUS) < 1024
-#define NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
+#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
#else
-#define NR_IRQS 1024
+#define IA64_NATIVE_NR_IRQS 1024
+#endif
+
+/*
+ * PARAVIRT_NR_IRQS is defined by asm-offsets.c as
+ * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) depending on config.
+ */
+#ifndef ASM_OFFSETS_C
+#include <asm/asm-offsets.h>
+#define NR_IRQS PARAVIRT_NR_IRQS
#endif
static __inline__ int
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
` (6 preceding siblings ...)
2008-04-24 11:19 ` Isaku Yamahata
@ 2008-04-24 11:52 ` Jes Sorensen
2008-04-24 12:21 ` Isaku Yamahata
2008-04-24 12:21 ` Isaku Yamahata
2008-04-30 12:29 ` Isaku Yamahata
9 siblings, 1 reply; 52+ messages in thread
From: Jes Sorensen @ 2008-04-24 11:52 UTC (permalink / raw)
To: linux-ia64
Isaku Yamahata wrote:
> On Wed, Apr 23, 2008 at 04:03:58PM +0200, Jes Sorensen wrote:
>> Isaku Yamahata wrote:
>>>> I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
>>>> all of these are constants anyway. If we cannot do that, then it would
>>>> be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
>>>> header files for Xen/KVM/lguest so we don't get the clutter in the main
>>>> makefile.
>>> Unfotunately Kconfig doesn't support arithmetic comparison.
>>> So do you want something like the followings?
>> IMHO, that would be better.
>
> How about this?
> Eventually I found another way which doesn't use #undef trick.
> ASM_OFFSET_C is somewhat tricky, but much better, I suppose.
Hi Isaku,
Yes, this looks like a much nicer way to solve the problem IMHO.
> +/*
> + * PARAVIRT_NR_IRQS is defined by asm-offsets.c as
> + * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) depending on config.
> + */
> +#ifndef ASM_OFFSETS_C
> +#include <asm/asm-offsets.h>
> +#define NR_IRQS PARAVIRT_NR_IRQS
> #endif
>
> static __inline__ int
Shouldn't this be defined as IA64_NATIVE_NR_IRQS? I wouldn't do the
#ifndef ASM_OFFSETS_C part, you should be able to just include it
unconditionally.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-24 11:19 ` Isaku Yamahata
@ 2008-04-24 11:52 ` Jes Sorensen
0 siblings, 0 replies; 52+ messages in thread
From: Jes Sorensen @ 2008-04-24 11:52 UTC (permalink / raw)
To: Isaku Yamahata; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
Isaku Yamahata wrote:
> On Wed, Apr 23, 2008 at 04:03:58PM +0200, Jes Sorensen wrote:
>> Isaku Yamahata wrote:
>>>> I'd rather have PARAVIRT_NR_IRQ set from Kconfig if possible given that
>>>> all of these are constants anyway. If we cannot do that, then it would
>>>> be better to do the #if FOO_NR_IRQ > PARAVIRT_NR_IRQ in the various
>>>> header files for Xen/KVM/lguest so we don't get the clutter in the main
>>>> makefile.
>>> Unfotunately Kconfig doesn't support arithmetic comparison.
>>> So do you want something like the followings?
>> IMHO, that would be better.
>
> How about this?
> Eventually I found another way which doesn't use #undef trick.
> ASM_OFFSET_C is somewhat tricky, but much better, I suppose.
Hi Isaku,
Yes, this looks like a much nicer way to solve the problem IMHO.
> +/*
> + * PARAVIRT_NR_IRQS is defined by asm-offsets.c as
> + * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) depending on config.
> + */
> +#ifndef ASM_OFFSETS_C
> +#include <asm/asm-offsets.h>
> +#define NR_IRQS PARAVIRT_NR_IRQS
> #endif
>
> static __inline__ int
Shouldn't this be defined as IA64_NATIVE_NR_IRQS? I wouldn't do the
#ifndef ASM_OFFSETS_C part, you should be able to just include it
unconditionally.
Cheers,
Jes
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
` (7 preceding siblings ...)
2008-04-24 11:52 ` Jes Sorensen
@ 2008-04-24 12:21 ` Isaku Yamahata
2008-04-30 12:29 ` Isaku Yamahata
9 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-24 12:21 UTC (permalink / raw)
To: linux-ia64
On Thu, Apr 24, 2008 at 01:52:20PM +0200, Jes Sorensen wrote:
> >+/*
> >+ * PARAVIRT_NR_IRQS is defined by asm-offsets.c as
> >+ * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) depending on config.
> >+ */
> >+#ifndef ASM_OFFSETS_C
> >+#include <asm/asm-offsets.h>
> >+#define NR_IRQS PARAVIRT_NR_IRQS
> > #endif
> >
> > static __inline__ int
>
> Shouldn't this be defined as IA64_NATIVE_NR_IRQS?
I eliminated this hunk completly.
> I wouldn't do the
> #ifndef ASM_OFFSETS_C part, you should be able to just include it
> unconditionally.
Still two ASM_OFFSET_C remain, but I couldn't find
a way to sort out deep header inclusion dependency.
Without them, asm-offset.c doesn't compile.
From c101e113912a4bbc117b4d93e215169a55581602 Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Thu, 24 Apr 2008 21:02:26 +0900
Subject: ia64/pv_ops: paravirtualize NR_IRQS
Make NR_IRQ overridable by each pv instances.
Pv instance may need each own number of irqs so that
NR_IRQS should be the maximum number of nr_irqs each
pv instances need.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/asm-offsets.c | 18 ++++++++++++++++++
include/asm-ia64/hardirq.h | 4 +++-
include/asm-ia64/irq.h | 4 ++--
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
index 230a6f9..08a09e3 100644
--- a/arch/ia64/kernel/asm-offsets.c
+++ b/arch/ia64/kernel/asm-offsets.c
@@ -10,6 +10,7 @@
#include <linux/pid.h>
#include <linux/clocksource.h>
+#include <asm-ia64/irq.h>
#include <asm-ia64/processor.h>
#include <asm-ia64/ptrace.h>
#include <asm-ia64/siginfo.h>
@@ -291,4 +292,21 @@ void foo(void)
offsetof (struct itc_jitter_data_t, itc_jitter));
DEFINE(IA64_ITC_LASTCYCLE_OFFSET,
offsetof (struct itc_jitter_data_t, itc_lastcycle));
+ BLANK();
+
+ {
+ /*
+ * calculate
+ * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, FOO_NR_IRQS...)
+ * depending on config.
+ */
+ union paravirt_nr_irqs_max {
+ char ia64_native_nr_irqs[IA64_NATIVE_NR_IRQS];
+#ifdef CONFIG_XEN
+ char xen_nr_irqs[XEN_NR_IRQS];
+#endif
+ };
+
+ DEFINE(NR_IRQS, sizeof (union paravirt_nr_irqs_max));
+ }
}
diff --git a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h
index 140e495..7ee7626 100644
--- a/include/asm-ia64/hardirq.h
+++ b/include/asm-ia64/hardirq.h
@@ -8,7 +8,9 @@
#include <linux/threads.h>
+#ifndef ASM_OFFSETS_C
#include <linux/irq.h>
+#endif
#include <asm/processor.h>
@@ -26,7 +28,7 @@
* The hardirq mask has to be large enough to have space for potentially all IRQ sources
* in the system nesting on a single CPU:
*/
-#if (1 << HARDIRQ_BITS) < NR_IRQS
+#if !defined (ASM_OFFSETS_C) && ((1 << HARDIRQ_BITS) < NR_IRQS)
# error HARDIRQ_BITS is too low!
#endif
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index a66d268..60e4c1d 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -17,9 +17,9 @@
#define NR_VECTORS 256
#if (NR_VECTORS + 32 * NR_CPUS) < 1024
-#define NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
+#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
#else
-#define NR_IRQS 1024
+#define IA64_NATIVE_NR_IRQS 1024
#endif
static __inline__ int
--
1.5.3
--
yamahata
^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-24 11:52 ` Jes Sorensen
@ 2008-04-24 12:21 ` Isaku Yamahata
0 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-24 12:21 UTC (permalink / raw)
To: Jes Sorensen; +Cc: eddie.dong, xen-ia64-devel, linux-ia64, virtualization
On Thu, Apr 24, 2008 at 01:52:20PM +0200, Jes Sorensen wrote:
> >+/*
> >+ * PARAVIRT_NR_IRQS is defined by asm-offsets.c as
> >+ * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) depending on config.
> >+ */
> >+#ifndef ASM_OFFSETS_C
> >+#include <asm/asm-offsets.h>
> >+#define NR_IRQS PARAVIRT_NR_IRQS
> > #endif
> >
> > static __inline__ int
>
> Shouldn't this be defined as IA64_NATIVE_NR_IRQS?
I eliminated this hunk completly.
> I wouldn't do the
> #ifndef ASM_OFFSETS_C part, you should be able to just include it
> unconditionally.
Still two ASM_OFFSET_C remain, but I couldn't find
a way to sort out deep header inclusion dependency.
Without them, asm-offset.c doesn't compile.
From c101e113912a4bbc117b4d93e215169a55581602 Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Thu, 24 Apr 2008 21:02:26 +0900
Subject: ia64/pv_ops: paravirtualize NR_IRQS
Make NR_IRQ overridable by each pv instances.
Pv instance may need each own number of irqs so that
NR_IRQS should be the maximum number of nr_irqs each
pv instances need.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/asm-offsets.c | 18 ++++++++++++++++++
include/asm-ia64/hardirq.h | 4 +++-
include/asm-ia64/irq.h | 4 ++--
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
index 230a6f9..08a09e3 100644
--- a/arch/ia64/kernel/asm-offsets.c
+++ b/arch/ia64/kernel/asm-offsets.c
@@ -10,6 +10,7 @@
#include <linux/pid.h>
#include <linux/clocksource.h>
+#include <asm-ia64/irq.h>
#include <asm-ia64/processor.h>
#include <asm-ia64/ptrace.h>
#include <asm-ia64/siginfo.h>
@@ -291,4 +292,21 @@ void foo(void)
offsetof (struct itc_jitter_data_t, itc_jitter));
DEFINE(IA64_ITC_LASTCYCLE_OFFSET,
offsetof (struct itc_jitter_data_t, itc_lastcycle));
+ BLANK();
+
+ {
+ /*
+ * calculate
+ * max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, FOO_NR_IRQS...)
+ * depending on config.
+ */
+ union paravirt_nr_irqs_max {
+ char ia64_native_nr_irqs[IA64_NATIVE_NR_IRQS];
+#ifdef CONFIG_XEN
+ char xen_nr_irqs[XEN_NR_IRQS];
+#endif
+ };
+
+ DEFINE(NR_IRQS, sizeof (union paravirt_nr_irqs_max));
+ }
}
diff --git a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h
index 140e495..7ee7626 100644
--- a/include/asm-ia64/hardirq.h
+++ b/include/asm-ia64/hardirq.h
@@ -8,7 +8,9 @@
#include <linux/threads.h>
+#ifndef ASM_OFFSETS_C
#include <linux/irq.h>
+#endif
#include <asm/processor.h>
@@ -26,7 +28,7 @@
* The hardirq mask has to be large enough to have space for potentially all IRQ sources
* in the system nesting on a single CPU:
*/
-#if (1 << HARDIRQ_BITS) < NR_IRQS
+#if !defined (ASM_OFFSETS_C) && ((1 << HARDIRQ_BITS) < NR_IRQS)
# error HARDIRQ_BITS is too low!
#endif
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index a66d268..60e4c1d 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -17,9 +17,9 @@
#define NR_VECTORS 256
#if (NR_VECTORS + 32 * NR_CPUS) < 1024
-#define NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
+#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
#else
-#define NR_IRQS 1024
+#define IA64_NATIVE_NR_IRQS 1024
#endif
static __inline__ int
--
1.5.3
--
yamahata
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info.
2008-04-09 4:48 ` Isaku Yamahata
` (8 preceding siblings ...)
2008-04-22 13:55 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
@ 2008-04-30 12:29 ` Isaku Yamahata
9 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-30 12:29 UTC (permalink / raw)
To: linux-ia64
introduce pv_info which describes some randome info about
underlying execution environment.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/kernel/Makefile | 2 +
arch/ia64/kernel/paravirt.c | 41 ++++++++++++++++++++++++++++
include/asm-ia64/paravirt.h | 62 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 105 insertions(+), 0 deletions(-)
create mode 100644 arch/ia64/kernel/paravirt.c
create mode 100644 include/asm-ia64/paravirt.h
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 13fd10e..10a4ddb 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -36,6 +36,8 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
+obj-$(CONFIG_PARAVIRT) += paravirt.o
+
obj-$(CONFIG_IA64_ESI) += esi.o
ifneq ($(CONFIG_IA64_ESI),)
obj-y += esi_stub.o # must be in kernel proper
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
new file mode 100644
index 0000000..d295ea5
--- /dev/null
+++ b/arch/ia64/kernel/paravirt.c
@@ -0,0 +1,41 @@
+/******************************************************************************
+ * arch/ia64/kernel/paravirt.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ * Yaozu (Eddie) Dong <eddie.dong@intel.com>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+
+#include <linux/compiler.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/iosapic.h>
+#include <asm/paravirt.h>
+
+/***************************************************************************
+ * general info
+ */
+struct pv_info pv_info = {
+ .kernel_rpl = 0,
+ .paravirt_enabled = 0,
+ .name = "bare hardware"
+};
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h
new file mode 100644
index 0000000..26b4334
--- /dev/null
+++ b/include/asm-ia64/paravirt.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ * include/asm-ia64/paravirt.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#ifndef __ASM_PARAVIRT_H
+#define __ASM_PARAVIRT_H
+
+#ifdef CONFIG_PARAVIRT_GUEST
+
+#ifndef __ASSEMBLY__
+
+#include <asm/hw_irq.h>
+#include <asm/meminit.h>
+
+/******************************************************************************
+ * general info
+ */
+struct pv_info {
+ unsigned int kernel_rpl;
+ int paravirt_enabled;
+ const char *name;
+};
+
+extern struct pv_info pv_info;
+
+static inline int paravirt_enabled(void)
+{
+ return pv_info.paravirt_enabled;
+}
+
+static inline unsigned int get_kernel_rpl(void)
+{
+ return pv_info.kernel_rpl;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#else
+/* fallback for native case */
+
+#endif /* CONFIG_PARAVIRT_GUEST */
+
+#endif /* __ASM_PARAVIRT_H */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
` (8 preceding siblings ...)
2008-04-24 12:21 ` Isaku Yamahata
@ 2008-04-30 12:29 ` Isaku Yamahata
9 siblings, 0 replies; 52+ messages in thread
From: Isaku Yamahata @ 2008-04-30 12:29 UTC (permalink / raw)
To: linux-ia64
Make NR_IRQ overridable by each pv instances.
Pv instance may need each own number of irqs so that
NR_IRQS should be the maximum number of nr_irqs each
pv instances need.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
arch/ia64/Makefile | 6 ++++++
arch/ia64/kernel/Makefile | 33 +++++++++++++++++++++++++++++++++
arch/ia64/kernel/nr-irqs.c | 24 ++++++++++++++++++++++++
include/asm-ia64/irq.h | 9 +--------
include/asm-ia64/native/irq.h | 35 +++++++++++++++++++++++++++++++++++
5 files changed, 99 insertions(+), 8 deletions(-)
create mode 100644 arch/ia64/kernel/nr-irqs.c
create mode 100644 include/asm-ia64/native/irq.h
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index ec4cca4..4721a12 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -99,3 +99,9 @@ define archhelp
echo ' boot - Build vmlinux and bootloader for Ski simulator'
echo '* unwcheck - Check vmlinux for invalid unwind info'
endef
+
+archprepare: make_nr_irqs_h FORCE
+PHONY += make_nr_irqs_h FORCE
+
+make_nr_irqs_h: FORCE
+ $(Q)$(MAKE) $(build)=arch/ia64/kernel include/asm-ia64/nr-irqs.h
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index cea91f1..87fea11 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -73,6 +73,39 @@ $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
# Note: kbuild does not track this dependency due to usage of .incbin
$(obj)/gate-data.o: $(obj)/gate.so
+# Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config
+define sed-y
+ "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"
+endef
+quiet_cmd_nr_irqs = GEN $@
+define cmd_nr_irqs
+ (set -e; \
+ echo "#ifndef __ASM_NR_IRQS_H__"; \
+ echo "#define __ASM_NR_IRQS_H__"; \
+ echo "/*"; \
+ echo " * DO NOT MODIFY."; \
+ echo " *"; \
+ echo " * This file was generated by Kbuild"; \
+ echo " *"; \
+ echo " */"; \
+ echo ""; \
+ sed -ne $(sed-y) $<; \
+ echo ""; \
+ echo "#endif" ) > $@
+endef
+
+# We use internal kbuild rules to avoid the "is up to date" message from make
+arch/$(SRCARCH)/kernel/nr-irqs.s: $(srctree)/arch/$(SRCARCH)/kernel/nr-irqs.c \
+ $(wildcard $(srctree)/include/asm-ia64/*/irq.h)
+ $(Q)mkdir -p $(dir $@)
+ $(call if_changed_dep,cc_s_c)
+
+include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s
+ $(Q)mkdir -p $(dir $@)
+ $(call cmd,nr_irqs)
+
+clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
+
#
# native ivt.S and entry.S
#
diff --git a/arch/ia64/kernel/nr-irqs.c b/arch/ia64/kernel/nr-irqs.c
new file mode 100644
index 0000000..1ae0491
--- /dev/null
+++ b/arch/ia64/kernel/nr-irqs.c
@@ -0,0 +1,24 @@
+/*
+ * calculate
+ * NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, FOO_NR_IRQS...)
+ * depending on config.
+ * This must be calculated before processing asm-offset.c.
+ */
+
+#define ASM_OFFSETS_C 1
+
+#include <linux/kbuild.h>
+#include <linux/threads.h>
+#include <asm-ia64/native/irq.h>
+
+void foo(void)
+{
+ union paravirt_nr_irqs_max {
+ char ia64_native_nr_irqs[IA64_NATIVE_NR_IRQS];
+#ifdef CONFIG_XEN
+ char xen_nr_irqs[XEN_NR_IRQS];
+#endif
+ };
+
+ DEFINE(NR_IRQS, sizeof (union paravirt_nr_irqs_max));
+}
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index a66d268..3627116 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -13,14 +13,7 @@
#include <linux/types.h>
#include <linux/cpumask.h>
-
-#define NR_VECTORS 256
-
-#if (NR_VECTORS + 32 * NR_CPUS) < 1024
-#define NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
-#else
-#define NR_IRQS 1024
-#endif
+#include <asm-ia64/nr-irqs.h>
static __inline__ int
irq_canonicalize (int irq)
diff --git a/include/asm-ia64/native/irq.h b/include/asm-ia64/native/irq.h
new file mode 100644
index 0000000..efe9ff7
--- /dev/null
+++ b/include/asm-ia64/native/irq.h
@@ -0,0 +1,35 @@
+/******************************************************************************
+ * include/asm-ia64/native/irq.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * moved from linux/include/asm-ia64/irq.h.
+ */
+
+#ifndef _ASM_IA64_NATIVE_IRQ_H
+#define _ASM_IA64_NATIVE_IRQ_H
+
+#define NR_VECTORS 256
+
+#if (NR_VECTORS + 32 * NR_CPUS) < 1024
+#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
+#else
+#define IA64_NATIVE_NR_IRQS 1024
+#endif
+
+#endif /* _ASM_IA64_NATIVE_IRQ_H */
--
1.5.3
^ permalink raw reply related [flat|nested] 52+ messages in thread
end of thread, other threads:[~2008-04-30 12:29 UTC | newest]
Thread overview: 52+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-09 4:48 [PATCH 00/15] RFC: ia64/pv_ops take 4 Isaku Yamahata
2008-04-09 4:48 ` [PATCH 01/15] ia64: preparation: remove extern in irq_ia64.c Isaku Yamahata
2008-04-09 4:48 ` [PATCH 02/15] ia64/pv_ops: preparation: introduce ia64_set_rr0_to_rr4() to make kernel paravirtualization friendly Isaku Yamahata
2008-04-09 4:48 ` [PATCH 03/15] ia64/pv_ops: preparation: introduce ia64_get_psr_i() " Isaku Yamahata
2008-04-09 4:48 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Isaku Yamahata
2008-04-09 4:48 ` Isaku Yamahata
2008-04-22 9:16 ` Jes Sorensen
2008-04-22 9:16 ` Jes Sorensen
2008-04-22 10:02 ` Isaku Yamahata
2008-04-22 10:02 ` Isaku Yamahata
2008-04-22 10:37 ` Jes Sorensen
2008-04-22 10:37 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
2008-04-22 10:41 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Dong, Eddie
2008-04-22 11:02 ` Isaku Yamahata
2008-04-22 10:41 ` Dong, Eddie
2008-04-22 11:30 ` Jes Sorensen
2008-04-22 11:02 ` Isaku Yamahata
2008-04-22 11:30 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
2008-04-22 13:15 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Dong, Eddie
2008-04-22 13:15 ` Dong, Eddie
2008-04-22 13:55 ` Jes Sorensen
2008-04-22 13:55 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes Jes Sorensen
2008-04-30 12:29 ` [PATCH 04/15] ia64/pv_ops: introduce pv_info which describes some random info Isaku Yamahata
2008-04-09 4:48 ` [PATCH 05/15] ia64/pv_ops: introduce pv_cpu_ops to paravirtualize privileged instructions Isaku Yamahata
2008-04-09 4:48 ` [PATCH 06/15] ia64/pv_ops: preparation for paravirtulization of hand written assembly code Isaku Yamahata
2008-04-09 4:49 ` [PATCH 07/15] ia64/pv_ops: define paravirtualized instructions for native Isaku Yamahata
2008-04-09 4:49 ` [PATCH 08/15] ia64/pv_ops: paravirtualize minstate.h Isaku Yamahata
2008-04-09 4:49 ` [PATCH 09/15] ia64/pv_ops: paravirtualize ivt.S Isaku Yamahata
2008-04-09 4:49 ` [PATCH 10/15] ia64/pv_ops: paravirtualize entry.S Isaku Yamahata
2008-04-09 4:49 ` [PATCH 11/15] ia64/pv_ops: paravirtualize NR_IRQS Isaku Yamahata
2008-04-22 9:08 ` Jes Sorensen
2008-04-22 9:08 ` Jes Sorensen
2008-04-22 10:11 ` Isaku Yamahata
2008-04-22 10:11 ` Isaku Yamahata
2008-04-22 12:05 ` Jes Sorensen
2008-04-22 12:05 ` Jes Sorensen
2008-04-23 2:54 ` Isaku Yamahata
2008-04-23 2:54 ` Isaku Yamahata
2008-04-23 14:03 ` Jes Sorensen
2008-04-23 14:03 ` Jes Sorensen
2008-04-24 11:19 ` Isaku Yamahata
2008-04-24 11:19 ` Isaku Yamahata
2008-04-24 11:52 ` Jes Sorensen
2008-04-24 11:52 ` Jes Sorensen
2008-04-24 12:21 ` Isaku Yamahata
2008-04-24 12:21 ` Isaku Yamahata
2008-04-30 12:29 ` Isaku Yamahata
2008-04-09 4:49 ` Isaku Yamahata
2008-04-09 4:49 ` [PATCH 12/15] ia64/pv_ops: define initialization hooks, pv_init_ops, for paravirtualized environment Isaku Yamahata
2008-04-09 4:49 ` [PATCH 13/15] ia64/pv_ops: add hooks, pv_iosapic_ops, to paravirtualize iosapic Isaku Yamahata
2008-04-09 4:49 ` [PATCH 14/15] ia64/pv_ops: add hooks, pv_irq_ops, to paravirtualized irq related operations Isaku Yamahata
2008-04-09 4:49 ` [PATCH 15/15] ia64/pv_ops: add to hooks, pv_time_ops, for steal time accounting Isaku Yamahata
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.