xref: /titanic_41/usr/src/uts/common/xen/public/domctl.h (revision 8475e04352e630e4bd0f59a283286ee2475a14ce)
1 /******************************************************************************
2  * domctl.h
3  *
4  * Domain management operations. For use by node control stack.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Copyright (c) 2002-2003, B Dragovic
25  * Copyright (c) 2002-2006, K Fraser
26  */
27 
28 #ifndef __XEN_PUBLIC_DOMCTL_H__
29 #define __XEN_PUBLIC_DOMCTL_H__
30 
31 /*
32  * XXPV - We need sysctl (physinfo) in the solaris kernel, which includes
33  * this file
34  */
35 #if 0
36 
37 #if !defined(__XEN__) && !defined(__XEN_TOOLS__)
38 #error "domctl operations are intended for use by node control tools only"
39 #endif
40 
41 #endif /* XXPV */
42 
43 #include "xen.h"
44 
45 #define XEN_DOMCTL_INTERFACE_VERSION 0x00000005
46 
47 struct xenctl_cpumap {
48     XEN_GUEST_HANDLE_64(uint8_t) bitmap;
49     uint32_t nr_cpus;
50     uint8_t  pad[4];
51 };
52 
53 /*
54  * NB. xen_domctl.domain is an IN/OUT parameter for this operation.
55  * If it is specified as zero, an id is auto-allocated and returned.
56  */
57 #define XEN_DOMCTL_createdomain       1
58 struct xen_domctl_createdomain {
59     /* IN parameters */
60     uint32_t ssidref;
61     xen_domain_handle_t handle;
62  /* Is this an HVM guest (as opposed to a PV guest)? */
63 #define _XEN_DOMCTL_CDF_hvm_guest 0
64 #define XEN_DOMCTL_CDF_hvm_guest  (1U<<_XEN_DOMCTL_CDF_hvm_guest)
65     uint32_t flags;
66 };
67 typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
68 DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t);
69 
70 #define XEN_DOMCTL_destroydomain      2
71 #define XEN_DOMCTL_pausedomain        3
72 #define XEN_DOMCTL_unpausedomain      4
73 #define XEN_DOMCTL_resumedomain      27
74 
75 #define XEN_DOMCTL_getdomaininfo      5
76 struct xen_domctl_getdomaininfo {
77     /* OUT variables. */
78     domid_t  domain;              /* Also echoed in domctl.domain */
79  /* Domain is scheduled to die. */
80 #define _XEN_DOMINF_dying     0
81 #define XEN_DOMINF_dying      (1U<<_XEN_DOMINF_dying)
82  /* Domain is an HVM guest (as opposed to a PV guest). */
83 #define _XEN_DOMINF_hvm_guest 1
84 #define XEN_DOMINF_hvm_guest  (1U<<_XEN_DOMINF_hvm_guest)
85  /* The guest OS has shut down. */
86 #define _XEN_DOMINF_shutdown  2
87 #define XEN_DOMINF_shutdown   (1U<<_XEN_DOMINF_shutdown)
88  /* Currently paused by control software. */
89 #define _XEN_DOMINF_paused    3
90 #define XEN_DOMINF_paused     (1U<<_XEN_DOMINF_paused)
91  /* Currently blocked pending an event.     */
92 #define _XEN_DOMINF_blocked   4
93 #define XEN_DOMINF_blocked    (1U<<_XEN_DOMINF_blocked)
94  /* Domain is currently running.            */
95 #define _XEN_DOMINF_running   5
96 #define XEN_DOMINF_running    (1U<<_XEN_DOMINF_running)
97  /* Being debugged.  */
98 #define _XEN_DOMINF_debugged  6
99 #define XEN_DOMINF_debugged   (1U<<_XEN_DOMINF_debugged)
100  /* CPU to which this domain is bound.      */
101 #define XEN_DOMINF_cpumask      255
102 #define XEN_DOMINF_cpushift       8
103  /* XEN_DOMINF_shutdown guest-supplied code.  */
104 #define XEN_DOMINF_shutdownmask 255
105 #define XEN_DOMINF_shutdownshift 16
106     uint32_t flags;              /* XEN_DOMINF_* */
107     uint64_aligned_t tot_pages;
108     uint64_aligned_t max_pages;
109     uint64_aligned_t shared_info_frame; /* GMFN of shared_info struct */
110     uint64_aligned_t cpu_time;
111     uint32_t nr_online_vcpus;    /* Number of VCPUs currently online. */
112     uint32_t max_vcpu_id;        /* Maximum VCPUID in use by this domain. */
113     uint32_t ssidref;
114     xen_domain_handle_t handle;
115     uint8_t pad[4];
116 };
117 typedef struct xen_domctl_getdomaininfo xen_domctl_getdomaininfo_t;
118 DEFINE_XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t);
119 
120 
121 #define XEN_DOMCTL_getmemlist         6
122 struct xen_domctl_getmemlist {
123     /* IN variables. */
124     /* Max entries to write to output buffer. */
125     uint64_aligned_t max_pfns;
126     /* Start index in guest's page list. */
127     uint64_aligned_t start_pfn;
128     XEN_GUEST_HANDLE_64(uint64_t) buffer;
129     /* OUT variables. */
130     uint64_aligned_t num_pfns;
131 };
132 typedef struct xen_domctl_getmemlist xen_domctl_getmemlist_t;
133 DEFINE_XEN_GUEST_HANDLE(xen_domctl_getmemlist_t);
134 
135 
136 #define XEN_DOMCTL_getpageframeinfo   7
137 
138 #define XEN_DOMCTL_PFINFO_LTAB_SHIFT 28
139 #define XEN_DOMCTL_PFINFO_NOTAB   (0x0U<<28)
140 #define XEN_DOMCTL_PFINFO_L1TAB   (0x1U<<28)
141 #define XEN_DOMCTL_PFINFO_L2TAB   (0x2U<<28)
142 #define XEN_DOMCTL_PFINFO_L3TAB   (0x3U<<28)
143 #define XEN_DOMCTL_PFINFO_L4TAB   (0x4U<<28)
144 #define XEN_DOMCTL_PFINFO_LTABTYPE_MASK (0x7U<<28)
145 #define XEN_DOMCTL_PFINFO_LPINTAB (0x1U<<31)
146 #define XEN_DOMCTL_PFINFO_XTAB    (0xfU<<28) /* invalid page */
147 #define XEN_DOMCTL_PFINFO_LTAB_MASK (0xfU<<28)
148 
149 struct xen_domctl_getpageframeinfo {
150     /* IN variables. */
151     uint64_aligned_t gmfn; /* GMFN to query */
152     /* OUT variables. */
153     /* Is the page PINNED to a type? */
154     uint32_t type;         /* see above type defs */
155     uint8_t pad[4];
156 };
157 typedef struct xen_domctl_getpageframeinfo xen_domctl_getpageframeinfo_t;
158 DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo_t);
159 
160 
161 #define XEN_DOMCTL_getpageframeinfo2  8
162 struct xen_domctl_getpageframeinfo2 {
163     /* IN variables. */
164     uint64_aligned_t num;
165     /* IN/OUT variables. */
166     XEN_GUEST_HANDLE_64(uint32_t) array;
167 };
168 typedef struct xen_domctl_getpageframeinfo2 xen_domctl_getpageframeinfo2_t;
169 DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo2_t);
170 
171 
172 /*
173  * Control shadow pagetables operation
174  */
175 #define XEN_DOMCTL_shadow_op         10
176 
177 /* Disable shadow mode. */
178 #define XEN_DOMCTL_SHADOW_OP_OFF         0
179 
180 /* Enable shadow mode (mode contains ORed XEN_DOMCTL_SHADOW_ENABLE_* flags). */
181 #define XEN_DOMCTL_SHADOW_OP_ENABLE      32
182 
183 /* Log-dirty bitmap operations. */
184  /* Return the bitmap and clean internal copy for next round. */
185 #define XEN_DOMCTL_SHADOW_OP_CLEAN       11
186  /* Return the bitmap but do not modify internal copy. */
187 #define XEN_DOMCTL_SHADOW_OP_PEEK        12
188 
189 /* Memory allocation accessors. */
190 #define XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION   30
191 #define XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION   31
192 
193 /* Legacy enable operations. */
194  /* Equiv. to ENABLE with no mode flags. */
195 #define XEN_DOMCTL_SHADOW_OP_ENABLE_TEST       1
196  /* Equiv. to ENABLE with mode flag ENABLE_LOG_DIRTY. */
197 #define XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY   2
198  /* Equiv. to ENABLE with mode flags ENABLE_REFCOUNT and ENABLE_TRANSLATE. */
199 #define XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE  3
200 
201 /* Mode flags for XEN_DOMCTL_SHADOW_OP_ENABLE. */
202  /*
203   * Shadow pagetables are refcounted: guest does not use explicit mmu
204   * operations nor write-protect its pagetables.
205   */
206 #define XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT  (1 << 1)
207  /*
208   * Log pages in a bitmap as they are dirtied.
209   * Used for live relocation to determine which pages must be re-sent.
210   */
211 #define XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY (1 << 2)
212  /*
213   * Automatically translate GPFNs into MFNs.
214   */
215 #define XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE (1 << 3)
216  /*
217   * Xen does not steal virtual address space from the guest.
218   * Requires HVM support.
219   */
220 #define XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL  (1 << 4)
221 
222 struct xen_domctl_shadow_op_stats {
223     uint32_t fault_count;
224     uint32_t dirty_count;
225 };
226 typedef struct xen_domctl_shadow_op_stats xen_domctl_shadow_op_stats_t;
227 DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_stats_t);
228 
229 struct xen_domctl_shadow_op {
230     /* IN variables. */
231     uint32_t       op;       /* XEN_DOMCTL_SHADOW_OP_* */
232 
233     /* OP_ENABLE */
234     uint32_t       mode;     /* XEN_DOMCTL_SHADOW_ENABLE_* */
235 
236     /* OP_GET_ALLOCATION / OP_SET_ALLOCATION */
237     uint32_t       mb;       /* Shadow memory allocation in MB */
238     uint8_t        pad[4];
239 
240     /* OP_PEEK / OP_CLEAN */
241     XEN_GUEST_HANDLE_64(uint8_t) dirty_bitmap;
242     uint64_aligned_t pages; /* Size of buffer. Updated with actual size. */
243     struct xen_domctl_shadow_op_stats stats;
244 };
245 typedef struct xen_domctl_shadow_op xen_domctl_shadow_op_t;
246 DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_t);
247 
248 
249 #define XEN_DOMCTL_max_mem           11
250 struct xen_domctl_max_mem {
251     /* IN variables. */
252     uint64_aligned_t max_memkb;
253 };
254 typedef struct xen_domctl_max_mem xen_domctl_max_mem_t;
255 DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_mem_t);
256 
257 
258 #define XEN_DOMCTL_setvcpucontext    12
259 #define XEN_DOMCTL_getvcpucontext    13
260 struct xen_domctl_vcpucontext {
261     uint32_t              vcpu;                  /* IN */
262     uint8_t               pad[4];
263     XEN_GUEST_HANDLE_64(vcpu_guest_context_t) ctxt; /* IN/OUT */
264 };
265 typedef struct xen_domctl_vcpucontext xen_domctl_vcpucontext_t;
266 DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpucontext_t);
267 
268 
269 #define XEN_DOMCTL_getvcpuinfo       14
270 struct xen_domctl_getvcpuinfo {
271     /* IN variables. */
272     uint32_t vcpu;
273     /* OUT variables. */
274     uint8_t  online;                  /* currently online (not hotplugged)? */
275     uint8_t  blocked;                 /* blocked waiting for an event? */
276     uint8_t  running;                 /* currently scheduled on its CPU? */
277     uint8_t  pad1;
278     uint64_aligned_t cpu_time;        /* total cpu time consumed (ns) */
279     uint32_t cpu;                     /* current mapping   */
280     uint8_t  pad2[4];
281 };
282 typedef struct xen_domctl_getvcpuinfo xen_domctl_getvcpuinfo_t;
283 DEFINE_XEN_GUEST_HANDLE(xen_domctl_getvcpuinfo_t);
284 
285 
286 /* Get/set which physical cpus a vcpu can execute on. */
287 #define XEN_DOMCTL_setvcpuaffinity    9
288 #define XEN_DOMCTL_getvcpuaffinity   25
289 struct xen_domctl_vcpuaffinity {
290     uint32_t  vcpu;              /* IN */
291     uint8_t pad[4];
292     struct xenctl_cpumap cpumap; /* IN/OUT */
293 };
294 typedef struct xen_domctl_vcpuaffinity xen_domctl_vcpuaffinity_t;
295 DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpuaffinity_t);
296 
297 
298 #define XEN_DOMCTL_max_vcpus         15
299 struct xen_domctl_max_vcpus {
300     uint32_t max;           /* maximum number of vcpus */
301 };
302 typedef struct xen_domctl_max_vcpus xen_domctl_max_vcpus_t;
303 DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t);
304 
305 
306 #define XEN_DOMCTL_scheduler_op      16
307 /* Scheduler types. */
308 #define XEN_SCHEDULER_SEDF     4
309 #define XEN_SCHEDULER_CREDIT   5
310 /* Set or get info? */
311 #define XEN_DOMCTL_SCHEDOP_putinfo 0
312 #define XEN_DOMCTL_SCHEDOP_getinfo 1
313 struct xen_domctl_scheduler_op {
314     uint32_t sched_id;  /* XEN_SCHEDULER_* */
315     uint32_t cmd;       /* XEN_DOMCTL_SCHEDOP_* */
316     union {
317         struct xen_domctl_sched_sedf {
318             uint64_aligned_t period;
319             uint64_aligned_t slice;
320             uint64_aligned_t latency;
321             uint32_t extratime;
322             uint32_t weight;
323         } sedf;
324         struct xen_domctl_sched_credit {
325             uint16_t weight;
326             uint16_t cap;
327         } credit;
328     } u;
329 };
330 typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t;
331 DEFINE_XEN_GUEST_HANDLE(xen_domctl_scheduler_op_t);
332 
333 
334 #define XEN_DOMCTL_setdomainhandle   17
335 struct xen_domctl_setdomainhandle {
336     xen_domain_handle_t handle;
337 };
338 typedef struct xen_domctl_setdomainhandle xen_domctl_setdomainhandle_t;
339 DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdomainhandle_t);
340 
341 
342 #define XEN_DOMCTL_setdebugging      18
343 struct xen_domctl_setdebugging {
344     uint8_t enable;
345 };
346 typedef struct xen_domctl_setdebugging xen_domctl_setdebugging_t;
347 DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdebugging_t);
348 
349 
350 #define XEN_DOMCTL_irq_permission    19
351 struct xen_domctl_irq_permission {
352     uint8_t pirq;
353     uint8_t allow_access;    /* flag to specify enable/disable of IRQ access */
354 };
355 typedef struct xen_domctl_irq_permission xen_domctl_irq_permission_t;
356 DEFINE_XEN_GUEST_HANDLE(xen_domctl_irq_permission_t);
357 
358 
359 #define XEN_DOMCTL_iomem_permission  20
360 struct xen_domctl_iomem_permission {
361     uint64_aligned_t first_mfn;/* first page (physical page number) in range */
362     uint64_aligned_t nr_mfns;  /* number of pages in range (>0) */
363     uint8_t  allow_access;     /* allow (!0) or deny (0) access to range? */
364 };
365 typedef struct xen_domctl_iomem_permission xen_domctl_iomem_permission_t;
366 DEFINE_XEN_GUEST_HANDLE(xen_domctl_iomem_permission_t);
367 
368 
369 #define XEN_DOMCTL_ioport_permission 21
370 struct xen_domctl_ioport_permission {
371     uint32_t first_port;              /* first port int range */
372     uint32_t nr_ports;                /* size of port range */
373     uint8_t  allow_access;            /* allow or deny access to range? */
374     uint8_t  pad[3];
375 };
376 typedef struct xen_domctl_ioport_permission xen_domctl_ioport_permission_t;
377 DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_permission_t);
378 
379 
380 #define XEN_DOMCTL_hypercall_init    22
381 struct xen_domctl_hypercall_init {
382     uint64_aligned_t  gmfn;           /* GMFN to be initialised */
383 };
384 typedef struct xen_domctl_hypercall_init xen_domctl_hypercall_init_t;
385 DEFINE_XEN_GUEST_HANDLE(xen_domctl_hypercall_init_t);
386 
387 
388 #define XEN_DOMCTL_arch_setup        23
389 #define _XEN_DOMAINSETUP_hvm_guest 0
390 #define XEN_DOMAINSETUP_hvm_guest  (1UL<<_XEN_DOMAINSETUP_hvm_guest)
391 #define _XEN_DOMAINSETUP_query 1 /* Get parameters (for save)  */
392 #define XEN_DOMAINSETUP_query  (1UL<<_XEN_DOMAINSETUP_query)
393 typedef struct xen_domctl_arch_setup {
394     uint64_aligned_t flags;  /* XEN_DOMAINSETUP_* */
395 #ifdef __ia64__
396     uint64_aligned_t bp;     /* mpaddr of boot param area */
397     uint64_aligned_t maxmem; /* Highest memory address for MDT.  */
398     uint64_aligned_t xsi_va; /* Xen shared_info area virtual address.  */
399     uint32_t hypercall_imm;  /* Break imm for Xen hypercalls.  */
400 #endif
401 } xen_domctl_arch_setup_t;
402 DEFINE_XEN_GUEST_HANDLE(xen_domctl_arch_setup_t);
403 
404 
405 #define XEN_DOMCTL_settimeoffset     24
406 struct xen_domctl_settimeoffset {
407     int32_t  time_offset_seconds; /* applied to domain wallclock time */
408 };
409 typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
410 DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
411 
412 
413 #define XEN_DOMCTL_gethvmcontext     33
414 #define XEN_DOMCTL_sethvmcontext     34
415 typedef struct xen_domctl_hvmcontext {
416     uint32_t size; /* IN/OUT: size of buffer / bytes filled */
417     uint8_t  pad[4];
418     XEN_GUEST_HANDLE_64(uint8_t) buffer; /* IN/OUT: data, or call
419                                           * gethvmcontext with NULL
420                                           * buffer to get size
421                                           * req'd */
422 } xen_domctl_hvmcontext_t;
423 DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t);
424 
425 
426 #define XEN_DOMCTL_set_address_size  35
427 #define XEN_DOMCTL_get_address_size  36
428 typedef struct xen_domctl_address_size {
429     uint32_t size;
430 } xen_domctl_address_size_t;
431 DEFINE_XEN_GUEST_HANDLE(xen_domctl_address_size_t);
432 
433 
434 #define XEN_DOMCTL_real_mode_area    26
435 struct xen_domctl_real_mode_area {
436     uint32_t log; /* log2 of Real Mode Area size */
437 };
438 typedef struct xen_domctl_real_mode_area xen_domctl_real_mode_area_t;
439 DEFINE_XEN_GUEST_HANDLE(xen_domctl_real_mode_area_t);
440 
441 
442 #define XEN_DOMCTL_sendtrigger       28
443 #define XEN_DOMCTL_SENDTRIGGER_NMI    0
444 #define XEN_DOMCTL_SENDTRIGGER_RESET  1
445 #define XEN_DOMCTL_SENDTRIGGER_INIT   2
446 struct xen_domctl_sendtrigger {
447     uint32_t  trigger;  /* IN */
448     uint32_t  vcpu;     /* IN */
449 };
450 typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t;
451 DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t);
452 
453 
454 struct xen_domctl {
455     uint32_t cmd;
456     uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
457     domid_t  domain;
458     uint8_t pad[6];
459     union {
460         struct xen_domctl_createdomain      createdomain;
461         struct xen_domctl_getdomaininfo     getdomaininfo;
462         struct xen_domctl_getmemlist        getmemlist;
463         struct xen_domctl_getpageframeinfo  getpageframeinfo;
464         struct xen_domctl_getpageframeinfo2 getpageframeinfo2;
465         struct xen_domctl_vcpuaffinity      vcpuaffinity;
466         struct xen_domctl_shadow_op         shadow_op;
467         struct xen_domctl_max_mem           max_mem;
468         struct xen_domctl_vcpucontext       vcpucontext;
469         struct xen_domctl_getvcpuinfo       getvcpuinfo;
470         struct xen_domctl_max_vcpus         max_vcpus;
471         struct xen_domctl_scheduler_op      scheduler_op;
472         struct xen_domctl_setdomainhandle   setdomainhandle;
473         struct xen_domctl_setdebugging      setdebugging;
474         struct xen_domctl_irq_permission    irq_permission;
475         struct xen_domctl_iomem_permission  iomem_permission;
476         struct xen_domctl_ioport_permission ioport_permission;
477         struct xen_domctl_hypercall_init    hypercall_init;
478         struct xen_domctl_arch_setup        arch_setup;
479         struct xen_domctl_settimeoffset     settimeoffset;
480         struct xen_domctl_real_mode_area    real_mode_area;
481         struct xen_domctl_hvmcontext        hvmcontext;
482         struct xen_domctl_address_size      address_size;
483         struct xen_domctl_sendtrigger       sendtrigger;
484         uint8_t                             pad[128];
485     } u;
486 };
487 typedef struct xen_domctl xen_domctl_t;
488 DEFINE_XEN_GUEST_HANDLE(xen_domctl_t);
489 
490 #endif /* __XEN_PUBLIC_DOMCTL_H__ */
491 
492 /*
493  * Local variables:
494  * mode: C
495  * c-set-style: "BSD"
496  * c-basic-offset: 4
497  * tab-width: 4
498  * indent-tabs-mode: nil
499  * End:
500  */
501