Skip to content

Commit eb4225b

Browse files
committed
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6: (25 commits) mmtimer: Push BKL down into the ioctl handler [IA64] Remove experimental status of kdump [IA64] Update ia64 mmr list for SGI uv [IA64] Avoid overflowing ia64_cpu_to_sapicid in acpi_map_lsapic() [IA64] adding parameter check to module_free() [IA64] improper printk format in acpi-cpufreq [IA64] pv_ops: move some functions in ivt.S to avoid lack of space. [IA64] pvops: documentation on ia64/pv_ops [IA64] pvops: add to hooks, pv_time_ops, for steal time accounting. [IA64] pvops: add hooks, pv_irq_ops, to paravirtualized irq related operations. [IA64] pvops: add hooks, pv_iosapic_ops, to paravirtualize iosapic. [IA64] pvops: define initialization hooks, pv_init_ops, for paravirtualized environment. [IA64] pvops: paravirtualize NR_IRQS [IA64] pvops: paravirtualize entry.S [IA64] pvops: paravirtualize ivt.S [IA64] pvops: paravirtualize minstate.h. [IA64] pvops: define paravirtualized instructions for native. [IA64] pvops: preparation for paravirtulization of hand written assembly code. [IA64] pvops: introduce pv_cpu_ops to paravirtualize privileged instructions. [IA64] pvops: add an early setup hook for pv_ops. ...
2 parents 807677f + 4cddb88 commit eb4225b

37 files changed

+2251
-387
lines changed

Documentation/ia64/paravirt_ops.txt

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
Paravirt_ops on IA64
2+
====================
3+
21 May 2008, Isaku Yamahata <yamahata@valinux.co.jp>
4+
5+
6+
Introduction
7+
------------
8+
The aim of this documentation is to help with maintainability and/or to
9+
encourage people to use paravirt_ops/IA64.
10+
11+
paravirt_ops (pv_ops in short) is a way for virtualization support of
12+
Linux kernel on x86. Several ways for virtualization support were
13+
proposed, paravirt_ops is the winner.
14+
On the other hand, now there are also several IA64 virtualization
15+
technologies like kvm/IA64, xen/IA64 and many other academic IA64
16+
hypervisors so that it is good to add generic virtualization
17+
infrastructure on Linux/IA64.
18+
19+
20+
What is paravirt_ops?
21+
---------------------
22+
It has been developed on x86 as virtualization support via API, not ABI.
23+
It allows each hypervisor to override operations which are important for
24+
hypervisors at API level. And it allows a single kernel binary to run on
25+
all supported execution environments including native machine.
26+
Essentially paravirt_ops is a set of function pointers which represent
27+
operations corresponding to low level sensitive instructions and high
28+
level functionalities in various area. But one significant difference
29+
from usual function pointer table is that it allows optimization with
30+
binary patch. It is because some of these operations are very
31+
performance sensitive and indirect call overhead is not negligible.
32+
With binary patch, indirect C function call can be transformed into
33+
direct C function call or in-place execution to eliminate the overhead.
34+
35+
Thus, operations of paravirt_ops are classified into three categories.
36+
- simple indirect call
37+
These operations correspond to high level functionality so that the
38+
overhead of indirect call isn't very important.
39+
40+
- indirect call which allows optimization with binary patch
41+
Usually these operations correspond to low level instructions. They
42+
are called frequently and performance critical. So the overhead is
43+
very important.
44+
45+
- a set of macros for hand written assembly code
46+
Hand written assembly codes (.S files) also need paravirtualization
47+
because they include sensitive instructions or some of code paths in
48+
them are very performance critical.
49+
50+
51+
The relation to the IA64 machine vector
52+
---------------------------------------
53+
Linux/IA64 has the IA64 machine vector functionality which allows the
54+
kernel to switch implementations (e.g. initialization, ipi, dma api...)
55+
depending on executing platform.
56+
We can replace some implementations very easily defining a new machine
57+
vector. Thus another approach for virtualization support would be
58+
enhancing the machine vector functionality.
59+
But paravirt_ops approach was taken because
60+
- virtualization support needs wider support than machine vector does.
61+
e.g. low level instruction paravirtualization. It must be
62+
initialized very early before platform detection.
63+
64+
- virtualization support needs more functionality like binary patch.
65+
Probably the calling overhead might not be very large compared to the
66+
emulation overhead of virtualization. However in the native case, the
67+
overhead should be eliminated completely.
68+
A single kernel binary should run on each environment including native,
69+
and the overhead of paravirt_ops on native environment should be as
70+
small as possible.
71+
72+
- for full virtualization technology, e.g. KVM/IA64 or
73+
Xen/IA64 HVM domain, the result would be
74+
(the emulated platform machine vector. probably dig) + (pv_ops).
75+
This means that the virtualization support layer should be under
76+
the machine vector layer.
77+
78+
Possibly it might be better to move some function pointers from
79+
paravirt_ops to machine vector. In fact, Xen domU case utilizes both
80+
pv_ops and machine vector.
81+
82+
83+
IA64 paravirt_ops
84+
-----------------
85+
In this section, the concrete paravirt_ops will be discussed.
86+
Because of the architecture difference between ia64 and x86, the
87+
resulting set of functions is very different from x86 pv_ops.
88+
89+
- C function pointer tables
90+
They are not very performance critical so that simple C indirect
91+
function call is acceptable. The following structures are defined at
92+
this moment. For details see linux/include/asm-ia64/paravirt.h
93+
- struct pv_info
94+
This structure describes the execution environment.
95+
- struct pv_init_ops
96+
This structure describes the various initialization hooks.
97+
- struct pv_iosapic_ops
98+
This structure describes hooks to iosapic operations.
99+
- struct pv_irq_ops
100+
This structure describes hooks to irq related operations
101+
- struct pv_time_op
102+
This structure describes hooks to steal time accounting.
103+
104+
- a set of indirect calls which need optimization
105+
Currently this class of functions correspond to a subset of IA64
106+
intrinsics. At this moment the optimization with binary patch isn't
107+
implemented yet.
108+
struct pv_cpu_op is defined. For details see
109+
linux/include/asm-ia64/paravirt_privop.h
110+
Mostly they correspond to ia64 intrinsics 1-to-1.
111+
Caveat: Now they are defined as C indirect function pointers, but in
112+
order to support binary patch optimization, they will be changed
113+
using GCC extended inline assembly code.
114+
115+
- a set of macros for hand written assembly code (.S files)
116+
For maintenance purpose, the taken approach for .S files is single
117+
source code and compile multiple times with different macros definitions.
118+
Each pv_ops instance must define those macros to compile.
119+
The important thing here is that sensitive, but non-privileged
120+
instructions must be paravirtualized and that some privileged
121+
instructions also need paravirtualization for reasonable performance.
122+
Developers who modify .S files must be aware of that. At this moment
123+
an easy checker is implemented to detect paravirtualization breakage.
124+
But it doesn't cover all the cases.
125+
126+
Sometimes this set of macros is called pv_cpu_asm_op. But there is no
127+
corresponding structure in the source code.
128+
Those macros mostly 1:1 correspond to a subset of privileged
129+
instructions. See linux/include/asm-ia64/native/inst.h.
130+
And some functions written in assembly also need to be overrided so
131+
that each pv_ops instance have to define some macros. Again see
132+
linux/include/asm-ia64/native/inst.h.
133+
134+
135+
Those structures must be initialized very early before start_kernel.
136+
Probably initialized in head.S using multi entry point or some other trick.
137+
For native case implementation see linux/arch/ia64/kernel/paravirt.c.

arch/ia64/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,8 @@ config KEXEC
540540
strongly in flux, so no good recommendation can be made.
541541

542542
config CRASH_DUMP
543-
bool "kernel crash dumps (EXPERIMENTAL)"
544-
depends on EXPERIMENTAL && IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
543+
bool "kernel crash dumps"
544+
depends on IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
545545
help
546546
Generate crash dump after being started by kexec.
547547

arch/ia64/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,9 @@ define archhelp
100100
echo ' boot - Build vmlinux and bootloader for Ski simulator'
101101
echo '* unwcheck - Check vmlinux for invalid unwind info'
102102
endef
103+
104+
archprepare: make_nr_irqs_h FORCE
105+
PHONY += make_nr_irqs_h FORCE
106+
107+
make_nr_irqs_h: FORCE
108+
$(Q)$(MAKE) $(build)=arch/ia64/kernel include/asm-ia64/nr-irqs.h

arch/ia64/kernel/Makefile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o
3636
mca_recovery-y += mca_drv.o mca_drv_asm.o
3737
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
3838

39+
obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o
40+
3941
obj-$(CONFIG_IA64_ESI) += esi.o
4042
ifneq ($(CONFIG_IA64_ESI),)
4143
obj-y += esi_stub.o # must be in kernel proper
@@ -70,3 +72,45 @@ $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
7072
# We must build gate.so before we can assemble it.
7173
# Note: kbuild does not track this dependency due to usage of .incbin
7274
$(obj)/gate-data.o: $(obj)/gate.so
75+
76+
# Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config
77+
define sed-y
78+
"/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"
79+
endef
80+
quiet_cmd_nr_irqs = GEN $@
81+
define cmd_nr_irqs
82+
(set -e; \
83+
echo "#ifndef __ASM_NR_IRQS_H__"; \
84+
echo "#define __ASM_NR_IRQS_H__"; \
85+
echo "/*"; \
86+
echo " * DO NOT MODIFY."; \
87+
echo " *"; \
88+
echo " * This file was generated by Kbuild"; \
89+
echo " *"; \
90+
echo " */"; \
91+
echo ""; \
92+
sed -ne $(sed-y) $<; \
93+
echo ""; \
94+
echo "#endif" ) > $@
95+
endef
96+
97+
# We use internal kbuild rules to avoid the "is up to date" message from make
98+
arch/$(SRCARCH)/kernel/nr-irqs.s: $(srctree)/arch/$(SRCARCH)/kernel/nr-irqs.c \
99+
$(wildcard $(srctree)/include/asm-ia64/*/irq.h)
100+
$(Q)mkdir -p $(dir $@)
101+
$(call if_changed_dep,cc_s_c)
102+
103+
include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s
104+
$(Q)mkdir -p $(dir $@)
105+
$(call cmd,nr_irqs)
106+
107+
clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
108+
109+
#
110+
# native ivt.S and entry.S
111+
#
112+
ASM_PARAVIRT_OBJS = ivt.o entry.o
113+
define paravirtualized_native
114+
AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
115+
endef
116+
$(foreach obj,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_native,$(obj))))

arch/ia64/kernel/acpi.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
774774
*/
775775
#ifdef CONFIG_ACPI_HOTPLUG_CPU
776776
static
777-
int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid)
777+
int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
778778
{
779779
#ifdef CONFIG_ACPI_NUMA
780780
int pxm_id;
@@ -854,8 +854,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu)
854854
union acpi_object *obj;
855855
struct acpi_madt_local_sapic *lsapic;
856856
cpumask_t tmp_map;
857-
long physid;
858-
int cpu;
857+
int cpu, physid;
859858

860859
if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
861860
return -EINVAL;

arch/ia64/kernel/cpufreq/acpi-cpufreq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ processor_set_pstate (
5151
retval = ia64_pal_set_pstate((u64)value);
5252

5353
if (retval) {
54-
dprintk("Failed to set freq to 0x%x, with error 0x%x\n",
54+
dprintk("Failed to set freq to 0x%x, with error 0x%lx\n",
5555
value, retval);
5656
return -ENODEV;
5757
}
@@ -74,7 +74,7 @@ processor_get_pstate (
7474

7575
if (retval)
7676
dprintk("Failed to get current freq with "
77-
"error 0x%x, idx 0x%x\n", retval, *value);
77+
"error 0x%lx, idx 0x%x\n", retval, *value);
7878

7979
return (int)retval;
8080
}

0 commit comments

Comments
 (0)