VirtualBox

source: vbox/trunk/src/VBox/VMM/include/EMInternal.h@ 72569

Last change on this file since 72569 was 72569, checked in by vboxsync, 6 years ago

EM,IEM,NEM: Started working on optimizing adjacent exits using IEM. Keep track of frequent exits, after 256 hits do a trial run in IEM to look for adjacent exits. Proof of concept using CPUID in NEMR3/win. bugref:9044

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.4 KB
Line 
1/* $Id: EMInternal.h 72569 2018-06-15 19:04:01Z vboxsync $ */
2/** @file
3 * EM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___EMInternal_h
19#define ___EMInternal_h
20
21#include <VBox/cdefs.h>
22#include <VBox/types.h>
23#include <VBox/vmm/em.h>
24#include <VBox/vmm/stam.h>
25#include <VBox/vmm/patm.h>
26#include <VBox/dis.h>
27#include <VBox/vmm/pdmcritsect.h>
28#include <iprt/avl.h>
29#include <setjmp.h>
30
31RT_C_DECLS_BEGIN
32
33
34/** @defgroup grp_em_int Internal
35 * @ingroup grp_em
36 * @internal
37 * @{
38 */
39
40/** The saved state version. */
41#define EM_SAVED_STATE_VERSION 5
42#define EM_SAVED_STATE_VERSION_PRE_IEM 4
43#define EM_SAVED_STATE_VERSION_PRE_MWAIT 3
44#define EM_SAVED_STATE_VERSION_PRE_SMP 2
45
46
47/** @name MWait state flags.
48 * @{
49 */
50/** MWait activated. */
51#define EMMWAIT_FLAG_ACTIVE RT_BIT(0)
52/** MWait will continue when an interrupt is pending even when IF=0. */
53#define EMMWAIT_FLAG_BREAKIRQIF0 RT_BIT(1)
54/** Monitor instruction was executed previously. */
55#define EMMWAIT_FLAG_MONITOR_ACTIVE RT_BIT(2)
56/** @} */
57
58/** EM time slice in ms; used for capping execution time. */
59#define EM_TIME_SLICE 100
60
61/**
62 * Cli node structure
63 */
64typedef struct CLISTAT
65{
66 /** The key is the cli address. */
67 AVLGCPTRNODECORE Core;
68#if HC_ARCH_BITS == 32 && !defined(RT_OS_WINDOWS)
69 /** Padding. */
70 uint32_t u32Padding;
71#endif
72 /** Occurrences. */
73 STAMCOUNTER Counter;
74} CLISTAT, *PCLISTAT;
75#ifdef IN_RING3
76AssertCompileMemberAlignment(CLISTAT, Counter, 8);
77#endif
78
79
80/**
81 * Excessive EM statistics.
82 */
83typedef struct EMSTATS
84{
85 /** GC: Profiling of EMInterpretInstruction(). */
86 STAMPROFILE StatRZEmulate;
87 /** HC: Profiling of EMInterpretInstruction(). */
88 STAMPROFILE StatR3Emulate;
89
90 /** @name Interpreter Instruction statistics.
91 * @{
92 */
93 STAMCOUNTER StatRZInterpretSucceeded;
94 STAMCOUNTER StatR3InterpretSucceeded;
95
96 STAMCOUNTER StatRZAnd;
97 STAMCOUNTER StatR3And;
98 STAMCOUNTER StatRZCpuId;
99 STAMCOUNTER StatR3CpuId;
100 STAMCOUNTER StatRZDec;
101 STAMCOUNTER StatR3Dec;
102 STAMCOUNTER StatRZHlt;
103 STAMCOUNTER StatR3Hlt;
104 STAMCOUNTER StatRZInc;
105 STAMCOUNTER StatR3Inc;
106 STAMCOUNTER StatRZInvlPg;
107 STAMCOUNTER StatR3InvlPg;
108 STAMCOUNTER StatRZIret;
109 STAMCOUNTER StatR3Iret;
110 STAMCOUNTER StatRZLLdt;
111 STAMCOUNTER StatR3LLdt;
112 STAMCOUNTER StatRZLIdt;
113 STAMCOUNTER StatR3LIdt;
114 STAMCOUNTER StatRZLGdt;
115 STAMCOUNTER StatR3LGdt;
116 STAMCOUNTER StatRZMov;
117 STAMCOUNTER StatR3Mov;
118 STAMCOUNTER StatRZMovCRx;
119 STAMCOUNTER StatR3MovCRx;
120 STAMCOUNTER StatRZMovDRx;
121 STAMCOUNTER StatR3MovDRx;
122 STAMCOUNTER StatRZOr;
123 STAMCOUNTER StatR3Or;
124 STAMCOUNTER StatRZPop;
125 STAMCOUNTER StatR3Pop;
126 STAMCOUNTER StatRZSti;
127 STAMCOUNTER StatR3Sti;
128 STAMCOUNTER StatRZXchg;
129 STAMCOUNTER StatR3Xchg;
130 STAMCOUNTER StatRZXor;
131 STAMCOUNTER StatR3Xor;
132 STAMCOUNTER StatRZMonitor;
133 STAMCOUNTER StatR3Monitor;
134 STAMCOUNTER StatRZMWait;
135 STAMCOUNTER StatR3MWait;
136 STAMCOUNTER StatRZAdd;
137 STAMCOUNTER StatR3Add;
138 STAMCOUNTER StatRZSub;
139 STAMCOUNTER StatR3Sub;
140 STAMCOUNTER StatRZAdc;
141 STAMCOUNTER StatR3Adc;
142 STAMCOUNTER StatRZRdtsc;
143 STAMCOUNTER StatR3Rdtsc;
144 STAMCOUNTER StatRZRdpmc;
145 STAMCOUNTER StatR3Rdpmc;
146 STAMCOUNTER StatRZBtr;
147 STAMCOUNTER StatR3Btr;
148 STAMCOUNTER StatRZBts;
149 STAMCOUNTER StatR3Bts;
150 STAMCOUNTER StatRZBtc;
151 STAMCOUNTER StatR3Btc;
152 STAMCOUNTER StatRZCmpXchg;
153 STAMCOUNTER StatR3CmpXchg;
154 STAMCOUNTER StatRZCmpXchg8b;
155 STAMCOUNTER StatR3CmpXchg8b;
156 STAMCOUNTER StatRZXAdd;
157 STAMCOUNTER StatR3XAdd;
158 STAMCOUNTER StatRZClts;
159 STAMCOUNTER StatR3Clts;
160 STAMCOUNTER StatRZStosWD;
161 STAMCOUNTER StatR3StosWD;
162 STAMCOUNTER StatR3Rdmsr;
163 STAMCOUNTER StatR3Wrmsr;
164 STAMCOUNTER StatRZRdmsr;
165 STAMCOUNTER StatRZWrmsr;
166 STAMCOUNTER StatRZWbInvd;
167 STAMCOUNTER StatR3WbInvd;
168 STAMCOUNTER StatRZLmsw;
169 STAMCOUNTER StatR3Lmsw;
170 STAMCOUNTER StatRZSmsw;
171 STAMCOUNTER StatR3Smsw;
172
173 STAMCOUNTER StatRZInterpretFailed;
174 STAMCOUNTER StatR3InterpretFailed;
175
176 STAMCOUNTER StatRZFailedAnd;
177 STAMCOUNTER StatR3FailedAnd;
178 STAMCOUNTER StatRZFailedCpuId;
179 STAMCOUNTER StatR3FailedCpuId;
180 STAMCOUNTER StatRZFailedDec;
181 STAMCOUNTER StatR3FailedDec;
182 STAMCOUNTER StatRZFailedHlt;
183 STAMCOUNTER StatR3FailedHlt;
184 STAMCOUNTER StatRZFailedInc;
185 STAMCOUNTER StatR3FailedInc;
186 STAMCOUNTER StatRZFailedInvlPg;
187 STAMCOUNTER StatR3FailedInvlPg;
188 STAMCOUNTER StatRZFailedIret;
189 STAMCOUNTER StatR3FailedIret;
190 STAMCOUNTER StatRZFailedLLdt;
191 STAMCOUNTER StatR3FailedLLdt;
192 STAMCOUNTER StatRZFailedLGdt;
193 STAMCOUNTER StatR3FailedLGdt;
194 STAMCOUNTER StatRZFailedLIdt;
195 STAMCOUNTER StatR3FailedLIdt;
196 STAMCOUNTER StatRZFailedMisc;
197 STAMCOUNTER StatR3FailedMisc;
198 STAMCOUNTER StatRZFailedMov;
199 STAMCOUNTER StatR3FailedMov;
200 STAMCOUNTER StatRZFailedMovCRx;
201 STAMCOUNTER StatR3FailedMovCRx;
202 STAMCOUNTER StatRZFailedMovDRx;
203 STAMCOUNTER StatR3FailedMovDRx;
204 STAMCOUNTER StatRZFailedOr;
205 STAMCOUNTER StatR3FailedOr;
206 STAMCOUNTER StatRZFailedPop;
207 STAMCOUNTER StatR3FailedPop;
208 STAMCOUNTER StatRZFailedSti;
209 STAMCOUNTER StatR3FailedSti;
210 STAMCOUNTER StatRZFailedXchg;
211 STAMCOUNTER StatR3FailedXchg;
212 STAMCOUNTER StatRZFailedXor;
213 STAMCOUNTER StatR3FailedXor;
214 STAMCOUNTER StatRZFailedMonitor;
215 STAMCOUNTER StatR3FailedMonitor;
216 STAMCOUNTER StatRZFailedMWait;
217 STAMCOUNTER StatR3FailedMWait;
218 STAMCOUNTER StatR3FailedRdmsr;
219 STAMCOUNTER StatR3FailedWrmsr;
220 STAMCOUNTER StatRZFailedRdmsr;
221 STAMCOUNTER StatRZFailedWrmsr;
222 STAMCOUNTER StatRZFailedLmsw;
223 STAMCOUNTER StatR3FailedLmsw;
224 STAMCOUNTER StatRZFailedSmsw;
225 STAMCOUNTER StatR3FailedSmsw;
226
227 STAMCOUNTER StatRZFailedAdd;
228 STAMCOUNTER StatR3FailedAdd;
229 STAMCOUNTER StatRZFailedAdc;
230 STAMCOUNTER StatR3FailedAdc;
231 STAMCOUNTER StatRZFailedBtr;
232 STAMCOUNTER StatR3FailedBtr;
233 STAMCOUNTER StatRZFailedBts;
234 STAMCOUNTER StatR3FailedBts;
235 STAMCOUNTER StatRZFailedBtc;
236 STAMCOUNTER StatR3FailedBtc;
237 STAMCOUNTER StatRZFailedCli;
238 STAMCOUNTER StatR3FailedCli;
239 STAMCOUNTER StatRZFailedCmpXchg;
240 STAMCOUNTER StatR3FailedCmpXchg;
241 STAMCOUNTER StatRZFailedCmpXchg8b;
242 STAMCOUNTER StatR3FailedCmpXchg8b;
243 STAMCOUNTER StatRZFailedXAdd;
244 STAMCOUNTER StatR3FailedXAdd;
245 STAMCOUNTER StatR3FailedMovNTPS;
246 STAMCOUNTER StatRZFailedMovNTPS;
247 STAMCOUNTER StatRZFailedStosWD;
248 STAMCOUNTER StatR3FailedStosWD;
249 STAMCOUNTER StatRZFailedSub;
250 STAMCOUNTER StatR3FailedSub;
251 STAMCOUNTER StatRZFailedWbInvd;
252 STAMCOUNTER StatR3FailedWbInvd;
253 STAMCOUNTER StatRZFailedRdtsc;
254 STAMCOUNTER StatR3FailedRdtsc;
255 STAMCOUNTER StatRZFailedRdpmc;
256 STAMCOUNTER StatR3FailedRdpmc;
257 STAMCOUNTER StatRZFailedClts;
258 STAMCOUNTER StatR3FailedClts;
259
260 STAMCOUNTER StatRZFailedUserMode;
261 STAMCOUNTER StatR3FailedUserMode;
262 STAMCOUNTER StatRZFailedPrefix;
263 STAMCOUNTER StatR3FailedPrefix;
264 /** @} */
265
266 /** @name Privileged Instructions Ending Up In HC.
267 * @{ */
268 STAMCOUNTER StatIoRestarted;
269 STAMCOUNTER StatIoIem;
270 STAMCOUNTER StatCli;
271 STAMCOUNTER StatSti;
272 STAMCOUNTER StatInvlpg;
273 STAMCOUNTER StatHlt;
274 STAMCOUNTER StatMovReadCR[DISCREG_CR4 + 1];
275 STAMCOUNTER StatMovWriteCR[DISCREG_CR4 + 1];
276 STAMCOUNTER StatMovDRx;
277 STAMCOUNTER StatIret;
278 STAMCOUNTER StatMovLgdt;
279 STAMCOUNTER StatMovLldt;
280 STAMCOUNTER StatMovLidt;
281 STAMCOUNTER StatMisc;
282 STAMCOUNTER StatSysEnter;
283 STAMCOUNTER StatSysExit;
284 STAMCOUNTER StatSysCall;
285 STAMCOUNTER StatSysRet;
286 /** @} */
287
288} EMSTATS;
289/** Pointer to the excessive EM statistics. */
290typedef EMSTATS *PEMSTATS;
291
292
293/**
294 * Exit history entry.
295 *
296 * @remarks We could perhaps trim this down a little bit by assuming uFlatPC
297 * only needs 48 bits (currently true but will change) and stuffing
298 * the flags+type in the available 16 bits made available. The
299 * timestamp could likewise be shortened to accomodate the index, or
300 * we might skip the index entirely. However, since we will have to
301 * deal with 56-bit wide PC address before long, there's not point.
302 *
303 * On the upside, there are unused bits in both uFlagsAndType and the
304 * idxSlot fields if needed for anything.
305 */
306typedef struct EMEXITENTRY
307{
308 /** The flat PC (CS:EIP/RIP) address of the exit.
309 * UINT64_MAX if not available. */
310 uint64_t uFlatPC;
311 /** The EMEXIT_MAKE_FLAGS_AND_TYPE */
312 uint32_t uFlagsAndType;
313 /** The index into the exit slot hash table.
314 * UINT32_MAX if too many collisions and not entered into it. */
315 uint32_t idxSlot;
316 /** The TSC timestamp of the exit.
317 * This is 0 if not timestamped. */
318 uint64_t uTimestamp;
319} EMEXITENTRY;
320/** Pointer to an exit history entry. */
321typedef EMEXITENTRY *PEMEXITENTRY;
322/** Pointer to a const exit history entry. */
323typedef EMEXITENTRY const *PCEMEXITENTRY;
324
325
326/**
327 * Converts a EM pointer into a VM pointer.
328 * @returns Pointer to the VM structure the EM is part of.
329 * @param pEM Pointer to EM instance data.
330 */
331#define EM2VM(pEM) ( (PVM)((char*)pEM - pEM->offVM) )
332
333/**
334 * EM VM Instance data.
335 * Changes to this must checked against the padding of the cfgm union in VM!
336 */
337typedef struct EM
338{
339 /** Offset to the VM structure.
340 * See EM2VM(). */
341 RTUINT offVM;
342
343 /** Whether IEM executes everything. */
344 bool fIemExecutesAll;
345 /** Whether a triple fault triggers a guru. */
346 bool fGuruOnTripleFault;
347 /** Alignment padding. */
348 bool afPadding[6];
349
350 /** Id of the VCPU that last executed code in the recompiler. */
351 VMCPUID idLastRemCpu;
352
353#ifdef VBOX_WITH_REM
354 /** REM critical section.
355 * This protects recompiler usage
356 */
357 PDMCRITSECT CritSectREM;
358#endif
359} EM;
360/** Pointer to EM VM instance data. */
361typedef EM *PEM;
362
363
364/**
365 * EM VMCPU Instance data.
366 */
367typedef struct EMCPU
368{
369 /** Execution Manager State. */
370 EMSTATE volatile enmState;
371
372 /** The state prior to the suspending of the VM. */
373 EMSTATE enmPrevState;
374
375 /** Force raw-mode execution.
376 * This is used to prevent REM from trying to execute patch code.
377 * The flag is cleared upon entering emR3RawExecute() and updated in certain return paths. */
378 bool fForceRAW;
379
380 /** Set if hypercall instruction VMMCALL (AMD) & VMCALL (Intel) are enabled.
381 * GIM sets this and the execution managers queries it. Not saved, as GIM
382 * takes care of that bit too. */
383 bool fHypercallEnabled;
384
385 /** Explicit padding. */
386 uint8_t abPadding[2];
387
388 /** The number of instructions we've executed in IEM since switching to the
389 * EMSTATE_IEM_THEN_REM state. */
390 uint32_t cIemThenRemInstructions;
391
392 /** Inhibit interrupts for this instruction. Valid only when VM_FF_INHIBIT_INTERRUPTS is set. */
393 RTGCUINTPTR GCPtrInhibitInterrupts;
394
395#ifdef VBOX_WITH_RAW_MODE
396 /** Pointer to the PATM status structure. (R3 Ptr) */
397 R3PTRTYPE(PPATMGCSTATE) pPatmGCState;
398#endif
399
400 /** Pointer to the guest CPUM state. (R3 Ptr) */
401 R3PTRTYPE(PCPUMCTX) pCtx;
402
403#if GC_ARCH_BITS == 64
404 RTGCPTR aPadding1;
405#endif
406
407 /** Start of the current time slice in ms. */
408 uint64_t u64TimeSliceStart;
409 /** Start of the current time slice in thread execution time (ms). */
410 uint64_t u64TimeSliceStartExec;
411 /** Current time slice value. */
412 uint64_t u64TimeSliceExec;
413
414 /** Pending ring-3 I/O port access (VINF_EM_PENDING_R3_IOPORT_READ / VINF_EM_PENDING_R3_IOPORT_WRITE). */
415 struct
416 {
417 RTIOPORT uPort; /**< The I/O port number.*/
418 uint8_t cbValue; /**< The value size in bytes. Zero when not pending. */
419 uint8_t cbInstr; /**< The instruction length. */
420 uint32_t uValue; /**< The value to write. */
421 } PendingIoPortAccess;
422
423 /** MWait halt state. */
424 struct
425 {
426 uint32_t fWait; /**< Type of mwait; see EMMWAIT_FLAG_*. */
427 uint32_t u32Padding;
428 RTGCPTR uMWaitRAX; /**< MWAIT hints. */
429 RTGCPTR uMWaitRCX; /**< MWAIT extensions. */
430 RTGCPTR uMonitorRAX; /**< Monitored address. */
431 RTGCPTR uMonitorRCX; /**< Monitor extension. */
432 RTGCPTR uMonitorRDX; /**< Monitor hint. */
433 } MWait;
434
435 union
436 {
437 /** Padding used in the other rings.
438 * This must be larger than jmp_buf on any supported platform. */
439 char achPaddingFatalLongJump[HC_ARCH_BITS == 32 ? 176 : 256];
440#ifdef IN_RING3
441 /** Long buffer jump for fatal VM errors.
442 * It will jump to before the outer EM loop is entered. */
443 jmp_buf FatalLongJump;
444#endif
445 } u;
446
447 /** For saving stack space, the disassembler state is allocated here instead of
448 * on the stack. */
449 DISCPUSTATE DisState;
450
451 /** @name Execution profiling.
452 * @{ */
453 STAMPROFILE StatForcedActions;
454 STAMPROFILE StatHalted;
455 STAMPROFILEADV StatCapped;
456 STAMPROFILEADV StatHMEntry;
457 STAMPROFILE StatHMExec;
458 STAMPROFILE StatIEMEmu;
459 STAMPROFILE StatIEMThenREM;
460 STAMPROFILEADV StatNEMEntry;
461 STAMPROFILE StatNEMExec;
462 STAMPROFILE StatREMEmu;
463 STAMPROFILE StatREMExec;
464 STAMPROFILE StatREMSync;
465 STAMPROFILEADV StatREMTotal;
466 STAMPROFILE StatRAWExec;
467 STAMPROFILEADV StatRAWEntry;
468 STAMPROFILEADV StatRAWTail;
469 STAMPROFILEADV StatRAWTotal;
470 STAMPROFILEADV StatTotal;
471 /** @} */
472
473 /** R3: Profiling of emR3RawExecuteIOInstruction. */
474 STAMPROFILE StatIOEmu;
475 /** R3: Profiling of emR3RawPrivileged. */
476 STAMPROFILE StatPrivEmu;
477 /** R3: Number of times emR3HmExecute is called. */
478 STAMCOUNTER StatHMExecuteCalled;
479 /** R3: Number of times emR3NEMExecute is called. */
480 STAMCOUNTER StatNEMExecuteCalled;
481
482 /** More statistics (R3). */
483 R3PTRTYPE(PEMSTATS) pStatsR3;
484 /** More statistics (R0). */
485 R0PTRTYPE(PEMSTATS) pStatsR0;
486 /** More statistics (RC). */
487 RCPTRTYPE(PEMSTATS) pStatsRC;
488#if HC_ARCH_BITS == 64
489 RTRCPTR padding0;
490#endif
491
492 /** Tree for keeping track of cli occurrences (debug only). */
493 R3PTRTYPE(PAVLGCPTRNODECORE) pCliStatTree;
494 STAMCOUNTER StatTotalClis;
495#if HC_ARCH_BITS == 32
496 uint64_t padding1;
497#endif
498
499 /** Where to store the next exit history entry.
500 * Since aExitHistory is 256 items longs, we'll just increment this and
501 * mask it when using it. That help the readers detect whether we've
502 * wrapped around or not. */
503 uint64_t iNextExit;
504 /** Exit history table (6KB). */
505 EMEXITENTRY aExitHistory[256];
506 /** Number of exit records in use. */
507 uint32_t cExitRecordUsed;
508 /** Number of exit records collisions. */
509 uint32_t cExitRecordCollisions;
510 /** Exit records (32KB). (Aligned on 32 byte boundrary.) */
511 EMEXITREC aExitRecords[1024];
512} EMCPU;
513/** Pointer to EM VM instance data. */
514typedef EMCPU *PEMCPU;
515
516/** @} */
517
518int emR3InitDbg(PVM pVM);
519
520int emR3HmExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
521VBOXSTRICTRC emR3NemExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
522int emR3RawExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
523
524int emR3RawHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);
525int emR3HmHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);
526int emR3NemHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);
527
528EMSTATE emR3Reschedule(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
529int emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc);
530VBOXSTRICTRC emR3HighPriorityPostForcedActions(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc);
531
532int emR3RawUpdateForceFlag(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);
533int emR3RawResumeHyper(PVM pVM, PVMCPU pVCpu);
534int emR3RawStep(PVM pVM, PVMCPU pVCpu);
535
536VBOXSTRICTRC emR3NemSingleInstruction(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
537
538int emR3SingleStepExecRem(PVM pVM, PVMCPU pVCpu, uint32_t cIterations);
539
540bool emR3IsExecutionAllowed(PVM pVM, PVMCPU pVCpu);
541
542VBOXSTRICTRC emR3ExecutePendingIoPortWrite(PVM pVM, PVMCPU pVCpu);
543VBOXSTRICTRC emR3ExecutePendingIoPortRead(PVM pVM, PVMCPU pVCpu);
544
545RT_C_DECLS_END
546
547#endif
548
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette